runtime-mcp
by idyllic-labs
README.md
# runtime-mcp
Drop-in MCP server that lets Claude inspect, debug, and hot-fix your running Bun process through conversation.
One line of code. Claude can now see inside your running Bun server — memory, queries, traffic, errors, everything.
```typescript
import { attachMCP } from 'runtime-mcp';
attachMCP({ port: 3100 }); // that's it
```
Your Bun process now speaks [MCP](https://modelcontextprotocol.io/). Connect Claude Desktop, Cursor, or any MCP client and start asking questions about your live app.
## Why
Debugging a running app today means adding logging, restarting, and hoping you guessed the right thing to log. LLMs can read your source code, but they can't see your runtime state — the variable values, the open connections, the slow queries, the memory growth.
runtime-mcp fixes that. It exposes your process internals as MCP resources and tools, so the LLM examines the live patient instead of guessing from the chart.
## Quick Start
### 1. Install
```bash
bun add runtime-mcp
```
### 2. Attach to your server
```typescript
import { serve } from 'bun';
import { attachMCP } from 'runtime-mcp';
const server = serve({
port: 3000,
fetch: () => new Response('Hello'),
});
attachMCP({
port: 3100,
bind: { server },
});
```
### 3. Connect Claude Desktop
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"my-app": {
"url": "http://localhost:3100/sse"
}
}
}
```
Restart Claude Desktop. Ask: *"What is this process doing?"*
## What Claude Can See
### Resources (read-only, always available)
| Resource | URI | Description |
|----------|-----|-------------|
| Process info | `runtime://process/info` | PID, uptime, Bun version, entrypoint, env vars |
| Memory | `runtime://process/memory` | RSS, heap used/total, external, array buffers |
| Event loop | `runtime://process/event-loop` | Pending timers, active handles, loop lag |
| HTTP routes | `runtime://server/routes` | All registered routes, active connections, req/min |
| Request log | `runtime://server/requests` | Recent HTTP requests with status, duration, bodies |
| Errors | `runtime://errors/recent` | Uncaught exceptions and unhandled rejections (deduplicated) |
| DB connections | `runtime://db/connections` | Pool state, recent queries, slow queries |
| Module graph | `runtime://modules/graph` | Full dependency tree from entrypoint |
| WebSockets | `runtime://websockets` | Active connections, message counts |
| Variables | `runtime://variables/{path}` | Inspect any bound variable by dot-path |
### Tools (actions Claude can take)
| Tool | Description |
|------|-------------|
| `inspect` | Deep-inspect any reachable object by expression |
| `eval` | Execute JavaScript in the process context |
| `get_source` | Read source files from the running process |
| `intercept_requests` | Capture HTTP traffic matching a glob pattern |
| `intercept_sql` | Capture SQL queries matching a substring |
| `subscribe_events` | Stream real-time events (requests, errors, queries) |
| `heap_snapshot` | Take a V8 heap snapshot, diff against previous |
| `profile` | CPU profile for N milliseconds* |
| `set_breakpoint` | Conditional breakpoints with state capture* |
| `hot_patch` | Replace a module's code at runtime without restart |
| `shell` | Run read-only shell commands in the process cwd |
*\*Requires `node:inspector` — not yet available in Bun ([tracking issue](https://github.com/oven-sh/bun/issues/2445)).*
### Prompts (guided debugging workflows)
| Prompt | Description |
|--------|-------------|
| `debug-endpoint` | Systematically debug a specific HTTP endpoint |
| `find-memory-leak` | Snapshot, wait, diff, identify growing allocations |
| `explain-process` | Full overview of what the process is doing right now |
| `generate-tests` | Watch live traffic and generate test cases from it |
| `optimize-query` | Find slow queries, explain plans, suggest fixes |
## Configuration
```typescript
attachMCP({
// Transport
port: 3100, // MCP server port (default: 3100)
host: 'localhost', // Bind address (default: 'localhost')
// What to expose
bind: { // Objects the LLM can inspect/eval against
server,
db,
config,
},
// Access control
readOnly: false, // Disable eval, hot_patch, shell (default: true in production)
allowedTools: undefined, // Whitelist specific tools
blockedTools: undefined, // Blacklist specific tools
// Observation tuning
requestLog: {
maxSize: 1000, // Ring buffer size
includeBodies: true, // Capture req/res bodies (default: false in production)
},
sqlLog: {
maxSize: 500,
includeParams: true, // Capture query params (default: false in production)
slowThreshold: 500, // Slow query threshold in ms
},
// Remote access (requires auth)
auth: 'your-secret-token', // Required when host !== localhost
});
```
### Production Defaults
When `NODE_ENV=production`, runtime-mcp automatically:
- Sets `readOnly: true` — disables `eval`, `hot_patch`, `shell`
- Hides request/response bodies
- Hides SQL query parameters
- All read-only inspection tools remain available
## Binding Objects
Pass objects to `bind` to make them accessible to Claude:
```typescript
import { serve } from 'bun';
import { SQL } from 'bun';
import { attachMCP } from 'runtime-mcp';
const db = new SQL('postgres://localhost/myapp');
const server = serve({ port: 3000, fetch: handleRequest });
const config = { featureFlags: { newCheckout: true }, rateLimit: 100 };
attachMCP({
port: 3100,
bind: { server, db, config },
});
```
runtime-mcp auto-detects:
- **Bun.serve() servers** — wraps the fetch handler to intercept HTTP traffic
- **Bun.sql instances** — wraps queries to capture SQL traffic
- **WebSocket handlers** — tracks connections and messages
Everything else is available through `inspect` and `eval` by name.
## Security
- Binds to `localhost` only by default
- Non-localhost binding requires the `auth` option (Bearer token)
- Production mode disables code execution tools
- Shell tool blocks destructive commands (`rm`, `kill`, `shutdown`, etc.)
- Sensitive env vars are filtered from process info
This is a **development tool**. Treat the MCP port like a debugger port — don't expose it to the internet.
## Requirements
- Bun >= 1.0.0
- An MCP client (Claude Desktop, Cursor, or any MCP-compatible tool)
## How It Was Built
This project was built in a single session using [Ralph](https://github.com/williamcotton/ralph), an autonomous AI agent loop. A PRD was written, converted to a task list, and Ralph implemented all 22 user stories sequentially — each one adding a resource, tool, or interceptor layer.
## License
MIT