Skip to main content

A2A wrapper service for opencode

Project description

opencode-a2a-server

Turn OpenCode into a stateful A2A service with a clear runtime boundary and production-friendly deployment workflow.

opencode-a2a-server exposes OpenCode through standard A2A interfaces and adds the operational pieces that raw agent runtimes usually do not provide by default: authentication, session continuity, streaming contracts, interrupt handling, deployment tooling, and explicit security guidance.

Why This Project Exists

OpenCode is useful as an interactive runtime, but applications and gateways need a stable service layer around it. This repository provides that layer by:

  • bridging A2A transport contracts to OpenCode session/message/event APIs
  • making session and interrupt behavior explicit and auditable
  • packaging release-first deployment scripts and operational guidance for long-running use

What It Already Provides

  • A2A HTTP+JSON endpoints (/v1/message:send, /v1/message:stream, GET /v1/tasks/{task_id}:subscribe)
  • A2A JSON-RPC endpoint (POST /) for standard methods and OpenCode-oriented extensions
  • SSE streaming with normalized text, reasoning, and tool_call blocks
  • session continuation via metadata.shared.session.id
  • request-scoped model selection via metadata.shared.model
  • OpenCode session query/control extensions and provider/model discovery
  • released CLI install/upgrade flow and release-based systemd deployment

Extension Capability Overview

The Agent Card declares six extension URIs. Shared contracts are intended for any compatible consumer; OpenCode-specific contracts stay provider-scoped even though they are exposed through A2A JSON-RPC.

Extension URI Scope Primary use
urn:a2a:session-binding/v1 Shared Bind a main chat request to an existing upstream session via metadata.shared.session.id
urn:a2a:model-selection/v1 Shared Override the default upstream model for one main chat request
urn:a2a:stream-hints/v1 Shared Advertise canonical stream metadata for blocks, usage, interrupts, and session hints
urn:opencode-a2a:session-query/v1 OpenCode-specific Query external sessions and invoke OpenCode session control methods
urn:opencode-a2a:provider-discovery/v1 OpenCode-specific Discover normalized OpenCode provider/model summaries
urn:a2a:interactive-interrupt/v1 Shared Reply to interrupt callbacks observed from stream metadata

Detailed consumption guidance:

Design Principle

One OpenCode + opencode-a2a-server instance pair is treated as a single-tenant trust boundary.

This repository's intended scaling model is parameterized self-deployment: consumers should launch their own isolated instance pairs through the provided deployment scripts instead of sharing one runtime across mutually untrusted tenants.

  • OpenCode may manage multiple projects/directories, but one deployed instance is not a secure multi-tenant runtime.
  • Shared-instance identity/session checks are best-effort coordination, not hard tenant isolation.
  • For mutually untrusted tenants, deploy separate instance pairs with isolated Linux users or containers, isolated workspace roots, isolated credentials, and distinct runtime ports.

Logical Components

flowchart TD
    Hub["A2A client / a2a-client-hub / app"] --> Api["opencode-a2a-server transport"]
    Api --> Mapping["Task / session / interrupt mapping"]
    Mapping --> Runtime["OpenCode HTTP runtime"]

    Api --> Auth["Bearer auth + request logging controls"]
    Api --> Deploy["release-based deployment tooling"]
    Runtime --> Workspace["Shared workspace / environment boundary"]

This repository wraps OpenCode in a service layer. It does not change OpenCode into a hard multi-tenant isolation platform.

Recommended Client Side

If you need a client-side integration layer to consume this service, prefer a2a-client-hub.

It is a better place for client concerns such as A2A consumption, upstream adapter normalization, and application-facing integration, while opencode-a2a-server stays focused on the server/runtime boundary around OpenCode.

Security Model

This project improves the service boundary around OpenCode, but it is not a hard multi-tenant isolation layer.

  • A2A_BEARER_TOKEN protects the A2A surface, but it is not a tenant isolation boundary inside one deployed instance.
  • LLM provider keys are consumed by the OpenCode process. Prompt injection or indirect exfiltration attempts may still expose sensitive values.
  • systemd deploy defaults use operator-provisioned root-only secret files unless ENABLE_SECRET_PERSISTENCE=true is explicitly enabled.

