Preset harnesses get no MCP server, so their agents can never post a reply
Summary
An agent whose harness is a preset (presets.rs — hermes, cursor, devin, opencode, …)
is started with mcpServers: [] in session/new. Since a Buzz agent publishes its reply
by calling the Buzz tools exposed through buzz-dev-mcp, such an agent has no way to post:
it runs the turn, streams agent_message_chunks, returns stopReason: end_turn — and
nothing is ever published (kind:9 count stays 0).
Built-in runtimes (claude, codex, goose, buzz-agent) carry an MCP command and work.
Evidence
Same relay, same app, same machine. Buzz Desktop 0.5.20 (macOS 26.6.2 arm64),
self-hosted deploy/compose relay.
session/new params, captured with RUST_LOG=buzz_acp=debug,acp=debug:
Honey (runtime=codex, builtin) → mcpServers: 1 {"command": ".../buzz-dev-mcp", "env": [...]}
Hermes (runtime=hermes, preset) → mcpServers: 0
Events published by each agent pubkey:
| kind |
Hermes (preset) |
Honey (builtin) |
| 7 / 5 (reaction + delete) |
yes |
yes |
| 9 (message) |
0 |
yes |
The one time Hermes did post, it had brute-forced its way there through its shell tool —
32 tool calls, several failing with relay error 403, until one worked:
INFO acp::tool: tool_call: terminal: buzz messages send --channel adafd400-... --reply-to ...
That is the only kind:9 it ever produced, and it came from the CLI, not from the harness
path.
Where it comes from
desktop/src-tauri/src/managed_agents/discovery/presets.rs builds every preset entry with
while the built-in runtime table supplies one. Nothing else appears to fill it in for
presets.
Note: the grok preset does work here, but only by accident — that agent's record was
created while it still ran the built-in buzz-agent runtime, so mcp_command: "buzz-dev-mcp" was persisted in managed-agents.json and survived the later switch to
the preset. A preset agent created from scratch (Hermes) has mcp_command: "".
Workarounds tried, all ineffective
- Setting
mcp_command directly in the agent's managed-agents.json record
- Injecting
BUZZ_ACP_MCP_COMMAND=/Applications/Buzz.app/Contents/MacOS/buzz-dev-mcp
through the agent's env_vars
Both persist in the store but session/new still carries mcpServers: 0, so the value
appears to be resolved from the runtime catalog at spawn time.
Ruled out
- Command resolution —
hermes-acp resolves; Settings → Agents shows Ready.
- ACP conformance — driving
hermes-acp directly over stdio, it answers initialize
(protocol v1), opens a session and streams standard agent_message_chunks.
messageId on chunks — codex-acp sends one, hermes-acp does not; patching
hermes-acp to emit a stable per-turn messageId changed nothing, and the working grok
preset sends none either.
- Membership / auth — the agent is a channel
bot member and authenticates with
BUZZ_AUTH_TAG like the working agents.
Expected
A preset harness that speaks ACP should receive the same buzz-dev-mcp server as a
built-in runtime, so its agent can publish replies.
Repro
- Install any preset harness CLI (e.g.
hermes-acp) so it is on PATH
- Create an agent, set harness to that preset, add it to a channel
- Mention it — the turn completes with
end_turn, no message is posted
Preset harnesses get no MCP server, so their agents can never post a reply
Summary
An agent whose harness is a preset (
presets.rs— hermes, cursor, devin, opencode, …)is started with
mcpServers: []insession/new. Since a Buzz agent publishes its replyby calling the Buzz tools exposed through
buzz-dev-mcp, such an agent has no way to post:it runs the turn, streams
agent_message_chunks, returnsstopReason: end_turn— andnothing is ever published (kind:9 count stays 0).
Built-in runtimes (
claude,codex,goose,buzz-agent) carry an MCP command and work.Evidence
Same relay, same app, same machine. Buzz Desktop 0.5.20 (macOS 26.6.2 arm64),
self-hosted
deploy/composerelay.session/newparams, captured withRUST_LOG=buzz_acp=debug,acp=debug:Events published by each agent pubkey:
The one time Hermes did post, it had brute-forced its way there through its shell tool —
32 tool calls, several failing with
relay error 403, until one worked:That is the only kind:9 it ever produced, and it came from the CLI, not from the harness
path.
Where it comes from
desktop/src-tauri/src/managed_agents/discovery/presets.rsbuilds every preset entry withwhile the built-in runtime table supplies one. Nothing else appears to fill it in for
presets.
Note: the
grokpreset does work here, but only by accident — that agent's record wascreated while it still ran the built-in
buzz-agentruntime, somcp_command: "buzz-dev-mcp"was persisted inmanaged-agents.jsonand survived the later switch tothe preset. A preset agent created from scratch (Hermes) has
mcp_command: "".Workarounds tried, all ineffective
mcp_commanddirectly in the agent'smanaged-agents.jsonrecordBUZZ_ACP_MCP_COMMAND=/Applications/Buzz.app/Contents/MacOS/buzz-dev-mcpthrough the agent's
env_varsBoth persist in the store but
session/newstill carriesmcpServers: 0, so the valueappears to be resolved from the runtime catalog at spawn time.
Ruled out
hermes-acpresolves; Settings → Agents shows Ready.hermes-acpdirectly over stdio, it answersinitialize(protocol v1), opens a session and streams standard
agent_message_chunks.messageIdon chunks — codex-acp sends one, hermes-acp does not; patchinghermes-acp to emit a stable per-turn
messageIdchanged nothing, and the workinggrokpreset sends none either.
botmember and authenticates withBUZZ_AUTH_TAGlike the working agents.Expected
A preset harness that speaks ACP should receive the same
buzz-dev-mcpserver as abuilt-in runtime, so its agent can publish replies.
Repro
hermes-acp) so it is on PATHend_turn, no message is posted