The secret sauce that powers Agentic Development Environments (ADEs) like Kepler is a little thing called the Agent Client Protocol (ACP). In this context, Kepler is the Client and harnesses like Claude Code and the Codex CLI are the Agents. We’re going to go over some of the details about how it works, how we use it at GitKraken, and how the protocol may be changing for the better.
ACP vs MCP
One of the things that came up in my stream chat recently while researching ACP was how the ACP is different from the MCP. For context, MCP is how agents communicate with third party services or local CLIs in a standardized way. Meanwhile the ACP is how the “Orchestrator” like Kepler communicates witht he Agent or harness. This poorly made diagram might help illustrate the point.
Sessions
The core thing that ACP handles is the creation and handling of sessions. Sessions are your conversations with harnesses. There are functions within the specification for listing, creating, resuming, and closing sessions.
Transports and JSON-RPC Schema
In all cases, ACP communicates via a JSON-RPC 2.0 protocol to local harnesses. The protocol uses simple JSON payloads like this:
{
"jsonrpc": "2.0",
"id": 1,
"method": "session/new",
"params": {
"cwd": "/home/user/project",
"mcpServers": [
{
"name": "filesystem",
"command": "/path/to/mcp-server",
"args": ["--stdio"],
"env": []
}
]
}
}
In the snippet above, you can see what starting a new session via ACP looks like. The new session even has the ability to pass available MCP servers. Most clients don’t do it, but it would be really cool to be able to dynamically discover MCP servers to prevent from polluting the context window too much, which is something many people like to complain about when talking about MCP vs Skills. We don’t have an official plan for this yet with Kepler, but it’s something I am pushing for. SO, stay tuned on that front.
Another thing that people might not be aware of is that the ACP supports remote agents as well. So, you can communicate easily with instances of Claude Code, Codex, or OpenCode living on remote servers/sandboxes. However, remote support is still in development and may change or evolve over time.
Extensibility
One thing I thought was interesting was the ability for extensibility. This allows clients and agents alike to build their own custom functionality into their tools and products. It lives in the _meta property of messages. An example from the docs shows how Zed can pass a debugMode boolean which they can use to enhance their developer experience.
{
"jsonrpc": "2.0",
"id": 1,
"method": "session/prompt",
"params": {
"sessionId": "sess_abc123def456",
"prompt": [
{
"type": "text",
"text": "Hello, world!"
}
],
"_meta": {
"traceparent": "00-80e1afed08e019fc1110464cfa66635c-7a085853722dc6d2-01",
"zed.dev/debugMode": true
}
}
}
There is also a traceparent prop to aid in observability. But one thing to be aware of is that these are very specific to each agent and client and are simply there for customization. There is no standard for these meta props other than the schema value of { [key: string]: unknown }.
v1 vs v2
Implementers of the protocol should probably be aware of changes coming to the specification. A v2 is in the works with some much needed updates. There are a number of changes but my favorite is the change around how prompts interact with “turns”. More specifically, in the current v1 form of the spec a prompt ends the turn with the agent. That makes sense when we think about how tools and applications were focused when LLMs became the thing we think about when it comes to AI. But, modern tools like Claude Code allow you to jump into the thread and thinking preemptively with messages that can steer its direction. This benefits all of us as users because I think we are well aware of the tendency for AI to go off on tangents that we never intended.
The beauty of the docs and spec is that clients and agents alike can conform to v1 and v2 concurrently. This section from the docs is so helpful:
Supporting both versions is the recommended path, not an edge case: v1 peers will remain in the wild well after v2 stabilizes, and dropping v1 support means losing them. Version negotiation gives you one protocol version per connection, so the cleanest approach is to keep two thin protocol surfaces behind shared application logic and select one after initialize.
Wrapping Up
This post was by no means comprehensive about the subject of ACP and all of the things that make it possible to communicate between Clients/Apps to Agents/Harnesses. But, I hope it was an interesting read and I hope it sparked your curiosity to dig deeper yourself. I would be remiss to mention that you should probably check out Kepler. We need your feedback to help make it the best way to manage concurrent work for all of your AI workflows and I think you will be pleasantly suprised by some of the things our team is cooking up behind the scenes.
GitKraken MCP
GitKraken Insights