diff --git a/examples/github-mcp-proxy-demo/README.md b/examples/github-mcp-proxy-demo/README.md index fcb9cc7..2a17633 100644 --- a/examples/github-mcp-proxy-demo/README.md +++ b/examples/github-mcp-proxy-demo/README.md @@ -27,7 +27,7 @@ Every `tools/call` request from the MCP client routes through Vaara before reach ## Prerequisites - Python 3.10+ -- Docker installed and running (the official GitHub MCP server ships as the OCI image `ghcr.io/github/github-mcp-server`) +- The `github-mcp-server` binary on disk. Either build from source (`go install github.com/github/github-mcp-server/cmd/github-mcp-server@latest` produces a stdio-capable binary, no external runtime required) or use the OCI image `ghcr.io/github/github-mcp-server` if you already run Docker. - A [GitHub Personal Access Token](https://github.com/settings/personal-access-tokens/new) with the scopes you want the agent to be able to use (read-only is a sensible starting point, widen later as your trust grows) - Claude Code or any other MCP-capable client @@ -41,18 +41,14 @@ pip install vaara ### 2. Replace your MCP server entry with the Vaara proxy -Before. Claude Code config pointing directly at the GitHub MCP server: +Before. Claude Code config pointing directly at the GitHub MCP server binary: ```json { "mcpServers": { "github": { - "command": "docker", - "args": [ - "run", "-i", "--rm", - "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", - "ghcr.io/github/github-mcp-server" - ], + "command": "/path/to/github-mcp-server", + "args": ["stdio"], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_your_token_here" } @@ -61,7 +57,7 @@ Before. Claude Code config pointing directly at the GitHub MCP server: } ``` -After. Claude Code config pointing at the Vaara proxy, which spawns the same GitHub MCP server as a subprocess: +After. Claude Code config pointing at the Vaara proxy, which spawns the same GitHub MCP server binary as a subprocess: ```json { @@ -70,13 +66,8 @@ After. Claude Code config pointing at the Vaara proxy, which spawns the same Git "command": "python", "args": [ "-m", "vaara.integrations.mcp_proxy", - "--upstream", "docker", - "--upstream-arg", "run", - "--upstream-arg", "-i", - "--upstream-arg", "--rm", - "--upstream-arg", "-e", - "--upstream-arg", "GITHUB_PERSONAL_ACCESS_TOKEN", - "--upstream-arg", "ghcr.io/github/github-mcp-server", + "--upstream", "/path/to/github-mcp-server", + "--upstream-arg", "stdio", "--db", "/path/to/github_audit.db" ], "env": { @@ -89,6 +80,8 @@ After. Claude Code config pointing at the Vaara proxy, which spawns the same Git The proxy inherits the environment, so the GitHub PAT flows through to the upstream MCP server unchanged. The upstream sees the same env it would see in the direct setup. +If you run the upstream via Docker instead of a local binary, swap `--upstream /path/to/github-mcp-server --upstream-arg stdio` for `--upstream docker --upstream-arg run --upstream-arg -i --upstream-arg --rm --upstream-arg -e --upstream-arg GITHUB_PERSONAL_ACCESS_TOKEN --upstream-arg ghcr.io/github/github-mcp-server`. The proxy shape is the same. The only difference is whether Docker wraps the binary or not. + A full example config lives at [`claude_code_config.example.json`](claude_code_config.example.json) in this directory. ### 3. Restart your MCP client and use it normally @@ -149,10 +142,10 @@ The PDF output is the format a Notified Body or internal compliance auditor read ## Troubleshooting -- **The proxy hangs on startup.** The upstream Docker container is probably failing its initialize handshake. Check the proxy's stderr (the upstream's stderr is forwarded through). Common cause: missing or invalid `GITHUB_PERSONAL_ACCESS_TOKEN`. -- **`docker: command not found`.** The proxy spawns `docker run` as the upstream. Install Docker, or swap the upstream for the [self-built binary](https://github.com/github/github-mcp-server#build-from-source) and point `--upstream` at the binary path. +- **The proxy hangs on startup.** The upstream is probably failing its initialize handshake. Check the proxy's stderr (the upstream's stderr is forwarded through). Common cause: missing or invalid `GITHUB_PERSONAL_ACCESS_TOKEN`. +- **`github-mcp-server: command not found`.** Build it with `go install github.com/github/github-mcp-server/cmd/github-mcp-server@latest` and point `--upstream` at the resulting binary in `$(go env GOBIN)` or `$(go env GOPATH)/bin`. - **Every tool call is blocked.** Default fail-closed policy. Define a policy file scoped to the GitHub MCP tool catalog, or relax for read-only tools as a starting point. -- **Rate limits surface as upstream errors.** GitHub rate limits hit the upstream container, not the proxy. The proxy records the failure in the audit chain and returns the upstream's error to the client. +- **Rate limits surface as upstream errors.** GitHub rate limits hit the upstream, not the proxy. The proxy records the failure in the audit chain and returns the upstream's error to the client. ## The same pattern in front of any MCP server diff --git a/examples/github-mcp-proxy-demo/claude_code_config.example.json b/examples/github-mcp-proxy-demo/claude_code_config.example.json index d0e301d..2b50ab5 100644 --- a/examples/github-mcp-proxy-demo/claude_code_config.example.json +++ b/examples/github-mcp-proxy-demo/claude_code_config.example.json @@ -1,8 +1,23 @@ { - "_comment": "Example Claude Code MCP config showing the Vaara proxy in front of GitHub's official MCP server (github/github-mcp-server). Set GITHUB_PERSONAL_ACCESS_TOKEN in your shell, or replace the env entry below with your own value. Copy the relevant block into your Claude Code mcp config.", + "_comment": "Example Claude Code MCP config showing the Vaara proxy in front of GitHub's official MCP server (github/github-mcp-server). The primary recipe uses the github-mcp-server binary directly, no Docker required. Build it with: go install github.com/github/github-mcp-server/cmd/github-mcp-server@latest. The _alternative_docker block below shows the Docker-wrapped variant if you prefer that runtime. Replace /path/to/... and the PAT with your own values.", "mcpServers": { "github-via-vaara": { + "command": "python", + "args": [ + "-m", "vaara.integrations.mcp_proxy", + "--upstream", "/path/to/github-mcp-server", + "--upstream-arg", "stdio", + "--db", "${HOME}/.vaara/github_audit.db", + "--agent-id", "claude-code-github" + ], + "env": { + "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_replace_with_your_token" + } + }, + + "_alternative_docker": { + "_comment": "Same proxy shape, with Docker wrapping the binary instead of running it directly. Use this only if you already run Docker. Requires the ghcr.io/github/github-mcp-server image (docker pull ghcr.io/github/github-mcp-server).", "command": "python", "args": [ "-m", "vaara.integrations.mcp_proxy", @@ -19,10 +34,6 @@ "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_replace_with_your_token" } - }, - - "_alternative_remote_http": { - "_comment": "GitHub also hosts a remote HTTP MCP server at https://api.githubcopilot.com/mcp/. Vaara's proxy is stdio-based and pairs with the local Docker server above. The HTTP variant would need a different bridge and is out of scope for this demo." } } }