Skip to main content
Glama

mcp-project-helper

Servidor MCP (Model Context Protocol) mínimo que proporciona al asistente de IA para programación —en particular, Claude Code— un conjunto pequeño y seguro de herramientas (tools) para trabajar con una única directorio concreto del proyecto: búsqueda en sus archivos, lectura de archivos, búsqueda en la documentación local y ejecución de una verificación previamente aprobada (tests).

El proyecto se ha implementado por etapas (Stage 0 → Stage 3, el historial de prompts está en PROMPTS.md); la etapa actual es Stage 3: finalización. Las cuatro tools están implementadas y cubiertas por tests (Stage 1), el servidor está conectado a Claude Code y verificado manualmente con solicitudes reales a través de Claude Code CLI (Stage 2–3, evidencia en evidence/).

Sobre el proyecto

En lugar de dar al asistente acceso directo al shell o acceso ilimitado al sistema de archivos, el proyecto proporciona una superficie estrecha y fácilmente auditable de cuatro tools:

  • search_project_files — búsqueda de texto, limitada a la raíz del proyecto.

  • read_project_file — lectura de un único archivo, limitada a la raíz del proyecto.

  • get_docs — búsqueda en la documentación local en docs/ de este repositorio.

  • run_project_check — ejecución de una verificación de la lista blanca (actualmente tests), pero nunca un comando de shell arbitrario.

Es un proyecto educativo (tarea) — cuyo objetivo no es cubrir todos los posibles casos de uso, sino mostrar un ejemplo de extremo a extremo, honestamente documentado, de un servidor MCP: desde el esqueleto y los primitivos de seguridad (Stage 0), pasando por la implementación real de las tools (Stage 1), hasta la integración con el agente del IDE y evidencia reproducible de llamadas reales (Stage 2–3).

Related MCP server: GPT Commander

Qué es MCP y cómo funciona la conexión del agente

MCP (Model Context Protocol) — un protocolo abierto basado en JSON-RPC que describe cómo un asistente de IA (cliente/host, por ejemplo Claude Code) descubre e invoca herramientas externas (tools) proporcionadas por un proceso separado (servidor MCP), sin que el asistente tenga acceso directo al shell, la red o el sistema de archivos del host.

En este proyecto se utiliza el transporte stdio — la forma más simple y más común para herramientas locales:

  1. El host (Claude Code) lee su configuración MCP (.mcp.json) y lanza el servidor como un subproceso local normal, con el comando/argumentos especificados y las variables de entorno.

  2. El host y el servidor intercambian mensajes JSON-RPC a través de stdin/stdout de ese subproceso (de ahí el requisito de que stdout está reservado solo para el protocolo — ver la sección "Registro y depuración").

  3. El host llama a initialize() — el servidor responde con su nombre/versión (mcp-project-helper 0.1.0) y sus capacidades.

  4. El host llama a list_tools() — el servidor devuelve la lista de tools registradas con su nombre, descripción y JSON Schema de los parámetros de entrada (inputSchema), generada por el MCP SDK a partir de la firma de la función.

  5. Cuando el usuario (o el propio modelo) decide invocar una de las tools, el host envía call_tool(name, arguments); el servidor ejecuta la función Python correspondiente y devuelve un resultado estructurado (ver "Contrato de salida de las tools" más abajo) o un error a nivel de tool.

  6. No se abre ningún puerto de red: el ciclo de vida del servidor está completamente vinculado al subproceso lanzado por el host — si el host cierra la conexión, el subproceso termina.

Aquí no hay llamadas a ninguna API de LLM/IA (OpenAI, Anthropic, etc.): este servidor solo proporciona tools que invoca el cliente (Claude Code); la "búsqueda" en get_docs es una simple coincidencia determinista de subcadenas sobre secciones de Markdown, sin embeddings/base de datos vectorial. Para ejecutar el servidor no se necesita ninguna clave de API.

Qué se considera tool en este servidor

Tool — es una función Python normal, decorada con @mcp.tool(), que acepta argumentos serializables a JSON y devuelve dict[str, Any]. El MCP SDK automáticamente:

  • genera inputSchema (JSON Schema) a partir de la firma y las anotaciones de tipos de los argumentos de la función — no es necesario describir ese esquema manualmente en ningún sitio;

  • convierte la anotación del valor de retorno -> dict[str, Any] en una salida estructurada de la tool (outputSchema/structuredContent), ver "Contrato de salida de las tools" más abajo;

  • convierte una excepción Python no manejada dentro de la función de la tool en un resultado estructurado con error a nivel de tool (CallToolResult.is_error = True), sin derribar la propia sesión MCP.

