guck-mcp
Guck MCP
Documentation
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/cliNote: 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-sdkLocal dev install:
uv pip install -e packages/guck-pyUsage:
from guck import emit
emit({"message": "hello from python"})Best practice (copy-paste)
1) 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`.
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 --
guck mcpSession 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 devConfig
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.jsonExample 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///.jsonlSet `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 --session -- ` — capture stdout/stderr
- `guck emit --service --session ` — append JSON events from stdin
- `guck mcp` — start MCP server
- `guck upgrade [--manager ]` — 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).
- `format` — `json` (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
Frequently asked questions
What is guck-mcp?
guck-mcp is Guck MCP
How do I install guck-mcp?
Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.
Is guck-mcp open source?
Yes — it is hosted on GitHub at https://github.com/tillkolter/guck-mcp and has 2 stars.
Related MCP tools
Model Context Protocol Servers
The Open-Source Multimodal AI Agent Stack: Connecting Cutting-Edge AI Models and Agent Infra
A MCP for Claude Desktop / Claude Code / Windsurf / Cursor to build n8n workflows for you
MCP server to provide Figma layout information to AI coding agents like Cursor
The world's best AI personal assistant for email. Open source app to help you reach inbox zero fast.
Instant is the best backend for AI-coded apps. You get auth, permissions, storage, presence, and streams — everything you need to ship apps your users will love.
Run your own MCP server? See who uses it and what to fix.
Measure it with TrackMCP