MCP Server

Connect repowise to Claude Code, Codex, Cursor, Cline, or any MCP-compatible editor.


Table of contents

  1. Overview
  2. Connecting to editors
    1. Claude Code
    2. Codex
    3. Cursor
    4. Cline
    5. Windsurf
  3. Transport protocols
    1. stdio (default)
    2. Streamable HTTP
    3. SSE (Server-Sent Events, legacy)
  4. The default single-repo tools
    1. get_answer(question, scope?)
    2. get_symbol(symbol_id)
    3. get_overview()
    4. get_context(targets, include?, compact?)
    5. get_risk(targets)
    6. get_why(query?, targets?)
    7. search_codebase(query, limit?, mode?, kind?, symbol_kind?, page_type?)
    8. get_change_risk(revspec?, extensions?, exclude_patterns?, baseline?)
    9. get_health(targets?, include?, limit?)
    10. get_dead_code(kind?, min_confidence?, safe_only?, tier?, directory?)
  5. Supplementary tools
    1. list_repos() (default in a workspace)
    2. Workspace-only (opt-in)
    3. Opt-in tools (off by default)
  6. 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 question
  • scope (optional, string) — path prefix to restrict retrieval (e.g. "src/auth/")

Returns:

  • answer (string) — synthesized 2–5 sentence answer
  • citations (list of strings) — file paths backing the answer
  • confidence (string) — "high", "medium", or "low". High-confidence answers can be cited directly without verification reads; lower confidence indicates the agent should fall back to search_codebase or Read.
  • fallback_targets (list of strings) — top retrieval hits the agent should Read if it does not trust the synthesized answer
  • candidate_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 otherwise
  • retrieval (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 form path/to/file.py::ClassName::method_name. Both :: and . are accepted as the symbol separator (Class::method and Class.method resolve identically).

Returns:

  • symbol_id, name, kind (class, function, method, …)
  • file_path, start_line, end_line
  • signature (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 names
  • include (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, default True) — when True, drops the structure block, the imported_by list, and per-symbol docstrings/end-line fields to keep the response under ~10K characters. Pass compact=False to 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 targets provided)
  • 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 query
  • limit (int, default 5) — max results
  • mode (optional) — auto (default) | concept | symbol | path | hybrid
  • kind (optional) — implementation | test | config | doc
  • symbol_kind (optional) — restrict symbol hits by kind (function, class, method, …)
  • page_type (optional) — restrict to one page type. The two you will reach for are file_page (the always-on per-file docs) and module_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 or base..head; omit it to score uncommitted work
  • extensions (optional) — file suffixes to count (e.g. [".py", ".ts"])
  • exclude_patterns (optional) — gitignore-style paths; combined with root .riskignore
  • baseline (optional, int) — recent commits for percentile ranking (default 200)

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, or module:foo; empty = dashboard mode
  • include (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 by unreachable_file, unused_export, unused_internal, zombie_package
  • min_confidence — 0.0–1.0, default 0.4
  • safe_only — only return findings marked safe_to_delete
  • tier — high, medium, or low
  • directory — limit to a specific directory
  • group_by — directory or owner

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:

  1. Before any task → get_overview() to orient
  2. Before reading a file → get_context(targets=[...]) instead of reading raw source
  3. Before editing a file → get_risk(targets=[...]) to assess impact
  4. Before merging a commit / PR → get_change_risk(revspec="main..HEAD")
  5. Before refactoring → get_health() (and get_dead_code for cleanup)
  6. When facing an architectural question → get_why(query="...") before changing structure
  7. 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.