mcp-terminal-share
mcp-terminal-share
An MCP server that lets two or more Claude Code terminals on the same machine talk to each other. Register each terminal with a short name, then send messages between them.
┌──────────────┐ ┌──────────────┐
│ terminal A │ ── send_message ──► │ terminal B │
│ │ ◄── send_message ── │ │
└──────────────┘ └──────────────┘
│ file-based │
└──────► ~/.claude/terminal-messages ──┘Why
Pair-running two Claude Code sessions and want one to hand off a long log or a task summary to the other? That's it.
Related MCP server: claude-intercom-mcp
Install
Wire it into Claude Code's MCP config (Claude Code → ~/.claude.json or via the CLI):
claude mcp add terminal-share -- npx -y mcp-terminal-shareOr by hand in your MCP config:
{
"mcpServers": {
"terminal-share": {
"command": "npx",
"args": ["-y", "mcp-terminal-share"]
}
}
}Requires Node.js 18+.
Tools
Tool | Purpose |
| Give this terminal a name (e.g. |
| Show all live terminals. Stale records are cleaned up automatically. |
| Send |
| Read messages addressed to you. Deletes them on read by default. |
| Block until a message arrives or |
Names must match ^[A-Za-z0-9_-]{1,32}$. Message content is capped at 1 MB, summary at 500 B.
Suggested slash commands
If you already use the bundled t-rg / t-list / t-send / t-get / t-watch skills, they map 1:1 onto the tools above.
Show the registered name in your statusline
After a successful register, the server writes a tiny session record keyed by a hash of the working directory:
~/.claude/terminal-messages/sessions/<sha256(cwd)[:16]>.jsonThe MCP server, your statusline, and any helper subprocess it spawns all inherit cwd from the same Claude Code session, so they can find each other without any extra plumbing.
claude-hud
Add --extra-cmd "mcp-terminal-share-label" to your statusline command:
{
"statusLine": {
"type": "command",
"command": "claude-hud --extra-cmd \"mcp-terminal-share-label\""
}
}The bundled mcp-terminal-share-label bin reads the record for the current cwd and outputs claude-hud's expected {"label": "📟 <name>"} (or {} when nothing is registered). Override the emoji/prefix with MCP_TERMINAL_SHARE_LABEL_PREFIX.
Other statuslines
Roll your own. The minimal Node version:
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { homedir } from "node:os";
import { createHash } from "node:crypto";
const key = createHash("sha256").update(process.cwd()).digest("hex").slice(0, 16);
try {
const { name } = JSON.parse(
readFileSync(
join(homedir(), ".claude", "terminal-messages", "sessions", `${key}.json`),
"utf-8",
),
);
process.stdout.write(`📟 ${name}`);
} catch {
// not registered
}The file is removed automatically when the MCP server shuts down.
Known limitation: if you open two Claude Code sessions in the same directory, the later one's register overwrites the earlier one's session record. This only affects the statusline label — message routing between terminals is unaffected.
How it works
Each terminal writes its registration to
~/.claude/terminal-messages/terminals/<name>.json.Messages are dropped into
~/.claude/terminal-messages/messages/to_<recipient>_<ts>_<rand>.json.A session record for statusline consumers lives at
~/.claude/terminal-messages/sessions/<sha256(cwd)[:16]>.json.Liveness uses a 5 s heartbeat; records older than 30 s whose owning PID is also dead are reaped on read.
Messages older than 24 h are reaped on read, and a per-recipient queue cap of 100 prevents runaway buildup.
All file writes go through a temp-file + rename for atomicity.
Override the storage root with MCP_TERMINAL_SHARE_DIR (mostly useful for tests).
Security model
Local, single-user, single-host. Anyone with read access to
~/.claude/terminal-messagescan read or spoof messages. This is fine on a personal dev machine and explicitly out of scope to defend otherwise.No network surface. Communication is purely through the local filesystem; nothing listens on a port.
Input validation. Names are regex-validated to prevent path traversal; content size is capped.
If you need cross-machine sharing or untrusted multi-tenant isolation, this is the wrong tool — reach for a real message bus.
Development
npm install
npm testTests use Node's built-in node:test runner with isolated temp dirs (no extra deps).
License
Available Tools
5 toolsget_messagesA
Read messages sent to this terminal. Returns all messages and optionally deletes them after reading.
| Name | Required | Description | Default |
|---|---|---|---|
| terminal_name | Yes | Your terminal name | |
| delete_after_read | No | Delete messages after reading (default: true) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the full burden. It discloses the core behavior (read and optionally delete) but does not mention potential side effects, rate limits, or authentication needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very concise at two short sentences, with no unnecessary words or repetition. It is front-loaded with the main action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description omits the return format, which is important since there is no output schema. While the tool is simple, more detail on what 'returns all messages' means (e.g., array of strings) would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers 100% of parameters with descriptions. The tool description adds no additional meaning beyond what is already in the schema, so baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads messages and optionally deletes them. It distinguishes from siblings like list_terminals, register, send_message, and watch_messages by focusing on reading and optional deletion.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies that this tool is for one-time reading of messages, but it does not explicitly guide when to use this tool versus watch_messages for continuous monitoring, nor does it mention when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_terminalsB
List all registered terminals.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears full responsibility for behavioral disclosure. It correctly implies a read-only operation but lacks any details about side effects, permissions required, or what 'registered' means. The simplicity of the tool prevents a lower score but the omission of behavioral nuance is notable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that immediately conveys the purpose. Every word earns its place with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless tool, the description provides the minimum viable information. However, it fails to explain what a terminal is in this context, what the output contains (no output schema), or how it relates to sibling tools like 'send_message'. The simplicity of the tool modestly compensates.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero parameters with 100% coverage, so the description does not need to add parameter details. The baseline of 4 is appropriate; it does not detract but also does not enhance understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'list' and the resource 'terminals'. It is specific and unambiguous. However, it does not differentiate from sibling tools like 'get_messages', which also lists resources, missing an opportunity to clarify the domain scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No instructions on when to use this tool versus alternatives such as 'register' or 'get_messages'. Without context, an AI agent may not know that terminals must be listed before sending messages, for example.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
registerA
Register this terminal with a name (e.g. A1, A2). Other terminals can then send messages to this name.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Terminal name, e.g. A1, A2, dev, test |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the burden. It explains that registration enables message reception but does not disclose side effects like overwriting existing registrations, idempotency, or required permissions. Moderate transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, both front-loaded with key information. No extraneous words, every sentence serves a purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter tool with no output schema, the description covers the action and its intended effect. Minor gap: it does not describe return values or error conditions, but the context is largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 100% coverage and already includes a description for the 'name' parameter. The tool description adds examples but does not significantly extend meaning beyond what the schema provides. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Register this terminal with a name' and gives examples like A1, A2. It also explains the purpose: enabling other terminals to send messages to the registered name. This distinguishes it from siblings like send_message and get_messages.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies that registration is a prerequisite for receiving messages, but does not explicitly state when to use this tool versus alternatives. It lacks explicit conditions or exclusions, such as when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_messageB
Send a message to another terminal. The target terminal can read it with get_messages.
| Name | Required | Description | Default |
|---|---|---|---|
| from | Yes | Your terminal name (the sender) | |
| to | Yes | Target terminal name (the receiver) | |
| summary | Yes | Brief summary of the message | |
| content | Yes | The full message content to share |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It states that the tool sends a message but omits important behavioral details such as whether the sender must be registered, persistence of messages, rate limits, or confirmation of delivery.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise with two sentences, no wasted words, and the action verb is front-loaded. It efficiently conveys the core functionality.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple parameter structure (all required, no nested objects, no output schema) and absence of annotations, the description is minimally adequate. It covers the basic action but leaves out behavioral context like success/error responses or authentication requirements.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% coverage with thorough descriptions for all 4 parameters. The tool description adds no extra meaning beyond the schema, so a baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Send a message to another terminal' with a specific verb and resource, and it distinguishes the tool from its sibling 'get_messages' by noting the target can read with that tool. However, it does not explicitly differentiate from other siblings like 'register' or 'list_terminals'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description hints at using 'get_messages' for reading but provides no explicit guidance on when to use or avoid 'send_message' itself. There is no mention of prerequisites, limitations, or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
watch_messagesA
Block and wait for a message to arrive for this terminal. Returns as soon as a message is received or timeout is reached.
| Name | Required | Description | Default |
|---|---|---|---|
| terminal_name | Yes | Your terminal name | |
| timeout | No | Max seconds to wait | |
| interval | No | Poll interval in seconds |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Describes blocking behavior and timeout, but omits what is returned (message content? confirmation?) and behavior on timeout. No annotations to supplement.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded, no extraneous words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Missing critical info about return value and whether it is a synthetic or real-time wait. With no output schema, description should explain what the tool returns.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers all parameters with descriptions. Description adds no extra meaning beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states verb ('Block and wait') and resource ('message for this terminal'). Distinguishes from siblings like get_messages (non-blocking retrieval) and send_message.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies a blocking use case for real-time waiting, but no explicit guidance on when to choose this over get_messages (polling) or 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.
5 tool updates
v1.1.0- First observed
get_messages - First observed
list_terminals - First observed
register - First observed
send_message - First observed
watch_messages
TDQS
Scored across 5 tools
Each tool has a clear, non-overlapping purpose: registration, sending, listing, and two distinct reading methods (polling and blocking). No ambiguity.
All tool names follow a consistent verb_noun pattern (get_messages, list_terminals, register, send_message, watch_messages), making them predictable.
With 5 tools covering the core operations of a terminal messaging service, the count is well-scoped and each tool earns its place.
The tool surface covers registration, sending, and two receive modes. A minor gap is the lack of an explicit unregister or delete functionality, but the core workflow is complete.
Maintenance
Related MCP Connectors
Messaging and inboxes for AI agents: register, send signed messages, check your inbox, find agents.
Real-time chat for AI agents. Claude Code, Cursor, Cline and Codex join channels over MCP.
Ephemeral REST chatrooms for AI agents to coordinate. Share a room URL — agents talk live.
End-to-end encrypted messaging and work coordination for autonomous AI agents.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables file-based agent-to-agent communication between Claude Code instances on the same machine, using MCP channels and plain JSON files.4 npm14MIT
- AlicenseAqualityBmaintenanceEnables local messaging between Claude Code, Codex, Pi, and other coding-agent sessions on the same machine, allowing them to discover each other, send updates, ask questions, and reply.89 npm2AGPL 3.0
- AlicenseNot gradedqualityDmaintenanceEnables Claude Code agents to communicate across sessions, terminals, and repositories through shared channels with persistent context.MIT
- AlicenseNot gradedqualityBmaintenanceEnables local agent-to-agent messaging between Claude Code sessions via file-based channels, with a registry, MCP tools and CLI for sending, reading, and tracking messages.2MIT