trazabilidad-mcp

trazabilidad-mcp

MCP server that exposes code tracing capabilities including journey flows, HTTP seams, and findings from indexed projects, allowing AI assistants to query software architecture.

Category
访问服务器

README

Trazabilidad

Motor de trazabilidad de código full-stack: construye un grafo de hechos de tu app (componentes → handlers → costuras HTTP → queries DB) y lo expone por web, MCP y CLI desde una sola fuente de verdad. Local-first, sin telemetría, el código nunca sale de tu máquina.

Estado: v1 funcional. El motor completo está implementado y verificado: extractor ts-morph, matcher de costuras HTTP, persistencia SQLite con migraciones, detección de doble-fuente, y las tres superficies vivas (CLI trazar, API REST en :8791, web en :5183, servidor MCP) y soporte multi-proyecto: un dueño apunta la herramienta a N repos reales. Las tres leen la MISMA query layer → una sola fuente de verdad.

Onboarding de un comando

Requisitos: Docker + Docker Compose.

git clone <repo> && cd trazabilidad
docker compose -f docker-compose.local.yml up --build -d
  • Web: http://127.0.0.1:5183 (shell con first-run)
  • API: http://127.0.0.1:8791/health (health honesto)

Ambos servicios se publican solo en 127.0.0.1 — nunca expuestos a la LAN (decisión de seguridad de la spec §5).

Para frenar todo:

docker compose -f docker-compose.local.yml down

Ciclo de desarrollo (hot-reload)

El compose usa bind-mount + --watch, no bakea el código:

  • apps/api corre con bun --watch → al guardar un .ts, el proceso reinicia solo.
  • apps/web corre vite con watch.usePolling → HMR cruza el FS del contenedor en macOS.

Editás en el host, el cambio se ve sin reconstruir la imagen. Solo necesitás up --build la primera vez (o tras tocar package.json / lockfile, para reinstalar deps).

Si cambiás dependencias: docker compose -f docker-compose.local.yml up --build -d recrea los contenedores y reinstala dentro de ellos.

Configuración de entorno

Convención de tres archivos en env/:

Archivo Tracked Contenido
env/local.env config no-secreta (puertos, NODE_ENV)
env/local.secret.env.example todas las keys de secretos, sin valores
env/local.secret.env no (gitignored) tus valores reales

v1 no tiene secretos reales (local-only, sin auth, sin servicios externos). El .example existe para fijar la convención de cara a v2.

Estructura (monorepo Bun + Turborepo)

packages/
  domain/    tipos puros del grafo (sin deps)
  core/      FactGraphBuilder + ExtractorPort (HEXAGONAL, no importa ts-morph)
  matcher/   SeamMatcher (STRATEGY, confianza descendente)
  db/        schema SQL + migraciones
  query/     query layer COMPARTIDA (fuente única que leen CLI, API y MCP)
apps/
  api/       Hono REST :8791 (bind 127.0.0.1) — /health, /index/status, /journeys, /seams, /findings
  web/       React + Vite + TanStack Router :5183 — canvas del grafo con polling de estado
  mcp/       servidor MCP stdio (SDK 1.29.0) — trace_flow, list_journeys, get_http_seams, index_status, ...
  cli/       `trazar` (index/add/projects/remove/overview/flow/journeys/seams/findings[+suppress/confirm]/serve)
examples/
  demo-login/  fixture de test: login React + Hono con plantados verificables

CLI trazar

Todos los comandos van sobre la misma query layer que la web y el MCP:

trazar index <ruta>                 # indexa un proyecto y construye el grafo de hechos
trazar add <ruta> [--name=X]        # registra un proyecto en el registro (lo verás en la web)
trazar projects                     # lista los proyectos registrados (id, name, ruta, estado)
trazar remove <id>                  # quita un proyecto del registro
trazar overview [<ruta>]            # salud del proyecto (healthScore, capas, findings por severidad)
trazar journeys [<ruta>]            # lista los journeys (entry points de UI) detectados
trazar flow <journey> [--mermaid]   # camino completo botón→DB de un journey (texto o Mermaid)
trazar seams [<ruta>] [--level=L]   # costuras HTTP con confianza y file:line de ambos lados
trazar findings [<ruta>]            # findings de doble-fuente con evidencia y estado
trazar findings suppress <key> [--reason=...]   # suprime un finding (persiste entre re-index)
trazar findings confirm <key>                   # confirma un finding
trazar serve                        # cómo levantar API + web (modo Docker demo o host)

