Andy.Acp.Core
2026.7.21.1
dotnet add package Andy.Acp.Core --version 2026.7.21.1
NuGet\Install-Package Andy.Acp.Core -Version 2026.7.21.1
<PackageReference Include="Andy.Acp.Core" Version="2026.7.21.1" />
<PackageVersion Include="Andy.Acp.Core" Version="2026.7.21.1" />
<PackageReference Include="Andy.Acp.Core" />
paket add Andy.Acp.Core --version 2026.7.21.1
#r "nuget: Andy.Acp.Core, 2026.7.21.1"
#:package Andy.Acp.Core@2026.7.21.1
#addin nuget:?package=Andy.Acp.Core&version=2026.7.21.1
#tool nuget:?package=Andy.Acp.Core&version=2026.7.21.1
andy-acp
Andy's implementation of ACP (Agent Client Protocol)
ALPHA RELEASE WARNING
This software is in ALPHA stage. NO GUARANTEES are made about its functionality, stability, or safety.
CRITICAL WARNINGS:
- This library implements a protocol server that accepts and executes commands
- Security features are NOT FULLY TESTED and may have vulnerabilities
- DO NOT USE in production environments
- DO NOT USE on systems exposed to untrusted networks or clients
- DO NOT USE without proper security review and hardening
- The authors assume NO RESPONSIBILITY for security breaches, data loss, or system damage
USE AT YOUR OWN RISK
Overview
This repository contains a C# implementation of the Agent Client Protocol (ACP), designed to enable AI agents to integrate with tools and editors like Zed. The implementation follows the ACP specification and provides a foundation for building ACP-compliant servers.
Project Structure
andy-acp/
├── src/
│ └── Andy.Acp.Core/ # Core ACP library
│ ├── Transport/ # Transport layer (stdio, line-delimited JSON)
│ ├── JsonRpc/ # JSON-RPC 2.0 implementation
│ ├── Session/ # Session management
│ ├── Protocol/ # ACP protocol handlers
│ ├── Agent/ # Agent provider interfaces
│ ├── Client/ # Agent-to-client requests (fs, terminal, permission)
│ ├── Server/ # Unified ACP server
│ └── Tools/ # Tool framework (MCP compatibility)
├── tests/
│ └── Andy.Acp.Tests/ # Comprehensive unit tests (334 tests)
│ ├── Transport/
│ ├── JsonRpc/
│ ├── Session/
│ ├── Protocol/
│ └── Tools/
├── examples/
│ ├── SimpleEchoAgent/ # Minimal working example
│ │ ├── SimpleEchoAgentProvider.cs
│ │ ├── Program.cs
│ │ ├── SimpleEchoAgent.csproj
│ │ └── README.md
│ └── Andy.Acp.Examples/ # Full-featured ACP server example
│ ├── Program.cs # Server/client implementation
│ ├── README.md # Zed integration guide
│ ├── zed-settings.example.json
│ └── test-server.sh
├── docs/
│ ├── TOOLS_COMPARISON.md # Andy.Tools vs ACP interfaces analysis
│ └── ZED_INTEGRATION_TESTING.md # Comprehensive Zed testing guide
└── Andy.Acp.sln
Features Implemented
[COMPLETE] Issue #2: Stdio Transport Layer Foundation
Status: Complete | 17 tests | Issue #2
- ITransport Interface: Defines the contract for transport implementations
- StdioTransport Class: Implements stdio-based communication with:
- Dual format support: Auto-detects Content-Length headers OR line-delimited JSON
- Line-delimited JSON: Newline-separated messages (Zed/Gemini style)
- Content-Length framing: Traditional LSP/MCP style (backwards compatible)
- Async read/write operations with cancellation token support
- Proper stream handling and disposal
- Comprehensive error handling and EOF detection
- Thread-safe write operations using semaphores
- Enhanced signal handling (SIGINT/SIGTERM) for graceful shutdown
- Structured Logging: Microsoft.Extensions.Logging with stderr output
- Signal Handling: POSIX signals for Unix systems, Console.CancelKeyPress for interactive mode
[COMPLETE] Issue #3: JSON-RPC 2.0 Message Handling
Status: Complete | 86 tests | Issue #3
- JsonRpcSerializer: Serialization/deserialization of JSON-RPC 2.0 messages
- JsonRpcHandler: Method registration and request dispatching
- Message Types: Request, Response, Notification, Error
- Error Handling: Standard JSON-RPC error codes and custom exceptions
- Method Registration: Dynamic method registration with async handlers
- Compliance:
result: nullon success, explicit-null-id vs. notification,error.data, and safe internal-error messages. Batch requests are not supported and a top-level array is rejected. Parameters are validated as structured JSON values (not full JSON Schema validation).
[COMPLETE] Issue #4: Session Management and State Handling
Status: Complete | 73 tests | Issue #4
- AcpSession: Session lifecycle management (Created → Initializing → Initialized → Active → ShuttingDown → Terminated)
- ISessionManager: Session creation, tracking, and cleanup
- SessionManager: Default implementation with timeout support
- Pending Request Tracking: Track in-flight requests for graceful shutdown
- Session Health Monitoring: Automatic timeout detection
- Client Capabilities: Store and manage client-provided capabilities
- Background Cleanup: Automatic session cleanup for terminated sessions
[COMPLETE] Issue #5: Initialization Handshake Protocol
Status: Complete | 23 tests | Issue #5
- AcpProtocolHandler: Handles the ACP v1
initializehandshake (only) - Protocol Models: ACP
ClientCapabilities/AgentCapabilities,Implementation - Capability Negotiation: Integer
protocolVersionnegotiation; client fs/terminal capabilities recorded for agent-to-client requests - Initialize-before-session ordering: session methods fail until
initializecompletes - Note:
initializedandshutdownwere removed (not part of ACP v1)
MCP-compatibility Tool Framework (not ACP tool calls)
Status: Available for MCP-style hosts | Issue #6
Note: This
tools/list+tools/callframework is an MCP-style convenience, distinct from ACP. In ACP, tool activity is reported to the client astool_callandtool_call_updatesession/update notifications (see the streaming section), not viatools/list/tools/call. Use this framework only when hosting MCP-style tool calls.
- IAcpToolProvider: Interface for tool registration and execution
- AcpToolsHandler: Handles
tools/listandtools/call(MCP-style) - Tool Models: AcpToolDefinition, AcpInputSchema, AcpToolResult (minimal)
- SimpleToolProvider: Example implementation with 4 demonstration tools
- Error Handling: Graceful error responses for missing tools and execution failures
- Example Tools: echo, calculator, get_time, reverse_string
Note: This is the generic framework. Concrete andy-cli tools will use andy-tools library with an adapter pattern (see docs/TOOLS_COMPARISON.md).
[COMPLETE] Agent Provider Interface & Session Management
Status: Complete | Integrated with Andy.CLI
- IAgentProvider: Core interface for implementing ACP-compatible agents
- IResponseStreamer: Interface for streaming responses to clients
- Session Methods: session/new, session/load, session/prompt, session/cancel, session/set_mode
- SessionUpdateStreamer: Sends session/update notifications for streaming responses
- AcpSessionHandler: Handles all session/* protocol methods
- AcpServer: Unified server that composes all handlers and providers
- Working Integration: Andy.CLI successfully integrates via AndyAgentProvider
Agent Protocol Flow:
- Client sends
initializewith protocol version - Server responds with capabilities (agent, filesystem, terminal)
- Client sends
session/newto create conversation session - Server returns session metadata
- Client sends
session/promptwith user message - Server streams response via
session/updatenotifications - Server returns stopReason when complete
[COMPLETE] Zed Editor Integration
Status: Working | Tested with Andy.CLI
- Line-delimited JSON transport working with Zed
- SimpleEchoAgent example provides minimal working implementation
- Andy.CLI integration providing full LLM + tools via ACP
- Response streaming working (word-by-word display in Zed)
- Session management properly tracking conversation state
Total: 334 tests passing (including schema-backed ACP v1 validation and end-to-end stdio flows)
Supported ACP version and capabilities
- Protocol version: ACP v1 (the
protocolVersioninteger1). Oninitialize, a higher requested version is negotiated down to1. - Agent capabilities advertised:
loadSession, andpromptCapabilities(image/audio/embeddedContext) reflecting the agent provider. Text andresource_linkcontent are always accepted. - Client capabilities consumed:
fs.readTextFile,fs.writeTextFile, andterminal. The agent issuesfs/*,terminal/*, andsession/request_permissionto the client and only when the client advertised the matching capability. - Lifecycle methods:
initialize, optionalauthenticate/logout,session/new,session/load,session/prompt,session/set_mode(bymodeId), optionalsession/set_config_optionand the session catalog (session/list,delete,resume,close), thesession/cancelnotification, and$/cancel_request.initialized,shutdown, andsession/set_modelare not part of ACP v1 and are not implemented (model selection flows through config options). - Optional provider interfaces: an
IAgentProviderimplementation opts into the optional surface by additionally implementingIAuthenticationProvider,ISessionConfigProvider, and/orISessionCatalogProvider— capabilities and method registration follow automatically.
See Known limitations below for optional ACP v1 features not yet implemented.
Building and Testing
Prerequisites
- .NET 8.0 SDK (all projects target
net8.0)
Build
dotnet build
Run Tests
dotnet test
Run Examples
SimpleEchoAgent (Minimal Example)
Perfect for learning and testing:
# Build and run
dotnet build examples/SimpleEchoAgent -c Release
dotnet run --project examples/SimpleEchoAgent -- --acp
# Or use the published binary
dotnet run --project examples/SimpleEchoAgent -- --help
See examples/SimpleEchoAgent/README.md for Zed configuration.
Andy.Acp.Examples (Full-Featured)
Demonstrates complete protocol with tools:
# Show usage help
dotnet run --project examples/Andy.Acp.Examples
# Run automated test (recommended)
cd examples/Andy.Acp.Examples && ./test-server.sh
# Run as server (receives ACP messages from stdin)
dotnet run --project examples/Andy.Acp.Examples -- --server
# Run as client (sends ACP messages to stdout)
dotnet run --project examples/Andy.Acp.Examples -- --client
# Pipe client output to server (demonstrates full ACP protocol)
dotnet run --project examples/Andy.Acp.Examples -- --client | \
dotnet run --project examples/Andy.Acp.Examples -- --server
Test with Zed Editor
Recommended: Start with SimpleEchoAgent for a working baseline.
Quick start:
- Build:
dotnet build examples/SimpleEchoAgent -c Release - Add a custom agent to
~/.config/zed/settings.jsonusing the currentagent_serverssyntax:
{
"agent_servers": {
"Andy Echo": {
"command": "/path/to/andy-acp/examples/SimpleEchoAgent/bin/Release/net8.0/SimpleEchoAgent",
"args": ["--acp"],
"env": {}
}
}
}
- Restart Zed, open the Agent Panel, and pick Andy Echo as the agent.
- Type a message — you should see it echoed back.
See examples/SimpleEchoAgent/README.md and examples/Andy.Acp.Examples/README.md for detailed instructions.
Message Format
The transport layer supports two message formats:
Line-Delimited JSON (Default for Zed)
{"jsonrpc":"2.0","method":"initialize","id":1,"params":{...}}
{"jsonrpc":"2.0","id":1,"result":{...}}
Each message is a single line terminated by \n. This is the format used by Zed and Gemini CLI.
Content-Length Headers (LSP/MCP Compatible)
Content-Length: <length>\r\n
\r\n
<JSON message body>
The transport auto-detects which format is being used.
Protocol Flow
Agent Session Flow (Primary)
// 1. Client sends initialize (protocolVersion is an integer)
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{
"protocolVersion":1,
"clientCapabilities":{"fs":{"readTextFile":true,"writeTextFile":true},"terminal":true}
}}
// 2. Agent responds with the negotiated version and its capabilities
{"jsonrpc":"2.0","id":1,"result":{
"protocolVersion":1,
"agentInfo":{"name":"Andy ACP Server","version":"1.0.0"},
"agentCapabilities":{
"loadSession":true,
"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false},
"mcpCapabilities":{"http":false,"sse":false}
},
"authMethods":[]
}}
// 3. Client creates a new session (cwd and mcpServers are required)
{"jsonrpc":"2.0","id":2,"method":"session/new","params":{
"cwd":"/absolute/path/to/workspace",
"mcpServers":[]
}}
// 4. Agent returns the session id (and optional mode state)
{"jsonrpc":"2.0","id":2,"result":{
"sessionId":"session-abc123"
}}
// 5. Client sends a prompt
{"jsonrpc":"2.0","id":3,"method":"session/prompt","params":{
"sessionId":"session-abc123",
"prompt":[{"type":"text","text":"Hello! What is 15 + 27?"}]
}}
// 6. Server streams response via session/update notifications
{"jsonrpc":"2.0","method":"session/update","params":{
"sessionId":"session-abc123",
"update":{
"content":{"type":"text","text":"Hello! "},
"sessionUpdate":"agent_message_chunk"
}
}}
{"jsonrpc":"2.0","method":"session/update","params":{
"sessionId":"session-abc123",
"update":{
"content":{"type":"text","text":"15 + 27 = 42"},
"sessionUpdate":"agent_message_chunk"
}
}}
// 7. Server returns final stopReason
{"jsonrpc":"2.0","id":3,"result":{"stopReason":"end_turn"}}
Tool-Based Flow (Legacy/MCP Compatible)
The library also supports the traditional MCP-style tools/list and tools/call methods. See examples/Andy.Acp.Examples for a demonstration.
Examples
SimpleEchoAgent (Recommended for Learning)
A minimal 150-line example demonstrating core concepts:
- IAgentProvider implementation with session management
- Response streaming via IResponseStreamer
- ACP server setup with minimal configuration
- Perfect for learning and testing Zed integration
See examples/SimpleEchoAgent/README.md for setup instructions.
Andy.Acp.Examples (Full-Featured)
Demonstrates the complete ACP protocol with tools support:
- Traditional tools/list and tools/call methods (MCP-compatible)
- Example tools: echo, calculator, get_time, reverse_string
- Client/server test modes
- Comprehensive protocol flow demonstration
See examples/Andy.Acp.Examples/README.md for details.
Andy.CLI Integration
Full LLM-powered agent working in Zed:
- session/prompt implementation with streaming
- Andy tools surfaced as ACP
tool_call/tool_call_updateupdates - LLM reasoning (OpenAI, Anthropic, Gemini, Cerebras, Ollama)
The integration is in the andy-cli repository via AndyAgentProvider.cs.
This library is ALPHA (see the warning at the top). It is not production-ready and has not undergone a security review.
Status & Next Steps
[COMPLETE] Zed Integration
Status: Working | Successfully tested with Andy.CLI
✓ Protocol Implementation:
- Line-delimited JSON transport (Zed-compatible)
- session/new, session/load, session/prompt methods
- session/update streaming notifications
- Consistent camelCase ACP wire serialization
✓ Working Examples:
- SimpleEchoAgent: Minimal working example (echoes messages)
- Andy.CLI: Full LLM + tools integration
✓ Tested Features:
- Session creation and management
- Response streaming (word-by-word display)
- Multiple conversation turns
- Graceful error handling
Known limitations
Implemented and covered by tests:
initializehandshake with integer protocol-version negotiationauthenticate/logoutwith advertised auth methods and-32000auth-required gating (opt-in viaIAuthenticationProvider)session/new,session/load(with history replay),session/prompt,session/set_mode(bymodeId),session/cancelsession/set_config_optionand config options in session responses — the ACP mechanism for model selection and reasoning levels (opt-in viaISessionConfigProvider)- Session catalog:
session/list,session/delete,session/resume,session/close, withsessionCapabilitiesadvertisement (opt-in viaISessionCatalogProvider) - All
session/updatevariants: message/thought chunks,tool_call(withlocationsand content/diff/terminalToolCallContent),tool_call_update(withrawOutput),plan,available_commands_update,current_mode_update,config_option_update,session_info_update,usage_update - Multimodal prompt content blocks (text, image, audio, resource, resource_link), validated against negotiated capabilities
- Agent → client
fs/read_text_file,fs/write_text_file,terminal/*, andsession/request_permission $/cancel_requestprotocol-level cancellation (responds-32800)- ACP-reserved error codes:
-32000auth required,-32002resource not found,-32800request cancelled - Schema-backed validation of wire output against the pinned ACP v1 schema
(
schema-v1.20.0)
Also implemented (gap-closure epic):
- Grouped select config options (
SessionConfigSelectGroup) alongside flat lists sessionCapabilities.additionalDirectoriesmarker, driven byAgentCapabilities.AdditionalDirectories- Agent-declared MCP transport capabilities (
AgentCapabilities.McpHttp/McpSse) advertised asmcpCapabilities; incomingmcpServersentries are validated against them (stdio always accepted)
By design (not gaps):
- MCP server configurations are passed through to the agent as data; connecting to MCP servers is the agent's responsibility, out of scope for this wire-protocol library
- JSON-RPC batch requests are intentionally not supported and are rejected
Choosing a protocol version
The library serves stable ACP v1 by default. ACP v2 (alpha) support exists but must be explicitly opted into — v2 is alpha upstream and may change incompatibly:
// Default: stable v1 only. A client requesting v2 is negotiated down to v1.
var server = new AcpServer(agent);
// Opt-in: serve v1 AND v2 alpha. Each connection's version is fixed at initialize.
var server = new AcpServer(agent, options: new AcpServerOptions { EnableV2Alpha = true });
There is exactly one source of truth per concern, so the supported version is never ambiguous in code:
| concern | single source of truth |
|---|---|
| Version constants | AcpVersions (V1, V2Alpha, Default, All) |
| What this server serves | AcpServerOptions.SupportedVersions |
| What this connection speaks | AcpConnectionState.ProtocolVersion (set at initialize) |
| Which methods exist in which version | AcpMethodRegistry (derived from the vendored meta.json files) |
Dispatch is centrally gated on the registry: calling a v1-only method (e.g.
session/load) on a v2 connection — or a v2-only method (e.g. auth/login) on a v1
connection — returns method-not-found regardless of what is registered. v2 wire models
live in the separate Andy.Acp.Core.Protocol.V2 namespace and are never mixed with v1
types where the schemas differ.
Key v2 differences handled automatically (the provider API stays version-neutral):
session/load → session/resume + replayFrom:{"type":"start"}; session/set_mode
→ config options; authenticate/logout → auth/login/auth/logout; prompt
stopReason moves from the response to state_update {state:"idle"}; capability
booleans become {} markers; config options use configId/groupId. On v2 there are
no client-served fs/*/terminal/* methods, and SendCurrentModeAsync throws
(v2 removed current_mode_update — use config options with category mode).
Both pinned schemas are vendored in the test project (v1 = schema-v1.20.0,
v2 = schema-v2.0.0-alpha.x), and CI validates all emitted wire shapes against the
schema of the negotiated version.
Contributing
This project follows standard C# coding conventions and includes comprehensive tests for all features. When implementing new issues:
- Write unit tests in the
tests/directory - Create examples in the
examples/directory - Ensure all tests pass before marking an issue as complete
- Update this README with implementation status
License
Apache License 2.0 - See LICENSE file for details
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2026.7.21.1 | 946 | 7/21/2026 |
| 2026.7.21 | 181 | 7/21/2026 |
| 2026.7.21-rc.17 | 71 | 7/21/2026 |
| 2026.7.21-rc.15 | 72 | 7/21/2026 |
| 2026.7.21-rc.13 | 73 | 7/21/2026 |
| 2026.7.21-rc.12 | 69 | 7/21/2026 |
| 2026.7.21-rc.11 | 66 | 7/21/2026 |
| 2026.7.21-rc.10 | 66 | 7/21/2026 |
| 2026.7.21-rc.8 | 66 | 7/21/2026 |
| 2026.7.21-rc.7 | 72 | 7/21/2026 |
| 2026.5.16-rc.5 | 80 | 5/16/2026 |
| 2025.11.18-rc.3 | 502 | 11/18/2025 |
| 2025.11.17-rc.1 | 291 | 11/17/2025 |