Expose OpenCode through A2A.
opencode-a2a adds an A2A runtime layer to opencode serve, with
auth, streaming, session continuity, interrupt handling, and a clear
deployment boundary.
- An A2A adapter service built on
opencode serve, with inbound runtime exposure plus outbound peer calling. - It supports both roles in one process: serving as an A2A Server and hosting an
embedded A2A Client for
a2a_call.
flowchart TD
External["A2A Clients / a2a-client-hub / Gateways"]
subgraph Adapter["opencode-a2a Runtime"]
Ingress["Inbound A2A Surface\nREST + JSON-RPC"]
OpenCode["OpenCode Runtime"]
Outbound["Embedded A2A Client\na2a_call"]
end
subgraph Peers["Peer A2A services"]
PeerA2A["Peer A2A Agent"]
PeerRuntime["Peer OpenCode Runtime"]
PeerA2A --> PeerRuntime
end
External -->|message/send,\nmessage:stream| Ingress
Ingress -->|tool call| OpenCode
OpenCode -->|model/tool result events| Ingress
Ingress -->|a2a_call| Outbound
Outbound -->|message/send,\nmessage:stream| PeerA2A
PeerA2A -->|tool result| Outbound
PeerRuntime -->|task session\nexecution| PeerA2A
Install the released CLI with uv tool:
uv tool install opencode-a2aUpgrade later with:
uv tool upgrade opencode-a2aMake sure provider credentials and a default model are configured on the OpenCode side, then start OpenCode:
opencode auth login
opencode models
opencode serve --hostname 127.0.0.1 --port 4096Treat the deployed OpenCode user's HOME/XDG config directories as part of the runtime state. If a packaged or service-managed deployment appears to ignore fresh provider env vars, inspect that user's persisted OpenCode auth/config files before assuming the A2A adapter layer is overriding credentials.
Then start opencode-a2a against that upstream:
A2A_BEARER_TOKEN=dev-token \
OPENCODE_BASE_URL=http://127.0.0.1:4096 \
A2A_HOST=127.0.0.1 \
A2A_PORT=8000 \
A2A_PUBLIC_URL=http://127.0.0.1:8000 \
OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \
opencode-a2aVerify that the service is up:
curl http://127.0.0.1:8000/.well-known/agent-card.json- A2A HTTP+JSON endpoints such as
/v1/message:sendand/v1/message:stream - A2A JSON-RPC support on
POST / - Peering capabilities: can act as a client via
opencode-a2a call - Autonomous tool execution: supports
a2a_calltool for outbound agent-to-agent communication - SSE streaming with normalized
text,reasoning, andtool_callblocks - Session continuity through
metadata.shared.session.id - Request-scoped model selection through
metadata.shared.model - OpenCode-oriented JSON-RPC extensions for session and model/provider queries
opencode-a2a supports a "Peering Node" architecture where a single process handles both inbound (Server) and outbound (Client) A2A traffic.
Interact with other A2A agents directly from the command line:
opencode-a2a call http://other-agent:8000 "How are you?" --token your-outbound-tokenThe server can autonomously execute a2a_call(url, message) tool calls emitted by the OpenCode runtime. Results are fetched via A2A and returned to the model as tool results, enabling multi-agent orchestration.
When the target peer requires bearer auth, configure A2A_CLIENT_BEARER_TOKEN
for server-side outbound calls. CLI calls can continue using --token or
A2A_CLIENT_BEARER_TOKEN.
Server-side outbound client settings are fully wired through runtime config:
A2A_CLIENT_TIMEOUT_SECONDS, A2A_CLIENT_CARD_FETCH_TIMEOUT_SECONDS,
A2A_CLIENT_USE_CLIENT_PREFERENCE, A2A_CLIENT_BEARER_TOKEN, and
A2A_CLIENT_SUPPORTED_TRANSPORTS.
Detailed protocol contracts, examples, and extension docs live in
docs/guide.md.
Use this project when:
- you want to keep OpenCode as the runtime
- you need A2A transports and Agent Card discovery
- you want a thin service boundary instead of building your own adapter
Look elsewhere if:
- you need hard multi-tenant isolation inside one shared runtime
- you want this project to manage your process supervisor or host bootstrap
- you want a general client integration layer rather than a server wrapper
For client-side integration, prefer a2a-client-hub.
This repository improves the service boundary around OpenCode, but it does not turn OpenCode into a hardened multi-tenant platform.
A2A_BEARER_TOKENprotects the A2A surface.- Provider auth and default model configuration remain on the OpenCode side; deployment-time precedence details and HOME/XDG state impact are documented in docs/guide.md.
- Use
A2A_CLIENT_BEARER_TOKENfor server-side outbound peer calls initiated bya2a_call. - Deployment supervision is intentionally BYO. Use
systemd, Docker, Kubernetes, or another supervisor if you need long-running operation. - For mutually untrusted tenants, run separate instance pairs with isolated users, containers, workspaces, credentials, and ports.
Read before deployment:
- docs/guide.md Usage guide, transport details, streaming behavior, extensions, and examples.
- SECURITY.md Threat model, deployment caveats, and vulnerability disclosure guidance.
For contributor workflow, local validation, and helper scripts, see CONTRIBUTING.md and scripts/README.md.
Apache-2.0. See LICENSE.