feat(acp): allow BUZZ_ACP_MCP_COMMAND to run several MCP servers - #3196
Open
noah-shipley-centric wants to merge 1 commit into
Open
feat(acp): allow BUZZ_ACP_MCP_COMMAND to run several MCP servers#3196noah-shipley-centric wants to merge 1 commit into
noah-shipley-centric wants to merge 1 commit into
Conversation
`build_mcp_servers` collapsed the whole MCP surface into a single server, so an agent could hold exactly one. `buzz-agent` never had that limit — `McpRegistry::spawn_all` takes a slice and enforces MAX_MCP_SERVERS (16) — the ceiling of one existed only here. One slot forces a real trade-off. An agent given a data MCP loses the tools it acts with: it can read, then has no way to reply. Observed with an agent wired to a remote data MCP, which reasoned itself into a corner mid-turn — "I don't have shell access ... there's no buzz tool exposed here directly" — and silently produced no output, because the slot that previously carried its dev tools now carried the data bridge. `--mcp-command` / `BUZZ_ACP_MCP_COMMAND` now accepts a comma-separated list, matching how `--agent-args` / `BUZZ_ACP_AGENT_ARGS` already parses in the same struct. A single value behaves exactly as before, so existing configurations are unaffected. Two details worth noting: - Blank entries are skipped, so the `""` default (and a stray trailing comma) still yields no servers rather than a bogus one. - Names are derived from the command's file stem, and `spawn_all` rejects duplicates — so colliding stems (`/opt/a/bridge`, `/opt/b/bridge`) are suffixed `bridge`, `bridge-2` instead of aborting startup. The operator's intent there is unambiguous; failing would be unhelpful. Existing `build_mcp_servers` tests are migrated to the list form and extended: several commands produce one server each in order, every server receives the identity env, stems are disambiguated, blank entries are skipped without dropping valid ones, and an empty list produces nothing. Signed-off-by: Noah Shipley <nshipley@centricsoftware.com>
noah-shipley-centric
force-pushed
the
feat/acp-multiple-mcp-servers
branch
from
July 27, 2026 20:06
3c95e32 to
35bcfee
Compare
This was referenced Aug 1, 2026
7 tasks
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.
Problem
build_mcp_serversincrates/buzz-acp/src/lib.rsbuilds at most oneMcpServer, so an agent driven bybuzz-acpcan hold exactly one MCP server.buzz-agentwas never the constraint —McpRegistry::spawn_alltakes a slice and already enforcesMAX_MCP_SERVERS = 16. The ceiling of one exists only in this function.That single slot forces a trade-off between reading and acting. Point an agent at a data MCP and it loses the tooling it replies with. I hit this with an agent wired to a remote data MCP: it made its tool calls correctly, then reasoned itself into a dead end mid-turn —
— and produced no visible output at all, because the slot that had been carrying its dev tools now carried the data bridge. Nothing errored; the turn just quietly went nowhere.
Change
--mcp-command/BUZZ_ACP_MCP_COMMANDnow accepts a comma-separated list:This mirrors
--agent-args/BUZZ_ACP_AGENT_ARGS, which already usesvalue_delimiter = ','in the same struct — so the parsing convention isn't new to the crate.Backward compatible. The flag and env var keep their names, and a single value produces exactly the server it produced before. No existing configuration changes behaviour.
Two deliberate details:
""default still yields no servers, and a stray trailing comma doesn't create a bogus one.spawn_allrejects duplicates, so/opt/a/bridge+/opt/b/bridgewould have aborted startup. They now becomebridgeandbridge-2— the operator's intent is unambiguous, and failing to boot would be unhelpful.Tests
Existing
build_mcp_serverstests are migrated to the list form and extended:BUZZ_RELAY_URL,BUZZ_PRIVATE_KEY)cargo fmtandcargo clippy -p buzz-acp --all-targets -- -D warningsare clean.Notes
Independent of #3192 — different crate, no shared commits; either can merge first.
If you'd rather express this as a repeatable
--mcp-server name=commandflag (explicit names, no stem-collision handling needed), I'm happy to rework it — the delimited list just seemed the smaller change and consistent with--agent-args.