Summary
Grok Build (xAI's coding TUI on the Mac) is a second MCP client of the broker,
alongside the Claude apps. It connects as its own broker app-key
(my_company:grok) with a separate token store and a narrower allow-list
than app1, so a compromise of Grok's key cannot reach the Claude client's
connectors — and vice versa. Added 2026-07-11; hardened + documented 2026-07-12.
Key points
- Its own key, its own allow-list.
my_company:grokhas scopes[proxy, status](no admin) andallowed_connectors: [notion_api, slack, github]only — it cannot reach gcp/tailscale/gitlab/etc. Separate app-key ⇒ separate encrypted token store, isolated fromapp1. - How it authenticates. Grok's
~/.grok/config.tomlpoints three MCP servers athttps://bobsmcp.uk/proxy/{notion_api,slack,github}/with headersX-Broker-Key: ${GROK_BROKER_KEY}+X-App-Id: my_company:grok. The key is the per-app broker key (br_…, not the admin key), stored in~/.grok/broker.env(mode 600) and referenced via env var — never inline, never committed to git (verified: the key is in zero tracked files). - Read-only GitHub (per-app OAuth scope override). A new broker capability:
an app's connector config may set
scopesto override the connector default for that app only.grok.githubrequests[read:user, read:org]whileapp1.githubkeeps the fullrepodefault. So Grok's GitHub token cannot write anything. (See the caveat below — this is metadata-only today; a read-only fine-grained-PAT path for private-repo contents is designed but not yet built.) - Network path. Either the Cloudflare Tunnel hostname (
bobsmcp.uk) or a Tailscale SSH local-forward to127.0.0.1:8002. The broker admin key is never placed in Grok's config.
The per-app scope override (how it works)
AppConnectorCredentials.scopes (optional) overrides ConnectorMeta.scopes for a
single app. The override wins in both the OAuth authorize request (what scope
is asked for) and the recorded connection (what the token is allowed to do); empty
= connector default. This is the security-load-bearing path — the requested
scope bounds the resulting token — and it is covered by unit tests
(tests/test_broker.py). Committed to the fork (d28436f) after being found live
but uncommitted on the VM (a latent deploy hazard, now removed).
Caveats & next steps
- GitHub
[read:user, read:org]grants no repo access at all. Classic GitHub OAuth has no "read private repos only" scope —repois the only key to private repos and it is read+write. Dropping it makes Grok's GitHub metadata-only (org/user info), not "read your code." To let Grok read private code without write, the connector needs a per-app fine-grained PAT (contents:read, metadata:read) — astatic_tokenpath that bypasses OAuth for that app. Designed, not yet built. - Connections not yet established. Grok holds a valid key but has not run the
OAuth connect flow for its connectors, so its tools return nothing until each is
connected under
my_company:grok. - Slack is unconfigured for everyone — the
slackconnector is enabled but no Slack app credentials exist yet (SLACK_CLIENT_ID/SECRETempty), so it won't work until a Slack app is created and its secret stored in Secret Manager.
Related
Sources
wiki/projects/gcp-mcp-standalone/grok-build-client.md · git is the source of truth