GitHub authorization for MCP servers
It’s easy to justify static credential configuration when an MCP server starts out as a one-user, one-server setup in a developer environment. But things quickly get complicated when that server moves into shared use by a handful of developers. When admins expand the token’s repository access to reduce request failures, GitHub can no longer distinguish one user from another, and the credential path no longer preserves clean attribution or least privilege.
In our first post, we laid out the backend authorization problem in MCP systems. Here, we look at the first practical pattern for solving it: a GitHub path where Stacklok’s open source project, ToolHive, acts as a proxy authorization server in front of the MCP server, manages the GitHub OAuth flow and keeps the downstream credential path tied to the individual user.
The GitHub pattern: Per-user access
In the GitHub MCP server authorization setup, ToolHive sits in front of the MCP server and brokers the auth path to GitHub. The MCP server doesn’t need to own a long-lived GitHub credential or implement the auth flow itself. ToolHive handles the GitHub sign-in flow, issues its own credential to the client and, on downstream requests, exchanges that client-side credential for the stored GitHub access token before forwarding the request.
That separation keeps OAuth handling and token storage in the ToolHive layer while the MCP server continues to execute GitHub operations on behalf of the signed-in user.
Request flow: GitHub authorization for MCP servers with ToolHive
In practice, the flow looks like this:
- The user selects the GitHub MCP server in the client.
- The client initiates the connection, and the ToolHive proxy authorization server responds with an authorization challenge.
- The user is redirected to ToolHive, which redirects to GitHub for sign-in.
- From the user’s point of view, the sign-in step is with GitHub.
- After GitHub authentication completes, ToolHive stores the GitHub credentials and issues the client its own credential, linked to that GitHub session.
- On later requests in that session, the client sends the ToolHive-issued credential. ToolHive validates it, retrieves the stored GitHub credentials and replaces the ToolHive credential in the request with the GitHub credential before forwarding the request to the MCP server.
- The MCP server receives the GitHub credential and uses it to operate on behalf of that specific user.
- The result is one downstream credential path per user rather than one shared credential for everyone.
Operational considerations
The GitHub setup also depends on one-time OAuth client registration, redirect URI configuration, session storage and one server-side constraint in the MCP layer.
On the GitHub side, an admin provisions the ToolHive proxy authorization server with a client_id and client_secret, then registers ToolHive as the redirect URI. That setup happens once at the proxy layer, so clients such as VS Code or Claude Code don’t each need separate GitHub app registration.
ToolHive also handles MCP-side client registration for those clients. In practice, that removes some of the friction in MCP adoption because the MCP spec includes client registration paths such as DCR and CIMD, and those mechanisms aren’t widely implemented. ToolHive absorbs that protocol layer in the middle while GitHub continues to use its standard OAuth flow.
Another deployment choice concerns session storage. For testing or a quick proof of concept, the auth server can use in-memory storage. For deployments that need persistent session storage across restarts, ToolHive can use Redis. The tradeoff is straightforward: in-memory storage is simpler to stand up, but session state disappears if ToolHive restarts. Redis adds setup overhead, but the stored tokens survive restarts during upgrades or infrastructure interruptions.
There’s also one requirement on the wrapped MCP server itself. It needs to accept the credential provided in the proxied request and pass it through to GitHub as part of its normal request handling.
Advantages of using ToolHive over a shared credential
In a shared deployment, ToolHive changes both the credential model and the operating model. The advantages show up in a few concrete areas:
- Per-user attribution: GitHub activity remains tied to the user behind the request, which preserves auditability and avoids collapsing all actions into one shared identity.
- Scoped access without a shared secret: Access can stay aligned to the user and the operation instead of broadening one long-lived credential to satisfy every request across the deployment.
- Centralized auth handling: OAuth handling, session state and token exchange stay in ToolHive rather than being implemented in each GitHub-connected server.
- Dynamic client registration support: ToolHive handles client registration in the proxy layer, which reduces separate GitHub-side setup across clients. Since dynamic client registration is still rarely supported by IDPs in practice, ToolHive manages that protocol requirement in the middle.
- Transparent token refresh: ToolHive can transparently refresh credentials in the background so users don’t need to repeat the sign-in flow unnecessarily.
GitHub access without a shared credential
The result is a GitHub MCP server authorization path that preserves user-linked access in a shared deployment without pushing OAuth handling and token management into the server itself. For more information about using ToolHive for GitHub MCP server authorization, you can email us at hello@stacklok.com or engage via our Discord.
Frequently asked questions
Working to get authorization right? Here are some additional questions you should ask:
After GitHub sign-in, the client keeps a ToolHive-issued session credential. On later requests, that credential tells ToolHive which GitHub session to resume. ToolHive then retrieves the stored GitHub tokens for that session and continues the request with the GitHub credential path the MCP server needs.
ToolHive moves client registration to the proxy layer so each MCP client doesn’t need its own GitHub-side setup. That’s important because MCP defines registration paths such as DCR and CIMD, and those aren’t broadly supported. ToolHive handles that step while GitHub continues to use a standard OAuth configuration.
Dynamic Client Registration, or DCR, is an OAuth standard for registering a client with an authorization server at runtime instead of pre-registering every client by hand. RFC 7591 defines that flow as a way for a client to send its metadata to the authorization server and receive a client identifier and related registration data in return. In the GitHub ToolHive setup, ToolHive handles the client-registration step at the proxy layer instead of pushing that setup into each client.
CIMD stands for Client ID Metadata Document. It is an IETF draft that describes a way for an OAuth client to identify itself using a URL that points to a metadata document instead of relying on prior registration at each authorization server. The draft frames this as a way to avoid manual registration when a client interacts with authorization servers it doesn’t already have a relationship with. In the context of MCP, CIMD matters because it’s one of the client-registration paths the ecosystem is moving toward, even though support is still emerging and the specification remains a draft.
April 20, 2026