automeli-docs-mcp
Official# automeli-docs-mcp
Servidor **MCP (Model Context Protocol)** que expone la documentación de la **API pública de Automeli** a LLMs (Claude Desktop, Claude Code, claude.ai, etc.).
Es **solo lectura de la documentación**: NO ejecuta la API real. Funciona como un wrapper de `fetch` + cache sobre los artefactos machine-readable que sirve `www.automeli.com` (`openapi.json`, `errors.json`, `llms-full.txt`, `llms.txt`). No duplica el spec → sin drift con la doc.
## Versiones de la API (desde 0.2.0)
La doc canónica de la landing es la **API v2**; la v1 quedó congelada bajo `/api-docs/v1/`. Todas las tools aceptan un parámetro opcional `version`:
- `"v2"` (default) → artefactos canónicos (`/api-docs/openapi.json`, …).
- `"v1"` → artefactos congelados (`/api-docs/v1/…`), solo para integraciones legadas.
`errors.json` (catálogo de errores) y `llms.txt` son **compartidos** entre versiones. Las respuestas incluyen `api_version`, leído del propio artefacto, para que el cliente confirme qué versión está viendo.
**Transición**: mientras la landing desplegada siga siendo la vieja (canónica = v1, sin `/api-docs/v1/`), pedir `"v1"` cae a los artefactos canónicos — que en ese mundo *son* v1. Cuando la landing nueva (rama `feat/api-docs-v2` de `automeli.com`) se despliegue, la canónica pasa a v2 y este server la sirve sin cambios. Después de ese deploy conviene refrescar el snapshot (`pnpm run build`).
## Cómo obtiene los datos
1. **Live + cache con TTL** — al pedir un artefacto, lo trae de `www.automeli.com`, valida **sintaxis y forma mínima** (que `openapi.paths` sea un objeto con entradas, que `errors.errors` sea un array, que los `.txt` parezcan la doc) y lo cachea en memoria (default 15 min) con clave `versión:artefacto`. Un 200 con basura (p. ej. `{}` o un envelope de error de un CDN) NO se cachea: se degrada al snapshot. Mientras esté fresco, no vuelve a la red.
2. **Fallback offline** — si la red falla, sirve un **snapshot bundleado** (`data/snapshot/`) que se baja en cada build. Así el server arranca al instante y sigue andando sin conexión. El snapshot se cachea **ya vencido**: apenas vuelva la red, la próxima llamada reintenta live. Los artefactos v1 congelados se guardan como `v1-*` (opcionales: si la landing aún no los sirve, se omiten). Si un pedido de `v1` termina servido por la doc canónica (fallback de transición), las tools estructuradas agregan `version_warning` y las de prosa (`describe_flow`, `generate_snippet`) anteponen el aviso en el propio texto.
La fuente de verdad es siempre la doc live; el snapshot es solo red de seguridad.
## Tools (7, todas read-only)
| Tool | Para qué |
|------|----------|
| `list_endpoints(version?)` | Índice de los endpoints: método, path, summary, scope, key env, idempotencia, costo. Devuelve `api_version` y `base_url`. |
| `get_endpoint(operationId \| method+path, version?)` | Detalle completo: parámetros, request body (schema+ejemplo), respuestas con ejemplos, errores, costo, scope y la prosa de la doc. |
| `search_docs(query, limit?, version?)` | Búsqueda léxica sobre endpoints + errores + guías + flujos. |
| `explain_error(code, version?)` | Status, cuándo ocurre, doc_url y qué endpoints emiten un código RFC 7807 (ej. `E_RATE_LIMITED`). El catálogo es compartido v1/v2. |
| `generate_snippet(lang, operationId \| method+path, version?)` | Snippet `curl` / `js` / `python` idéntico al de la web. El parámetro es `lang`, no `language`. |
| `describe_flow(flow, version?)` | Guía narrativa de un flujo end-to-end (hoy: `test-to-live`). |
| `get_openapi(version?)` | El documento OpenAPI 3.1 completo, crudo. |
## Instalación y build
Este servidor se distribuye **como repositorio para clonar** (no se publica en npm). Requiere **Node ≥ 20**. Se recomienda **pnpm**, pero **npm también funciona**: el repo trae `pnpm-lock.yaml` para builds reproducibles con pnpm; npm resuelve desde `package.json` (solo 2 dependencias) y genera su propio lockfile.
```bash
git clone https://github.com/Automeli-Services-Organization/automeli-docs-mcp.git
cd automeli-docs-mcp
# con pnpm (recomendado):
pnpm install
pnpm run build # corre prebuild (baja snapshot) + compila a dist/
# …o con npm:
npm install
npm run build
```
Verificación opcional (usa `npm run …` si instalaste con npm):
```bash
pnpm run smoke # test de interoperabilidad con el cliente MCP real
pnpm run smoke:offline # el mismo smoke contra una base muerta → fuerza el camino snapshot
```
El smoke es agnóstico de versión (descubre los operationIds vía `list_endpoints`), así que pasa igual antes y después del deploy de la landing v2. Para probarlo contra otra fuente (ej. un dev server con la doc nueva):
```bash
AUTOMELI_DOCS_BASE=https://<base> AUTOMELI_DOCS_TIMEOUT_MS=10000 pnpm run smoke
```
## Conectarlo a un cliente MCP
### Claude Code (CLI)
```bash
# apuntando al build local (usa la ruta ABSOLUTA a tu clon):
claude mcp add --scope user automeli-docs -- node /ruta/absoluta/a/automeli-docs-mcp/dist/index.js
```
Dos detalles que ahorran un rato de confusión:
- **Usa `--scope user`.** Sin él, el servidor queda registrado solo para la
carpeta desde la que ejecutaste el comando — y como lo natural es ejecutarlo
desde dentro del clon, después no aparece al trabajar en otro proyecto.
- **Reinicia la sesión.** Las herramientas de un servidor recién agregado no
se cargan en la sesión en curso: cierra y vuelve a abrir `claude`. Que
`claude mcp list` diga `✔ Connected` no significa que ya las puedas usar
ahí mismo.
### Claude Desktop
En `claude_desktop_config.json` (Settings → Developer → Edit Config):
```json
{
"mcpServers": {
"automeli-docs": {
"command": "node",
"args": ["/ruta/absoluta/a/automeli-docs-mcp/dist/index.js"]
}
}
}
```
## Configuración (variables de entorno)
| Variable | Default | Qué hace |
|----------|---------|----------|
| `AUTOMELI_DOCS_BASE` | `https://www.automeli.com` | Base de los artefactos. **Usar `www`** (el apex hace 301). |
| `AUTOMELI_DOCS_TTL_SECONDS` | `900` | Frescura del cache en memoria. |
| `AUTOMELI_DOCS_TIMEOUT_MS` | `5000` | Timeout del fetch live antes de caer al cache/snapshot. |
## Refrescar el snapshot
El snapshot se regenera solo en cada `pnpm run build`. Para refrescarlo a mano:
```bash
pnpm run fetch-snapshot
```
## Notas / límites conocidos
- `components.schemas` del OpenAPI hoy trae pocos schemas nombrados (bodies inline). Suficiente para las tools; si se quisiera tipado fuerte por endpoint, enriquecer el registry de la doc (`automeli.com/src/lib/api-spec/`).
- `explain_error` devuelve `when` + `doc_url` (no hay un campo estructurado "cómo reaccionar"; esa guía vive en la prosa de la doc).
- `generate_snippet` **extrae** el bloque exacto de `llms-full.txt` (incluye los valores de query de ejemplo autorados). Si esa extracción fallara, cae a un snippet generado desde el OpenAPI (sin esos query de ejemplo).
- `describe_flow` y la sección de guías dependen de los headings de `llms-full.txt` / `llms.txt`; el formato de la landing nueva (rama v2) se verificó compatible (anclas `{#operationId}` en H3, fences `bash`/`javascript`/`python`, flujo como H2).
TDQS
Scored across 7 tools
Cada herramienta tiene un propósito claramente distinto: listar endpoints, obtener detalle, buscar en docs, explicar errores, generar snippets, describir flujos y obtener OpenAPI. No hay solapamiento ambiguo; las descripciones refuerzan cuándo usar cada una.
Todos los nombres siguen el patrón verbo_objeto en snake_case (list_endpoints, get_endpoint, search_docs, explain_error, generate_snippet, describe_flow, get_openapi). Es altamente consistente y predecible.
Siete herramientas es un número bien ajustado para un servidor de documentación de API; cada una cubre una necesidad de descubrimiento o consulta sin redundancia.
La superficie cubre descubrimiento, detalle, búsqueda, errores, snippets, flujos y contrato OpenAPI, lo cual es muy completo para docs. Faltaría, por ejemplo, una herramienta para listar versiones de API o comparar cambios, pero son carencias menores.