add y index son cosas distintas: add registra la ruta en el catálogo (para verla en la web/MCP por id), index construye el grafo. index no auto-registra (deja un hint copiable); add no indexa. Mirá la sección Multi-proyecto más abajo.

Honestidad por diseño: sin index → comando copiable; stale tras editar sin re-indexar → ⚠; seams no resueltas → declaradas como huecos, nunca ocultadas. Exit codes: 0 ok · 2 uso · 1 error.

El proyecto objetivo de los comandos de lectura sale de: arg explícito > TRAZABILIDAD_PROJECT > cwd.

Instalar trazar en el PATH

El bin del CLI apunta a apps/cli/src/index.ts, que ya tiene shebang #!/usr/bin/env bun. bun link NO sirve acá: en un monorepo de workspaces solo registra el paquete para enlazarlo en otro proyecto (bun link @trazabilidad/cli), no instala el binario trazar en el PATH (verificado: tras bun link, which trazar → not found). Dos formas que sí funcionan:

Opción A — symlink al bin dir de bun (recomendada; ~/.bun/bin ya está en tu PATH si usás bun):

chmod +x apps/cli/src/index.ts
ln -sf "$(pwd)/apps/cli/src/index.ts" ~/.bun/bin/trazar
trazar journeys examples/demo-login    # ✓ funciona por el shebang

Opción B — alias/función en tu shell (si no querés tocar ~/.bun/bin):

# en ~/.zshrc o ~/.bashrc (ajustá la ruta absoluta del repo):
trazar() { bun "/ruta/al/repo/trazabilidad/apps/cli/src/index.ts" "$@"; }

Sin instalar nada, el CLI siempre corre con bun apps/cli/src/index.ts <comando> desde la raíz del repo (lo que usan los ejemplos de este README).

Multi-proyecto

Trazabilidad apunta a N proyectos desde un solo dueño. El catálogo de rutas vive en ~/.trazabilidad/projects.json (config, separado de la .db de cada proyecto). Cada superficie —web, MCP, CLI— resuelve el proyecto de forma independiente; cuando no se especifica, cae al default (env TRAZABILIDAD_PROJECT), así el demo dockerizado y los tests no se rompen.

Dos modos de arranque

Modo Comando Qué ve Para qué
Demo (Docker) docker compose -f docker-compose.local.yml up --build -d solo el fixture montado en /repo onboarding de un comando, conocer la herramienta
Host (bun) bun run api:host + bun run web:host tus repos reales (cualquier path absoluto del host) trabajar sobre tu código de verdad

La API en Docker está encajonada al volumen montado; para apuntar a tus repos reales usá el modo host (la API corre con bun directo en loopback y ve todo el filesystem). Ambos publican solo en 127.0.0.1.

Registrar y listar proyectos (CLI)

# 1) registrar una o más rutas reales (idempotente; imprime el id estable)
trazar add ~/code/mi-api          # → ✓ registrado "mi-api" — id mi-api-3f9a2c
trazar add ~/code/mi-web --name="Front"

# 2) listar el registro con estado (id, name, ruta, ✓/✗ index, ⚠ si la ruta no existe)
trazar projects

# 3) construir el grafo de cada uno (index ≠ add; corré index aparte)
trazar index ~/code/mi-api

# 4) quitar uno del registro (no borra la .db ni el código)
trazar remove mi-api-3f9a2c

El id es estable y se deriva del path absoluto (slug(basename)-hash6), no del basename: dos repos api en carpetas distintas obtienen ids distintos, sin colisión.

El registro es CLI-only. No hay POST /add ni POST /index en la API: registrar e indexar se hacen por el CLI en el host (decisión v1 — la API es de solo lectura sobre el grafo). La web y el MCP leen el catálogo, pero quien lo escribe es trazar add / trazar remove.

Selector en la web

