ruvnet/ruflo · error

TOOL_DISABLED

TOOL_DISABLED

Error message

Tool "${name}" is disabled by default. Set MCP_ENABLE_TERMINAL=true to allow.

What it means

executeTool() matched the requested tool name against the terminal_execute deny-set (or /terminal_execute/i pattern) and MCP_ENABLE_TERMINAL is not 'true'. This is the ADR-166 hardening gate that blocks the previously unauthenticated-RCE path: shell-executing tools are denied unless the operator explicitly opts in via environment.

Source

Thrown at ruflo/src/mcp-bridge/index.js:796

// link that made the disclosed unauthenticated-RCE chain reach shell.
const DANGEROUS_TOOLS = Object.freeze(new Set([
  "terminal_execute",
  "ruflo__terminal_execute",
  "devtools__terminal_execute",
]));
function isTerminalTool(name) {
  return DANGEROUS_TOOLS.has(name) || /terminal_execute/i.test(name);
}
const MCP_ENABLE_TERMINAL = process.env.MCP_ENABLE_TERMINAL === "true";

async function executeTool(name, args) {
  // Deny dangerous tools unless the operator explicitly opted in.
  // Enforced on every path (not just autopilot) — root cause of ADR-166 V2/V3.
  if (isTerminalTool(name) && !MCP_ENABLE_TERMINAL) {
    return {
      error:
        `Tool "${name}" is disabled by default. Set MCP_ENABLE_TERMINAL=true to allow.`,
      code: "TOOL_DISABLED",
    };
  }
  // Validate that search-like tools have a non-empty query to prevent 400 errors
  if (!args || typeof args !== "object") args = {};
  const rawQuery = args.query ?? args.q ?? args.input ?? "";
  const queryStr = typeof rawQuery === "string" ? rawQuery.trim() : String(rawQuery || "").trim();
  const isSearchTool = name === "search" || name === "web_research" || /^(web_)?search/i.test(name);
  if (isSearchTool && !queryStr) {
    return { content: [{ type: "text", text: `No search query provided. Please specify a search query for '${name}'.` }] };
  }

  switch (name) {
    case "search":
      if (!CLOUD_FUNCTIONS.search) return { error: "search endpoint not configured" };
      return callCloudFunction(CLOUD_FUNCTIONS.search, { query: args.query, limit: args.limit || 5 });

    case "web_research": {
      const action = args.action || "search";

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Set MCP_ENABLE_TERMINAL=true in the environment to explicitly enable this tool.
  2. Use an alternative enabled tool, or confirm the security implications before enabling terminal access.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at ruflo/src/mcp-bridge/index.js:796 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/1c58613a4a1ec6ef. Report an issue: GitHub.