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,
    // Print the MCP connection state and setup command on startup.
    mcpHint: true,
  },
})
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.
mcpHinttruePrint the MCP connection state and setup command on startup.

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                  # finds this project's log file by itself
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.
The module prints this command on dev startup as well, next to the log file it writes to.

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.
  • No paths, no per-project setup. The server starts in the directory your AI client was opened in and finds that project's log file itself - monorepo layouts like packages/app/.data/spyglass/logs.ndjson included. Register it once, it serves every project you open, always the current one. Pass a path as the first argument (or set SPYGLASS_LOG_FILE) only for a custom logFile.

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 (capped at 200 entries by default).
searchCase-insensitive substring search across messages.
logs_since_last_checkOnly what arrived since the previous call - see what changed after an action.
spyglass_statusWhich project is being read, how many entries there are, and whether the dev server is still running.

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 --scope user spyglass -- npx -y -p nuxt-spyglass nuxt-spyglass-mcp

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 } },
})