Claude Agent ACP

repository·main·Indexed 24 days ago

https://github.com/agentclientprotocol/claude-agent-acp

An ACP-compatible coding agent adapter powered by the Claude Agent SDK (TypeScript). It enables advanced agentic features, such as nested subagent transcripts and tool calls, to work across Agent Client Protocol (ACP) compatible clients. The package supports model overrides and availability configuration via CLAUDE_MODEL_CONFIG, session steering, and integration with providers including Anthropic, AWS Bedrock, and Google Vertex AI.

Tokens
10.8K
Snippets
16
Records
73
Agent score
81%

What's inside @agentclientprotocol/claude-agent-acp

  1. Understand model configuration precedence

    main

    Model settings are applied based on the following priority. If a higher-priority source is present, the lower-priority source is ignored.

    1. Highest Priority: _meta.claudeCode.options.settings provided by the caller in the sessions/create request.
    2. Fallback Priority: CLAUDE_MODEL_CONFIG environment variable (used only if the caller provides no settings).
  2. Handle ExitPlanMode permission requests

    main

    When the ExitPlanMode tool is called, the agent presents the user with several options to transition out of planning mode. The available options are filtered based on the session's currently advertised modes (e.g., a model like Haiku might not support auto mode).

    Available options include:

    • auto: Yes, and use "auto" mode
    • acceptEdits: Yes, and auto-accept edits
    • default: Yes, and manually approve edits
    • plan: No, keep planning
    • bypassPermissions: Yes, and bypass permissions (only if ALLOW_BYPASS is enabled)

    If a mode like auto, acceptEdits, or bypassPermissions is selected, the agent updates the session's current mode and configuration via sessionUpdate and updateConfigOption.

  3. Handle tool progress and rate limit events

    main

    The agent processes various message types from the SDK and converts them into ACP notifications. Key event types include:

    • tool_progress: Reports the status of a tool call. It includes metadata such as toolName, elapsedTimeSeconds, and if applicable, subagentType or subagentRetry details (useful for showing why a subagent might be stalled due to rate limits).
    • rate_limit_event: Provides usage updates, including the amount used, the size of the context window, and rate limit metadata (_meta.claude/rateLimit).
  4. Configure LLM providers and routing

    main

    The agent exposes a single configurable provider with the ID "main". This allows clients to redirect API calls via a custom gateway.

    Supported Protocols:

    • anthropic
    • bedrock
    • vertex

    Configuration via providers/set: When configuring the provider, you can specify apiType, baseUrl, and headers. If using vertex, you must also provide projectId and region via _meta.claudeCode.vertex.

    Provider Configuration Shape:

    type ProviderConfig = {
      apiType: LlmProtocol;
      baseUrl: string;
      headers: Record<string, string>;
      vertex?: {
        projectId: string;
        region: string;
      };
    };

    If the provider is unconfigured or disabled, the agent falls back to its default routing (standard Claude login).

  5. Understand ACP session usage updates

    main

    The ACP adapter emits usage_update notifications to keep clients synchronized with token consumption and context window sizes. These updates are triggered when:

    1. Total usage changes: As tokens are consumed during a stream or a completed message.
    2. Context window changes: When an authoritative context window size is learned from a model response and cached.

    An update payload includes the total tokens used, the current context window size, and optionally the cost in USD.

  6. Manage session modes and configuration options

    main

    The agent manages session state including currentModeId (e.g., auto, default, bypassPermissions) and various configOptions (e.g., MODEL_CONFIG_ID, AGENT_CONFIG_ID, EFFORT_CONFIG_ID, FAST_MODE_CONFIG_ID).

    Key behaviors:

    • Model Switching: When the model is changed, the agent recomputes available modes and clamps the current mode if the new model doesn't support it (e.g., switching to a model that doesn't support auto mode will reset the session to default).
    • Effort Level: Changing the effort level via EFFORT_CONFIG_ID triggers an update to the underlying SDK via applyFlagSettings.
    • Fast Mode: The agent synchronizes the fast_mode_state reported by the SDK with the client's UI. If the SDK enters a cooldown state, the agent preserves the user's intent but may notify the user via an agent_message_chunk if the mode is forced off.
  7. Configure model overrides and availability via `CLAUDE_MODEL_CONFIG`

    main

    When using claude-agent-acp with alternative providers like AWS Bedrock, model IDs often differ from the standard Anthropic API IDs. You can use the CLAUDE_MODEL_CONFIG environment variable to map Anthropic model IDs to provider-specific IDs (like Bedrock ARNs) and restrict which models are available to users.

    CLAUDE_MODEL_CONFIG must be a valid JSON string. It supports two optional fields:

    • modelOverrides: A mapping (Record<string, string>) where the key is the Anthropic model ID and the value is the provider-specific model ID.
    • availableModels: An array of strings (string[]) that restricts the models offered to users. You can use aliases (e.g., "opus"), prefixes (e.g., "opus-4-5"), or full IDs.

    Note: If an ACP caller provides settings via _meta.claudeCode.options.settings in a sessions/create request, this environment variable is ignored. It serves as a deployment-level fallback.

  8. Handle AskUserQuestion via ACP form elicitation

    main

    The AskUserQuestion tool is treated as a permission check by the SDK. If the client supports form elicitation (clientCapabilities.elicitation.form), the agent converts the tool's input into an ACP form elicitation. The user's answers are then fed back into the tool's updatedInput.

    Note: This tool is automatically disabled if the client does not support form elicitation.

  9. How subagent transcripts are handled for different clients

    main

    The ACP adapter manages how subagent text and thinking blocks are exposed to the client based on client capabilities:

    1. Capable Clients: If the client supports subagent transcripts (checked via supportsSubagentTranscript), subagent content is forwarded normally, with parentToolUseId stamped on the notifications to allow the client to nest the transcript.
    2. Legacy Clients: If the client does not support nested transcripts, subagent text and thinking blocks are filtered out of the top-level assistant message content. This keeps the subagent output internal to the tool call, preventing it from leaking into the main conversation feed.

    This ensures backward compatibility while allowing modern clients to provide rich, nested agentic workflows.

  10. Handle model refusal stop reasons

    main

    When an assistant message returns a refusal stop reason, the ACP adapter handles it by:

    1. Sending an agent_message_chunk containing the refusal explanation (if available) to the client.
    2. Setting the stopReason to refusal.
    3. Using settleOrDefer to ensure the turn is closed without disrupting active subagents (preventing deadlocks).

    This ensures that model refusals are surfaced as explicit protocol events rather than generic internal errors.