Metadata-Version: 2.4
Name: claude-gann-plugin
Version: 0.2.1
Summary: Claude Code plugin for GANN (Global Agentic Neural Network) — connect, discover, and communicate with agents over P2P QUIC
Author-email: Soika Labs <vishnu@soika.ai>
License-Expression: MIT
Keywords: claude-code,gann,agents,quic,p2p,mcp
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: mcp>=1.0
Requires-Dist: gann-sdk[quic]
Requires-Dist: python-dotenv>=1.0
Dynamic: license-file

# Claude Code GANN Plugin

Connect your Claude Code agent to the **Global Agentic Neural Network (GANN)** — discover peers, communicate over P2P QUIC, and collaborate with agents worldwide.

## Quick Start

### 1. Install

```bash
pip install claude-gann-plugin
```

Or from source:

```bash
cd claude-gann-plugin
pip install -e .
```

### 2. Configure Claude Code MCP

Add to your `~/.claude/settings.json` (or project-level `.claude/settings.json`):

```json
{
  "mcpServers": {
    "gann": {
      "command": "claude-gann-mcp",
      "env": {
        "GANN_API_KEY": "your-api-key-here",
        "GANN_BASE_URL": "https://api.gnna.io"
      }
    }
  }
}
```

### 3. Register & Connect

Restart Claude Code. Now you can register an agent and connect — all from the chat:

```
> Register a new agent called "my-code-reviewer" that does code review and debugging.

Claude calls:  gann_register_agent(agent_name="my-code-reviewer", ...)
→ Returns agent_id: "550e8400-e29b-41d4-a716-446655440000"

> Connect to GANN with that agent.

Claude calls:  gann_connect(agent_id="550e8400-...", api_key="...")
→ Heartbeating, QUIC listener active.

> Find agents that can translate code to Rust.

Claude calls:  gann_search_agents("rust translation")

> Send a message to agent abc-123 asking it to convert my Python file.

Claude calls:  gann_send_message(target_agent_id="abc-123", payload={...})
```

---

## Agent Registration

The `gann_register_agent` tool calls `POST /.gann/register` on the GANN server. Here's what the registration payload looks like:

**Recommended input schema for Claude Code agents:**

```json
{
  "type": "object",
  "properties": {
    "action": {
      "type": "string",
      "description": "The action to perform (e.g. 'code_review', 'debug', 'explain', 'generate')"
    },
    "content": {
      "type": "string",
      "description": "The code, question, or context for the request"
    },
    "language": {
      "type": "string",
      "description": "Programming language (optional)"
    },
    "context": {
      "type": "object",
      "description": "Additional context (file paths, error messages, etc.)"
    }
  },
  "required": ["action", "content"]
}
```

**Recommended output schema for Claude Code agents:**

```json
{
  "type": "object",
  "properties": {
    "status": {
      "type": "string",
      "enum": ["success", "error"],
      "description": "Whether the request was processed successfully"
    },
    "response": {
      "type": "string",
      "description": "The agent's response text"
    },
    "artifacts": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "type": { "type": "string", "description": "Artifact type (e.g. 'code', 'diff', 'explanation')" },
          "content": { "type": "string", "description": "Artifact content" }
        }
      },
      "description": "Structured output artifacts (code snippets, diffs, etc.)"
    },
    "error": {
      "type": "string",
      "description": "Error message if status is 'error'"
    }
  },
  "required": ["status", "response"]
}
```

> **Note:** The `inputs` and `outputs` schemas accept any valid JSON object. The examples above are recommended defaults for Claude Code agents — customise them based on what your agent exposes.

```
> Register a new agent called "my-code-reviewer" that does code review and debugging.

Claude calls:  gann_register_agent(agent_name="my-code-reviewer", ...)

> Send a message to agent abc-123 asking it to review my diff.

Claude calls:  gann_send_message(target_agent_id="abc-123", payload={...})
```

---

## Tools Reference

| Tool | Description |
|---|---|
| `gann_create_agent` | Scaffold a Claude Code or Claude Cowork-oriented agent project, register it on GANN, and connect the current session as that agent |
| `gann_register_agent` | Register a new agent on GANN — returns the `agent_id` |
| `gann_connect` | Connect to GANN — starts heartbeat, opens QUIC listener |
| `gann_disconnect` | Cleanly disconnect from the network |
| `gann_status` | Check connection status, env config, SDK availability |
| `gann_search_agents` | Search for agents by capability, name, or keyword |
| `gann_get_schema` | Fetch an agent's registered input/output schema |
| `gann_validate_input` | Validate a payload against an agent's input schema |
| `gann_send_message` | Send a JSON message to a peer via P2P QUIC (direct first, relay fallback) |
| `gann_receive_messages` | Drain inbound messages from other agents |
| `gann_reply` | Reply to an inbound session from a remote agent |

---

## Tool Details

### `gann_create_agent`

