Clients
Claude Code
Section titled “Claude Code”claude mcp add --transport http kode-gopher https://<host>/mcpThen run /mcp and authenticate. Claude Code receives its tokens on a localhost callback, the standard pattern for OAuth clients that run on your machine. That means the browser must reach the machine Claude Code runs on.
Claude Code on a remote machine
Section titled “Claude Code on a remote machine”When Claude Code runs over SSH or on a Cloud Workstation, the final redirect to http://localhost:<port>/callback lands on your laptop instead. Pin the port, then do one of these:
claude mcp add --transport http --callback-port 33418 kode-gopher https://<host>/mcp- Forward the port from your laptop to the remote machine:
ssh -L 33418:localhost:33418 <host>, or on Cloud Workstations,gcloud workstations start-tcp-tunnel ... <workstation> 33418 --local-host-port=localhost:33418. - Rewrite the URL. When the browser fails to load
http://localhost:33418/callback?code=..., replace justhttp://localhost:33418with an address that reaches the remote machine’s port 33418, such as the Cloud Workstations port proxyhttps://33418-<workstation-host>, and keep the rest of the URL.
MCP Inspector
Section titled “MCP Inspector”Connect to https://<host>/mcp with the Streamable HTTP transport, and use its OAuth flow.
Pre-registered clients
Section titled “Pre-registered clients”By default, any MCP client can register itself, by dynamic client registration or a Client ID Metadata Document. Before Google sign-in, each user sees a kode-gopher page that names the client and asks them to confirm.
To accept only clients you list, set OPEN_REGISTRATION=false and pass CLIENTS_FILE, a JSON array:
[ {"client_id": "inspector", "client_name": "MCP Inspector", "redirect_uris": ["http://localhost:6274/oauth/callback"]}]Pre-registered clients skip the confirmation page. Their redirect_uris must be https, http on a loopback host (localhost, 127.0.0.1, [::1]), or an app’s private-use scheme in reverse-DNS form, with a dot (com.example.app:/cb), as for a client that registers itself. kode-gopher refuses to start otherwise. A scheme without a dot, such as vscode:// or cursor://, doesn’t qualify.
CI and automation: client credentials
Section titled “CI and automation: client credentials”A client with a service_account is a client-credentials client. It gets access tokens with its secret, no browser, and its snippets run as that service account:
[ {"client_id": "ci", "client_secret": "<random>", "client_name": "CI", "service_account": "runner@<PROJECT_ID>.iam.gserviceaccount.com"}]curl -u ci:<secret> -d grant_type=client_credentials https://<host>/tokenRules for these clients:
- No redirect URIs: they can’t sign users in.
- Access tokens only: there’s no refresh token, so the client asks again with its secret.
- Scope and resource:
scopemay only bekode-gopher:execute, which is also the default, andresource, if sent, must be the MCP endpoint. - Revocation: removing the client from the file, changing its account, or rotating its secret revokes its tokens at the next request.
- IAM: kode-gopher needs
roles/iam.serviceAccountTokenCreatoron the account, as in service-account mode.
In Go, the MCP SDK’s extauth.ClientCredentialsHandler speaks this grant. To check it end to end, run scripts/smoketest-http.sh --client-credentials <file> with a file holding {"client_id", "client_secret"}.