Skip to content

ACP: Adopt MCP-over-ACP native transport and connect/disconnect lifecycle #362

Description

@julianromli

Problem or Opportunity

The upstream ACP specification (latest RFc, "MCP-over-ACP") introduces a native MCP-over-ACP transport with a dynamic connect/disconnect lifecycle. Termul's ACP integration currently uses the older static model and is behind on three points:

  1. mcpCapabilities is missing the acp field. The spec now defines:

    { "capabilities": { "mcpCapabilities": { "http": false, "sse": false, "acp": true } } }

    An agent with mcpCapabilities.acp === true can handle MCP servers declared with "type": "acp" natively. Termul's renderer type (src/renderer/lib/acp-api.ts:74) only models { http?, sse? }no acp field, so the capability is parsed away / invisible.

  2. No type: "acp" MCP server transport. The renderer's McpServer variants are stdio / http / sse (src/renderer/lib/acp-api.ts:177-198, src/renderer/lib/acp-mcp-persistence.ts). The spec's "type": "acp" transport (which references another ACP component by id/name, no subprocess) is not modeled, so a user cannot add an ACP-transport MCP server.

  3. No mcp/connect / mcp/disconnect lifecycle. The spec defines dynamic MCP connection management:

    // mcp/connect → returns connectionId
    { "method": "mcp/connect", "params": { "acpId": "550e8400-...", "_meta": {} } }
    // mcp/disconnect → closes by connectionId
    { "method": "mcp/disconnect", "params": { "connectionId": "conn-123", "_meta": {} } }

    Termul only injects MCP servers statically at session/new time (acp_new_sessionmanager.new_session). There is no support for connecting/disconnecting MCP servers mid-session.

This is not a regression — the current static injection is still valid per spec. But agents that prefer the native ACP transport (e.g. a tool-providing ACP component running in the same app) cannot be wired up, and mid-session MCP management isn't possible.

Proposed Solution

Adopt the MCP-over-ACP native transport and lifecycle (track as lower priority; gated on a concrete use case / agent demand).

  1. Extend the mcpCapabilities type to include acp?: boolean (src/renderer/lib/acp-api.ts:74), and surface it in the capability UI (ACP: Surface agent-advertised mcpCapabilities and promptCapabilities in the UI #359).

  2. Add the type: "acp" MCP server variant. Model McpServerAcp { type: "acp", name, id } alongside stdio/http/sse in persistence and the wire types. Update validateMcpServer and the settings UI (when ACP: User-managed MCP server list injected into agent sessions (session/new) #287 lands) to let users register an ACP-transport MCP server.

  3. Implement mcp/connect + mcp/disconnect in the backend (src-tauri/src/acp/manager.rs), bridged to the renderer as acp:mcp_connected / acp:mcp_disconnected events. Expose Tauri commands (e.g. acp_mcp_connect(agent_id, session_id, acp_id), acp_mcp_disconnect(connection_id)) for mid-session management.

  4. Capability-aware routing. When injecting an MCP server, prefer the acp transport when the agent advertises mcpCapabilities.acp; fall back to stdio/http/sse otherwise.

Success Criteria

  • mcpCapabilities.acp is parsed, typed, and surfaced.
  • Users can register an MCP server with type: "acp" (name + id).
  • mcp/connect and mcp/disconnect are implemented and exposed as commands/events.
  • Mid-session connect/disconnect works without a full session/new.
  • Capability-aware transport selection prefers acp when supported.

Alternatives Considered

  • Keep static session/new injection only. Simpler, and fine for stdio/http/sse servers that don't change. Insufficient for ACP-transport servers and mid-session tool changes. Defer this issue until there's a concrete agent/component that requires it.

Additional Context

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions