Skip to content

V1Adait/Context-MCP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Context-MCP

An MCP server that gives Claude Code real structural understanding of a codebase — via tree-sitter AST parsing — before it starts a task. The goal is to cut down on wasted tokens from re-reading/re-discovery, tighten task scope, and ground acceptance criteria in the code's actual structure instead of guesswork.

The problem

Handing an agent a task usually goes wrong for one of three reasons:

  1. Insufficient context — the agent greps and re-reads files it's already seen, burning tokens rediscovering things a proper index already knows.
  2. Ambiguous scope — "fix the auth bug" has no stated boundary, so the agent decides its own, and scope creep follows.
  3. Missing acceptance criteria — "make sure it works" isn't checkable, so there's no way to tell if the task actually finished.

Context-MCP addresses all three with structural, deterministic data — no LLM calls happen inside the server itself. It returns facts; Claude Code does the reasoning.

How it's different

Similar tools (e.g. preflight-dev/preflight) mine session logs and use regex-based contract extraction — inference from past conversations. Context-MCP parses the actual source with tree-sitter and builds a real symbol index and reference graph, so what it returns is ground truth about the code as it exists right now, not a guess based on what happened before.

Architecture

Two pieces working together:

  • The MCP server (this repo's actual product) — exposes get_context_map, validate_brief, check_scope, and list_symbols. Does all the real analysis.

  • A companion PreToolUse hook (hooks/pretooluse_gate.py, ~100 lines) — blocks Edit/Write tool calls unless the MCP server has already written a valid brief_id for the session. The hook does no analysis of its own; it only enforces call order, which an MCP server alone cannot do, since nothing stops an agent from simply not calling a given tool. Most MCP-only tools skip this layer and rely on the agent choosing to cooperate.

    This enforcement is real but not absolute — see Known limitations.

Install

Requires Python 3.11+.

git clone <this-repo-url> Context-MCP
cd Context-MCP
python -m venv .venv

# macOS/Linux
.venv/bin/pip install -r requirements.txt
# Windows
.venv\Scripts\pip install -r requirements.txt

Register the server

Register it against any project you want structural context for — it doesn't need to live inside that project. Point it at wherever you cloned it:

# from inside the project you want to analyze
claude mcp add context-mcp --scope project -- \
  /absolute/path/to/Context-MCP/.venv/bin/python \
  /absolute/path/to/Context-MCP/src/server.py

(On Windows, the interpreter is at ...\Context-MCP\.venv\Scripts\python.exe.)

Or copy .mcp.json.example to .mcp.json in the target project and fill in the real paths yourself.

This alone gives you get_context_map, list_symbols, validate_brief, and check_scope as callable tools — useful on their own, with no enforcement.

Adding the enforcement gate (optional)

Registering the hook means every Edit/Write in that project gets gated behind a validated brief — including edits unrelated to whatever task you're consciously briefing. Only add it to a project where you actually want that discipline enforced.

Copy .claude/settings.json.example to .claude/settings.json in the target project, filling in your own absolute paths. Use forward slashes and the args array form (not a single backslash-joined command string — see Known limitations for why that matters on Windows).

Usage

# 1. Before touching code, ask what's relevant
get_context_map("AuthService")

# 2. Submit a brief — required before any Edit/Write will be allowed
validate_brief({
  "target": "AuthService",
  "scope": {
    "in_scope": ["src/auth/service.py", "src/auth/routes.py"],
    "out_scope": ["src/db/"]
  },
  "acceptance_criteria": [
    "login() returns a signed JWT with a 1-hour expiry",
    "invalid credentials return 401, not 500"
  ]
})

# 3. Work normally — Edit/Write are checked against in_scope automatically

# 4. Optionally audit drift explicitly before finishing
check_scope(brief_id, files_touched)

validate_brief rejects the brief outright if acceptance criteria are empty or vague (a keyword blocklist catches things like "it works", "should work"), if scope has no in/out boundary, or if the target doesn't resolve against the repo's symbol index — catching typos or hallucinated file/symbol names before any work starts.

Known limitations

  • The hook only covers Edit and Write. A Bash or PowerShell call can write files directly and completely bypass the gate — this was found by direct testing, not theorized. It isn't fixable by widening the tool matcher alone: reliably classifying "is this shell command about to write a file" without running it isn't possible. Enforcement here is real for the tools it covers, not an unconditional guarantee.
  • Windows shell quoting is unforgiving. If Git Bash is present, hook commands run through bash, which strips backslashes from a single joined command string. Always use forward slashes and the args array form in hook config, not a command string built from Windows-style paths.
  • Dynamic imports and reflection-like patterns (e.g. require(computedPath), dynamic importlib calls) can't be resolved statically by tree-sitter and won't show up in the reference graph.
  • Language support is currently Python, JavaScript, and TypeScript/TSX only.
  • No published before/after benchmark yet. The mechanism is verified working end-to-end; a real token-usage / scope-accuracy comparison against running tasks without this tool hasn't been run yet. Treat claims of "improves your workflow" as unproven until that data exists.

License

MIT — see LICENSE.

About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages