mcp-codebase-index
Indexador estrutural de base de código com 17 ferramentas de consulta. Redução de 87% de tokens. Zero dependências.
Documentação
mcp-codebase-index
Um indexador estrutural de codebases com um servidor MCP para desenvolvimento assistido por IA. Zero dependências em tempo de execução — usa o módulo ast do Python para análise de Python e parsing baseado em regex para TypeScript/JS, Go, Rust e C#. Requer Python 3.11+.
O Que Ele Faz
Indexa codebases analisando arquivos-fonte e convertendo-os em metadados estruturais — funções, classes, imports, grafos de dependência e cadeias de chamadas entre arquivos — e então expõe 18 ferramentas de consulta via Model Context Protocol, permitindo que Claude Code e outros clientes MCP naveguem por codebases com eficiência sem ler arquivos inteiros.
Reindexação incremental automática: Em repositórios git, o índice permanece atualizado automaticamente. Antes de cada consulta, o servidor verifica git diff e git status (~1-2ms). Se arquivos foram alterados, apenas esses arquivos são reanalisados e o grafo de dependências é reconstruído. Não é necessário chamar reindex manualmente após edições, trocas de branch ou pulls.
Cache persistente em disco: O índice é salvo em um arquivo de cache pickle (.codebase-index-cache.pkl) após cada build. Em inicializações subsequentes do servidor, o cache é carregado e validado contra o HEAD git atual — se a referência coincidir, a inicialização é instantânea. Se um pequeno número de arquivos foi alterado (≤20), o índice em cache é carregado e atualizado incrementalmente em vez de ser reconstruído do zero. Isso elimina a penalidade de cold start ao reiniciar sessões do Claude Code, reiniciar o servidor MCP ou retomar o trabalho após compactação de contexto.
Suporte a Linguagens
| Linguagem | Método | Extrai |
|---|---|---|
Python (.py) | Parsing de AST | Funções, classes, métodos, imports, grafo de dependências |
TypeScript/JS (.ts, .tsx, .js, .jsx) | Baseado em regex | Funções, arrow functions, classes, interfaces, type aliases, imports |
Go (.go) | Baseado em regex | Funções, métodos (baseados em receiver), structs, interfaces, type aliases, imports, comentários de documentação |
Rust (.rs) | Baseado em regex | Funções (pub/async/const/unsafe), structs, enums, traits, blocos impl, declarações use, atributos, comentários de documentação, macro_rules |
C# (.cs) | Baseado em regex | Classes, interfaces, structs, enums, records, métodos, construtores, diretivas using, [Attributes], comentários de documentação XML /// |
Markdown/Texto (.md, .txt, .rst) | Detecção de cabeçalhos | Seções (cabeçalhos #, sublinhados, numerados, TODAS EM MAIÚSCULAS) |
| Outros | Genérico | Apenas contagem de linhas |
Instalação
pip install "mcp-codebase-index[mcp]"
O extra [mcp] inclui a dependência do servidor MCP. Omita-o se você precisar apenas da API programática.
Para desenvolvimento (a partir de um clone local):
pip install -e ".[dev,mcp]"
Servidor MCP
Execução
# As a console script
PROJECT_ROOT=/path/to/project mcp-codebase-index
# As a Python module
PROJECT_ROOT=/path/to/project python -m mcp_codebase_index.server
PROJECT_ROOT especifica qual diretório indexar. O padrão é o diretório de trabalho atual.
Cache Persistente
Em repositórios git, o servidor armazena automaticamente o índice em .codebase-index-cache.pkl na raiz do projeto. Na inicialização:
- Cache hit (correspondência exata): Se a referência git em cache corresponder ao HEAD atual, o índice é carregado instantaneamente do disco — sem parsing, sem varredura de arquivos.
- Cache hit (changeset pequeno): Se ≤20 arquivos foram alterados desde a referência em cache, o índice em cache é carregado e atualizado incrementalmente na primeira consulta.
- Cache miss: Se o changeset for grande ou não houver cache, uma reconstrução completa é executada e um novo cache é salvo.
Adicione .codebase-index-cache.pkl ao seu .gitignore — é um artefato de build apenas local.
Configuração com OpenClaw
Instale o pacote na máquina onde o OpenClaw está sendo executado:
# Local install
pip install "mcp-codebase-index[mcp]"
# Or inside a Docker container / remote VPS
docker exec -it openclaw bash
pip install "mcp-codebase-index[mcp]"
Adicione o servidor MCP à configuração do agente OpenClaw (openclaw.json):
{
"agents": {
"list": [{
"id": "main",
"mcp": {
"servers": [
{
"name": "codebase-index",
"command": "mcp-codebase-index",
"env": {
"PROJECT_ROOT": "/path/to/project"
}
}
]
}
}]
}
}
Reinicie o OpenClaw e verifique a conexão:
openclaw mcp list
Todas as 18 ferramentas estarão disponíveis para o seu agente.
Nota de desempenho: O servidor detecta automaticamente alterações de arquivos via git diff antes de cada consulta (~1-2ms) e reindexa incrementalmente apenas o que mudou. No entanto, a integração MCP padrão do OpenClaw via mcporter cria um novo processo de servidor a cada chamada de ferramenta, o que descarta o índice em memória e força uma reconstrução completa a cada vez (~1-2s para projetos pequenos, mais para projetos grandes). Com o cache persistente, esses cold starts agora são significativamente mais rápidos — o servidor carrega do cache em disco em vez de reanalisar todo o codebase. Para conexões persistentes (evitando até mesmo a sobrecarga de carregamento do cache), use o plugin openclaw-mcp-adapter, que conecta uma vez na inicialização e mantém o servidor em execução:
pip install openclaw-mcp-adapter
Configuração com Claude Code
Adicione ao .mcp.json do seu projeto:
{
"mcpServers": {
"codebase-index": {
"command": "mcp-codebase-index",
"env": {
"PROJECT_ROOT": "/path/to/project"
}
}
}
}
Ou usando o módulo Python diretamente (útil se instalado em um virtualenv):
{
"mcpServers": {
"codebase-index": {
"command": "/path/to/.venv/bin/python3",
"args": ["-m", "mcp_codebase_index.server"],
"env": {
"PROJECT_ROOT": "/path/to/project"
}
}
}
}
Reforçando o Uso das Ferramentas com Hooks
O Claude Code tende a usar por padrão as ferramentas integradas Glob/Grep/Read mesmo quando o codebase-index está disponível. Além das instruções no CLAUDE.md (veja abaixo), você pode adicionar hooks que disparam a cada prompt para reforçar o comportamento. Adicione isso ao .claude/settings.local.json:
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "echo 'CRITICAL REMINDER: Use codebase-index MCP tools FIRST for ALL code navigation (find_symbol, get_function_source, search_codebase, get_dependencies, etc). Only fall back to Glob/Grep/Read for non-code files.'"
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "echo 'Use codebase-index MCP tools first for code navigation.'"
}
]
}
]
}
}
O stdout do hook é injetado como contexto que o Claude vê antes de responder. SessionStart dispara na inicialização, retomada e compactação de contexto. UserPromptSubmit dispara a cada turno.
Importante: Faça a IA Realmente Usar as Ferramentas Indexadas
Por padrão, assistentes de IA ignoram as ferramentas indexadas e recorrem à leitura de arquivos inteiros com Glob/Grep/Read. Linguagem suave como "prefira" acaba sendo racionalizada e ignorada. Adicione isso ao CLAUDE.md do seu projeto (ou arquivo de instruções equivalente) com linguagem obrigatória:
## Codebase Navigation — MANDATORY
You MUST use codebase-index MCP tools FIRST when exploring or navigating the codebase. This is not optional.
- ALWAYS start with: get_project_summary, find_symbol, get_function_source, get_class_source,
get_structure_summary, get_dependencies, get_dependents, get_change_impact, get_call_chain, search_codebase
- Only fall back to Read/Glob/Grep when codebase-index tools genuinely don't have what you need
(e.g. reading non-code files, config, frontmatter)
- If you catch yourself reaching for Glob/Grep/Read to find or understand code, STOP and use
codebase-index instead
A palavra "prefira" é fraca demais — os modelos a tratam como sugestão e recorrem às ferramentas familiares. Linguagem obrigatória com critérios explícitos de fallback é o que realmente muda o comportamento.
Ferramentas Disponíveis (18)
| Ferramenta | Descrição |
|---|---|
get_project_summary | Contagem de arquivos, pacotes, principais classes/funções |
list_files | Lista arquivos indexados com filtro glob opcional |
get_structure_summary | Estrutura de um arquivo ou do projeto inteiro |
get_functions | Lista funções com nome, linhas, parâmetros |
get_classes | Lista classes com nome, linhas, métodos, bases |
get_imports | Lista imports com módulo, nomes, linha |
get_function_source | Código-fonte completo de uma função/método |
get_class_source | Código-fonte completo de uma classe |
find_symbol | Encontra onde um símbolo é definido (arquivo, linha, tipo) |
get_dependencies | O que um símbolo chama/usa |
get_dependents | O que chama/usa um símbolo |
get_change_impact | Dependentes diretos + transitivos |
get_call_chain | Caminho de dependência mais curto (BFS) |
get_file_dependencies | Arquivos importados por um determinado arquivo |
get_file_dependents | Arquivos que importam de um determinado arquivo |
search_codebase | Busca por regex em todos os arquivos (máx. 100 resultados) |
reindex | Força reindexação completa (raramente necessário — atualizações incrementais acontecem automaticamente em repositórios git) |
get_usage_stats | Estatísticas de eficiência da sessão: chamadas de ferramentas, caracteres retornados vs. fonte total, economia estimada de tokens |
Benchmarks
Testado em quatro projetos reais em um MacBook Pro com chip M-series, de um projeto pequeno ao próprio CPython (1,1 milhão de linhas):
Desempenho de Build do Índice
| Projeto | Arquivos | Linhas | Funções | Classes | Tempo de Indexação | Pico de Memória |
|---|---|---|---|---|---|---|
| RMLPlus | 36 | 7.762 | 237 | 55 | 0,9s | 2,4 MB |
| FastAPI | 2.556 | 332.160 | 4.139 | 617 | 5,7s | 55 MB |
| Django | 3.714 | 707.493 | 29.995 | 7.371 | 36,2s | 126 MB |
| CPython | 2.464 | 1.115.334 | 59.620 | 9.037 | 55,9s | 197 MB |
Com o cache persistente, inicializações subsequentes ignoram completamente o build completo. O tempo de carregamento do cache é desprezível em comparação com o parsing — um cache hit no CPython restaura o índice completo em menos de um segundo, em vez de 56s.
Tamanho da Resposta de Consulta vs. Fonte Total
Consultando o CPython — 41 milhões de caracteres de código-fonte:
| Consulta | Resposta | Fonte Total | Redução |
|---|---|---|---|
find_symbol("TestCase") | 67 caracteres | 41.077.561 caracteres | 99,9998% |
get_dependencies("compile") | 115 caracteres | 41.077.561 caracteres | 99,9997% |
get_change_impact("TestCase") | 16.812 caracteres | 41.077.561 caracteres | 99,96% |
get_function_source("compile") | 4.531 caracteres | 41.077.561 caracteres | 99,99% |
get_function_source("run_unittest") | 439 caracteres | 41.077.561 caracteres | 99,999% |
find_symbol retorna 54-67 caracteres independentemente de o projeto ter 7K linhas ou 1,1M de linhas. O tamanho da resposta escala com a resposta, não com o codebase.
get_change_impact("TestCase") no CPython encontrou 154 dependentes diretos e 492 dependentes transitivos em 0,45ms — o tipo de consulta que é impossível sem um grafo de dependências. Use max_direct e max_transitive para limitar a saída ao seu orçamento de tokens.
Tempo de Resposta de Consulta
Todas as consultas direcionadas retornam em tempo submilissegundo, mesmo no CPython com 1,1M de linhas:
| Consulta | RMLPlus | FastAPI | Django | CPython |
|---|---|---|---|---|
find_symbol | 0,01ms | 0,01ms | 0,03ms | 0,08ms |
get_dependencies | 0,00ms | 0,00ms | 0,00ms | 0,01ms |
get_change_impact | 0,02ms | 0,00ms | 2,81ms | 0,45ms |
get_function_source | 0,01ms | 0,02ms | 0,03ms | 0,10ms |
Execute os benchmarks você mesmo: python benchmarks/benchmark.py
Em Que Isso Difere do LSP?
O LSP responde "onde está esta função?" — o mcp-codebase-index responde "o que acontece se eu alterá-la?" O LSP é feito de consultas pontuais: um símbolo, um arquivo, uma posição. Ele pode dizer onde LLMClient é definido e quem o referencia. Mas pergunte "o que quebra transitivamente se eu refatorar LLMClient?" e o LSP não tem resposta. Esta ferramenta retorna 11 dependentes diretos e 31 impactos transitivos em uma única chamada — 204 caracteres. Para obter a mesma resposta do LSP, a IA precisaria encadear dezenas de chamadas recursivas de find-reference, lendo arquivos a cada etapa, queimando milhares de tokens para reconstruir o que o grafo de dependências já sabe.
O LSP também exige que você instale um language server separado para cada linguagem do seu projeto — pyright para Python, vtsls para TypeScript, gopls para Go. Cada um é um binário pesado com suas próprias dependências e configuração. O mcp-codebase-index tem zero dependências, lida com Python + TypeScript/JS + Go + Rust + C# + Markdown prontamente, e cada resposta tem controles integrados de orçamento de tokens (max_results, max_lines). O LSP foi construído para IDEs. Esta ferramenta foi construída para IA.
Uso Programático
from mcp_codebase_index.project_indexer import ProjectIndexer
from mcp_codebase_index.query_api import create_project_query_functions
indexer = ProjectIndexer("/path/to/project", include_patterns=["**/*.py"])
index = indexer.index()
query_funcs = create_project_query_functions(index)
# Use query functions
print(query_funcs["get_project_summary"]())
print(query_funcs["find_symbol"]("MyClass"))
print(query_funcs["get_change_impact"]("some_function"))
Desenvolvimento
pip install -e ".[dev,mcp]"
pytest tests/ -v
ruff check src/ tests/
Referências
O indexador estrutural foi originalmente desenvolvido como parte do projeto RMLPlus, uma implementação do framework Recursive Language Models.
Licença
Este projeto é licenciado duplamente:
- AGPL-3.0 para uso open-source — veja LICENSE
- Licença Comercial para uso proprietário — veja COMMERCIAL-LICENSE.md
Se você está usando o mcp-codebase-index como um servidor MCP autônomo para desenvolvimento, a licença AGPL-3.0 se aplica sem custo. Se você está incorporando-o em um produto proprietário ou oferecendo-o como parte de um serviço hospedado, você precisará de uma licença comercial. Veja COMMERCIAL-LICENSE.md para detalhes.