Atlas / MCP servers / brutalsystems / Tin Can

Tin CanSAFE

mcp/brutalsystems/tincan

Peer messaging between live Claude Code, Codex and opencode sessions on one machine. One binary, run as an MCP server inside each.

Verdict
SAFE
Grade
B
Trust score
89 /100
Exposed tools
3 1r · 2w · 0d
Transport
stdio
License
MIT
Stars
1
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

[](https://www.npmjs.com/package/@brutalsystems/tincan) [](./LICENSE)

Two cans and a string. Let the coding agents already running on your machine send each other messages, instead of you carrying them.

Tin Can lets live Claude Code, Codex and opencode sessions on one machine message each other. You are probably already running more than one: one knows the API, another is deep in the migration that calls it, and you are the one relaying questions between terminals. Tin Can lets them ask each other directly, so you stop being the message bus.

The same tincan binary runs as a stdio MCP server inside each session — that is the whole install for Claude Code and Codex. opencode needs one extra step: a small plugin that lets it receive what the binary sends. Nothing here spawns a session, owns a conversation, or blocks.

Same machine only. No network listener, no remote transport.

It is the messaging third of a small family: muster starts agents, Tin Can lets them message each other, birddog watches what they do.

What it's for

Asking the session that already knows. A question that would cost you a context switch — does `verifyToken` tolerate clock skew? — goes to the session holding that code, and the answer comes back into yours. Neither agent stops, and neither one needed you to carry it.

It also works from outside a session entirely. A shell script, a cron job or a Go binary can reach a running agent with tincan send, which is how an alerting tool tells an orchestrator that something needs attention.

What make

Read from source at commit 341beea4b263OBSERVED · 2026-10-11
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control.

claude-code
claude mcp add tincan-opencode -- npx -y @brutalsystems/[email protected]
claude-desktop
{
  "mcpServers": {
    "tincan-opencode": {
      "command": "npx",
      "args": [
        "-y",
        "@brutalsystems/[email protected]"
      ]
    }
  }
}
03

Exposed tools (3)

1 read · 2 write · 0 destructive.

ToolRiskDescription
peersreadList the live ${peer} sessions on this machine that you can message.
reregisterwriteRe-publish this session
send_peerwriteSend a text message to one live ${peer} session on this machine, or to several
04

Trust audit

SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codePASS
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
none-observed
Network
none-observed
Shell
none-observed
Dependencies
not all pinned
Secrets in source
none-found

Findings (9)

LOWFilesystem / path · fs.system_paths · CWE-22, CWE-59
test/opencode-host.test.ts:31
400: { ppid: 500, command: '/usr/local/bin/npm' },
LOWFilesystem / path · fs.system_paths · CWE-22, CWE-59
test/opencode-host.test.ts:38
for (const harness of ['claude', '/usr/local/bin/codex']) {
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
plugins/opencode/test/names.test.ts:41
it.each(['../evil', 'ses_../../x', 'msg_abc', '', 'ses_a/b'])(
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
plugins/opencode/test/plugin.test.ts:318
callID: '../../escaped',
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
plugins/opencode/test/types.test.ts:13
const pkg = JSON.parse(readFileSync(new URL('../../../package.json', import.meta.url), 'utf8'));
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
test/claude-registry.test.ts:68
writePointer(dir, rec({ sessionId: '../../escaped' }));
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
test/cli-idempotency.test.ts:83
const nasty = '../../etc/passwd:7:disk';
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
package.json
@modelcontextprotocol/sdk, zod, @types/node, typescript, vitest
Why it matters. 5 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
plugins/opencode/README.md:107
| **Messages accepted but nothing happens; `event=transport-broken detail=html response`** | The `/api/` prefix was lost in the request path. The opencode server falls back to its web UI and returns 2
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine

Gates applied: no_behavioural_pass.

Audited 2026-10-11 · audit v0.4.1 · source sha 341beea4b263full audit observations/trust-audit/mcp-server/brutalsystems__tincan.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-11341beea4b263SAFEB89first audit
06

Questions

What is the @brutalsystems/tincan MCP server?

Peer messaging between live Claude Code, Codex and opencode sessions on one machine. One binary, run as an MCP server inside each.

What tools does @brutalsystems/tincan expose?

3 in total: 1 read-only, 2 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.

Is @brutalsystems/tincan safe to connect to an agent?

The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean server reads B.

What credentials does @brutalsystems/tincan need?

No credential environment variables were found in its source, so it appears to need none.

How does @brutalsystems/tincan run?

It speaks stdio, so it runs as a local process your client starts. It is published on npm as @brutalsystems/tincan-opencode at 2.4.1.

How current is this page?

The grade is for one exact copy of the source (341beea4b263), read on 2026-10-11. The repository is watched and re-audited when it changes.

Advertisement