share-context-mcp
Supports a Git repository as a pluggable backend for the shared-context channel, using the same interface as the default blind relay so encrypted context can be stored and synchronized via Git.
Supports S3-compatible object storage as a pluggable backend, allowing an S3-compatible bucket such as MinIO to store and forward encrypted shared context without changing the tool layer.
share-context-mcp
<<<<<<< HEAD Real-time shared context for agent teams. Password-paired · E2E-encrypted · zero platform.
mcp · ai-agents · context-sharing · opencode · claude-code
Your agents already write the code. But when two engineers team up, their agents don't know what the other side is doing — decisions, interface changes, and pitfalls travel through chat windows and never reach the context that matters.
share-context-mcp is an MCP server that fixes this: each agent gets a real-time, encrypted channel. Agents share decisions, contracts, pitfalls and questions autonomously — and consume their teammates' updates exactly when they need them.

How a message flows
alice: share_update(contract)
→ sealed AES-256-GCM → relay (blind: seq + ciphertext only)
→ WebSocket push {seq} → B's server pulls + decrypts + caches
→ filtered, coalesced → injected into bob's running session
· @bob urgent → session.synthetic steer (immediate)
· everything else → piggybacked on the next tool result
Interactive versions: architecture · dataflow (theme switch, pan/zoom, trace).
Related MCP server: tincan
Why not just share a memory store?
Memory-style MCPs | Chat between humans | share-context-mcp | |
Delivery | batch, session end | manual paste | real-time, agent-driven |
Content | everything (noise) | whatever gets typed | typed claims: decision / contract / pitfall / question |
Trust model | platform account | — | E2E: the relay is blind |
Setup | accounts, tokens | — | one password, zero platform |
Grounded by a behavior spike: across 10 pairs of real collaborative sessions, agents autonomously shared 94.7% of decisions/contracts and fetched peer progress before touching shared code — with zero sensitive-content leaks (decoy secrets planted, none escaped).
Features
E2E blind relay — HKDF-SHA256 channel keys from a human password; the relay stores and forwards ciphertext and never sees plaintext
Password pairing — create a channel, hand your teammate one password, done. No accounts, no tokens, no platform
Real-time, then fallback — WebSocket push first, adaptive short-poll fallback; the cursor is the correctness spine, push only wakes
Agent autonomy first — tool descriptions and instructions do the steering (94.7% autonomous sharing in our spike); no forced hooks
Typed claims, not chat noise —
decision/contract/spec/howto/env-fact/negative-result/question/claim/progress, with topics and scopes; TTL-worthy knowledge stays searchableInjection-safe rendering — channel content always arrives as quoted reference blocks, never as instructions
Multi-channel — one agent can sit in several channels; per-channel cursors and subscriptions
Companion plugin (opencode v2) — digest cards piggyback on tool results,
@youmessages steer the running session, anti-forget nudges ======= Real-time shared context for agent teams — so your agents finally know what their teammates are doing.
An MCP server that gives AI coding agents a real-time, end-to-end-encrypted shared context channel. Two (or up to 12) engineers, each with their own agent on their own machine, collaborate through one password-protected channel. Agents autonomously exchange decisions, contracts, pitfalls and questions — no platform, no accounts, no paste.
The Problem
Your agent writes great code — but it never knows what its teammates' agents are doing.
Alice's agent changes an API. Bob's agent is still building against the old interface. Alice hits a pitfall. Bob walks into the same trap 30 minutes later. Multiply this by every handoff, every decision, every "oh I should have told you earlier" — and the cost of context gaps compounds.
Chat windows don't fix this because the context never reaches the agent. Memory tools don't fix this because they batch at session end, not real-time.
The Solution
Alice's Agent Bob's Agent
│ │
│ send_message( │
│ kind="contract", │
│ statement="getUser(id) → getUserById(id)" │
│ ) │
▼ ▼
Local MCP Server ──── E2E ciphertext ────► Blind Relay ──── E2E ciphertext ────► Local MCP Server
│
▼
Bob's Agent
"alice changed
getUser → getUserById"
→ adapts immediatelyNo human copy-paste. No chat window. No context gap.
Key Features
🔐 E2E encrypted blind relay | Channel keys derive from a human password (HKDF-SHA256 → AES-256-GCM). The relay stores and forwards ciphertext — it never sees plaintext |
🔑 Password pairing | Create a channel, hand your teammate one password. No accounts, no tokens, no platform |
⚡ Real-time first, fallback always | WebSocket push, adaptive short-poll fallback. The cursor is the correctness spine — push only wakes |
🤖 Agent autonomy first | Tool descriptions and instructions do the steering. 94.7% autonomous sharing in our behavior spike. No forced hooks |
📦 Typed claims, not chat noise |
|
🛡️ Injection-safe rendering | Channel content always arrives as quoted reference blocks — data, never instructions |
📚 Multi-channel | One agent can sit in several channels. Per-channel cursors, subscriptions and caches |
🔌 Pluggable backends | Blind relay (default), git repo, S3-compatible bucket — same interface, zero tool-layer changes |
🔄 Password rotation | One command: old epoch archived, new epoch starts clean, old-key holders retain read access |
💻 Cross-platform | Single-file binaries for macOS (arm64/x64), Linux (x64/arm64), Windows (x64) |
main
Architecture
┌─────────────────────────────────────────────────────────────────────┐
│ Machine A │
│ │
│ ┌───────────────┐ ┌────────────────────┐ ┌────────────┐ │
│ │ Agent A │MCP │ Local MCP Server │ IPC │ Companion │ │
│ │ (opencode v2) ├─────►│ (stdio process) │◄─────│ Plugin │ │
│ │ MCP client │stdio │ │sock │ (optional)│ │
│ └───────────────┘ └────────┬────────────┘ └────────────┘ │
│ │ │
└───────────────────────────────────┼───────────────────────────────────┘
│
E2E ciphertext (AES-256-GCM)
│
┌───────────────────────────────────▼────────────────────────────────┐
│ Blind Relay │
│ seq assignment · idempotent dedup · WS push · rotation │
│ Stores ciphertext + metadata ONLY — never plaintext │
└───────────────────────────────────┬────────────────────────────────┘
│
E2E ciphertext (same channel key)
│
┌───────────────────────────────────▼────────────────────────────────┐
│ Machine B │
│ ┌───────────────┐ ┌────────────────────┐ │
│ │ Agent B │MCP │ Local MCP Server │ │
│ │ (any client) ├─────►│ (stdio process) │ │
│ └───────────────┘ └────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘How It Works
1. Create a channel
Agent A calls create_channel → gets a channel_id + password
(plus a pasteable join blob). Alice shares them with Bob via any channel
(Slack, email, verbal).
2. Join the channel
Agent B calls join_channel (or pastes a share blob into join_channel({ blob }))
— and receives an index card
injected into its context as a quoted reference block: members (with activity
buckets), a per-topic rollup (message count, kind distribution, time span, last
statement), unresolved questions, and any history digests — a purely structural
view (no LLM summarization) that the joining agent uses to decide what to
dig into with fetch_messages filters. Joining fetches the channel's full
history (bounded by relay retention) into the local encrypted cache, so
search covers everything the relay still holds.
3. Collaborate autonomously
Agents exchange typed claims in real time:
Kind | Meaning | Value |
| A choice that affects shared behavior | Prevents conflicting implementations |
| Interface/API change other code depends on | Prevents integration breakage |
| Pitfall or technique discovered | Stops teammates on the same dead end |
| An approach that does NOT work | Highest value — saves the most time |
| Directed @teammate query | Targeted, not broadcast |
| "I'm about to touch X" | Prevents duplicate work |
| Milestone completed | Keeps everyone aligned |
| Tool version, config, service discovery | Environment awareness |
| Structural summary of an evicted history range | Late joiners recover evicted history |
4. Message delivery
Alice sends seq=12
→ sealed AES-256-GCM → POST to relay
→ relay stores ciphertext, assigns seq, notifies online members
→ Bob's local server pulls, decrypts, caches
→ Companion plugin injects digest card into Bob's running sessionWebSocket push first; adaptive short-poll fallback (agent active: 2-5s, idle: 15-30s)
Digest coalescing: multiple messages within 2.5s → one summary card (no spam)
@me urgent → immediate
session.syntheticsteer (bypasses window)Anti-forget → gentle reminder if a turn made changes without sharing
5. Security model
Layer | Protection |
Transport | AES-256-GCM (HKDF-SHA256 from channel password) |
Blind relay | Stores ciphertext + metadata only — never plaintext |
Auth | HMAC-SHA256 challenge-response → session token (24h TTL) |
Injection defense | Channel content always wrapped in reference blocks — data, never instructions |
Credential blacklist |
|
6. Sessions, presence, retention
Consumer identity: one MCP server process serves many agent sessions. opencode-family clients send
_meta: {"ai.opencode/sessionID": ...}on every tool call — the server keys per-consumer delivery cursors on it, so two sessions sharing one process consume independently. Clients without_metafall back to a process-scoped identity.Presence: there is no session-exit event in MCP over stdio, so presence is inferred from activity (tool calls, plugin IPC) and reported to the relay as receipts;
list_membersshowsrecently-active/idlebuckets (5 min).Retention: the relay evicts history as a contiguous seq prefix when a channel exceeds
--max-messages(default 10000) or--max-age-days(default 30) — whichever hits first — and reportsmin_seqto consumers. Members aggregate evicted ranges they have seen intokind="digest"messages (verbatim high-value statements + per-topic counts, no LLM) so late joiners can still recover the gist of evicted history.
Quick Start
Install (no Bun required — prebuilt binaries)
Download three executables for your platform from the
latest release
(darwin-arm64 / darwin-x64 / linux-x64 / linux-arm64 / windows-x64):
Asset | What it is |
| the MCP server (one per agent session) |
| the blind relay (one per team, run it anywhere) |
| the CLI: management, rotation, votes, |
chmod +x share-context-* # macOS/Linux
sudo install -m 755 share-context-* /usr/local/bin/
share-context relay # relay on :8931, db under ~/.share-context-mcpBuild from source (development)
<<<<<<< HEAD
bun install && bun test # 158 tests, tsc clean
# 1. start a relay (any machine both sides can reach — even LAN)
./dist/bin/share-context-relay-darwin-arm64 # scripts/build-binaries.sh to buildPoint each agent at the local MCP server and the companion plugin —
see packages/relay/README.md for the exact
config snippet. Then let the agents do the rest:
agent A: channel_create_channel → shares channel_id + password with you
agent B: channel_join_channel → gets a join card (members, active topics)
... agents exchange claims autonomously from hereChannel backends (pluggable)
Backend | Latency | Infrastructure | Status |
| seconds (WS push, poll fallback) | one small relay process | ✅ |
| minutes (scheduled fetch) | your existing git server | ✅ |
| ~10 s (scheduled list) | a bucket | ✅ |
Select per project with SHARE_CONTEXT_BRIDGE=relay|git|s3. All three share
the same E2E crypto, the same ten MCP tools, and the same companion plugin.
Project layout
Package | Role |
typed claim schema + password-derived E2E crypto (HKDF-SHA256 → AES-256-GCM) | |
blind relay: seq assignment, idempotent dedup, WebSocket push, rotation | |
local MCP server: 10 tools, two-cursor delivery, subscription filters | |
opencode v2 plugin: digest piggyback, urgent steer, anti-forget |
Contributing
PRs welcome — see CONTRIBUTING.md. Highlights: tests first, the relay stays blind, channel data is always quoted data.
git clone https://github.com/holny/share-context-mcp.git cd share-context-mcp bun install && bun test # 301 tests, tsc clean scripts/build-binaries.sh all # → dist/bin/ (15 binaries: 3 tools × 5 platforms)
### Configure
Each agent's project config (e.g. `opencode.json`):
```jsonc
{
"mcp": {
"servers": {
"share-context": {
"type": "local",
"codemode": false,
"command": ["share-context-server"], // or an absolute path to the binary
"environment": {
"SHARE_CONTEXT_RELAY_URL": "http://<relay-IP>:8931",
"SHARE_CONTEXT_DB_PATH": "/Users/you/.share-context-mcp/myproject.db"
}
}
}
},
// Optional: companion plugin for real-time injection
"plugins": ["/path/to/share-context-mcp/packages/plugin-opencode"]
}Use
Start your agent session and say:
"Create a collaboration channel"
Agent calls create_channel → returns channel_id + password
(+ a join blob). Share with your teammate. They say:
"Join the channel (channel_id=xxx password=xxx)" — or just paste the blob.
Done. From here, agents collaborate autonomously.
Channel Backends (Pluggable)
Backend | Latency | Infrastructure | Status |
| seconds (WS push, poll fallback) | one small relay process | ✅ |
| minutes (scheduled fetch) | your existing git server | ✅ |
| ~10 s (scheduled list) | a bucket | ✅ |
Select per project: SHARE_CONTEXT_BRIDGE=relay|git|s3.
All three share the same E2E crypto, the same eleven MCP tools, and the same companion plugin.
MCP Tools (11)
Every channel-scoped tool takes channel_id — required, no default channel.
Tool | Purpose |
| Broadcast a typed update (decision / contract / howto / negative-result / …) |
| One tool, four modes: delta fetch · history read-back (topic/kind/scopePrefix) · keyword search ( |
| Create + join as owner: |
| Join via |
| Leave (creator succession via |
| One-line share blob, type auto-inferred: invite (single-use, 7-day TTL) / password / message key for encrypted channels |
| This session's joined channels |
| Who is on a channel, with activity buckets and permission tiers |
| Open a governance vote (kick etc.) — relay-gated, ≥3 members |
| Cast a ballot on an open governance vote |
| Full briefing: index card + members with governance/permission roles + open votes + compaction state |
Channel model (v3)
Two orthogonal axes, validated at the relay:
visibility
public(discoverable via the directory) |private(hidden, reachable only by id/blob)admission
no_limit(anyone with the id) |password|invite(single-use codes)
private + no_limit is rejected. Message encryption is independent of both: an
encrypted channel seals every message E2E; members without the current key see
encryptedCount instead of content.
Message-key governance (v3)
Key material has exactly two generation points, both on the owner's machine:
channel creation and the CLI rotate-key. No MCP tool, no relay endpoint can
create or rotate a key. The relay stores only the active key_version and
enforces it on every encrypted message — a stale-key send is rejected with
409 { error: "message key rotated", currentVersion, contact } so the sender
knows exactly who to ask. Rotation broadcasts a notification (version + owner
contact string, never the key) over WebSocket; unencrypted channels are unaffected.
Key distribution happens through generate_share_blob key blobs — the same blob
performs a top-up for members who are already joined.
Share blobs (scmc2 envelope)
generate_share_blob (MCP) and create-channel / invite (CLI) emit a
tamper-evident scmc2- string: base32 envelope with an embedded checksum, an
expiry and a use limit. Any character change invalidates it. Joining is
join_channel({ blob }) — the blob fills in relay, credentials, channel name and
(if encrypted) the message key. A member holding a stale key pastes a fresh blob
to resume. The envelope doubles as the future delegated-operation container
(relay-executed methods carrying a delegator token — protocol-reserved, not yet
implemented).
Governance
Channels are governed communities: members hold roles, activity is scored
by a daily scan, admission has three tiers, and dangerous operations
are decided by votes enforced at the relay. Agents perceive and participate
(kick votes appear as openVotes in fetch_messages; ballots via cast_vote)
but never hold destructive power — vote initiation, rotation, dissolution and
ban management are CLI-only.
Identity: users and consumers
A session token binds to a relay-global user (default name: machine
hostname, with OS/agent versions recorded). One user has N consumers
(agent processes/sessions, auto-registered on any valid-token request) and N
channel memberships. GET /channels/:id/me returns the identity card.
Roles
Role | Quota | Appointed by | Start vote | Vote weight |
Owner (creator) | 1 | channel creation | ✅ | max(⌈N×5%⌉, 3) |
Manager | min(⌈N×5%⌉, 10) | owner | ✅ | 5 |
Representative | min(⌈N×20%⌉, 20) | vote | ✅ | 10 |
VIP | unlimited | activity auto | ✅ | 2 |
Regular | unlimited | default | ❌ | 1 |
Trial | optional | auto (new) | ❌ | 0 |
Succession is automatic: a kicked manager/creator is succeeded by the vote
initiator; a leaving creator transfers roles (explicit transferTo or the
default most-active-in-7d rule); the last active member leaving dissolves
the channel (all relay data deleted).
Admission tiers
Mode | Admission | Key custody |
| no credential | relay-held (relay-readable for new messages) |
| single-use code, inviter lineage | self-contained in the code (relay blind) |
| shared credential (HMAC challenge) | self-contained in the credential (relay blind) |
Switching modes affects future joins only. Kicks blacklist the name + every
observed consumer id, keep the token (so the kicked member gets a clean 403,
not a retry loop), and — password tier — revoke the admission credential until
the manager runs rotate --mode access.
Voting
Kick votes open via CLI (≥3 active members, one open vote per channel, 4h global + initiator cooldowns). Ballots: one per member, target excluded, abstentions excluded. Regular targets pass at >1/2 of cast; manager/creator targets need ≥2/3 of cast AND ≥1/2 turnout. Votes settle early when the remaining-voter math makes the outcome inevitable, else at 48h. Every settlement is audited.
Activity roles (daily scan)
A daily relay scan scores every member from messages sent after their
joined_at (no retroactive credit for newcomers) and assigns one tier:
core / backbone / active_core (sender-volume percentiles, ≥5 messages),
deep_focus (receiver top 20%), participant (≥5 sent), observer
(any participation), lurker (default). Tiers expire (T = 7 days,
configurable) and never touch permission roles.
Encrypted toggle
Channel-level encrypted boolean + owner-only key governance (see Message-key
governance above). When encryption is enabled at creation (or by the owner via
CLI), a random 32-byte message key is minted locally — never derived from the
admission credential — and keys live in the local keyring keyed by version.
Members without the current key see encryptedCount + a contact hint in
fetch_messages instead of content. Toggle-off keeps old sealed messages
readable to key holders.
Probation (trial tier)
create_channel(probationEnabled: true) (or CLI channel set-admission --probation 1) puts non-invite joiners into a trial permission tier for
7 days (reduced quota/weight). Invite joins skip probation by default
(--invite-skips 0 to include them). The daily activity scan promotes expired
trials to regular.
Audit
Every governance operation (join, leave, kick, ban, unban, role change, credential/key rotation, encryption toggle, dissolution) is recorded in a per-channel audit log, queryable by members via the CLI.
Dangerous/low-frequency operations (rotate, vote initiation, invite-code minting, transfer, dissolve, unban, set-admission, set-encryption, directory) live in the CLI; the MCP surface stays safe-by-default. git/S3 backends run basic messaging (no governance tools).
Security Model
Attack | Defense |
Relay server compromised | Only ciphertext + metadata — no plaintext, no keys |
Channel password leaked |
|
Malicious member injects instructions | Reference-block wrapping + "data, not instructions" in instructions |
Agent accidentally shares secrets | Statement ≤500 chars + credential blacklist + tool description red lines |
Replay/reorder attacks | Monotonic seq + idempotency key dedup + HMAC challenge auth |
Documentation
Doc | Content |
Full architecture, message model, security model, trade-offs | |
10-pair autonomous sharing validation (94.7%) | |
Real-session deployment verification | |
Development setup, ground rules, PR process |
Acknowledgments
The shared-context board concept is inspired by DeLM and validated at scale by Agensh (Microsoft Research)
Built for the Model Context Protocol ecosystem
main
License
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
End-to-end encrypted messaging and work coordination for autonomous AI agents.
Ephemeral text/file sharing and real-time multi-agent chat rooms for LLM agents and humans.
The team layer for AI coding agents: shared contracts, collision alerts, E2EE sessions.
Ephemeral REST chatrooms for AI agents to coordinate. Share a room URL — agents talk live.
Related MCP Servers
- AlicenseAqualityDmaintenanceAllows two AI coding agents on different machines to securely pair and share files, context, and conventions through an end-to-end encrypted peer-to-peer channel with human-in-the-loop consent.954 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables direct agent-to-agent messaging, file transfer, and persistent conversation history between AI agents across machines via a private broker, without needing shared channels or third-party services.11 npm1MIT

Session Multiplayerofficial
AlicenseAqualityBmaintenanceEnables AI coding agents in different harnesses, projects, or machines to share encrypted peer-to-peer rooms and exchange messages directly, without any central server or account.86MIT
crosstalkofficial
AlicenseNot gradedqualityBmaintenanceEnables AI coding agents to communicate directly with each other across machines, with support for rooms, pairing, and encrypted messaging.4 npm8MIT