safe-runbook-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@safe-runbook-mcpplan docker-service-status for service api"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
safe-runbook-mcp
A policy-gated MCP server for operational runbooks. It lets an AI inspect and run known commands without giving it an unrestricted shell.
Why it exists
AI agents are useful for operations, but handing one a terminal is a large trust decision. This project keeps the useful part—repeatable diagnostics and maintenance—inside a small, reviewable boundary:
AI client → inspect plan → policy checks → optional human approval → exact command
Related MCP server: AgentsGate
Safety model
Runbooks are version-controlled JSON; the AI cannot invent a command.
Execution is off by default.
Executables must be explicitly allowlisted.
Variables are regex-validated and become complete process arguments.
Commands run with
shell: falseinside a realpath-confined workspace.Mutating and destructive plans require a short-lived HMAC approval token created outside MCP.
The token is bound to the runbook and exact plan hash, so changed inputs invalidate it.
Processes have time and output limits; declared secrets are redacted.
MCP tool annotations are also provided for clients, while server-side checks remain the authority.
Stack
TypeScript 7, Node.js 22, MCP TypeScript SDK v2, Zod 4, Vitest 4, Biome 2, Docker, and GitHub Actions. The project is open source and has no paid API dependency.
Quick start
npm install
npm run cli -- list
npm run cli -- plan docker-service-status --var service=api
npm testExecution must be enabled explicitly:
RUNBOOK_EXECUTION_ENABLED=true npm run cli -- run disk-usageFor a mutating runbook, generate approval outside the MCP connection and use the same variables for approval and execution:
export RUNBOOK_EXECUTION_ENABLED=true
export RUNBOOK_APPROVAL_SECRET='replace-with-a-long-random-secret'
TOKEN=$(npm run --silent cli -- approve restart-compose-service --var service=api)
npm run cli -- run restart-compose-service --var service=api --approval "$TOKEN"Connect an MCP client
Build once, then add this stdio server to an MCP-compatible client. Replace the paths with absolute paths on your machine.
{
"mcpServers": {
"safe-runbooks": {
"command": "node",
"args": ["/absolute/path/safe-runbook-mcp/dist/server.js"],
"env": {
"RUNBOOK_DIRECTORY": "/absolute/path/safe-runbook-mcp/runbooks",
"RUNBOOK_WORKSPACE": "/workspace/to/manage",
"RUNBOOK_EXECUTION_ENABLED": "false"
}
}
}
}The server exposes:
list_runbooks— discover available runbooks and risk levels.inspect_runbook— resolve variables and return the exact plan plus its hash.execute_runbook— execute the already-defined plan after policy checks.runbook://catalog— read-only catalog resource.
Logs go to stderr because stdout is reserved for MCP JSON-RPC traffic.
Add a runbook
Create a JSON file in runbooks/:
{
"id": "service-status",
"title": "Inspect a service",
"description": "Read one Compose service state.",
"risk": "diagnostic",
"variables": {
"service": {
"description": "Compose service name",
"pattern": "[a-zA-Z0-9][a-zA-Z0-9_-]{0,62}",
"required": true
}
},
"steps": [
{
"id": "status",
"title": "Read status",
"executable": "docker",
"args": ["compose", "ps", "{{service}}"]
}
]
}Choose diagnostic, mutating, or destructive. Variables must occupy a complete argument such as "{{service}}"; string interpolation is intentionally rejected.
Docker
docker build -t safe-runbook-mcp .
docker run --rm -i \
-v "$PWD:/workspace:ro" \
-e RUNBOOK_WORKSPACE=/workspace \
-e RUNBOOK_DIRECTORY=/app/runbooks \
safe-runbook-mcpKeep execution disabled for a read-only mount. If a runbook needs Docker, mount only the required socket or remote context after reviewing that trust boundary.
Development
npm run check
npm run typecheck
npm test
npm run buildSee CONTRIBUTING.md for the branch workflow and AGENTS.md for repository rules used by coding agents.
References
License
MIT
Available Tools
3 toolsexecute_runbookExecute an approved runbookADestructive
Execute only commands declared in a version-controlled runbook. Requires the global execution gate; mutating plans also require an out-of-band approval token.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| variables | No | ||
| approvalToken | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral detail beyond the annotations by warning that only commands declared in a version-controlled runbook may be executed, and by disclosing both the global execution gate and the special approval token needed for mutating plans. This meaningfully helps an agent understand the operational restrictions around execution, while the destructiveHint annotation is not contradicted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise: two sentences that front-load the core scoping rule, then state the indispensable prerequisites. Every sentence contributes meaningful information, with no repetition or irrelevant detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description adequately covers the approval and mutating-plan aspects of the tool, which matters given its destructive, non-idempotent nature. However, with three parameters, nested objects, and no output schema, it omits crucial guidance about what the 'id' refers to, how variables are used, and what happens on invocation. This leaves the definition minimally usable, not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description itself must clarify parameters, but it does not. It indirectly references the approvalToken concept when mentioning an out-of-band approval token, but it never explains the 'id' parameter or the 'variables' object, both of which are non-obvious and important for actual invocation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a concrete verb, 'execute', and a specific scoped resource: commands declared only in a version-controlled runbook. It clearly differentiates this execution action from the sibling 'inspect_runbook' and 'list_runbooks' tools by focusing on execution rather than inspection or enumeration.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear preconditions for use: the global execution gate is required, and mutating runbooks additionally require an out-of-band approval token. It does not explicitly state when not to use the tool or compare it to siblings, but the prerequisites provide enough context for when it is valid to invoke.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inspect_runbookInspect a resolved runbook planARead-onlyIdempotent
Validate variables and return the exact commands, plan hash, risk, and approval requirement without executing.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| variables | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the description doesn't need to restate those. The description adds value by explicitly stating 'without executing', which clarifies that no side effects will occur, and it lists what the tool returns (commands, plan hash, risk, approval requirement). This goes beyond the annotations, which only cover the general safety profile. The description doesn't contradict annotations; in fact, it reinforces them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that front-loads the action ('Validate variables and return the exact commands') and adds the critical constraint ('without executing'). Every word earns its place, and it's appropriately sized for the tool's complexity. There is no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an inspection tool with no output schema, the description covers the essential return values (commands, plan hash, risk, approval requirement) and explicitly says it doesn't execute, which is a key behavioral detail. It doesn't mention any security implications or prerequisites, but given the simplicity and annotations, it's fairly complete. The only minor gap is explaining what 'resolved' means, but it's not critical.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description does not add specific detail about the parameters. The 'id' parameter is obvious, but 'variables' is only hinted at by the phrase 'Validate variables', which gives some context. However, the description doesn't explain the structure of the variables object or any constraints, which the schema already provides some info on. With 0% coverage, the description should do more to compensate, but it partially does by mentioning 'validate variables'. This is a baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the verb 'validate' and 'return' to specify what the tool does, with the resource being a 'resolved runbook plan'. It clearly enumerates the outputs (commands, plan hash, risk, approval requirement) and emphasizes 'without executing', which distinguishes it from its sibling 'execute_runbook'. However, it could be more explicit about the 'inspect' nature versus 'inspect' in the name, but it's clear enough.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Validate variables and return the exact commands... without executing' clearly implies this tool is for inspection, not execution, and the title 'Inspect a resolved runbook plan' sets the context. It doesn't explicitly name the sibling 'execute_runbook' as the alternative, but the 'without executing' phrase effectively communicates the distinction. It doesn't mention when to use this over 'list_runbooks', but the purpose is distinct enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_runbooksList safe runbooksARead-onlyIdempotent
List version-controlled runbooks and their risk levels. Does not execute anything.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds value by saying the tool does not execute runbooks, which is a meaningful behavioral guarantee beyond generic read-only, and notes the resource is version-controlled.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with no filler. The primary action and result are front-loaded, and the critical behavioral clarification 'Does not execute anything' earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-parameter read-only list tool, the description covers what the call and returns conceptually: version-controlled runbooks and their risk levels. There is no return schema, but the description gives sufficient context for invocation and interpretation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is no parameter semantics gap to compensate for. The description needs no parameter documentation to make the tool invocable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'List version-controlled runbooks and their risk levels.' The added 'Does not execute anything' clearly separates it from execute_runbook, and 'list' vs 'inspect' is self-evident against inspect_runbook.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Does not execute anything' provides a practical exclusion and implicitly points to execute_runbook for execution needs. It does not explicitly mention inspect_runbook, but the list-vs-inspect distinction is clear enough from context and the sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
execute_runbook - First observed
inspect_runbook - First observed
list_runbooks
TDQS
Scored across 3 tools
Each tool has a clearly distinct purpose: inspect validates and previews, execute runs commands, and list enumerates available runbooks. There is no overlap or ambiguity between them.
All three tool names follow a consistent verb_noun pattern: inspect, execute, and list all pair with 'runbook'. The naming is uniform and predictable.
With only three tools, the server is lean but covers the essential operations for runbook management: discover, preview, and execute. It is slightly minimal but appropriate for a focused purpose.
The server provides the core lifecycle for runbooks: list, inspect, and execute. Missing are update/delete operations, but since runbooks are version-controlled externally, those may be intentionally out of scope. No critical gaps for safe execution.
Maintenance
Related MCP Connectors
Security gateway for AI agents: policy, approval, and audited execution, no secrets shared.
Runtime permission, approval, and audit layer for AI agent tool execution.
- emisarOAuthdev.emisar
Let AI operate servers without SSH. Choose actions, approve risky changes, and audit every step.
The system of record for AI agent authority: playbooks, routed policy questions, reusable rules.
Related MCP Servers
- FlicenseNot gradedqualityAmaintenanceThe Control Plane for Autonomous AI Enforce policy before execution, require human approvals where risk demands it, and keep a full audit trail — from first action to final result.504-

AgentsGateofficial
AlicenseNot gradedqualityAmaintenanceEnables AI agents to securely call MCP tools with risk scoring, checkpoints, rollback, and approval workflows.17MIT- FlicenseNot gradedqualityBmaintenanceEnables AI coding agents to evaluate actions against team-defined policies, record decisions, and obtain human approvals for potentially risky operations.1131-
- FlicenseNot gradedqualityCmaintenanceEnables controlled AI-agent access to enterprise-shaped tools with a deny-by-default gated write path, human approval, dry-run execution, and append-only audit logging.1-