brainlog

Transparent process wrapper that captures stdout, stderr, and stdin — with an MCP server so LLM agents can read your terminal output.

v1.0 · production ready Pair it with the agent skill for the best results.

Get started in seconds

Grab the prebuilt binary, or build from source with Cargo.

Prebuilt binary
curl -fsSL https://raw.githubusercontent.com/urjitbhatia/brainlog/master/install.sh | sh

macOS & Linux, no Rust toolchain required. Linux builds are statically linked (musl).

From source
cargo install --git https://github.com/urjitbhatia/brainlog

Compiles from source — requires a Rust toolchain.

Everything you need

Drop brainlog in front of any command and gain full observability with zero configuration.

Invisible Wrapping

PTY proxy so wrapped processes behave identically. Colors, interactive prompts, TUI apps — isatty() returns true, everything just works.

Full I/O Capture

Every byte of stdout, stderr, and stdin recorded with nanosecond timestamps in a compact framed binary format. Nothing is lost.

MCP Server for Agents

7 tools let LLM agents discover, read, search, and watch process output directly — no copy-pasting required.

Auto-restart & Resume

Keep services alive with --restart, and resume named services across sessions. Long-running processes made easy.

Daemon mode

Hand a command to brainlog -D and get your shell back instantly. A singleton daemon supervises detached wrappers, so services outlive your terminal.

Status you can trust

running means actually running. Records are reconciled against live processes on every read, so a wrapper killed by SIGKILL or lost with its terminal self-heals to crashed instead of lingering as a phantom service.

Your agent waits for
exactly the right moment

Instead of sleeping blindly and hoping a server is up, wait_for_pattern blocks until a regex appears in the process output — then returns immediately. Like Playwright's waitForText, but for any terminal process.

No polling loops. No arbitrary timeouts. No racing against a server that isn't ready yet. The agent proceeds with certainty.

configurable timeout regex pattern returns matched line works on running processes

Wrap any command

Prefix any command with brainlog — the process runs exactly as before.

# Wrap any process — transparent to the child
$ brainlog node server.js
$ brainlog python app.py
$ brainlog cargo build
 
# Name your services for easy reference
$ brainlog -n my-api node server.js
$ brainlog -n worker -t env:prod ./run.sh
 
# Auto-restart on exit
$ brainlog run --restart -- node server.js
 
# Resume a previous service (same name, new run)
$ brainlog run --resume my-api -- node server.js
 
# Start the MCP server for Claude Code / other agents
$ brainlog mcp

Connect to your agent

Brainlog speaks MCP — add it to any agent that supports the protocol.

One command — globally available across all projects:

$ claude mcp add brainlog -- brainlog mcp
 
# Or scope to a single project
$ claude mcp add --scope project brainlog -- brainlog mcp

Brainlog + the skill = agents that actually know

The MCP server gives your agent the tools. The skill teaches it when to reach for them. Together they are how agents get the most out of brainlog.

Connecting the MCP server alone leaves your agent guessing. The skill closes that gap — it teaches the agent to check brainlog first when you say a build failed or a server is crashing, to wait on a real readiness line instead of sleeping, and to suggest brainlog <cmd> when it needs output it cannot see.

  • Reads your dev server's output instead of asking you to paste it
  • Blocks on wait_for_pattern until a service is genuinely ready
  • Searches every tracked process for the error, not just the one you mentioned
  • Knows when to reach for daemon mode, kill, and restart
Install for Claude Code
mkdir -p .claude/skills/brainlog-guide && curl -fsSL https://raw.githubusercontent.com/urjitbhatia/brainlog/master/.claude/skills/brainlog-guide/SKILL.md -o .claude/skills/brainlog-guide/SKILL.md

Drops SKILL.md into your project. Use ~/.claude/skills/ instead to make it available everywhere.

Full command-line interface

View logs, search output, control processes, and manage storage — all from the terminal.

View Logs

# List tracked services (newest first)
brainlog list
# Group by executable + working directory
brainlog list -g
 
# View logs by name, service ID, or run ID
brainlog logs my-api
# Last 50 lines
brainlog logs my-api --tail 50
# Follow (like tail -f) — keeps following across restarts
brainlog logs my-api -f
# Stderr only
brainlog logs my-api -s stderr

Search

# Regex across all services
brainlog search "ERROR|WARN"
 
# Scoped to one service
brainlog search "panic" --service my-api

Process Control

# Send SIGTERM (graceful stop)
brainlog kill my-api
# Force kill (SIGKILL)
brainlog kill my-api -f
# Send a specific signal
brainlog kill my-api -s HUP
 
# Restart via wrapper (SIGUSR1)
brainlog restart my-api

Housekeeping

# Delete services older than 7 days
brainlog purge --before 7d
 
# Preview what would be purged
brainlog purge --before 1h --name tmp --dry-run

Daemon mode

# Launch in the background (daemon autostarts on first use)
brainlog -D -n api node server.js
 
# Inspect supervised services
brainlog daemon status
 
# Stop the daemon (also stops its children)
brainlog daemon stop

7 tools for LLM agents

A complete toolkit for agents to observe, query, and control your processes without any manual copy-pasting.

Tool Description
list_recent_runs Last N runs across all services, newest first — best for "what just happened?"
discover_services Find tracked services by name, cwd, tags, port, executable, status, or exit code
get_logs Read stdout, stderr, or stdin by service ID, run ID, or working directory
search_logs Regex search across all services with timestamps and context lines
wait_for_pattern Block until a regex appears in output — like Playwright's waitForText
kill_service Send a signal (SIGTERM, SIGKILL, etc.) to stop a running process
restart_service Restart a running process via its wrapper (SIGUSR1)

Agents know what's happening

A natural sequence of tool calls gives any LLM agent full situational awareness over your running processes.

list_recent_runs
"What just ran?" — See the last N runs with status, exit codes, and optional log previews.
discover_services
"What's running in this project?" — Filter by cwd to scope to the current repository.
get_logs
Read output by ID or by cwd shorthand — no need to discover first.
search_logs
Find errors, warnings, or specific patterns across all tracked commands with regex.
wait_for_pattern
Start a server, then wait for "listening on port 3000" before proceeding.

How it works

Built on solid Unix primitives — PTY, SQLite, and a compact binary frame format.

PTY Proxy

Allocates a pseudo-terminal so the wrapped process behaves identically. isatty() returns true, colors and interactive prompts work, and terminal dimensions are inherited.

Framed Binary Logs

Every byte of stdout, stderr, and stdin is recorded with nanosecond timestamps. Frame format: [timestamp_ns:u64][stream:u8][len:u32][payload]

Auto-naming

Services without -n get a derived name from working directory and executable. LLM enrichment can generate human-readable names from initial output.

SQLite + WAL

Service and run metadata lives in a SQLite database with WAL mode for concurrent reads. Logs are compact binary files in ~/.brainlog/logs/.

Storage layout

~/.brainlog/ brainlog.db # SQLite (WAL mode) — service + run metadata config.yaml # optional LLM enrichment config logs/<run-id>/ stdout.log, stderr.log, stdin.log # per-stream framed binary logs combined.log # interleaved stream