On this page

Commander MCP services - umbrellas, commands, scopes and workflows

The commander-mcp gateway is the half of Commander's MCP story that faces inbound: a chat client - Claude on the web or desktop, ChatGPT, MCP Inspector, any client that speaks Streamable HTTP - signs in once and operates Commander through a small set of umbrella tools. The other half, Commander handing MCP connections to the agents it launches, is described under the application page.

At this version the gateway serves 15 umbrella tools with 70 commands - 51 of them read-only, 4 destructive - plus two resources and one prompt per persona. It is published at <commander origin>/mcp (for example https://commander-dev.myorg.ai/mcp), with OAuth discovery served for that path. Commander proxies the path to the gateway process (commander-mcp-dev on dev, commander-mcp on prod), so a client needs one hostname and nothing else.

Three boxes a call crosses

  1. The MCP client holds an access token minted by the gateway's own OAuth server after the operator signed in on the consent page and ticked scopes.
  2. The gateway verifies the token locally, resolves the caller's role, checks scope → phase → role, validates the command's parameters, and relays over the loopback to Commander with a service token - acting as the signed-in subject, which Commander logs as acting=<subject>.
  3. Commander answers the same REST API the browser uses. The gateway redacts the result (tokens, keys, PEM blocks, ANSI, invisible characters), frames anything agent-written as untrusted content, caps its size, and writes one audit row per call - denials included.

The umbrellas

Every tool is an umbrella: one MCP tool name, a command enum, and per-command parameters spelled out in the tool description. Call _hello first - it returns identity, role, effective phases and scopes, and a plan for the intent you state. Commands marked write need a phase above 0; destructive commands need confirm: true and are refused on prod.

umbrellaphasecommands
_hello0single call - identity, capabilities, a plan
projects0list · get · environments · update (write)
sessions0list · get · status · rename (write) · archive · restore · restart (destructive) · kill (destructive)
transcripts0search · messages · session_log · stats · kinds
artifacts0list · get · raw · rescan (write)
personas0list · get · skill_packs · update · bind_skills · bind_subagents (writes)
git0status · log · branches · commit_details · file_at_ref · diff · file_history - read-only; committing is not exposed
deploy1status · history · releases · release · rollback_candidates - read-only; promote and rollback are never exposed
workboard0tasks.list · tasks.create · tasks.update · tasks.delete (destructive) · notes.list · notes.patch · prompts.list · prompts.create · prompts.delete (destructive) · shots.list · roadmap · changelog
usage0summary · hourly · window · session
health0heartbeat · logs · activity · system · disk · deps · guardian
settings1tunables.list · tunables.set (admin) · settings.get - registry tunables only; secrets are never readable
access0me · roles · principals · grant · revoke - who may do what (admin scope for the last three)
search0single call - the ChatGPT-shaped full-text façade over projects, sessions, artifacts and prompts
fetch0single call - the full record behind a search result id

Resources: commander://project/{slug}/sessions (a project's sessions; slug, short id or uuid) and commander://session/{id}/brief (Commander's own redacted conversation log). Prompts: every persona is offered as persona:<id>; the body is redacted, size-capped and scope-checked before it leaves.

Not on the list, on purpose: promote, rollback, pm2 restart, the Password Vault, Integrations, service accounts, license activation, the login seam and file uploads. Those remain the operator's hand in the browser.

Three gates every command passes

scopeunlocksphase
commander:readevery read-only command, both resources, persona prompts, search and fetch0
commander:workboardprojects.update · sessions.rename · artifacts.rescan · persona writes · workboard writes1
commander:sessions.writesessions archive / restore / restart / kill2
commander:git.writereserved - git stays read-only today1
commander:terminalreserved - no handler in the registry2
commander:adminsettings.tunables.set, access grants, plus everything above1
rolephasesscope ceiling
visitor (default)0read
editor0, 1read · workboard · git.write
operator0, 1, 2+ sessions.write · terminal
admin0, 1, 2+ admin

Workflows

Connecting Claude (web or desktop)

  1. Add the connector - Settings → Connectors → Add custom connector → <commander origin>/mcp.
  2. Discovery - the client reads the protected-resource metadata (RFC 9728) and the authorization-server metadata (RFC 8414) the gateway publishes for its path.
  3. Registration - dynamic client registration (RFC 7591), bounded by rate, count and redirect-host rules; PKCE-only public clients.
  4. Consent - the gateway's login page takes the Commander app password and shows the requested scopes as checkboxes; grant a subset if you like.
  5. Token - authorization code → ES256 access token (1 h by default) + rotating refresh token (30 d). A replayed code revokes exactly its own lineage.
  6. Tools appear - namespaced by umbrella; destructive commands carry a hint so Claude asks before sending confirm: true.

The step-by-step with screenshots and troubleshooting is on Connect a chat client to Commander over MCP.

Connecting ChatGPT

Create the connector with the same URL and OAuth. Standard connectors and Deep Research use only search and fetch; Developer Mode exposes the full umbrella set under the same scopes, phases and roles.

One tool call, end to end

Rolling out (operator, in short)

  1. Mint the service token with scripts/mcp-gateway-setup.js --instance dev - it lands in secrets.env and the Password Vault, never in chat or git.
  2. Start the gateway process with pm2 (--only commander-mcp-dev); Commander itself is not restarted.
  3. Publish it: mcp_gateway_enabled, mcp_gateway_public_url (<origin>/mcp), and the reverse-proxy contexts for /mcp and the well-known discovery paths.
  4. Phase 0 first, for as long as it takes to trust the audit trail; then 0,1 and 0,1,2 on dev. Phases are read at gateway boot - restart the gateway, not Commander.
  5. Revoke a client or subject from the runbook when needed; every token lineage is traceable to the code that issued it.

Tunables the operator owns

All live under Settings → Advanced → MCP gateway and resolve settings row → environment → named default.

settingdefaultwhat it governs
mcp_gateway_enabledfalsewhether Commander publishes the gateway (proxy + client-config)
mcp_gateway_public_url-the URL clients are told to use (<origin>/mcp)
mcp_gateway_upstreamhttp://127.0.0.1:3212where Commander proxies /mcp to
mcp_gateway_proxy_connect_timeout_ms5000connect budget for that proxy hop
mcp_gateway_enable_phases0tool phases served; read at gateway boot
mcp_gateway_default_rolevisitorrole for a connector with no grant
mcp_gateway_roles-JSON override of the role catalogue
mcp_gateway_access_token_ttl_s3600access token lifetime
mcp_gateway_refresh_token_ttl_s2 592 000refresh token lifetime (30 d), rotating
mcp_gateway_code_ttl_s300authorization-code lifetime
mcp_gateway_dcr_enabledtruedynamic client registration on/off
mcp_gateway_login_rate_max10consent-page login attempts per window
mcp_gateway_rate_limit_per_min60tool calls per subject per minute
mcp_gateway_result_max_bytes65 536cap on any single tool result
mcp_gateway_upstream_timeout_ms15 000loopback call budget to Commander
mcp_gateway_request_logtrueCommander logs acting=<subject> on relayed requests
mcp_gateway_audit_detailhashhash · args · args+result - how much of each call the audit keeps
mcp_gateway_audit_max_bytes16 384cap on a kept argument object / result text
mcp_gateway_audit_detail_retention_days14after this, kept bodies are blanked (rows and hashes stay)

The other direction: Commander as a consumer

Commander also uses MCP servers. The broker resolves each credential path into one resolved connection that the per-session .mcp.json writer consumes when an agent is launched, and revokes tokens at session end. The gateway described here never touches that path; the two share only Commander's settings and audit conventions.

Reserved, not built

The terminal umbrella and git.commit have scopes but no handlers. ChatGPT Apps SDK widgets are a separate phase.

You've seen the proof

Ready for a number? Scope your deployment and we'll price it against your own economics.

Get your quote →