
Security News
Deno Goes the Way of the Dinosaur
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.
@systemdox/runbook-mcp
Advanced tools
Your runbooks, as agent tools. Declare scripts in a runbooks.json manifest and serve them to Claude Code, Cursor and any MCP client as typed, allowlisted tools - no free text ever reaches your shell.
Your runbooks, as agent tools.
SystemDox gives AI coding agents your
architecture context — the checks, rules, decisions and docs that say what
good looks like. This server gives them hands, safely: declare the scripts
your team already runs in a runbooks.json manifest, and every one of them
becomes an MCP tool with a typed, allowlisted input schema that Claude Code,
Cursor and any other MCP client can call.
No free text ever reaches your shell. That is the whole design.
// runbooks.json
{
"version": 1,
"runbooks": [
{
"name": "sync_repos",
"description": "Fetch every repo and fast-forward clean checkouts. Run before researching a repository.",
"script": "ops/sync-repos.ps1",
"interpreter": "powershell",
"params": {
"reportOnly": { "type": "boolean", "flag": "-ReportOnly", "description": "Fetch and report; change nothing." }
}
}
]
}
Result, as the agent sees it:
sync_repos(reportOnly?: boolean)
"Fetch every repo and fast-forward clean checkouts. Run before researching a repository.
Runs sync-repos.ps1 (powershell); timeout 300s."
A shell is an unbounded surface: any command, any argument, no record of which ones the team sanctioned. A runbook server is a declared surface:
| An agent with a shell | An agent with runbooks |
|---|---|
| Runs anything it can type | Runs only the scripts in the manifest |
| Composes arguments as free text | Fills typed parameters that must match a pattern or an enum |
| No timeouts, unbounded output | Per-runbook timeout, bounded output (the tail, with the drop reported) |
| Nothing tells the client what is safe | readOnly / destructive / idempotent annotations on every tool |
| The operator learns what ran afterwards | Every result starts with the exact command line that ran |
The manifest is the contract. Agents cannot extend it; they can only call what it offers, with what it allows.
npx @systemdox/runbook-mcp init # writes runbooks.json + runbooks/hello.mjs
npx @systemdox/runbook-mcp validate # shows exactly what agents will get
Then register the server with your MCP client. Claude Code, project scope
(.mcp.json in the repository root):
{
"mcpServers": {
"runbooks": {
"command": "npx",
"args": ["-y", "@systemdox/runbook-mcp", "--manifest", "./runbooks.json"]
}
}
}
Restart the client and ask: "List the runbooks you have and run hello with
name set to the team."
The manifest is found via --manifest <path>, then $RUNBOOK_MCP_MANIFEST,
then ./runbooks.json in the working directory.
| Field | Required | Default | Meaning |
|---|---|---|---|
name | yes | — | Tool name; snake_case (^[a-z][a-z0-9_]{0,63}$) |
description | yes | — | What it does and when to use it — this is what the agent reads |
script | yes | — | Path to the script, relative to the manifest (absolute allowed) |
interpreter | yes | — | powershell, pwsh, bash, sh, node, python or exe |
cwd | no | manifest folder | Working directory, relative to the manifest |
timeoutSeconds | no | 300 | Hard limit; the whole process tree is killed when it passes |
maxOutputChars | no | 60000 | Per stream. The tail is kept and the drop is reported |
env | no | — | Extra environment for the script (literal values — put secrets in the client's env) |
readOnly / destructive / idempotent | no | false | Published as MCP tool annotations |
params | no | {} | The tool's input schema — see below |
Every parameter maps to one of: a fixed flag from the manifest, or a positional argument. Booleans emit their flag when true and nothing when false.
| Field | Applies to | Meaning |
|---|---|---|
type | all | boolean, string, number or array (of strings) |
flag | all | The literal flag to emit, e.g. --name or -ReportOnly (^-{1,2}[A-Za-z][A-Za-z0-9-]*$) |
positional | string, number, array | Emit the value without a flag |
required | all | Refuse the call when missing |
default | all | Applied when the agent omits the argument; must satisfy the constraint |
description | all | Shown to the agent |
pattern | string, array | Anchored regex (^...$) every value must match |
enum | string, array | The only values accepted |
integer, minimum, maximum | number | Bounds |
join | array | Emit one flag with the items joined by this separator instead of repeating the flag |
maxItems | array | Upper bound on the number of items |
A string or array parameter must declare pattern or enum. There is
no "any string" parameter type. Values containing a double quote or a control
character are refused whatever the pattern says.
interpreter | Runs | Windows default |
|---|---|---|
powershell | powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command "& '<script>' <args>; exit $LASTEXITCODE" | Windows PowerShell 5.1 (pwsh elsewhere) |
pwsh | same, via PowerShell 7 | pwsh |
bash / sh | <bash> <script> <args> | Git for Windows bash ($RUNBOOK_MCP_BASH to override) |
node | the running Node binary | — |
python | python <script> <args> | python (python3 elsewhere) |
exe | the script itself is the executable | — |
Override any of them per manifest:
"interpreters": { "bash": "C:\\Program Files\\Git\\bin\\bash.exe" }
PowerShell scripts are invoked through -Command rather than -File because
-File cannot bind array parameters and cannot set the console encoding.
Every value is single-quoted, with embedded quotes doubled — inside single
quotes PowerShell performs no expansion, so a value that passed its pattern
cannot change the shape of the command. Array parameters arrive as real
PowerShell arrays (-Keep 'a','b'). All other interpreters receive an
argument array directly; nothing goes through a shell.
clean_worktrees: exit 0 (41.3s)
$ powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command "... & 'C:\ops\clean-worktrees.ps1' -ReportOnly -Match 'sdx*'; exit $LASTEXITCODE"
--- stdout ---
Would delete 7 worktrees (3 held back: uncommitted changes)
...
A non-zero exit, a timeout or a process that failed to start comes back as an MCP error result with the same layout, so the agent can read the log and decide — it is never a protocol error.
validate tells you first.env
(for example "${SENTRY_ACCESS_TOKEN}" in Claude Code's .mcp.json); the
manifest holds literals only.RUNBOOK_MCP_DRY_RUN=1 makes every tool report the command it
would run instead of running it — useful in CI and when reviewing a new
manifest.The manifest says what the agent can run. The when belongs in your standards, where every agent in every repository reads it at write time:
sync_repos before researching a
repository checkout; research the fresh tree, never a stale one";One .mcp.json then carries the whole toolbelt:
{
"mcpServers": {
"systemdox": {
"type": "http",
"url": "https://<your-workspace>.mcp.systemdox.com/mcp",
"headers": { "Authorization": "Bearer ${SYSTEMDOX_API_KEY}" }
},
"runbooks": {
"command": "npx",
"args": ["-y", "@systemdox/runbook-mcp", "--manifest", "./runbooks.json"]
},
"sentry": {
"command": "npx",
"args": ["-y", "@sentry/mcp-server@latest", "--host=de.sentry.io"],
"env": { "SENTRY_ACCESS_TOKEN": "${SENTRY_ACCESS_TOKEN}" }
},
"cloudwatch": {
"command": "uvx",
"args": ["awslabs.cloudwatch-mcp-server@latest"],
"env": { "AWS_REGION": "eu-west-2", "AWS_PROFILE": "${AWS_PROFILE:-default}" }
}
}
}
Full guide: Runbooks as agent tools.
systemdox-runbook-mcp [--manifest <path>] Start the MCP server (stdio)
systemdox-runbook-mcp init Write a starter manifest and example script
systemdox-runbook-mcp validate Check the manifest; list tools and the command each would run
systemdox-runbook-mcp --help | --version
| Environment variable | Purpose |
|---|---|
RUNBOOK_MCP_MANIFEST | Manifest path (alternative to --manifest) |
RUNBOOK_MCP_DRY_RUN=1 | Report commands instead of running them |
RUNBOOK_MCP_BASH | Path to bash.exe on Windows |
import { loadManifest, createServer } from "@systemdox/runbook-mcp";
const server = createServer(loadManifest("./runbooks.json"));
// connect it to any transport from @modelcontextprotocol/sdk
ISC — PuglieseWeb LTD.
FAQs
Your runbooks, as agent tools. Declare scripts in a runbooks.json manifest and serve them to Claude Code, Cursor and any MCP client as typed, allowlisted tools - no free text ever reaches your shell.
The npm package @systemdox/runbook-mcp receives a total of 253 weekly downloads. As such, @systemdox/runbook-mcp popularity was classified as not popular.
We found that @systemdox/runbook-mcp demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.

Security News
Anthropic’s free OSS Scanner uses Mythos and other Claude models to find open source vulnerabilities and send maintainers reports with proposed fixes.

Security News
On Front Lines’ Early Adopters: CISO podcast, Andrew Becherer shares lessons from Datadog, weighs the long-term costs of AI-built tools, and explains how founders can actually gain a CISO’s trust.