Skip to main content
Glama
MiiKiyoshi

agent-channel-mcp

by MiiKiyoshi

agent-channel-mcp

What it does

Connects local agent sessions running in different harnesses, such as Claude Code and Codex. Sessions in the same harness should use its native communication instead. Both harnesses run this MCP server on the same host and OS account.

Related MCP server: mcp-comms

Install and connect

Requires Python 3.10 or newer, uv, and a harness with MCP support.

git clone https://github.com/MiiKiyoshi/agent-channel-mcp.git
cd agent-channel-mcp
uv sync
claude mcp add --scope user agent-channel -- uv run --directory "$PWD" --no-sync agent-channel-mcp
codex mcp add agent-channel -- uv run --directory "$PWD" --no-sync agent-channel-mcp

Reconnect MCP in both harnesses after registration. See the Codex MCP documentation for Codex configuration details.

Create a room and invite the other agent

Ask your agent to create a room and write an invitation. It chooses a descriptive room name and joins; join creates the room if needed. Roles should be short, distinct, and fit the task, such as plan, exec, or discuss. The invitation is text to paste into the other harness. It holds the role's purpose in a line, the handoff role to contact, the join call, and the waiter step, and nothing else: the task's detail reaches the new agent from that handoff role inside the room, not from the invitation.

Purpose: <the role's purpose, in a line>.
Handoff role: after joining, contact <role> for the current state and tasks.
Call agent-channel join(room="<room>", name="<peer role>").
Follow the returned how if waiter is offline; if active, do nothing.

Join, wait, and send

On a new MCP connection, the agent calls join(room, name). In the response, registered_roles lists the roles whose connection or waiter is active, and role_statuses shows which of those leases are active. A fully offline registration stays internal so direct messages can remain queued and the same name can reconnect, but it is not shown as a current participant. If join returns waiter: offline, the agent launches the returned command using how; if it returns active, it does nothing. It keeps that waiter running and does not poll. The Codex command registers a waiter managed by the MCP server, while Claude Code keeps the waiter in a Monitor. A Monitor expires after 30 minutes and ends the waiter; on each expiry notice the agent calls join again, which returns offline and the same command. Messages sent meanwhile stay queued.

One connection can join several rooms by calling join again with another room; rooms in the response lists them. A room can carry standing rules: join(room, name, policy="...") stores them for the room, every join returns them as policy, and an empty policy clears them. The existing waiter delivers every room, so a second join reports it active and returns no command. Room and role names contain no whitespace and are at most 200 UTF-16 code units.

Ask the agent to send directly with send(text="...", to="exec"); omitting to broadcasts to every other role in that room. It uses rename(name="...") if its role changes and leave() when leaving. With several rooms joined, send, rename, and leave take room="..."; with one room it may be omitted. Leaving the last room stops the waiter. Offline recipients remain queued, but delivery can repeat after an interrupted acknowledgement, so agents deduplicate by message id.

A newly joined agent sends first to the handoff role named in its invitation. That role answers with the current state, the settled contracts, the assets in hand, and the tasks that fall to the new role. Deliveries begin with id room sender. Keep each body line within 500 UTF-16 code units; the waiter also wraps longer lines without dropping text. A peer directs work only when the user explicitly delegated authority to that role; the handoff briefing is under the same rule.

Upgrade

A database from an earlier version is brought up to date when it is next opened. Messages that were still unacknowledged at that moment are marked as handed over once, since an earlier delivery may already have reached the receiver without a key to recognise it by: they are looked for, not added, and one that is not found stays pending as "delivery uncertain" until a person sends it again.

Restart or reconnect

After either harness, client, or server restarts, tell the agent to join each of its rooms again and follow the live-status procedure above; the previous connection's room list is not restored automatically, and never assume its waiter survived. Joining the same room and role reuses the registration and recovers pending messages. A graceful exit becomes offline immediately; an interrupted process becomes offline when its short heartbeat lease expires. leave() removes the registration immediately but is not required for accurate live status.

Troubleshooting

  • Recipient not found: ask that agent to join the room, then tell the sending agent to call join again to refresh registered roles and live status.

  • Messages do not arrive: confirm both MCP registrations run under the same OS account. If either uses --db, both must use the same absolute path.

  • Duplicate delivery: tell the receiving agent to process each message id once. To a Codex thread the waiter adds a message at most once: it queues it under the key agent-channel:<channel id>:<message id> through a stock codex app-server child, and a message handed over once is never added again, only looked for in the thread's queue and items by that key.

  • Codex message pending, waiter_detail says "delivery uncertain": the message was handed over once, the answer was lost, and the key is in neither the queue nor the items. The app-server removes a queued message when its turn starts and records the item later, so the message may still appear; the waiter looks again every 10 seconds, acknowledges when it appears, and serves later messages meanwhile. A message that never appears stays pending with that note; delivering it again is a person's decision (it can be sent again as a new message). The same note follows a role taken over by a new connection in the instant between the old waiter's hand-over and its add: the message then sits in the old thread.

  • Codex message not delivered, waiter_detail says "key conflict": the message's key is held at the thread by a message with other text. It is not queued and not acknowledged; a person decides.

  • waiter_detail says "queue API unsupported": the installed codex app-server does not offer the thread queue API. Nothing is delivered to Codex until a Codex with that API is installed.

  • Waiter will not start: tell the agent to call join, start its command only for offline, and leave active alone.

  • Waiter disappeared: inspect waiter_detail from join. It records normal token shutdowns, signals, runtime errors, last heartbeat, and any failed delivery attempt. An abrupt kill becomes offline when its heartbeat lease expires.

Test and contribute

Install development dependencies and run the full test suite before submitting a change:

uv sync --extra dev
uv run --no-sync pytest -q

Tests use temporary databases and a fake codex app-server; the installed Codex is exercised in a private network namespace where codex and unshare are available. Live delivery checks require both real harnesses to be connected.

Available Tools

4 tools
joinA

Join a room and return identity, participants, waiter state, command, and client-specific launch instructions.

On each new MCP connection, call once and start command exactly once when waiter is missing. A new connection with the same room and name takes ownership.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
roomYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses ownership semantics ('takes ownership'), the existence of waiter state, and the once-per-connection contract. Remaining ambiguity (what 'waiter state' means, what happens on conflict) keeps it short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences: the first front-loads purpose and return contents, the second carries the invocation contract. Dense but every clause earns its place; minor awkwardness in 'start command exactly once when waiter is missing.'

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an annotation-free tool with no output schema, the description covers what it returns and the critical call-once/ownership behavior, which is what an agent needs to avoid misusing a coordination primitive. Only the parameter semantics gap leaves it imperfect.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, but it only re-uses the words 'room' and 'name' without defining their format, uniqueness, or role. The two required parameters remain effectively undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource ('Join a room') and even enumerates what the call returns (identity, participants, waiter state, command, launch instructions). The verb 'join' is self-evidently distinct from the sibling actions send/rename/leave, though no sibling is named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete when-to-call guidance: invoke once per new MCP connection, and 'start command exactly once when waiter is missing.' This is rarer and more actionable than generic usage text, though it never contrasts with the sibling tools or states when NOT to call.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

leaveA

Leave the current room, stop its waiter, and allow another join.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden and does disclose the two key side effects: stopping the waiter and freeing the slot ('allow another join'). It omits failure behavior (e.g., calling while not in a room), so it is not fully transparent but substantially better than a bare verb.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with three clauses, each adding distinct information and no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, no-output, annotation-free tool, the description covers the action and its consequences well. Only the absence of error/precondition detail keeps it from being fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline of 4 applies; there is nothing for the description to clarify beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Leave') plus the resource ('the current room') and enumerates the side effects, distinguishing it cleanly from the sibling 'join'. An agent can identify the action without opening anything else.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is strongly implied by 'the current room' (you must already be in one) and the contrast with 'join', but there is no explicit when-to-use/when-not statement or named alternative. Adequate but leaves routing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

renameC

Change your role name in the current room.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes

TDQS

C2.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It adds the scope 'current room' but omits permissions required, reversibility, success/failure behavior, and other mutation traits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no wasted words. It immediately states the action and scope, making it maximally concise for its content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple 1-parameter mutation, the description is insufficient given zero annotation coverage and no output schema. It omits prerequisites, error behavior, and name constraints that an agent would need to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It links the 'name' parameter to 'role name', adding some semantic meaning, but provides no format, length, or constraint details to fully document the single parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Change') and resource ('role name') with a scope ('in the current room'). It clearly distinguishes the action from siblings join, send, and leave, though it does not explicitly reference them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance, prerequisites, or alternatives are provided. The description only states what the tool does, not when an agent should choose it over other available actions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sendB

Send to one role, or omit to to broadcast to every other registered role.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNo
textYes

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It does disclose the significant side effect that omitting 'to' broadcasts to every other registered role, which is valuable behavioral information. But it says nothing about delivery, errors, or whether this is a read or write operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence that front-loads the key behavioral distinction. It loses a point for the typo 'omit to to' and for compressing two distinct ideas (targeting and broadcasting) without a clear pivot.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple 2-parameter tool with no output schema, the description covers the one genuinely ambiguous parameter and its broadcast behavior, which is the main gap it needed to fill. It still omits what is actually transmitted and any failure/permission context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema coverage and two undocumented parameters, the description compensates well for the ambiguous one: it explains that 'to' targets a single role and that its absence triggers a broadcast. 'text' is left unexplained but is self-evident from its name.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The verb 'Send' is paired with the concept of roles, and the broadcast-vs-targeted behavior is stated, which distinguishes it somewhat from join/rename/leave. However, the resource being sent is never named explicitly (presumably the 'text' parameter, but the description never says 'message'), leaving the purpose only implied.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It effectively tells the agent when to pass 'to' versus when to omit it (omit = broadcast to all other roles), which is real usage guidance for the parameter choice. It does not, however, mention any prerequisite (e.g., that the agent must join first) or reference the sibling tools as alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.0
    • First observedjoin
    • First observedleave
    • First observedrename
    • First observedsend

TDQS

A3.7/5.0

Scored across 4 tools

Disambiguation5/5

Each tool targets a distinct action in the room lifecycle: joining, sending messages, renaming, and leaving. There is no overlap in purpose; join's complexity does not confuse it with other operations.

Naming Consistency5/5

All tool names are single imperative verbs in lowercase (join, send, rename, leave), following a predictable and consistent convention throughout.

Tool Count5/5

Four tools is well-scoped for a basic agent channel. Each tool earns its place by covering a necessary room interaction without redundancy.

Completeness4/5

The surface covers join, send, rename, and leave, which is most of the chat lifecycle. An explicit message-retrieval tool is missing, but the join response points to a waiter process that likely delivers incoming messages.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables inter-session communication and coordination for multiple Claude Code instances through a shared SQLite database. Supports real-time messaging, shared state management, and resource locking to facilitate parallel development workflows between AI agents.
    5 npm
    8
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables multiple AI agents to communicate and coordinate via a shared SQLite-backed message log, supporting directed messages, broadcasts, and session discovery.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables inter-session messaging for Claude Code, allowing sessions on different machines to send messages to each other, with delivery as user turns and support for offline queuing.
    60 npm
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables coordination and communication between multiple Claude Code sessions across machines via a chat server, providing tools for sending messages, waiting for responses, and managing session status.
    MIT