Scouter MCP

Consulta Scouter APM (objetos, contadores, transacciones XLog) a través de stdio mediante un colector Scouter.

Documentación

scouter-mcp

La documentación en coreano está disponible en README.ko.md.

Un servidor MCP stdio que se conecta directamente a un Scouter Collector a través de TCP y consulta XLogs, contadores y objetos. Su propósito es permitir que una IA explore rápidamente las métricas de Scouter y diagnostique causas raíz. Cada resultado incluye txid / gxid / objName / endTimeIso, que puedes usar como claves para realizar análisis cruzados con otras herramientas de observabilidad como OpenSearch o Datadog.

Arquitectura

Java 17. Reutiliza scouter-common y porta las clases net/server de scouter.webapp al paquete scouter.mcp.client. MCP utiliza el transporte stdio del SDK de Java 2.0.0. Todas las operaciones contra el Collector son de solo lectura.

Compilación

./gradlew shadowJar
# output: build/libs/scouter-mcp-<version>-all.jar

El paquete .mcpb solo se genera mediante el CI de lanzamiento (que envuelve este jar); las compilaciones locales solo generan el jar.

Registro (Claude Code, Claude Desktop, ...)

Para un solo collector, instala el paquete .mcpb desde el GitHub Release para una instalación con un clic — o copia .mcp.json.example, apúntalo al fat jar (descargado del release o compilado localmente) y completa las credenciales. Para múltiples collectors, consulta Múltiples collectors.

Variable de entornoDescripción
SCOUTER_COLLECTOR_HOSTHost del Collector
SCOUTER_COLLECTOR_PORTPuerto TCP del Collector (por defecto 6100)
SCOUTER_USERUsuario de inicio de sesión
SCOUTER_PASSWORDContraseña de inicio de sesión
SCOUTER_TZZona horaria (p. ej., Asia/Seoul)
SCOUTER_LOCALEIdioma de los mensajes visibles: en o ko. Si no se define, se deriva del valor predeterminado de la JVM (coreano solo cuando el idioma de la JVM es coreano; de lo contrario, inglés)
SCOUTER_INCLUDE_BIND_PARAMSInterruptor de seguridad para los parámetros de enlace SQL en get_xlog_detail (por defecto true). Establécelo en false para eliminar los parámetros de enlace en el servidor, independientemente del argumento por llamada: un LLM no puede volver a habilitarlos. Úsalo cuando los valores de enlace puedan contener PII.

Múltiples collectors

El release oficial incluye un paquete .mcpb (instalación con un clic, un solo collector) además del fat jar independiente. Un .mcpb define exactamente un servidor con un conjunto de credenciales, por lo que no puede registrar dos collectors a la vez. Para múltiples collectors — que normalmente difieren en todo su conjunto de conexión (host/puerto y usuario/contraseña) — usa el jar directamente y añade una entrada por collector:

  1. Descarga scouter-mcp-<version>-all.jar desde el GitHub Release.
  2. Añade una entrada mcpServers por collector a tu configuración de cliente (.mcp.json / claude_desktop_config.json), todas apuntando al mismo jar, cada una con su propio conjunto de variables de entorno. Esto mantiene cada credencial aislada:
{
  "mcpServers": {
    "scouter-prod": {
      "command": "java",
      "args": ["-jar", "/ABSOLUTE/PATH/scouter-mcp-<version>-all.jar"],
      "env": {
        "SCOUTER_COLLECTOR_HOST": "prod-collector", "SCOUTER_COLLECTOR_PORT": "6100",
        "SCOUTER_USER": "prod-user", "SCOUTER_PASSWORD": "***", "SCOUTER_TZ": "Asia/Seoul"
      }
    },
    "scouter-stg": {
      "command": "java",
      "args": ["-jar", "/ABSOLUTE/PATH/scouter-mcp-<version>-all.jar"],
      "env": {
        "SCOUTER_COLLECTOR_HOST": "stg-collector", "SCOUTER_COLLECTOR_PORT": "6100",
        "SCOUTER_USER": "stg-user", "SCOUTER_PASSWORD": "***", "SCOUTER_TZ": "Asia/Seoul"
      }
    }
  }
}

La IA luego orquesta entre los collectors.

Herramientas (14)

