Skip to content

MCP Servers That Understand Your Codebase: Serena, codebase-memory-mcp, Claude Context and Repomix

Code-intelligence MCP servers give a coding agent structural knowledge of a repository instead of grep-and-read loops. Serena finds and edits symbols through language servers, codebase-memory-mcp traces call paths in a local knowledge graph, Claude Context runs semantic search over a vector database, and Repomix packs a repository into one file. None of them proves a change correct; your tests do.

You ask the agent to rename OrderService.applyDiscount in a 400,000-line TypeScript monorepo. It greps for applyDiscount, reads 30 files to tell the real callers from a test fixture, a log string and an unrelated applyDiscount on CartService, and runs out of context before it has edited anything. A language server already knows the answer. The agent only needs a tool that asks it.

This page is for developers who refactor large codebases with an agent, and for tech leads deciding which of these servers the team standardises on. You get a decision table for the four servers, Serena installed the upstream way in all three tools, a worked rename across every caller, a four-stage refactor workflow (map, plan, edit symbols, test), an audit of codebase-memory-mcp’s installer, and the failure modes with their recovery. The page assumes you have added an MCP server before; if not, start with the MCP overview.

Which code-intelligence MCP server fits your codebase?

Section titled “Which code-intelligence MCP server fits your codebase?”

The four servers answer different questions. Pick by the question you keep asking, not by star count.

Serenacodebase-memory-mcpClaude ContextRepomix
Answers“Where is this symbol, who references it, rename it”“What calls this, what does it call, what does this diff touch”“Where is the code that handles X” (by meaning)“Give me this whole repository, or a slice of it, in one file”
EngineLanguage servers (LSP), or a paid JetBrains pluginTree-sitter knowledge graph persisted locally, plus embeddings bundled in the binary for local semantic searchEmbeddings in a Milvus or Zilliz vector databaseTree-sitter compression and packing
Edits codeYes: rename_symbol, replace_symbol_body, insert_after_symbol, safe_delete_symbolNo, read-only graphNoNo
Your code leaves the machineNoNo (README: “100% locally”)Yes with a hosted embedding provider or Zilliz Cloud; no with local Milvus and OllamaNo, unless you pack a remote repository
Needsuv, plus a language server per languageOne native binaryNode.js 20+, a vector database, an embedding providerNode.js (npx)
Current version (2026-09-26)PyPI serena-agent 1.7.0 (2026-08-09)0.11.0 on npm and PyPInpm @zilliz/claude-context-mcp 0.1.15 (2026-06-22)npm repomix 1.18.1 (2026-09-21)

The decision rules that follow from the table:

  • Renames, moves and signature changes in a typed language: Serena. It is the only one of the four that edits, and a language-server rename is exact where a text replace is not.
  • “What breaks if I change this?” on a codebase you do not know: codebase-memory-mcp. trace_path and detect_changes answer impact questions in one call.
  • Finding code by intent (“where do we retry payments?”) when your organisation already runs a vector database: Claude Context. Try codebase-memory-mcp’s local semantic search first; Claude Context is the heaviest to operate.
  • Handing a whole repository, or a third-party one, to a model at once, or turning a library into a reference skill: Repomix.

Serena and codebase-memory-mcp combine well: the graph maps the blast radius, the language server edits. All four at once costs context for little gain.

Install Serena from upstream, not from a marketplace

Section titled “Install Serena from upstream, not from a marketplace”

Serena’s README is explicit: “Do not install Serena via an MCP or plugin marketplace! They contain outdated and suboptimal installation commands.” The serena plugin in claude-plugins-official still launches it with uvx --from git+https://github.com/oraios/serena, the route upstream warns against. Install the tool once, then point each agent at it.

  1. Install uv (Serena’s only prerequisite), then install Serena as a uv tool and initialise it:

    Terminal window
    uv tool install -p 3.13 serena-agent
    serena init

    serena init sets up the default language-server backend. Some languages need an extra dependency; Serena’s language-support page lists them. serena-agent 1.7.0 requires Python 3.11 to 3.14 (PyPI, checked 2026-09-26).

  2. Connect your agent. The contexts differ per tool, because each context switches off the Serena tools that duplicate the agent’s own file and shell tools.

    Terminal window
    # all projects; Serena activates the directory Claude Code starts in
    claude mcp add --scope user serena -- serena start-mcp-server --context claude-code --project-from-cwd

    serena setup claude-code writes the same entry for you. If Serena starts too slowly and /mcp shows it as failed, set MCP_TIMEOUT=60000 in your shell profile, as Serena’s client docs suggest.

  3. Check the connection. Run /mcp in Claude Code or Codex (in Cursor, open the MCP list in settings) and confirm serena is connected. Then ask: “Use serena to give me the symbols overview of src/orders/order-service.ts”. The agent should call get_symbols_overview, not read the file.

Keep the agent using Serena instead of grep

Section titled “Keep the agent using Serena instead of grep”

Serena’s client docs report that recent Claude Code releases lean hard toward the built-in tools, so the agent often ignores Serena in long sessions. Upstream ships alpha hooks for this: remind nudges the agent after a run of grep or read_file calls, activate activates the project at session start, and cleanup removes hook state at the end. Add them to .claude/settings.json:

{
"hooks": {
"SessionStart": [
{ "matcher": "", "hooks": [{ "type": "command", "command": "serena-hooks activate --client=claude-code" }] }
],
"PreToolUse": [
{ "matcher": "", "hooks": [{ "type": "command", "command": "serena-hooks remind --client=claude-code" }] }
],
"SessionEnd": [
{ "matcher": "", "hooks": [{ "type": "command", "command": "serena-hooks cleanup --client=claude-code" }] }
]
}
}

Leave out upstream’s auto-approve hook and replacement system prompt at first: the hook approves Serena’s editing tools without a prompt in acceptEdits or auto mode, and claude --system-prompt="$(serena prompts print-cc-system-prompt-override)" replaces Claude Code’s default system prompt instead of adding to it.

Serena’s docs give a Codex version in ~/.codex/hooks.json (--client=codex, PreToolUse matched to Bash, plus a reset hook after Serena’s own tools). Copy that block from upstream rather than adapting the JSON above; its SessionEnd cleanup needs Codex 0.145.0 or newer. The same docs tell you to set codex_hooks = true under [features]. On codex-cli 0.157.1 that flag is not listed: codex features list shows hooks as stable and on by default, so skip it. Codex runs a new or changed hook only after you trust it in /hooks (codex-cli 0.157.1).

Rename OrderService.applyDiscount across every caller with Serena

Section titled “Rename OrderService.applyDiscount across every caller with Serena”

This is the task from the opening. The prompt names the symbol by its Serena name path (OrderService/applyDiscount) and the file, so the language server resolves exactly one symbol.

What you should see: find_symbol, then find_referencing_symbols (each result carries the referencing symbol and a snippet of code around the reference), a pause for your confirmation, then one rename_symbol call that updates every reference the language server knows about in a single operation. CartService.applyDiscount stays untouched, because it is a different symbol.

The last text search matters. A language server cannot see a method name in a string, a JSON fixture, a mock such as vi.spyOn(service, 'applyDiscount'), or service[methodName](), and the type check will not flag them either. In Java and other languages with overloading, pick the overload with a 0-based index in find_symbol, such as OrderService/applyDiscount[0]; Serena’s rename_symbol documentation says its name path may have to include the method’s signature instead.

Refactor a large codebase: map callers, plan, edit symbols, test

Section titled “Refactor a large codebase: map callers, plan, edit symbols, test”

A real refactor, such as splitting the discount logic out of OrderService into a PromotionEngine, needs the blast radius first. This workflow uses codebase-memory-mcp for the map and Serena for the edits, the same way in all three tools.

  1. Record the baseline. On a fresh branch, run the type check, lint and the full test suite, and save the output. If the code you are about to move has thin coverage, add characterization tests first; how strong your oracle is shows how to check.

  2. Map the callers. Index the repository once, then trace inbound paths.

    Without MCP, the same query runs from a terminal: codebase-memory-mcp cli trace_path --project my-project --function-name applyDiscount --direction inbound.

  3. Plan in reviewable slices. Ask for the plan as a file.

    Review this plan: it is the contract for the rest of the work, and untested callers get tests before the move.

  4. Edit at the symbol level, one slice at a time.

  5. Prove it with tests, then check what the graph says changed. Run the full gate against the baseline. Then ask the agent to run detect_changes, which maps the uncommitted diff to affected symbols with a risk classification. Every affected symbol should be in the plan. Any affected symbol outside it is scope creep or a missed caller.

Install codebase-memory-mcp without letting it rewrite your configs

Section titled “Install codebase-memory-mcp without letting it rewrite your configs”

codebase-memory-mcp (DeusData) indexes a repository into a persistent local graph and exposes 17 MCP tools, among them index_repository, search_graph, trace_path (alias trace_call_path), detect_changes, query_graph and get_architecture. It needs no API key, its README says it runs “100% locally and collects no telemetry”, and search_graph does semantic search with an embedding model compiled into the binary.

The one-line install is curl -fsSL https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.sh | bash. That script downloads a native binary and runs its install command, which writes to the configuration of every coding agent it detects: for Claude Code, an MCP entry in ~/.claude.json, a skill, three subagents and hooks on SessionStart, SubagentStart and PreToolUse for Grep, Glob and Bash; for Codex, config.toml, a pointer in $CODEX_HOME/AGENTS.md, a skill and agents. That is more change than you asked for.

  1. Read the script before you run it. Download install.sh (or install.ps1 on Windows) to a file, read it, and only then run it.

  2. Install the binary only. Pass --skip-config so the installer touches no agent configuration:

    Terminal window
    bash install.sh --skip-config

    Or use a package manager: npm install -g codebase-memory-mcp or pip install codebase-memory-mcp (both 0.11.0, checked 2026-09-26).

  3. Add the server yourself, where you want it.

    Terminal window
    claude mcp add codebase-memory -- /usr/local/bin/codebase-memory-mcp

    Replace /usr/local/bin/codebase-memory-mcp with the path which codebase-memory-mcp prints. The Claude Code and Codex lines are derived from the README’s JSON. /mcp should then show the server with 17 tools.

  4. Say “Index this project”, and confirm with index_status. To index new projects automatically on first connection, run codebase-memory-mcp config set auto_index true. A background watcher keeps indexed projects fresh.

If you already ran the full installer, codebase-memory-mcp uninstall removes the config entries, skills, hooks and instructions it owns plus the binary, asks before deleting indexes, and prints (but does not delete) the install script’s path.

Claude Context: semantic search when you can run a vector database

Section titled “Claude Context: semantic search when you can run a vector database”

Claude Context (Zilliz) splits code into AST-based chunks, embeds them, stores them in Milvus or Zilliz Cloud, and answers natural-language queries with hybrid BM25 and vector search. It exposes four tools: index_codebase, search_code, clear_index and get_indexing_status. It helps most where related code shares no vocabulary. It is also the one server here with external dependencies. With the default EMBEDDING_PROVIDER=OpenAI, your code chunks go to the embedding API and the vectors to Zilliz Cloud. For a fully local setup, run Milvus yourself and set EMBEDDING_PROVIDER=Ollama.

Keep the keys out of the command line and out of committed files:

Terminal window
claude mcp add --scope project claude-context \
-e 'OPENAI_API_KEY=${OPENAI_API_KEY}' -e 'MILVUS_TOKEN=${MILVUS_TOKEN}' \
-- npx -y @zilliz/claude-context-mcp@0.1.15

The single quotes keep ${OPENAI_API_KEY} literal in .mcp.json (tested on Claude Code 2.1.283); Claude Code expands it from your environment at launch.

MILVUS_ADDRESS is optional with a Zilliz personal API key; add it for a self-hosted Milvus. Then run the vendor’s flow: “Index this codebase”, “Check the indexing status”, “Find functions that handle user authentication”.

Weigh its health before you standardise on it. On 2026-09-26 its last npm release was 2026-06-22 and its last push 2026-07-14. For the index-tuning side of semantic search, see semantic code search in large codebases.

Repomix packs a repository, or a glob-filtered slice of it, into one AI-friendly file (XML by default) with token counts and a Secretlint scan for secrets. It is a delivery format more than an index. Use it to study a third-party library without cloning it, to hand a model a whole module, or to generate a reference skill.

As an MCP server it registers six tools in 1.18.1 (tested handshake, 2026-09-26): pack_codebase, pack_remote_repository, read_repomix_output, grep_repomix_output, generate_skill and attach_packed_output.

Terminal window
claude mcp add repomix -- npx -y repomix --mcp

Repomix also ships its own plugin marketplace: /plugin marketplace add yamadashy/repomix, then /plugin install repomix-mcp@repomix.

Add --sandbox after --mcp to confine the file tools to the working directory. Without it, the README says the server “can read any path the host user can”; with it, remote packing and skill generation are disabled.

The CLI covers the same ground without MCP:

Terminal window
npx repomix --compress # packs the current directory into repomix-output.xml
npx repomix --remote yamadashy/repomix --compress # packs a GitHub repository without cloning it
npx repomix --include "src/**/*.ts" --ignore "**/*.test.ts" # packs a slice
npx repomix --skill-generate # writes a Claude Agent Skill to .claude/skills/<name>/

--compress keeps signatures and drops function bodies; the vendor claims about 70% fewer tokens, which this page did not measure. --skill-output <path> writes the skill to another directory, for when your agent reads skills from somewhere else.

How do you prove the refactor is correct without reading every line?

Section titled “How do you prove the refactor is correct without reading every line?”

A code-intelligence server makes edits more precise, not correct. The proof is your usual gate for agent changes, plus two checks these servers make cheap.

CheckWhat it catchesWho owns it
Type check and lint on every sliceMissed references in typed code, broken importsCI, blocking
Full test suite against the recorded baselineBehaviour changes the types cannot seeCI, blocking
Test files unchanged unless the plan names them (git diff --stat -- '*.test.ts')An agent that “fixed” the tests to make the refactor passReviewer
Leftover string hits for the old name, listed in the PRRenames missed in strings, mocks, fixtures and dynamic accessAuthor (agent), checked by the reviewer
detect_changes output matches the plan’s symbol listScope creep and missed callersReviewer
Impact and plan files attached to the PRA refactor nobody can audit afterwardsTech lead

The tech lead signs off on this evidence. The evidence bundle page has a PR template that makes these rows required, and reviewing an agent’s pull request covers the review itself.

What code-intelligence servers cost in context

Section titled “What code-intelligence servers cost in context”

Claude Code 2.1.283 and codex-cli 0.157.1 both load MCP tool schemas through tool search by default, so idle servers cost little; results are what fill the window.

  • Serena: use the context that matches the agent (claude-code, codex, ide), so you do not pay for duplicate file and shell tools.
  • codebase-memory-mcp: its responses page by default and accept max_output_tokens. Ask for one depth level at a time rather than a whole call tree.
  • Repomix: a packed repository is the biggest single result you can add. Pack a glob slice with --compress, and grep the output instead of reading all of it.
  • Claude Context: search_code returns chunks, so narrow queries return less.

Run /context in Claude Code before and after one query to measure it. For the general pattern, see reducing MCP token cost.

As of 2026-09-26 (GitHub stars read from the repository pages; plugin installs from claude.com/plugins): codebase-memory-mcp ★44.9k, Serena ★29.8k with 89,147 installs of its marketplace plugin, Repomix ★28,494, and Claude Context ★12,572. Serena, codebase-memory-mcp and Repomix are listed in the Official MCP Registry; Claude Context is not.

The agent ignores Serena and greps anyway. The built-in tools win in long sessions. Recovery: add the remind and activate hooks above, and name the Serena tool in the prompt (“use find_referencing_symbols”).

Serena reports no symbols, or finds the wrong project. A global configuration started Serena outside the repository, or the language server for that language is missing. Recovery: activate the project as the Codex and Cursor tabs above show, use --project-from-cwd in Claude Code and Codex, and install the dependency listed on Serena’s language-support page.

/mcp shows Serena as failed on startup. The language server starts slower than the client waits. Recovery: MCP_TIMEOUT=60000 in Claude Code, a higher startup_timeout_sec in Codex.

The rename passed the type check but broke at runtime. A string, mock, fixture or obj[name]() call still uses the old name. Recovery: search for the old name after every rename, as the prompt requires, and fix the hits by hand.

trace_path misses a caller. Dynamic dispatch, string-token injection or reflection leaves no static edge. Recovery: run check_index_coverage for the paths in question, cross-check with Serena’s find_referencing_symbols, and rely on the test suite for anything neither can see.

codebase-memory-mcp changed your agent setup. New hooks fire on every Grep and Bash call, and a skill you did not install has appeared. Recovery: codebase-memory-mcp uninstall, then reinstall with --skip-config and add the server by hand.

Claude Context returns stale results. The index predates a large merge. Recovery: clear_index, index_codebase, then wait for get_indexing_status.

A packed repository flooded the context. Recovery: pack a slice with --include, use --compress, and let the agent call grep_repomix_output rather than read_repomix_output on the whole file.