Files
github--github-mcp-server/docs/streamable-http.md
T
Sam Morrow 8ec62491c6 Add confirmed repository deletion tool (#3076)
* feat(repos): add confirmed repository deletion

Add a destructive delete_repository tool that requires an exact owner/repo confirmation through multi-round-trip elicitation. Gate the tool to MCP protocol 2026-07-28 and newer across local and remote transports.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8

* refactor(inventory): generalize tool availability guards

Gate protocol-restricted tools on required elicitation capabilities and enforce direct calls inside the registered handler so SDK result finalization remains intact.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8

* feat(http): protect MRTR request state

Seal repository deletion targets for self-hosted HTTP with a stable AES-256-GCM key. Hide only delete_repository when no key is configured and expose an optional sealer interface for remote integrators.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8

* fix(repos): expire deletion confirmations

Bind sealed repository deletion state to the immutable repository ID and a ten-minute expiry. Re-check identity before deletion so replay cannot affect a recreated repository.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8

* fix(http): preserve tool and scope restrictions

Apply static allowlists before removing unavailable tools and fail closed on invalid configured tool names. Model independent OAuth requirements as conjunctive groups so repository deletion requires both delete_repo and repo.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8

* fix(repos): require protected confirmation state

Give stdio a process-local request-state sealer and make deletion fail closed without one. Preserve legacy any-of OAuth behavior globally while documenting and enforcing delete_repository's conjunctive delete_repo and repo requirements.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8

* fix(oauth): request repository deletion scope

Include delete_repo in the supported OAuth scope set used by stdio login, HTTP protected-resource metadata, and tool filtering.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8

* fix(oauth): require deletion scope opt-in

Keep delete_repo in protected-resource discovery for step-up authorization while excluding it from the default stdio OAuth grant.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8

* refactor(oauth): derive scope sets from catalog

Generate protected-resource supported scopes and the lower-risk default OAuth grant from one canonical scope definition list.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8

* refactor(scopes): own OAuth scope catalog

Move supported and default OAuth scope policy into pkg/scopes so protected-resource metadata and stdio grants derive from the scope domain package.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8

* fix(scopes): require workflow scope opt-in

Keep workflow and codespace in protected-resource discovery while excluding both from the default OAuth grant alongside delete_repo.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8

---------

Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8
2026-08-18 14:50:38 +02:00

4.7 KiB

Streamable HTTP Server

The Streamable HTTP mode enables the GitHub MCP Server to run as an HTTP service, allowing clients to connect via standard HTTP protocols. This mode is ideal for deployment scenarios where stdio transport isn't suitable, such as reverse proxy setups, containerized environments, or distributed architectures.

Features

  • Streamable HTTP Transport — Full HTTP server with streaming support for real-time tool responses
  • OAuth Metadata Endpoints — Standard .well-known/oauth-protected-resource discovery for OAuth clients
  • Scope Challenge Support — Automatic scope validation with proper HTTP 403 responses and WWW-Authenticate headers
  • Scope Filtering — Restrict available tools based on authenticated credentials and permissions
  • Custom Base Paths — Support for reverse proxy deployments with customizable base URLs

Running the Server

Basic HTTP Server

Start the server on the default port (8082):

github-mcp-server http

The server will be available at http://localhost:8082.

With Scope Challenge

Enable scope validation to enforce GitHub permission checks:

github-mcp-server http --scope-challenge

When --scope-challenge is enabled, requests with insufficient scopes receive a 403 Forbidden response with a WWW-Authenticate header indicating the required scopes.

Repository deletion and request-state encryption

The delete_repository tool uses multi-round-trip elicitation and carries its confirmed target through client-held request state. To expose this tool in HTTP mode, configure a stable 32-byte encryption key encoded with standard Base64:

export GITHUB_MCP_SERVER_MRTR_STATE_KEY="$(openssl rand -base64 32 | tr -d '\n')"
github-mcp-server http

Use the same key on every replica that may handle a retry. Keep it secret and stable during deployments; changing it invalidates confirmations already in flight. If the variable is absent, delete_repository is not exposed by the HTTP server. If it is present but malformed, the server refuses to start.

This self-hosted key is independent of keys used by the hosted remote server. Integrators can provide their own request-state sealer through the exported github.RequestStateSealer interface and expose it from their tool dependencies through github.RequestStateSealerProvider without changing their key format.

With OAuth Metadata Discovery

For use behind reverse proxies or with custom domains, expose OAuth metadata endpoints:

github-mcp-server http --scope-challenge --base-url https://myserver.com --base-path /mcp

The OAuth protected resource metadata's resource attribute will be populated with the full URL to the server's protected resource endpoint:

{
  "resource_name": "GitHub MCP Server",
  "resource": "https://myserver.com/mcp",
  "authorization_servers": [
    "https://github.com/login/oauth"
  ],
  "scopes_supported": [
    "repo",
    ...
  ],
  ...
}

This allows OAuth clients to discover authentication requirements and endpoint information automatically.

Behind a Trusted Proxy (advanced)

By default, the server ignores the X-Forwarded-Host and X-Forwarded-Proto headers when constructing OAuth resource metadata URLs, so an untrusted client cannot influence the URL advertised to MCP clients. For most deployments, setting --base-url to the externally visible URL is the right approach.

If the server sits behind an internal forwarder that you fully control (for example, an in-cluster gateway that needs to preserve the originating hostname per request), you can opt into honoring those headers:

github-mcp-server http --trust-proxy-headers

Equivalent environment variable: GITHUB_TRUST_PROXY_HEADERS=1. Only enable this when the upstream proxy is trusted to set or strip these headers; otherwise prefer --base-url. When --base-url is set, it always takes precedence and --trust-proxy-headers has no effect.

Client Configuration

Using OAuth Authentication

If your IDE or client has GitHub credentials configured (i.e. VS Code), simply reference the HTTP server:

{
  "type": "http",
  "url": "http://localhost:8082"
}

The server will use the client's existing GitHub authentication.

Using Bearer Tokens or Custom Headers

To provide PAT credentials, or to customize server behavior preferences, you can include additional headers in the client configuration:

{
  "type": "http",
  "url": "http://localhost:8082",
  "headers": {
    "Authorization": "Bearer ghp_yourtokenhere",
    "X-MCP-Toolsets": "default",
    "X-MCP-Readonly": "true"
  }
}

See Remote Server documentation for more details on client configuration options.