Skip to main content

ACP integration

Operator guide for CodeGraph ACP v1, the experimental ACP v2 profile, transports, MCP servers, authorization, and runtime limits.

API Reference

CodeGraph exposes Agent Client Protocol (ACP) over JSON-RPC for editor integrations. ACP v1 is the default and production-compatible profile. An experimental ACP v2 alpha profile is available behind CODEGRAPH_ACP_EXPERIMENTAL_V2=true. The profile is selected by initialize and remains fixed for the lifetime of that connection.

Both profiles use the same CodeGraph session core, workspace controls, permission requests, and Model Context Protocol (MCP) bridge. Image and audio capabilities are not advertised.

Transports and routes

Transports and routes
Transport Entry point Contract
stdio codegraph-acp A local IDE starts one agent subprocess. Requests, responses, and notifications are streamed.
HTTP POST /api/v1/admin/runtime/acp/rpc CodeGraph request/response JSON-RPC endpoint. It is not the official ACP Streamable HTTP transport.
WebSocket WS /api/v1/admin/runtime/acp/ws Bidirectional requests, agent-to-client calls, and streamed notifications.

HTTP session administration is available through GET /api/v1/admin/runtime/acp/sessions and DELETE /api/v1/admin/runtime/acp/sessions/{session_id}. HTTP protocol state and sessions are isolated by authenticated subject and project. WebSocket connections keep the project scope resolved from the token, machine credential, or explicitly enabled local-development boundary.

The HTTP endpoint collects ACP v1 prompt notifications and returns them in result._meta.codegraph.sessionUpdates. ACP v2 session/prompt is asynchronous and needs a streaming transport, so HTTP rejects it with JSON-RPC error -32004 before executing the turn.

Authentication boundary

The HTTP JSON-RPC and session routes require an administrator, the admin:all scope, or a service account with scenarios:execute. An unauthenticated localhost bypass exists only when local_dev_unauthenticated_surfaces_enabled is explicitly enabled.

WebSocket accepts a bearer access token or an API key. Machine credentials are additionally checked against project scope, the X-CodeGraph-Machine-Contract version, interface policy, and configured mTLS requirements. Transport authentication finishes before JSON-RPC parameters are parsed. Both ACP initialize responses advertise an empty authMethods list; the legacy v1 authenticate method therefore operates only inside an already verified transport boundary.

ACP v1 methods

Call initialize with protocolVersion: 1 before any other method. The server rejects an uninitialized request with -32002.

The standard v1 surface contains session/new, session/load, session/prompt, and session/cancel. During a prompt, the server can issue client requests for fs/read_text_file, fs/write_text_file, terminal operations, and session/request_permission. Clients must route responses by JSON-RPC request ID while continuing to process session/update notifications.

CodeGraph v1 prompts may opt in to those client calls with the _meta.codegraph.clientContext extension on a content block. Its readTextFiles array accepts objects with path; its terminals array accepts command, string args, and optional cwd, env, or outputByteLimit. CodeGraph invokes only capabilities advertised at initialize, adds the returned editor-visible file content and terminal result to that prompt, and always releases a created terminal. This metadata is a CodeGraph extension, not a new standard ACP method.

CodeGraph-specific editor functions use the _codegraph/ namespace:

  • _codegraph/thread/start, _codegraph/thread/resume, _codegraph/thread/fork, _codegraph/thread/list, _codegraph/thread/archive, and _codegraph/thread/compact;
  • _codegraph/turn/start and _codegraph/turn/interrupt;
  • _codegraph/diagnostics/subscribe, _codegraph/diagnostics/unsubscribe, and _codegraph/hover/request;
  • _codegraph/item/fileChange/respondApproval.

Pre-Story-1257 unprefixed names remain available through an explicit compatibility adapter. Such responses carry _meta.codegraph.legacyMethod; new clients should use the namespaced methods. The internal ClientCapabilitiesV2 class names the extended CodeGraph capability model and does not mean ACP protocol v2.

Experimental ACP v2 profile

With CODEGRAPH_ACP_EXPERIMENTAL_V2=true, a connection may initialize with protocolVersion: 2, info.name, and info.version. The profile supports session/new, session/list, session/resume, session/close, session/delete, session/prompt, session/cancel, and $/cancel_request.

