Skip to content

Intelligent-Internet/opencode-a2a-server

Repository files navigation

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 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
  • systemd multi-instance deployment and lightweight current-user 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.

  • 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, and isolated credentials.

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["systemd and lightweight deployment scripts"]
    Runtime --> Workspace["Shared workspace / environment boundary"]
Loading

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:

Quick Start & Development

  1. Start OpenCode:
opencode serve
  1. Install dependencies:
uv sync --all-extras
  1. Start this service:
A2A_BEARER_TOKEN=dev-token uv run opencode-a2a-server

Default address: http://127.0.0.1:8000

Baseline validation:

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

Documentation Map

  • docs/guide.md Product behavior, API contracts, and detailed streaming/session/interrupt consumption guidance.
  • docs/agent_deploy_sop.md Operator-facing SOP for choosing, starting, verifying, and releasing deploy.sh vs deploy_light.sh.
  • scripts/README.md Entry points for init, deploy, lightweight deploy, local start, and uninstall scripts.
  • scripts/deploy_readme.md systemd deployment, runtime secret strategy, and operations guidance.
  • scripts/deploy_light_readme.md current-user lightweight deployment without systemd.
  • SECURITY.md threat model, deployment caveats, and vulnerability disclosure guidance.

License

Apache-2.0. See LICENSE.

About

An adapter layer that exposes OpenCode as an A2A service.

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors