Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger
Crawl and scrape any site into clean data, 10% off logoCrawl and scrape any site into clean data, 10% off

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits, and new users get 10% off their first purchase.

Try Firecrawl free
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free
SetupClaw: done-for-you OpenClaw for founders & exec teams logoSetupClaw: done-for-you OpenClaw for founders & exec teams

White-glove OpenClaw for founders and exec teams (4–50+ employees): we install, harden, integrate your tools, and maintain it — secured from day one.

Get it set up for you
SEO data APIs for your agent, $1 free credit logoSEO data APIs for your agent, $1 free credit

DataForSEO gives your agent live access to SERP results, keyword data, backlinks, and on-page SEO data through one API. New accounts get a $1 credit, good for up to 20,000 keyword or backlink lookups.

Try DataForSEO free
Reach 47,000+ AI builders

A flat monthly placement in front of developers actively installing AI tools. No lock-in, cancel anytime.

Advertise here

Works with

Claude CodeClaude DesktopCursorVS CodeClineCodex CLIOpenClaw+ any MCP client

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

Guck is a tiny, MCP-first telemetry store for agentic debugging. It provides token-efficient log analytics by capturing JSONL telemetry events and exposing a minimal MCP toolset for fast, filtered queries.

README.md

Guck

Guck is a tiny, MCP-first telemetry store for agentic debugging. It provides token-efficient log analytics by capturing JSONL telemetry events and exposing a minimal MCP toolset for fast, filtered queries.

Guck is designed to be:

  • Language-agnostic: emit JSONL from any runtime
  • Filter-first: no default tailing; MCP tools focus on targeted queries
  • Low-friction: small optional SDK, simple wrap CLI for stdout/stderr

Install

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

Note: the guck command is provided by @guckdev/cli. If you already have the unrelated npm guck installed globally, uninstall it first. If you previously installed guck-cli, switch to @guckdev/cli.

Quick start

1) Configure MCP (Codex/Claude/Copilot):

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

2) Drop‑in log capture (JS) — use auto‑capture, emit(), or both:

import "@guckdev/sdk/auto";
import { emit } from "@guckdev/sdk";

emit({ message: "hello from app" });

3) Run your app; the MCP client will spawn guck mcp and logs are queryable via guck.stats / guck.search.

Vite drop-in (dev)

Add the Vite plugin to proxy /guck/emit during development:

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

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

Then point the browser SDK at /guck/emit.

Monorepo layout

  • packages/guck-cli — CLI (wrap/emit/checkpoint/mcp)
  • packages/guck-core — shared config/types/store/redaction
  • packages/guck-js — JS SDK
  • packages/guck-mcp — MCP server
  • packages/guck-py — Python SDK
  • packages/guck-vite — Vite dev server plugin
  • specs — shared contract fixtures for parity tests

Python SDK (preview)

PyPI install:

pip install guck-sdk

Local dev install:

uv pip install -e packages/guck-py

Usage:

from guck import emit

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

Best practice (copy-paste)

1) Add shared config (commit to repo):

.guck.json ``json { "version": 1, "enabled": true, "default_service": "api" } ``

Optional: add .guck.local.json for per-dev overrides (ignored by git). You can run guck init to scaffold .guck.json.

2) Add one line to AGENTS.md:

When debugging, use Guck telemetry first (guck.stats → guck.search; tail only if asked).

3) Run:

guck wrap --service api --session session-001 -- <your command>
guck mcp

Session vs trace

Guck supports both session_id and trace_id, but they serve different purposes:

  • trace_id is request-scope correlation (a single transaction across services).
  • session_id is run-scope correlation (a dev run, test run, or local experiment).

session_id is useful even when you already have traces because many events are not tied to a trace (startup, background jobs, cron tasks, etc.). It also gives you a simple way to filter a whole dev run without wiring trace propagation.

Example:

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

Config

Guck reads .guck.json from your repo root. If present, .guck.local.json is merged on top for per-dev overrides.

Guck is enabled by default using built-in defaults. Add a .guck.json (and optional .guck.local.json) or set GUCK_CONFIG_PATH (or GUCK_CONFIG) to point at a config file or repo directory. You can also set "enabled": false inside the config to turn it off explicitly.

For MCP usage across multiple repos, each tool accepts an optional config_path parameter to point at a specific .guck.json.

Multi-service or multi-repo tracing (shared store)

To trace across local microservices (or multiple repos), point every service at the same absolute log directory via GUCK_DIR. This creates a single shared log store that guck.search can query across. Use a shared GUCK_SESSION_ID to correlate events and distinct service names to separate sources.

Example shared env:

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

Example shared config:

{
  "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 }
}

Remote backends (CloudWatch/K8s) require optional SDK installs; install only if you use them.

JS SDK auto-capture (stdout/stderr)

The JS SDK can patch process.stdout and process.stderr to emit Guck events. Enable it early in your app startup:

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

Config toggles:

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

If you're using guck wrap, the CLI sets GUCK_WRAPPED=1 and the SDK auto-capture intentionally skips to avoid double logging.

Browser SDK (console + errors)

Use a dev server endpoint that accepts /guck/emit and writes events to the local store. In Vite, the @guckdev/vite plugin provides this endpoint. For other stacks, add a small endpoint that forwards payloads to your server-side emit().

Emit browser events:

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-capture console output + unhandled errors:

const { stop } = client.installAutoCapture();

console.error("boom");

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

Notes:

  • installAutoCapture() should usually be called once at app startup; repeated calls will wrap console multiple times.
  • If you install it inside a component or test, call stop() on cleanup to avoid duplicate logging.
  • For SPAs, it's fine to call installAutoCapture() once in your app entry (e.g. index.ts) and never call stop().
  • There is no prebuilt UMD/IIFE bundle yet; for vanilla JS you should use a bundler or a native ESM import.

Environment overrides

  • GUCK_CONFIG_PATH — explicit config path (file or repo dir)
  • GUCK_CONFIG — alias of GUCK_CONFIG_PATH
  • GUCK_DIR — store dir override (default: ~/.guck/logs)
  • GUCK_ENABLED — true/false
  • GUCK_SERVICE — service name
  • GUCK_SESSION_ID — session override
  • GUCK_RUN_ID — run id override

Checkpoint

guck checkpoint writes a .guck-checkpoint file in the root of your store dir (GUCK_DIR or ~/.guck/logs) containing an epoch millisecond timestamp. When MCP tools are called without since, Guck uses the checkpoint timestamp as the default time window. You can also pass since: "checkpoint" to explicitly anchor a query to the checkpoint.

Event schema (JSONL)

Each line in the log is a single JSON event:

{
  "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" }
}

Store layout

By default, Guck writes per-run JSONL files under ~/.guck/logs:

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

Set GUCK_DIR to override the root.

Minimal CLI

Guck’s CLI is intentionally minimal. It exists to capture and serve telemetry; filtering is MCP-first.

  • guck init — create .guck.json
  • guck checkpoint — write .guck-checkpoint epoch timestamp
  • guck wrap --service <name> --session <id> -- <cmd...> — capture stdout/stderr
  • guck emit --service <name> --session <id> — append JSON events from stdin
  • guck mcp — start MCP server
  • guck upgrade [--manager <npm|pnpm|yarn|bun>] — update the CLI install

MCP tools

Guck exposes these MCP tools (filter-first):

  • guck.search
  • guck.search_batch
  • guck.stats
  • guck.sessions
  • guck.tail (available, but not default in docs)

Search and tail parameters

guck.search and guck.tail support additional output and query controls:

  • query — boolean search over message only (case-insensitive). Supports AND, OR, NOT, parentheses, and quoted phrases.
  • contains — substring search across message/type/session_id/data (unchanged).
  • formatjson (default) or text.
  • fields — when format: "json", project events to these fields. Dotted paths like data.rawPeak are supported.
  • flatten — when format: "json", emit dotted field paths as top-level keys (e.g. "data.rawPeak": 43).
  • template — when format: "text", format each line using tokens like {ts}|{service}|{message}. Dotted tokens like {data.rawPeak} are supported. Missing tokens become empty strings.
  • force — bypass output-size guard and return the full payload.
  • max_message_chars — per-message cap; trims the message field only.

Output is capped by mcp.max_output_chars. If a response would exceed the cap, the tool returns a warning instead of events/lines unless force=true. Warnings include avg_message_chars and max_message_chars computed from full, untrimmed messages.

Examples:

{ "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 }

Batch search:

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

Recommended minimal output for agents:

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

AI usage guidance

Start with stats, then search, and only tail if needed:

1) guck.stats with a narrow time window 2) guck.search for relevant types/levels/messages 3) guck.tail only when live-streaming is required

This keeps prompts short and avoids flooding the model with irrelevant logs.

Debugging strategy (recommended)

Use Guck as a tight loop to avoid log spam and wasted tokens:

1) Scope with guck.stats (short time window, service/session). 2) Inspect with guck.search for errors/warns or a specific boundary. 3) Hypothesize the failing stage or component. 4) Instrument only the boundary (entry/exit, inputs/outputs). 5) Re-run and re-query the same narrow window.

This keeps investigations focused while still enabling deep, iterative debugging.

Redaction

Guck applies redaction on write and on read using configured key names and regex patterns.

Compatibility

Any language can emit Guck events by writing JSONL lines to the store. The optional SDK simply adds conveniences like run_id and redaction.

MCP server config example

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

License

MIT

guck

See related servers & alternatives →

Related MCP servers

Browse all →

Related guides

Hand-picked reading to help you choose and use Developer Tools servers.