claude-a2a
与A2A兼容的服务器,封装 克劳德代码CLI,使任何A2A客户端能够向机器上的Claude代理发送消息并接收响应。支持多模式输入(图像、PDF)、会话连续性、多代理配置和成本跟踪。还包括一个MCP客户端,以便交互式Claude Code会话可以本地调用远程代理。
这解决了什么问题?
运行在不同机器上的Claude Code代理没有内置的相互通信方式。MCP中没有推送机制,无法将消息注入活动的Claude Code会话,也没有桥接单独Claude实例的标准协议。
claude-a2a 通过暴露本地 claude CLI作为使用A2A协议的网络服务。任何可以通过HTTP到达服务器的机器都可以向Claude发送消息并获得响应,包括会话连续性、成本跟踪和访问控制。
协议
claude-a2a实现了两个协议:
A2A(代理人对代理人)
服务器公开JSON-RPC和REST传输:
POST /a2a/jsonrpc--A2A JSON-RPC 2.0端点/a2a/rest/v1/...--A2A REST端点GET /.well-known/agent-card.json--用于发现的代理卡
MCP(模型上下文协议)
主控程序 是Anthropic的协议,用于让AI模型访问工具和数据。所包含的MCP客户端作为Claude Code可以连接的stdio服务器运行,为调用远程Claude-a2a服务器提供交互式Claude会话工具。
运作原理
Remote Agent / A2A Client
|
| A2A Protocol (HTTP)
v
+------------------+
| claude-a2a | Express + @a2a-js/sdk
| |
| Agent Card | /.well-known/agent-card.json
| Auth layer | Master key / JWT tokens
| Rate limiter |
| Budget tracker |
| Claude Session | Long-lived claude CLI process (stream-json NDJSON I/O)
+------------------+
|
v
Claude CLI (local)服务器使用以下命令在每个会话中生成一个长期存在的Claude CLI进程 --input-format stream-json --output-format stream-json。消息在stdin上以NDJSON格式发送,结果从stdout读取。会话连续性是通过在消息之间保持进程活动来维护的 --resume 用于重启后的恢复。
| A2A概念 | claude-A2A实施 |
|---|---|
| 代理卡 | 描述每个配置的Claude代理 |
| 消息(用户) | 以NDJSON格式写入Claude进程stdin |
| 消息(代理) | 从Claude进程stdout结果解析 |
| 任务上下文 | 映射到长期存在的Claude CLI会话 |
| 技能 | 代理配置(工具、模型、描述) |
每个响应都包括消息中特定于Claude的元数据(会话ID、令牌使用、成本、使用的模型) metadata.claude 现场。
多模态输入
claude-a2a支持通过a2a向claude发送图像、PDF和结构化数据 FilePart 和 DataPart 消息类型:
| A2A零件类型 | 克劳德内容块 |
|---|---|
TextPart | 纯文本(或 { type: "text" } 块) |
FilePart (图像MIME+base64) | { type: "image", source: { type: "base64" } } |
FilePart (PDF/其他MIME+base64格式) | { type: "document", source: { type: "base64" } } |
FilePart (URI) | 文本描述(不支持URI下载) |
DataPart | JSON字符串化为文本 |
纯文本消息以纯字符串形式发送,以实现向后兼容性。当存在非文本部分时,消息将作为 ContentBlock[] 阵列。
支持的输入MIME类型在代理卡的 defaultInputModes: text, image/png, image/jpeg, image/gif, image/webp, application/pdf.
安装
# Use directly with npx (no install needed)
CLAUDE_A2A_MASTER_KEY=my-secret-key npx claude-a2a-cli serve --agent my-agent
# Or install globally
npm install -g claude-a2a-cli
CLAUDE_A2A_MASTER_KEY=my-secret-key claude-a2a serve --agent my-agent需求
- Node.js >=18(用24测试)
- 克劳德代码CLI 已安装并验证(
claudePATH中可用的命令)
快速启动
选项A:npx(不需要克隆)
# Scaffold a config in the current directory
npx claude-a2a-cli init --yes
# Start the server
CLAUDE_A2A_MASTER_KEY=my-secret-key npx claude-a2a-cli serve选项B:单代理模式(根本没有配置文件)
# Start a single agent directly from CLI flags
CLAUDE_A2A_MASTER_KEY=my-secret-key npx claude-a2a-cli serve \
--agent my-agent \
--work-dir ./my-project \
--model claude-sonnet-4-6 \
--max-budget 5.0选项C:克隆和构建
cd claude-a2a
npm install
npm run build
# Start with a master key for auth
CLAUDE_A2A_MASTER_KEY=my-secret-key ./dist/cli.js serve验证它是否正常工作
# Check health
curl http://localhost:8462/health
# View the agent card
curl http://localhost:8462/.well-known/agent-card.json
# Send a message
curl -X POST http://localhost:8462/a2a/jsonrpc \
-H "Authorization: Bearer my-secret-key" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": "1",
"method": "message/send",
"params": {
"message": {
"kind": "message",
"messageId": "msg-1",
"role": "user",
"parts": [{"kind": "text", "text": "What is 2+2?"}]
},
"configuration": {"blocking": true}
}
}'注: 如果从Claude Code会话中运行CLAUDECODE环境变量将导致生成的Claude进程立即退出。在单独的终端中启动服务器或使用env -u CLAUDECODE -u CLAUDE_CODE_ENTRYPOINT使其不稳定。
配置
配置服务器有三种方法:
1. init 命令(建议用于新项目)
claude-a2a init # interactive prompts
claude-a2a init --yes # non-interactive with defaults
claude-a2a init --yes -d ./my-project # specify target directory这个脚手架a config.yaml 和一个 .claude/settings.json 具有工具权限。
2.单代理CLI标志(无配置文件)
claude-a2a serve --agent [options]| 标志 | 描述 |
|---|---|
--agent | 代理名称(启用单代理模式) |
| `--work-dir | |
| ` | 代理工作目录 |
--model | 克劳德模型(例如。 claude-sonnet-4-6) |
--permission-mode | 权限模式(默认: default) |
--system-prompt | 系统提示 |
--max-budget | 每次调用的最大预算(美元) |
当 --agent 设置后,服务器将完全跳过配置文件查找。数据存储在 ./data 默认情况下。
3.YAML配置文件
服务器按以下顺序查找配置文件:
- 通过的路径
--config/-c旗帜 ./config.yaml在当前目录中/etc/claude-a2a/config.yaml
如果找不到文件,则使用合理的默认值。复制 config/example.yaml 开始:
cp config/example.yaml config.yaml环境变量
机密应该通过环境变量设置,而不是在配置文件中设置:
| 变量 | 目的 |
|---|---|
CLAUDE_A2A_MASTER_KEY | 主身份验证密钥(完全访问) |
CLAUDE_A2A_JWT_SECRET | 签名/验证JWT令牌的秘密 |
CLAUDE_A2A_PORT | 覆盖服务器端口(默认值:8462) |
CLAUDE_A2A_DATA_DIR | 覆盖数据目录(默认: /var/lib/claude-a2a 或 ./data 在单代理模式下) |
CLAUDE_A2A_CONFIG | 覆盖配置文件路径 |
LOG_LEVEL | 日志记录级别: debug, info, warn, error (默认值: info) |
关键配置部分
服务器 --主机、端口、TLS、最大并发克劳德进程数、请求超时、最大正文大小(默认值 10mb 支持base64编码文件)。
认证 --主密钥和JWT设置。如果两者都没有配置,则服务器允许未经身份验证的访问。
费率限制 --令牌桶速率限制器。每个客户端,每分钟可配置的请求数和突发数。
预算 --每日支出限额(全球和每个客户),以防止成本失控。
会话 --最大会话寿命、空闲超时和每个客户端会话限制。
克劳德 --通往 claude 二进制、默认模型、默认权限模式和工作目录。
代理 --最重要的部分。这就是你定义代理人的地方。
代理
在A2A协议中 代理卡 是一个JSON文档,描述代理可以做什么。它在一个众所周知的URL上提供(/.well-known/agent-card.json)以便其他代理和工具可以在发送消息之前发现和理解代理的功能。
claude-a2a自动生成代理卡 agents 配置的一部分。每个条目 agents 成为a 技能 在卡上。
定义代理
每个代理都是一个命名配置,用于控制Claude在接收该代理的消息时的行为。以下是一个完整的示例:
agents:
general:
description: "General-purpose Claude assistant"
enabled: true
model: null # null = use Claude's default model
append_system_prompt: "You are responding via the claude-a2a A2A API. Be concise."
settings_file: null # path to a Claude Code settings.json file
permission_mode: "default" # Claude's permission mode
allowed_tools: [] # passed as --allowedTools to the CLI
max_budget_usd: 1.0 # max spend per invocation
required_scopes: # JWT scopes needed to use this agent
- "agent:general"
work_dir: null # working directory (null = use global default)代理配置字段
| 字段 | 描述 |
|---|---|
description | 人类可读的描述。出现在代理卡中。 |
enabled | 设置为 false 禁用代理而不删除其配置。 |
model | 使用克劳德模型(例如。 claude-sonnet-4-6). null 使用CLI默认值。 |
append_system_prompt | 附加到克劳德系统提示中的此代理的额外说明。 |
settings_file | Claude Code设置JSON文件的路径。 在无头模式下授予工具权限时需要。 看 权限. |
permission_mode | 克劳德的许可模式。看 权限. |
allowed_tools | 传递的工具列表 --allowedTools 到CLI(例如。 ["Bash(git:*)"]). |
max_budget_usd | 每次调用的最大支出(美元)。 |
required_scopes | 调用此代理需要JWT作用域。忽略主密钥身份验证。 |
work_dir | 克劳德的工作目录。确定Claude可以查看哪些文件。 |
示例:多个代理
agents:
general:
description: "General-purpose assistant for questions and research"
enabled: true
max_budget_usd: 0.50
required_scopes: ["agent:general"]
code:
description: "Code assistant that can read, write, and run code"
enabled: true
model: "claude-sonnet-4-6"
append_system_prompt: "You are a code assistant. Focus on writing clean, correct code."
settings_file: "/home/projects/my-app/.claude/settings.json"
permission_mode: "default"
max_budget_usd: 5.0
required_scopes: ["agent:code"]
work_dir: "/home/projects/my-app"
reviewer:
description: "Code reviewer that reads code and provides feedback"
enabled: true
max_budget_usd: 1.0
required_scopes: ["agent:reviewer"]
work_dir: "/home/projects/my-app"客户端通过包括以下内容来定位特定代理 "metadata": {"agent": "code"} 在他们的信息中。如果未指定代理,则使用第一个启用的代理。
查看代理卡
服务器运行后,查看生成的代理卡:
curl http://localhost:8462/.well-known/agent-card.json这将返回完整的A2A代理卡JSON,包括所有已启用的代理作为技能、支持的身份验证方案和能力声明。
权限
Claude CLI的权限系统控制代理可以使用哪些工具。这对于无头(非交互式)操作至关重要,因为没有人来批准权限提示。
权限模式
这 permission_mode 现场地图 --permission-mode 在CLI上:
| 模式 | 行为 |
|---|---|
default | 自动批准阅读。Writes和Bash需要在设置文件中明确允许规则。 建议无头使用。 |
acceptEdits | 自动批准项目目录中的文件读取和写入。阻止Bash。 |
plan | 进入规划工作流程——不适合无头使用。 |
dontAsk | 拒绝使用通常会提示的所有工具。 |
bypassPermissions | 允许一切。 以root身份运行时无法使用。 |
设置文件(推荐方法)
授予无头操作权限的最可靠方法是通过Claude Code设置文件。集 settings_file 在代理配置中指向它,并使用 permission_mode: "default":
{
"permissions": {
"allow": [
"Read",
"Edit",
"Glob",
"Grep",
"Write"
]
}
}将此文件放置在 /.claude/settings.json 并从代理配置中引用它:
agents:
myagent:
work_dir: "/home/projects/my-app"
settings_file: "/home/projects/my-app/.claude/settings.json"
permission_mode: "default"设置文件 allow 规则授予工具访问权限,否则需要交互式批准。如果没有设置文件,大多数工具将在无头模式下被拒绝。
路径模式: 在设置文件中,/path与设置文件相关。使用//path对于绝对文件系统路径(例如。Write(//tmp/**)).请注意,一些系统路径如下/tmp可能需要毯子工具允许("Write")而不是路径范围的规则。
以root身份运行
bypassPermissions 出于安全考虑,以root身份运行时会阻止该模式。使用 default 使用设置文件切换模式。
认证
claude-a2a支持三层身份验证:
1.万能钥匙
授予完全访问权限的共享密钥。通过设置 CLAUDE_A2A_MASTER_KEY 环境变量。将其作为Bearer代币传递:
curl -H "Authorization: Bearer my-secret-key" http://localhost:8462/admin/stats最适合:同一网络或VPN上的受信任代理。
2.JWT代币
具有每个客户端控件的作用域令牌。使用CLI生成它们:
# Generate a token for "my-agent" with access to the "general" agent
CLAUDE_A2A_JWT_SECRET=your-jwt-secret \
npx claude-a2a-cli token my-agent agent:general
# Generate a token with access to all agents
CLAUDE_A2A_JWT_SECRET=your-jwt-secret \
npx claude-a2a-cli token my-agent '*'智威汤逊的声明可能包括:
scopes--令牌可以访问哪些代理(例如。agent:general,agent:code,或*)budget_daily_usd--每位客户每日支出限额rate_limit_rpm--每个客户端速率限制覆盖
3.无身份验证
如果两者都没有 CLAUDE_A2A_MASTER_KEY 也不 CLAUDE_A2A_JWT_SECRET 设置后,服务器允许未经身份验证的访问。只适合当地发展。
会话连续性
claude-a2a使用a2a在消息之间保持会话连续性 contextId。当您发送第一条消息时,响应包括 contextId。包括同样的内容 contextId 在后续消息中继续同一克劳德会话中的对话:
# First message — note the contextId in the response
RESPONSE=$(curl -s -X POST http://localhost:8462/a2a/jsonrpc \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0", "id": "1",
"method": "message/send",
"params": {
"message": {
"kind": "message", "messageId": "m1", "role": "user",
"parts": [{"kind": "text", "text": "Remember the number 42."}]
},
"configuration": {"blocking": true}
}
}')
# Extract contextId from response
CONTEXT_ID=$(echo "$RESPONSE" | jq -r '.result.contextId')
# Second message — same contextId, Claude remembers the conversation
curl -s -X POST http://localhost:8462/a2a/jsonrpc \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"jsonrpc\": \"2.0\", \"id\": \"2\",
\"method\": \"message/send\",
\"params\": {
\"message\": {
\"kind\": \"message\", \"messageId\": \"m2\", \"role\": \"user\",
\"contextId\": \"$CONTEXT_ID\",
\"parts\": [{\"kind\": \"text\", \"text\": \"What number did I say?\"}]
},
\"configuration\": {\"blocking\": true}
}
}"在幕后,claude-a2a为每个会话保留了一个长期存在的claude CLI进程。如果进程死亡(例如服务器重新启动),它将重新启动 --resume 以恢复对话。
MCP客户端(用于交互式Claude Code会话)
所包含的MCP客户端允许交互式Claude Code会话调用远程Claude-a2a服务器作为工具。这意味着您笔记本电脑上的Claude代理可以要求您服务器上的克劳德代理执行工作。
设置
- 在以下位置创建客户端配置文件
~/.claude-a2a/client.json:
{
"servers": {
"my-server": {
"url": "http://192.168.1.80:8462",
"token": "my-secret-key"
}
}
}- 将MCP服务器添加到项目的
.mcp.json:
{
"mcpServers": {
"claude-a2a": {
"type": "stdio",
"command": "node",
"args": ["/path/to/claude-a2a/dist/client.js"]
}
}
}添加MCP配置后重新启动Claude Code。
可用的MCP工具
一旦连接,Claude Code将获得以下工具:
| 工具 | 说明 |
|---|---|
list_remote_servers | 列出已配置的远程服务器 |
list_remote_agents | 从远程服务器获取代理卡 |
send_message | 向远程代理发送消息并获得响应 |
get_server_health | 检查服务器运行状况和状态 |
list_sessions | 列出活动会话(管理员) |
delete_session | 清理远程会话(管理员) |
管理员API
管理端点需要主密钥身份验证。
# Server stats
curl -H "Authorization: Bearer $MASTER_KEY" http://localhost:8462/admin/stats
# List active sessions
curl -H "Authorization: Bearer $MASTER_KEY" http://localhost:8462/admin/sessions
# Delete a session
curl -X DELETE -H "Authorization: Bearer $MASTER_KEY" \
http://localhost:8462/admin/sessions/
# Create a JWT token
curl -X POST -H "Authorization: Bearer $MASTER_KEY" \
-H "Content-Type: application/json" \
http://localhost:8462/admin/tokens \
-d '{"sub": "my-client", "scopes": ["agent:general"]}'
# Revoke a token
curl -X DELETE -H "Authorization: Bearer $MASTER_KEY" \
http://localhost:8462/admin/tokens/生产部署
生产部署中包含一个systemd服务文件:
# Build
npm run build
# Run the install script (creates user, directories, copies files)
sudo bash scripts/install.sh
# Configure
sudo vim /etc/claude-a2a/config.yaml
sudo vim /etc/claude-a2a/env # set CLAUDE_A2A_MASTER_KEY, CLAUDE_A2A_JWT_SECRET
# Start
sudo systemctl enable --now claude-a2a
# Check status
sudo systemctl status claude-a2a
curl http://localhost:8462/healthsystemd服务在安全强化(只读文件系统、无新权限、受限系统调用)的情况下运行。
发展
# Run in dev mode (uses tsx, no build step)
CLAUDE_A2A_MASTER_KEY=dev-key npm run dev
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Lint
npm run lint
# Build
npm run build项目结构
claude-a2a/
src/
cli.ts # CLI entry point (serve, init, client, token)
init.ts # Interactive config scaffolding
version.ts # Version constant
server/
index.ts # Express server setup, wires everything together
config.ts # YAML config loading + Zod validation
agent-card.ts # Generates A2A Agent Card from config
claude-session.ts # Long-lived Claude CLI process wrapper (NDJSON I/O)
claude-runner.ts # Session pool manager
agent-executor.ts # A2A executor: bridges A2A protocol to Claude Runner
auth/
middleware.ts # Express auth middleware (master key + JWT)
tokens.ts # JWT creation, verification, revocation
user.ts # User context type
services/
database.ts # SQLite connection with migrations
session-store.ts # Tracks Claude sessions by context ID
task-store.ts # A2A task persistence with tenant isolation
rate-limiter.ts # Token-bucket rate limiter
budget-tracker.ts # Daily per-client and global cost tracking
routes/
admin.ts # Token CRUD, session management, stats
health.ts # Health check endpoint
client/
index.ts # MCP client entry point
mcp-server.ts # MCP tool definitions
a2a-client.ts # HTTP client for remote A2A servers
config.ts # Client config loading
tests/ # Vitest unit tests
config/
example.yaml # Example server configuration
systemd/
claude-a2a.service # systemd unit file
scripts/
install.sh # Production install script响应元数据
claude-a2a的每个响应都包含claude特定的元数据 result.metadata.claude:
{
"claude": {
"agent": "general",
"session_id": "7fcfc468-2111-4fc2-97ad-bcb4d91ce0c8",
"context": null,
"cost_usd": 0.014664,
"duration_ms": 1932,
"duration_api_ms": 1859,
"permission_denials": [],
"model_used": "claude-sonnet-4-6",
"num_turns": 1,
"usage": {
"input_tokens": 3,
"output_tokens": 5,
"cache_creation_input_tokens": 816,
"cache_read_input_tokens": 18848
}
}
}这使客户端可以跟踪成本、监视令牌使用情况、检测权限问题和管理会话状态。
建于
- @a2a js/sdk --官方A2A TypeScript SDK(谷歌)
- @模型上下文协议/sdk --MCP TypeScript官方SDK(Anthropic)
- 快递5 --HTTP框架
- 佐德 --配置验证
- 皮诺 --结构化日志记录
- 更好平方3 --SQLite用于持久化
- Vitest --测试
- esbuild --构建工具
