Skip to content

Add proxy_file MCP injection mode (token-less proxy-backed --mcp-config) and use it for Claude#74

Open
maxlamagna wants to merge 3 commits into
bcurts:mainfrom
maxlamagna:proxy-file-stale-session
Open

Add proxy_file MCP injection mode (token-less proxy-backed --mcp-config) and use it for Claude#74
maxlamagna wants to merge 3 commits into
bcurts:mainfrom
maxlamagna:proxy-file-stale-session

Conversation

@maxlamagna

Copy link
Copy Markdown
Contributor

What & why

File-config CLIs (Claude, mcp_inject = "flag") bake the server token into a --mcp-config file read once at startup. After an idle crash-timeout the server rotates that token; the wrapper re-registers and mints a new one, but the CLI doesn't re-read the file mid-session, so it keeps presenting the dead token → stale or unknown authenticated agent session until a manual /mcp reconnect. Proxy-routed agents (proxy_flag, e.g. Codex) don't hit this, because the wrapper swaps the token on the live McpIdentityProxy.

This adds a proxy_file mode that gives file-config CLIs the same live-token path, and defaults Claude to it.

Closes #73.

Changes

  • wrapper.py — new _apply_mcp_inject branch proxy_file: writes the --mcp-config file pointing at the proxy URL with no token (the proxy injects the live token) while still merging project MCP servers (reuses _write_claude_mcp_config + _read_project_mcp_servers). Raises ValueError if proxy_url is missing. Added proxy_file to _VALID_INJECT_MODES and to needs_proxy. Defaulted Claude (_BUILTIN_DEFAULTS["claude"]) from flagproxy_file.
  • tests/test_wrapper_mcp_config.py — tests that proxy_file writes the proxy URL, no baked token, and a surviving non-agentchattr project server; plus the missing-proxy_url guard.
  • config.toml — document proxy_file in the injection-modes comment.

On re-register, _rewrite_mcp_config is already a no-op for proxy-backed modes, so the token-less file is left untouched while the proxy updates its token live. No change to proxy_flag, flag, or any other agent's wiring.

Behavior

  • Claude now routes through the identity proxy: a server-side token rotation no longer produces a stale session and needs no /mcp reconnect.
  • Project MCP servers are still merged into Claude's config (unchanged from flag).
  • *-2 re-registration naming (the 30s GRACE_PERIOD reclaim) is unchanged and intentionally out of scope here.

Testing

  • python -m unittest tests/test_wrapper_mcp_config.py10/10.
  • End-to-end (isolated server): real claude on a proxy_file config called a tool through the proxy (Online: claude); after a forced token rotation (deregister → re-register → proxy token swapped) the same unchanged config still worked (Online: claude-2) with unity-mcp merge still present.

Notes / open to feedback

  • Happy to split "default Claude to proxy_file" into a separate commit from the new-mode addition.
  • The provided agentchattr-proxy-file.patch is git apply-clean against main.

Diff

See agentchattr-proxy-file.patch (≈78 insertions across wrapper.py, tests/test_wrapper_mcp_config.py, config.toml).

- Add whitelisted per-agent env-var overrides (AGENTCHATTR_AGENT_<KEY_UPPER>
  overrides agent_cfg[<key_lower>], restricted to {cwd, mcp_settings_path})
  so launchers can scope a wrapper to one repo without touching shared
  config.toml.
- Add AGENTCHATTR_REPO_SLUG: when set and non-empty, tmux session is named
  agentchattr-{slug}-{assigned_name} instead of agentchattr-{assigned_name},
  so two repos' wrappers don't evict each other.

Both env vars are opt-in; behaviour unchanged when unset.

Candidate for upstream PR pending bcurts feedback on the issue.
Replaces the runtime mutation that agentchattr_apply_profile was doing on
every launch with a committed default. Per-repo cwd / mcp_settings_path
overrides happen at runtime via the AGENTCHATTR_AGENT_* env vars added
in the previous commit; cwd stays at ".." so bundled scripts work.

Codex: mcp_inject = "proxy_flag" + mcp_proxy_flag_template with 12-tool
approval template (chat_channels..chat_who) so codex doesn't prompt at
runtime for known agentchattr tools.

Gemini (Antigravity migration): command = "env" (so the launcher can
scope AGY_CLI_DISABLE_AUTO_UPDATE=1 via env(1)); mcp_inject = "settings_file";
mcp_settings_path = "~/.gemini/config/mcp_config.json" (upstream-style default
so bundled start_gemini.sh works); mcp_transport = "http";
mcp_http_key = "serverURL" (Antigravity rejects httpUrl and url, requires
camelCase serverURL); mcp_merge_project = true (preserves prior built-in
default since explicit mcp_inject drops defaults).

Local-only: not for upstream PR. Antigravity is Google-specific.
… (no /mcp reconnect after idle crash-timeout)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant