Guck MCP
Guck is a tiny, MCP-first telemetry store for agentic debugging
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
wrapCLI 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
- Configure MCP (Codex/Claude/Copilot):
{
"mcpServers": {
"guck": {
"command": "guck",
"args": ["mcp"],
"env": {
"GUCK_CONFIG_PATH": "/path/to/.guck.json"
}
}
}
}
- 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" });
- Run your app; the MCP client will spawn
guck mcpand logs are queryable viaguck.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/redactionpackages/guck-js— JS SDKpackages/guck-mcp— MCP serverpackages/guck-py— Python SDKpackages/guck-vite— Vite dev server pluginspecs— 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)
- Add shared config (commit to repo):
.guck.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.
- Add one line to AGENTS.md:
When debugging, use Guck telemetry first (guck.stats → guck.search; tail only if asked).
- 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_idis request-scope correlation (a single transaction across services).session_idis 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 callstop(). - 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 ofGUCK_CONFIG_PATHGUCK_DIR— store dir override (default:~/.guck/logs)GUCK_ENABLED— true/falseGUCK_SERVICE— service nameGUCK_SESSION_ID— session overrideGUCK_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.jsonguck checkpoint— write.guck-checkpointepoch timestampguck wrap --service <name> --session <id> -- <cmd...>— capture stdout/stderrguck emit --service <name> --session <id>— append JSON events from stdinguck mcp— start MCP serverguck upgrade [--manager <npm|pnpm|yarn|bun>]— update the CLI install
MCP tools
Guck exposes these MCP tools (filter-first):
guck.searchguck.search_batchguck.statsguck.sessionsguck.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). SupportsAND,OR,NOT, parentheses, and quoted phrases.contains— substring search across message/type/session_id/data (unchanged).format—json(default) ortext.fields— whenformat: "json", project events to these fields. Dotted paths likedata.rawPeakare supported.flatten— whenformat: "json", emit dotted field paths as top-level keys (e.g."data.rawPeak": 43).template— whenformat: "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 themessagefield 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:
guck.statswith a narrow time windowguck.searchfor relevant types/levels/messagesguck.tailonly 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:
- Scope with
guck.stats(short time window, service/session). - Inspect with
guck.searchfor errors/warns or a specific boundary. - Hypothesize the failing stage or component.
- Instrument only the boundary (entry/exit, inputs/outputs).
- 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
Related Servers
Travel MCP Server
A comprehensive travel planning server for flight search, accommodation booking, currency exchange, and weather forecasting.
Obsidian via REST
Access and manage your Obsidian vault through a local REST API.
Goatcounter
Interact with the Goatcounter web analytics API.
TaskWarrior MCP Server
An MCP server for managing tasks with the command-line tool TaskWarrior.
Memory Graph
A graph-based Model Context Protocol (MCP) server that gives AI coding agents persistent memory. Originally built for Claude Code, MemoryGraph works with any MCP-enabled coding agent. Store development patterns, track relationships, and retrieve contextual knowledge across sessions and projects.
ActiveCampaign
Built for the next generation of intelligent experiences, ActiveCampaign's remote MCP server makes it easy for AI agents to understand, store, and use customer context across tools, channels, and workflows.
Umami MCP Server
Integrate Umami Analytics with any MCP client like Claude Desktop, VS Code, and more.
Simplenote MCP Server
A server to connect and manage your Simplenote notes within Claude Desktop.
atlassian-mcp-server
Atlassian’s Remote Model Context Protocol (MCP) Server to allow LLMs to talk to Jira, Confluence, OpsGenie, and many other Atlassian prodcuts
Confluence MCP Server
Programmatically access and search Confluence spaces, pages, and content using its REST API.