# OmniRoute MCP Server Documentation (Español) 🌐 **Languages:** 🇺🇸 [English](../../../../frameworks/MCP-SERVER.md) · 🇪🇹 [am](../../../am/docs/frameworks/MCP-SERVER.md) · 🇸🇦 [ar](../../../ar/docs/frameworks/MCP-SERVER.md) · 🇦🇿 [az](../../../az/docs/frameworks/MCP-SERVER.md) · 🇧🇬 [bg](../../../bg/docs/frameworks/MCP-SERVER.md) · 🇧🇩 [bn](../../../bn/docs/frameworks/MCP-SERVER.md) · 🇧🇦 [bs](../../../bs/docs/frameworks/MCP-SERVER.md) · 🇨🇿 [cs](../../../cs/docs/frameworks/MCP-SERVER.md) · 🇩🇰 [da](../../../da/docs/frameworks/MCP-SERVER.md) · 🇩🇪 [de](../../../de/docs/frameworks/MCP-SERVER.md) · 🇬🇷 [el](../../../el/docs/frameworks/MCP-SERVER.md) · 🇪🇪 [et](../../../et/docs/frameworks/MCP-SERVER.md) · 🇮🇷 [fa](../../../fa/docs/frameworks/MCP-SERVER.md) · 🇫🇮 [fi](../../../fi/docs/frameworks/MCP-SERVER.md) · 🇫🇷 [fr](../../../fr/docs/frameworks/MCP-SERVER.md) · 🇮🇪 [ga](../../../ga/docs/frameworks/MCP-SERVER.md) · 🇮🇳 [gu](../../../gu/docs/frameworks/MCP-SERVER.md) · 🇳🇬 [ha](../../../ha/docs/frameworks/MCP-SERVER.md) · 🇮🇱 [he](../../../he/docs/frameworks/MCP-SERVER.md) · 🇮🇳 [hi](../../../hi/docs/frameworks/MCP-SERVER.md) · 🇭🇷 [hr](../../../hr/docs/frameworks/MCP-SERVER.md) · 🇭🇺 [hu](../../../hu/docs/frameworks/MCP-SERVER.md) · 🇦🇲 [hy](../../../hy/docs/frameworks/MCP-SERVER.md) · 🇮🇩 [id](../../../id/docs/frameworks/MCP-SERVER.md) · 🇳🇬 [ig](../../../ig/docs/frameworks/MCP-SERVER.md) · 🇮🇹 [it](../../../it/docs/frameworks/MCP-SERVER.md) · 🇯🇵 [ja](../../../ja/docs/frameworks/MCP-SERVER.md) · 🇬🇪 [ka](../../../ka/docs/frameworks/MCP-SERVER.md) · 🇰🇭 [km](../../../km/docs/frameworks/MCP-SERVER.md) · 🇮🇳 [kn](../../../kn/docs/frameworks/MCP-SERVER.md) · 🇰🇷 [ko](../../../ko/docs/frameworks/MCP-SERVER.md) · 🇱🇹 [lt](../../../lt/docs/frameworks/MCP-SERVER.md) · 🇱🇻 [lv](../../../lv/docs/frameworks/MCP-SERVER.md) · 🇮🇳 [ml](../../../ml/docs/frameworks/MCP-SERVER.md) · 🇮🇳 [mr](../../../mr/docs/frameworks/MCP-SERVER.md) · 🇲🇾 [ms](../../../ms/docs/frameworks/MCP-SERVER.md) · 🇲🇹 [mt](../../../mt/docs/frameworks/MCP-SERVER.md) · 🇲🇲 [my](../../../my/docs/frameworks/MCP-SERVER.md) · 🇳🇵 [ne](../../../ne/docs/frameworks/MCP-SERVER.md) · 🇳🇱 [nl](../../../nl/docs/frameworks/MCP-SERVER.md) · 🇳🇴 [no](../../../no/docs/frameworks/MCP-SERVER.md) · 🇮🇳 [or](../../../or/docs/frameworks/MCP-SERVER.md) · 🇮🇳 [pa](../../../pa/docs/frameworks/MCP-SERVER.md) · 🇵🇭 [phi](../../../phi/docs/frameworks/MCP-SERVER.md) · 🇵🇱 [pl](../../../pl/docs/frameworks/MCP-SERVER.md) · 🇵🇹 [pt](../../../pt/docs/frameworks/MCP-SERVER.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/frameworks/MCP-SERVER.md) · 🇷🇴 [ro](../../../ro/docs/frameworks/MCP-SERVER.md) · 🇷🇺 [ru](../../../ru/docs/frameworks/MCP-SERVER.md) · 🇱🇰 [si](../../../si/docs/frameworks/MCP-SERVER.md) · 🇸🇰 [sk](../../../sk/docs/frameworks/MCP-SERVER.md) · 🇸🇮 [sl](../../../sl/docs/frameworks/MCP-SERVER.md) · 🇷🇸 [sr](../../../sr/docs/frameworks/MCP-SERVER.md) · 🇸🇪 [sv](../../../sv/docs/frameworks/MCP-SERVER.md) · 🇰🇪 [sw](../../../sw/docs/frameworks/MCP-SERVER.md) · 🇮🇳 [ta](../../../ta/docs/frameworks/MCP-SERVER.md) · 🇮🇳 [te](../../../te/docs/frameworks/MCP-SERVER.md) · 🇹🇭 [th](../../../th/docs/frameworks/MCP-SERVER.md) · 🇹🇷 [tr](../../../tr/docs/frameworks/MCP-SERVER.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/frameworks/MCP-SERVER.md) · 🇵🇰 [ur](../../../ur/docs/frameworks/MCP-SERVER.md) · 🇺🇿 [uz](../../../uz/docs/frameworks/MCP-SERVER.md) · 🇻🇳 [vi](../../../vi/docs/frameworks/MCP-SERVER.md) · 🇳🇬 [yo](../../../yo/docs/frameworks/MCP-SERVER.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/frameworks/MCP-SERVER.md) · 🇹🇼 [zh-TW](../../../zh-TW/docs/frameworks/MCP-SERVER.md) --- > Servidor Model Context Protocol con 110 herramientas para operaciones de enrutamiento, caché, compresión, memoria, habilidades, proxy, pool, Radar y fuentes de contexto. > > Fuente de referencia: `open-sse/mcp-server/server.ts` calcula **110 herramientas únicas** con `countUniqueMcpTools()`: 45 definiciones canónicas (incluidas las seis herramientas del ciclo de vida de CCR, el trío de habilidades de agente, `omniroute_radar_catalog` y `omniroute_x_search`), además de memoria (3), habilidades (4), habilidades de GitHub (3), pool (6), gamificación (8), plugins (8), Notion (6), Obsidian (22), corpus local (3) y dos herramientas de compresión exclusivas de RTK. ## Instalación OmniRoute MCP viene integrado. Inícielo con: ```bash omniroute --mcp ``` O mediante el transporte open-sse: ```bash # Transporte HTTP transmisible (puerto 20130) omniroute --dev # MCP se inicia automáticamente en el endpoint /mcp ``` Los transportes HTTP (`sse` / `streamable-http`, servidos dentro del proceso por el servidor del panel) están desactivados de forma predeterminada y anteriormente solo podían alternarse desde la página `/dashboard/mcp`. Desde v3.8.51, la CLI ofrece las mismas funciones: ```bash omniroute mcp status # estado habilitado/en línea, transporte y número de herramientas omniroute mcp enable [--transport stdio|sse|streamable-http] omniroute mcp disable omniroute mcp restart # restablece las sesiones sse/streamable-http activas ``` `mcp enable`/`mcp disable` realizan una solicitud PATCH sobre la misma configuración `mcpEnabled` (y, opcionalmente, `mcpTransport`) que el panel alterna mediante `/api/settings`. `mcp restart` llama a `POST /api/mcp/restart`: cierra las sesiones `sse`/`streamable-http` activas para que la siguiente solicitud vuelva a inicializarse correctamente, devuelve `409` si MCP está deshabilitado y `501` para el transporte `stdio` (los clientes stdio gestionan su propio subproceso; no existe un identificador dentro del proceso que se pueda reiniciar). ## Transportes El servidor MCP expone tres transportes, todos respaldados por la misma fábrica `createMcpServer()`: | Transporte | Ubicación | Cuándo usarlo | | :---------------- | :----------------------------------------------- | :------------------------------------------------------------- | | `stdio` | `open-sse/mcp-server/server.ts` | Integraciones con IDE (Claude Desktop, Cursor, etc.) | | `sse` | `POST/GET /api/mcp/sse` mediante `httpTransport` | Clientes de navegador/agente que necesitan un flujo de eventos | | `streamable-http` | `POST/GET/DELETE /api/mcp/stream` | Clientes HTTP multisesión (encabezado `mcp-session-id`) | El transporte HTTP activo (`sse` o `streamable-http`) se selecciona mediante la configuración `mcpTransport`. Cambiar de transporte cierra las sesiones existentes del otro transporte. ### Acceso remoto (omisión mediante el ámbito manage) `/api/mcp/*` se encuentra en el nivel LOCAL_ONLY (`src/server/authz/routeGuard.ts`); de forma predeterminada, solo los hosts de bucle local (`localhost`, `127.0.0.1`, `::1`) pueden acceder a él. Desde v3.8.2, los clientes que no sean de bucle local pueden conectarse si presentan un encabezado `Authorization: Bearer ` cuya clave incluya el ámbito `manage`. Esta es la única forma de acceder al servidor MCP remoto a través de un túnel, un proxy inverso o un nombre de host público. ```bash # Conceda el ámbito manage: abra la página de claves de API del panel y active # "Acceso de administración" para la clave, o envíe POST scopes:["manage"] al crearla. # A continuación, conéctese desde un cliente MCP remoto: curl -i \ -H "Host: your-public-host.example" \ -H "Authorization: Bearer sk-…" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"my-client","version":"0"}}}' \ https://your-public-host.example/api/mcp/stream ``` Una clave sin el ámbito manage (o sin Bearer) devuelve `403 LOCAL_ONLY`. El prefijo relacionado `/api/cli-tools/runtime/*` no permite esta omisión de forma intencionada; consulte [Niveles de protección de rutas — Excepción para el ámbito manage](../security/ROUTE_GUARD_TIERS.md#manage-scope-carve-out). ## Configuración del IDE Consulta [Configuración del cliente MCP](../guides/SETUP_GUIDE.md#mcp-client-configuration) para configurar Claude Desktop, Cursor, Cline y clientes MCP compatibles. --- ## Herramientas esenciales (14) — Fase 1 | Herramienta | Ámbitos | Descripción | | :------------------------------ | :-------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------- | | `omniroute_get_health` | `read:health` | Tiempo de actividad, memoria, disyuntores, límites de frecuencia, estadísticas de caché | | `omniroute_list_combos` | `read:combos` | Todos los combos configurados con sus estrategias (métricas opcionales) | | `omniroute_get_combo_metrics` | `read:combos` | Métricas de rendimiento de un combo específico | | `omniroute_switch_combo` | `write:combos` | Activa o desactiva un combo | | `omniroute_create_combo` | `write:combos` | Crea un combo validado mediante la API de combos existente | | `omniroute_check_quota` | `read:quota` | Cuota utilizada/total, porcentaje restante, hora de restablecimiento, estado de los tokens | | `omniroute_route_request` | `execute:completions` | Envía una solicitud de finalización de chat mediante el enrutamiento de OmniRoute | | `omniroute_cost_report` | `read:usage` | Informe de costes por período (sesión/día/semana/mes) | | `omniroute_list_models_catalog` | `read:models` | Catálogo completo de modelos con capacidades, estado y precios | | `omniroute_radar_catalog` | `read:radar` | Catálogo Radar local firmado; filtros opcionales por proveedor/familia | | `omniroute_tool_search` | `read:tools` | Descubre herramientas del catálogo MCP registrado | | `omniroute_web_search` | `execute:search` | Búsqueda web mediante los proveedores de búsqueda configurados. No incluye X/Twitter. | | `omniroute_x_search` | `execute:search` | Busca en X mediante xAI/SuperGrok, o elige `xquik-search` para obtener resultados de la API de Xquik. Requiere credenciales para el backend seleccionado. | | `omniroute_web_fetch` | `execute:search` | Obtiene contenido web mediante los proveedores de obtención configurados | ## Herramientas avanzadas (11) — Fase 2 | Herramienta | Permisos | Descripción | | :--------------------------------- | :----------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------- | | `omniroute_simulate_route` | `read:health`, `read:combos` | Simulación de enrutamiento sin ejecución con árbol de alternativas | | `omniroute_set_budget_guard` | `write:budget` | Presupuesto de sesión con acción de degradación, bloqueo o alerta | | `omniroute_set_routing_strategy` | `write:combos` | Actualiza la estrategia del combo en tiempo de ejecución (prioridad/ponderada/automática/etc.) | | `omniroute_set_resilience_profile` | `write:resilience` | Aplica un perfil predefinido de resiliencia `aggressive` / `balanced` / `conservative` | | `omniroute_test_combo` | `execute:completions`, `read:combos` | Prueba en vivo de cada proveedor de un combo mediante una llamada real al servicio ascendente | | `omniroute_get_provider_metrics` | `read:health` | Métricas por proveedor con latencia p50/p95/p99 y estado del disyuntor | | `omniroute_best_combo_for_task` | `read:combos`, `read:health` | Recomienda un combo según el tipo de tarea, con restricciones de presupuesto y latencia | | `omniroute_explain_route` | `read:health`, `read:usage` | Explica por qué una solicitud se enrutó a un proveedor (factores de puntuación + alternativas) | | `omniroute_get_session_snapshot` | `read:usage` | Instantánea completa de la sesión: coste, tokens, modelos/proveedores principales, errores y límite presupuestario | | `omniroute_db_health_check` | `read:health`, `write:resilience` | Diagnostica (y, opcionalmente, repara automáticamente) inconsistencias de la base de datos, como referencias de combos rotas o filas huérfanas | | `omniroute_sync_pricing` | `pricing:write` | Sincroniza datos de precios desde fuentes externas (LiteLLM); admite `dryRun` | ## Herramientas de caché (2) | Herramienta | Permisos | Descripción | | :---------------------- | :------------ | :--------------------------------------------------------------- | | `omniroute_cache_stats` | `read:cache` | Estadísticas de caché semántica, caché de prompts e idempotencia | | `omniroute_cache_flush` | `write:cache` | Vacía la caché globalmente o por firma/modelo | ## Herramientas de compresión (13) | Herramienta | Permisos | Descripción | | :---------------------------------- | :------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `omniroute_compression_status` | `read:compression` | Configuración de compresión, resumen analítico y estadísticas con reconocimiento de caché (incluye metadatos de `analytics.mcpDescriptionCompression`) | | `omniroute_compression_configure` | `write:compression` | Configura el modo de compresión, el umbral, la proporción objetivo, la conservación del prompt del sistema y la activación de la compresión de descripciones MCP | | `omniroute_set_compression_engine` | `write:compression` | Selecciona el motor activo (off/caveman/rtk/stacked) y la intensidad de Caveman/RTK | | `omniroute_list_compression_combos` | `read:compression` | Enumera los combos de compresión con nombre y sus canalizaciones de motores | | `omniroute_compression_combo_stats` | `read:compression` | Analíticas agrupadas por combo de compresión y motor | | `omniroute_ccr_store` | `write:compression` | Almacena contenido aislado por invocador en el almacén CCR limitado en memoria y devuelve un marcador junto con una referencia `ccr://` | | `omniroute_ccr_retrieve` | `read:compression` | Recupera contenido CCR completo o mediante los modos de inicio, final, líneas, grep y estadísticas | | `omniroute_ccr_inspect` | `read:compression` | Inspecciona los metadatos CCR propiedad del invocador sin devolver el contenido | | `omniroute_ccr_list` | `read:compression` | Enumera metadatos paginados de los bloques CCR propiedad del invocador | | `omniroute_ccr_delete` | `write:compression` | Elimina un bloque CCR propiedad del invocador | | `omniroute_ccr_stats` | `read:compression` | Informa del uso de memoria por invocador, los contadores del ciclo de vida y los límites del almacén | | `omniroute_rtk_discover` | `read:compression` | Detecta ruido recurrente en muestras de salida RTK proporcionadas voluntariamente | | `omniroute_rtk_learn` | `read:compression` | Genera un borrador revisable de filtro RTK a partir de muestras proporcionadas voluntariamente | Las entradas CCR se almacenan únicamente en memoria y desaparecen al reiniciar. Cada bloque está limitado a 2 MiB, cada principal a 16 MiB y el almacén global a 64 MiB. De forma predeterminada, las entradas tienen un TTL de 24 horas (máximo de siete días). La recuperación MCP completa está limitada a 256 KiB; los bloques más grandes siguen estando disponibles mediante los modos por rangos y grep. El almacenamiento, la recuperación, la enumeración, la inspección, la eliminación y las estadísticas están aislados por el principal autenticado de la clave de API. Los registros de auditoría contienen hashes y metadatos de tamaño, nunca contenido. `omniroute_compression_status` informa de la compresión de descripciones MCP por separado en `analytics.mcpDescriptionCompression`. Esos valores son estimaciones del tamaño de los metadatos de las descripciones enumerables de MCP (`tools`, `prompts`, `resources` y `resourceTemplates`); no son comprobantes de uso del proveedor y están marcados con `source: "mcp_metadata_estimate"`. ### Filtro del árbol de accesibilidad de MCP (v3.8.0) Independientemente de las herramientas de compresión anteriores, OmniRoute incluye un filtro posterior a la ejecución que comprime los **resultados de herramientas** de las herramientas de navegador/accesibilidad de MCP antes de devolverlos al agente. Este filtro no es en sí mismo una herramienta: se ejecuta de forma transparente sobre cualquier resultado de herramienta que contenga texto detallado de un árbol de accesibilidad o una instantánea del navegador (≥2000 caracteres). Comportamientos principales: - Contrae ≥30 líneas consecutivas de elementos hermanos repetidos en un resumen con el inicio y el final - Conserva los anclajes `[ref=eXX]` requeridos por Playwright/computer-use - Trunca de forma estricta el texto excesivamente grande (>50,000 caracteres) e incluye una indicación de navegación - Ahorro esperado: **60–80%** en las cargas útiles de instantáneas del navegador Configuración: `compression.mcpAccessibility` en la configuración global (migración 056). Implementación: `open-sse/services/compression/engines/mcpAccessibility/`. Documentación completa: [Motores de compresión — Filtro del árbol de accesibilidad de MCP](../compression/COMPRESSION_ENGINES.md#mcp-accessibility-tree-filter). Consulte [Motores de compresión](../compression/COMPRESSION_ENGINES.md) y [Compresión RTK](../compression/RTK_COMPRESSION.md) para conocer el modelo de compresión en tiempo de ejecución en el que se basan estas herramientas. ## Herramientas de 1Proxy (3) | Herramienta | Ámbitos | Descripción | | :-------------------------- | :------------- | :---------------------------------------------------------------------------------------------- | | `omniroute_oneproxy_fetch` | `read:proxies` | Obtiene proxies gratuitos del mercado de 1Proxy (filtros de protocolo/país/calidad/límite) | | `omniroute_oneproxy_rotate` | `read:proxies` | Obtiene el siguiente proxy disponible según la estrategia (`random` / `quality` / `sequential`) | | `omniroute_oneproxy_stats` | `read:proxies` | Estadísticas del pool, estado de sincronización y distribución por protocolo y país | ## Herramientas de memoria (3) Definidas en `open-sse/mcp-server/tools/memoryTools.ts`. La autenticación y los ámbitos se aplican mediante el flujo estándar de ámbitos de MCP. | Herramienta | Ámbitos | Descripción | | :------------------------ | :------------- | :----------------------------------------------------------------------------------------------------- | | `omniroute_memory_search` | `read:memory` | Busca memorias por consulta / tipo / clave de API, aplicando el presupuesto de tokens | | `omniroute_memory_add` | `write:memory` | Añade una nueva entrada de memoria (`factual` / `episodic` / `procedural` / `semantic`) | | `omniroute_memory_clear` | `write:memory` | Borra las memorias de una clave de API, opcionalmente filtradas por tipo o marca de tiempo `olderThan` | ## Herramientas de habilidades (4) Definidas en `open-sse/mcp-server/tools/skillTools.ts`. Respaldadas por `src/lib/skills/registry` + `src/lib/skills/executor`. | Herramienta | Ámbitos | Descripción | | :---------------------------- | :--------------- | :------------------------------------------------------------------------------------------------- | | `omniroute_skills_list` | `read:skills` | Enumera las habilidades registradas con filtrado opcional por clave de API, nombre o estado activo | | `omniroute_skills_enable` | `write:skills` | Activa o desactiva una habilidad específica por ID | | `omniroute_skills_execute` | `execute:skills` | Ejecuta una habilidad con la entrada proporcionada y devuelve el registro de ejecución | | `omniroute_skills_executions` | `read:skills` | Enumera el historial reciente de ejecuciones de habilidades | ## Fuente de contexto de Notion (6) Definida en `open-sse/mcp-server/tools/notionTools.ts`. El token se almacena en la tabla `key_value` mediante `src/lib/db/notion.ts`. El cliente REST se encuentra en `src/lib/notion/api.ts`. La API de configuración se encuentra en `src/app/api/settings/notion/route.ts`. La interfaz del panel se encuentra en `src/app/(dashboard)/dashboard/endpoint/components/NotionSourceCard.tsx`. Configura el token de integración de Notion desde la pestaña **Fuentes de contexto** del panel del endpoint o mediante la API REST: ```bash # Establecer el token curl -X POST http://localhost:20128/api/settings/notion \ -H "Content-Type: application/json" \ -d '{"token": "ntn_..."}' # Comprobar el estado curl http://localhost:20128/api/settings/notion # Desconectar curl -X DELETE http://localhost:20128/api/settings/notion ``` | Herramienta | Ámbitos | Descripción | | :--------------------------- | :------------- | :---------------------------------------------------------------------------- | | `notion_search` | `read:notion` | Realiza una búsqueda de texto completo en todas las páginas y bases de datos | | `notion_get_page` | `read:notion` | Obtiene una página por ID junto con sus propiedades | | `notion_list_block_children` | `read:notion` | Enumera los bloques secundarios de una página o bloque | | `notion_query_database` | `read:notion` | Consulta una base de datos con filtros, criterios de ordenación y paginación | | `notion_get_database` | `read:notion` | Obtiene el esquema de una base de datos por ID | | `notion_append_blocks` | `write:notion` | Añade bloques secundarios a un bloque principal (máximo de 100 por solicitud) | ## Herramientas del catálogo de habilidades de agentes (3) Definidas en `open-sse/mcp-server/tools/agentSkillTools.ts`. Respaldadas por `src/lib/agentSkills/catalog`. Estas herramientas exponen el catálogo de documentación de 45 habilidades de agentes a clientes MCP y agentes externos. Ámbito: `read:catalog`. | Herramienta | Ámbitos | Descripción | | :-------------------------------- | :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `omniroute_agent_skills_list` | `read:catalog` | Enumera las 45 habilidades de agentes con filtros opcionales de `category` (api\|cli) y `area`; devuelve metadatos + cobertura | | `omniroute_agent_skills_get` | `read:catalog` | Obtiene los metadatos completos + el contenido de SKILL.md de una habilidad mediante su `id` canónico | | `omniroute_agent_skills_coverage` | `read:catalog` | Estadísticas de cobertura: cuántas de las 23 habilidades de API, 21 de CLI y 1 de configuración tienen archivos SKILL.md en el sistema de archivos frente a los totales del catálogo | Consulta [AGENT-SKILLS.md](./AGENT-SKILLS.md) para ver el catálogo completo y cómo lo utilizan los agentes externos. ## Frameworks relacionados (v3.8.0) El inventario de herramientas MCP anterior (110 herramientas únicas, calculadas mediante `countUniqueMcpTools()`) está limitado intencionadamente a las operaciones en tiempo de ejecución de enrutamiento/caché/compresión/memoria/habilidades/proxy/fuentes de contexto. Dos frameworks adyacentes se distribuyen junto con el servidor MCP en v3.8.0 y se documentan por separado: ### Agentes en la nube Los agentes en la nube son agentes de IA de programación que se ejecutan fuera del proceso (codex-cloud, cursor-cloud, devin, jules) y están conectados a OmniRoute mediante el mismo modelo de conexión utilizado para los proveedores de LLM. Se exponen mediante su propia superficie REST (`/api/v1/agents/*`) y **no** forman parte del catálogo de herramientas MCP — invocar un agente en la nube no consume ningún ámbito MCP. - Implementación: `src/lib/cloudAgent/` (`registry.ts`, `agents/codex.ts`, `agents/cursor.ts`, `agents/devin.ts`, `agents/jules.ts`). - Ciclo de vida: `createTask`, `getStatus`, `approvePlan`, `sendMessage`, `listSources`. - Documentación: [docs/frameworks/CLOUD_AGENT.md](./CLOUD_AGENT.md). ### Barreras de protección Las barreras de protección son filtros previos/posteriores a la ejecución (vision-bridge, pii-masker, prompt-injection) aplicados dentro del flujo de chat. Se ejecutan antes de alcanzar la capa de herramientas/enrutamiento de MCP y emiten infracciones estructuradas al flujo de auditoría; no se invocan como herramientas MCP. - Implementación: `src/lib/guardrails/`. - Documentación: [docs/security/GUARDRAILS.md](../security/GUARDRAILS.md). Al depurar una llamada MCP que parece bloqueada, comprueba tanto el registro de auditoría de MCP (entradas `scope_denied:*`) como el historial de auditoría de las barreras de protección; una solicitud puede ser rechazada por una barrera de protección **antes** de llegar a la capa de aplicación de ámbitos de MCP. --- ## Endpoints de la API REST | Endpoint | Método | Descripción | Autenticación | | :--------------------- | :-------------------- | :----------------------------------------------------------------------------------------------------------------- | :---------------------------- | | `/api/mcp/status` | `GET` | Estado del servidor: señal de actividad, estado del transporte HTTP, resumen de actividad de auditoría | Administración (sesión/admin) | | `/api/mcp/tools` | `GET` | Catálogo de herramientas (nombre, descripción, ámbitos, fase, endpoints de origen) | Administración | | `/api/mcp/sse` | `GET` / `POST` | Endpoint de transporte SSE (condicionado por `mcpEnabled` + `mcpTransport === "sse"`) | Clave de API + ámbitos | | `/api/mcp/stream` | `POST`/`GET`/`DELETE` | Transporte HTTP con streaming (utiliza la cabecera `mcp-session-id`; `DELETE` finaliza la sesión) | Clave de API + ámbitos | | `/api/mcp/audit` | `GET` | Entradas del registro de auditoría de `mcp_tool_audit` (filtros: `limit`, `offset`, `tool`, `success`, `apiKeyId`) | Administración | | `/api/mcp/audit/stats` | `GET` | Estadísticas de auditoría agregadas (`totalCalls`, `successRate`, `avgDurationMs`, herramientas principales) | Administración | Archivos fuente: `src/app/api/mcp/{status,tools,sse,stream,audit,audit/stats}/route.ts`. Tanto el transporte SSE como el HTTP con streaming permanecen bloqueados hasta que el servidor MCP se habilita en Configuración (`mcpEnabled`) y se selecciona el `mcpTransport` adecuado. Si se configura el transporte incorrecto, la ruta devuelve HTTP 400 con una sugerencia para cambiar la configuración. --- ## Autenticación y ámbitos Las llamadas a herramientas MCP leen las cadenas de ámbito del llamador. Esa comprobación es uno de tres espacios de nombres independientes. Superar una comprobación no implica superar las demás. Las reglas están en [Tres espacios de nombres de ámbitos](#tres-espacios-de-nombres-de-ámbitos). El catálogo de herramientas está en [Ámbitos de herramientas MCP](#ámbitos-de-herramientas-mcp). ### Tres espacios de nombres de ámbitos `manage` en una clave de API, `read:compression` en una herramienta MCP y `read` en un token de acceso `oma_live_…` son tres permisos distintos. Los llamadores que envían un token de acceso `read` a una ruta de administración con operaciones de modificación reciben un HTTP 403: `Access token scope 'read' is insufficient; 'write' required.` Ese rango corresponde a `scopeSatisfies`. No consulta la tabla de MCP, y el comparador de MCP tampoco lo consulta. | Espacio de nombres | Credencial | Comprobador | Superar la comprobación permite | | :------------------------------ | :--------------------------------------------------------------------------------------- | :----------------------- | :--------------------------------------------------------------- | | Administración por clave de API | `api_keys.scopes` | `hasManageScope` | REST de administración para esa clave Bearer | | Ámbito aditivo de clave de API | el mismo array, una cadena exacta | el helper indicado abajo | Solo esa capacidad concreta | | Ámbitos de herramientas MCP | el mismo array; de lo contrario, `_meta` de MCP; de lo contrario, `OMNIROUTE_MCP_SCOPES` | `scopeMatches` | Esa herramienta, una vez activada la aplicación de ámbitos | | Token de acceso | `oma_live_…` | `scopeSatisfies` | La ruta de administración cuyo método y ruta requieren ese rango | La emisión de cada credencial se describe en [Autenticación de administración](../guides/MANAGEMENT-AUTH.md). #### Ámbitos de claves de API Un array `api_keys.scopes` desempeña dos funciones. Cada una utiliza funciones diferentes. **REST de administración.** `manage` y `admin` son los miembros de `MANAGEMENT_API_KEY_SCOPES` (`src/shared/constants/managementScopes.ts`). `hasManageScope` es lo que autoriza las rutas de administración para esa clave. `admin` permite realizar operaciones de administración en esas rutas. La palabra `admin` aquí no representa el rango del token de acceso ni se expande a ámbitos de herramientas MCP. **Cadenas aditivas.** Cada una se comprueba mediante una prueba de pertenencia exacta y permanece fuera de `MANAGEMENT_API_KEY_SCOPES`. | Ámbito | Superar la comprobación permite | | :----------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `mcp:connect` | Solo la excepción LOCAL_ONLY de `/api/mcp/` para direcciones que no sean loopback (`hasMcpConnectOrManageScope`). Una clave con `manage` o `admin` también supera esa excepción. | | `self:usage` | `GET /api/v1/me/status` para esta clave (`src/app/api/v1/me/status/route.ts`). `POST /api/keys` añade este ámbito al crear (`normalizeSelfServiceScopesForCreate`). | | `self:account-quota` | Cuotas de cuentas upstream dentro de esa carga útil de estado (`src/lib/usage/apiKeySelfService.ts`). La ruta de estado sigue requiriendo `self:usage`. | | `policy:bypass-provider-quota` | Las llamadas de inferencia de esta clave omiten la política de cuota del proveedor (`hasProviderQuotaBypassScope` en `src/sse/handlers/chat.ts`). | #### Coincidencia El catálogo es la tabla situada bajo [Ámbitos de herramientas MCP](#ámbitos-de-herramientas-mcp). No considere `MCP_SCOPE_LIST` en `src/shared/constants/mcpScopes.ts` como ese catálogo: es el subconjunto tipado original. Las herramientas posteriores declaran ámbitos adicionales junto a él (`read:notion`, `read:skills`, `read:local-corpus` y el resto de la tabla). `evaluateToolScopes` en `open-sse/mcp-server/scopeEnforcement.ts` permite una llamada cuando cada ámbito requerido coincide con algún ámbito concedido: - `*` coincide con todos los ámbitos requeridos. - Un ámbito concedido que termina en `*` coincide con un ámbito requerido que comienza con el prefijo anterior al asterisco. `read:*` coincide con `read:compression`. - Cualquier otro ámbito concedido coincide únicamente con la cadena requerida idéntica. Una clave cuyos ámbitos sean `["manage"]` no supera `scopeMatches` para `read:compression`. La misma llamada tampoco se permite con `admin`, `mcp:connect`, `read` ni `write` cuando esas son las únicas cadenas concedidas. No existe ninguna jerarquía entre los ámbitos de herramientas MCP, salvo el `*` final. La aplicación de ámbitos está desactivada a menos que `OMNIROUTE_MCP_ENFORCE_SCOPES=true` (valor predeterminado: `false`). Mientras esté desactivada, `evaluateToolScopes` permite la llamada y omite el catálogo. Mientras esté activada, HTTP utiliza `api_keys.scopes` de la clave Bearer como `authInfo` (consulte [Vinculación de ámbitos HTTP por clave](#vinculación-de-ámbitos-http-por-clave-7895)). Cuando no se resuelve ningún ámbito de clave, el conjunto concedido recurre a `_meta` de MCP y, después, a `OMNIROUTE_MCP_SCOPES`. #### Ámbitos de tokens de acceso Los tokens `oma_live_…` (`src/lib/accessTokens/scopes.ts`) incluyen `read`, `write` o `admin`. `scopeSatisfies` es un rango: `admin` abarca `write` y `read`, y `write` abarca `read`. Los ámbitos desconocidos no abarcan nada. `evaluateAccessTokenAuth` (`src/server/authz/accessTokenAuth.ts`) compara ese rango con `inferRequiredScope` (`src/server/authz/accessScopes.ts`): - `GET`, `HEAD` y `OPTIONS` requieren `read`. - Cualquier otro método requiere `write`. - Las rutas incluidas en `ADMIN_SCOPE_PREFIXES` requieren `admin` para todos los métodos. `/api/mcp` está en esa lista, por lo que un token de acceso `write` tampoco puede llamar a la interfaz HTTP de MCP. - Las rutas incluidas en `ADMIN_MUTATION_PREFIXES` requieren `admin` únicamente para las operaciones de modificación. `PATCH /api/keys/{id}` es una mutación y no figura en esas listas de administración, por lo que un token con alcance `read` recibe un error 403: `Access token scope 'read' is insufficient; 'write' required.` Un token de acceso con alcance `write` o `admin` cumple los requisitos de esa ruta. Un JWT del panel, el token de machine-id de la CLI en loopback y una clave de API con alcance `manage` o `admin` siguen otras ramas y no están limitados por esta jerarquía. Un token de acceso que supera `scopeSatisfies` para `/api/mcp` solo ha superado la puerta de administración. Las llamadas a herramientas siguen ejecutando `scopeMatches` con los alcances de las claves de API. La jerarquía del token de acceso no es una entrada para `scopeMatches`. ### Alcances de las herramientas MCP La aplicación de los alcances está centralizada en `open-sse/mcp-server/scopeEnforcement.ts`. Cada herramienta requiere alcances específicos: | Alcance | Herramientas | | :-------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `read:health` | `get_health`, `get_provider_metrics`, `simulate_route`, `explain_route`, `best_combo_for_task`, `db_health_check` | | `read:combos` | `list_combos`, `get_combo_metrics`, `simulate_route`, `best_combo_for_task`, `test_combo` | | `write:combos` | `switch_combo`, `set_routing_strategy` | | `read:quota` | `check_quota` | | `read:usage` | `cost_report`, `get_session_snapshot`, `explain_route` | | `read:models` | `list_models_catalog` | | `execute:completions` | `route_request`, `test_combo` | | `execute:search` | `web_search`, `x_search`, `web_fetch` | | `write:budget` | `set_budget_guard` | | `write:resilience` | `set_resilience_profile`, `db_health_check` | | `pricing:write` | `sync_pricing` | | `read:cache` | `cache_stats` | | `write:cache` | `cache_flush` | | `read:compression` | `compression_status`, `list_compression_combos`, `compression_combo_stats` | | `write:compression` | `compression_configure`, `set_compression_engine` | | `read:proxies` | `oneproxy_fetch`, `oneproxy_rotate`, `oneproxy_stats` | | `read:notion` | `notion_search`, `notion_get_page`, `notion_list_block_children`, `notion_query_database`, `notion_get_database` | | `write:notion` | `notion_append_blocks` | | `read:memory` | `memory_search` | | `write:memory` | `memory_add`, `memory_clear` | | `read:skills` | `skills_list`, `skills_executions` | | `write:skills` | `skills_enable` | | `execute:skills` | `skills_execute` | | `read:catalog` | `agent_skills_list`, `agent_skills_get`, `agent_skills_coverage` | | `read:tools` | `omniroute_tool_search` | | `read:radar` | `omniroute_radar_catalog` | | `read:gamification` | `gamification_profile`, `gamification_rank`, `gamification_leaderboard`, `gamification_badges`, `gamification_servers`, `gamification_anomalies` | | `write:gamification` | `gamification_invite`, `gamification_transfer` | | `read:plugins` | `plugin_list`, `plugin_executions` | | `write:plugins` | `plugin_scan`, `plugin_install`, `plugin_uninstall`, `plugin_activate`, `plugin_deactivate`, `plugin_configure` | | `read:obsidian` | 13 herramientas de lectura — `obsidian_list_vault`, `obsidian_read_note`, `obsidian_search_simple`, `obsidian_search_structured`, `obsidian_get_periodic_note`, `obsidian_sync_status`, … | | `write:obsidian` | 9 herramientas de escritura — `obsidian_write_note`, `obsidian_append_note`, `obsidian_patch_note`, `obsidian_move_note`, `obsidian_delete_note`, `obsidian_sync_trigger`, … | | `read:local-corpus` | `local_corpus_search`, `local_corpus_read`, `local_corpus_status` | Se admiten ámbitos con comodines: `read:*` concede todos los ámbitos de lectura y `*` concede acceso completo. ### `mcp:connect` — capacidad restringida de ruta (#7895) Acceder al transporte HTTP/SSE de MCP (`/api/mcp/*`) desde una dirección que no sea de bucle local requiere la excepción LOCAL_ONLY de `/api/mcp/` (consulte `docs/security/ROUTE_GUARD_TIERS.md`). Históricamente, esa excepción solo aceptaba una clave de API con ámbito completo `manage`/`admin`, lo cual era demasiado amplio para un cliente que solo necesitara comunicarse con MCP. `src/shared/constants/managementScopes.ts` ahora exporta `MCP_CONNECT_SCOPE = "mcp:connect"`: un ámbito adicional y restringido (siguiendo el mismo precedente que `SELF_USAGE_SCOPE`) que autoriza ÚNICAMENTE la omisión de `/api/mcp/` en `src/server/authz/policies/management.ts`; no concede acceso a ninguna otra ruta de administración y se mantiene deliberadamente FUERA de `MANAGEMENT_API_KEY_SCOPES`. Una clave que posea `manage`/`admin` sigue superando la excepción sin cambios; `mcp:connect` es una alternativa con menos privilegios para clientes remotos que solo usan MCP, comprobada mediante `hasMcpConnectOrManageScope()`. ### Vinculación de ámbitos HTTP por clave (#7895) A través de HTTP/SSE, `open-sse/mcp-server/httpTransport.ts` ahora resuelve los `api_keys.scopes` reales del cliente mediante `resolveMcpCallerAuthInfo()` (`open-sse/mcp-server/httpAuthContext.ts`) y los pasa al método `transport.handleRequest(req, { authInfo })` del SDK de MCP, de modo que `extra.authInfo.scopes`, que llega a cada llamada de herramienta, refleje los ámbitos propios de la clave Bearer. `resolveCallerScopeContext()` de `scopeEnforcement.ts` ya daba prioridad a `authInfo` sobre `_meta` y la alternativa de la variable de entorno `OMNIROUTE_MCP_SCOPES`; esto solo rellena esa primera fuente, la de mayor prioridad, que anteriormente no recibía datos a través de HTTP. Cuando no se resuelve ninguna clave de API (sin encabezado o con una clave no válida), `authInfo` permanece como `undefined` y la resolución continúa mediante la cadena existente de metadatos/variables de entorno sin cambios. Esto NO cambia el valor predeterminado de `OMNIROUTE_MCP_ENFORCE_SCOPES`: la aplicación de ámbitos aún debe habilitarse explícitamente; este cambio solo hace que la ruta por clave tenga prioridad una vez habilitada. stdio no tiene identidad por cliente (consulte `mcpCallerIdentity.ts`) y no se ve afectado: sigue utilizando la cadena alternativa de `_meta`/variables de entorno. --- ## Variables de entorno | Variable | Valor predeterminado | Propósito | | :-------------------------------------- | :---------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `OMNIROUTE_BASE_URL` | `http://localhost:20128` | URL base que utiliza el servidor MCP al llamar a las API internas de OmniRoute | | `OMNIROUTE_API_KEY` | (vacío) | Clave de API reenviada como `Authorization: Bearer` a las llamadas a la API interna | | `OMNIROUTE_MCP_ENFORCE_SCOPES` | `false` (solo `"true"` lo habilita) | Cuando está habilitado, los ámbitos faltantes deniegan las llamadas a herramientas y registran `scope_denied:` en el registro de auditoría | | `OMNIROUTE_MCP_SCOPES` | (vacío) | Lista de ámbitos permitidos separados por comas que se consideran «disponibles» de forma predeterminada (se utiliza cuando el autor de la llamada no proporciona sus propios ámbitos) | | `OMNIROUTE_MCP_COMPRESS_DESCRIPTIONS` | (sin definir = activado) | Cuando se establece en `0/false/off/no`, deshabilita la compresión de descripciones de MCP durante el registro | | `OMNIROUTE_MCP_DESCRIPTION_COMPRESSION` | (sin definir = activado) | Alias alternativo para la misma opción anterior | | `OMNIROUTE_MCP_FETCH_TIMEOUT_MS` | `10000` | Límite de tiempo antes de cancelar las lecturas internas de administración (estado, resiliencia, combinaciones, cuota y uso) | | `OMNIROUTE_MCP_UPSTREAM_TIMEOUT_MS` | `60000` | Límite de tiempo antes de cancelar los saltos que esperan a un proveedor (`route_request`, `web_search`, `web_fetch`) | | `MCP_TOOL_DENY` | (sin definir = sin filtro) | Nombres de herramientas separados por comas que deben excluirse de `tools/list` (reducción de la cardinalidad de herramientas; véase más abajo) | | `MCP_TOOL_ALLOW` | (sin definir = sin filtro) | Nombres de herramientas separados por comas que deben conservarse de forma exclusiva (modo de lista de permitidos; véase más abajo) | | `DATA_DIR` | `~/.omniroute` | El archivo de latido se escribe en `${DATA_DIR}/runtime/mcp-heartbeat.json` | --- ## Compresión de descripciones Los registros de herramientas, indicaciones y recursos de MCP pueden comprimir las descripciones durante el registro o el listado para reducir el volumen de metadatos expuesto a los clientes (y, por lo tanto, el coste del contexto de las indicaciones). La implementación se encuentra en `open-sse/mcp-server/descriptionCompressor.ts` y está integrada en el servidor MCP mediante `compressMcpRegistryMetadata` dentro de `createMcpServer()`. - La compresión se aplica al texto de la descripción utilizando el conjunto de reglas Caveman (`getRulesForContext("all", "full")`) con extracción de bloques preservados (fragmentos de código, bloques delimitados, etc.), de modo que no se altera el contenido estructural. - Puede activarse o desactivarse en cada despliegue mediante el valor `compression.mcpDescriptionCompressionEnabled` de la tabla de configuración `key_value` (valor predeterminado: habilitado), expuesto en la interfaz de usuario como **Analítica → Compresión de descripciones de MCP**. - Puede activarse o desactivarse en todo el proceso mediante `OMNIROUTE_MCP_COMPRESS_DESCRIPTIONS=false` o `OMNIROUTE_MCP_DESCRIPTION_COMPRESSION=false`. - Las estadísticas en tiempo real se muestran mediante `omniroute_compression_status` en `analytics.mcpDescriptionCompression` y se etiquetan con `source: "mcp_metadata_estimate"` para diferenciarlas de los comprobantes de uso reales del proveedor. --- ## Reducción de la cardinalidad de herramientas (F4.3) La compresión de descripciones reduce los metadatos de cada herramienta; la **reducción de la cardinalidad de herramientas** va un paso más allá al reducir _cuántas_ herramientas se anuncian. Anunciar menos herramientas en el manifiesto `tools/list` reduce el coste de tokens por solicitud que el modelo del cliente paga por el catálogo de herramientas (compresión de «capa 5»). La implementación es un filtro puro y sin estado en `open-sse/mcp-server/toolCardinality.ts` (`reduceToolManifest`), integrado en el bucle de registro de `createMcpServer()` (`open-sse/mcp-server/server.ts`). **Activación voluntaria; desactivado de forma predeterminada.** El filtro solo se ejecuta cuando se establece al menos una de las dos variables de entorno; si no se establece ninguna, las 110 herramientas se anuncian sin cambios. | Variable | Modo | | :--------------- | :-------------------------------------------------------------------------------------------------------------------- | | `MCP_TOOL_DENY` | Lista de bloqueo: nombres de herramientas separados por comas que siempre se omiten de `tools/list` | | `MCP_TOOL_ALLOW` | Lista de permitidos: nombres de herramientas separados por comas; solo se conservan estos y se omiten todos los demás | `deny` tiene prioridad sobre `allow`. Los nombres se separan mediante comas, se eliminan los espacios en blanco circundantes y se ignoran las entradas vacías. Ejemplos: ```bash # Omitir dos herramientas del catálogo MCP_TOOL_DENY="omniroute_get_health,omniroute_list_combos" omniroute --mcp # Anunciar solo las herramientas de enrutamiento y cuota (modo de lista de permitidos) MCP_TOOL_ALLOW="omniroute_route_request,omniroute_check_quota" omniroute --mcp ``` **Cómo se eliminan las herramientas filtradas:** el registro siempre se completa correctamente; después, se aplica `.disable()` a las herramientas rechazadas por el perfil en el identificador del SDK de MCP, por lo que nunca aparecen en `tools/list`, aunque el cableado permanece intacto (activación y desactivación limpias, sin volver a registrarlas). El analizador de perfiles es `readMcpToolProfileFromEnv(process.env)`, que devuelve `null` (sin filtrado) cuando ambas variables están vacías. La estructura más completa `ToolProfile` subyacente a `reduceToolManifest` también admite el filtrado por intersección de ámbitos (`allowScopes`, con coincidencias mediante comodines del tipo `read:*`) y un límite determinista `maxTools`, pero estas dos opciones necesitan el manifiesto completo durante el registro y actualmente **no** se exponen mediante variables de entorno (un mecanismo de enlace a nivel de `tools/list` está registrado como tarea pendiente). `estimateManifestTokens()` permite comparar el coste en tokens del manifiesto antes y después de la reducción. --- ## Latido del entorno de ejecución El transporte stdio guarda el estado de actividad en `${DATA_DIR}/runtime/mcp-heartbeat.json` cada 5 segundos. El panel (`/api/mcp/status`) consulta este archivo junto con el estado del PID para determinar `online`. En su lugar, los transportes HTTP informan del estado mediante `getMcpHttpStatus()` dentro del proceso (sin escribir archivos). La instantánea del latido contiene: ```json { "pid": 12345, "startedAt": "2026-05-13T12:34:56.000Z", "lastHeartbeatAt": "2026-05-13T12:35:01.000Z", "version": "1.8.1", "transport": "stdio", "scopesEnforced": false, "allowedScopes": [], "toolCount": 110 } ``` --- ## Registro de auditoría Cada llamada a una herramienta se registra en la tabla `mcp_tool_audit` de SQLite mediante `open-sse/mcp-server/audit.ts`: - Nombre de la herramienta, argumentos (con hash o truncados según el valor `auditLevel` de cada herramienta) y resultado - Duración en ms, indicador de éxito o fallo y mensaje de error (cuando corresponda) - Hash de la clave de API y marca de tiempo - Las denegaciones por ámbito se registran como `scope_denied:` junto con la lista de ámbitos faltantes Use el panel o los endpoints REST `/api/mcp/audit` y `/api/mcp/audit/stats` para consultar las llamadas recientes. --- ## Archivos | Archivo | Propósito | | :----------------------------------------------------------------------- | :----------------------------------------------------------------------------------------- | | `open-sse/mcp-server/server.ts` | Factoría del servidor MCP, punto de entrada stdio y registros de herramientas con ámbito | | `open-sse/mcp-server/httpTransport.ts` | Transporte SSE + HTTP transmitible (gestión de sesiones) | | `open-sse/mcp-server/scopeEnforcement.ts` | Evaluación del ámbito de las herramientas y resolución del llamante | | `open-sse/mcp-server/audit.ts` | Registro de auditoría de llamadas a herramientas (`mcp_tool_audit`) | | `open-sse/mcp-server/runtimeHeartbeat.ts` | Escritor de latidos de stdio (`mcp-heartbeat.json`) | | `open-sse/mcp-server/descriptionCompressor.ts` | Compresión de descripciones para los registros de herramientas, prompts y recursos | | `open-sse/mcp-server/schemas/tools.ts` | Esquemas Zod + registro de herramientas (`MCP_TOOLS`, 45 entradas) | | `open-sse/mcp-server/tools/advancedTools.ts` | Manejadores de herramientas de la fase 2, caché y 1proxy | | `open-sse/mcp-server/tools/compressionTools.ts` | Manejadores de herramientas de compresión | | `open-sse/mcp-server/tools/memoryTools.ts` | Definiciones de herramientas de memoria (3 herramientas) | | `open-sse/mcp-server/tools/skillTools.ts` | Definiciones de herramientas de habilidades (4 herramientas) | | `open-sse/mcp-server/tools/notionTools.ts` | Definiciones de herramientas de fuente de contexto de Notion (6 herramientas) | | `open-sse/mcp-server/tools/gamificationTools.ts` | Definiciones de herramientas de gamificación (8 herramientas) | | `open-sse/mcp-server/tools/pluginTools.ts` | Herramientas de registro y gestión de plugins (8 herramientas) | | `src/app/api/mcp/status/route.ts` | Endpoint `/api/mcp/status` | | `src/app/api/mcp/tools/route.ts` | Endpoint `/api/mcp/tools` | | `src/app/api/mcp/sse/route.ts` | Ruta de transporte SSE `/api/mcp/sse` | | `src/app/api/mcp/stream/route.ts` | Ruta de transporte HTTP transmitible `/api/mcp/stream` | | `src/app/api/mcp/audit/route.ts` | Consulta del registro de auditoría `/api/mcp/audit` | | `src/app/api/mcp/audit/stats/route.ts` | Métricas de auditoría agregadas de `/api/mcp/audit/stats` | | `src/lib/notion/api.ts` | Cliente de la API REST de Notion (reintentos, tiempo de espera y clasificación de errores) | | `src/lib/db/notion.ts` | Persistencia del token de Notion (tabla `key_value`) | | `src/app/api/settings/notion/route.ts` | API de configuración de Notion (GET/POST/DELETE) | | `src/app/(dashboard)/dashboard/endpoint/components/NotionSourceCard.tsx` | Interfaz de gestión del token de Notion | | `tests/unit/notion-api.test.ts` | Pruebas del cliente de la API de Notion (7) | | `tests/unit/notion-tools.test.ts` | Pruebas de aplicación del ámbito de las herramientas de Notion (10) | | `tests/unit/db/notion.test.mjs` | Pruebas del módulo de base de datos de Notion (3) |