Description
openab's ACP path forwards session/new and session/load to the agent with mcpServers: [] and no strictMcpConfig flag (src/acp/connection.rs:414 and :549). For claude-agent-acp, this means the spawned agent inherits whatever MCP servers its OAuth login carries — for a Claude session signed in to claude.ai, that's the cloud connectors (Linear, Notion, Slack, Drive, Calendar, Gmail, Heptabase, etc.).
Operators today have no way to opt out of that inheritance. Requesting an [agent].inherit_cloud_mcp_servers boolean in config.toml, default true so existing deployments keep their current behavior. Operators flip to false to suppress inheritance per deployment (which in openab's helm-chart-per-agent model is per-bot).
Use Case
The current behavior is genuinely wanted in some deployments and unwanted in others, which is why this should be a config knob and not a unilateral default change:
Inherit = true (default, current behavior)
- Personal / single-operator bot signed in to the operator's own claude.ai. The operator wants
@bot summarize my next 3 calendar events or @bot find Linear issues assigned to me to reach their own connectors. This is a feature, not a bug.
Inherit = false
- Multi-user community Slack/Discord bot. The operator OAuth-signed-in their account, but other users in the workspace shouldn't be able to query the operator's personal Notion / Drive / Gmail through the bot.
- Token-budget-sensitive deployments. Each cloud connector contributes its tool schemas to every prompt — typically ~90K tokens of
mcp__claude_ai__* tools the operator never intended to expose. For high-throughput bots that's real cost.
Proposed Solution
[agent]
command = "claude-agent-acp"
working_dir = "/home/node"
# inherit_cloud_mcp_servers = true # default; omit to keep current behavior
Plumbing (~30 lines):
-
src/config.rs — add field to AgentConfig:
#[serde(default = "default_inherit_cloud_mcp_servers")]
pub inherit_cloud_mcp_servers: bool,
with fn default_inherit_cloud_mcp_servers() -> bool { true }. Cannot use #[serde(default)] because bool::default() is false, which would invert the intended default.
-
src/acp/connection.rs — session_new and session_load accept the flag and, when false, attach the strict marker to the JSON-RPC payload:
{
"cwd": "...",
"mcpServers": [],
"_meta": { "claudeCode": { "options": { "strictMcpConfig": true } } }
}
-
src/acp/pool.rs — thread self.config.inherit_cloud_mcp_servers into the two callers.
-
config.toml.example and docs/config-reference.md — document the new field.
-
Two unit tests in src/config.rs (default-true parse; explicit-false parse).
Why this works without any claude-agent-acp upstream change. The createSession handler in claude-agent-acp reads params._meta.claudeCode.options into userProvidedOptions and spreads it into the SDK options object before the explicit override block (dist/acp-agent.js, around the const options = { systemPrompt, ..., ...userProvidedOptions, ..., cwd: params.cwd, ..., mcpServers: { ... }, ... } construction). strictMcpConfig is not in the override block, so the spread path carries it cleanly into the SDK call. Other agents (kiro / codex / gemini / copilot / cursor) ignore the _meta.claudeCode namespace, so the param is harmless when sent to non-Claude backends.
I've been running this behavior in production for several weeks via a runtime SDK overlay (patching strictMcpConfig: true directly into that same SDK options block) and can confirm cloud connectors are cleanly suppressed without other side effects. The proposed config-driven path eliminates the SDK overlay and routes the choice through the existing ACP _meta channel instead.
Happy to send a PR in this shape if the direction is acceptable. The change is intentionally narrow — no per-user MCP injection, no slash commands, no behavior change for any existing deployment.
Description
openab's ACP path forwards
session/newandsession/loadto the agent withmcpServers: []and nostrictMcpConfigflag (src/acp/connection.rs:414and:549). Forclaude-agent-acp, this means the spawned agent inherits whatever MCP servers its OAuth login carries — for a Claude session signed in to claude.ai, that's the cloud connectors (Linear, Notion, Slack, Drive, Calendar, Gmail, Heptabase, etc.).Operators today have no way to opt out of that inheritance. Requesting an
[agent].inherit_cloud_mcp_serversboolean inconfig.toml, defaulttrueso existing deployments keep their current behavior. Operators flip tofalseto suppress inheritance per deployment (which in openab's helm-chart-per-agent model is per-bot).Use Case
The current behavior is genuinely wanted in some deployments and unwanted in others, which is why this should be a config knob and not a unilateral default change:
Inherit =
true(default, current behavior)@bot summarize my next 3 calendar eventsor@bot find Linear issues assigned to meto reach their own connectors. This is a feature, not a bug.Inherit =
falsemcp__claude_ai__*tools the operator never intended to expose. For high-throughput bots that's real cost.Proposed Solution
Plumbing (~30 lines):
src/config.rs— add field toAgentConfig:with
fn default_inherit_cloud_mcp_servers() -> bool { true }. Cannot use#[serde(default)]becausebool::default()isfalse, which would invert the intended default.src/acp/connection.rs—session_newandsession_loadaccept the flag and, whenfalse, attach the strict marker to the JSON-RPC payload:{ "cwd": "...", "mcpServers": [], "_meta": { "claudeCode": { "options": { "strictMcpConfig": true } } } }src/acp/pool.rs— threadself.config.inherit_cloud_mcp_serversinto the two callers.config.toml.exampleanddocs/config-reference.md— document the new field.Two unit tests in
src/config.rs(default-true parse; explicit-false parse).Why this works without any
claude-agent-acpupstream change. ThecreateSessionhandler inclaude-agent-acpreadsparams._meta.claudeCode.optionsintouserProvidedOptionsand spreads it into the SDK options object before the explicit override block (dist/acp-agent.js, around theconst options = { systemPrompt, ..., ...userProvidedOptions, ..., cwd: params.cwd, ..., mcpServers: { ... }, ... }construction).strictMcpConfigis not in the override block, so the spread path carries it cleanly into the SDK call. Other agents (kiro / codex / gemini / copilot / cursor) ignore the_meta.claudeCodenamespace, so the param is harmless when sent to non-Claude backends.I've been running this behavior in production for several weeks via a runtime SDK overlay (patching
strictMcpConfig: truedirectly into that same SDK options block) and can confirm cloud connectors are cleanly suppressed without other side effects. The proposed config-driven path eliminates the SDK overlay and routes the choice through the existing ACP_metachannel instead.Happy to send a PR in this shape if the direction is acceptable. The change is intentionally narrow — no per-user MCP injection, no slash commands, no behavior change for any existing deployment.