DEV-ONLY NUXT MODULE
Every log in one place -
and in your AI's hands.
nuxt-spyglass captures your browser console and your Nitro server logs into one correlated stream - then hands it to your AI agent over MCP. Stop copy-pasting between terminals and tabs. Stop guessing.
- ๐๐ฅ๏ธ Browser + server
- ๐ Correlated per request
- ๐ค MCP for AI agents
- ๐ซ Zero-cost in prod
WHY SPYGLASS
Everything, in one correlated place
Browser + server
Unified browser and server logs in a single NDJSON file.
Correlated
Linked across the boundary via pageLoadId (per page load) and requestId (per request).
Real stack traces
Captures console.*, uncaught errors, unhandled rejections and server throws.
MCP built in
A stdio MCP server so AI agents can query your logs directly.
Terminal viewer
Built-in live log viewer for humans - tail, colors, search.
Dev-only
A verified no-op in production. Zero code, zero cost in your build.
Quick start
Install in two steps
Install it as a dev dependency:
npx nuxt module add nuxt-spyglasspnpm add -D nuxt-spyglassAdd it to your Nuxt config - that's the whole setup:
export default defineNuxtConfig({
modules: ['nuxt-spyglass'],
}) Start your dev server and logs land in .data/spyglass/logs.ndjson (already covered by the default .gitignore).
Configuration
Options
export default defineNuxtConfig({
modules: ['nuxt-spyglass'],
spyglass: {
// Master switch. Always off in production builds, regardless of this value.
enabled: true,
// NDJSON log file; relative paths resolve against the project root.
logFile: '.data/spyglass/logs.ndjson',
// Rotate once the active file reaches this size (keeps at most two files).
maxFileSize: 5 * 1024 * 1024,
},
})| Option | Default | What it does |
|---|---|---|
enabled | true | Master switch. Always off in production builds, regardless of this value. |
logFile | .data/spyglass/logs.ndjson | NDJSON log file. Relative paths resolve against the project root. |
maxFileSize | 5ย MB | Rotate once the active file reaches this size. Keeps at most two files. |
Under the hood
How it works
- Browser: a client plugin wraps
console.*and listens forerror/unhandledrejection, buffers entries and ships them to a Nitro endpoint. - Server: a consola reporter plus a Nitro
errorhook capture server logs and unhandled errors - with their original stack. - Everything lands in one NDJSON file through a single write queue.
- Correlation: each page load carries a
pageLoadId(injected during SSR, sent back to the server on same-origin requests); each request gets its ownrequestId. Browser and server entries of the same page load therefore share one id.
For humans
Live log viewer (CLI)
A built-in terminal viewer - run it in a second terminal next to your dev server:
npx nuxt-spyglass # uses .data/spyglass/logs.ndjson
npx nuxt-spyglass <path-to-logs> # or point it at the file explicitly- Live tail, newest at the bottom, auto-follows; scroll with โ/โ, PageUp/PageDown, Home/End, or the mouse wheel.
- Browser + server logs interleaved, colored by level, framework noise dimmed.
- / to search - jump to a hit, which briefly highlights. q or Ctrl+C to quit.
On dev startup the module prints the exact command with the resolved path - just copy-paste it.
For your AI
AI access (MCP)
Spyglass ships nuxt-spyglass-mcp, a lightweight stdio MCP server that reads your log file and exposes it to AI agents.
- Your AI agent launches the server itself - you never run it manually.
- Keep your Nuxt dev server running; the MCP server only reads the file on demand.
- After registering, start a new agent session so the tools load.
Tools
| Tool | What it returns |
|---|---|
recent_errors | The most recent errors, browser and server. |
recent_logs | Recent logs, optionally filtered by level, source or start time. |
logs_for_page | Every log of one page load by pageLoadId - the full correlated tree. |
search | Case-insensitive substring search across messages. |
logs_since_last_check | Only what arrived since the previous call - see what changed after an action. |
Framework noise (Vue warnings, devtools, build lifecycle) is excluded by default; pass includeNoise: true to any tool to see everything.
Set up your agent
claude mcp add spyglass -- \
npx -p nuxt-spyglass nuxt-spyglass-mcp /abs/path/to/your-app/.data/spyglass/logs.ndjsonEasiest of all: copy the fully-resolved command straight from the dev startup log.
Integration
Works with evlog
Using evlog for structured logging? Spyglass captures it automatically via evlog's evlog:drain hook - reading the structured event directly, so it works even with evlog's console-less default. Per-request logs become individual entries; the wide event becomes a request summary with its fields and error stack, correlated like everything else.
Enable evlog's transport to pull in browser-side evlog logs too:
export default defineNuxtConfig({
modules: ['nuxt-spyglass', 'evlog/nuxt'],
// Browser-side evlog logs are captured too once transport is on.
evlog: { transport: { enabled: true } },
})