Las cuatro registraciones están juntas en server.py:37-58; cada una es un envoltorio fino orientado a MCP (cuyo docstring se convierte en la descripción de la tool visible para el modelo) que delega la llamada a la implementación real en tools/*.py, separando la firma a nivel de protocolo de la lógica.

Stack

  • Python 3.14 (requires-python = ">=3.10" en pyproject.toml — este es el límite inferior real del MCP SDK utilizado, no una afirmación de que solo funciona con 3.14).

  • MCP Python SDK oficial (paquete mcp, versión instalada 2.0.0) — proporciona el framework del servidor (mcp.server.MCPServer), el registro de tools (@mcp.tool()) y el transporte stdio (mcp.run(transport="stdio")).

  • pytest — única dependencia de desarrollo, para el conjunto de tests.

  • No hay integración con API de LLM/IA ni transporte de red (HTTP/SSE no está configurado) — ver la sección anterior.

Arquitectura

src/mcp_project_helper/
  server.py        точка входа: создаёт MCPServer, регистрирует tools, запускает stdio
  config.py        корень проекта / корень docs / настройки логирования / whitelist проверок / лимиты
  security.py      resolve_within_root() — единый шлюз ограничения путей
  logging_setup.py логирование в stderr (+ опционально файл), не затрагивая stdout
  tools/
    search_project_files.py   поиск текста в пределах корня проекта
    read_project_file.py      чтение одного файла в пределах корня проекта
    get_docs.py                поиск по секциям markdown в docs/
    run_project_check.py       запуск подпроцесса из белого списка

Cada tool que trabaja con archivos pasa por security.resolve_within_root(root, relative_path) antes de abrir cualquier ruta. config.py define la raíz del proyecto a partir de la variable de entorno MCP_PROJECT_HELPER_ROOT (por defecto ./demo_project), por lo que el servidor puede apuntarse a cualquier proyecto sin cambiar el código.

Tools MCP implementadas

search_project_files(query, path=".", max_results=50)

Busca recursivamente en los archivos de texto bajo path (relativo a la raíz del proyecto; por defecto — toda la raíz) la coincidencia exacta de la subcadena query. Omite los directorios de config.IGNORED_DIR_NAMES (.git, .venv, __pycache__, node_modules, ...) y cualquier directorio *.egg-info. Los archivos se comprueban por contenido binario (byte NUL o UTF-8 no válido en los primeros 4 KB) y se omiten silenciosamente, en lugar de provocar un error. Nunca sigue enlaces simbólicos a directorios o archivos fuera de la raíz — cada ruta candidata se comprueba adicionalmente mediante resolve_within_root, además del comportamiento estándar de os.walk, que no sigue enlaces simbólicos a directorios.

max_results está limitado superiormente por config.SEARCH_RESULTS_CAP (200); las líneas coincidentes más largas que config.SEARCH_MAX_LINE_CHARS (300) se truncan; los archivos mayores que config.SEARCH_MAX_FILE_BYTES (2 MB) se omiten, en lugar de escanearse.

Implementación: tools/search_project_files.py:41-130.

read_project_file(path)

Lee un único archivo de texto en la ruta path (relativa a la raíz del proyecto). Rechaza directorios, archivos inexistentes y contenido binario (byte NUL o UTF-8 no válido). El contenido está limitado por config.READ_MAX_FILE_BYTES (200 KB) — los archivos de mayor tamaño se devuelven truncados, en lugar de rechazarse.

Implementación: tools/read_project_file.py:25-69.

get_docs(query=None, max_results=10)

Busca en docs/*.md (recursivamente), divididos en secciones por los encabezados de Markdown. Con query presente, devuelve las secciones cuyo encabezado o cuerpo contienen la subcadena buscada (sin distinguir mayúsculas), cada una con indicación del archivo de origen y el encabezado. Sin query, devuelve una lista de una sección por archivo — un inventario de qué documentación existe. Limitado solo por config.get_docs_root() — nunca por la raíz del proyecto.

max_results está limitado superiormente por config.DOCS_RESULTS_CAP (50); los fragmentos (snippets) están limitados por config.DOCS_MAX_SNIPPET_CHARS (800 caracteres).

Implementación: tools/get_docs.py:58-114.

run_project_check(check_name)

Ejecuta una verificación de la lista blanca. check_name se busca en config.ALLOWED_CHECKS antes de que se ejecute nada — un nombre desconocido provoca inmediatamente un error, y el subproceso nunca se lanza. El argv de la lista blanca se ejecuta mediante subprocess.run(argv, shell=False, cwd=<raíz del proyecto>, timeout=...): sin shell, con directorio de trabajo fijo, y nada de la parte que llama se añade a la línea de comandos.

Implementación: tools/run_project_check.py:32-90.

Lista blanca

ALLOWED_CHECKS = {
    "tests": [sys.executable, "-m", "pytest", "-q"],
}

Definida en config.py:55-57. Se usa sys.executable (y no simplemente la cadena "pytest") para que la verificación se ejecute siempre con el mismo intérprete/entorno que el propio servidor, independientemente de lo que esté primero en PATH. Aquí deliberadamente no hay una entrada lint: en este repositorio no hay dependencia ni configuración de ruff, por lo que conectar una verificación "lint" sería o una ficción o un engaño. Se puede añadir más adelante (config.ALLOWED_CHECKS["lint"] = [sys.executable, "-m", "ruff", "check", "."]), cuando ruff se convierta en una dependencia real del proyecto con configuración real — el mecanismo de lista blanca ya lo soporta sin ningún otro cambio de código.

El tiempo de espera (config.CHECK_TIMEOUT_SECONDS, por defecto 60 s) y el límite de volumen de salida (config.CHECK_MAX_OUTPUT_CHARS, por defecto 20 000 caracteres por flujo) se aplican a cada ejecución de verificación.

Contrato de salida de las tools

Cada tool devuelve un dict Python normal desde una función con anotación -> dict[str, Any]; el MCP SDK reconoce automáticamente esto como salida estructurada de la tool (rellena CallToolResult.structured_content y emite outputSchema) — aquí no se serializan manualmente los resultados a una cadena JSON en ningún sitio. Las situaciones de error (entrada incorrecta, salida fuera de la ruta, verificación desconocida, archivo no encontrado, contenido binario, etc.) lanzan una excepción Python, en lugar de devolver un dict; el SDK convierte automáticamente esto en un resultado con error a nivel de tool (CallToolResult.is_error = True). La única excepción es el tiempo de espera de la verificación: es un resultado legítimo de la ejecución de una verificación lanzada con éxito, no un error de datos de entrada, por lo que se devuelve como un dict estructurado {"status": "error", ...}, en lugar de lanzar una excepción.

search_project_files

{
  "status": "success",
  "query": "apply_discount",
  "path": ".",
  "matches": [
    {"file": "demo_app/services.py", "line": 12, "text": "def apply_discount(order: Order, percent: float) -> float:"}
  ],
  "count": 4,
  "truncated": false
}

read_project_file

{
  "status": "success",
  "file": "demo_app/models.py",
  "content": "...",
  "size": 397,
  "truncated": false
}

get_docs

{
  "status": "success",
  "query": "whitelist",
  "results": [
    {"file": "architecture.md", "heading": "Whitelist", "snippet": "..."}
  ],
  "count": 1,
  "truncated": false
}

run_project_check

{
  "status": "success",
  "check_name": "tests",
  "exit_code": 0,
  "stdout": "...",
  "stderr": "",
  "truncated": false
}

En caso de tiempo de espera: {"status": "error", "check_name": ..., "error": "check timed out after 60s", "exit_code": null, "stdout": "...", "stderr": "...", "truncated": ...}.

Los nombres de los campos y las convenciones status/count/truncated anteriores se consideran un contrato estable para el futuro, no un detalle de implementación.

Limitaciones de seguridad

  • Limitación de rutas: security.resolve_within_root (security.py:19-50) rechaza rutas absolutas, el ascenso mediante .. (a cualquier profundidad), los bytes NUL y los enlaces simbólicos que apunten fuera de la raíz configurada. Se usa en read_project_file y search_project_files relativo a la raíz del proyecto, y de nuevo en search_project_files para cada archivo candidato durante el recorrido. Está cubierto por unit tests en tests/test_security.py y confirmado manualmente con una prueba negativa real mediante Claude Code (ver "Resultados de la verificación" más abajo, prueba 6).

  • Sin salida de la raíz mediante enlaces simbólicos durante el recorrido: search_project_files y get_docs nunca siguen enlaces simbólicos a directorios (comportamiento predeterminado de os.walk) y omiten por completo los enlaces simbólicos a archivos.

  • Sin comandos shell arbitrarios: run_project_check comprueba el nombre de verificación solicitado contra config.ALLOWED_CHECKS (config.py:55-57) antes de que se ejecute nada; los nombres desconocidos se rechazan de inmediato, y la propia verificación se ejecuta mediante subprocess.run(argv, shell=False, ...) con un cwd fijo y sin ningún argumento añadido por la parte que invoca.

  • Salida limitada en todas partes: cada tool limita el volumen de datos devueltos: max_results + límites estrictos para búsqueda y docs, límite de bytes para lectura de archivos, límite de caracteres + tiempo de espera para la salida de la verificación — de modo que ninguna llamada puede devolver un volumen ilimitado de datos ni ejecutarse indefinidamente.

  • stdout permanece limpio: todo el registro va a través de logging_setup.py a stderr (y opcionalmente a un archivo de log); nada en el servidor escribe a stdout, que está reservado para el enmarcado JSON-RPC del protocolo MCP.

  • Sin secretos en los logs: el servidor no acepta en absoluto claves API ni credenciales. Cada llamada real a un tool registra el nombre del tool, sus parámetros de entrada seguros (cadenas de consulta, rutas, nombres de verificación, cantidad/tamaño de resultados — pero nunca el contenido de archivos) y el status=success/status=error final.

Registro y depuración

Cada llamada real a un tool registra una línea a través del logger común mcp_project_helper (stderr, más un archivo opcional mediante MCP_PROJECT_HELPER_LOG_FILE), por ejemplo (líneas reales de evidence/tool-calls.log):

INFO mcp_project_helper: tool=search_project_files query='apply_discount' path='.' max_results=50 matches=4 truncated=False status=success
INFO mcp_project_helper: tool=read_project_file path='demo_app/models.py' size=397 truncated=False status=success
INFO mcp_project_helper: tool=run_project_check check_name='tests' exit_code=0 status=success
INFO mcp_project_helper: tool=read_project_file path='../../../../etc/passwd' status=error

El contenido de los archivos nunca se registra — solo metadatos de la llamada (rutas, cadenas de consulta, tamaños, cantidades, códigos de salida). La configuración del registro es logging_setup.py:20-42.

Para depurar:

  • El nivel de registro se ajusta con MCP_PROJECT_HELPER_LOG_LEVEL (DEBUG, INFO, WARNING, ERROR, CRITICAL; por defecto INFO).

  • El archivo de log se define con MCP_PROJECT_HELPER_LOG_FILE; por defecto (sin esta variable) se escribe solo a stderr. Al iniciarse desde Claude Code (.mcp.json) apunta a evidence/tool-calls.log.

  • Nunca use print() en el código del servidor — stdout está reservado para el protocolo JSON-RPC; cualquier salida extra a stdout rompe el transporte stdio.

  • Para ver qué llamadas ocurrieron realmente en la sesión actual de Claude Code, abra el archivo al que apunta MCP_PROJECT_HELPER_LOG_FILE (evidence/tool-calls.log), o ejecute el servidor manualmente (python -m mcp_project_helper.server) y observe stderr.

Instalación

python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

La única dependencia en tiempo de ejecución es el paquete mcp; pytest es una dependencia solo para desarrollo/pruebas (ambas fijadas en pyproject.toml).

Configuración del entorno

La configuración se define mediante variables de entorno — copie .env.example a .env y modifique los valores si es necesario:

Variable

Propósito

Valor predeterminado

MCP_PROJECT_HELPER_ROOT

El único directorio al que tienen acceso las herramientas de archivos (search_project_files, read_project_file, get_docs — solo a su docs/; get_docs opera desde la raíz del repositorio, no desde MCP_PROJECT_HELPER_ROOT).

./demo_project

MCP_PROJECT_HELPER_LOG_FILE

Ruta al archivo de log (ver "Registro y depuración"). Los logs siempre van también a stderr.

no definido (solo stderr)

MCP_PROJECT_HELPER_LOG_LEVEL

Uno de DEBUG/INFO/WARNING/ERROR/CRITICAL.

INFO

El servidor no necesita secretos (claves API, tokens) — .env.example contiene solo ejemplos seguros de rutas y nivel de registro, y .env es ignorado por git (ver "Estructura del proyecto" más abajo).

Ejecución del servidor MCP

Ejecutar el servidor directamente (permanecerá esperando al cliente en stdin — esto es normal para servidores MCP con transporte stdio; salir con Ctrl+C):

python -m mcp_project_helper.server

Ejecutar la suite de pruebas:

pytest -q

Ejecutar directamente las pruebas del propio demo-proyecto (lo que por defecto ejecuta run_project_check("tests"), ya que MCP_PROJECT_HELPER_ROOT por defecto apunta a demo_project):

cd demo_project && pytest -q

Integración con Claude Code

Este repositorio contiene un archivo project-scoped .mcp.json en la raíz del repositorio: la configuración específicamente para Claude Code (a diferencia de .vscode/mcp.json, una configuración separada del host MCP nativo VS Code; ver la comparación detallada más abajo).

Claude Code detecta .mcp.json al abrir la carpeta del proyecto, inicia el servidor como proceso hijo y se comunica con él mediante JSON-RPC a través de stdio — el mismo transporte utilizado en todas las pruebas automatizadas de este proyecto, solo que iniciado por el propio Claude Code, no por un harness de pruebas.

Escenario end-to-end confirmado: Claude Code CLI → MCP server → custom tools. Las 6 solicitudes de verificación (ver "Resultados de la verificación" más abajo) se ejecutaron realmente a través de Claude Code CLI con este servidor conectado mediante .mcp.json — no solo configuradas, sino realmente invocadas, con capturas de pantalla reales y registros en el log del lado del servidor.

Configuración para Claude Code

.mcp.json:

{
  "mcpServers": {
    "mcp-project-helper": {
      "command": "${CLAUDE_PROJECT_DIR:-.}/.venv/bin/python",
      "args": ["-m", "mcp_project_helper.server"],
      "env": {
        "MCP_PROJECT_HELPER_ROOT": "${CLAUDE_PROJECT_DIR:-.}/demo_project",
        "MCP_PROJECT_HELPER_LOG_FILE": "${CLAUDE_PROJECT_DIR:-.}/evidence/tool-calls.log"
      }
    }
  }
}

${CLAUDE_PROJECT_DIR} es expandido por el propio Claude Code a la ruta absoluta del directorio en el que se clonó el repositorio, por lo que el archivo no contiene rutas específicas de una máquina concreta y no requiere ediciones después de git clone. Se utiliza precisamente la forma con valor de respaldo ${CLAUDE_PROJECT_DIR:-.}, y no el ${CLAUDE_PROJECT_DIR} a secas: sin :-. la variable no se expandía y Claude Code intentaba ejecutar literalmente ${CLAUDE_PROJECT_DIR}/.venv/bin/python como ruta al ejecutable (este error se observó realmente en la primera versión de la configuración de Stage 2, ver REPORT.md). MCP_PROJECT_HELPER_ROOT está definido explícitamente como ${CLAUDE_PROJECT_DIR:-.}/demo_project, para que la raíz del proyecto pasada al servidor no sea ambigua, independientemente del valor predeterminado propio en config.py.

Nota sobre plataformas: .venv/bin/python es la estructura de venv para Unix (macOS/Linux), utilizada en todo este proyecto. En Windows la ruta equivalente es .venv\Scripts\python.exe; para admitir también esa plataforma, .mcp.json habría requerido una segunda entrada específica para Windows (o un script envoltorio) — no se ha hecho, porque el proyecto se desarrolló y verificó solo en macOS.

Configuración para VS Code

Este repositorio también contiene .vscode/mcp.json, una configuración separada de espacio de trabajo para el host MCP integrado de VS Code (utilizado por el modo agéntico de GitHub Copilot Chat):

{
  "servers": {
    "mcp-project-helper": {
      "type": "stdio",
      "command": "${workspaceFolder}/.venv/bin/python",
      "args": ["-m", "mcp_project_helper.server"],
      "env": {
        "MCP_PROJECT_HELPER_ROOT": "${workspaceFolder}/demo_project",
        "MCP_PROJECT_HELPER_LOG_FILE": "${workspaceFolder}/evidence/tool-calls.log"
      }
    }
  }
}

El mismo servidor stdio mcp-project-helper, con MCP_PROJECT_HELPER_ROOT definido como ${workspaceFolder}/demo_project, y MCP_PROJECT_HELPER_LOG_FILE definido como ${workspaceFolder}/evidence/tool-calls.log.

Por qué dos archivos y no uno: .mcp.json y .vscode/mcp.json siguen esquemas diferentes e incompatibles, y sus variables de sustitución de rutas no son intercambiables entre hosts:

  • .mcp.json (configuración de Claude Code) utiliza la clave de nivel superior mcpServers y expande ${CLAUDE_PROJECT_DIR:-.} a la raíz del repositorio.

  • .vscode/mcp.json (configuración del host MCP nativo de VS Code) utiliza la clave de nivel superior servers, el campo explícito "type": "stdio" y expande en su lugar ${workspaceFolder} a la ruta de la carpeta abierta. El host MCP de VS Code no entiende ${CLAUDE_PROJECT_DIR}: al intentar abrir .mcp.json directamente desde VS Code, la variable se pasa literalmente y el servidor no puede iniciarse (spawn ${CLAUDE_PROJECT_DIR}/.venv/bin/python ENOENT) — este es un error realmente observado, que dio origen al .vscode/mcp.json separado. Almacenar la configuración de cada host en su propio archivo, con su propia variable, evita este error y permite utilizar ambas herramientas con el mismo clon sin que una configuración comprometa la sintaxis de la otra.

.vscode/mcp.json es la única excepción a la regla general de ignorar .vscode/* en .gitignore; el resto del estado local de VS Code (settings.local.json, etc.) no se rastrea.

Estado de verificación de VS Code: .vscode/mcp.json es sintáctica y semánticamente correcto (el mismo servidor, el mismo comando/variables de entorno que la configuración de trabajo de Claude Code) y fue validado como JSON. Además, la captura de pantalla real evidence/vscode_mcp_server_connected.png confirma que el host MCP nativo de VS Code realmente inicia el servidor con esta configuración: Starting server mcp-project-helperConnection state: RunningDiscovered 4 tools, con una línea de confirmación del propio registro de stderr del proceso mcp_project_helper en esa misma salida. Esto no es lo mismo que la confirmación de invocación de custom tools a través de la interfaz de VS Code: ningún escenario de usuario (search_project_files, etc.) se ejecutó a través de esa interfaz ni se afirma como verificado. La única integración con IDE confirmada hasta las invocaciones reales de tools por el usuario (capturas de pantalla + logs del lado del servidor para los 6 escenarios) es Claude Code CLI, ver "Resultados de la verificación" más abajo. De forma independiente a ambos: la integración mediante Claude Code Desktop / extensión de Claude Code dentro de VS Code no se probó en esta sesión en absoluto — no debe confundirse ni con el host MCP nativo de VS Code (esta sección), ni con Claude Code CLI.

Cómo habilitar MCP

Brevemente (los detalles — en las subsecciones anteriores):

Claude Code:

  1. Cree un venv e instale las dependencias (sección "Instalación").

  2. Abra la raíz del repositorio en Claude Code (claude desde la raíz del repositorio).

  3. Claude Code detecta .mcp.json y ofrece una vez confirmar la confianza del espacio de trabajo para el servidor mcp-project-helper: confírmelo.

  4. Ejecute /mcp (o claude mcp list en la terminal) y compruebe que mcp-project-helper está conectado con 4 tools.

VS Code (host MCP nativo, modo agéntico de Copilot Chat):

  1. Cree un venv igual que para Claude Code — .vscode/mcp.json espera el mismo .venv/bin/python.

  2. Abra la raíz del repositorio como carpeta en VS Code.

  3. VS Code detecta .vscode/mcp.json y ofrece iniciar el servidor — inícielo/confirme la confianza.

  4. Compruebe el estado mediante MCP: List Servers.

Ambas opciones suponen una estructura Unix de venv (.venv/bin/python); en Windows — .venv\Scripts\python.exe (no configurado, ver arriba).

Consultas de verificación

Seis escenarios ejecutados realmente a través de Claude Code CLI para confirmar la integración (tabla completa con resultados en evidence/README.md):

  1. Busca a través de MCP todos los lugares donde se usa la función apply_discount en demo_project → se espera search_project_files.

  2. Lee a través de MCP el archivo demo_app/models.py y explica brevemente qué modelos están definidos allí → se espera read_project_file.

  3. Usando la documentación MCP del proyecto, cuenta qué limitaciones de seguridad tiene el servidor MCP → se espera get_docs.

  4. Comprueba a través de la herramienta MCP si pasan los tests de demo_project → se espera run_project_check.

  5. Usando solo las herramientas MCP, encuentra en demo_project la implementación de apply_discount, luego lee el archivo donde está definida y explica sus parámetros/retorno/cálculo del descuento → se espera una cadena de dos tools: search_project_files y luego read_project_file.

  6. (prueba negativa / de seguridad) Intenta leer a través de MCP el archivo ../../../../etc/passwd → se espera denegación de read_project_file con un error estructurado (la ruta excede la raíz permitida).

Resultados de la verificación

Las 6 de 6 consultas se completaron con éxito (en la prueba 5, ambas tools esperadas, en el orden correcto; en la prueba 6, el éxito es la denegación esperada). Cada línea está confirmada tanto con una captura de pantalla real como con una línea independiente en evidence/tool-calls.log. La tabla completa está en evidence/README.md; el análisis detallado con enlaces al código y los registros está en REPORT.md.

Tool

Resultado

1

search_project_files

Éxito, 4 coincidencias

2

read_project_file

Éxito, size=397

3

get_docs

Éxito, se encontró la sección «Seguridad»

4

run_project_check

Éxito, exit_code=0, 2/2 tests superados

5

search_project_filesread_project_file

Éxito, cadena de dos tools

6

read_project_file

Denegación exitosa (path traversal bloqueado)

Comprobaciones automatizadas (no sustituyen, sino que complementan las pruebas manuales de IDE anteriores):

  • pytest -q desde la raíz del repositorio — 44 passed.

  • pytest -q dentro de demo_project/2 passed.

  • Handshake stdio programático (initialize() + list_tools()) — el servidor informa mcp-project-helper 0.1.0 y exactamente 4 tools: get_docs, read_project_file, run_project_check, search_project_files.

Estructura del proyecto

mcp-project-helper/
  .mcp.json                конфигурация MCP для Claude Code (project-scoped)
  .vscode/mcp.json          конфигурация MCP для native MCP host VS Code
  .env.example              безопасные примеры переменных окружения (без секретов)
  pyproject.toml            зависимости, entry point, конфигурация pytest
  README.md                 этот файл
  REPORT.md                 итоговый отчёт по всем стадиям, со ссылками файл:строки
  PROMPTS.md                история фактически использованных промптов (Этапы 0-3)
  docs/
    architecture.md          документация, которую обслуживает get_docs
  src/mcp_project_helper/
    server.py                 точка входа: MCPServer, регистрация tools, stdio
    config.py                  корень проекта/docs, лимиты, whitelist проверок
    security.py                resolve_within_root() — ограничение путей
    logging_setup.py           логирование в stderr (+ опционально файл)
    tools/
      search_project_files.py
      read_project_file.py
      get_docs.py
      run_project_check.py
  tests/                     unit- и интеграционные тесты mcp_project_helper (44 теста)
  demo_project/              демонстрационный проект — цель для файловых tools
    demo_app/
      models.py                Product, Order
      services.py               apply_discount, OrderBuilder
      tests/test_services.py    2 теста, запускаемые run_project_check("tests")
  evidence/                  реальные доказательства ручного тестирования через Claude Code и VS Code
    README.md                  реестр всех 6 тестов с результатами + доп. evidence по VS Code
    tool-calls.log              реальный server-side лог всех 6 тестов (закоммичен)
    tool-calls.log.example      формат строки лога (шаблон)
    test1_search_project_files.png … test6_path_traversal.png   скриншоты 6 тестов Claude Code CLI (закоммичены)
    vscode_mcp_server_connected.png   доп. скриншот: native MCP host VS Code подключился, 4 tools (закоммичен)
F
license - not found
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Agent-safe code retrieval MCP server that indexes repositories and provides semantic search, file navigation, call graph analysis, and bounded file reading tools for coding agents.
    3,977,962
    3
    AGPL 3.0
  • A
    license
    A
    quality
    C
    maintenance
    Zero-config MCP server that connects local codebases to AI assistants, providing secure project tree, regex search, file reading, and tech stack tools locally.
    4
    33
    MIT

View all related MCP servers

Related MCP Connectors

  • Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.

  • MCP server for generating rough-draft project plans from natural-language prompts.

  • An MCP server that gives your AI access to the source code and docs of all public github repos

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pw5rhn4tnn-dotcom/mcp-project-helper'

If you have feedback or need assistance with the MCP directory API, please join our Discord server