Guck MCP

Guck es un pequeño almacén de telemetría priorizando MCP para depuración de agentes.

Documentación

Guck

Guck es un almacén de telemetría diminuto, pensado primero para MCP, orientado a la depuración de agentes. Proporciona análisis de registros eficientes en tokens al capturar eventos de telemetría JSONL y exponer un conjunto mínimo de herramientas MCP para consultas rápidas y filtradas.

Guck está diseñado para ser:

  • Independiente del lenguaje: emite JSONL desde cualquier runtime
  • Filtro primero: sin tailing por defecto; las herramientas MCP se centran en consultas específicas
  • De baja fricción: SDK opcional pequeño, CLI simple wrap para stdout/stderr

Instalación

pnpm add -g @guckdev/cli
# or
npm install -g @guckdev/cli
# or
npx @guckdev/cli

Nota: el comando guck lo proporciona @guckdev/cli. Si ya tienes el npm guck no relacionado instalado globalmente, desinstálalo primero. Si instalaste previamente guck-cli, cambia a @guckdev/cli.

Inicio rápido

  1. Configura MCP (Codex/Claude/Copilot):
{
  "mcpServers": {
    "guck": {
      "command": "guck",
      "args": ["mcp"],
      "env": {
        "GUCK_CONFIG_PATH": "/path/to/.guck.json"
      }
    }
  }
}
  1. Captura de registros integrable (JS): usa auto-capture, emit(), o ambos:
import "@guckdev/sdk/auto";
import { emit } from "@guckdev/sdk";

emit({ message: "hello from app" });
  1. Ejecuta tu aplicación; el cliente MCP iniciará guck mcp y los registros se pueden consultar mediante guck.stats / guck.search.

Integración Vite (dev)

Añade el plugin de Vite para hacer proxy de /guck/emit durante el desarrollo:

import { defineConfig } from "vite";
import { guckVitePlugin } from "@guckdev/vite";

export default defineConfig({
  plugins: [guckVitePlugin()],
});

Luego apunta el SDK del navegador a /guck/emit.

Estructura del monorepo

  • packages/guck-cli — CLI (wrap/emit/checkpoint/mcp)
  • packages/guck-core — config/tipos/store/redacción compartidos
  • packages/guck-js — SDK de JS
  • packages/guck-mcp — servidor MCP
  • packages/guck-py — SDK de Python
  • packages/guck-vite — plugin de servidor de desarrollo Vite
  • specs — fixtures de contrato compartidos para pruebas de paridad

SDK de Python (vista previa)

Instalación desde PyPI:

pip install guck-sdk

Instalación local de desarrollo:

uv pip install -e packages/guck-py

Uso:

from guck import emit

emit({"message": "hello from python"})

Buenas prácticas (copiar y pegar)

  1. Añade configuración compartida (haz commit al repositorio):

.guck.json

{
  "version": 1,
  "enabled": true,
  "default_service": "api"
}

Opcional: añade .guck.local.json para anulaciones por desarrollador (ignorado por git). Puedes ejecutar guck init para generar el esqueleto de .guck.json.

  1. Añade una línea a AGENTS.md:
When debugging, use Guck telemetry first (guck.stats → guck.search; tail only if asked).
  1. Ejecuta:
guck wrap --service api --session session-001 -- <your command>
guck mcp

Sesión vs traza

Guck admite tanto session_id como trace_id, pero sirven para propósitos diferentes:

  • trace_id es correlación de ámbito de solicitud (una sola transacción entre servicios).
  • session_id es correlación de ámbito de ejecución (una ejecución de desarrollo, una ejecución de pruebas o un experimento local).

session_id es útil incluso cuando ya tienes trazas porque muchos eventos no están vinculados a una traza (arranque, trabajos en segundo plano, tareas cron, etc.). También te ofrece una forma sencilla de filtrar una ejecución de desarrollo completa sin conectar la propagación de trazas.

Ejemplo:

export GUCK_SESSION_ID=session-001
guck wrap --service api --session session-001 -- pnpm run dev

Configuración

Guck lee .guck.json desde la raíz de tu repositorio. Si está presente, .guck.local.json se fusiona encima para anulaciones por desarrollador.

Guck está habilitado por defecto usando valores predeterminados integrados. Añade un .guck.json (y opcionalmente .guck.local.json) o establece GUCK_CONFIG_PATH (o GUCK_CONFIG) para apuntar a un archivo de configuración o directorio de repositorio. También puedes establecer "enabled": false dentro de la configuración para desactivarlo explícitamente.

Para uso de MCP en múltiples repositorios, cada herramienta acepta un parámetro opcional config_path para apuntar a un .guck.json específico.

Trazado multi-servicio o multi-repositorio (almacén compartido)

Para trazar entre microservicios locales (o múltiples repositorios), apunta cada servicio al mismo directorio de registros absoluto mediante GUCK_DIR. Esto crea un único almacén de registros compartido que guck.search puede consultar de forma transversal. Usa un GUCK_SESSION_ID compartido para correlacionar eventos y nombres de service distintos para separar fuentes.

Ejemplo de entorno compartido:

export GUCK_DIR=/path/to/guck/logs
export GUCK_SESSION_ID=session-001
# optional: share a single config across repos
export GUCK_CONFIG_PATH=/path/to/shared/.guck.json

Ejemplo de configuración compartida:

{
  "version": 1,
  "enabled": true,
  "default_service": "api",
  "redaction": {
    "enabled": true,
    "keys": ["authorization","api_key","token","secret","password"],
    "patterns": ["sk-[A-Za-z0-9]{20,}","Bearer\\s+[A-Za-z0-9._-]+"]
  },
  "mcp": { "max_results": 200, "max_output_chars": 20000, "default_lookback_ms": 300000 }
}

Los backends remotos (CloudWatch/K8s) requieren instalaciones opcionales del SDK; instala solo si los usas.

Auto-captura del SDK de JS (stdout/stderr)

El SDK de JS puede parchear process.stdout y process.stderr para emitir eventos de Guck. Habilítalo al inicio del arranque de tu aplicación:

import "@guckdev/sdk/auto";
// or
import { installAutoCapture } from "@guckdev/sdk";
installAutoCapture();

Alternancias de configuración:

{ "sdk": { "enabled": true, "capture_stdout": true, "capture_stderr": true } }

Si estás usando guck wrap, el CLI establece GUCK_WRAPPED=1 y el SDK omite intencionalmente la auto-captura para evitar el doble registro.

SDK del navegador (consola + errores)

Usa un endpoint del servidor de desarrollo que acepte /guck/emit y escriba eventos en el almacén local. En Vite, el plugin @guckdev/vite proporciona este endpoint. Para otros stacks, añade un endpoint pequeño que reenvíe los payloads a tu emit() del lado del servidor.

Emite eventos del navegador:

import { createBrowserClient } from "@guckdev/browser";

const client = createBrowserClient({
  endpoint: "/guck/emit",
  service: "web",
  sessionId: "session-001",
});

await client.emit({ message: "hello from the browser" });

Auto-captura de salida de consola + errores no controlados:

const { stop } = client.installAutoCapture();

console.error("boom");

// call stop() to restore console and listeners (useful in component unmounts/tests)
stop();

Notas:

  • installAutoCapture() normalmente debería llamarse una vez al arrancar la aplicación; las llamadas repetidas envolverán la consola múltiples veces.
  • Si lo instalas dentro de un componente o prueba, llama a stop() en la limpieza para evitar registros duplicados.
  • Para SPAs, está bien llamar a installAutoCapture() una vez en la entrada de tu aplicación (p. ej. index.ts) y nunca llamar a stop().
  • Aún no hay un bundle UMD/IIFE precompilado; para JS vanilla debes usar un bundler o una importación ESM nativa.

Anulaciones de entorno

  • GUCK_CONFIG_PATH — ruta de configuración explícita (archivo o directorio de repo)
  • GUCK_CONFIG — alias de GUCK_CONFIG_PATH
  • GUCK_DIR — anulación del directorio de almacenamiento (predeterminado: ~/.guck/logs)
  • GUCK_ENABLED — true/false
  • GUCK_SERVICE — nombre del servicio
  • GUCK_SESSION_ID — anulación de sesión
  • GUCK_RUN_ID — anulación de id de ejecución

Checkpoint

guck checkpoint escribe un archivo .guck-checkpoint en la raíz de tu directorio de almacenamiento (GUCK_DIR o ~/.guck/logs) que contiene una marca de tiempo en milisegundos de época. Cuando se llaman herramientas MCP sin since, Guck usa la marca de tiempo del checkpoint como ventana de tiempo predeterminada. También puedes pasar since: "checkpoint" para anclar explícitamente una consulta al checkpoint.

Esquema de eventos (JSONL)

Cada línea del registro es un único evento JSON:

{
  "id": "uuid",
  "ts": "2026-02-08T18:40:00.123Z",
  "level": "info",
  "type": "log",
  "service": "worker",
  "run_id": "uuid",
  "session_id": "session-123",
  "message": "speaker started",
  "data": { "turnId": 3 },
  "tags": { "env": "local" },
  "trace_id": "...",
  "span_id": "...",
  "source": { "kind": "sdk" }
}

Estructura del almacén

Por defecto, Guck escribe archivos JSONL por ejecución bajo ~/.guck/logs:

~/.guck/logs/<service>/<YYYY-MM-DD>/<run_id>.jsonl

Establece GUCK_DIR para anular la raíz.

CLI mínimo

El CLI de Guck es intencionalmente mínimo. Existe para capturar y servir telemetría; el filtrado es primero-MCP.

  • guck init — crear .guck.json
  • guck checkpoint — escribir marca de tiempo de época .guck-checkpoint
  • guck wrap --service <name> --session <id> -- <cmd...> — capturar stdout/stderr
  • guck emit --service <name> --session <id> — añadir eventos JSON desde stdin
  • guck mcp — iniciar servidor MCP
  • guck upgrade [--manager <npm|pnpm|yarn|bun>] — actualizar la instalación del CLI

Herramientas MCP

Guck expone estas herramientas MCP (filtro primero):

  • guck.search
  • guck.search_batch
  • guck.stats
  • guck.sessions
  • guck.tail (disponible, pero no predeterminada en la documentación)

Parámetros de búsqueda y tail

guck.search y guck.tail admiten controles adicionales de salida y consulta:

  • query — búsqueda booleana sobre solo el mensaje (sin distinción de mayúsculas/minúsculas). Admite AND, OR, NOT, paréntesis y frases entre comillas.
  • contains — búsqueda de subcadena en message/type/session_id/data (sin cambios).
  • formatjson (predeterminado) o text.
  • fields — cuando format: "json", proyecta eventos a estos campos. Se admiten rutas punteadas como data.rawPeak.
  • flatten — cuando format: "json", emite rutas de campo punteadas como claves de nivel superior (p. ej. "data.rawPeak": 43).
  • template — cuando format: "text", formatea cada línea usando tokens como {ts}|{service}|{message}. Se admiten tokens punteados como {data.rawPeak}. Los tokens faltantes se convierten en cadenas vacías.
  • force — omite la protección de tamaño de salida y devuelve el payload completo.
  • max_message_chars — límite por mensaje; recorta solo el campo message.

La salida está limitada por mcp.max_output_chars. Si una respuesta excediera el límite, la herramienta devuelve una advertencia en lugar de eventos/líneas a menos que force=true. Las advertencias incluyen avg_message_chars y max_message_chars calculados a partir de mensajes completos y sin recortar.

Ejemplos:

{ "query": "error AND (db OR timeout)" }
{ "format": "text", "template": "{ts}|{service}|{message}" }
{ "format": "json", "fields": ["ts", "level", "message"] }
{ "format": "json", "fields": ["ts", "data.rawPeak"], "flatten": true }

Búsqueda por lotes:

{
  "searches": [
    { "id": "errors", "query": "error", "limit": 50 },
    { "id": "warnings", "levels": ["warn"], "limit": 50, "max_message_chars": 200 }
  ]
}

Salida mínima recomendada para agentes:

{ "format": "text", "template": "{ts}|{service}|{message}" }

Guía de uso para IA

Comienza con stats, luego search, y usa tail solo si es necesario:

  1. guck.stats con una ventana de tiempo estrecha
  2. guck.search para types/levels/messages relevantes
  3. guck.tail solo cuando se requiera transmisión en vivo

Esto mantiene los prompts cortos y evita inundar el modelo con registros irrelevantes.

Estrategia de depuración (recomendada)

Usa Guck como un bucle cerrado para evitar spam de registros y tokens desperdiciados:

  1. Delimita con guck.stats (ventana de tiempo corta, servicio/sesión).
  2. Inspecciona con guck.search para errores/advertencias o un límite específico.
  3. Formula hipótesis sobre la etapa o componente que falla.
  4. Instrumenta solo el límite (entrada/salida, inputs/outputs).
  5. Vuelve a ejecutar y vuelve a consultar la misma ventana estrecha.

Esto mantiene las investigaciones enfocadas mientras permite una depuración profunda e iterativa.

Redacción

Guck aplica redacción al escribir y al leer usando nombres de claves configurados y patrones de regex.

Compatibilidad

Cualquier lenguaje puede emitir eventos de Guck escribiendo líneas JSONL en el almacén. El SDK opcional simplemente añade conveniencias como run_id y redacción.

Ejemplo de configuración del servidor MCP

{
  "mcpServers": {
    "guck": {
      "command": "guck",
      "args": ["mcp"],
      "env": {
        "GUCK_CONFIG_PATH": "/path/to/.guck.json"
      }
    }
  }
}

Licencia

MIT

guck