Software development isn't a pipeline from idea to product. A product is what generates the next idea - what broke, what confused users, what worked better than expected. Janus closes that loop.
Most coding agents work from specs and diffs. They don't know what actually happened in the browser. Janus captures real sessions - interactions, errors, network calls - and pipes them directly into Claude, so your agent starts from what's true instead of what's assumed.
No more copy-pasting interaction traces into Claude. Your browser and terminal can do that itself.
Demo
demo.mp4
Dev workflow for splendor.
Architecture
Browser Terminal
┌──────────┐ ┌───────────┐
│Extension │ │ janus cli │
└────┬─────┘ └─────┬─────┘
│ WebSocket │ WebSocket
│ ws://localhost:3457 │
│ │
└──────────────────────┘
│
┌──────▼──────┐
│ MCP server │
└──────┬──────┘
│ SSE
┌──────▼──────┐
│ Claude │
└─────────────┘
Extension - works standalone without the MCP server. Captures interactions in the sidebar and lets you copy a formatted prompt directly. The MCP server adds ambient, queryable access for Claude.
janus CLI - without the MCP server it's a no-op passthrough. The MCP server is required for CLI journeys to be queryable.
Table of contents
- Install the extension
- Install the MCP server
- Install the
janusCLI
Install the extension
Run from the repo root (
/path/to/janus)
Chrome:
npm install && npm run build- Open
chrome://extensions, enable Developer Mode, click "Load unpacked", selectoutput/chrome-mv3/
Firefox:
npm install && npm run build:firefox- Open
about:debugging#/runtime/this-firefox, click "Load Temporary Add-on", select any file insideoutput/firefox-mv2/
Install the MCP server
The MCP server is a local daemon that receives journey data from the extension and janus CLI over WebSocket, and exposes it to Claude Code via four MCP tools: list_journeys, get_journey_by_id, get_journeys_by_domain, and latest_journey.
1. Build the server
Run from
packages/mcp-server
cd packages/mcp-server
npm install
npm run buildThis compiles TypeScript to packages/mcp-server/dist/.
2. Start the daemon
Run from anywhere - keep this terminal open while using Claude Code
node /path/to/janus/packages/mcp-server/dist/index.js
The server listens on two ports:
3456- MCP SSE endpoint (http://localhost:3456/sse) - Claude talks here3457- WebSocket endpoint (ws://localhost:3457) - extension and CLI talk here
3. Register with Claude Code
Run from the root of the project you want to use Janus in (not the Janus repo)
cat > .mcp.json << 'EOF' { "mcpServers": { "janus": { "type": "sse", "url": "http://localhost:3456/sse" } } } EOF
Claude Code picks this up automatically when you open that project.
To register globally instead (available in all projects), add the same block to ~/.claude/settings.json under "mcpServers".
4. Verify
In Claude Code, the mcp__janus__list_journeys tool should be available. Start a recording in the extension, then call list_journeys - the journey should appear.
Notes
- The daemon must be running before Claude Code connects. If you start it after, restart Claude Code or reconnect the MCP server.
- Journey data is in-memory only - it is lost when the daemon restarts. The extension will resync the active recording on reconnect, but stopped journeys are gone.
- Attached files are written to
$TMPDIR/janus-mcp/<journeyId>/and survive daemon restarts at the filesystem level, but the in-memory journey record referencing them does not.
Install the janus CLI
The janus CLI wraps any command and streams its output as a journey to the MCP server, so Claude can see what your processes are doing alongside browser sessions.
1. Build and install
Run from
packages/janus-cli
cd packages/janus-cli
npm install
npm run build
npm linkThis makes janus available on your PATH.
Development (no build step)
Run from
packages/janus-cli
npm install npm start -- echo "hello" # runs via tsx directly npm start -- -n 100 rails server # with flags echo "hello" | npm start # pipe mode
Or from anywhere after installing tsx globally (npm install -g tsx):
tsx /path/to/janus/packages/janus-cli/src/index.ts echo "hello"
2. Use it
Run from anywhere
# Wrap a command - captures stdout and stderr separately janus npm run dev janus python server.py # Rolling window - keep only the last N lines (useful for chatty daemons) janus -n 100 rails server # Pipe mode - filter output before it reaches Janus long_running_command | grep ERROR | janus -n 50
Janus prints the journey ID to stderr on start and again on exit:
[janus] journey: a1b2c3
...
[janus] journey: a1b2c3
Use that ID with get_journey_by_id or combine multiple journeys with merge_journeys to correlate CLI output with browser interactions.
Notes
- The MCP server must be running before you use
janus- if it's not reachable, the command runs normally with no MCP side effect - Without
-n, all output is buffered in memory - use-nfor long-running processes janusexits with the wrapped command's exit code
Development
Run from the repo root (
/path/to/janus)
npm run dev # extension hot-reload (Chrome) npm run dev:firefox # extension hot-reload (Firefox) npm test # run tests


























