Skip to main content
Glama

Agent HQ - Inter-Agent Messaging Channel for Claude Code

A local MCP channel server that enables direct agent-to-agent communication between Claude Code sessions. Built for multi-agent systems where persistent Claude Code instances need to coordinate.

How It Works

Each agent runs its own instance of this server. The server exposes:

  • send_message tool — sends a message to another agent by name

  • HTTP listener — receives messages from other agents and pushes them into the Claude session as <channel> notifications

  • Built-in guardrails — enforces one message + one response per exchange with a configurable cooldown

When Agent A calls send_message(to: "agent-b", message: "..."):

  1. Agent A's server POSTs to Agent B's HTTP listener (localhost:<port>)

  2. Agent B's server receives it and pushes a notifications/claude/channel event

  3. Agent B sees: <channel source="agent-hq" from="agent-a" to="agent-b" ts="...">message</channel>

  4. Agent B can reply once via send_message, then the exchange is locked

  5. Optionally, all messages are also posted to a Telegram group for human visibility

Related MCP server: SafeFlo

Requirements

  • Bun runtime

  • Claude Code v2.1.80+

  • Multiple Claude Code sessions running as persistent agents

Install

git clone https://github.com/aj-dev-smith/claude-channel-agenthq.git
cd claude-channel-agenthq
bun install

Configure

1. Add to .mcp.json in each agent's project root

Each agent needs its own entry with a unique name and port:

{
  "mcpServers": {
    "agent-hq": {
      "command": "bun",
      "args": ["run", "--cwd", "/path/to/claude-channel-agenthq", "--shell=bun", "--silent", "start"],
      "env": {
        "AGENT_HQ_NAME": "nova",
        "AGENT_HQ_PORT": "7001"
      }
    }
  }
}

2. Update the agent registry in server.ts

Edit the AGENTS object to match your agent setup:

const AGENTS: Record<string, { port: number; botUsername: string }> = {
  nova:   { port: 7001, botUsername: 'your_nova_bot' },
  summit: { port: 7002, botUsername: 'your_summit_bot' },
  // ... add your agents
}

The botUsername is only used for Telegram group posting (optional). If you're not using Telegram, set it to any identifier.

3. Environment variables

Variable

Required

Description

AGENT_HQ_NAME

Yes

This agent's name (must match a key in the AGENTS registry)

AGENT_HQ_PORT

Yes

Port this agent listens on for inbound messages

AGENT_HQ_GROUP_ID

No

Telegram group chat_id for human visibility (default: none)

TELEGRAM_BOT_TOKEN

No

Bot token for posting to the Telegram group

4. Start Claude Code with the development channel flag

During the channel research preview, custom channels require:

claude --dangerously-load-development-channels server:agent-hq --channels plugin:telegram@claude-plugins-official

This triggers a one-time confirmation prompt ("I am using this for local development"). For unattended operation, you can auto-accept it by sending Enter to the terminal after startup:

# In a start script:
claude --dangerously-load-development-channels server:agent-hq ... &
sleep 8
tmux send-keys -t your-session Enter 2>/dev/null

Guardrails

The server enforces strict loop prevention:

  • One message, one response per agent pair. After Agent A messages Agent B and B replies, no further messages are allowed between them until the cooldown expires.

  • 1-hour cooldown (configurable in server.ts via COOLDOWN_MS).

  • No self-messaging — an agent cannot send a message to itself.

  • Shared state — exchange tracking is stored in a shared JSON file so both sides of an exchange see the same state.

If an agent needs more than one round-trip of coordination, it should message a human operator instead.

Message Format

Inbound messages arrive as channel notifications:

<channel source="agent-hq" from="nova" to="summit" ts="2026-03-24T00:34:43.376Z">
Hey Summit, Nova here. AJ mentioned he's traveling next week -- adjust his training plan for limited equipment.
</channel>

The from field identifies the sender. Respond using the send_message tool:

send_message(to: "nova", message: "Got it, I'll write a bodyweight-only plan for next week.")

Telegram Group Visibility (Optional)

If TELEGRAM_BOT_TOKEN and AGENT_HQ_GROUP_ID are set, all messages are also posted to a Telegram group so humans can observe agent cross-talk. The format is:

[nova → @aj_summit_bot]
Hey Summit, AJ mentioned he's traveling next week...

Note: Telegram bots cannot see messages from other bots in groups. The Telegram posting is purely for human visibility — the actual message delivery uses the HTTP localhost mechanism.

Architecture

Agent A (port 7001)                    Agent B (port 7002)
┌──────────────────┐                   ┌──────────────────┐
│ Claude Session   │                   │ Claude Session   │
│                  │                   │                  │
│ send_message(    │   HTTP POST       │  ← channel       │
│   to: "agent-b", ├─────────────────►│  notification     │
│   message: "..." │  localhost:7002   │  pushed to       │
│ )                │                   │  Claude session   │
│                  │                   │                  │
│ MCP Server       │                   │ MCP Server       │
│ (stdio to Claude)│                   │ (stdio to Claude)│
│ + HTTP listener  │                   │ + HTTP listener  │
└──────────────────┘                   └──────────────────┘
         │                                      │
         └──────── Telegram Group (optional) ───┘
                   (human visibility)

Example: Starter Config for Two Agents

Agent 1 — assistant/.mcp.json:

{
  "mcpServers": {
    "agent-hq": {
      "command": "bun",
      "args": ["run", "--cwd", "/path/to/claude-channel-agenthq", "--shell=bun", "--silent", "start"],
      "env": {
        "AGENT_HQ_NAME": "assistant",
        "AGENT_HQ_PORT": "7001"
      }
    }
  }
}

Agent 2 — researcher/.mcp.json:

{
  "mcpServers": {
    "agent-hq": {
      "command": "bun",
      "args": ["run", "--cwd", "/path/to/claude-channel-agenthq", "--shell=bun", "--silent", "start"],
      "env": {
        "AGENT_HQ_NAME": "researcher",
        "AGENT_HQ_PORT": "7002"
      }
    }
  }
}

Update server.ts registry:

const AGENTS: Record<string, { port: number; botUsername: string }> = {
  assistant:  { port: 7001, botUsername: 'assistant' },
  researcher: { port: 7002, botUsername: 'researcher' },
}

Start both:

cd assistant && claude --dangerously-load-development-channels server:agent-hq
cd researcher && claude --dangerously-load-development-channels server:agent-hq

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    A Telegram-integrated MCP server that enables remote control of Claude sessions through a Telegram bot, including chat, tool approvals, task tracking, and workspace management. It provides a MiniApp interface for real-time monitoring and control of Claude's activities from mobile devices.
    90 npm
    4
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A local MCP server that connects AI coding agents (Claude Code, Codex, Cursor, etc.) on the same machine via a shared message bus, enabling them to chat, delegate tasks, and collaborate privately without cloud or internet.
    44 npm
    17
    MIT