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
Visit Server

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.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured