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 #
- create a google oauth web application client, not a desktop client.
- register
<origin>/.auth/colab/callbackas its authorized redirect uri. - set
COLAB_GOOGLE_CLIENT_IDandCOLAB_GOOGLE_CLIENT_SECRET, then restart. - 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.