El Model Context Protocol (MCP) es una forma estándar de darle a un agente de IA un conjunto de herramientas. Describes lo que sabe hacer tu producto, el cliente del agente se conecta y, a partir de ahí, el agente puede llamar a esas herramientas en mitad de una conversación, igual que lee un archivo o ejecuta un comando.
La especificación es pequeña y la implementación no es lo difícil. Un servidor que funcione sale en una tarde. Lo que exigió trabajo de diseño de verdad fue conseguir que un agente lo usara correctamente: sin adivinar identificadores, sin pedir datos equivocados y sin concluir con total seguridad que una salida vacía significa que no hay datos.
Estas son las decisiones que importaron cuando lancé el servidor MCP de BugDump, y sirven para cualquier herramienta de desarrollo que se plantee tener uno.
Primero, qué cambia MCP en la práctica
Sin MCP, conectar un agente a tu producto significa que el usuario hace de integración. Abre tu panel, busca los datos que importan, los copia y los pega en la conversación. Cada pieza de contexto se traslada a mano, así que el agente tiene tanto contexto como la persona esté dispuesta a copiar.
Con MCP, el agente busca los datos por su cuenta. En BugDump, la diferencia concreta es entre esto:
Aquí tienes un reporte de bug. [pega 200 líneas de salida de la consola]
y esto:
Mira la tarea #42 en BugDump y arréglala.
En la segunda versión, el agente trae la tarea, lista sus reportes, lee la telemetría de la consola y de la red, cruza el stack trace con los archivos de código reales del repositorio y propone un cambio. Nadie abrió el panel. El agente tuvo acceso al reporte entero, no a la parte que una persona consideró que valía la pena copiar. Y decidir qué vale la pena copiar es justo el criterio que la depuración tiene que producir, no consumir.
Ahí está la ventaja, y por eso el objetivo del diseño no es «exponer la API». Es «exponer una API por la que un agente se mueva sin mapa».
1. Vincula la clave a un solo alcance, para siempre
Mi primer diseño tenía un parámetro de proyecto en cada herramienta. Era la traducción obvia de la API REST, y estaba mal por partida doble.
Estaba mal por seguridad. Una clave MCP vive en un archivo de configuración y la usa un proceso autónomo. El radio de impacto de esa clave debe ser tan pequeño como lo permita el trabajo.
Estaba mal por usabilidad. Si le das al agente un parámetro projectId y ningún ID de proyecto, intentará rellenarlo. Probará con proj_1. Pasará el nombre del proyecto. Inventará algo plausible, recibirá un error y probará otra invención. Un parámetro que se puede adivinar, se adivinará.
Por eso una clave MCP de BugDump está vinculada a un único proyecto, para siempre, y ninguna herramienta acepta un argumento de proyecto. No hay nada que adivinar. Si un usuario pregunta por otro proyecto, el servidor solo puede decir a qué proyecto está limitada esta clave, mediante una herramienta get_current_project que existe únicamente para que el agente se oriente en lugar de especular.
La regla general: todo parámetro que el agente no pueda deducir de una respuesta anterior es un parámetro que alucinará. Elimínalo o haz que se pueda descubrir.
2. Diseña la cadena de llamadas de forma explícita
Las herramientas de BugDump forman una secuencia pensada a propósito:
list_tasks → find a task, get its taskId
get_task → read one task
list_reports_for_task → list a task's reports, get each reportId
get_report → read one report
get_report_telemetry → page through everything in that report
Cada ID que se pasa a una herramienta tiene que haber salido de una respuesta anterior. Las instrucciones del servidor lo dicen con esas palabras, junto con la prohibición explícita de construir IDs.
El fallo que esto evita es sutil y caro. Los agentes paralelizan de forma agresiva, y la mayoría de las veces hacen bien. Pero un agente que decide lanzar en paralelo varias llamadas a get_report antes de tener ningún ID de reporte se los fabricará, recibirá siete errores y gastará buena parte del contexto en recuperarse. La instrucción que lo arregla es la que dice que las llamadas en paralelo solo son seguras con IDs que ya tienes.
3. Acepta los identificadores que usan las personas
En BugDump, cada tarea tiene un UUID y un ID público que se muestra como #42. Los usuarios dicen «la tarea 42». Nadie ha dicho nunca «la tarea 9f8c1a4e-...».
get_task acepta cualquiera de los dos. Es una concesión pequeña con un efecto desproporcionado, porque elimina toda una clase de primeros intentos fallidos. El agente prueba lo que dijo la persona, y funciona.
Busca el identificador que tus usuarios escriben en Slack. Acepta ese.
4. Devuelve resúmenes por defecto, pero di qué recortaste
Un solo reporte de bug puede traer miles de entradas de consola, cientos de peticiones de red con sus cuerpos, capturas de pantalla y una repetición de sesión. Devolverlo todo por defecto inundaría el contexto del agente en la primera llamada y no dejaría sitio para el trabajo de verdad.
Por eso get_report devuelve por defecto un resumen compacto: las entradas de consola recientes y los metadatos de red sin los cuerpos.
Lo crítico es la siguiente frase de la respuesta. El resumen dice qué se recortó. Nada de recortes silenciosos: lo dice de forma explícita, en la propia respuesta.
El truncado silencioso es el peor fallo que puede cometer quien diseña una herramienta, porque no produce un error. Produce una respuesta equivocada dicha con seguridad. Un agente que recibe un registro de red truncado sin ninguna señal de que lo esté le dirá al usuario que no hubo peticiones fallidas. Nadie descubre que era falso hasta mucho después.
Es la misma disciplina que --max-count en una herramienta de búsqueda: informa del límite que alcanzaste. Si tu herramienta limita algo, ese límite tiene que aparecer en la salida.
5. Dale al agente una forma de obtener el resto
Un resumen solo es aceptable si existe una lectura completa. Para eso está get_report_telemetry: recorre por páginas la consola, la red con cuerpos o las acciones del usuario en bloques cronológicos, con offset y nextOffset, y un indicador hasMore que pasa a false cuando el flujo se agota.
Dos propiedades hacen que esto funcione para un agente y no solo para un programa.
Bloques cronológicos, no arbitrarios. Ordenar por tiempo hace que una lectura parcial siga teniendo sentido. Un agente que trae las dos primeras páginas tiene la primera parte de la historia, no una muestra al azar.
Una condición de fin explícita. hasMore: false es un hecho sobre el que el agente puede actuar. «El array volvió más corto que el límite» es una inferencia, y las inferencias al final de largos bucles de herramientas son el punto donde los agentes se ponen creativos.
6. Escribe las instrucciones para el agente, no para el usuario
Los servidores MCP incluyen un bloque de instrucciones que entra en el contexto del agente. Es tentador escribir ahí texto de marketing. Es mucho mejor usar ese espacio para lo que no se deduce de los esquemas de las herramientas:
El orden en que hay que llamar a las herramientas
La prohibición de inventar IDs
Qué llamadas se pueden hacer en paralelo y cuáles no
Qué significa, y qué no, que «el resumen no mostró nada»
Esa última se gana su sitio. Mis instrucciones dicen, en esencia: la respuesta resumida te dice qué se recortó, así que no asumas que «el resumen no muestra nada» significa «no hay nada». Esa sola frase evita una conclusión errónea concreta que vi sacar a los agentes.
Trata el bloque de instrucciones como una nota para un colega competente que se incorpora a mitad de la tarea. Las firmas de tipos las sabe leer. Lo que necesita es lo que solo se aprende equivocándose.
7. Solo lectura también es una funcionalidad
El servidor MCP de BugDump expone siete herramientas, y las siete leen. Ninguna crea una tarea, cierra una tarea ni publica un comentario.
Fue una decisión pensada, no algo a medio terminar. El flujo de trabajo que habilita el servidor es la investigación: reunir las pruebas, cruzarlas con el código y proponer un arreglo. La mitad del flujo que escribe (decidir que un bug es real, que es un duplicado, que está resuelto) es donde el criterio humano hace el trabajo de verdad.
Hay también un argumento más simple. Una clave de solo lectura que se filtra es un problema de exposición de datos. Una clave de lectura y escritura que se filtra, en manos de un proceso autónomo, es un problema de integridad de datos. Entre las dos, y sin necesitar escritura para el flujo de trabajo al que apuntaba, la decisión se tomó sola.
Empieza con solo lectura. Añade escritura cuando un flujo de trabajo la exija, y dales a esas claves un alcance propio.
El requisito incómodo
Por debajo de todo esto hay una condición previa que no tiene nada que ver con el diseño del protocolo.
Un agente no puede hacer una pregunta de seguimiento. No puede escribirle a quien reportó el bug para preguntarle qué navegador usaba. Tiene exactamente una oportunidad con las pruebas que haya, y si son escasas, producirá una respuesta fluida, bien estructurada y completamente especulativa.
Así que el valor de un servidor MCP tiene como techo la calidad de los datos que hay detrás. El mío funciona porque un reporte de BugDump ya contiene la consola, el registro de red, la repetición de sesión, las acciones del usuario y el entorno completo, todo capturado automáticamente en el momento en que ocurrió el bug. El protocolo solo lo traslada.
Si estás pensando en un servidor MCP para tu propia herramienta, esa es la pregunta que conviene responder primero: ¿los datos que hay detrás son lo bastante completos como para actuar sin una pregunta de seguimiento? Si la respuesta es sí, MCP es una capa fina que vale la pena. Si es no, el protocolo solo hará que los huecos sean más fáciles de alcanzar.
Te puede interesar
Por qué tu agente de IA hace 40 llamadas para responder una pregunta — el problema N+1 trasladado del ORM al servidor MCP, y las tres preguntas que lo resuelven.
Autenticación en servidores MCP: por qué los agentes de IA necesitan tokens personales — qué cambia cuando el agente puede mover tareas y escribir comentarios, y cómo los tokens personales dejan claro quién hizo cada cambio.
Depura reportes de bug de usuarios con Claude Code: el servidor MCP de BugDump — cómo un asistente de IA lee la consola, la red y la repetición de sesión de un reporte para encontrar el bug en tu código.