$ shellfirm

MCP Server

Run shellfirm as an MCP server for AI coding agents

shellfirm implements a Model Context Protocol (MCP) server that AI agents can connect to for command safety checks. The server runs over stdio using JSON-RPC 2.0.

Starting the server

shellfirm mcp

This starts the MCP server, reading JSON-RPC requests from stdin and writing responses to stdout. The server runs until stdin is closed.

Exposed tools

The MCP server exposes four tools:

ToolPurpose
check_commandCheck if a shell command is risky. Returns a full risk assessment.
suggest_alternativeGet safer alternative commands for a risky command.
get_policyGet the current shellfirm configuration and active policy.
explain_riskGet a detailed explanation of why a command is risky.

check_command

The primary tool. Send a command and receive a structured risk assessment.

Request:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "check_command",
    "arguments": {
      "command": "git push --force origin main"
    }
  }
}

Response (risky command):

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [{
      "type": "text",
      "text": "{\"allowed\":false,\"risk_level\":\"Normal\",\"severity\":\"High\",\"matched_rules\":[{\"id\":\"git:force_push\",\"description\":\"Force push can overwrite remote history.\",\"severity\":\"High\",\"group\":\"git\"}],\"alternatives\":[{\"command\":\"git push --force-with-lease\",\"explanation\":\"Prevents overwriting others' work\",\"source\":\"regex-pattern\"}],\"context\":{\"risk_level\":\"Normal\",\"labels\":[]},\"requires_human_approval\":false,\"denial_reason\":\"Severity HIGH meets or exceeds agent auto-deny threshold HIGH\"}"
    }]
  }
}

Response (safe command):

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "content": [{
      "type": "text",
      "text": "{\"allowed\":true,\"risk_level\":\"Normal\",\"severity\":null,\"matched_rules\":[],\"alternatives\":[],\"context\":{\"risk_level\":\"Normal\",\"labels\":[]},\"requires_human_approval\":false}"
    }]
  }
}

RiskAssessment fields

The check_command tool returns a RiskAssessment JSON object:

FieldTypeDescription
allowedbooleanWhether the command is safe to execute
risk_levelstringNormal, Elevated, or Critical
severitystring or nullHighest severity among matched rules (Info, Low, Medium, High, Critical)
matched_rulesarrayList of matched check patterns
alternativesarraySafer alternative commands
contextobjectRuntime context with risk_level and labels
requires_human_approvalbooleanWhether human approval is needed
denial_reasonstring or nullExplanation for why the command was denied
blast_radius_scopestring or nullScope of impact (RESOURCE, PROJECT, MACHINE)
blast_radius_detailstring or nullHuman-readable impact description

Each entry in matched_rules contains:

FieldTypeDescription
idstringPattern ID (e.g., git:force_push)
descriptionstringHuman-readable description of the risk
severitystringInfo, Low, Medium, High, or Critical
groupstringCheck group (e.g., git, fs, kubernetes)
blast_radius_scopestring or nullImpact scope for this specific match
blast_radius_detailstring or nullImpact detail for this specific match

suggest_alternative

Get safer alternatives for a risky command.

Request:

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "suggest_alternative",
    "arguments": {
      "command": "git push --force"
    }
  }
}

Response:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [{
      "type": "text",
      "text": "{\"command\":\"git push --force\",\"alternatives\":[{\"command\":\"git push --force-with-lease\",\"explanation\":\"Prevents overwriting others' work\",\"source\":\"regex-pattern\"}]}"
    }]
  }
}

get_policy

Retrieve the current shellfirm configuration and active policy.

Request:

{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {
    "name": "get_policy",
    "arguments": {}
  }
}

Response:

{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "content": [{
      "type": "text",
      "text": "{\"challenge\":\"Math\",\"active_groups\":[\"aws\",\"azure\",\"base\",\"database\",\"docker\",\"fs\",\"gcp\",\"git\",\"heroku\",\"kubernetes\",\"mongodb\",\"mysql\",\"network\",\"psql\",\"redis\",\"terraform\"],\"active_checks_count\":87,\"min_severity\":null,\"audit_enabled\":true,\"agent_config\":{\"auto_deny_severity\":\"High\",\"require_human_approval\":false},\"session_id\":\"abc-123\"}"
    }]
  }
}

explain_risk

Get a detailed explanation of why a command is risky.

Request:

{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "tools/call",
  "params": {
    "name": "explain_risk",
    "arguments": {
      "command": "rm -rf /"
    }
  }
}

Response:

{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "content": [{
      "type": "text",
      "text": "{\"command\":\"rm -rf /\",\"risky\":true,\"allowed\":false,\"severity\":\"Critical\",\"risk_level\":\"Normal\",\"context\":{\"risk_level\":\"Normal\",\"labels\":[]},\"matched_rules\":[{\"id\":\"fs:recursively_delete\",\"description\":\"Recursive delete can destroy files irreversibly\",\"severity\":\"High\",\"group\":\"fs\"}],\"alternatives\":[],\"explanation\":\"- [HIGH] fs:recursively_delete: Recursive delete can destroy files irreversibly\"}"
    }]
  }
}

Protocol details

The MCP server implements the following JSON-RPC 2.0 methods:

MethodTypeDescription
initializeRequestReturns server capabilities and version info
notifications/initializedNotificationClient acknowledgment (no response)
tools/listRequestReturns the list of available tools
tools/callRequestInvokes a tool by name with arguments

Protocol version: 2024-11-05

Error handling

Tool errors are returned as content with isError: true rather than as JSON-RPC errors. This follows the MCP convention:

{
  "jsonrpc": "2.0",
  "id": 6,
  "result": {
    "content": [{
      "type": "text",
      "text": "Error: Missing 'command' parameter"
    }],
    "isError": true
  }
}

JSON-RPC level errors (parse errors, unknown methods) use standard error codes:

  • -32700 -- Parse error (invalid JSON)
  • -32601 -- Method not found