Skip to main content
Glama
EDMMY

codebase-bridge-mcp

by EDMMY

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.

Related MCP server: repo-intelligence-mcp

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 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.

Available Tools

3 tools
ask_codebaseA

Ask a natural-language question about the local codebase, with turn-based steering.

Headless Claude Code explores the repo READ-ONLY (Read/Grep/Glob) and returns a synthesized answer with file:line references -- no need to attach or paste files.

thread: optional name (e.g. "auth-investigation"). Reuse the SAME name across questions to STEER: each follow-up keeps the prior session's context, so you can redirect ("no, the token check is in middleware.py -- re-check there") and it stays cheap (prompt-cache hits). Omit for a one-off fresh session. model: optional model (e.g. "sonnet", "opus"). For a thread it BINDS on the first call; a DIFFERENT model on an existing thread is refused, because switching forces a full-context reprocess -- start a new thread instead. Ephemeral (no-thread) calls just use the given model. effort: optional reasoning effort -- low, medium, high, xhigh, max. Per-call (safe to vary within a thread; unlike model it does not invalidate the cache). Lower = cheaper/faster; raise it for hard cross-file reasoning. show_steps: when true, append the exploration trail (which files it read, what it grepped) so you can see HOW it reached the answer and steer the next turn.

Each answer ends with a [bridge] cost footer (call cost + cache hit rate, plus the thread's running total). Call bridge_cost for the full ledger.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNo
effortNo
threadNo
questionYes
show_stepsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description fully discloses the tool's read-only nature ('explores the repo READ-ONLY'), exploration methods (Read/Grep/Glob), return format (synthesized answer with file:line references and cost footer), thread behavior (context caching for steering), model binding rules, effort variability, and the optional show_steps to reveal the exploration trail. This exceeds what is required for confident invocation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured, starting with the primary purpose followed by parameter details. It is efficient, with each sentence serving a clear purpose. However, it is somewhat lengthy; a touch more conciseness could be achieved without losing clarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (5 parameters, turn-based steering, model binding, caching), the description covers all essential behavioral and contextual aspects: usage scenarios, parameter interactions, cost reporting, and output format. Since an output schema exists, omission of explicit return value details is acceptable. A minor gap is the lack of error condition description, but overall it is complete enough for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explains all five parameters: the required 'question,' optional 'thread' for steering, 'model' with binding rules, 'effort' with allowed values (low, medium, high, xhigh, max), and 'show_steps' for transparency. Although defaults are not explicitly stated, the descriptions are clear and add significant meaning beyond the raw schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's core function: 'Ask a natural-language question about the local codebase, with turn-based steering.' It uses specific verbs ('ask,' 'steer') and a well-defined resource ('local codebase'), and distinguishes itself from siblings (bridge_cost, bridge_forget) by focusing on querying and analysis.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains when to use a thread (for multi-turn steering) versus one-off queries, and how to vary effort within a thread. It also notes that switching models on an existing thread is refused, prompting the user to start a new thread. While it mentions bridge_cost for cost details, it does not explicitly exclude other alternatives, but the context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bridge_costA

Report cumulative API cost of ask_codebase calls in this server process, broken down by thread plus a grand total.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description indicates a read-only operation (report cumulative cost) but does not detail whether the report resets, the time scope, or any potential side effects. Given no annotations, the description carries full burden but leaves some ambiguity.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no wasted words. It immediately conveys the tool's purpose and output structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given zero parameters and an existing output schema, the description sufficiently explains the tool's output (breakdown by thread and grand total). It could be improved by clarifying what 'API cost' means (e.g., tokens or dollars), but overall complete for a simple report.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With zero parameters, the description inherently covers all parameter semantics. The baseline is 4 per guidelines, and the description does not contradict schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool reports cumulative API cost of ask_codebase calls, broken down by thread and grand total. This distinguishes it from siblings like ask_codebase (which likely makes API calls) and bridge_forget (which might manage state).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for monitoring costs but provides no explicit guidance on when to use this tool versus alternatives. It lacks when-not-to-use or prerequisite instructions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bridge_forgetA

Drop a thread's session so the next call to that name starts fresh. Pass a thread name to forget just that one, or omit it to forget ALL threads. A call already in flight for that thread finishes but its state update is discarded.

ParametersJSON Schema
NameRequiredDescriptionDefault
threadNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Fully discloses behavioral traits: session is dropped, next call starts fresh, in-flight call finishes but its state update is discarded. With no annotations, the description carries the full burden and does so completely.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, no wasted words. The main action is front-loaded, and each sentence adds essential information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers core behavior and parameter use. An output schema exists, so no need to explain return values. Could mention error conditions (e.g., invalid thread name), but overall complete for a simple tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema has 0% description coverage, but the description fully explains the single parameter 'thread': passing a name forgets that thread, omitting forgets all. This exceeds the schema's contribution.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states the verb 'Drop' and resource 'thread's session', with explicit distinction between forgetting one thread or all. The action is unique among siblings (ask_codebase, bridge_cost), so purpose is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear usage patterns (pass thread name or omit for all), but no guidance on when to use this tool versus alternatives. The description explains behavior but does not contrast with other tools or indicate when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 3 tool updatesv0.1.0
    • First observedask_codebase
    • First observedbridge_cost
    • First observedbridge_forget

TDQS

A4.4/5.0
Disambiguation5/5

The three tools have clearly distinct purposes: ask_codebase for Q&A with turn-based steering, bridge_cost for cost reporting, and bridge_forget for thread management. There is no overlap in functionality.

Naming Consistency4/5

Tool names follow a predictable pattern with an underscore separator, though the primary tool uses 'ask_' while the auxiliary tools use 'bridge_' prefix. This is a common and acceptable namespace convention but slightly deviates from a fully uniform verb_noun pattern.

Tool Count5/5

With three tools, the count is appropriate for the server's focused scope of codebase Q&A with supporting cost and thread management. Each tool serves a necessary function without redundancy.

Completeness5/5

The toolset covers the full workflow: asking questions with thread support, tracking costs, and forgetting threads when needed. No obvious gaps exist for the stated purpose of exploring a codebase with a conversational agent.

Maintenance

ActivityStale
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that gives Claude Desktop complete intelligence about any public GitHub repository. Research libraries, compare packages, audit dependencies, and explore codebases through natural conversation.
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that gives LLMs structured, read-only insight into local code repositories — directory tree, languages, dependencies, scripts, and config files.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A small MCP server that turns a shared Ollama box into a team resource for Claude Code, providing typed tools and delegated read-only repo exploration using local models.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    An MCP server that indexes local code repositories, extracting symbols and call graphs to give Claude precise, structural answers with real file paths and line numbers. Runs entirely locally with no network requests, for privacy-focused code understanding.
    646
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/EDMMY/codebase-bridge-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server