session/prompt acknowledges the request before the turn finishes. The client then receives session/update notifications, including state transitions and tool-call updates. Use stdio or WebSocket for this flow. Reinitializing a connection with another protocol version fails closed; open a new connection instead.

To roll back the experimental profile, set CODEGRAPH_ACP_EXPERIMENTAL_V2=false and restart ACP connections. ACP v1 does not depend on the v2 flag.

MCP servers and permission flow

session/new and the applicable resume/load flows accept ACP MCP descriptors for stdio and http transports. Stdio commands are resolved to an executable and run as a native argv with no shell. Environment and header entries must use name/value objects; names are validated and values cannot contain NUL, carriage-return, or newline characters.

HTTP MCP descriptors accept public HTTPS endpoints only. Credentials in the URL, query strings, fragments, loopback addresses, private networks, link-local addresses, and plaintext HTTP are rejected. Redirect handling remains subject to the shared outbound URL policy.

Every declared MCP server must connect during session creation. If any connection fails, the server closes connections already opened for that request and removes the incomplete ACP session. Before invoking an MCP tool, CodeGraph sends session/request_permission; a denial or timeout prevents the call. One lifecycle-owner task performs each MCP SDK context entry, operation, and exit so session close and transport shutdown can release subprocesses and network clients.

Workspace and terminal containment

File calls require an absolute workspaceRoot and target path. A path that resolves outside the root fails with outside workspace root. Writes also reject sensitive path fragments such as .git, .env, .ssh, .aws, and node_modules.

Terminal calls require the same absolute workspaceRoot; cwd must remain below it. Commands run as argv with shell=False. The checked-in allowlist contains bounded build and inspection commands. Interpreters and shells such as python, powershell, pwsh, cmd, bash, sh, and node are blocked. Arguments must be a native list of strings without NUL or newline control characters.

These checks do not turn ACP into a general remote shell. Keep network routes behind the normal authentication and project boundary.

File-change approval limitation

The server advertises an approval flow and sends the established item/fileChange/requestApproval notification. Clients answer with the canonical _codegraph/item/fileChange/respondApproval method; the unprefixed response name is accepted by the compatibility adapter. An unanswered request is declined after the configured timeout.

The current fs/write_text_file handler does not automatically invoke that bridge. It performs a workspace-contained write after its own path checks. A client or outer workflow that requires human approval must enforce and record it before exposing the write operation.

Runtime limits

Defaults in ACPRuntimeConfig bound the service to 100 concurrent sessions with a 60-minute session timeout, 128 pending agent-to-client requests per connection, 256 queued stdio notifications, and a 300-second approval timeout. The same configuration also controls terminal wait and cleanup timing, bridge polling, and streamed chunk sizes. Deployments may override these values through the unified runtime configuration; clients must not assume that defaults were retained.

Recovery checklist

  1. Confirm the route prefix is /api/v1/admin/runtime/acp, not the historical /acp prefix.
  2. Verify transport authentication before debugging JSON-RPC parameters.
  3. Send one initialize request and keep that protocol profile for the connection.
  4. Use stdio or WebSocket for ACP v2 prompts and agent-to-client requests.
  5. For file or terminal errors, keep absolute workspaceRoot, path, and cwd values below the same root.
  6. Treat a blocked executable, rejected MCP endpoint, or missing permission as a policy outcome.

Source of truth

  • src/api/routers/collaboration_suite/acp.py: HTTP/WebSocket routes and authentication.
  • src/acp/server/core/agent.py: v1 dispatch, profile selection, client requests, and shared MCP execution.
  • src/acp/server/core/v2_profile.py: experimental v2 session lifecycle and asynchronous turns.
  • src/acp/server/core/session_manager.py: session ownership, MCP setup, cancellation, and cleanup.
  • src/acp/server/routing/handlers.py: workspace containment and bounded terminal policy.
  • src/acp/integration/mcp_bridge.py: MCP descriptor validation and connection lifecycle.
  • src/acp/transport/: stdio, HTTP, and WebSocket behavior.
  • src/config/runtime_sections/unified_config_runtime_models.py: ACP runtime defaults.