Skip to content

Custom ACP agents cannot join a team, even when they advertise mcpCapabilities.stdio: true #4177

Description

@arnaud-moona

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 APIPOST /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:

  1. persist agentCapabilities.mcpCapabilities.stdio into agent_metadata.agent_capabilities
    (today only http and sse survive);
  2. 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.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions