dotacp.agent
2026.5.10
dotnet add package dotacp.agent --version 2026.5.10
NuGet\Install-Package dotacp.agent -Version 2026.5.10
<PackageReference Include="dotacp.agent" Version="2026.5.10" />
<PackageVersion Include="dotacp.agent" Version="2026.5.10" />
<PackageReference Include="dotacp.agent" />
paket add dotacp.agent --version 2026.5.10
#r "nuget: dotacp.agent, 2026.5.10"
#:package dotacp.agent@2026.5.10
#addin nuget:?package=dotacp.agent&version=2026.5.10
#tool nuget:?package=dotacp.agent&version=2026.5.10
dotacp.agent
.NET library for implementing Agent Client Protocol (ACP) agents.
What is dotacp.agent?
This package provides the tools needed to build ACP agent implementations in .NET. It includes:
- IAcpAgent Interface: Core interface with all required protocol methods
- Connection Management: Handles JSON-RPC communication with ACP clients
- RPC Message Routing: Automatic dispatch of inbound protocol calls
Dependencies
- .NET Standard 2.0 or higher
dotacp.protocol- Protocol type definitionsStreamJsonRpc(v2.7.76+) - JSON-RPC communication
Installation
dotnet add package dotacp.agent
Or reference the project directly:
<ItemGroup>
<ProjectReference Include="path/to/agent/agent.csproj" />
</ItemGroup>
Quick Start
1. Implement the IAcpAgent Interface
using dotacp.agent;
using dotacp.protocol;
using System.Threading;
using System.Threading.Tasks;
public class MyAcpAgent : IAcpAgent
{
private Connection? _connection;
public void OnClientConnected(Connection connection)
{
_connection = connection;
// Agent is now connected to the client
}
public async Task<InitializeResponse> InitializeAsync(
InitializeRequest request,
CancellationToken cancellationToken = default)
{
return new InitializeResponse
{
ProtocolVersion = ProtocolMeta.Version,
AgentCapabilities = new AgentCapabilities
{
LoadSession = true,
PromptCapabilities = new PromptCapabilities
{
Audio = false,
Image = true,
EmbeddedContext = true
}
}
};
}
public async Task<AuthenticateResponse> AuthenticateAsync(
AuthenticateRequest request,
CancellationToken cancellationToken = default)
{
// Implement your authentication logic
// Use request.MethodId to identify which auth method is being used
return new AuthenticateResponse();
}
public async Task<NewSessionResponse> NewSessionAsync(
NewSessionRequest request,
CancellationToken cancellationToken = default)
{
// request.Cwd contains the working directory
// request.McpServers contains MCP server configurations
var sessionId = new SessionId(Guid.NewGuid().ToString());
return new NewSessionResponse
{
SessionId = sessionId,
ConfigOptions = new SessionConfigOption[] { },
Modes = new SessionModeState
{
AvailableModes = new SessionMode[] { },
CurrentModeId = new SessionModeId("default")
}
};
}
public async Task<LoadSessionResponse> LoadSessionAsync(
LoadSessionRequest request,
CancellationToken cancellationToken = default)
{
// Load and restore session state
return new LoadSessionResponse { /* ... */ };
}
public async Task<PromptResponse> PromptAsync(
PromptRequest request,
CancellationToken cancellationToken = default)
{
// Process the prompt from request.Prompt (array of ContentBlock)
// The session ID is in request.SessionId
// Return the stop reason indicating why the agent stopped processing
return new PromptResponse
{
StopReason = StopReason.EndTurn
};
}
public async Task<SetSessionConfigOptionResponse> SetSessionConfigOptionAsync(
SetSessionConfigOptionRequest request,
CancellationToken cancellationToken = default)
{
// Update session configuration
return new SetSessionConfigOptionResponse { };
}
public async Task<SetSessionModeResponse> SetSessionModeAsync(
SetSessionModeRequest request,
CancellationToken cancellationToken = default)
{
// Handle session mode changes
return new SetSessionModeResponse { };
}
public async Task CancelAsync(
CancelNotification notification,
CancellationToken cancellationToken = default)
{
// Handle cancellation requests
}
public async Task<object> ExtMethodAsync(
string method,
object request,
CancellationToken cancellationToken = default)
{
// Handle custom extension methods
throw new NotImplementedException($"Unknown extension method: {method}");
}
Task<CloseSessionResponse> CloseAsync(CloseSessionRequest request,
CancellationToken cancellationToken = default)
{
// Handle session close requests
return Task.FromResult(new CloseSessionResponse { });
}
}
2. Connect the Agent
using System.Diagnostics;
// Start the agent process (in a host application)
var agent = new MyAcpAgent();
var process = Process.Start(/* your agent executable */);
// Create the connection
var connection = Connection.RunAgent(
agent,
process.StandardInput.BaseStream,
process.StandardOutput.BaseStream);
// Wait for the connection to close
await connection.Completion;
Protocol Methods
Your implementation must handle the following methods:
Agent Methods (called by client)
initialize- Handshake and capability negotiationauthenticate- User authenticationsession/new- Create a new sessionsession/load- Load an existing sessionsession/prompt- Process a user promptsession/set_config_option- Update session settingssession/set_mode- Change session modesession/cancel- Cancel an ongoing operation
Using the Connection
After initialization, use the Connection object to call client methods:
// Request permission for an action
var permissionResponse = await _connection!.RequestPermissionAsync(
new RequestPermissionRequest
{
SessionId = sessionId,
Options = new PermissionOption[]
{
new PermissionOption
{
OptionId = "approve",
Name = "Approve",
Kind = PermissionOptionKind.AllowOnce
}
},
ToolCall = new ToolCallUpdate
{
Title = "Create file",
Kind = ToolKind.Tool,
Status = ToolCallStatus.InProgress
}
},
cancellationToken);
// Write a file
await _connection!.WriteTextFileAsync(
new WriteTextFileRequest
{
SessionId = sessionId,
Path = "/tmp/output.txt",
Content = "File content here"
},
cancellationToken);
// Create a terminal
var terminalResponse = await _connection!.CreateTerminalAsync(
new CreateTerminalRequest
{
SessionId = sessionId,
Label = "Build Terminal"
},
cancellationToken);
// Send terminal output
await _connection!.TerminalOutputAsync(
new TerminalOutputRequest
{
TerminalId = terminalResponse.TerminalId,
Output = "Build command output here"
},
cancellationToken);
// Send session updates
await _connection!.SessionUpdateAsync(
new SessionNotification
{
SessionId = sessionId,
State = new SessionState { /* ... */ }
},
cancellationToken);
Error Handling
Implement proper error handling in your protocol method implementations:
public async Task<PromptResponse> PromptAsync(
PromptRequest request,
CancellationToken cancellationToken = default)
{
try
{
// Process the prompt
return new PromptResponse { /* ... */ };
}
catch (OperationCanceledException)
{
// Handle cancellation
throw;
}
catch (Exception ex)
{
// Log and handle errors appropriately
// The RPC layer will marshal exceptions back to the client
throw;
}
}
Extensions
Support custom extension methods not in the core protocol:
public async Task<object> ExtMethodAsync(
string method,
object request,
CancellationToken cancellationToken = default)
{
switch (method)
{
case "custom.analyze":
// Handle custom analyze method
return new { result = "analyzed" };
default:
throw new NotImplementedException($"Unknown method: {method}");
}
}
Best Practices
- Cancellation Tokens: Always respect
CancellationTokenin async methods - Error Handling: Properly handle and log exceptions
- Resource Management: Clean up resources in
OnClientConnectedif needed - Timeouts: Consider implementing timeouts for long-running operations
- Logging: Use structured logging to track protocol interactions
License
Licensed under the Apache License 2.0. See the LICENSE file for details.
See Also
- dotacp.protocol - Protocol definitions
- dotacp.client - Client implementation guide
- Agent Client Protocol Specification
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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 is compatible. 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 is compatible. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 is compatible. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.7.2
- dotacp.protocol (>= 2026.5.10)
- StreamJsonRpc (>= 2.7.76)
-
.NETStandard 2.0
- dotacp.protocol (>= 2026.5.10)
- StreamJsonRpc (>= 2.7.76)
-
net10.0
- dotacp.protocol (>= 2026.5.10)
- StreamJsonRpc (>= 2.7.76)
-
net8.0
- dotacp.protocol (>= 2026.5.10)
- StreamJsonRpc (>= 2.7.76)
-
net9.0
- dotacp.protocol (>= 2026.5.10)
- StreamJsonRpc (>= 2.7.76)
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.5.10 | 102 | 5/10/2026 |
| 2026.3.18 | 103 | 3/18/2026 |
| 2026.3.12-beta.1 | 63 | 3/12/2026 |
| 0.1.0-beta.2 | 60 | 3/9/2026 |
| 0.1.0-beta.1 | 65 | 3/5/2026 |
| 0.1.0-alpha.4 | 63 | 3/3/2026 |
| 0.1.0-alpha.3 | 60 | 3/2/2026 |
| 0.1.0-alpha.2 | 66 | 3/2/2026 |