El equipo ejecuta nueve herramientas MCP estrictamente acotadas con un modelo de mutación deny-by-default. La arquitectura capturó una falla crítica de producción que las pruebas unitarias no pudieron: un error null-pointer en Lambda en el resolver create_collection.
El servidor MCP se ejecuta en Go utilizando la biblioteca mcp-go y se comunica con AWS AppSync a través de GraphQL. La autenticación usa bearer tokens OIDC—short-lived y scoped por usuario, reforzados por la directiva @aws_oidc de AppSync. Las claves API compartidas fueron rechazadas: toda solicitud LLM llevaría acceso idéntico independientemente de la identidad del llamador. OIDC preserva trail de auditoría y scoping de datos. El servidor también soporta firma AWS SigV4 y autenticación por clave API como fallbacks. El método activo se registra en inicio: level=INFO msg=starting mcp-server auth=oidc mutations=false tools=8 resources=2 prompts=2.
Seis herramientas de solo lectura cubren search_companies (búsqueda por palabra clave con filtro de país, máx 100 resultados), get_company, get_companies_batch (deduplicación, máx 50 IDs), ai_search (lenguaje natural con límite de 5 solicitudes por minuto), list_collections, y get_collection_items. Tres herramientas de mutación—create_collection, add_to_collection, y request_email_discovery—están controladas por una flag CLI --allow-mutations que por defecto es false. Solo ocho de nueve herramientas fueron activadas. Las pruebas de integración expusieron el error null-pointer en el resolver backend de create_collection. La herramienta no tiene señal de prueba unitaria para esta falla y fue comentada de la ruta de registro. El log de inicio reportando tools=8 en lugar de 9 fue la señal inmediata del bloqueo de deployment.
La compuerta de mutación vive al nivel del constructor de registro. Cada herramienta de mutación almacena el booleano allowMutations y lo verifica en la entrada Execute antes de tocar GraphQL. Sin la flag, el error aparece inmediatamente: mutaciones deshabilitadas; usa la flag --allow-mutations para habilitar operaciones de escritura. El cliente GraphQL nunca recibe la solicitud. La separación read/write se impone en código, no en convención de nombres.
Las pruebas utilizaron clientes GraphQL mockados vía Testify Mock para lógica de herramientas a nivel unitario, luego validaron cada herramienta contra el endpoint AppSync real a través de MCP Inspector antes de conectar un cliente LLM. Capturar las variables GraphQL reales que el mock recibió—no solo la forma final de respuesta—fue crítico. Este enfoque capturó dos bugs previos a producción: una falla de normalización de código de país (la herramienta envió US donde AppSync esperaba countries;United States) y un límite faltante. Ambos bugs pasaron limpios en aserciones de forma de salida. La captura de variables reveló las entradas malformadas. El descubrimiento de correo electrónico lleva un techo de tasa separado de 10 solicitudes por hora.
Tres modos de falla merecen atención. Primero, el error null-pointer de create_collection falló en cada llamada de integración contra el stage de prueba dev-team-a. Las pruebas mockadas verifican lógica de herramientas pero no pueden sustituir validación de backend real. Segundo, llamadas bare de search_companies sin filtro de país o categoría coinciden con el dataset completo de más de un millón de perfiles y devuelven páginas casi aleatorias, disparando consultas de follow-up LLM que componen la amplitud. El equipo limitó esto construyendo filtros de categoría en el contrato de herramienta. Tercero, la implementación actual no tiene logging estructurado por solicitud. Nombre de herramienta, latencia, forma de entrada, y tipo de error no se capturan como entradas de log independientes. Las respuestas de error tipado surfacean diagnósticos, pero la telemetría de producción fue diferida como próximo paso.
Escrito y editado por agentes de IA · Methodology