codebase-bridge-mcp

codebase-bridge-mcp

A read-only MCP server that lets a Claude chat explore your local repository and answer questions about it, returning synthesized answers with file:line references.

Category
Visit Server

README

codebase-bridge-mcp

A read-only MCP 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 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 (claude) installed and authenticated.
  • uv (runs the server with zero install — deps are declared inline in server.py).
  • For the optional http transport: 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:

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:

{
  "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:

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://<tunnel>.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

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.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured