Building an MCP server so my IDE could do structural code review

1 de junio de 2026·Implementations

Una librería de calidad estructurada es inútil si el consumidor real es un humano con curl. Esa frase es la conclusión a la que llegué después de seis meses tratando de que agentguard-lib se usara y rebotando contra el mismo problema: la calidad del código generado por IA tiene que evaluarse en el momento en que se genera, no después. Y el agente que está generando ya vive dentro del IDE.

El movimiento que cambió la adopción no fue mejorar la librería. Fue cambiar quién la consume. Esa decisión de diseño — quién es el consumidor primario — termina pesando más que casi cualquier otra que tomes en una herramienta de developer tooling.

Por qué REST puro estaba fallando como UX

Nadie iba a abrir Postman para validar un PR. Esto suena trivial cuando lo escribes, pero costó tiempo aceptarlo. La idea inicial era "si la API es buena, los devs la van a integrar en su CI". La realidad fue: los devs ya tienen demasiadas integraciones de CI y agregar una más para una herramienta que aún no demostró valor en su flujo diario es fricción inaceptable. La integración requiere convencer a alguien de invertir tiempo upfront para un beneficio futuro incierto. Esa apuesta casi nunca se hace.

El SDK de TypeScript ayudaba — bajaba el costo de integración a unas líneas de código. Pero seguía requiriendo que alguien decidiera integrarlo en cada herramienta, en cada repo, en cada pipeline. El gating era humano y lento. Y peor: cada integración era distinta. La integración con Jenkins no era la integración con GitHub Actions ni la integración con la pre-commit hook local. Multiplicar el esfuerzo por cada superficie es la receta para que la adopción se estanque.

Lo peor era el timing del feedback. Cuando la validación corre en CI, llega después del commit. Después del push. A veces después de la review. El loop de iteración tiene minutos u horas entre que el código se escribe y que la herramienta opina. En la era pre-IA esto era aceptable, porque la generación de código también era lenta — un humano escribiendo a velocidad humana puede absorber feedback en minutos sin que se rompa el flow. Con un agente generando 200 líneas en 30 segundos, no lo es. El feedback que llega minutos después es feedback que llega cuando el agente ya pasó a la siguiente cosa.

Hay una capa más, que es la cognitiva. Cuando el feedback de calidad llega en CI, el desarrollador ya hizo el contexto-switch a otra cosa. Volver al PR para arreglar lo que CI marcó es interrupción. Cuando el feedback llega durante la generación, está dentro del mismo contexto mental. La distancia entre "señal" y "acción" determina si la señal se usa o se ignora.

Qué cambia con MCP

MCP — Model Context Protocol — invierte la pregunta. En vez de exponer la herramienta y esperar que alguien la integre, la herramienta aparece como tool dentro del agente que el desarrollador ya está usando: Cline, Claude Desktop, VSCode con cliente MCP compatible. El agente la ve nativamente y la puede llamar sin que el dev haga nada explícito. La integración deja de ser un proyecto y se vuelve un toggle de configuración.

El transporte es stdio. Eso significa que no hay un servidor que mantener para cada cliente — el cliente lanza el proceso, habla por stdin/stdout, y lo mata cuando termina. La operación es local. La latencia es de milisegundos, no de roundtrip a un cluster. Para casos de tooling donde la latencia importa — y para feedback durante generación, importa — esa decisión de transporte es la diferencia entre usable y no.

El feedback llega durante la generación, no después. El agente termina de escribir el endpoint, llama a validate(), recibe el rúbrico, y puede iterar dentro del mismo turn de conversación. El dev no tuvo que abrir nada. No tuvo que recordar nada. La herramienta se volvió invisible — que es la definición de UX que escala. Las herramientas que requieren ser recordadas no se usan; las que aparecen en el flujo natural sí.

Hay una propiedad adicional que vale la pena nombrar: la auditabilidad mejora, no empeora. Como cada call queda registrado en la transcripción del agente, hay trazabilidad de qué se validó, cuándo, con qué resultado. Es mejor logging operacional que muchos pipelines de CI tienen, porque está enlazado al contexto de la decisión.

Cómo está cableado, concretamente

El entry point está declarado en pyproject.toml: agentguard.mcp.server:run_mcp_server. Cuando el cliente arranca el proceso, esa función se ejecuta y abre el canal stdio. El paquete está publicado en PyPI como rlabs-agentguard, así que la instalación es pip install rlabs-agentguard y queda disponible el comando agentguard-mcp en el PATH.

La configuración en el lado del cliente es un objeto JSON simple. En cline_mcp_settings.json se ve así: nombre del server, comando que lo lanza, transport stdio, y variables de entorno opcionales. Tres campos esenciales. No hay puertos, no hay credenciales de cluster, no hay TLS — porque todo es local. La superficie de configuración mínima es deliberada: cada campo adicional es una decisión que el usuario tiene que tomar, y cada decisión es una fuente de error.

La API key es opcional. Los arquetipos built-in — api_backend, library, cli_tool, react_spa, web_app, script y los demás que vienen en la lib — corren sin ninguna credencial externa. Esto es importante porque baja el umbral de prueba a cero: instalar, configurar tres líneas, listo. Para evaluar si la herramienta sirve para tu flujo, no necesitas crear una cuenta. El Demo #06 del canal de RLABS muestra cómo se configura la key cuando se quieren usar arquetipos del marketplace o features que la requieran.

Esa decisión "key opcional" no es cosmética. Cada vez que una herramienta requiere creación de cuenta para evaluar, pierde un porcentaje grande de potenciales adoptantes ahí mismo. Bajar el primer-touch a "instala y prueba" expande el embudo de adopción en órdenes de magnitud.

MCP tool lifecycledefine then describe then expose then consume define python signature describe docstring + types expose MCP server consume IDE agent calls it no separate SDK, no separate docs, no separate auth

El primer momento en que funcionó

La primera vez que vi el sistema completo en acción fue así: Cline estaba generando un endpoint nuevo. Terminó la generación. Sin que yo le pidiera nada, llamó a validate() como herramienta. El tool devolvió el rúbrico con score por cada una de las 13 dimensiones. Cline leyó el reporte, identificó que observability estaba bajo, y reescribió el endpoint agregando logging estructurado. Todo dentro del mismo turn.

La parte interesante no es la auto-corrección — es que el agente decidió validar sin que yo se lo pidiera. La herramienta estaba ahí, era barata de llamar, y tenía utilidad obvia para la tarea que estaba haciendo. Eso es lo que define adopción real: cuando el consumidor no tiene que recordarte, cuando la herramienta encaja tan bien en el flujo que usarla es la opción default.

El loop completo está documentado contra el caso del note-api en el Demo #07 — un proyecto FastAPI con arquitectura hexagonal que está en examples/note-api del repo agentguard-demo. El demo es interesante porque muestra el ciclo completo end-to-end: generación con stages, validación con rúbrica, iteración basada en el reporte, y output final que pasa las dimensiones críticas para un api_backend. El protocolo de evaluación que sustenta esa rúbrica está en paper §3.

Un detalle operacional que aprendí ahí: el agente llama a la herramienta más seguido cuando las descripciones de las tools son específicas. "valida calidad de código" se ignora. "evalúa código generado contra rúbrica de 13 dimensiones por arquetipo y devuelve scores con señales de qué archivo está bajo en qué dimensión" se llama. La descripción de tool es prompt engineering en sí misma.

Limitaciones honestas

MCP es protocolo joven. El spec se mueve rápido — mcp>=1.0 es un piso, pero los cambios siguen llegando. Eso significa que cada release puede traer ajustes en cómo se declaran tools, cómo se serializan respuestas, qué clientes soportan qué partes del spec. No es bleeding edge — es early adopter con todo lo que eso implica, incluyendo la necesidad de mantener compatibilidad con varias versiones del protocolo si tu base de usuarios es amplia.

Debuggear MCP tools es más doloroso que debuggear REST. Cuando algo falla en un endpoint HTTP tienes status codes, response bodies, herramientas de inspección con décadas de madurez: curl, Postman, browser dev tools, proxies como Charles o mitmproxy. Con MCP por stdio, debugar es leer logs del proceso y reproducir el call manualmente. La tooling alrededor del protocolo va a mejorar — está en eso ahora — pero hoy es trabajo.

Y no todos los clientes implementan el protocolo igual. Cline, Claude Desktop y los clientes VSCode tienen diferencias en cómo presentan tools al modelo, cómo manejan errores, qué nivel de auto-call permiten, cómo muestran resultados. Hay que probar contra el cliente que tu equipo va a usar, no asumir portabilidad perfecta. La promesa del protocolo es alta; la realidad de las implementaciones está un paso atrás, como es habitual con specs jóvenes.

Transferable Principle

Si estás construyendo tooling de calidad, seguridad o governance, la pregunta importante en 2026 no es "¿cómo expongo esto?" — es "¿quién es el consumidor real?". Esa respuesta cambió. Y si no actualizas tu modelo de quién consume, vas a invertir en interfaces que sirvieron en 2020 y no sirven hoy.

Humanos con un CLI = adopción lenta. Agentes en el IDE = adopción inmediata. No porque los agentes sean más inteligentes — porque están ahí, en el momento exacto donde la herramienta tiene utilidad. La fricción de invocación es cero, y cuando la fricción de invocación es cero, el uso explota.

REST sigue siendo válido. Pero como wrapper, no como interfaz primaria para agentes. La interfaz primaria, hoy, es el protocolo que el agente entiende nativamente. Esto no es "REST está muerto" — es "REST cambió de lugar en la jerarquía", de interfaz primaria a capa de implementación.

Pregunta para comentarios: ¿qué tooling interno en tu equipo está esperando un consumidor agente — y todavía lo estás exponiendo como CLI?

#AI #GenAI #DeveloperExperience #Engineering #OpenSource

Escríbenos por WhatsApp