NombrePropósitoEntradas clave
list_objectsListar objetos/agentesobjType?, nameLike? (sin distinción de mayúsculas)
search_xlogBuscar XLogs (latencia/errores)from, to, objNameLike?, objHash?, service?, login?, ip?, desc?, minElapsedMs?, onlyError?, limit? (por defecto 20, máximo 200)
get_service_summaryAgregado por servicio (count/avg/max/p95/errorRate), top 50from, to, mismos filtros que search_xlog
get_summaryEstadísticas diarias preagregadas del Collector (top-50 SQL/servicio/error/... — sin escaneo)category (service/sql/apiCall/ip/userAgent/error/alert), from, to (hasta 31 días), objType?, objNameLike?, objHash?
get_xlog_detailDetalle de XLog (SQL/parámetros de enlace)txid, date?/at?, includeBindParams? (por defecto true)
get_xlog_by_gxidGrupo de transacciones distribuidasgxid, date?/at?
get_counterSerie temporal de contadores (mismo día, resolución completa)objNameLike|objHashes|objType, counter, from, to
get_counter_statEstadísticas de contadores a largo plazo (resolución de 5 minutos, hasta 31 días)objNameLike|objHashes|objType, counter, from, to
list_countersContadores disponibles para un objTypeobjType
list_alertsAlertas pasadas del Collectorfrom, to, level?, object?, key?, limit?
get_active_servicesServicios en ejecución ahora mismoobjNameLike|objType|objHash
list_threadsLista de hilos JVM (histograma de estados + top 50 por CPU)objNameLike|objHash (máximo 5 instancias activas)
get_thread_detailHilo en vivo de una transacción ACTIVA (stack/owner de bloqueo/SQL actual)txid (obligatorio, activo), id?, objNameLike|objHash
get_object_envPropiedades del sistema JVM del agente (secretos enmascarados)objNameLike|objHash, keyLike?

Segmentación difusa (objNameLike)

Los usuarios escriben fragmentos de nombres de aplicación ("shop-order-api"), pero los objNames reales incorporan el nombre del pod k8s (/shop-order-api-deployment-5f4b8c7d9-abcde/shop-order-api1), por lo que objHash cambia en cada despliegue y una aplicación abarca múltiples instancias. objNameLike resuelve esto: un fragmento sin distinción de mayúsculas se resuelve a todas las instancias coincidentes (primero las activas, máximo 20) y se consulta a través de ellas — sin necesidad de objHash, nunca. Para la búsqueda/resumen de XLog, la resolución también combina la base de datos diaria de objetos del collector, por lo que los pods reemplazados por un despliegue durante la ventana consultada aún se encuentran. Si nada coincide, el error es NOT_FOUND con una pista candidates que lista los objNames reales para que el llamador pueda autocorregirse en un solo paso.

Consultas de servicios imprecisas

Los nombres de servicios de Scouter se ven como /api/order/.../search-order-info-grade<POST>, pero los usuarios escriben "GET orderDetail" o "order info grade". El filtro service normaliza dicha entrada: se extrae un método HTTP de cualquier posición (GET x, x POST, <POST> pegado), las palabras separadas por espacios se reducen al token más largo en el servidor, y los patrones * explícitos pasan sin cambios. La coincidencia en el servidor sigue distinguiendo mayúsculas — por lo que cuando un patrón no coincide con nada, la misma ventana se vuelve a escanear (acotada) sin el filtro de servicio y los nombres de servicios reales que coinciden con los tokens de la consulta sin distinción de mayúsculas se devuelven como serviceCandidates, ordenados por tráfico. Un reintento con un nombre exacto lo resuelve.

service/login/ip/desc usan coincidencia de subcadena por defecto (StrMatch en el servidor), por lo que un token corto como search-order-info-grade coincide con /api/order/ext/order-info/search-order-info-grade<POST>. objNameLike/login/ip/desc cuentan como filtros del servidor, por lo que relajan el límite de ventana sin filtrar de 5 minutos. list_counters también acepta objNameLike y deriva el objType, por lo que los usuarios nunca necesitan conocer la taxonomía de tipos de Scouter.

Todas las herramientas se anuncian con readOnlyHint. Un prompt MCP diagnose_root_cause expone el orden de herramientas recomendado para investigaciones de latencia/errores.

Política de seguridad de recursos/tokens

