Dev Runner CLI - Terminal UI for managing multiple dev services with colored logs, filtering, and MCP integration for Claude Code
A terminal UI for managing multiple dev services with colored logs, filtering, and MCP integration.
curl -fsSL https://raw.githubusercontent.com/productdevbook/devir/master/install.sh | bash
brew install productdevbook/tap/devir
Download from Releases
| Platform | Download |
|---|---|
| macOS (Apple Silicon) | devir-darwin-arm64.tar.gz |
| macOS (Intel) | devir-darwin-amd64.tar.gz |
| Linux (x64) | devir-linux-amd64.tar.gz |
| Linux (ARM64) | devir-linux-arm64.tar.gz |
| Windows (x64) | devir-windows-amd64.zip |
go install github.com/productdevbook/devir@latest
Or build manually:
git clone https://github.com/productdevbook/devir.git
cd devir
make build
# Create devir.yaml (auto-detects project structure)
devir init
# Start services
devir
devir init
This creates a devir.yaml file by detecting your project structure:
package.json with dev scriptgo.modCargo.tomlrequirements.txt or pyproject.tomlapps/*, packages/*, services/*# Start all default services
devir
# Start specific services
devir admin server
# With filters
devir --filter "error"
devir --exclude "hmr"
devir --mcp
Devir uses a Unix socket daemon, allowing multiple clients (TUI or MCP) to connect to the same running services:
# Terminal 1: Start TUI (daemon starts automatically)
devir
# Terminal 2: Connect another TUI (same services, same logs)
devir
# Terminal 3: Connect via MCP (Claude Code controls same services)
devir --mcp
All clients share the same daemon and see the same logs in real-time. When Claude Code restarts a service, you’ll see it immediately in your TUI.
| Key | Action |
|---|---|
Tab |
Cycle through services |
1-9 |
Select specific service |
a |
Show all services |
/ |
Search logs |
c |
Copy logs to clipboard |
r |
Restart current service |
j/k |
Scroll up/down |
q |
Quit |
Create devir.yaml in your project root:
services:
admin:
dir: apps/admin
cmd: bun run dev
port: 3000
color: blue
server:
dir: server
cmd: bun run dev
port: 3123
color: magenta
defaults:
- admin
- server
| Field | Description |
|---|---|
dir |
Working directory (relative to config file) |
cmd |
Command to run |
port |
Port number (for status display) |
color |
Log prefix color: blue, green, yellow, magenta, cyan, red, white |
icon |
Custom emoji/icon for the service |
type |
Service type: service (default), oneshot, interval, http |
interval |
Run interval for interval type (e.g., 5s, 1m) |
url |
URL for http type |
method |
HTTP method for http type (default: GET) |
body |
Request body for http type |
headers |
Custom headers for http type |
Devir supports 4 different service types:
service (default)Long-running process. For web servers, APIs, etc.
web:
dir: apps/web
cmd: npm run dev
port: 3000
icon: "🌐"
color: blue
oneshotRun once and exit. For migrations, setup scripts, etc.
migrate:
type: oneshot
dir: .
cmd: npm run migrate
icon: "⚙️"
color: yellow
intervalRun periodically. For health checks, cleanup jobs, etc.
health:
type: interval
interval: 5s
dir: .
cmd: bash health.sh
icon: "💓"
color: green
httpMake HTTP requests. For API calls, webhooks, etc.
api-check:
type: http
url: https://api.example.com/health
method: GET
icon: "📡"
color: magenta
With POST body:
notify:
type: http
url: https://api.example.com/webhook
method: POST
body: '{"event": "started"}'
headers:
- "Authorization: Bearer token123"
icon: "📤"
color: cyan
| Symbol | Status | Description |
|---|---|---|
● |
Running | Service is active |
✓ |
Completed | Oneshot/HTTP completed successfully |
✗ |
Failed | Service failed |
◐ |
Waiting | Interval service waiting for next run |
○ |
Stopped | Service is stopped |
Services can dynamically update their icon and status by writing to .devir-status file in their directory:
# Simple - just icon
echo "🟢" > .devir-status
# JSON - icon + message
echo '{"icon": "🟢", "message": "All OK"}' > .devir-status
# JSON - full control
echo '{"icon": "🔴", "color": "red", "status": "failed", "message": "DB down!"}' > .devir-status
| Field | Description |
|---|---|
icon |
Override icon with emoji or short text |
color |
Override service color |
status |
Override status: running, completed, failed, waiting |
message |
Status message (shown in MCP response) |
#!/bin/bash
# health.sh
if curl -sf http://localhost:3000/health >/dev/null 2>&1; then
echo '{"icon": "🟢", "message": "All systems operational"}' > .devir-status
echo "Health OK"
else
echo '{"icon": "🔴", "color": "red", "message": "Service down!"}' > .devir-status
echo "Health FAIL"
fi
Add to your project’s .mcp.json:
{
"mcpServers": {
"devir": {
"command": "devir",
"args": ["--mcp"],
"cwd": "/path/to/project"
}
}
}
undefinedNote: Set
cwdto the directory containing yourdevir.yaml. The daemon socket is unique per project directory, so multiple projects can run independently.
| Tool | Description |
|---|---|
devir_start |
Start services |
devir_stop |
Stop all services |
devir_status |
Get service status (includes type, icon, message) |
devir_logs |
Get recent logs |
devir_restart |
Restart a service |
devir_check_ports |
Check if ports are in use |
devir_kill_ports |
Kill processes on ports |
{
"services": [
{
"name": "web",
"running": true,
"port": 3000,
"type": "service",
"status": "running",
"icon": "🌐"
},
{
"name": "health",
"running": true,
"type": "interval",
"status": "waiting",
"icon": "🟢",
"message": "All systems operational",
"runCount": 5
}
]
}
View devir logs directly in Chrome DevTools. The extension connects via WebSocket to the devir daemon.
Download from Releases and extract devir-extension.zip.
chrome://extensionsStart devir with WebSocket enabled (default port 9222):
devir
Open Chrome DevTools (F12) on any page
Click the “Devir” tab
By default, devir starts WebSocket server on port 9222. To use a different port:
devir --ws-port 9333
undefinedNote: If you change the port, you’ll need to modify the extension’s
useWebSocket.tsto match.
# Build
make build
# Build for all platforms
make build-all
# Run tests
make test
# Lint
make lint
MIT
We use cookies
We use cookies to analyze traffic and improve your experience. You can accept or reject analytics cookies.