En modo host (bun run web:host), el sidebar muestra un dropdown que lista GET /projects. El proyecto activo vive en la URL como segmento (/p/<id>/overview, deep-linkeable). Al elegir otro proyecto, todas las vistas (overview/journeys/seams/findings/status) se re-scopean a ese proyecto. Si un proyecto está sin indexar o su ruta ya no existe, aparece con un punto rojo y un estado honesto. Sin proyectos registrados → estado vacío con CTAs copiables (trazar add / trazar index).

El param project del MCP

Cada tool del MCP acepta un project opcional (el id del registro). Con project=<id> responde sobre ese proyecto; sin el param, sobre el default (TRAZABILIDAD_PROJECT). La tool list_projects devuelve el catálogo para que el agente descubra los ids.

// un agente consulta dos proyectos en la MISMA sesión, sin reconectar:
{ "tool": "overview",      "arguments": { "project": "mi-api-3f9a2c" } }
{ "tool": "list_journeys", "arguments": { "project": "mi-web-b71e04" } }
{ "tool": "overview",      "arguments": {} }   // ← default (back-compat)

Las tres superficies pueden operar sobre proyectos distintos a la vez sin interferir: son procesos independientes que leen .dbs distintas, y cada uno cae al default cuando no se especifica.

Flujo completo con el demo

bun install

# 1) indexar el fixture → 22 nodos, 14 aristas, 3 seams (1 finding de doble-fuente)
bun apps/cli/src/index.ts index examples/demo-login

# 2) ver los journeys de UI detectados (onSubmit, signOut)
bun apps/cli/src/index.ts journeys examples/demo-login

# 3) trazar el journey de login botón→DB (con el puente honesto del extractor)
bun apps/cli/src/index.ts flow onSubmit examples/demo-login

# 4) ver el finding estrella: doble fuente de verdad de `user`
bun apps/cli/src/index.ts findings examples/demo-login

# 5) levantar API + web (consumen la MISMA verdad que el CLI)
TRAZABILIDAD_PROJECT="$(pwd)/examples/demo-login" bun apps/api/src/index.ts   # :8791
cd apps/web && bun run dev                                                    # :5183

Si editás un .tsx del demo sin re-indexar, todas las superficies (CLI, /index/status, /health, web) reportan stale con ⚠ — la verdad sigue siendo honesta hasta que vuelvas a trazar index.

Conectar el MCP a Claude Code / Claude Desktop / Cursor

El servidor MCP (apps/mcp) expone el grafo de hechos por stdio (trace_flow, list_journeys, get_http_seams, index_status, find_data_providers, list_findings, overview y list_projects) leyendo la MISMA query layer que el CLI y la API. Cada tool acepta un project opcional (el id del registro) para apuntar a un proyecto puntual; sin ese param usa la env TRAZABILIDAD_PROJECT (back-compat). Ver la sección Multi-proyecto arriba. El MCP solo LEE — indexá antes con trazar index <ruta>.

El paquete expone el bin trazabilidad-mcp (entry apps/mcp/src/index.ts, con shebang #!/usr/bin/env bun igual que trazar). El entry es directamente ejecutable; bun link registra el paquete @trazabilidad/mcp para consumirlo desde otro repo.

Flujo de una pasada: index → connect → query

# 1) INDEX — el MCP solo LEE; primero construí el grafo de hechos.
bun apps/cli/src/index.ts index examples/demo-login

# 2) CONNECT — agregá el server a Claude Code en un comando (un único proyecto por env):
claude mcp add trazabilidad \
  -e TRAZABILIDAD_PROJECT="$(pwd)/examples/demo-login" \
  -- bun "$(pwd)/apps/mcp/src/index.ts"
#   ...o versioná el `.mcp.json` de la raíz del repo (ver abajo) y abrí el repo con Claude Code.

# 3) QUERY — confirmá el boot y pedí la primera consulta:
claude mcp get trazabilidad        # Status: ✓ Connected
#   Desde el agente: `list_projects` → elegí un `id` → `overview` / `trace_flow onSubmit`.

# Smoke real (boot por stdio + las 8 tools + datos del demo), repetible:
bun apps/mcp/smoke.ts              # o: bun run --filter @trazabilidad/mcp smoke

.mcp.json versionable (raíz del repo, project-scoped para Claude Code). Claude Code lanza el server con cwd = raíz del repo, así que el path RELATIVO resuelve sin hardcodear nada — y NO fija TRAZABILIDAD_PROJECT: el agente elige proyecto pasando project por tool (descubrilos con list_projects), diseño stateless:

{
  "mcpServers": {
    "trazabilidad": {
      "type": "stdio",
      "command": "bun",
      "args": ["apps/mcp/src/index.ts"]
    }
  }
}

Comprobá la conexión con claude mcp get trazabilidad (debe decir Status: ✓ Connected). Quitalo con claude mcp remove trazabilidad. Usá -s project para escribirlo en el .mcp.json versionable del repo, o -s user para que esté disponible en todos tus proyectos.

Path relativo vs absoluto. El .mcp.json de la raíz usa un path relativo porque Claude Code arranca el server con cwd = raíz del repo. Claude Desktop / Cursor no garantizan ese cwd: ahí usá rutas absolutas (y, si querés un proyecto fijo, la env TRAZABILIDAD_PROJECT):

{
  "mcpServers": {
    "trazabilidad": {
      "type": "stdio",
      "command": "bun",
      "args": ["/ruta/absoluta/al/repo/apps/mcp/src/index.ts"],
      "env": { "TRAZABILIDAD_PROJECT": "/ruta/absoluta/al/repo/examples/demo-login" }
    }
  }
}

El fixture: examples/demo-login

App de login completa (React + Hono) que es el contrato de test del producto. Planta a propósito tres situaciones que los lotes 2 y 5 deben detectar (marcadas con // FIXTURE:):

  1. Doble fuente de verdad de user: Dashboard.tsx lo lee de AuthContext, Profile.tsx lo lee directo de localStorage. → Finding double-source (LOTE 5).
  2. Fetch dinámico (fetchProfile, URL template en runtime) → seam no-resuelta visible (LOTE 2).
  3. Fetch literal fetch('/api/auth/login') → costura literal con el handler Hono (LOTE 2).

Typecheck del fixture:

bun install
bun run --filter '@trazabilidad/example-demo-login' typecheck

Limitaciones conocidas v1

Trazabilidad declara sus huecos en vez de ocultarlos. Lo que v1 todavía NO cubre:

  • sessionStorage y claves dinámicas no se detectan como fuente de estado. El extractor reconoce localStorage con clave literal y el Context explícito; una doble-fuente sobre sessionStorage (o localStorage con una clave armada en runtime) no genera finding y find_data_providers devuelve 0 proveedores. Cobertura ampliable en v2.
  • finding_key vs renames. La identidad de un finding (para que la supresión persista entre re-index) se deriva del contenido del hecho; si renombrás el símbolo/archivo involucrado, la key cambia y una supresión previa no se reasocia automáticamente al finding "equivalente".
  • Puente del flujo botón→DB es heurístico. Cuando el extractor no puede unir dos tramos con certeza (p. ej. una URL armada en runtime), declara la costura como no-resuelta (hueco visible) en lugar de inventar una arista — preferimos un hueco honesto a una conexión falsa.
  • La API es de SOLO LECTURA sobre el grafo + supresión/confirmación de findings. El indexado se dispara únicamente por CLI (trazar index); no hay POST /index en v1 (cola + progreso es backlog v2).
  • DB local single-project, single-writer. La base SQLite usa journal_mode=DELETE (no WAL): se comparte host↔contenedor por bind-mount sobre VirtioFS, donde el -shm de WAL no es coherente y causaba "disk I/O error" intermitentes y estados divergentes. DELETE serializa escritor↔lectores, aceptable para un dev local; no es una DB pensada para concurrencia multi-cliente.
  • Sin auth ni multi-tenant. Local-first, bind 127.0.0.1, sin telemetría; multi-usuario/remoto es la visión SaaS de v2, no v1.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选
mcp-server-qdrant

mcp-server-qdrant

这个仓库展示了如何为向量搜索引擎 Qdrant 创建一个 MCP (Managed Control Plane) 服务器的示例。

官方
精选