Automatic A2A Protocol Adapter for apcore Module Registry
Project description
apcore-a2a (Python)
What is apcore-a2a?
apcore-a2a is the A2A (Agent-to-Agent) protocol adapter for the apcore ecosystem.
It solves a common problem: you've built AI capabilities with apcore modules, but you need them to talk to other AI agents over a standard protocol. apcore-a2a bridges that gap — it reads your existing module metadata (schemas, descriptions, examples) and automatically exposes them as a standards-compliant A2A server. No hand-written Agent Cards, no JSON-RPC boilerplate, no manual task lifecycle management.
In short: apcore modules + apcore-a2a = a fully functional A2A agent, ready to be discovered and invoked by any A2A-compatible client.
Also available in TypeScript:
apcore-a2a(npm)
Features
- One-call server — launch a compliant A2A server with
serve(registry) - Automatic Agent Card —
/.well-known/agent.jsongenerated from module metadata - Skill mapping — apcore modules become A2A Skills with names, descriptions, tags, and examples;
metadata["display"]["a2a"]overrides surface-facing fields (§5.13) - Full task lifecycle — submitted, working, completed, failed, canceled, input-required
- SSE streaming —
message/streamwith real-time status and artifact updates - Push notifications — optional webhook delivery of task state changes
- JWT authentication — tokens bridged to apcore's Identity context
- A2A Explorer UI — browser UI for discovering and testing skills
- Built-in client —
A2AClientfor calling remote A2A agents - Pluggable storage — swap in Redis or PostgreSQL via the
TaskStoreprotocol - Observability —
/health,/metricsendpoints, structured logging - Dynamic registration — add/remove modules at runtime without restart
Requirements
- Python >= 3.11
apcore>= 0.14.0
For Users: Getting Started
Installation
pip install apcore-a2a
Expose your modules as an A2A Agent
If you already have apcore modules, a few lines turn them into a discoverable agent:
from apcore import Executor, Registry
from apcore_a2a import serve
registry = Registry(extensions_dir="./extensions")
registry.discover()
serve(Executor(registry)) # Starts on http://0.0.0.0:8000
Your agent is now live at http://localhost:8000/.well-known/agent.json.
Try the Examples
Run all 5 example modules (3 class-based + 2 binding YAML) with the Explorer UI:
PYTHONPATH=./examples/binding_demo python examples/run.py
Open http://127.0.0.1:8000/explorer/ to browse skills, send messages, and stream responses.
See examples/README.md for more options (CLI, binding-only, JWT auth).
Call a remote A2A Agent
Use the built-in client to discover and invoke any A2A-compliant agent:
import asyncio
from apcore_a2a import A2AClient
async def main():
async with A2AClient("http://remote-agent:8000") as client:
# Discover what the agent can do
card = await client.discover()
print(f"Agent: {card['name']}, Skills: {len(card['skills'])}")
# Send a message
task = await client.send_message(
{"role": "user", "parts": [{"kind": "text", "text": "Hello!"}]},
skill_id="my.skill",
)
print(f"Result: {task['status']['state']}")
# Or stream the response
async for event in client.stream_message(...):
print(event)
asyncio.run(main())
Add authentication
from apcore_a2a import serve
from apcore_a2a.auth.jwt import JWTAuthenticator, ClaimMapping
auth = JWTAuthenticator(
key="your-secret-key",
algorithms=["HS256"],
issuer="https://auth.example.com",
audience="my-agent",
claim_mapping=ClaimMapping(
id_claim="sub",
type_claim="type",
roles_claim="roles",
attrs_claims=["org", "dept"],
),
require_claims=["sub"],
)
serve(registry, auth=auth)
For Developers: API Reference
serve()
Blocking call — starts uvicorn and serves until SIGINT/SIGTERM.
from apcore_a2a import serve
serve(
registry_or_executor, # apcore Registry or Executor
*,
host="0.0.0.0",
port=8000,
name=None, # Agent name (fallback: registry config)
description=None, # Agent description
version=None, # Agent version
url=None, # Public URL (default: f"http://{host}:{port}")
auth=None, # Authenticator instance
task_store=None, # TaskStore instance (default: InMemoryTaskStore)
cors_origins=None, # List of allowed CORS origins
push_notifications=False,
explorer=False, # Enable A2A Explorer UI
explorer_prefix="/explorer",
cancel_on_disconnect=True,
shutdown_timeout=30,
execution_timeout=300,
log_level=None,
metrics=False, # Enable /metrics endpoint
)
async_serve()
Returns the ASGI app without starting a server — use for embedding in larger applications.
from apcore_a2a import async_serve
app = await async_serve(registry_or_executor, **kwargs)
# app is a Starlette ASGI application
TaskStore
Default in-memory task store. Implement the TaskStore protocol for persistent backends (Redis, PostgreSQL, etc.).
from apcore_a2a.storage.memory import InMemoryTaskStore
store = InMemoryTaskStore()
serve(registry, task_store=store)
Architecture
apcore-a2a acts as a thin protocol layer on top of apcore. The mapping is straightforward:
| A2A Concept | apcore Mapping |
|---|---|
| Agent Card | Derived from Registry configuration |
| Skill id | module_id |
| Skill name | metadata["display"]["a2a"]["alias"] or humanized module_id |
| Skill desc | metadata["display"]["a2a"]["description"] or module.description |
| Skill tags | metadata["display"]["tags"] or module.tags |
| Task | Managed execution of Executor.call_async() |
| Streaming | Wrapped Executor.stream() via SSE |
| Security | Bridged to apcore's Identity context |
Contributing
git clone https://github.com/aiperceivable/apcore-a2a-python.git
cd apcore-a2a-python
pip install -e ".[dev]"
pytest
Documentation
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file apcore_a2a-0.3.0.tar.gz.
File metadata
- Download URL: apcore_a2a-0.3.0.tar.gz
- Upload date:
- Size: 142.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
241d795b4677f3657fe68b714b90b041f9149abc2cf2e47a056c2a10fe449dc1
|
|
| MD5 |
2b5c2a9a34aa98cd0b8ce2efc7e079d4
|
|
| BLAKE2b-256 |
ce9036d526c9d759bb0e285fa218c1a8219508e4ae1c32a8448a8841c0f36877
|
File details
Details for the file apcore_a2a-0.3.0-py3-none-any.whl.
File metadata
- Download URL: apcore_a2a-0.3.0-py3-none-any.whl
- Upload date:
- Size: 42.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fffaeba2c3518d1075b850664495c2766a3be40e5621ab1cd66be3e71758d566
|
|
| MD5 |
6bf5c10c103ff51869889d75efddbaa7
|
|
| BLAKE2b-256 |
53a547d27ab4c67126c75dbf29700d4eb428c1f88ca8f2b0ac96a825ca4010e3
|