BB

birdywen/batch-runner-mcp

Developer tools
0 stars 0 forks Quality 81 Trend 20MIT

Batch bash runner for MCP with mechanical expect checks. Zero npm deps.

Overview

Run several bash steps in one MCP call, and know whether each one actually did what you wanted. A zero exit code only proves a command ran. With omega_batch, every step can carry an expect assertion (contains / notContains / regex). Each step is reported as ok, FAIL (process) or FAIL (expectation), with exit code, signal, timeout and stderr kept separate. Steps skipped after a failure are listed as (halted) instead of silently disappearing. Zero npm dependencies. Node >= 20. Works with any MCP host that speaks stdio (Claude Code, opencode, Claude Desktop, ...). Then call omega_health once. The first line is the verdict (HEALTHY / DEGRADED); optional parts that are missing show as [--]. omega_batch waits for the verdict (up to waitMs, default 45s) and answers in the same call. Success is one line: A failure shows the exit code and the of the output, where errors are: - expect is checked against the output. Output over 4000 chars goes to an artifact:// ref.

README

batch-runner-mcp

Run several bash steps in one MCP call, and know whether each one actually did what you wanted.

A zero exit code only proves a command ran. With omega_batch, every step can carry an expect assertion (contains / notContains / regex). Each step is reported as ok, FAIL (process) or FAIL (expectation), with exit code, signal, timeout and stderr kept separate. Steps skipped after a failure are listed as (halted) instead of silently disappearing.

Zero npm dependencies. Node >= 20. Works with any MCP host that speaks stdio (Claude Code, opencode, Claude Desktop, …).

Install

Claude Code:

claude mcp add batch-runner -- npx -y github:Birdywen/batch-runner-mcp

Generic JSON config (mcpServers):

{ "batch-runner": { "command": "npx", "args": ["-y", "github:Birdywen/batch-runner-mcp"] } }

opencode (opencode.json, mcp section):

{ "batch-runner": { "type": "local", "command": ["npx", "-y", "github:Birdywen/batch-runner-mcp"] } }

Then call omega_health once. The first line is the verdict (HEALTHY / DEGRADED); optional parts that are missing show as [--].

Example

{ "steps": [
  { "label": "build", "command_line": "npm run build", "expect": { "contains": ["compiled successfully"] } },
  { "label": "smoke", "command_line": "node dist/cli.js --version", "env": { "NO_COLOR": "1" }, "expect": { "regex": "^\\d+\\.\\d+" } }
], "stopOnError": true }

omega_batch waits for the verdict (up to waitMs, default 45s) and answers in the same call. Success is one line:

batch job-xxxx: success 2/2 (3.1s): build | smoke

A failure shows the exit code and the tail of the output, where errors are:

batch job-xxxx: failed 1/2 (0.4s)
  [FAIL] 1. build (process)
      exit=2
      src/a.ts(3,7): error TS2322: Type 'string' is not assignable to type 'number'.
  [--] 2. (halted) -- stopOnError
  • expect is checked against the full output. Output over 4000 chars goes to an artifact:// ref.
  • Still running after waitMs: the reply has the job id; omega_batch_status {id, waitMs} picks it up. cancel: true kills the running step’s process group.
  • Job state is on disk after every step; after a restart an unfinished job reads as interrupted.
  • format: "json" gives structured per-step fields; verbose: true adds output.

Tools

Nine tools, about 1.8k tokens of schema in total.

Tool What it does
omega_batch Bash steps with expect checks; verdict in one call
omega_batch_status Wait for / cancel a batch that outlived waitMs
omega_read Many files in one call: slices, regex-filtered lines, outlines
omega_grep path:line search (rg, grep -E fallback)
omega_edit Multi-file exact-string edits, all-or-nothing; short summary + undo id; undo:"" rolls back
vfs_local_write Atomic file write without shell quoting
omega_sqlite Read-only SQL on any sqlite file
artifact Long output: regex lines with context, a slice, or the last 80 lines
omega_health Self-check

omega_flow (multi-step tool composition, see OMEGA-FLOW.md) is off by default; set OMEGA_FLOW=1 to advertise it.

Configuration

Everything works with defaults. Common overrides:

Variable Default / meaning
OMEGA_ARTIFACT_DIR ~/.omega-mcp/artifacts
OMEGA_JOB_DIR /tmp/omega-jobs — batch job state
OMEGA_SNAP_DIR /tmp/omega-snaps — omega_edit undo snapshots
OMEGA_MCP_LOG /tmp/omega-mcp.log
OMEGA_INLINE_LIMIT 20000 — output kept inline before spilling to an artifact
OMEGA_DEFAULT_TIMEOUT 120000 ms per step
OMEGA_CWD default working directory (home if unset)
OMEGA_FLOW=1 advertise omega_flow (limits: see OMEGA-FLOW.md)
OMEGA_FORCE_GREP 1 pins omega_grep to the grep fallback

Batch shells get /opt/homebrew/bin and /usr/local/bin prepended to PATH; a per-step env.PATH still wins.

Development

npm test

The MCP server loads code once at startup: restart the host after changing it.

omega_grep keeps rg and the grep fallback in step: the fallback uses ERE (so a|b works) and passes exactly one matcher flag (GNU grep rejects -E -F). OMEGA_GREP_TRACE=1 dumps the argv so the suite can assert on it.

View this README on GitHub

Install

npx -y github:Birdywen/batch-runner-mcp