feat(cli): substitute ${COMMONLY_AGENT_TOKEN} / ${COMMONLY_API_URL} in MCP config#238
Open
feat(cli): substitute ${COMMONLY_AGENT_TOKEN} / ${COMMONLY_API_URL} in MCP config#238
Conversation
… in MCP config
Lets users keep their checked-in env files free of secrets — the
wrapper substitutes the runtime token + instance URL at spawn time
from values it already has on hand (the saved token record).
Surfaced during the 2026-04-17 cross-agent demo: every spec referencing
commonly-mcp had to be hand-rewritten with the agent's runtime token
after attach, because the token is minted at attach time and only known
to the wrapper.
Recognised placeholders (substituted everywhere a string appears in the
MCP config — env values, command args, and url fields):
\${COMMONLY_AGENT_TOKEN} — per-(agent, pod) cm_agent_* runtime token
\${COMMONLY_API_URL} — instance URL the agent is attached to
\${COMMONLY_INSTANCE_URL} — alias for COMMONLY_API_URL
One-pass + literal substitution; no nested expansion, no shell quoting.
Unknown \${COMMONLY_*} placeholders are left intact so typos surface as
runtime MCP errors, not silent empty strings. Falsy ctx values are also
no-ops (placeholder preserved) so users can diagnose missing context.
Plumbing: performRun now passes runtimeToken + instanceUrl into the
adapter.spawn ctx; claude adapter passes them through to writeMcpConfig.
131/133 cli tests pass (6 new: 5 substitution + 1 ctx plumbing assertion;
2 skipped Linux-only paths).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Lets users keep their checked-in env files free of secrets. The wrapper substitutes the agent's runtime token + instance URL into the generated MCP config at spawn time, from values already on hand (the saved token record).
Why this is needed. Surfaced during the 2026-04-17 cross-agent demo validation: every env spec referencing
commonly-mcphad to be hand-rewritten with the agent'scm_agent_*token after attach, because the token is minted at attach time and only known to the wrapper. Without substitution, a shared/checked-in env file is unusable across agents.Recognised placeholders (substituted everywhere a string appears in the MCP config — env values, command args, and url fields):
${COMMONLY_AGENT_TOKEN}cm_agent_*runtime token${COMMONLY_API_URL}${COMMONLY_INSTANCE_URL}${COMMONLY_API_URL}Properties:
${COMMONLY_*}placeholders are left intact so typos surface as runtime MCP errors, not silent empty strings.Plumbing:
performRunnow passesruntimeToken+instanceUrlinto theadapter.spawnctx; claude adapter passes them through towriteMcpConfig.Example
After
commonly agent attach claude --env env.json --pod <id>, the same file works for every attached agent without manual editing.Test plan
cd cli && npm test— 131/133 passing (6 new: 5 substitution + 1 ctx plumbing; 2 skipped Linux-only)docs/REVIEW.mdcommonly-devwith placeholder env (no hardcoded tokens)Out of scope (deferred)
agent.askevents in the run loop. Was bundled with this work originally (see closed feat(cli): close cross-agent loop — auto-handle agent.ask + ${COMMONLY_AGENT_TOKEN} substitution #237), but pulled out: collapsing cross-agent talk into a hidden RPC backchannel undercuts Commonly's "shared social substrate" pitch. Default for agent↔agent should be DM-pod messaging (existing chat infra) — separate design discussion + ADR addendum.🤖 Generated with Claude Code