mcp-codebase-index
Indexador estructural de base de código
Documentación
mcp-codebase-index
Un indexador estructural de codebases con un servidor MCP para desarrollo asistido por IA. Cero dependencias en tiempo de ejecución: utiliza el módulo ast de Python para el análisis de Python y el análisis basado en expresiones regulares para TypeScript/JS, Go, Rust y C#. Requiere Python 3.11+.
Qué Hace
Indexa codebases analizando archivos fuente en metadatos estructurales: funciones, clases, importaciones, grafos de dependencias y cadenas de llamadas entre archivos; luego expone 18 herramientas de consulta a través del Model Context Protocol, lo que permite a Claude Code y otros clientes MCP navegar por los codebases de manera eficiente sin leer archivos completos.
Re-indexación incremental automática: En repositorios git, el índice se mantiene actualizado automáticamente. Antes de cada consulta, el servidor verifica git diff y git status (~1-2 ms). Si los archivos cambiaron, solo esos archivos se vuelven a analizar y se reconstruye el grafo de dependencias. No es necesario llamar manualmente a reindex después de ediciones, cambios de rama o pulls.
Caché persistente en disco: El índice se guarda en un archivo de caché pickle (.codebase-index-cache.pkl) después de cada compilación. En los inicios posteriores del servidor, la caché se carga y se valida contra el HEAD actual del git; si la referencia coincide, el inicio es instantáneo. Si un pequeño número de archivos cambió (≤20), la caché indexada se carga y se actualiza incrementalmente en lugar de reconstruirse desde cero. Esto elimina la penalización de arranque en frío al reiniciar sesiones de Claude Code, reiniciar el servidor MCP o reanudar el trabajo después de la compactación de contexto.
Soporte de Lenguajes
| Lenguaje | Método | Extrae |
|---|---|---|
Python (.py) | Análisis AST | Funciones, clases, métodos, importaciones, grafo de dependencias |
TypeScript/JS (.ts, .tsx, .js, .jsx) | Basado en expresiones regulares | Funciones, funciones flecha, clases, interfaces, alias de tipos, importaciones |
Go (.go) | Basado en expresiones regulares | Funciones, métodos (basados en receptor), structs, interfaces, alias de tipos, importaciones, comentarios de documentación |
Rust (.rs) | Basado en expresiones regulares | Funciones (pub/async/const/unsafe), structs, enums, traits, bloques impl, sentencias use, atributos, comentarios de documentación, macro_rules |
C# (.cs) | Basado en expresiones regulares | Clases, interfaces, structs, enums, records, métodos, constructores, directivas using, [Attributes], /// comentarios XML de documentación |
Markdown/Texto (.md, .txt, .rst) | Detección de encabezados | Secciones (encabezados #, subrayados, numerados, TODO EN MAYÚSCULAS) |
| Otros | Genérico | Solo recuento de líneas |
Instalación
pip install "mcp-codebase-index[mcp]"
El extra [mcp] incluye la dependencia del servidor MCP. Omítelo si solo necesitas la API programática.
Para desarrollo (desde un clon local):
pip install -e ".[dev,mcp]"
Servidor MCP
Ejecución
# 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 qué directorio indexar. Por defecto, el directorio de trabajo actual.
Caché Persistente
En repositorios git, el servidor guarda automáticamente el índice en .codebase-index-cache.pkl en la raíz del proyecto. Al iniciar:
- Acierto de caché (coincidencia exacta): Si la referencia git en caché coincide con el HEAD actual, el índice se carga al instante desde el disco — sin análisis, sin recorrido de archivos.
- Acierto de caché (cambios pequeños): Si ≤20 archivos cambiaron desde la referencia en caché, el índice en caché se carga y se actualiza incrementalmente en la primera consulta.
- Fallo de caché: Si el conjunto de cambios es grande o no existe caché, se ejecuta una reconstrucción completa y se guarda una nueva caché.
Añade .codebase-index-cache.pkl a tu .gitignore — es un artefacto de compilación solo local.
Configuración con OpenClaw
Instala el paquete en la máquina donde se ejecuta OpenClaw:
# 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]"
Añade el servidor MCP a la configuración de tu agente OpenClaw (openclaw.json):
{
"agents": {
"list": [{
"id": "main",
"mcp": {
"servers": [
{
"name": "codebase-index",
"command": "mcp-codebase-index",
"env": {
"PROJECT_ROOT": "/path/to/project"
}
}
]
}
}]
}
}
Reinicia OpenClaw y verifica la conexión:
openclaw mcp list
Las 18 herramientas estarán disponibles para tu agente.
Nota de rendimiento: El servidor detecta automáticamente los cambios de archivos mediante git diff antes de cada consulta (~1-2 ms) y re-indexa incrementalmente solo lo que cambió. Sin embargo, la integración MCP predeterminada de OpenClaw a través de mcporter genera un proceso de servidor nuevo por cada llamada de herramienta, lo que descarta el índice en memoria y fuerza una reconstrucción completa cada vez (~1-2 s para proyectos pequeños, más para grandes). Con la caché persistente, estos arranques en frío son ahora significativamente más rápidos: el servidor carga desde la caché de disco en lugar de re-analizar todo el codebase. Para conexiones persistentes (evitando incluso la sobrecarga de carga de caché), usa el plugin openclaw-mcp-adapter, que se conecta una vez al inicio y mantiene el servidor en ejecución:
pip install openclaw-mcp-adapter
Configuración con Claude Code
Añade a .mcp.json de tu proyecto:
{
"mcpServers": {
"codebase-index": {
"command": "mcp-codebase-index",
"env": {
"PROJECT_ROOT": "/path/to/project"
}
}
}
}
O usando el módulo de Python directamente (útil si está instalado en un virtualenv):
{
"mcpServers": {
"codebase-index": {
"command": "/path/to/.venv/bin/python3",
"args": ["-m", "mcp_codebase_index.server"],
"env": {
"PROJECT_ROOT": "/path/to/project"
}
}
}
}
Reforzando el Uso de Herramientas con Hooks
Claude Code tiende a usar por defecto las herramientas integradas Glob/Grep/Read incluso cuando codebase-index está disponible. Además de las instrucciones de CLAUDE.md (ver más abajo), puedes añadir hooks que se activen en cada prompt para reforzar el comportamiento. Añade esto a .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.'"
}
]
}
]
}
}
El stdout del hook se inyecta como contexto que Claude ve antes de responder. SessionStart se activa al inicio, al reanudar y en la compactación de contexto. UserPromptSubmit se activa en cada turno.
Importante: Haz que la IA Use Realmente las Herramientas Indexadas
Por defecto, los asistentes de IA ignorarán las herramientas indexadas y volverán a leer archivos completos con Glob/Grep/Read. El lenguaje suave como "preferir" se racionaliza. Añade esto a CLAUDE.md de tu proyecto (o archivo de instrucciones equivalente) con lenguaje obligatorio:
## 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
La palabra "preferir" es demasiado débil: los modelos la tratan como una sugerencia y usan por defecto herramientas familiares. El lenguaje obligatorio con criterios explícitos de respaldo es lo que realmente cambia el comportamiento.
Herramientas Disponibles (18)
| Herramienta | Descripción |
|---|---|
get_project_summary | Recuento de archivos, paquetes, principales clases/funciones |
list_files | Lista archivos indexados con filtro glob opcional |
get_structure_summary | Estructura de un archivo o de todo el proyecto |
get_functions | Lista funciones con nombre, líneas, parámetros |
get_classes | Lista clases con nombre, líneas, métodos, bases |
get_imports | Lista importaciones con módulo, nombres, línea |
get_function_source | Código fuente completo de una función/método |
get_class_source | Código fuente completo de una clase |
find_symbol | Encuentra dónde se define un símbolo (archivo, línea, tipo) |
get_dependencies | Qué llama/usa un símbolo |
get_dependents | Qué llama/usa a un símbolo |
get_change_impact | Dependientes directos + transitivos |
get_call_chain | Ruta de dependencia más corta (BFS) |
get_file_dependencies | Archivos importados por un archivo dado |
get_file_dependents | Archivos que importan desde un archivo dado |
search_codebase | Búsqueda de expresiones regulares en todos los archivos (máx. 100 resultados) |
reindex | Forzar re-indexación completa (rara vez necesario: las actualizaciones incrementales ocurren automáticamente en repos git) |
get_usage_stats | Estadísticas de eficiencia de sesión: llamadas a herramientas, caracteres devueltos vs fuente total, ahorro estimado de tokens |
Benchmarks
Probado en cuatro proyectos reales en un MacBook Pro con chip de la serie M, desde un proyecto pequeño hasta el propio CPython (1,1 millones de líneas):
Rendimiento de Construcción del Índice
| Proyecto | Archivos | Líneas | Funciones | Clases | Tiempo de Índice | Memoria Pico |
|---|---|---|---|---|---|---|
| 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 |
Con la caché persistente, los inicios posteriores omiten por completo la construcción completa. El tiempo de carga de la caché es insignificante en comparación con el análisis: un acierto de caché en CPython restaura el índice completo en menos de un segundo en lugar de 56 s.
Tamaño de Respuesta de Consulta vs Fuente Total
Consultando CPython — 41 millones de caracteres de código fuente:
| Consulta | Respuesta | Fuente Total | Reducción |
|---|---|---|---|
find_symbol("TestCase") | 67 chars | 41,077,561 chars | 99.9998% |
get_dependencies("compile") | 115 chars | 41,077,561 chars | 99.9997% |
get_change_impact("TestCase") | 16,812 chars | 41,077,561 chars | 99.96% |
get_function_source("compile") | 4,531 chars | 41,077,561 chars | 99.99% |
get_function_source("run_unittest") | 439 chars | 41,077,561 chars | 99.999% |
find_symbol devuelve 54-67 caracteres independientemente de si el proyecto tiene 7K líneas o 1,1M de líneas. El tamaño de la respuesta escala con la respuesta, no con el codebase.
get_change_impact("TestCase") en CPython encontró 154 dependientes directos y 492 dependientes transitivos en 0,45 ms — el tipo de consulta que es imposible sin un grafo de dependencias. Usa max_direct y max_transitive para limitar la salida a tu presupuesto de tokens.
Tiempo de Respuesta de Consulta
Todas las consultas específicas devuelven en tiempo sub-milisegundo, incluso en las 1,1M de líneas de CPython:
| 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 |
Ejecuta los benchmarks tú mismo: python benchmarks/benchmark.py
¿En Qué se Diferencia de LSP?
LSP responde "¿dónde está esta función?" — mcp-codebase-index responde "¿qué pasa si la cambio?" LSP es consultas puntuales: un símbolo, un archivo, una posición. Puede decirte dónde se define LLMClient y quién lo referencia. Pero pregunta "¿qué se rompe transitivamente si refactorizo LLMClient?" y LSP no tiene nada. Esta herramienta devuelve 11 dependientes directos y 31 impactos transitivos en una sola llamada — 204 caracteres. Para obtener la misma respuesta de LSP, la IA tendría que encadenar docenas de llamadas de búsqueda de referencias recursivamente, leyendo archivos en cada paso, quemando miles de tokens para reconstruir lo que el grafo de dependencias ya sabe.
LSP también requiere instalar un servidor de lenguaje separado para cada lenguaje en tu proyecto: pyright para Python, vtsls para TypeScript, gopls para Go. Cada uno es un binario pesado con sus propias dependencias y configuración. mcp-codebase-index tiene cero dependencias, maneja Python + TypeScript/JS + Go + Rust + C# + Markdown de fábrica, y cada respuesta tiene controles integrados de presupuesto de tokens (max_results, max_lines). LSP fue construido para IDEs. Esto fue construido 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"))
Desarrollo
pip install -e ".[dev,mcp]"
pytest tests/ -v
ruff check src/ tests/
Referencias
El indexador estructural fue desarrollado originalmente como parte del proyecto RMLPlus, una implementación del framework Recursive Language Models.
Licencia
Este proyecto tiene doble licencia:
- AGPL-3.0 para uso de código abierto — ver LICENSE
- Licencia Comercial para uso propietario — ver COMMERCIAL-LICENSE.md
Si estás usando mcp-codebase-index como un servidor MCP independiente para desarrollo, la licencia AGPL-3.0 se aplica sin costo. Si lo estás integrando en un producto propietario u ofreciéndolo como parte de un servicio alojado, necesitarás una licencia comercial. Ver COMMERCIAL-LICENSE.md para más detalles.