Skip to content

Support the ability to have multiple instances running at the same time #206

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ylazzari opened this issue Apr 9, 2025 · 8 comments
Open
Labels
enhancement New feature or request

Comments

@ylazzari
Copy link

ylazzari commented Apr 9, 2025

Hi.

My organization is currently slowing migrating from a hosted Github Enterprise Server instance to Github Enterprise Cloud. When I try to use VS Code's Agent support, I can configure two distinct tools with different names and different configurations. Something like this:

{ 
  "chat.agent.enabled": true,
  "mcp": {
    "inputs": [
      {
        "type": "promptString",
        "id": "ghec_token",
        "description": "GitHub Enterprise Cloud Personal Access Token",
        "password": true
      },
      {
        "type": "promptString",
        "id": "ghes_token",
        "description": "GitHub Enterprise Server Personal Access Token",
        "password": true
      }
    ],
    "servers": {
      "GHEC": {
        "command": "github-mcp-server",
        "args": [
            "stdio"
        ],
        "env": {
            "GITHUB_PERSONAL_ACCESS_TOKEN": "${input:ghec_token}"
        }
      },      
      "GHES": {
        "command": "github-mcp-server",
        "args": [
            "stdio"
        ],
        "env": {
            "GITHUB_PERSONAL_ACCESS_TOKEN": "${input:ghes_token}",
            "GH_HOST": "https://someotherdomain.com"
        }
      }           
    }       
  }
}

The problem is that the Agent is confused and seems to pin itself to only the set of tools exposed by one of the servers, hence I cannot navigate between the repos hosted on both Github instances. I can't seem to "prompt" engineer my way out of this.

The Github MCP server docs show how to overwrite individual tool descriptions. I haven't tried, but I guess I could override the tool descriptions for both servers, explicitly call out one set is for GHEC, one for GHES, and see if I can then adjust the prompt to force it to use one set of tools, so one server, or the other. But I'm hoping there's a better way to do this.

This may be more of a VS Code issue, but maybe there's something in how the server is actually implemented that could help facilitate this use case.

Thank you!

@ylazzari ylazzari added the enhancement New feature or request label Apr 9, 2025
@smadi0x86
Copy link

The github MCP server already has the code to support multiple instances as shown in codebase:

  1. Server Configuration Support (from cmd/github-mcp-server/main.go):
// Create GH client
token := os.Getenv("GITHUB_PERSONAL_ACCESS_TOKEN")
if token == "" {
    cfg.logger.Fatal("GITHUB_PERSONAL_ACCESS_TOKEN not set")
}
ghClient := gogithub.NewClient(nil).WithAuthToken(token)
ghClient.UserAgent = fmt.Sprintf("github-mcp-server/%s", version)

// Check GH_HOST env var first, then fall back to viper config
host := os.Getenv("GH_HOST")
if host == "" {
    host = viper.GetString("gh-host")
}

if host != "" {
    var err error
    ghClient, err = ghClient.WithEnterpriseURLs(host, host)
    if err != nil {
        return fmt.Errorf("failed to create GitHub client with host: %w", err)
    }
}
  1. Tool Name Differentiation (from pkg/github/server.go):
func NewServer(client *github.Client, version string, readOnly bool, t translations.TranslationHelperFunc) *server.MCPServer {
    s := server.NewMCPServer(
        "github-mcp-server",
        version,
        server.WithResourceCapabilities(true, true),
        server.WithLogging())

As previously shown, the server already supports:

  1. Running multiple instances with different configurations
  2. Using different tokens for each instance
  3. Configuring different GitHub hosts for each instance
  4. Overriding tool descriptions using environment variables or configuration files

The issue appears to be more related to vscode agent implementation rather than a limitation in the GitHub MCP server itself.

@SamMorrowDrums
Copy link
Collaborator

I would love to hear back if overriding tool descriptions works. Definitely also share this use case with vscode.

@digitarald
Copy link
Member

digitarald commented Apr 10, 2025

Feature I am tracking for client-side controls/customizations; as I heard the same use case before: microsoft/vscode#243940

@rajbos
Copy link

rajbos commented Apr 23, 2025

@SamMorrowDrums , I have been testing with configuring the github-mcp-server twice on the same VS Code configuration:

  1. github_emu for the connection to our EMU instance
  2. github_ghes for the connection to one of our GitHub Enterprise Server environments (including the GITHUB_HOST variable)

Feedback:

  1. I cannot see a differentiation between the MCP servers in the visible tools. Both MCP servers are running with each 36 tools available, but the tool picker in the chat interface only shows 36 tools, where as I would expect either 72, or a differentiation that the tool is available twice (once for each configured server).
  2. It seems to be that just the server that gets started first is visible in the tools dropdown, with the correct name though (so MCP Server: github_ghes if I start that one first.
  3. Prompting for anything goes to the server that started up first, I have not been able to prompt my way around that either.

Hope that info helps!

Config example:

"mcp": {
        "inputs": [
            {
                "type": "promptString",
                "id": "github_token_ghes",
                "description": "GitHub Personal Access Token for GHES",
                "password": true
            },
            {
                "type": "promptString",
                "id": "github_token_emu",
                "description": "GitHub Personal Access Token for EMU GHEC",
                "password": true
            }
        ],
        "servers": {
            "github_emu": {
                "command": "docker",
                "args": [
                "run",
                "-i",
                "--rm",
                "-e",
                "GITHUB_PERSONAL_ACCESS_TOKEN",
                "ghcr.io/github/github-mcp-server"
                ],
                "env": {
                    "GITHUB_PERSONAL_ACCESS_TOKEN": "${input:github_token_emu}"
                }
            },
            "github_ghes": {
                "command": "docker",
                "args": [
                "run",
                "-i",
                "--rm",
                "-e",
                "GITHUB_PERSONAL_ACCESS_TOKEN",
                "-e",
                "GITHUB_HOST",
                "ghcr.io/github/github-mcp-server"
                ],
                "env": {
                    "GITHUB_PERSONAL_ACCESS_TOKEN": "${input:github_token_ghes}",
                    "GITHUB_HOST": "https://gh.domain.com"
                }
            }
        }
    }

@SamMorrowDrums
Copy link
Collaborator

I could imagine adding a --tool-prefix flag to enable experimentation, I'm curious how well models would handle it.

@tjamet
Copy link

tjamet commented May 2, 2025

Overriding tool descriptions using environment variables or configuration files

While this is true, it feels a lot of burden on the users to maintain.

First, because --export-translations does not work and it makes it even harder to know all tools exposed (see #367)

Second because then, users would have to manually update all the descriptions each time there is a new tool added.

It's a burden that can easily be completely removed by allowing parameterising the GitHub name of descriptions.
For instance, using a --tool-prefix argument as described above or a --github-server-description.

That way mcp.WithDescription(t("TOOL_GET_CODE_SCANNING_ALERT_DESCRIPTION", "Get details of a specific code scanning alert in a GitHub repository.")), could become mcp.WithDescription(t("TOOL_GET_CODE_SCANNING_ALERT_DESCRIPTION", fmt.Sprintf("Get details of a specific code scanning alert in a %s repository.", t.GitHubInstanceName()))), here to adapt to all cases. (change that should also apply everywhere else)

@rajbos
Copy link

rajbos commented May 3, 2025

Thinking out loud here: Wouldn't it make sense to be able to configure a rule or other MCP tool to be able to reference which tool instance it needs to use? In the case of the GitHub MCP server, the switch needs to happen on the current remote (only works reliably if there is a single remote).

So either that kind of intelligence is build into the server (required input for the remote to use) and then have an understanding of what to do), or configurable in the client (by injecting another tool or script?).

That direction might also solve issues that I constantly have of the tool not understanding the difference between a user space repo and a repo in an org for example.

It's basically making the tools and the tool selection context aware. Example: if the client has the context that the current repo does not have for example GHAS enabled, then the tool selection should not return any GHAS tools (or indicate that those are not available because it's not enabled). Save the user a lot of guess work and having to know these type of intricacies.

@SamMorrowDrums
Copy link
Collaborator

@tjamet I replied to your issue, but --export-translations is working, it is just janky and should be improved (at least docs should be).

I am definitely not against a tool prefix, and @rajbos I think there are times where you might want the ability to have a sort of repo server or specific host server that is tied only to one of those resources.

These are all really interesting ideas - we'll let them brew a while longer while we also consider what the best approaches are, but I am always really interested in enabling this sort of thing - it's very cool if it could enable you to work well across GHES and GitHub.com so I do think it would be worth providing a solution in some form.

I'm curious to see if other users join in with this issue and add their use-cases too.

Also, considering this is open source, as well as contributing solution back - you can also create a useful fork version for a specific use-case that you have, even if it doesn't end up in the release. I think these kind of ideas can sometimes be best explored by just showcasing what you are thinking, letting others use it and reporting back! ❤

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants