# Codebase Bridge Mcp

> Read-only MCP server that lets a Claude chat (desktop or web) explore your local repo and answer questions about it, with file:line references — no file-pasting, no write access to your machine.

- **Type:** MCP server
- **Install:** `agentstack add mcp-edmmy-codebase-bridge-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [EDMMY](https://agentstack.voostack.com/s/edmmy)
- **Installs:** 0
- **Category:** [Integrations](https://agentstack.voostack.com/c/integrations)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [EDMMY](https://github.com/EDMMY)
- **Source:** https://github.com/EDMMY/codebase-bridge-mcp

## Install

```sh
agentstack add mcp-edmmy-codebase-bridge-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# codebase-bridge-mcp

A read-only [MCP](https://modelcontextprotocol.io) server that lets a Claude chat — in
the desktop or web app — explore your local repository and answer questions about it,
returning synthesized answers with `file:line` references. **No copy-pasting files, no
giving the chat write access to your machine.**

`ask_codebase` runs headless Claude Code (`claude -p`) inside your repo with an
**exclusive** read-only tool set (`Read Grep Glob` — no Edit, Write, Bash, agents, or
MCP) and a hook that **confines reads to the target repo**, so a disposable agent
explores the code and returns a synthesized, `file:line` answer. See
[Security](#security) for exactly what is and isn't enforced.

```
Claude client  --MCP-->  codebase-bridge  -->  claude -p (Read/Grep/Glob only)
                                                └─ explores /path/to/your/repo
```

## Why I built this

I do my best thinking about a problem in a conversational Claude chat, not in a coding
agent — the back-and-forth on an idea tends to go deeper there. But every time I wanted
to ask about a specific part of my code, I had to go hunting for the right file, find
the relevant section, and paste it in by hand — every single question. It broke the
flow exactly when I wanted to think freely.

I went looking for something to close the gap and found the existing codebase tools all
point the wrong way: filesystem and repo-packing servers (like Repomix) feed a coding
agent that already has your repo, and structural-index servers (like
codebase-memory-mcp) need a coding agent to be the brain. Nothing brought a finished,
read-only answer about my code into the chat where I was actually thinking. So I built
it: it shells out to a headless, read-only Claude scoped to a single repo (Read/Grep/Glob
only — no Write, no Bash), and hands the synthesized answer back to my chat. I can
interrogate my codebase mid-conversation without ever leaving the thinking.

## Requirements

- [Claude Code](https://claude.com/claude-code) (`claude`) installed and authenticated.
- [`uv`](https://docs.astral.sh/uv/) (runs the server with zero install — deps are
  declared inline in `server.py`).
- For the optional `http` transport: [`cloudflared`](https://github.com/cloudflare/cloudflared)
  or any HTTPS tunnel.

## Tools

| Tool | What it does |
| ---- | ------------ |
| `ask_codebase(question, thread="", model="", effort="", show_steps=False)` | Explore the repo read-only and answer. |
| `bridge_cost()` | Return the per-thread + grand-total cost ledger for this server process. |
| `bridge_forget(thread="")` | Drop a thread's session (or all threads) so the next call starts fresh. |

`ask_codebase` parameters:

- **`thread`** — a friendly name (e.g. `"auth-investigation"`). Reuse the **same name**
  to keep one Claude Code session alive — **turn-based steering**: each follow-up keeps
  prior context, so you redirect it and it stays cheap (prompt-cache hits, measured
  45% → 95% → 99% cache-read across turns). Omit for a one-off fresh session.
- **`model`** — e.g. `"sonnet"` / `"opus"`. **Binds** to a thread on its first call; a
  *different* model on an existing thread is **refused with a note**, because switching
  models forces a full-context reprocess. Start a new thread for a different model.
- **`effort`** — reasoning effort: `low`, `medium`, `high`, `xhigh`, `max`. Per-call
  (safe to vary within a thread — unlike `model` it doesn't invalidate the cache).
  Lower = cheaper/faster; raise it for hard cross-file reasoning. Unknown values are
  ignored with a note.
- **`show_steps`** — append the exploration trail so you see *how* it reached the
  answer and can steer the next turn.

Example answer:

```
Auth is enforced in app/middleware.py:42 (verify_token), called from the
@requires_auth decorator in app/security.py:18.

[bridge] explored via 2 step(s):
  1. grep 'verify_token'
  2. read app/middleware.py
--
[bridge] model=opus-4-8 | call=$0.0383 | cache 58k read / 19 fresh (100% cached)
[bridge] thread 'auth' total=$0.81 over 3 call(s) -- reuse this thread for cheap follow-ups
```

## Install / run

### stdio (recommended — Claude Desktop & Claude Code)

stdio is launched as a local subprocess by the client: no URL, no tunnel, no token.

**Claude Code:**

```sh
claude mcp add codebase-bridge -- uv run --script /ABS/PATH/server.py --repo /ABS/PATH/your-repo
```

**Claude Desktop:** edit `~/Library/Application Support/Claude/claude_desktop_config.json`
(macOS) — see [`examples/claude_desktop_config.json`](examples/claude_desktop_config.json):

```json
{
  "mcpServers": {
    "codebase-bridge": {
      "command": "/opt/homebrew/bin/uv",
      "args": ["run", "--script", "/ABS/PATH/server.py", "--repo", "/ABS/PATH/your-repo"]
    }
  }
}
```

Use the **absolute path to `uv`** (`which uv`) — Claude Desktop doesn't inherit your
shell `PATH`. Restart Desktop after editing. Then ask:
*"Use ask_codebase on thread 'auth', show_steps: how does login work?"*

### http (only for claude.ai web)

claude.ai reaches servers from Anthropic's cloud, so it needs a public URL + token:

```sh
export BRIDGE_TOKEN=$(openssl rand -hex 16); echo "token: $BRIDGE_TOKEN"
uv run --script server.py --transport http --repo /ABS/PATH/your-repo   # 127.0.0.1:8765
cloudflared tunnel --url http://localhost:8765                  # new terminal
```

http transport **refuses to start without `BRIDGE_TOKEN`** (pass `--insecure-no-auth`
to deliberately run an open server, e.g. when you front it with your own auth). It
binds **`127.0.0.1`** by default — the tunnel connects to localhost; set `--host
0.0.0.0` only if you really need other interfaces. The token check is constant-time.

Add `https://.trycloudflare.com/mcp` (no trailing slash) as a custom connector
in claude.ai with the bearer token.

## Configuration

All knobs have CLI flags and/or env vars:

| Env | CLI | Default | Meaning |
| --- | --- | ------- | ------- |
| `BRIDGE_REPO` | `--repo` | current dir | repo Claude Code explores |
| `BRIDGE_TRANSPORT` | `--transport` | `stdio` | `stdio` or `http` |
| `BRIDGE_TOKEN` | — | unset | http bearer token (http refuses to start unless set or `--insecure-no-auth`) |
| `BRIDGE_HOST` | `--host` | `127.0.0.1` | http bind address |
| `BRIDGE_PORT` | — | `8765` | http listen port |
| `BRIDGE_TIMEOUT` | — | `240` | per-call wall-clock cap (seconds) |
| `BRIDGE_MODEL` | — | Claude Code default | default model for new threads / ephemeral calls |
| `BRIDGE_MAX_CONCURRENT` | — | `4` | cap on concurrent `claude` subprocesses (DoS/cost guard) |
| `BRIDGE_THREAD_TTL` | — | `1800` | idle seconds before a thread session is dropped (`0` = never) |
| `BRIDGE_MAX_THREADS` | — | `256` | live-thread cap before LRU eviction |
| `BRIDGE_CONFINE_READS` | — | `1` | PreToolUse hook confines reads to `--repo` (`0` = read anywhere) |
| — | `--insecure-no-auth` | off | allow http without a token (explicit opt-in; refused on non-loopback host) |

## Security

This project has **not been independently security-audited.** It is hardened, and the
guarantees below are enforced and were verified empirically — but read this before
exposing it to untrusted input.

**What is enforced (default), at Claude's tool-dispatch layer:**

- **Exclusive read-only tool set.** The agent is launched with `--tools "Read Grep
  Glob"` — the *exclusive* built-in tool flag (unlike `--allowedTools`, which is merely
  additive and lets unlisted tools still run). The agent literally has **no Bash, Edit,
  Write, agent/subagent, or MCP tool** — verified: it reports only `Read/Grep/Glob`.
- **Reads confined to `--repo`.** A `PreToolUse` hook (this script, registered via
  `--settings`) runs host-side before every tool call and **denies any read whose path
  resolves outside the target repo** (absolute paths, `../`, `/proc/self/environ`, etc.)
  — verified: reading `/etc/hosts` is rejected with "outside the target repo". This is
  the one thing no `claude` flag does (Read accepts absolute paths by design). Disable
  with `BRIDGE_CONFINE_READS=0` for trusted local cross-repo use.
- **No shell injection / no flag injection.** Argv list (no shell); the question is
  passed after a `--` end-of-options separator so it can't be reparsed as a flag.
- **The server's own secrets aren't inherited.** `BRIDGE_*` env vars (incl.
  `BRIDGE_TOKEN`) are stripped from the child env, and `/proc/self/environ` is outside
  the repo so the read hook blocks it too.
- **http transport.** Refuses to start without `BRIDGE_TOKEN` (override with
  `--insecure-no-auth`, itself refused on a non-loopback host), binds `127.0.0.1`,
  constant-time token compare, concurrent subprocesses capped (`BRIDGE_MAX_CONCURRENT`).

**The honest caveats:**

- **This is policy enforcement, not a kernel sandbox.** The tool restriction and read
  hook are evaluated by Claude Code host-side and are deterministic (the model can't
  reason around them), but they are not an OS-level boundary. For a **fully untrusted**
  client (e.g. exposed over a public tunnel), additionally wrap the process in an OS
  sandbox (`sandbox-exec` on macOS, `bubblewrap` on Linux, or a container) so even a
  hypothetical `claude`/Node compromise can't escape. (`code.claude.com/docs/sandboxing`.)
- **Files *inside* the repo are readable** — including any secrets committed there
  (`.env`, keys). Point it at repos you trust to expose.
- **Prompt injection.** Untrusted content inside repo files could try to misdirect the
  agent; the read-confinement hook limits the blast radius to the repo itself.

## Known limitations

- **State is in-memory and per-process.** Thread sessions and the cost ledger reset on
  restart; there is no cross-restart persistence (by design for now). Idle threads are
  dropped after `BRIDGE_THREAD_TTL` and evicted by LRU past `BRIDGE_MAX_THREADS`.
- **No mid-flight cancellation.** Cancelling the MCP request does not kill the running
  `claude` subprocess; it finishes (bounded by `BRIDGE_TIMEOUT`).
- **Depends on the `claude` CLI's output schema.** It parses `--output-format
  stream-json`; a future CLI change could require an update (the smoke test guards the
  tool surface, not the parser).
- **Not independently security-audited.** Reviewed adversarially (incl. by separate AI
  reviewers) but not professionally audited.

## Cost model

Each `ask_codebase` call spins up a fresh headless Claude Code agent, so dollar cost
varies with how much it explores. The win from `thread` reuse shows as a climbing
**cache-hit rate** and cheap short follow-ups — not a strictly lower price every call.
State is in-memory per server process; restarting resets threads and the ledger.

## Development

```sh
uv run tests/smoke.py   # MCP handshake + tool-surface check (no API key needed)
uv build                # build wheel + sdist
```

CI runs both on every push/PR (`.github/workflows/ci.yml`).

## License

MIT — see [LICENSE](LICENSE).

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [EDMMY](https://github.com/EDMMY)
- **Source:** [EDMMY/codebase-bridge-mcp](https://github.com/EDMMY/codebase-bridge-mcp)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** yes
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-edmmy-codebase-bridge-mcp
- Seller: https://agentstack.voostack.com/s/edmmy
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
