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:

bash
npx nuxt module add nuxt-spyglass
bash ยท alternative
pnpm add -D nuxt-spyglass

Add it to your Nuxt config - that's the whole setup:

nuxt.config.ts
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

nuxt.config.ts
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,
  },
})
OptionDefaultWhat it does
enabledtrueMaster switch. Always off in production builds, regardless of this value.
logFile.data/spyglass/logs.ndjsonNDJSON log file. Relative paths resolve against the project root.
maxFileSize5ย MBRotate 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 for error / unhandledrejection, buffers entries and ships them to a Nitro endpoint.
  • Server: a consola reporter plus a Nitro error hook 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 own requestId. 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:

bash
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

ToolWhat it returns
recent_errorsThe most recent errors, browser and server.
recent_logsRecent logs, optionally filtered by level, source or start time.
logs_for_pageEvery log of one page load by pageLoadId - the full correlated tree.
searchCase-insensitive substring search across messages.
logs_since_last_checkOnly 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

terminal
claude mcp add spyglass -- \
  npx -p nuxt-spyglass nuxt-spyglass-mcp /abs/path/to/your-app/.data/spyglass/logs.ndjson

Easiest 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:

nuxt.config.ts
export default defineNuxtConfig({
  modules: ['nuxt-spyglass', 'evlog/nuxt'],
  // Browser-side evlog logs are captured too once transport is on.
  evlog: { transport: { enabled: true } },
})