Skip to main content

Agent-to-Agent communication protocol for CLI agents

Project description

Synapse A2A

๐ŸŒ Language: English | ๆ—ฅๆœฌ่ชž

Enable agents to collaborate on tasks without changing their behavior

Python 3.10+ License: MIT Tests Ask DeepWiki

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

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
Task Delegation Auto-forward tasks to other agents via natural language rules
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), terminal jump with Enter/j key

Prerequisites


Quick Start

1. Install Synapse A2A

# Install from PyPI (recommended)
pip install synapse-a2a

# With gRPC support
pip install "synapse-a2a[grpc]"

For developers (editing this repository):

# Install with uv
uv sync

# Or pip (editable)
pip install -e .

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, task delegation, 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 claude
synapse send gemini "Suggest API improvements" --from claude

For multiple instances of the same type, use type-port format:

synapse send codex-8120 "Handle this task" --from claude
synapse send codex-8121 "Handle that task" --from claude

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 claude

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 claude

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 claude

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 claude

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 gemini

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 codex

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 claude
  • Priority control: Message sending with Priority 1-5 (5 = emergency stop)
  • Task delegation: Automatic task routing with delegation.enabled
  • 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
delegation Automatic task delegation setup: delegation.enabled, pre-checks, error handling, File Safety integration

Directory Structure

plugins/
โ””โ”€โ”€ synapse-a2a/
    โ”œโ”€โ”€ .claude-plugin/plugin.json
    โ”œโ”€โ”€ README.md
    โ””โ”€โ”€ skills/
        โ”œโ”€โ”€ synapse-a2a/SKILL.md
        โ””โ”€โ”€ delegation/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 .codex/skills/ or .gemini/skills/ directory respectively to enable these features.


Documentation


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

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 codex
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> Kill agent immediately
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 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 config Settings management (interactive TUI)
synapse config show Show current settings

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.

Enable:

# Enable via environment variable
export SYNAPSE_HISTORY_ENABLED=true
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:

  • Enable: SYNAPSE_HISTORY_ENABLED=true
  • Disable: SYNAPSE_HISTORY_ENABLED=false (default)

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 (default)

Examples:

# Send message (single instance)
synapse send claude "Hello" --priority 1 --from codex

# 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 codex

# Wait for response (roundtrip)
synapse send gemini "Analyze this" --response --from claude

Important: Always use --from to identify the sender.

synapse reply Command

Reply to the last received message:

synapse reply "<message>" --from <your_agent_type>

The --from flag is required in sandboxed environments (like Codex).

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

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)

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" --from <your_agent_type>

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

  1. On send: Reference Registry, identify own agent_id via PID matching
  2. On Task creation: Attach sender info to metadata.sender
  3. 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 list execution
  • 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

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"

# 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). Change via SYNAPSE_FILE_SAFETY_DB_PATH (e.g., ./.synapse/file_safety.db for per-project).

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
TYPE Agent type (claude, gemini, codex, etc.)
NAME Custom name (if assigned)
ROLE Agent role description (if assigned)
PORT HTTP port number
STATUS Current status (READY, WAITING, PROCESSING, DONE)
WORKING_DIR Current working directory
TRANSPORT Communication transport indicator

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 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. Option selection UI, Allow execution prompts
  • Claude: โฏ Option cursor, โ˜/โ˜‘ 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
delegate.md Task delegation rules
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"
  },
  "delegation": {
    "enabled": false
  }
}

Environment Variables (env)

Variable Description Default
SYNAPSE_HISTORY_ENABLED Enable task history false
SYNAPSE_FILE_SAFETY_ENABLED Enable file safety false
SYNAPSE_FILE_SAFETY_DB_PATH File safety DB path ~/.synapse/file_safety.db
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

A2A Communication Settings (a2a)

Setting Value Description
flow roundtrip Always wait for result
flow oneway Always forward only (don't wait)
flow auto AI agent decides per task (default)

Delegation Settings (delegation)

Setting Value Description
enabled true Load .synapse/delegate.md and enable delegation rules
enabled false Disable delegation (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:

  1. Agent-specific setting (claude, gemini, codex, opencode, copilot) if present
  2. Otherwise use default
  3. 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

Pushing a tag automatically publishes to PyPI via GitHub Actions.

# 1. Update version in pyproject.toml
# version = "0.2.0"

# 2. Create and push tag
git tag v0.2.0
git push origin v0.2.0

Manual Publishing

# Build and publish with uv
uv build
uv publish

User Installation

# pipx (recommended)
pipx install synapse-a2a

# or pip
pip install synapse-a2a

# Run directly with uvx
uvx synapse-a2a claude

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
guides/delegation.md Task delegation guide
docs/file-safety.md File conflict prevention
docs/project-philosophy.md Design philosophy

License

MIT License


Related Links

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

synapse_a2a-0.3.11.tar.gz (312.4 kB view details)

Uploaded Source

Built Distribution

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

synapse_a2a-0.3.11-py3-none-any.whl (165.3 kB view details)

Uploaded Python 3

File details

Details for the file synapse_a2a-0.3.11.tar.gz.

File metadata

  • Download URL: synapse_a2a-0.3.11.tar.gz
  • Upload date:
  • Size: 312.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for synapse_a2a-0.3.11.tar.gz
Algorithm Hash digest
SHA256 e7e5d8f1912cf10d08f406a601d2d691e5140109cdaf7e0d014657d51b3c39a2
MD5 a683ce63369b9f6814eb751601eabf75
BLAKE2b-256 255ef18e8438ca757bbd5e1f90f214498d1754b0abfdd9914edc47b601d0c356

See more details on using hashes here.

Provenance

The following attestation bundles were made for synapse_a2a-0.3.11.tar.gz:

Publisher: publish.yml on s-hiraoku/synapse-a2a

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file synapse_a2a-0.3.11-py3-none-any.whl.

File metadata

  • Download URL: synapse_a2a-0.3.11-py3-none-any.whl
  • Upload date:
  • Size: 165.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for synapse_a2a-0.3.11-py3-none-any.whl
Algorithm Hash digest
SHA256 0fcbcfe44d6d284bd3f930b59e8654629f4a955a8639ed61cae83deb2b3c7cba
MD5 2db2d274aaf5c4aa8b16247ee13879ae
BLAKE2b-256 8e32c3f5a1144c06342cfeb74a72e1dcc46b321ec17744d34a0f1ac22b2cf450

See more details on using hashes here.

Provenance

The following attestation bundles were made for synapse_a2a-0.3.11-py3-none-any.whl:

Publisher: publish.yml on s-hiraoku/synapse-a2a

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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