Version: AionUi 2.1.59 (macOS, arm64)
Summary
A custom ACP agent that declares MCP stdio support at initialize is still rejected from team mode
with "This assistant's agent does not support team mode."
Team eligibility is documented as being derived from that capability:
// packages/desktop/src/renderer/utils/model/agentTypes.ts
/** True when the agent supports team mode (MCP stdio capable). Computed by backend. */
team_capable?: boolean;
In practice it is gated on a stored behavior_policy.supports_team flag that is seeded false for
custom agents, and the handshake's stdio capability never reaches the catalog.
Reproduction
A custom ACP agent whose initialize response contains:
{
"protocolVersion": 1,
"agentCapabilities": {
"loadSession": true,
"mcpCapabilities": { "http": false, "sse": false, "stdio": true }
}
}
Register it as a custom agent, run a connection test (the handshake succeeds), then try to add it to
a team → rejected.
What the catalog actually stores
After a successful connection test, agent_metadata.agent_capabilities reads:
{"load_session":true,
"prompt_capabilities":{"image":false,"audio":false,"embedded_context":false},
"mcp_capabilities":{"http":false,"sse":false},
"session_capabilities":{},"auth":{}}
mcp_capabilities has no stdio key — the agent advertised it, and it was dropped on the way
in. So nothing downstream can derive "MCP stdio capable" from the stored row.
Meanwhile behavior_policy.supports_team is what actually decides: agents with 1 are selectable,
an otherwise identical agent with the flag absent is not. Setting it flips the behaviour
immediately, with no other change.
Why this is hard to work around
- UI — the advanced panel of the custom agent editor silently discards the key while parsing
(filed separately as a PR: the JSON round-trip whitelists supports_side_question only).
- HTTP API —
POST /api/agents/custom does accept advanced.behavior_policy, but business
endpoints now require an authenticated session, so an external tool gets 401.
/api/webui/* and /api/auth/internal/* answer 403, with or without x-aionui-internal: 1.
- What remains is editing aioncore's SQLite directly, which is not something a user should have to
do to add an agent to a team.
Suggested fix
Derive team_capable from the handshake, as the type comment already describes:
- persist
agentCapabilities.mcpCapabilities.stdio into agent_metadata.agent_capabilities
(today only http and sse survive);
- compute
team_capable from it, keeping behavior_policy.supports_team as an explicit override
for agents that need to opt out.
That would make any ACP agent honestly declaring MCP stdio usable in a team with no manual step, and
would match the documented intent. If the flag must stay authoritative, exposing it in the editor
(see the linked PR) would at least make it reachable.
Happy to test a build against a real custom ACP agent that speaks MCP stdio.
Version: AionUi 2.1.59 (macOS, arm64)
Summary
A custom ACP agent that declares MCP stdio support at
initializeis still rejected from team modewith "This assistant's agent does not support team mode."
Team eligibility is documented as being derived from that capability:
In practice it is gated on a stored
behavior_policy.supports_teamflag that is seededfalseforcustom agents, and the handshake's
stdiocapability never reaches the catalog.Reproduction
A custom ACP agent whose
initializeresponse contains:{ "protocolVersion": 1, "agentCapabilities": { "loadSession": true, "mcpCapabilities": { "http": false, "sse": false, "stdio": true } } }Register it as a custom agent, run a connection test (the handshake succeeds), then try to add it to
a team → rejected.
What the catalog actually stores
After a successful connection test,
agent_metadata.agent_capabilitiesreads:{"load_session":true, "prompt_capabilities":{"image":false,"audio":false,"embedded_context":false}, "mcp_capabilities":{"http":false,"sse":false}, "session_capabilities":{},"auth":{}}mcp_capabilitieshas nostdiokey — the agent advertised it, and it was dropped on the wayin. So nothing downstream can derive "MCP stdio capable" from the stored row.
Meanwhile
behavior_policy.supports_teamis what actually decides: agents with1are selectable,an otherwise identical agent with the flag absent is not. Setting it flips the behaviour
immediately, with no other change.
Why this is hard to work around
(filed separately as a PR: the JSON round-trip whitelists
supports_side_questiononly).POST /api/agents/customdoes acceptadvanced.behavior_policy, but businessendpoints now require an authenticated session, so an external tool gets
401./api/webui/*and/api/auth/internal/*answer403, with or withoutx-aionui-internal: 1.do to add an agent to a team.
Suggested fix
Derive
team_capablefrom the handshake, as the type comment already describes:agentCapabilities.mcpCapabilities.stdiointoagent_metadata.agent_capabilities(today only
httpandssesurvive);team_capablefrom it, keepingbehavior_policy.supports_teamas an explicit overridefor agents that need to opt out.
That would make any ACP agent honestly declaring MCP stdio usable in a team with no manual step, and
would match the documented intent. If the flag must stay authoritative, exposing it in the editor
(see the linked PR) would at least make it reachable.
Happy to test a build against a real custom ACP agent that speaks MCP stdio.