MCP Server
Connect repowise to Claude Code, Codex, Cursor, Cline, or any MCP-compatible editor.
Table of contents
- Overview
- Connecting to editors
- Transport protocols
- The default single-repo tools
get_answer(question, scope?)get_symbol(symbol_id)get_overview()get_context(targets, include?, compact?)get_risk(targets)get_why(query?, targets?)search_codebase(query, limit?, mode?, kind?, symbol_kind?, page_type?)get_change_risk(revspec?, extensions?, exclude_patterns?, baseline?)get_health(targets?, include?, limit?)get_dead_code(kind?, min_confidence?, safe_only?, tier?, directory?)
- Supplementary tools
- How AI editors use these tools
Overview
The MCP (Model Context Protocol) server is how repowise talks to AI coding assistants. It registers 18 tools: a curated 10-tool default surface in a single repository, list_repos added by default in workspace mode, and seven opt-in specialists subject to mode eligibility. Once connected, your editor’s AI can query your codebase wiki for synthesized answers, symbols, docs, ownership, file and change-risk signals, code health, and architectural decisions.
Start the server with:
repowise mcp [PATH]
Connecting to editors
Claude Code
Via plugin (recommended): The repowise Claude Code plugin registers the MCP server automatically. See Claude Code Plugin →.
Manual setup: Add this to .mcp.json at your repo root:
{
"mcpServers": {
"repowise": {
"command": "repowise",
"args": ["mcp", "/path/to/your-repo"],
"description": "repowise codebase intelligence"
}
}
}
If you’re running repowise for the current directory, you can omit the path:
{
"mcpServers": {
"repowise": {
"command": "repowise",
"args": ["mcp"]
}
}
}
Codex
Run the Codex setup command from your repository:
repowise init --codex
This writes project-local .codex/config.toml with a Repowise MCP server entry:
[mcp_servers.repowise]
command = "repowise"
args = ["mcp"]
cwd = "/path/to/your-repo"
startup_timeout_sec = 20
It also writes .codex/hooks.json and managed AGENTS.md. See Codex Integration.
Cursor
Add to .cursor/mcp.json in your repo or ~/.cursor/mcp.json globally:
{
"mcpServers": {
"repowise": {
"command": "repowise",
"args": ["mcp", "/path/to/your-repo"]
}
}
}
Cline
Add to Cline’s MCP settings file (cline_mcp_settings.json):
{
"mcpServers": {
"repowise": {
"command": "repowise",
"args": ["mcp", "/path/to/your-repo"],
"disabled": false,
"autoApprove": ["get_overview", "get_context", "search_codebase"]
}
}
}
Windsurf
Add to Windsurf’s MCP configuration:
{
"mcpServers": {
"repowise": {
"command": "repowise",
"args": ["mcp", "/path/to/your-repo"]
}
}
}
Transport protocols
stdio (default)
The default transport. The MCP server runs as a subprocess of your editor, communicating over stdin/stdout. This is the correct option for Claude Code, Codex, Cursor, Cline, and Windsurf.
repowise mcp # stdio, current directory
repowise mcp /path/to/repo # stdio, specific repo
repowise mcp --transport stdio # explicit
Streamable HTTP
For HTTP-based MCP clients or headless setups where a persistent local server is preferable.
repowise mcp --transport streamable-http # HTTP on port 7338
repowise mcp --transport streamable-http --port 8080 # Custom port
Clients connect to http://localhost:7338/mcp.
SSE (Server-Sent Events, legacy)
For clients that still require the older SSE transport.
repowise mcp --transport sse # SSE on port 7338
repowise mcp --transport sse --port 8080 # Custom port
Clients connect to http://localhost:7338/sse and receive server-sent events.
The default single-repo tools
The ten flagship tools below, plus list_repos, are on by default in a
single-repo server. Full reference: MCP_TOOLS.md.
get_answer(question, scope?)
One-call RAG over the wiki layer. Runs retrieval, gates on confidence, and synthesizes a 2–5 sentence answer with concrete file/symbol citations. Responses are cached per repository by question hash, so repeated questions cost nothing on the second call.
Parameters:
question(string) — natural-language developer questionscope(optional, string) — path prefix to restrict retrieval (e.g."src/auth/")
Returns:
answer(string) — synthesized 2–5 sentence answercitations(list of strings) — file paths backing the answerconfidence(string) —"high","medium", or"low". High-confidence answers can be cited directly without verification reads; lower confidence indicates the agent should fall back tosearch_codebaseorRead.fallback_targets(list of strings) — top retrieval hits the agent shouldReadif it does not trust the synthesized answercandidate_files(list of strings): ranked file paths retrieval resolved that the citations do not already name: up to 3 on a high-confidence answer, 5 otherwiseretrieval(list) — raw top-N hits with snippets
When to use: First call on any code question. Collapses the typical “search → read → reason” loop into a single round-trip.
Example:
get_answer(question="how does the request context get pushed and popped per request")
→ answer: "Flask pushes a RequestContext onto _request_ctx_stack at the start
of every request via Flask.wsgi_app, and pops it in the corresponding
finally clause. The push happens in src/flask/app.py::Flask.wsgi_app."
citations: ["src/flask/app.py", "src/flask/ctx.py"]
confidence: "high"
get_symbol(symbol_id)
Resolves a fully-qualified symbol identifier to its definition. Returns the source body, signature, file location, line range, and any associated docstring without the agent having to grep then read.
Parameters:
symbol_id(string) — qualified id of the formpath/to/file.py::ClassName::method_name. Both::and.are accepted as the symbol separator (Class::methodandClass.methodresolve identically).
Returns:
symbol_id,name,kind(class,function,method, …)file_path,start_line,end_linesignature(recovered from source so base classes, decorators, and full type annotations are preserved)body(the symbol’s source code)docstring
When to use: When the question names a specific class, function, or method and you want its source without a separate Read call.
get_overview()
Returns a high-level architecture summary of the indexed repository: key modules, entry points, tech stack, git health (churn percentiles, bus factors), and recent activity trends.
When to use: Start every new task by calling this. It orients the AI and surfaces risk signals before any code is read.
Example response:
Repository: repowise
Architecture: Python monorepo (cli, core, server, web)
Entry points: packages/cli/src/repowise/cli/main.py
Tech stack: Python, FastAPI, SQLite, LanceDB, Next.js
Top hotspots: init_cmd.py (99.8th %ile), test_mcp.py (99.5th %ile)
Bus factor risk: git_indexer.py (1 author)
get_context(targets, include?, compact?)
Returns rich context for one or more files, modules, or symbols: documentation, ownership, last change, governing decisions, and freshness status.
Parameters:
targets(list of strings) — file paths, module names, or symbol namesinclude(optional) — opt-in blocks such as"ownership","last_change","decisions","callers","metrics","skeleton","health", and"doc_drift"(the documents that name this file)compact(optional, defaultTrue) — whenTrue, drops thestructureblock, theimported_bylist, and per-symbol docstrings/end-line fields to keep the response under ~10K characters. Passcompact=Falseto receive the full payload, e.g. when you specifically need the import-graph dependents or every symbol docstring on a dense file.
When to use: Before reading or editing any file. Faster and richer than reading the raw source.
Example:
get_context(targets=["packages/cli/src/repowise/cli/commands/init_cmd.py"])
→ Purpose: Orchestrates the 4-phase init pipeline
Owner: RaghavChamadiya (89% of commits)
Last changed: 3 days ago (14 commits in 90d — 99.8th %ile)
Decisions: "Use interactive mode when stdin is a TTY"
Freshness: current
get_risk(targets)
Returns a modification risk assessment for each target file.
Parameters:
targets(list of strings) — file paths
Returns per file:
- Churn percentile rank
- Number of direct and transitive dependents
- Co-change partners (files that tend to change together)
- Bus factor (number of authors with meaningful ownership)
- Change trend: increasing / decreasing / stable
When to use: Required before making changes to any file, especially in hotspot areas.
Example:
get_risk(targets=["packages/core/src/repowise/core/ingestion/git_indexer.py"])
→ Hotspot: 99.3th %ile (9 commits in 90 days)
Dependents: 7 direct, 23 transitive
Co-change partners: init_cmd.py, update_cmd.py
Bus factor: 1 (sole author: RaghavChamadiya)
Trend: increasing
Recommendation: High risk — coordinate before changing
get_why(query?, targets?)
Searches for architectural decisions and intent behind code structure.
Parameters:
query(string) — natural language question (“why JWT instead of sessions?”)targets(optional, list) — file paths to focus on
Returns:
- Matching decision records with title, rationale, and status
- Git archaeology: commit messages and PR descriptions that explain design choices
- Origin story for specific files (if
targetsprovided) - Decision health (staleness scores for applicable decisions)
When to use: Before any architectural change. Ask “why is this structured this way” before refactoring.
Example:
get_why(query="why is rate limiting done in the app layer")
→ Decision: "Rate limiting at application layer"
Rationale: Need per-user limits; load balancer can't distinguish users
Status: active
Source: cli (manually recorded)
Affected: server/middleware/rate_limit.py
search_codebase(query, limit?, mode?, kind?, symbol_kind?, page_type?)
Hybrid code search. Depending on the query, it searches the indexed symbols, file paths, or the wiki — a single tool for “find this function”, “find this file”, and “find code about this topic”.
Parameters:
query(string) — identifier, path, or natural-language querylimit(int, default 5) — max resultsmode(optional) —auto(default) |concept|symbol|path|hybridkind(optional) —implementation|test|config|docsymbol_kind(optional) — restrict symbol hits by kind (function,class,method, …)page_type(optional) — restrict to one page type. The two you will reach for arefile_page(the always-on per-file docs) andmodule_page(the subsystem/concept pages).
Modes: auto routes by shape — an identifier searches indexed symbols (results carry symbol_id + line bounds, pipe into get_symbol), a path searches file pages (pipe into get_context), prose runs wiki-semantic search, and mixed queries run hybrid (symbols first). Force a branch with an explicit mode.
Returns: Symbol hits (symbol_id, file, line bounds, signature, next: "get_symbol"), file hits (page_id, file, next: "get_context"), or ranked wiki pages with relevance scores and a search_method. Recently-changed files receive a freshness boost.
When to use: Locating a symbol or file by name, or discovering code by topic — prefer over grep/find.
Example:
search_codebase(query="GitIndexer index_repo")
→ 1. symbol packages/core/.../git_indexer/indexer.py::GitIndexer.index_repo
async def index_repo(...) -> tuple[GitIndexSummary, list[dict]] (lines 75-306)
next: get_symbol
search_codebase(query="how database connections are pooled")
→ 1. packages/server/src/repowise/server/db.py (0.92)
"Creates async SQLAlchemy engine with connection pooling..."
get_change_risk(revspec?, extensions?, exclude_patterns?, baseline?)
Live risk scoring for one commit or a base..head range. Unlike get_risk
(indexed files), this scores the shape of the live diff and needs no index
refresh.
Parameters:
revspec(optional, string) — commit orbase..head; omit it to score uncommitted workextensions(optional) — file suffixes to count (e.g.[".py", ".ts"])exclude_patterns(optional) — gitignore-style paths; combined with root.riskignorebaseline(optional, int) — recent commits for percentile ranking (default200)
Returns: risk_authority names risk_percentile and classification as
the benchmarked, population-relative authority for live change review.
fix_history reports the recency-weighted bug-fix record of the
files touched, which is what distinguishes a small dangerous change from a large
boring one. diff_shape is one sentence on size and spread, beside repo-relative
risk_percentile / review_priority / classification, plus
impacted_tests when a per-test coverage map is ingested
(repowise coverage add). The raw 0-10 score and its absolute
fallback_band sit behind include=["diagnostics"]: the score ranks 0.99
against lines added, so the percentile already carries the ranking.
include=["scales"] supplies the kind, units, range, calibration, authority
and shared thresholds for each value.
When to use: Before merging a commit or PR range, or on work you have not committed yet.
Example:
get_change_risk(revspec="main..HEAD", extensions=[".py"], exclude_patterns=["tests/"])
get_health(targets?, include?, limit?)
Code-health marker scores (defect risk, maintainability, performance) — the
same deterministic markers as repowise health. Zero LLM calls.
Parameters:
targets(optional) — file paths, ormodule:foo; empty = dashboard modeinclude(optional) — opt-in blocks such as"biomarkers","refactoring","trend","coverage","accuracy","signals","churn_complexity","doc_drift"limit(optional, int) — max lowest-scoring files (default 20)
When to use: Self-check a change before opening a PR, or find the worst
files before refactoring. Pair with get_risk on hotspots.
Example:
get_health()
get_health(targets=["src/api/server.py"], include=["signals"])
get_dead_code(kind?, min_confidence?, safe_only?, tier?, directory?)
Returns a tiered report of unused code.
Parameters:
kind— filter byunreachable_file,unused_export,unused_internal,zombie_packagemin_confidence— 0.0–1.0, default 0.4safe_only— only return findings markedsafe_to_deletetier—high,medium, orlowdirectory— limit to a specific directorygroup_by—directoryorowner
When to use: Before any cleanup or removal tasks. Gives confirmed unused code rather than guesses.
Also always on by default: list_repos() (repo aliases for the repo= parameter
on other tools). See Supplementary tools below.
Full parameter tables and return shapes live in the repo guide: docs/agent/MCP_TOOLS.md.
Supplementary tools
list_repos() (default in a workspace)
Lists every configured alias in a workspace. It is not advertised in single-repo mode, where the server is bound to the only repository.
Workspace-only (opt-in)
These need a workspace and are off by default there too. Enable them the same way as the opt-in tools below:
| Tool | Purpose |
|---|---|
get_architecture() |
Whole-system coupling, cyclic core, 1–10 architecture score |
get_blast_radius(targets, …) |
Cross-repo downstream impact of changing a service |
get_conformance(…) |
Architecture-rule violations and dependency cycles |
Opt-in tools (off by default)
Registered everywhere but not advertised until enabled via
mcp.tools: ["+name"] in .repowise/config.yaml, the dashboard Settings page,
or repowise mcp --tools "+name":
| Tool | Purpose |
|---|---|
get_dependency_path(source, target) |
Shortest graph path between two files/modules |
get_execution_flows(…) |
Top entry points and call traces |
generate_refactoring_code(…) |
Code for a ranked refactoring plan from get_health |
set_finding_status(…) |
Record a triage status on a refactoring plan |
How AI editors use these tools
The tools are designed to form a decision workflow:
- Before any task →
get_overview()to orient - Before reading a file →
get_context(targets=[...])instead of reading raw source - Before editing a file →
get_risk(targets=[...])to assess impact - Before merging a commit / PR →
get_change_risk(revspec="main..HEAD") - Before refactoring →
get_health()(andget_dead_codefor cleanup) - When facing an architectural question →
get_why(query="...")before changing structure - When locating code →
search_codebase(query="...")before grep
The CLAUDE.md generator writes these instructions directly into your project’s CLAUDE.md, so Claude Code follows this workflow automatically. Codex setup writes the same workflow into managed AGENTS.md.