Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,8 @@ jobs:
with:
node-version: ${{ matrix.node-version }}
cache: npm
- run: |
sudo apt-get update -qq
sudo apt-get install -y tmux
- run: npm ci
- run: npm run check
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ npm install
npm run check
```

Keep the safety model intact: workspace paths must remain fixed at server startup, child working directories must remain inside that boundary, Git calls must not use a shell or user-provided argument arrays, and new persistence paths must pass through redaction and sensitive-path filtering.
Keep the safety model intact: workspace paths must remain fixed at server startup, child working directories must remain inside that boundary, Git and tmux calls must not use a shell or user-provided argument arrays, and new persistence paths must pass through redaction and sensitive-path filtering.

For behavior changes, add an integration test using a temporary Git repository. For new MCP tools, explain why the behavior cannot fit one of the existing ten tools; a small and predictable tool surface is a product constraint.
For behavior changes, add an integration test using a temporary Git repository. Terminal changes also need an isolated tmux socket test; never attach tests to a user's default server. For new MCP tools, explain why the behavior cannot fit one of the existing tools; a small and predictable tool surface is a product constraint.
21 changes: 21 additions & 0 deletions LICENSES/tmux-bridge-mcp-MIT.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Howard Peng and tmux-bridge-mcp contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
63 changes: 55 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@

**Let AI continue where another AI stopped.**

It tracks active sessions, task leases, advisory file ownership, decisions, failed attempts, Git state, and handoffs so Codex, Claude Code, and other agents can continue each other's work without rebuilding context from scratch.
It tracks active sessions, task leases, advisory file ownership, decisions, failed attempts, Git state, and handoffs so Codex, Claude Code, and other agents can continue each other's work without rebuilding context from scratch. Its built-in tmux transport also lets those agents read and message trusted panes without installing a second MCP server.

> Not another chat memory. A local coordination layer for coding agents.

## What works in v0.3.1
## What works in v0.4.0

- Local-first SQLite storage inside a repository or workspace
- Fixed non-Git workspace boundaries with child-repository Git context
- MCP server with ten focused tools
- MCP server with ten coordination tools and five live terminal tools
- Built-in tmux transport with no `tmux-bridge-mcp` runtime dependency
- One-session tmux boundary with pane labels and self-message prevention
- Redacted, size-limited terminal reads and single-line message sends
- Persistent read-before-send guards and content-free terminal audit events
- Agent sessions and heartbeats
- Expiring task leases
- Advisory file and glob claims with overlap warnings
Expand All @@ -39,10 +43,19 @@ Agent B joins
-> claims the continuation and starts from verified project state
```

## Install from source
## Install

AgentRelay is not published to npm yet.

Install the current GitHub repository as one self-contained CLI and MCP server:

```bash
npm install -g github:arumwu/agentrelay
agentrelay --version
```

Or install from a source checkout:

```bash
git clone https://github.com/arumwu/agentrelay.git
cd agentrelay
Expand All @@ -51,7 +64,7 @@ npm run build
npm link
```

Node.js 22.13 or newer is required.
Node.js 22.13 or newer is required. The coordination and memory features work without tmux; the live terminal tools additionally require tmux 3.2 or newer.

## Quick start

Expand Down Expand Up @@ -120,6 +133,31 @@ claude mcp add --scope local agentrelay -- \

AgentRelay advertises its lifecycle instructions through MCP initialization. For clients that do not consume server instructions, place the fallback rules from [`examples/AGENTS.md`](examples/AGENTS.md) in the repository's `AGENTS.md` or `CLAUDE.md`.

## Live tmux transport

AgentRelay includes the terminal transport directly. Installing `@arumwu/agentrelay` or the GitHub package is enough; do not install or register a separate `tmux-bridge-mcp` server.

Run the agents you want to coordinate in one tmux session. When AgentRelay starts inside tmux it automatically restricts terminal access to that current session:

```bash
agentrelay terminal list
agentrelay terminal name %3 codex
agentrelay terminal read codex --lines 40
agentrelay terminal send codex "Review src/auth.ts and report any regressions"
```

`terminal read` opens a 90-second, one-use guard for that actor and pane. After one send, read the pane again before sending another message. AgentRelay stores audit metadata such as the pane, byte count, and correlation ID, but never persists captured terminal output or message content.

If AgentRelay starts outside tmux, explicitly allow one session:

```bash
agentrelay terminal --tmux-session agent-work list
```

For MCP clients launched outside tmux, set `AGENTRELAY_TMUX_SESSION` in that server's environment. Set `AGENTRELAY_TMUX_SOCKET` only when using a non-default socket. Terminal targets outside the selected session are rejected.

`terminal_send` types one literal, single-line message followed by Enter. A shell pane can interpret that text as a command, so only label and target panes you trust. AgentRelay intentionally exposes no arbitrary key or generic shell-execution tool.

## Workspace mode

A workspace may contain many independent Git repositories and non-Git projects:
Expand Down Expand Up @@ -150,6 +188,11 @@ Task and scope claims remain workspace-wide. In the example above, claim `produc
| `search_memory` | Search events, decisions, and handoffs with SQLite FTS5 |
| `build_context` | Compile task-specific Git, coordination, and memory context |
| `create_handoff` | Generate a Markdown handoff and optionally release leases |
| `terminal_list` | List panes only in the allowed tmux session |
| `terminal_read` | Read redacted, capped pane output and open a one-use send guard |
| `terminal_send` | Send one literal single-line message and Enter after a recent read |
| `terminal_name` | Assign an AgentRelay-specific pane label |
| `terminal_doctor` | Diagnose tmux binary, socket, session, and safety limits |

## Local data

Expand Down Expand Up @@ -180,7 +223,11 @@ Decision conflicts are also advisory. AgentRelay flags related active decisions
- The workspace root is resolved once when the server starts.
- Agent working directories must exist inside that fixed workspace.
- MCP tools cannot escape to another workspace path.
- AgentRelay does not expose arbitrary shell or test-command execution.
- AgentRelay does not expose a generic shell, arbitrary-key, or test-command tool.
- Terminal access is limited to the current or explicitly configured tmux session.
- Terminal sends require a recent read, reject self-targeting, and accept only one literal line.
- Terminal output is redacted and size-limited; captured output and message text are not persisted.
- Sending to a shell pane may still execute text, so terminal access is only for trusted panes.
- Git inspection uses fixed argument arrays without a shell.
- `.env`, private keys, and credential-like paths are filtered.
- Common API keys, tokens, passwords, cookies, and bearer headers are redacted before storage.
Expand All @@ -195,7 +242,7 @@ npm install
npm run check
```

The integration tests create temporary Git repositories and exercise task conflict, scope overlap, memory search, decision conflict, handoff generation, and a real in-memory MCP client/server handshake.
The integration tests create temporary Git repositories and exercise task conflict, scope overlap, memory search, decision conflict, handoff generation, and a real in-memory MCP client/server handshake. When tmux is installed, they also create an isolated socket and verify real pane listing, labeling, read-before-send enforcement, messaging, self-target rejection, and cross-session isolation. CI always installs tmux and runs this path.

## Roadmap

Expand All @@ -209,4 +256,4 @@ The integration tests create temporary Git repositories and exercise task confli

## License

Apache License 2.0. See [LICENSE](LICENSE).
AgentRelay is licensed under Apache License 2.0. See [LICENSE](LICENSE). The built-in terminal transport includes work adapted from MIT-declared `tmux-bridge-mcp`; see [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) and [LICENSES/tmux-bridge-mcp-MIT.txt](LICENSES/tmux-bridge-mcp-MIT.txt).
14 changes: 11 additions & 3 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,31 @@ Include the affected version, operating system, reproduction steps, security imp

AgentRelay assumes coding agents and repository content may produce inaccurate or adversarial text. Stored memory is treated as context, not executable instructions.

The v0.1 boundary is intentionally narrow:
The boundary is intentionally narrow:

- one fixed repository or workspace boundary per server process
- local SQLite and Markdown storage
- no arbitrary shell command tool
- no generic shell, arbitrary-key, or test-command tool
- fixed Git command argument arrays
- workspace-relative scope paths only
- path traversal and absolute-path rejection
- sensitive filename filtering
- best-effort secret redaction before persistence
- one allowed tmux session per server process
- one-use, actor-and-pane-specific read-before-send guards
- single-line terminal messages with byte limits and self-target rejection
- redacted and size-limited terminal reads
- terminal audit metadata that excludes captured output and message text

Secret redaction is defense in depth, not a substitute for avoiding secret input. Users should not intentionally send credentials to AgentRelay.

## Out of scope for v0.1
`terminal_send` types literal text followed by Enter. If the target is a shell pane, that text can execute as a command. Only expose AgentRelay to trusted MCP clients, use a dedicated tmux session, label intended agent panes, inspect the pane with `terminal_read`, and do not target unrelated shells or production consoles.

## Out of scope

- hostile local users with filesystem access to `.agentrelay/`
- full-disk compromise
- malicious changes to the AgentRelay executable or dependencies
- malicious or compromised processes already running inside the allowed tmux session
- perfect detection of every possible credential format
- enforcing scope claims against tools that bypass AgentRelay
23 changes: 23 additions & 0 deletions THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Third-party notices

AgentRelay is licensed under Apache-2.0. The built-in tmux transport also adapts
the public behavior and selected implementation ideas of the following project.

## tmux-bridge-mcp

- Project: `tmux-bridge-mcp`
- Author and current contributor: Howard Peng (`howardpen9`)
- Upstream: https://github.com/howardpen9/tmux-bridge-mcp
- Reviewed revision: `eccf41bc1ab89a12d9c7540fcbf6d00e7161ff5c`
- Upstream package version: `0.3.0`
- Declared license: MIT in the upstream `package.json`

The upstream repository did not contain a root `LICENSE` file at the reviewed
revision. AgentRelay therefore reproduces the standard MIT license text in
[`LICENSES/tmux-bridge-mcp-MIT.txt`](LICENSES/tmux-bridge-mcp-MIT.txt) and keeps
this provenance notice with source and package distributions. Copyright in the
upstream work remains with its author and contributors.

AgentRelay's integration uses its own `terminal_*` interface and adds a single
tmux-session boundary, redaction and output limits, persistent read-before-send
guards, audit metadata, self-message prevention, and no arbitrary key tool.
10 changes: 10 additions & 0 deletions examples/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ AgentRelay normally advertises this lifecycle through MCP server instructions. U
- Record durable architecture choices with `record_decision`.
- Never store secrets, credentials, raw `.env` values, or private keys in AgentRelay.

## Live terminal coordination

1. Call `terminal_list` to inspect panes in the allowed tmux session.
2. Optionally call `terminal_name` once to assign a stable AgentRelay label.
3. Call `terminal_read` on the target before every `terminal_send`.
4. Send only to trusted agent panes. Do not target shells, production consoles, or your own pane.
5. Stop after sending; read again only when a new response is expected. Do not poll continuously.

Terminal output is redacted and capped, but may still contain sensitive context that redaction does not recognize. Never ask another pane to print credentials or raw environment files.

## Before ending or handing off

1. Record the latest test result and unresolved issues.
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@arumwu/agentrelay",
"version": "0.3.1",
"description": "One project. Multiple AI agents. Zero repeated work.",
"version": "0.4.0",
"description": "Local-first coordination, shared project memory, and live tmux transport for coding agents.",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand All @@ -17,14 +17,18 @@
"files": [
"dist",
"README.md",
"LICENSE"
"SECURITY.md",
"LICENSE",
"LICENSES",
"THIRD_PARTY_NOTICES.md"
],
"scripts": {
"build": "tsc -p tsconfig.json",
"dev": "tsx src/cli.ts",
"test": "vitest run",
"test:watch": "vitest",
"check": "npm run build && npm test",
"prepare": "npm run build",
"prepack": "npm run check"
},
"engines": {
Expand All @@ -34,6 +38,8 @@
"mcp",
"coding-agents",
"multi-agent",
"tmux",
"terminal",
"handoff",
"project-memory"
],
Expand Down
Loading