Read before deployment:

User Paths

Released versions are published to PyPI and mapped to Git tags / GitHub Releases. This is the recommended entry point for users.

Path 1: Run a Released CLI in an Existing User Environment

Install the latest release:

uv tool install opencode-a2a-server

Upgrade an existing installation:

uv tool upgrade opencode-a2a-server

Install an exact release:

uv tool install "opencode-a2a-server==<version>"

Run it against an existing project/workspace:

GOOGLE_GENERATIVE_AI_API_KEY=<your-key> \
OPENCODE_PROVIDER_ID=google \
OPENCODE_MODEL_ID=gemini-3.1-pro-preview \
opencode serve

A2A_BEARER_TOKEN=prod-token \
A2A_PUBLIC_URL=http://127.0.0.1:8000 \
OPENCODE_DIRECTORY=/abs/path/to/workspace \
opencode-a2a-server

Default address: http://127.0.0.1:8000

If you omit OPENCODE_PROVIDER_ID / OPENCODE_MODEL_ID, opencode serve uses your local OpenCode defaults (for example ~/.config/opencode/opencode.json).

For provider-specific auth, model IDs, and config details, use the OpenCode official docs and CLI:

This path is for users who already manage their own shell, workspace, and process lifecycle. No host bootstrap script is required.

Path 2: Formal systemd Deploy From a Released Version

For long-running systemd deployments, use the release-based scripts:

./scripts/init_release_system.sh
./scripts/deploy_release.sh project=alpha a2a_port=8010 a2a_host=127.0.0.1

This path is for users who want:

  • isolated Linux users and per-project directories
  • systemd-managed restart behavior
  • root-only secret files
  • published package versions as the deployment boundary

Primary operator docs:

Contributor Paths

Use the repository checkout directly only for development, local debugging, or validation against unreleased changes. Source-based deploy/bootstrap docs are kept for contributors and internal debugging, not as the recommended user path.

Quick source run:

uv sync --all-extras

GOOGLE_GENERATIVE_AI_API_KEY=<your-key> \
OPENCODE_PROVIDER_ID=google \
OPENCODE_MODEL_ID=gemini-3.1-pro-preview \
opencode serve

A2A_BEARER_TOKEN=dev-token \
OPENCODE_DIRECTORY=/abs/path/to/workspace \
uv run opencode-a2a-server

Baseline validation:

uv run pre-commit run --all-files
uv run pytest

Documentation Map

User / Operator Docs

Contributor / Internal Docs

License

Apache-2.0. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

opencode_a2a_server-0.2.1.tar.gz (212.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

opencode_a2a_server-0.2.1-py3-none-any.whl (57.4 kB view details)

Uploaded Python 3

File details

Details for the file opencode_a2a_server-0.2.1.tar.gz.

File metadata

  • Download URL: opencode_a2a_server-0.2.1.tar.gz
  • Upload date:
  • Size: 212.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for opencode_a2a_server-0.2.1.tar.gz
Algorithm Hash digest
SHA256 d2271f6a9850912f69d747c76b42dd3968e2e869ecc757ec8acd06a523b0e20b
MD5 2079a77f69a04384a942e7a8baeae562
BLAKE2b-256 15b1d6e0ff8df2673c2a3eca65e9ffcc9201137a6026748b2520fc411120447f

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencode_a2a_server-0.2.1.tar.gz:

Publisher: publish.yml on Intelligent-Internet/opencode-a2a-server

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opencode_a2a_server-0.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for opencode_a2a_server-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9b42bf81662586a6dc9c09dcd33aebdccf37fb4a2e46011030a8815dd7108b20
MD5 8e0e0e0971d4c401b9e1bd0dd7820595
BLAKE2b-256 09556c7488ddecd2da2380191cd0c7d914b432a1340d47bd22ed7137b342f98e

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencode_a2a_server-0.2.1-py3-none-any.whl:

Publisher: publish.yml on Intelligent-Internet/opencode-a2a-server

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page