Install
$ agentstack add mcp-bantarus-context-bridge-mcp ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ● Shell / process execution Used
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Context Bridge MCP
[](https://github.com/Bantarus/context-bridge-mcp/actions/workflows/ci.yml) [](https://github.com/Bantarus/context-bridge-mcp/releases/latest) [](LICENSE) [](https://nodejs.org/)
A lightweight, project-agnostic MCP server that gives Claude Code agents shared context across multiple repos on the same machine. Each repo owns its own .context/ folder — the server is a stateless I/O tool with zero project knowledge.
Install
Three install paths depending on your use case:
A. .mcpb bundle (one-click install in Claude Desktop and other MCPB-aware hosts)
Download the latest .mcpb from the GitHub Releases page, or build one from source:
npm install
npm run release:mcpb
# Produces: context-bridge-mcp.mcpb
Then drag the .mcpb file into Claude Desktop (or any host that implements the MCPB spec). The host will prompt for the Ecosystem Root (defaults to ~/.context-bridge) and wire everything up. No manual config.
B. Claude Code CLI (manual stdio registration)
npm install
npm run build
Register once at user scope so it works in every repo automatically:
claude mcp add --scope user --transport stdio context-bridge \
-- node /absolute/path/to/context-bridge-mcp/dist/index.js
Optional: override the contracts directory for a shared location:
claude mcp add --scope user --transport stdio context-bridge \
-- node /absolute/path/to/context-bridge-mcp/dist/index.js \
--env CONTRACTS_ROOT=/absolute/path/to/shared-contracts
Or use claude.json.example as a template for per-repo configuration.
C. Embed in a host application (Electron operator gateway, IDE plugin, etc.)
Context Bridge is not published to npm — install it directly from this GitHub repo:
npm install github:Bantarus/context-bridge-mcp
# Or pin to a specific release tag:
npm install github:Bantarus/context-bridge-mcp#v1.0.0
npm runs the prepare script after install, which builds dist/ for you.
See [Embedding in a host application](#embedding-in-a-host-application) below for the spawn pattern.
How it works
The server reads and writes .context/ folders relative to the working directory of the process that invokes it (typically the repo root where Claude Code is running).
Each repo is self-describing via a manifest.json in its .context/ folder. The server trusts that manifest — it does not enforce any schema or naming.
Cross-repo access is explicit via bridge_get_from, which takes a path to another repo and reads its .context/ folder.
Environment variables
| Variable | Default | Description | |----------|---------|-------------| | CONTEXT_ROOT | $CWD/.context | Path to the context directory | | CONTRACTS_ROOT | $CONTEXT_ROOT/contracts | Path to contracts (can be shared across repos) | | ECOSYSTEM_ROOT | ~/.context-bridge | Path to the shared ecosystem registry |
Tools
| Tool | Description | |------|-------------| | bridge_manifest | Full registry — call first every session | | bridge_get | Fetch one context file by domain/component | | bridge_update | Write a context file after implementing | | bridge_list | Discover existing files, optionally filtered by domain | | bridge_get_from | Fetch a context file from another repo by path | | bridge_register | Register a repo in the shared ecosystem | | bridge_discover | List or inspect repos in the ecosystem | | bridge_get_contract | Fetch a contract — searches local then ecosystem | | bridge_update_contract | Write a contract file | | bridge_list_contracts | List all contracts | | bridge_changes | Show changes from other repos since last check | | bridge_sync_skills | Install/update companion skills into current repo | | bridge_manifest_update | Deep-merge a patch into manifest.json |
.context/ directory layout
Each repo that uses the bridge creates this structure:
your-repo/
.context/
manifest.json /.context/CONTEXT.md` and fill it in
2. Create your first context file and manifest:
```bash
mkdir -p .context/api
echo '{"version":"1.0","domains":{"api":["routes"]}}' > .context/manifest.json
- Install the companion skills into the repo:
bridge_sync_skills()
This copies context-reader, context-feeder, and context-bridge skills into .claude/skills/ so Claude Code knows how to use the bridge automatically.
- Start using the bridge tools in Claude Code — call
bridge_manifest()first
Usage guide
The problem this solves
When Claude Code works in one repo, it has no idea what exists in related repos. If your frontend calls an API, Claude Code in the frontend repo doesn't know the endpoint signatures, event shapes, or data models from the backend. Loading the entire backend codebase into context is wasteful and noisy.
The bridge solves this by giving each repo a small .context/ folder that describes its architecture in plain markdown. Claude Code reads only the context files relevant to the current task — not the full codebase of every repo.
Core workflow
1. Set up each repo once
Create a .context/ folder with a manifest and context files that describe your repo's architecture. You don't need to document everything — start with the parts that other repos interact with.
my-api/
.context/
manifest.json
routes/
users.md ← describes the /users endpoints
billing.md ← describes the /billing endpoints
schemas/
user.md ← describes the User data model
contracts/
users.md ← the agreed API contract other repos depend on
my-frontend/
.context/
manifest.json
pages/
dashboard.md ← describes what data the dashboard needs
settings.md
contracts/
users.md ← same contract, from the consumer's perspective
The manifest is a simple registry:
{
"version": "1.0",
"domains": {
"routes": ["users", "billing"],
"schemas": ["user"],
}
}
2. Register each repo in the ecosystem
Each repo declares its existence once so other repos can discover it automatically:
bridge_register({
name: "my-api",
path: "/absolute/path/to/my-api",
exposes: ["routes", "schemas", "contracts"],
stack: "Node.js / Express"
})
bridge_register({
name: "my-frontend",
path: "/absolute/path/to/my-frontend",
exposes: ["contracts"],
stack: "React / TypeScript"
})
This writes to a shared ecosystem.json at ~/.context-bridge/. All repos on the machine can see each other without hardcoded paths.
3. Claude Code reads context at the start of a session
When you start working, Claude Code orients itself, checks for changes, then fetches only the context relevant to the task:
bridge_manifest() ← what domains does this repo have?
bridge_discover() ← what other repos exist in the ecosystem?
bridge_changes() ← what changed in other repos since last session?
bridge_get("routes", "users") ← fetch the context I need
bridge_get_contract("users") ← resolved automatically from ecosystem
bridge_changes is filtered by watches in your manifest. If you declare watches, you only see changes from the repos and domains you care about:
{
"watches": {
"my-api": ["contracts", "schemas"],
"shared-lib": ["events"]
}
}
Each watch token matches in two ways:
- Category keyword —
"contracts"matches all contract changes,
"context" matches all context changes, "manifests" matches manifest changes. Both singular ("contract") and plural ("contracts") forms work, case-insensitive.
- Specific domain name —
"schemas"matches changes whose domain is
schemas (typically context files under .context/schemas/); "users" matches the users contract or any domain literally named users.
The example above subscribes to all of my-api's contracts plus changes in its schemas domain, and to anything in shared-lib's events domain.
If no watches are declared, bridge_changes shows all contract changes from other repos as a safe default.
bridge_get_contract is ecosystem-aware: it searches the current repo first, then all ecosystem repos that expose contracts. No need to know which repo owns a contract.
4. Claude Code reads from other repos when needed
For internal context (not contracts), Claude Code can read another repo directly via path or by discovering it first:
bridge_discover("my-api") ← get path and details
bridge_get_from("/path/to/my-api", "routes", "users") ← read internal context
This is read-only — Claude Code never writes to another repo's context.
5. Claude Code writes back after implementing
After making changes, Claude Code updates the context files so they stay in sync with the actual code. This is the most important step — stale context is worse than no context.
bridge_update("routes", "users", "# Users Routes\n\n## Purpose\n...")
bridge_manifest_update({ "patch": { "domains": { "routes": ["users", "billing", "auth"] } } })
Contracts vs context files
- Context files (
.context//.md) describe internal
architecture. They help Claude Code understand your repo. Other repos can read them via bridge_get_from, but they're not designed as a stable interface.
- Contracts (
.context/contracts/.md) define the agreed boundary
between repos — endpoints, event shapes, shared types. They are the only thing another repo should rely on. When a contract changes, both sides need to update.
When to use bridge_get_from vs contracts
| Situation | Use | |-----------|-----| | Need to know another repo's API shape | bridge_get_contract (read the contract) | | Debugging a mismatch between repos | bridge_get_from (peek at their internals) | | Implementing against a stable interface | bridge_get_contract | | Understanding how another repo works internally | bridge_get_from |
Contract version tracking
Every contract must have a ## Version section:
# Contract: users
## Version
2.1
## Changelog
- 2026-04-21: Added rate limit header
- 2026-04-15: Initial contract
When a repo reads a contract via bridge_get_contract, the bridge automatically pins the consumed version in the ecosystem. On the next session start, bridge_changes compares the pinned version against the current version and warns about drift:
Version drift detected (1):
⚠ contract "users": you consumed v2.0 from my-api on 2026-04-15, current is v2.1
This means the agent knows exactly what changed and can re-fetch the contract to understand the delta before writing any code against a stale interface.
Tips
- Start small. You don't need to document every file. Begin with the
components that cross repo boundaries, then expand as needed.
- Contracts are the source of truth. If a contract and a context file
disagree, the contract wins.
- Keep context files short. A few paragraphs per component is ideal.
If a file is getting long, split it into multiple components.
- Automate the write-back. Use the
context-feederskill to automatically
update context files after implementing. Context drift is the main failure mode of the bridge pattern.
WSL + Windows cross-environment usage
The bridge works between repos in the same environment (WSL-to-WSL or Windows-to-Windows) with no extra setup. Cross-environment usage (WSL repo talking to a Windows repo or vice versa) requires using cross-filesystem mount paths when registering.
If the MCP server runs in WSL, register Windows projects via /mnt/c/:
bridge_register({
name: "my-windows-project",
path: "/mnt/c/Users/you/projects/my-app",
exposes: ["contracts", "api"],
stack: "..."
})
If the MCP server runs on Windows, register WSL projects via the UNC path:
bridge_register({
name: "my-wsl-project",
path: "\\\\wsl$\\Ubuntu\\home\\you\\DEV\\my-app",
exposes: ["contracts"],
stack: "..."
})
Caveats:
/mnt/c/access from WSL has a performance overhead (filesystem bridge)- File watching does not work across the boundary
- Two separate Claude Code instances (one in WSL, one in Windows) need two
MCP server processes, but can share the same ecosystem.json by setting ECOSYSTEM_ROOT to a path both environments can access
Recommendation: keep all repos in the same environment (ideally WSL). Use cross-mount paths only when you have no choice.
Embedding in a host application
Context Bridge MCP can be embedded as a child process inside any host that speaks MCP — Electron operator gateways, IDE plugins, custom orchestrators. This is the same pattern Claude Code, Cursor, Continue, and Zed use for native MCPs.
Install
Either depend on it via npm:
npm install context-bridge-mcp
Or bundle the compiled dist/ folder directly with your app's resources.
Spawn pattern (with @modelcontextprotocol/sdk)
The cleanest path is to let the MCP SDK manage the child process via StdioClientTransport:
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { app } from "electron";
import { resolve } from "node:path";
// Resolve to the bundled or installed binary
const binary = resolve(
app.getAppPath(),
"node_modules/context-bridge-mcp/dist/index.js"
);
const transport = new StdioClientTransport({
command: process.execPath, // Electron's bundled Node
args: [binary],
env: {
...process.env,
// Persistent state under the host's user data dir
ECOSYSTEM_ROOT: resolve(app.getPath("userData"), "context-bridge"),
// Override per active workspace if needed
CONTEXT_ROOT: resolve(activeRepoPath, ".context"),
},
cwd: activeRepoPath, // .context/ is read from cwd by default
});
const client = new Client({ name: "operator-gateway", version: "1.0.0" }, {});
await client.connect(transport);
// Now call tools
const manifest = await client.callTool({ name: "bridge_manifest", arguments: {} });
Manual spawn (full lifecycle control)
If you need to manage the process yourself (custom restart logic, crash supervision, log capture):
import { spawn } from "node:child_process";
const proc = spawn(process.execPath, [binary], {
stdio: ["pipe", "pipe", "pipe"],
cwd: activeRepoPath,
env: {
...process.env,
ECOSYSTEM_ROOT: resolve(app.getPath("userData"), "context-bridge"),
},
});
proc.stderr.on("data", (chunk) => {
// Server logs (boot info, warnings) go to stderr
console.log("[context-bridge]", chunk.toString());
});
// Wire proc.stdin / proc.stdout to your MCP client transport
// Handle proc.on("exit", ...) for restart logic
// Call proc.kill() in app.on("before-quit", ...)
Environment variables an embedding host should set
| Var | Purpose | Recommended value | |-----|---------|-------------------| | ECOSYSTEM_ROOT | Where ecosystem.json and changelog.jsonl live | app.getPath("userData") + "/context-bridge" (or shared across all your app instances) | | CONTEXT_ROOT | Override the .context/ location | Usually unset — process.cwd() + "/.context" is correct when you set cwd | | CONTRACTS_ROOT | Override contracts location | Set if you want a shared contracts folder across multiple repos |
Switching active workspaces
The bridge resolves .context/ from process.cwd(). To switch active workspaces in your host app, you have two options:
- Restart the child process with a new
cwd— clean state, simple,
takes ~50ms. Recommended for most operator gateways.
- Set
CONTEXT_ROOTper-call via env — not currently supported, w
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Bantarus
- Source: Bantarus/context-bridge-mcp
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.