mcp for colab
README.md

hosted setup #

the gateway is a local fork of sigbit/mcp-auth-proxy; see upstream and its license. it owns downstream mcp oauth and owner sessions; google account linking is separate from that login.

npm ci
npm run build:gateway
cp .env.example .env
# fill in .env, then export its values in your shell
set -a
. ./.env
set +a
npm run serve

use a tls reverse proxy in front of the loopback listener. rate-limit the public /.idp/register endpoint (for example 1/minute, burst 3) and /.idp/token (5/second, burst 20); client registrations persist, so do not expose unrestricted registration to floods. keep oauth callback queries, headers, and bodies out of proxy logs.

EXTERNAL_URL must be your public https origin; TRUSTED_PROXIES must identify only your reverse proxy. set the oidc discovery url, client id/secret, and MCP_ALLOWED_SUBJECT to the exact subject your identity provider returns. register <origin>/.auth/oidc/callback with that provider. the default oidc subject field is /sub.

connect google #

  1. create a google oauth web application client, not a desktop client.
  2. register <origin>/.auth/colab/callback as its authorized redirect uri.
  3. set COLAB_GOOGLE_CLIENT_ID and COLAB_GOOGLE_CLIENT_SECRET, then restart.
  4. visit <origin>/.auth/colab, sign in as the gateway owner, and connect google.

the gateway requests offline access with s256 pkce, verifies google's userinfo response, and checks read-only colab access before saving credentials. optionally set COLAB_GOOGLE_ACCOUNT to an expected google email address. a cancelled or failed connection keeps the previous credential. credentials are stored atomically with mode 0600 in the private state directory; they never go to the mcp client or the browser.

the default google scopes are openid and https://www.googleapis.com/auth/userinfo.email, following the official colab cli's documented runtime-api requirement. custom web-client access to colab still needs a real sign-in test; mocked oauth tests do not prove google accepts your client. COLAB_GOOGLE_SCOPES can override the space-separated scope list if needed. google consent screens in testing mode can expire refresh tokens after seven days; configure the app's publishing status appropriately.

multiple accounts #

connect more google accounts from <origin>/.auth/colab; the google account chooser appears on each connection. the owner-only page shows emails and opaque ids. reconnecting the same google identity updates its credentials without changing its id, even if its email changes.

mcp clients see colab_accounts: stable, independently random 256-bit ids, not emails or email hashes. use colab_usage(account_id=...) to inspect each account and choose an explicit account_id for colab_launch. both require a choice when multiple accounts are connected. colab_list lists all accounts, or filters by account_id; partial failures appear in errors without hiding working accounts. discovery itself does not verify token health.

runtime ids returned by the hosted pool include their account binding. pass the whole id to execute, files, interrupt, kernels, and stop. missing or removed accounts never substitute another account, and an uncertain allocation never triggers automatic failover. quotas remain separate. all eleven tools retain readOnlyHint: true by convention, including mutating operations.

credential storage and migration #

COLAB_MANAGED_CREDENTIALS defaults to $DATA_PATH/colab-google.json. the pool is stored beside it as colab-google.json.accounts.json: a versioned, atomic 0600 file in the private state directory, capped at 16 accounts and 1 MiB. the gateway is its only writer; workers notice replacement and refresh tokens in memory, separately per account. an invalid store fails closed.

on upgrade, an existing managed single-account credential is imported once, without changing the original file. a verified reconnect matching its old email adopts google's immutable subject, retaining its id. the original file remains private rollback material; back up the pool too. removing an account from the pool does not erase that historical copy, revoke google consent, or stop its runtimes. stop runtimes before removal and revoke access in google to invalidate retained credentials. removing the last account leaves an authoritative empty store, never resurrecting the old account.

before a pool exists, the legacy single-account path still works, including a read-only COLAB_CREDENTIALS fallback; it uses the non-identifying default selector. desktop login remains single-account. once a pool exists, its records pin their own google clients and override token or fallback environment settings. do not set COLAB_ACCESS_TOKEN with browser login.

state and clients #

DATA_PATH defaults to ~/.local/share/colab-mcp and must have mode 0700. keep this directory across upgrades: it contains the gateway database, session key, signing key, and connected google credential. use service credentials or a secret manager for client secrets; never add them to this checkout.

by default, mcp client registration accepts canonical https callbacks on google's three exact oauth relay origins (production, sandbox, test). set MCP_REDIRECT_PREFIXES explicitly for other clients; entries are comma-separated, parsed origins/path prefixes, not wildcard strings. an empty policy fails closed. all clients require s256 pkce, and every mcp access token must match the owner and resource audience. changing the allowed registration paths does not permit an unregistered callback during authorization.

run npm test for the node server and npm run test:gateway for the go gateway. npm run build also produces the optional standalone node-side binary; put it beside colab-mcp-gateway and run ./dist/colab-mcp serve.