Agent-to-Agent communication protocol for CLI agents
Project description
Synapse A2A
๐ Language: English | ๆฅๆฌ่ช | ไธญๆ | ํ๊ตญ์ด | Espaรฑol | Franรงais
Enable agents to collaborate on tasks without changing their behavior
A framework that enables inter-agent collaboration via the Google A2A Protocol while keeping CLI agents (Claude Code, Codex, Gemini, OpenCode, GitHub Copilot CLI) exactly as they are
Project Goals
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
Non-Invasive: Don't change agent behavior โ
โ โ
Collaborative: Enable agents to work together โ
โ โ
Transparent: Maintain existing workflows โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Synapse A2A transparently wraps each agent's input/output without modifying the agent itself. This means:
- Leverage each agent's strengths: Users can freely assign roles and specializations
- Zero learning curve: Continue using existing workflows
- Future-proof: Resistant to agent updates
See Project Philosophy for details.
flowchart LR
subgraph Terminal1["Terminal 1"]
subgraph Agent1["synapse claude :8100"]
Server1["A2A Server"]
PTY1["PTY + Claude CLI"]
end
end
subgraph Terminal2["Terminal 2"]
subgraph Agent2["synapse codex :8120"]
Server2["A2A Server"]
PTY2["PTY + Codex CLI"]
end
end
subgraph External["External"]
ExtAgent["Google A2A Agent"]
end
Server1 <-->|"POST /tasks/send"| Server2
Server1 <-->|"A2A Protocol"| ExtAgent
Server2 <-->|"A2A Protocol"| ExtAgent
Table of Contents
- Features
- Prerequisites
- Quick Start
- Use Cases
- Skills
- Documentation
- Architecture
- CLI Commands
- API Endpoints
- Task Structure
- Sender Identification
- Priority Levels
- Agent Card
- Registry and Port Management
- File Safety
- Agent Monitor
- Testing
- Configuration (.synapse)
- Development & Release
Features
| Category | Feature |
|---|---|
| A2A Compliant | All communication uses Message/Part + Task format, Agent Card discovery |
| CLI Integration | Turn existing CLI tools into A2A agents without modification |
| synapse send | Send messages between agents via synapse send <agent> "message" |
| Sender Identification | Auto-identify sender via metadata.sender + PID matching |
| Priority Interrupt | Priority 5 sends SIGINT before message (emergency stop) |
| Multi-Instance | Run multiple agents of the same type (automatic port assignment) |
| External Integration | Communicate with other Google A2A agents |
| File Safety | Prevent multi-agent conflicts with file locking and change tracking (visible in synapse list) |
| Agent Naming | Custom names and roles for easy identification (synapse send my-claude "hello") |
| Agent Monitor | Real-time status (READY/WAITING/PROCESSING/DONE), CURRENT task preview, terminal jump |
| Task History | Automatic task tracking with search, export, and statistics (enabled by default) |
| Shared Task Board | SQLite-based task coordination with dependency tracking (synapse tasks) |
| Quality Gates | Configurable hooks (on_idle, on_task_completed) that control status transitions |
| Plan Approval | Plan-mode workflow with synapse approve/reject for human-in-the-loop review |
| Graceful Shutdown | synapse kill sends shutdown request before SIGTERM (30s timeout, -f for force) |
| Delegate Mode | --delegate-mode makes an agent a coordinator that delegates instead of editing files |
| Auto-Spawn Panes | synapse team start โ 1st agent takes over current terminal, others in new panes. --all-new to start all in new panes. Supports profile:name:role:skill_set spec (tmux/iTerm2/Terminal.app/zellij) |
| Spawn Single Agent | synapse spawn <profile> โ Spawn a single agent in a new terminal pane or window |
Prerequisites
- OS: macOS / Linux (Windows via WSL2 recommended)
- Python: 3.10+
- CLI Tools: Pre-install and configure the agents you want to use:
Quick Start
1. Install Synapse A2A
macOS / Linux / WSL2 (recommended)
# pipx (recommended)
pipx install synapse-a2a
# Or run directly with uvx (no install)
uvx synapse-a2a claude
Windows
WSL2 is strongly recommended. Synapse A2A uses
pty.spawn()which requires a Unix-like terminal.
# Inside WSL2 โ same as Linux
pipx install synapse-a2a
# Scoop (experimental, WSL2 still required for pty)
scoop bucket add synapse-a2a https://github.com/s-hiraoku/scoop-synapse-a2a
scoop install synapse-a2a
Developer (from source)
# Install with uv
uv sync
# Or pip (editable)
pip install -e .
With gRPC support:
pip install "synapse-a2a[grpc]"
2. Install Skills (Recommended)
Installing skills is strongly recommended to get the most out of Synapse A2A.
Skills help Claude automatically understand Synapse A2A features: @agent messaging, File Safety, and more.
# Install via skills.sh (https://skills.sh/)
npx skills add s-hiraoku/synapse-a2a
See Skills for details.
3. Start Agents
# Terminal 1: Claude
synapse claude
# Terminal 2: Codex
synapse codex
# Terminal 3: Gemini
synapse gemini
# Terminal 4: OpenCode
synapse opencode
# Terminal 5: GitHub Copilot CLI
synapse copilot
Note: If terminal scrollback display is garbled, try:
uv run synapse gemini # or uv run python -m synapse.cli gemini
Ports are auto-assigned:
| Agent | Port Range |
|---|---|
| Claude | 8100-8109 |
| Gemini | 8110-8119 |
| Codex | 8120-8129 |
| OpenCode | 8130-8139 |
| Copilot | 8140-8149 |
4. Inter-Agent Communication
Use synapse send to send messages between agents:
synapse send codex "Please review this design" --from synapse-claude-8100
synapse send gemini "Suggest API improvements" --from synapse-claude-8100
For multiple instances of the same type, use type-port format:
synapse send codex-8120 "Handle this task" --from synapse-claude-8100
synapse send codex-8121 "Handle that task" --from synapse-claude-8100
5. HTTP API
# Send message
curl -X POST http://localhost:8100/tasks/send \
-H "Content-Type: application/json" \
-d '{"message": {"role": "user", "parts": [{"type": "text", "text": "Hello!"}]}}'
# Emergency stop (Priority 5)
curl -X POST "http://localhost:8100/tasks/send-priority?priority=5" \
-H "Content-Type: application/json" \
-d '{"message": {"role": "user", "parts": [{"type": "text", "text": "Stop!"}]}}'
Use Cases
1. Instant Specification Lookup (Simple)
While coding with Claude, quickly query Gemini (better at web search) for the latest library specs or error info without context switching.
# In Claude's terminal:
synapse send gemini "Summarize the new f-string features in Python 3.12" --from synapse-claude-8100
2. Cross-Review Designs (Intermediate)
Get feedback on your design from agents with different perspectives.
# After Claude drafts a design:
synapse send gemini "Critically review this design from scalability and maintainability perspectives" --from synapse-claude-8100
3. TDD Pair Programming (Intermediate)
Separate "test writer" and "implementer" for robust code.
# Terminal 1 (Codex):
Create unit tests for auth.py - normal case and token expiration case.
# Terminal 2 (Claude):
synapse send codex-8120 "Implement auth.py to pass the tests you created" --from synapse-claude-8100
4. Security Audit (Specialized)
Have an agent with a security expert role audit your code before committing.
# Give Gemini a role:
You are a security engineer. Review only for vulnerabilities (SQLi, XSS, etc.)
# After writing code:
synapse send gemini "Audit the current changes (git diff)" --from synapse-claude-8100
5. Auto-Fix from Error Logs (Advanced)
Pass error logs to an agent for automatic fix suggestions.
# Tests failed...
pytest > error.log
# Ask agent to fix
synapse send claude "Read error.log and fix the issue in synapse/server.py" --from synapse-gemini-8110
6. Language/Framework Migration (Advanced)
Distribute large refactoring work across agents.
# Terminal 1 (Claude):
Read legacy_api.js and create TypeScript type definitions
# Terminal 2 (Codex):
synapse send claude "Use the type definitions you created to rewrite legacy_api.js to src/new_api.ts" --from synapse-codex-8121
Comparison with SSH Remote
| Operation | SSH | Synapse |
|---|---|---|
| Manual CLI operation | โ | โ |
| Programmatic task submission | โณ requires expect etc. | โ HTTP API |
| Multiple simultaneous clients | โณ multiple sessions | โ single endpoint |
| Real-time progress notifications | โ | โ SSE/Webhook |
| Automatic inter-agent coordination | โ | โ synapse send |
Note: SSH is often sufficient for individual CLI use. Synapse shines when you need automation, coordination, and multi-agent collaboration.
Skills
Installing skills is strongly recommended when using Synapse A2A with Claude Code.
Why Install Skills?
With skills installed, Claude automatically understands and executes:
- synapse send: Inter-agent communication via
synapse send codex "Fix this" --from synapse-claude-8100 - Priority control: Message sending with Priority 1-5 (5 = emergency stop)
- File Safety: Prevent multi-agent conflicts with file locking and change tracking
- History management: Search, export, and statistics for task history
Installation
# Install via skills.sh (https://skills.sh/)
npx skills add s-hiraoku/synapse-a2a
Included Skills
| Skill | Description |
|---|---|
| synapse-a2a | Comprehensive guide for inter-agent communication: synapse send, priority, A2A protocol, history, File Safety, settings |
Core Skills: Essential skills like synapse-a2a are automatically deployed to agent directories on startup (best-effort) to ensure basic quality even if skill sets are skipped.
Skill Management
Synapse includes a built-in skill manager with a central store (~/.synapse/skills/) for organizing and deploying skills across agents.
Skill Scopes
| Scope | Location | Description |
|---|---|---|
| Synapse | ~/.synapse/skills/ |
Central store (deploy to agents from here) |
| User | ~/.claude/skills/, ~/.agents/skills/, etc. |
User-wide skills |
| Project | ./.claude/skills/, ./.agents/skills/, etc. |
Project-local skills |
| Plugin | ./plugins/*/skills/ |
Read-only plugin skills |
Commands
# Interactive TUI
synapse skills
# List and browse
synapse skills list # All scopes
synapse skills list --scope synapse # Central store only
synapse skills show <name> # Skill details
# Manage
synapse skills delete <name> [--force]
synapse skills move <name> --to <scope>
# Central store operations
synapse skills import <name> # Import from agent dirs to ~/.synapse/skills/
synapse skills deploy <name> --agent claude,codex --scope user
synapse skills add <repo> # Install from repo (npx skills wrapper)
synapse skills create # Show guided skill creation steps
# Skill sets (named groups)
synapse skills set list
synapse skills set show <name>
Directory Structure
plugins/
โโโ synapse-a2a/
โโโ .claude-plugin/plugin.json
โโโ README.md
โโโ skills/
โโโ synapse-a2a/SKILL.md
See plugins/synapse-a2a/README.md for details.
Note: Codex and Gemini don't support plugins, but you can place expanded skills in the
.agents/skills/(Codex/OpenCode) or.gemini/skills/directory respectively to enable these features.
Documentation
- guides/README.md - Documentation overview
- guides/multi-agent-setup.md - Setup guide
- guides/usage.md - Commands and usage patterns
- guides/settings.md -
.synapseconfiguration details - guides/troubleshooting.md - Common issues and solutions
Architecture
A2A Server/Client Structure
In Synapse, each agent operates as an A2A server. There's no central server; it's a P2P architecture.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ synapse claude (port 8100) โ โ synapse codex (port 8120) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ FastAPI Server (A2A Server) โ โ โ โ FastAPI Server (A2A Server) โ โ
โ โ /.well-known/agent.json โ โ โ โ /.well-known/agent.json โ โ
โ โ /tasks/send โโโโผโโโโโผโโโ A2AClient โ โ
โ โ /tasks/{id} โ โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ โ PTY + Codex CLI โ โ
โ โ PTY + Claude CLI โ โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Each agent is:
- A2A Server: Accepts requests from other agents
- A2A Client: Sends requests to other agents
Key Components
| Component | File | Role |
|---|---|---|
| FastAPI Server | synapse/server.py |
Provides A2A endpoints |
| A2A Router | synapse/a2a_compat.py |
A2A protocol implementation |
| A2A Client | synapse/a2a_client.py |
Communication with other agents |
| TerminalController | synapse/controller.py |
PTY management, READY/PROCESSING detection |
| InputRouter | synapse/input_router.py |
@Agent pattern detection |
| AgentRegistry | synapse/registry.py |
Agent registration and lookup |
| SkillManager | synapse/skills.py |
Skill discovery, deploy, import, skill sets |
| SkillManagerCmd | synapse/commands/skill_manager.py |
Skill management TUI and CLI |
Startup Sequence
sequenceDiagram
participant Synapse as Synapse Server
participant Registry as AgentRegistry
participant PTY as TerminalController
participant CLI as CLI Agent
Synapse->>Registry: 1. Register agent (agent_id, pid, port)
Synapse->>PTY: 2. Start PTY
PTY->>CLI: 3. Start CLI agent
Synapse->>PTY: 4. Send initial instructions (sender: synapse-system)
PTY->>CLI: 5. AI receives initial instructions
Communication Flow
sequenceDiagram
participant User
participant Claude as Claude (8100)
participant Client as A2AClient
participant Codex as Codex (8120)
User->>Claude: @codex Review this design
Claude->>Client: send_to_local()
Client->>Codex: POST /tasks/send-priority
Codex->>Codex: Create Task โ Write to PTY
Codex-->>Client: {"task": {"id": "...", "status": "working"}}
Client-->>Claude: [โ codex] Send complete
CLI Commands
Basic Operations
# Start agent (foreground)
synapse claude
synapse codex
synapse gemini
synapse opencode
synapse copilot
# Start with custom name and role
synapse claude --name my-claude --role "code reviewer"
# Skip interactive name/role setup
synapse claude --no-setup
# Specify port
synapse claude --port 8105
# Pass arguments to CLI tool
synapse claude -- --resume
Agent Naming
Assign custom names and roles to agents for easier identification and management:
# Interactive setup (default when starting agent)
synapse claude
# โ Prompts for name and role
# Skip interactive setup
synapse claude --no-setup
# Set name and role via CLI options
synapse claude --name my-claude --role "code reviewer"
# After agent is running, change name/role
synapse rename synapse-claude-8100 --name my-claude --role "test writer"
synapse rename my-claude --role "documentation" # Change role only
synapse rename my-claude --clear # Clear name and role
Once named, use the custom name for all operations:
synapse send my-claude "Review this code" --from synapse-codex-8121
synapse jump my-claude
synapse kill my-claude
Name vs ID:
- Display/Prompts: Shows name if set, otherwise ID (e.g.,
Kill my-claude (PID: 1234)?) - Internal processing: Always uses agent ID (
synapse-claude-8100) - Target resolution: Name has highest priority when matching targets
Command List
| Command | Description |
|---|---|
synapse <profile> |
Start in foreground |
synapse start <profile> |
Start in background |
synapse stop <profile|id> |
Stop agent (can specify ID) |
synapse kill <target> |
Graceful shutdown (sends shutdown request, then SIGTERM after 30s) |
synapse kill <target> -f |
Force kill (immediate SIGKILL) |
synapse jump <target> |
Jump to agent's terminal |
synapse rename <target> |
Assign name/role to agent |
synapse --version |
Show version |
synapse list |
List running agents (Rich TUI with auto-refresh and terminal jump) |
synapse logs <profile> |
Show logs |
synapse send <target> <message> |
Send message |
synapse reply <message> |
Reply to the last received A2A message |
synapse trace <task_id> |
Show task history + file-safety cross-reference |
synapse instructions show |
Show instruction content |
synapse instructions files |
List instruction files |
synapse instructions send |
Resend initial instructions |
synapse history list |
Show task history |
synapse history show <task_id> |
Show task details |
synapse history search |
Keyword search |
synapse history cleanup |
Delete old data |
synapse history stats |
Show statistics |
synapse history export |
Export to JSON/CSV |
synapse file-safety status |
Show file safety statistics |
synapse file-safety locks |
List active locks |
synapse file-safety lock |
Lock a file |
synapse file-safety unlock |
Release lock |
synapse file-safety history |
File change history |
synapse file-safety recent |
Recent changes |
synapse file-safety record |
Manually record change |
synapse file-safety cleanup |
Delete old data |
synapse file-safety debug |
Show debug info |
synapse skills |
Skill Manager (interactive TUI) |
synapse skills list |
List discovered skills |
synapse skills show <name> |
Show skill details |
synapse skills delete <name> |
Delete a skill |
synapse skills move <name> |
Move skill to another scope |
synapse skills deploy <name> |
Deploy skill from central store to agent dirs |
synapse skills import <name> |
Import skill to central store (~/.synapse/skills/) |
synapse skills add <repo> |
Install skill from repository (via npx skills) |
synapse skills create |
Show guided skill creation steps (uses anthropic-skill-creator) |
synapse skills set list |
List skill sets |
synapse skills set show <name> |
Show skill set details |
synapse config |
Settings management (interactive TUI) |
synapse config show |
Show current settings |
synapse tasks list |
List shared task board |
synapse tasks create |
Create a task |
synapse tasks assign |
Assign task to agent |
synapse tasks complete |
Mark task completed |
synapse approve <task_id> |
Approve a plan |
synapse reject <task_id> |
Reject a plan with reason |
synapse team start |
Launch agents (1st=handoff, rest=new panes). --all-new for all new panes |
synapse spawn <profile> |
Spawn a single agent in a new terminal pane |
Resume Mode
When resuming an existing session, use these flags to skip initial instruction sending (A2A protocol explanation), keeping your context clean:
# Resume Claude Code session
synapse claude -- --resume
# Resume Gemini with history
synapse gemini -- --resume=5
# Codex uses 'resume' as a subcommand (not --resume flag)
synapse codex -- resume --last
Default flags (customizable in settings.json):
- Claude:
--resume,--continue,-r,-c - Gemini:
--resume,-r - Codex:
resume - OpenCode:
--continue,-c - Copilot:
--continue,--resume
Instruction Management
Manually resend initial instructions when they weren't sent (e.g., after --resume mode):
# Show instruction content
synapse instructions show claude
# List instruction files
synapse instructions files claude
# Send initial instructions to running agent
synapse instructions send claude
# Preview before sending
synapse instructions send claude --preview
# Send to specific agent ID
synapse instructions send synapse-claude-8100
Useful when:
- You need A2A protocol info after starting with
--resume - Agent lost/forgot instructions and needs recovery
- Debugging instruction content
External Agent Management
# Register external agent
synapse external add http://other-agent:9000 --alias other
# List
synapse external list
# Send message
synapse external send other "Process this task"
Task History Management
Search, browse, and analyze past agent execution results.
Note: History is enabled by default since v0.3.13. To disable:
# Disable via environment variable
export SYNAPSE_HISTORY_ENABLED=false
synapse claude
Basic Operations
# Show latest 50 entries
synapse history list
# Filter by agent
synapse history list --agent claude
# Custom limit
synapse history list --limit 100
# Show task details
synapse history show task-id-uuid
Keyword Search
Search input/output fields by keyword:
# Single keyword
synapse history search "Python"
# Multiple keywords (OR logic)
synapse history search "Python" "Docker"
# AND logic (all keywords must match)
synapse history search "Python" "function" --logic AND
# With agent filter
synapse history search "Python" --agent claude
# Limit results
synapse history search "error" --limit 20
Statistics
# Overall stats (total, success rate, per-agent breakdown)
synapse history stats
# Specific agent stats
synapse history stats --agent claude
Data Export
# JSON export (stdout)
synapse history export --format json
# CSV export
synapse history export --format csv
# Save to file
synapse history export --format json --output history.json
synapse history export --format csv --agent claude > claude_history.csv
Retention Policy
# Delete data older than 30 days
synapse history cleanup --days 30
# Keep database under 100MB
synapse history cleanup --max-size 100
# Force (no confirmation)
synapse history cleanup --days 30 --force
# Dry run
synapse history cleanup --days 30 --dry-run
Storage:
- SQLite database:
~/.synapse/history/history.db - Stored: task ID, agent name, input, output, status, metadata
- Auto-indexed: agent_name, timestamp, task_id
Settings:
- Enabled by default (v0.3.13+)
- Disable:
SYNAPSE_HISTORY_ENABLED=false
synapse send Command (Recommended)
Use synapse send for inter-agent communication. Works in sandboxed environments.
synapse send <target> "<message>" [--from <sender>] [--priority <1-5>] [--response | --no-response]
Target Formats:
| Format | Example | Description |
|---|---|---|
| Custom name | my-claude |
Highest priority, use when agent has a name |
| Agent type | claude |
Only works when single instance exists |
| Type-port | claude-8100 |
Use when multiple instances of same type |
| Full ID | synapse-claude-8100 |
Complete agent ID |
When multiple agents of the same type are running, type-only (e.g., claude) will error. Use claude-8100 or synapse-claude-8100.
Options:
| Option | Short | Description |
|---|---|---|
--from |
-f |
Sender agent ID (for reply identification) |
--priority |
-p |
Priority 1-4: normal, 5: emergency stop (sends SIGINT) |
--response |
- | Roundtrip - sender waits, receiver replies with synapse reply |
--no-response |
- | Oneway - fire and forget, no reply needed |
Examples:
# Send message (single instance)
synapse send claude "Hello" --priority 1 --from synapse-codex-8121
# Long message support (automatic temp-file fallback)
synapse send claude --message-file /path/to/message.txt --no-response
echo "very long content..." | synapse send claude --stdin --no-response
# File attachments
synapse send claude "Review this" --attach src/main.py --no-response
# Send to specific instance (multiple of same type)
synapse send claude-8100 "Hello" --from synapse-claude-8101
# Emergency stop
synapse send claude "Stop!" --priority 5 --from synapse-codex-8121
# Wait for response (roundtrip)
synapse send gemini "Analyze this" --response --from synapse-claude-8100
Default behavior: With a2a.flow=auto (default), synapse send waits for a response unless --no-response is specified.
Important: Always use --from with your agent ID (format: synapse-<type>-<port>).
synapse reply Command
Reply to the last received message:
synapse reply "<message>"
The --from flag is only needed in sandboxed environments (like Codex). Without --from, Synapse auto-detects the sender via process ancestry.
Low-Level A2A Tool
For advanced operations:
# List agents
python -m synapse.tools.a2a list
# Send message
python -m synapse.tools.a2a send --target claude --priority 1 "Hello"
# Reply to last received message (uses reply tracking)
python -m synapse.tools.a2a reply "Here is my response"
API Endpoints
A2A Compliant
| Endpoint | Method | Description |
|---|---|---|
/.well-known/agent.json |
GET | Agent Card |
/tasks/send |
POST | Send message |
/tasks/send-priority |
POST | Send with priority |
/tasks/create |
POST | Create task (no PTY send, for --response) |
/tasks/{id} |
GET | Get task status |
/tasks |
GET | List tasks |
/tasks/{id}/cancel |
POST | Cancel task |
/status |
GET | READY/PROCESSING status |
Agent Teams
| Endpoint | Method | Description |
|---|---|---|
/tasks/board |
GET | List shared task board |
/tasks/board |
POST | Create task on board |
/tasks/board/{id}/claim |
POST | Claim task atomically |
/tasks/board/{id}/complete |
POST | Complete task |
/tasks/{id}/approve |
POST | Approve a plan |
/tasks/{id}/reject |
POST | Reject a plan with reason |
/team/start |
POST | Start multiple agents in terminal panes (A2A-initiated) |
/spawn |
POST | Spawn a single agent in a new terminal pane (A2A-initiated) |
Synapse Extensions
| Endpoint | Method | Description |
|---|---|---|
/reply-stack/get |
GET | Get sender info without removing (for peek before send) |
/reply-stack/pop |
GET | Pop sender info from reply map (for synapse reply) |
/tasks/{id}/subscribe |
GET | Subscribe to task updates via SSE |
Webhooks
| Endpoint | Method | Description |
|---|---|---|
/webhooks |
POST | Register a webhook for task notifications |
/webhooks |
GET | List registered webhooks |
/webhooks |
DELETE | Unregister a webhook |
/webhooks/deliveries |
GET | Recent webhook delivery attempts |
External Agents
| Endpoint | Method | Description |
|---|---|---|
/external/discover |
POST | Register external agent |
/external/agents |
GET | List |
/external/agents/{alias} |
DELETE | Remove |
/external/agents/{alias}/send |
POST | Send |
Task Structure
In the A2A protocol, all communication is managed as Tasks.
Task Lifecycle
stateDiagram-v2
[*] --> submitted: POST /tasks/send
submitted --> working: Processing starts
working --> completed: Success
working --> failed: Error
working --> input_required: Waiting for input
input_required --> working: Input received
completed --> [*]
failed --> [*]
Task Object
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"context_id": "conversation-123",
"status": "working",
"message": {
"role": "user",
"parts": [{ "type": "text", "text": "Review this design" }]
},
"artifacts": [],
"metadata": {
"sender": {
"sender_id": "synapse-claude-8100",
"sender_type": "claude",
"sender_endpoint": "http://localhost:8100"
}
},
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:05Z"
}
Field Descriptions
| Field | Type | Description |
|---|---|---|
id |
string | Unique task identifier (UUID) |
context_id |
string? | Conversation context ID (for multi-turn) |
status |
string | submitted / working / completed / failed / input_required |
message |
Message | Sent message |
artifacts |
Artifact[] | Task output artifacts |
metadata |
object | Sender info (metadata.sender) |
created_at |
string | Creation timestamp (ISO 8601) |
updated_at |
string | Update timestamp (ISO 8601) |
Message Structure
{
"role": "user",
"parts": [
{ "type": "text", "text": "Message content" },
{
"type": "file",
"file": {
"name": "doc.pdf",
"mimeType": "application/pdf",
"bytes": "..."
}
}
]
}
| Part Type | Description |
|---|---|
text |
Text message |
file |
File attachment |
data |
Structured data |
Sender Identification
The sender of A2A messages can be identified via metadata.sender.
PTY Output Format
Messages are sent to the agent's PTY with a simple A2A: prefix:
A2A: <message content>
Reply Handling
Synapse automatically manages reply routing. Agents simply use synapse reply:
synapse reply "Here is my response"
The framework internally tracks sender information and routes replies automatically.
Task API Verification (Development)
curl -s http://localhost:8120/tasks/<id> | jq '.metadata.sender'
Response:
{
"sender_id": "synapse-claude-8100",
"sender_type": "claude",
"sender_endpoint": "http://localhost:8100"
}
How It Works
- On send: Reference Registry, identify own agent_id via PID matching
- On Task creation: Attach sender info to
metadata.sender - On receive: Check via PTY prefix or Task API
Priority Levels
| Priority | Behavior | Use Case |
|---|---|---|
| 1-4 | Normal stdin write | Regular messages |
| 5 | SIGINT then write | Emergency stop |
# Emergency stop
synapse send claude "Stop!" --priority 5
Agent Card
Each agent publishes an Agent Card at /.well-known/agent.json.
curl http://localhost:8100/.well-known/agent.json
{
"name": "Synapse Claude",
"description": "PTY-wrapped claude CLI agent with A2A communication",
"url": "http://localhost:8100",
"capabilities": {
"streaming": false,
"pushNotifications": false,
"multiTurn": true
},
"skills": [
{
"id": "chat",
"name": "Chat",
"description": "Send messages to the CLI agent"
},
{
"id": "interrupt",
"name": "Interrupt",
"description": "Interrupt current processing"
}
],
"extensions": {
"synapse": {
"agent_id": "synapse-claude-8100",
"pty_wrapped": true,
"priority_interrupt": true,
"at_agent_syntax": true
}
}
}
Design Philosophy
Agent Card is a "business card" containing only external-facing information:
- capabilities, skills, endpoint, etc.
- Internal instructions are not included (sent via A2A Task at startup)
Registry and Port Management
Registry Files
~/.a2a/registry/
โโโ synapse-claude-8100.json
โโโ synapse-claude-8101.json
โโโ synapse-gemini-8110.json
Auto Cleanup
Stale entries are automatically removed during:
synapse listexecution- Message sending (when target is dead)
Port Ranges
PORT_RANGES = {
"claude": (8100, 8109),
"gemini": (8110, 8119),
"codex": (8120, 8129),
"opencode": (8130, 8139),
"copilot": (8140, 8149),
"dummy": (8190, 8199),
}
Typical Memory Usage (Resident Agents)
On macOS, idle resident agents are lightweight. As of January 25, 2026, RSS is around ~12 MB per agent process in a typical development setup.
Actual usage varies by profile, plugins, history settings, and workload.
Note that ps reports RSS in KB (so ~12 MB corresponds to ~12,000 KB).
To measure on your machine:
ps -o pid,comm,rss,vsz,etime,command -A | rg "synapse"
If you don't have ripgrep:
ps -o pid,comm,rss,vsz,etime,command -A | grep "synapse"
File Safety
Prevents conflicts when multiple agents edit the same files simultaneously.
sequenceDiagram
participant Claude
participant FS as File Safety
participant Gemini
Claude->>FS: acquire_lock("auth.py")
FS-->>Claude: ACQUIRED
Gemini->>FS: validate_write("auth.py")
FS-->>Gemini: DENIED (locked by claude)
Claude->>FS: release_lock("auth.py")
Gemini->>FS: acquire_lock("auth.py")
FS-->>Gemini: ACQUIRED
Features
| Feature | Description |
|---|---|
| File Locking | Exclusive control prevents simultaneous editing |
| Change Tracking | Records who changed what and when |
| Context Injection | Provides recent change history on read |
| Pre-write Validation | Checks lock status before writing |
| List Integration | Active locks visible in synapse list EDITING_FILE column |
Enable
# Enable via environment variable
export SYNAPSE_FILE_SAFETY_ENABLED=true
synapse claude
Basic Commands
# Show statistics
synapse file-safety status
# List active locks
synapse file-safety locks
# Acquire lock
synapse file-safety lock /path/to/file.py claude --intent "Refactoring"
# Wait for lock to be released
synapse file-safety lock /path/to/file.py claude --wait --wait-timeout 60 --wait-interval 2
# Release lock
synapse file-safety unlock /path/to/file.py claude
# File change history
synapse file-safety history /path/to/file.py
# Recent changes
synapse file-safety recent
# Delete old data
synapse file-safety cleanup --days 30
Python API
from synapse.file_safety import FileSafetyManager, ChangeType, LockStatus
manager = FileSafetyManager.from_env()
# Acquire lock
result = manager.acquire_lock("/path/to/file.py", "claude", intent="Refactoring")
if result["status"] == LockStatus.ACQUIRED:
# Edit file...
# Record change
manager.record_modification(
file_path="/path/to/file.py",
agent_name="claude",
task_id="task-123",
change_type=ChangeType.MODIFY,
intent="Fix authentication bug"
)
# Release lock
manager.release_lock("/path/to/file.py", "claude")
# Pre-write validation
validation = manager.validate_write("/path/to/file.py", "gemini")
if not validation["allowed"]:
print(f"Write blocked: {validation['reason']}")
Storage: Default is .synapse/file_safety.db (SQLite, relative to working directory). Change via SYNAPSE_FILE_SAFETY_DB_PATH (e.g., ~/.synapse/file_safety.db for global).
See docs/file-safety.md for details.
Agent Monitor
Real-time monitoring of agent status with terminal jump capability.
Rich TUI Mode
# Start Rich TUI with auto-refresh (default)
synapse list
The display automatically updates when agent status changes (via file watcher) with a 10-second fallback polling interval.
Display Columns
| Column | Description |
|---|---|
| ID | Agent ID (e.g., synapse-claude-8100) |
| NAME | Custom name (if assigned) |
| TYPE | Agent type (claude, gemini, codex, etc.) |
| ROLE | Agent role description (if assigned) |
| STATUS | Current status (READY, WAITING, PROCESSING, DONE) |
| CURRENT | Current task preview |
| TRANSPORT | Communication transport indicator |
| WORKING_DIR | Current working directory |
| EDITING_FILE | File being edited (File Safety enabled only) |
Customize columns in settings.json:
{
"list": {
"columns": ["ID", "NAME", "STATUS", "CURRENT", "TRANSPORT", "WORKING_DIR"]
}
}
Status States
| Status | Color | Meaning |
|---|---|---|
| READY | Green | Agent is idle, waiting for input |
| WAITING | Cyan | Agent is showing selection UI, waiting for user choice |
| PROCESSING | Yellow | Agent is actively working |
| DONE | Blue | Task completed (auto-transitions to READY after 10s) |
Interactive Controls
| Key | Action |
|---|---|
| 1-9 | Select agent row (direct) |
| โ/โ | Navigate agent rows |
| Enter or j | Jump to selected agent's terminal |
| k | Kill selected agent (with confirmation) |
| / | Filter by TYPE, NAME, or WORKING_DIR |
| ESC | Clear filter/selection |
| q | Quit |
Supported Terminals: iTerm2, Terminal.app, Ghostty, VS Code, tmux, Zellij
WAITING Detection
Note: WAITING detection is currently disabled due to false positives on startup. See #140 for details.
When enabled, detects agents waiting for user input (selection UI, Y/n prompts) using regex patterns:
- Gemini:
โ 1. Optionselection UI,Allow executionprompts - Claude:
โฏ Optioncursor,โ/โcheckboxes,[Y/n]prompts - Codex: Indented numbered lists
- OpenCode: Numbered choices, selection indicators,
[y/N]prompts - Copilot: Numbered choices, selection indicators,
[y/N]or(y/n)prompts
Testing
Comprehensive test suite verifies A2A protocol compliance:
# All tests
pytest
# Specific category
pytest tests/test_a2a_compat.py -v
pytest tests/test_sender_identification.py -v
Configuration (.synapse)
Customize environment variables and initial instructions via .synapse/settings.json.
Scopes
| Scope | Path | Priority |
|---|---|---|
| User | ~/.synapse/settings.json |
Low |
| Project | ./.synapse/settings.json |
Medium |
| Local | ./.synapse/settings.local.json |
High (gitignore recommended) |
Higher priority settings override lower ones.
Setup
# Create .synapse/ directory (copies all template files)
synapse init
# ? Where do you want to create .synapse/?
# โฏ User scope (~/.synapse/)
# Project scope (./.synapse/)
#
# โ Created ~/.synapse
# Reset to defaults
synapse reset
# Edit settings interactively (TUI)
synapse config
# Show current settings (read-only)
synapse config show
synapse config show --scope user
synapse init copies these files to .synapse/:
| File | Description |
|---|---|
settings.json |
Environment variables and initial instruction settings |
default.md |
Initial instructions common to all agents |
gemini.md |
Gemini-specific initial instructions |
file-safety.md |
File Safety instructions |
settings.json Structure
{
"env": {
"SYNAPSE_HISTORY_ENABLED": "true",
"SYNAPSE_FILE_SAFETY_ENABLED": "true",
"SYNAPSE_FILE_SAFETY_DB_PATH": ".synapse/file_safety.db"
},
"instructions": {
"default": "[SYNAPSE INSTRUCTIONS...]\n...",
"claude": "",
"gemini": "",
"codex": ""
},
"approvalMode": "required",
"a2a": {
"flow": "auto"
}
}
Environment Variables (env)
| Variable | Description | Default |
|---|---|---|
SYNAPSE_HISTORY_ENABLED |
Enable task history | true |
SYNAPSE_FILE_SAFETY_ENABLED |
Enable file safety | true |
SYNAPSE_FILE_SAFETY_DB_PATH |
File safety DB path | .synapse/file_safety.db |
SYNAPSE_FILE_SAFETY_RETENTION_DAYS |
Lock history retention days | 30 |
SYNAPSE_AUTH_ENABLED |
Enable API authentication | false |
SYNAPSE_API_KEYS |
API keys (comma-separated) | - |
SYNAPSE_ADMIN_KEY |
Admin key | - |
SYNAPSE_ALLOW_LOCALHOST |
Skip auth for localhost | true |
SYNAPSE_USE_HTTPS |
Use HTTPS | false |
SYNAPSE_WEBHOOK_SECRET |
Webhook secret | - |
SYNAPSE_WEBHOOK_TIMEOUT |
Webhook timeout (sec) | 10 |
SYNAPSE_WEBHOOK_MAX_RETRIES |
Webhook retry count | 3 |
SYNAPSE_SKILLS_DIR |
Central skill store directory | ~/.synapse/skills |
SYNAPSE_LONG_MESSAGE_THRESHOLD |
Character threshold for file storage | 200 |
SYNAPSE_LONG_MESSAGE_TTL |
TTL for message files (seconds) | 3600 |
SYNAPSE_LONG_MESSAGE_DIR |
Directory for message files | System temp |
SYNAPSE_SEND_MESSAGE_THRESHOLD |
Threshold for auto temp-file fallback (bytes) | 102400 |
A2A Communication Settings (a2a)
| Setting | Value | Description |
|---|---|---|
flow |
roundtrip |
Always wait for result |
flow |
oneway |
Always forward only (don't wait) |
flow |
auto |
Flag-controlled; if omitted, waits by default |
Approval Mode (approvalMode)
Controls whether to show a confirmation prompt before sending initial instructions.
| Setting | Description |
|---|---|
required |
Show approval prompt at startup (default) |
auto |
Send instructions automatically without prompting |
When set to required, you'll see a prompt like:
[Synapse] Agent: synapse-claude-8100 | Port: 8100
[Synapse] Initial instructions will be sent to configure A2A communication.
Proceed? [Y/n/s(skip)]:
Options:
- Y (or Enter): Send initial instructions and start agent
- n: Abort startup
- s: Start agent without sending initial instructions
Initial Instructions (instructions)
Customize instructions sent at agent startup:
{
"instructions": {
"default": "Common instructions for all agents",
"claude": "Claude-specific instructions (takes priority over default)",
"gemini": "Gemini-specific instructions",
"codex": "Codex-specific instructions"
}
}
Priority:
- Agent-specific setting (
claude,gemini,codex,opencode,copilot) if present - Otherwise use
default - If both empty, no initial instructions sent
Placeholders:
{{agent_id}}- Agent ID (e.g.,synapse-claude-8100){{port}}- Port number (e.g.,8100)
See guides/settings.md for details.
Development & Release
Publishing to PyPI
Merging a pyproject.toml version change to main automatically creates a git tag, GitHub Release, and publishes to PyPI.
# 1. Update version in pyproject.toml and CHANGELOG.md
# 2. Create PR and merge to main
# 3. Automation handles: tag โ GitHub Release โ PyPI โ Homebrew/Scoop PR
Manual Publishing (Fallback)
# Build and publish with uv
uv build
uv publish
User Installation
macOS / Linux / WSL2 (recommended):
pipx install synapse-a2a
# Upgrade
pipx upgrade synapse-a2a
# Uninstall
pipx uninstall synapse-a2a
Windows (Scoop, experimental โ WSL2 required for pty):
scoop bucket add synapse-a2a https://github.com/s-hiraoku/scoop-synapse-a2a
scoop install synapse-a2a
# Upgrade
scoop update synapse-a2a
Known Limitations
- TUI Rendering: Display may be garbled with Ink-based CLIs
- PTY Limitations: Some special input sequences not supported
- Codex Sandbox: Codex CLI's sandbox blocks network access, requiring configuration for inter-agent communication (see below)
Inter-Agent Communication in Codex CLI
Codex CLI runs in a sandbox by default with restricted network access. To use @agent pattern for inter-agent communication, allow network access in ~/.codex/config.toml.
Global Setting (applies to all projects):
# ~/.codex/config.toml
sandbox_mode = "workspace-write"
[sandbox_workspace_write]
network_access = true
Per-Project Setting:
# ~/.codex/config.toml
[projects."/path/to/your/project"]
sandbox_mode = "workspace-write"
[projects."/path/to/your/project".sandbox_workspace_write]
network_access = true
See guides/troubleshooting.md for details.
Enterprise Features
Security, notification, and high-performance communication features for production environments.
API Key Authentication
# Start with authentication enabled
export SYNAPSE_AUTH_ENABLED=true
export SYNAPSE_API_KEYS=<YOUR_API_KEY>
synapse claude
# Request with API Key
curl -H "X-API-Key: <YOUR_API_KEY>" http://localhost:8100/tasks
Webhook Notifications
Send notifications to external URLs when tasks complete.
# Register webhook
curl -X POST http://localhost:8100/webhooks \
-H "Content-Type: application/json" \
-d '{"url": "https://your-server.com/hook", "events": ["task.completed"]}'
| Event | Description |
|---|---|
task.completed |
Task completed successfully |
task.failed |
Task failed |
task.canceled |
Task canceled |
SSE Streaming
Receive task output in real-time.
curl -N http://localhost:8100/tasks/{task_id}/subscribe
Event types:
| Event | Description |
|---|---|
output |
New CLI output |
status |
Status change |
done |
Task complete (includes Artifact) |
Output Parsing
Automatically parse CLI output for error detection, status updates, and Artifact generation.
| Feature | Description |
|---|---|
| Error Detection | Detects command not found, permission denied, etc. |
| input_required | Detects question/confirmation prompts |
| Output Parser | Structures code/files/errors |
gRPC Support
Use gRPC for high-performance communication.
# Install gRPC dependencies
pip install synapse-a2a[grpc]
# gRPC runs on REST port + 1
# REST: 8100 โ gRPC: 8101
See guides/enterprise.md for details.
Documentation
| Path | Content |
|---|---|
| guides/usage.md | Detailed usage |
| guides/architecture.md | Architecture details |
| guides/enterprise.md | Enterprise features |
| guides/troubleshooting.md | Troubleshooting |
| docs/file-safety.md | File conflict prevention |
| docs/project-philosophy.md | Design philosophy |
License
MIT License
Related Links
- Claude Code - Anthropic's CLI agent
- OpenCode - Open-source AI coding agent
- GitHub Copilot CLI - GitHub's AI coding assistant
- Google A2A Protocol - Agent-to-Agent protocol
Project details
Release history Release notifications | RSS feed
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 synapse_a2a-0.6.1.tar.gz.
File metadata
- Download URL: synapse_a2a-0.6.1.tar.gz
- Upload date:
- Size: 423.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0dc4e8ff0ada0227aab8f88990cf6992e308c745ac667a1f6e85b3164d7f5ec8
|
|
| MD5 |
d5dccd43dea49ab21d12d1c6ba62a9e7
|
|
| BLAKE2b-256 |
adfd9604d84332c77b4484c11b1caedf2f69812429ff59b90310c76587e698ef
|
Provenance
The following attestation bundles were made for synapse_a2a-0.6.1.tar.gz:
Publisher:
publish.yml on s-hiraoku/synapse-a2a
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
synapse_a2a-0.6.1.tar.gz -
Subject digest:
0dc4e8ff0ada0227aab8f88990cf6992e308c745ac667a1f6e85b3164d7f5ec8 - Sigstore transparency entry: 961030876
- Sigstore integration time:
-
Permalink:
s-hiraoku/synapse-a2a@93437690cb7d033cd17f3c6ac47c365c693802e6 -
Branch / Tag:
refs/tags/v0.6.1 - Owner: https://github.com/s-hiraoku
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@93437690cb7d033cd17f3c6ac47c365c693802e6 -
Trigger Event:
push
-
Statement type:
File details
Details for the file synapse_a2a-0.6.1-py3-none-any.whl.
File metadata
- Download URL: synapse_a2a-0.6.1-py3-none-any.whl
- Upload date:
- Size: 217.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
22297a607f2e7462cb3c85ae474087c935585ab4903d98346bfd8db0372f30ea
|
|
| MD5 |
6367a6aa2e07632ec8a9a5f557580e5a
|
|
| BLAKE2b-256 |
23e1a01c1bf9823f7d821f0ca00cdf4eca9d13c0bf3596f6a54ce473ab288fe6
|
Provenance
The following attestation bundles were made for synapse_a2a-0.6.1-py3-none-any.whl:
Publisher:
publish.yml on s-hiraoku/synapse-a2a
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
synapse_a2a-0.6.1-py3-none-any.whl -
Subject digest:
22297a607f2e7462cb3c85ae474087c935585ab4903d98346bfd8db0372f30ea - Sigstore transparency entry: 961030954
- Sigstore integration time:
-
Permalink:
s-hiraoku/synapse-a2a@93437690cb7d033cd17f3c6ac47c365c693802e6 -
Branch / Tag:
refs/tags/v0.6.1 - Owner: https://github.com/s-hiraoku
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@93437690cb7d033cd17f3c6ac47c365c693802e6 -
Trigger Event:
push
-
Statement type: