Skip to main content

Run Claude Code as an A2A protocol agent server.

Project description

a2claude

a2claude

Run Claude Code as an A2A agent server. Other agents call it over the protocol; it drives a real Claude Code session in your project and streams back the actual work — the tools it runs, the diffs it writes, what it costs, and the permissions it needs.

CI License: Apache 2.0 Python 3.13+ Protocol: A2A 1.0

a2claude streaming a task, then pausing on a permission prompt

Most "wrap a coding agent in A2A" adapters flatten everything to text in, text out. a2claude keeps the parts that matter for the agent on the other end: which tools ran, what files changed, what it cost, and how to continue the same session on the next turn.

How it maps to A2A

Claude Code produces A2A surface it lands on
Assistant text A streamed artifact (append / last_chunk)
A tool call (Bash, Edit) A working status update for the action
A file edit A named artifact carrying the diff
Run result Cost, turns, and usage on the completion message
Session id Mapped to the A2A contextId so follow-ups resume

The mapping lives in one place (executor.py). Backends only emit normalized events; they never touch the protocol.

Requirements

  • Python 3.13+
  • uv
  • Claude Code CLI on PATH (only for the claude backend)

Quick start

Install:

uv sync

The echo backend needs no API key and no Claude install, so you can exercise the whole path offline first:

uv run a2claude serve --backend echo &
# once the "Uvicorn running" line appears:
uv run a2claude call "fix the failing test"
task 189b1c63-1a7b-4908-87c4-c8f3bba8f6b5
context 0b2a901e-2b6f-4c56-bba2-d0da546936e9

  · Echo
fix the failing test
[completed] $0.0 · 1 turns

Then point it at a real project:

uv run a2claude serve --backend claude --cwd /path/to/project
uv run a2claude call "add a /health endpoint" --url http://localhost:9100/

Continue the same conversation by passing the context from a previous turn:

uv run a2claude call "now add a test for it" --context <context-id>

Commands

Command Description
a2claude serve Start the A2A server
a2claude call TEXT Send a message and print the streamed events
a2claude card Fetch and print the agent card

The agent card is served at /.well-known/agent-card.json and advertises Claude Code's abilities as discrete skills (generation, refactor, debug, review, test, explain).

Backends

A backend turns a prompt into a stream of normalized events. Two ship today:

  • echo — no dependencies; mirrors the input. For wiring checks and tests.
  • claude — drives Claude Code through the Claude Agent SDK.

The split keeps the A2A layer independent of how Claude Code is invoked, so a raw-CLI backend can be added later without touching the server or the protocol mapping.

Authentication

The claude backend uses whatever the Claude CLI is configured with. When the server answers on behalf of other agents, that has to be an Anthropic API key (or Bedrock / Vertex) — Anthropic does not permit subscription credentials for third-party serving. Set a per-run cost ceiling with --max-budget-usd.

Permissions

A tool that needs approval pauses the task in the A2A input-required state instead of being skipped. The caller answers with a follow-up message on the same task:

uv run a2claude call "sudo reboot"
# ... [input-required] Permission requested for Bash: $ sudo reboot
#       reply: a2claude call "allow" --task <id> --context <id>
uv run a2claude call "allow" --task <id> --context <id>

allow (or yes, approve, ok) approves; anything else denies. The Claude session stays alive across the pause, so it resumes exactly where it stopped.

The server does not inherit your personal Claude settings, so it has no pre-approved tool allowlist — every tool that needs approval routes through the caller. Read-only actions Claude already treats as safe still run without a prompt.

Long-running tasks

The agent card advertises push notifications. A caller can register a webhook for a task and receive status and artifact updates by HTTP POST instead of holding a stream open — useful when a run takes minutes. Streaming and polling (tasks/get) both work too.

Development

uv sync --dev
uv run ruff check src tests
uv run ruff format src tests
uv run mypy
uv run pytest

CI runs these on Python 3.13 and 3.14, plus a Markdown lint, on every push and pull request.

Releasing

Pushing a v* tag builds the package, creates a GitHub release with the artifacts, and publishes to PyPI via trusted publishing:

git tag v0.1.0
git push origin v0.1.0

Status

The mapping is complete end to end and verified against real Claude: text round trip, tool-progress updates, streaming artifacts, file diffs as artifacts, run metadata, session continuity, the permission → input-required round trip, and push notifications. The offline echo backend covers every path including permissions, so it can all be exercised without an API key.

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

a2claude-0.1.0.tar.gz (15.7 kB view details)

Uploaded Source

Built Distribution

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

a2claude-0.1.0-py3-none-any.whl (20.5 kB view details)

Uploaded Python 3

File details

Details for the file a2claude-0.1.0.tar.gz.

File metadata

  • Download URL: a2claude-0.1.0.tar.gz
  • Upload date:
  • Size: 15.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for a2claude-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ba240b5dc323205380a19886ed3f862fb4eaca07ee6a6d5d0e3ea2b408e10183
MD5 0f20c618eb6e354fd5f495b3bf41b01f
BLAKE2b-256 e1b1e0254b69d55006b76ed9b6a2b6e17fbb1edeed69a6df49eed4eacb699d78

See more details on using hashes here.

File details

Details for the file a2claude-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: a2claude-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 20.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for a2claude-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8032b8a087dae60149752bb23dd0fa566ebe95f8b4a801b2ce00d784b016029c
MD5 1f2ec7e6ef5011aa875158e133138497
BLAKE2b-256 a796c863eb62076036a0715e611b3e11b906422982d896a6b33771442f402173

See more details on using hashes here.

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