Un Scouter de producción puede producir cientos de miles de XLogs en cinco minutos, por lo que search_xlog aplica salvaguardas (consulta scouter.mcp.policy.Limits):

  • Durante la transmisión, se detiene una vez que se alcanza el limit o el límite de escaneo (5,000 paquetes examinados) y cierra el socket, lo que también detiene el escaneo/transferencia del Collector — acotando la carga del servidor, la red y el heap de MCP en conjunto.
  • Sin un filtro service o objHash, solo se permiten ventanas de hasta 5 minutos; el límite absoluto de ventana es de 24 horas.
  • limit tiene un valor predeterminado de 20 y un máximo de 200. Los resultados incluyen truncated/scanCapReached y un hint para que el llamador pueda estrechar los filtros en lugar de volver a consultar.
  • get_service_summary no retiene filas (solo contadores por servicio), por lo que usa un límite de escaneo mayor (200,000) para cubrir ventanas más amplias de forma económica; también informa scanCapReached/examined.
  • get_counter limita el fan-out por objType a 20 instancias y reduce el muestreo de series largas con un esquema min/max que preserva picos/caídas (el resumen min/max/avg se calcula a partir de la serie completa).
  • Las ventanas que cruzan la medianoche se dividen por día calendario (el collector particiona XLogs/contadores/alertas por día), por lo que no se pierden datos en ninguno de los lados del límite.
  • Presupuestos de texto de respuesta: el texto SQL se corta en 1,500 caracteres, los mensajes de error en 500, los stack traces de hilos en 4,000, los valores de entorno en 500 — cada uno con un marcador de truncamiento que indica la longitud original. Los pasos de perfil get_xlog_detail tienen un máximo de 150, señalado mediante totalSteps/stepsTruncated.
  • Una sola solicitud puede expandirse a un máximo de 40 viajes de ida y vuelta al collector (instancias x segmentos de día). Cuando los filtros del lado del cliente (minElapsedMs/onlyError) descartan más del 99% de las filas escaneadas, una pista de baja selectividad orienta al modelo hacia filtros del servidor o get_summary.
  • get_summary/get_counter_stat leen los datos diarios preagregados del collector (sin escaneo), con un máximo de 31 días; el resumen devuelve las 50 filas principales por categoría. list_threads limita a 5 instancias activas y 50 filas de hilos cada una (el histograma de estados siempre cubre todos los hilos).
  • La telemetría por solicitud (passes/examined/kept/tookMs) se registra en stderr como líneas key=value estructuradas para el análisis de carga posterior.

Internacionalización

Solo la salida dinámica visible (mensajes de error de herramientas, pistas de resultados, notas) está localizada, en inglés y coreano, mediante messages.properties / messages_ko.properties. Las descripciones estáticas de esquema/herramientas y los registros estructurados de stderr (key=value) permanecen en inglés para un contrato estable y un análisis de registros consistente.

Notas de seguridad

  • Solo lectura contra el Collector (no se exponen comandos de escritura).
  • Las credenciales se inyectan únicamente mediante variables de entorno (nunca en archivos o argumentos en texto plano). Prefiere una cuenta de Scouter de mínimo privilegio / solo lectura.
  • El transporte es TCP en texto plano (el protocolo de Scouter no tiene TLS): el digest SHA-256 de la contraseña, el token de sesión y todos los datos de XLog/contadores cruzan el cable sin cifrar. Ejecuta solo dentro de una red confiable, o mediante un túnel SSH/VPN. No expongas el puerto del collector a través de internet público.
  • Los parámetros de enlace get_xlog_detail pueden contener PII. Establece SCOUTER_INCLUDE_BIND_PARAMS=false para eliminarlos en el servidor (el LLM no puede volver a habilitarlos). Consulta la tabla de variables de entorno anterior. Los valores de enlace en vivo de get_thread_detail (SQLActiveBindVar) obedecen el mismo interruptor de seguridad.
  • get_object_env incondicionalmente enmascara los valores de claves que coinciden con password/secret/token/credential/ private — una política del servidor de la que el LLM no puede optar por no participar.
  • stdout está reservado para JSON-RPC, por lo que todos los registros van solo a stderr.

Licencia / Aviso

El paquete scouter.mcp.client se porta desde el código de cliente de Scouter v2.20.0 (Apache License 2.0). Consulta NOTICE para más detalles.

Limitaciones conocidas

  1. search_xlog/get_service_summary minElapsedMs/onlyError/limit se aplican del lado del cliente porque el Collector no tiene parámetros nativos para ellos. truncated=true es heurístico (recuento devuelto == límite) y puede dar un falso positivo.
  2. Ante una expiración de sesión (INVALID_SESSION), el cliente vuelve a iniciar sesión una vez y reintenta la solicitud; un segundo fallo se muestra como SCOUTER_AUTH_FAILED (sin bucle infinito de reintentos). El daemon de actualización de diferencia de tiempo de 2 segundos aguas arriba aún no se ha portado, por lo que los procesos de larga duración pueden desviarse ligeramente en consultas relativas en tiempo real. Las consultas históricas de época absoluta no se ven afectadas.
  3. list_alerts/get_active_services se portaron del protocolo aguas arriba y se validaron contra un collector mediante las pruebas de humo (SmokeIT); la cobertura de campos puede variar según la versión del collector.