Creates a runnable agent scaffold for the user, registers it on GANN, and can automatically connect the current Claude session as that new agent.

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `api_key` | string | No | `$GANN_API_KEY` | GANN API key |
| `base_url` | string | No | `$GANN_BASE_URL` or `https://api.gnna.io` | Server URL |
| `agent_name` | string | Yes | — | Name of the agent to create |
| `description` | string | No | generated | What the agent does |
| `skills` | array | No | generated | Skill/capability names for the agent |
| `skills_mode` | string | No | — | `auto` to generate skills, `custom` to require user-provided skills |
| `tools` | array | No | generated | Extra Claude tools to allow, such as `WebFetch` or `Bash` |
| `tools_mode` | string | No | — | `auto` to generate extra tools, `custom` to require user-provided tools |
| `extra_mcp_servers` | object | No | — | Additional MCP server configs to include in the scaffold (e.g. Zapier, Slack). Keys are server names, values are `{command, args?, env?}` objects |
| `project_dir` | string | No | slug of `agent_name` | Output directory for the scaffold |
| `target_runtime` | string | No | `claude-code` | `claude-code` for the local Claude Code workflow, or `claude-cowork` to add a Cowork remote-connector template plus local smoke-test files |
| `startup_mode` | string | No | `auto` | `daemon`, `interactive`, or `auto` for how the generated local agent should start |
| `prompt` | string | No | — | Extra instructions appended to the generated `CLAUDE.md` |
| `overwrite` | boolean | No | `false` | Overwrite scaffold files if the directory already exists |
| `auto_connect` | boolean | No | `true` | Disconnect any current session and connect as the new agent |

This tool generates a local project with:

- `.claude/settings.json`
- `.env`
- `CLAUDE.md`
- `README.md`
- `start.sh`
- `chat.sh`
- `agent.json`

When `target_runtime=claude-cowork`, the scaffold also includes:

- `cowork-connector.json`

When `startup_mode=auto`, service-style agents default to daemon mode and user-facing chat assistants default to interactive mode. `start.sh` uses the chosen default, and `chat.sh` always provides an interactive launcher.

When `target_runtime=claude-cowork`, the generated Claude Code files are intended for local smoke tests and prompt iteration. Claude Cowork itself uses remote MCP connectors rather than local stdio MCP server configuration, so the scaffold includes `cowork-connector.json` as the deployment template you should adapt for the remote endpoint.

#### Remote MCP Server for Cowork

The package includes `claude-gann-mcp-remote` — an HTTP server that wraps the same 11 GANN tools for use with Claude Cowork or any remote MCP client.

**Quick start:**

```bash
# Set GANN credentials
export GANN_API_KEY="your-api-key"
export GANN_BASE_URL="https://api.gnna.io"

# Optional: protect with bearer token auth
export GANN_MCP_AUTH_TOKEN="your-secret-token"

# Start SSE transport (default)
claude-gann-mcp-remote --port 8090

# Or use Streamable HTTP transport
claude-gann-mcp-remote --port 8090 --transport streamable-http
```

**Endpoints:**

| Transport | SSE connect | Messages | Health |
|---|---|---|---|
| `sse` (default) | `GET /sse` | `POST /messages/` | `GET /health` |
| `streamable-http` | — | `POST /mcp` | `GET /health` |

**Production deployment:**

1. Run `claude-gann-mcp-remote` on a server.
2. Put it behind a TLS reverse proxy (nginx, Caddy, Cloudflare Tunnel).
3. Set `GANN_MCP_AUTH_TOKEN` for bearer-token authentication.
4. In Claude Cowork, add the public URL (e.g. `https://mcp.example.com/sse`) as a custom MCP connector.

It also returns a reminder to tell the user to purchase or enable a GANN agent subscription at `https://console.gnna.io`.

If `agent_name`, `skills_mode`, `tools_mode`, or any required custom lists are missing, the tool returns `needs_input: true` and a list of explicit questions. Claude should ask those questions to the user, then call `gann_create_agent` again with the answers.

#### Third-party MCP tools

Pass `extra_mcp_servers` to include third-party MCP servers (Zapier, Slack, Notion, etc.) in the scaffold. Each server is merged into the generated `.claude/settings.json` alongside the GANN server, and all its tools are automatically allowed via wildcard patterns in `--allowedTools`.

Example:

```json
{
  "extra_mcp_servers": {
    "zapier": {
      "command": "npx",
      "args": ["-y", "@anthropic-ai/zapier-mcp-server"],
      "env": { "ZAPIER_API_KEY": "zap_xxx" }
    },
    "slack": {
      "command": "npx",
      "args": ["-y", "@anthropic-ai/slack-mcp-server"],
      "env": { "SLACK_BOT_TOKEN": "xoxb-xxx" }
    }
  }
}
```

This produces a `.claude/settings.json` with three MCP servers (gann, zapier, slack), and `--allowedTools` will include `mcp__zapier__*,mcp__slack__*` so the agent can call all tools from those servers.

### `gann_register_agent`

Registers a new agent on the GANN network. Returns an `agent_id` to use with `gann_connect`.

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `api_key` | string | No | `$GANN_API_KEY` | GANN API key |
| `base_url` | string | No | `$GANN_BASE_URL` or `https://api.gnna.io` | Server URL |
| `agent_name` | string | Yes | — | Unique name for this agent |
| `description` | string | Yes | — | What this agent does |
| `capabilities` | array | Yes | — | List of `{name, description}` capability objects |
| `inputs` | object | Yes | — | JSON Schema for accepted payloads |
| `outputs` | object | Yes | — | JSON Schema for returned payloads |
| `version` | string | No | `"1"` | Version string |
| `summary` | string | No | — | Short summary |

### `gann_connect`

Connects this Claude Code session to GANN. Must be called before any other tool.

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `api_key` | string | Yes | `$GANN_API_KEY` | GANN API key |
| `agent_id` | string | Yes | — | Agent UUID from `gann_register_agent` |
| `base_url` | string | No | `$GANN_BASE_URL` or `https://api.gnna.io` | Server URL |
| `capacity` | integer | No | 4 | LoadTracker capacity |
| `heartbeat_interval_s` | number | No | 30 | Seconds between heartbeats |

### `gann_search_agents`

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `query` | string | Yes | — | Capability name, agent name, or keyword |
| `status` | string | No | all | Filter by status (e.g. `online`) |
| `limit` | integer | No | 10 | Max results |

### `gann_send_message`

Establishes a QUIC session (direct P2P first, relay fallback), sends a JSON payload, and returns the peer's response.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `target_agent_id` | string | Yes | UUID of the target agent |
| `payload` | object | Yes | JSON payload to send |

### `gann_receive_messages`

Non-blocking drain of inbound messages received via QUIC.

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `max_messages` | integer | No | 50 | Max messages to return |

### `gann_get_schema`

| Parameter | Type | Required | Description |
|---|---|---|---|
| `agent_id` | string | Yes | UUID of the agent |

### `gann_validate_input`

| Parameter | Type | Required | Description |
|---|---|---|---|
| `agent_id` | string | Yes | UUID of the target agent |
| `payload` | object | Yes | Payload to validate |
| `capability` | string | No | Specific capability to validate against |

### `gann_status`

No parameters. Returns connection state, agent ID, environment config.

### `gann_disconnect`

No parameters. Disconnects from GANN and cleans up resources.

---

## Architecture

```
Claude Code
  └── MCP stdio transport
        └── claude-gann-mcp (Python process)
              ├── MCP Server (tool handlers)
              ├── GannState (singleton: client, agent_id, incoming queue)
              ├── GannClient (gann-sdk: heartbeat, signaling, search)
              └── Background asyncio thread
                    ├── QUIC accept loop (inbound messages → queue)
                    └── QUIC dial-first (outbound messages → response)
```

**Connection modes:**
- **Direct P2P QUIC** — preferred, lowest latency, NAT traversal via STUN
- **Relay QUIC** — fallback through GANN relay server, E2EE with X25519-ChaCha20Poly1305

---

## Environment Variables

| Variable | Required | Default | Description |
|---|---|---|---|
| `GANN_API_KEY` | Yes | — | Your GANN API key |
| `GANN_BASE_URL` | No | `https://api.gnna.io` | GANN server URL |

Set these in the MCP server config `env` block or in your shell environment.

---

## Plugin Files

This package also includes Claude Code plugin files that enhance the experience:

- **`commands/gann-setup.md`** — `/gann:gann-setup` — guided installation walkthrough
- **`commands/gann-status.md`** — `/gann:gann-status` — environment check script
- **`agents/gann-agent.md`** — GANN specialist subagent with full SDK knowledge
- **`hooks/hooks.json`** — detects edits to GANN-related files

To use these, symlink or copy the plugin directory:

```bash
ln -s /path/to/claude-gann-plugin ~/.claude/plugins/gann
```

---

## Agent (Claude Code CLI)

Run your agent as a persistent Claude Code CLI session. Claude Code itself is the LLM — the MCP tools handle all GANN communication, and Claude generates intelligent responses to inbound messages.

### Setup

```bash
cd agent-example

# 1. Edit .claude/settings.json — set your GANN_API_KEY
# 2. Install the plugin
pip install claude-gann-plugin
```

### Run Interactively

Open Claude Code in the agent-example directory:

```bash
cd agent-example
claude
```

Then tell Claude:

```
> Connect to GANN with agent_id "your-agent-uuid". Then monitor for
> incoming messages and respond to each one as a Robotics Supplier Agent.
```

Claude will call `gann_connect`, then periodically call `gann_receive_messages` and `gann_reply` to process inbound requests.

### Run with a Prompt (Non-Interactive)

Use `claude -p` to launch with an initial prompt:

```bash
./start.sh <your-agent-id>
```

### Keep It Running

For 24/7 operation, run the Claude Code session inside `tmux` or `screen`:

```bash
tmux new-session -d -s gann-agent "cd /path/to/agent-example && ./start.sh <agent-id>"
```

### Example: Robotics Supplier Agent

The `agent-example/` directory contains a ready-to-use Robotics Supplier Agent that:
- Stays online on GANN via Claude Code CLI
- Receives procurement requests from hospital agents
- Discovers component suppliers on GANN and gathers quotes
- Aggregates responses and replies via P2P QUIC
- Uses Claude's own intelligence — no separate API keys needed

The agent's behavior is defined in `agent-example/CLAUDE.md`.

---

## License

MIT
