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 entorno | Descripción |
|---|---|
SCOUTER_COLLECTOR_HOST | Host del Collector |
SCOUTER_COLLECTOR_PORT | Puerto TCP del Collector (por defecto 6100) |
SCOUTER_USER | Usuario de inicio de sesión |
SCOUTER_PASSWORD | Contraseña de inicio de sesión |
SCOUTER_TZ | Zona horaria (p. ej., Asia/Seoul) |
SCOUTER_LOCALE | Idioma 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_PARAMS | Interruptor 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:
- Descarga
scouter-mcp-<version>-all.jardesde el GitHub Release. - Añade una entrada
mcpServerspor 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)
| Nombre | Propósito | Entradas clave |
|---|---|---|
list_objects | Listar objetos/agentes | objType?, nameLike? (sin distinción de mayúsculas) |
search_xlog | Buscar XLogs (latencia/errores) | from, to, objNameLike?, objHash?, service?, login?, ip?, desc?, minElapsedMs?, onlyError?, limit? (por defecto 20, máximo 200) |
get_service_summary | Agregado por servicio (count/avg/max/p95/errorRate), top 50 | from, to, mismos filtros que search_xlog |
get_summary | Estadí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_detail | Detalle de XLog (SQL/parámetros de enlace) | txid, date?/at?, includeBindParams? (por defecto true) |
get_xlog_by_gxid | Grupo de transacciones distribuidas | gxid, date?/at? |
get_counter | Serie temporal de contadores (mismo día, resolución completa) | objNameLike|objHashes|objType, counter, from, to |
get_counter_stat | Estadísticas de contadores a largo plazo (resolución de 5 minutos, hasta 31 días) | objNameLike|objHashes|objType, counter, from, to |
list_counters | Contadores disponibles para un objType | objType |
list_alerts | Alertas pasadas del Collector | from, to, level?, object?, key?, limit? |
get_active_services | Servicios en ejecución ahora mismo | objNameLike|objType|objHash |
list_threads | Lista de hilos JVM (histograma de estados + top 50 por CPU) | objNameLike|objHash (máximo 5 instancias activas) |
get_thread_detail | Hilo en vivo de una transacción ACTIVA (stack/owner de bloqueo/SQL actual) | txid (obligatorio, activo), id?, objNameLike|objHash |
get_object_env | Propiedades 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
limito 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
serviceoobjHash, solo se permiten ventanas de hasta 5 minutos; el límite absoluto de ventana es de 24 horas. limittiene un valor predeterminado de 20 y un máximo de 200. Los resultados incluyentruncated/scanCapReachedy unhintpara que el llamador pueda estrechar los filtros en lugar de volver a consultar.get_service_summaryno 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 informascanCapReached/examined.get_counterlimita el fan-out porobjTypea 20 instancias y reduce el muestreo de series largas con un esquema min/max que preserva picos/caídas (el resumenmin/max/avgse 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_detailtienen un máximo de 150, señalado mediantetotalSteps/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 oget_summary. get_summary/get_counter_statleen 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_threadslimita 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=valueestructuradas 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_detailpueden contener PII. EstableceSCOUTER_INCLUDE_BIND_PARAMS=falsepara 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 deget_thread_detail(SQLActiveBindVar) obedecen el mismo interruptor de seguridad. get_object_envincondicionalmente 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
search_xlog/get_service_summaryminElapsedMs/onlyError/limitse aplican del lado del cliente porque el Collector no tiene parámetros nativos para ellos.truncated=truees heurístico (recuento devuelto == límite) y puede dar un falso positivo.- 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 comoSCOUTER_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. list_alerts/get_active_servicesse 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.