{"record":{"id":"f506e185ccd4fb1f","repo":"screenpipe/screenpipe","slug":"tool-is-required","errorCode":null,"errorMessage":"tool is required","messagePattern":"tool is required","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/screenpipe-core/assets/acp/screenpipe-tools.mjs","lineNumber":963,"sourceCode":"    inputSchema: {\n      type: \"object\",\n      properties: {\n        server_id: { type: \"string\", description: \"The MCP server id (from sp_mcp_list_tools or list_connections).\" },\n        tool: { type: \"string\", description: \"The tool name advertised by that server.\" },\n        arguments: {\n          type: \"object\",\n          description: \"JSON arguments matching the tool's parameter schema.\",\n          additionalProperties: true,\n        },\n      },\n      required: [\"server_id\", \"tool\"],\n      additionalProperties: false,\n    },\n    async run(args) {\n      const serverId = String(args?.server_id ?? \"\").trim();\n      const tool = String(args?.tool ?? \"\").trim();\n      if (!serverId) throw new Error(\"server_id is required\");\n      if (!tool) throw new Error(\"tool is required\");\n      const res = await fetch(`${apiBase()}/mcp-servers/${encodeURIComponent(serverId)}/call`, {\n        method: \"POST\",\n        headers: mcpBridgeHeaders(),\n        body: JSON.stringify({ tool, arguments: args?.arguments ?? {} }),\n      });\n      const bodyText = await res.text();\n      if (!res.ok) {\n        throw new Error(`sp_mcp_call failed (${res.status}): ${bodyText.slice(0, 800)}`);\n      }\n      // The engine wraps the raw MCP result as { data: { content, isError? } }.\n      // Return the inner result so the agent sees content and any isError flag;\n      // if the tool itself errored (isError=true, HTTP still 200), surface it.\n      let parsed;\n      try {\n        parsed = JSON.parse(bodyText);\n      } catch {\n        return JSON.stringify({ content: [{ type: \"text\", text: bodyText.slice(0, 4000) }] });\n      }","sourceCodeStart":945,"sourceCodeEnd":981,"githubUrl":"https://github.com/screenpipe/screenpipe/blob/4ebf712990fee17eeaf904dacf749b6e96ac9bf3/crates/screenpipe-core/assets/acp/screenpipe-tools.mjs#L945-L981","documentation":"Same tool as errorIndex 58: after server_id validation, it requires a non-empty `tool` name identifying which MCP tool to invoke on that server. Empty/whitespace tool names throw this error before the POST to /mcp-servers/{id}/call.","triggerScenarios":"Calling with tool omitted, empty string, or whitespace-only; passing a description instead of the tool's callable name.","commonSituations":"Agents inventing tool names instead of reading sp_mcp_list_tools output; trailing-whitespace strings from copy/paste; templating bugs leaving the variable empty.","solutions":["Run sp_mcp_list_tools for the server_id and copy the exact tool name.","Trim the tool string before calling.","Put per-tool parameters under `arguments` (defaults to {}), not as top-level fields."],"exampleFix":"// before\nmcpCallTool({ server_id: \"composio-abc123\", tool: \"  \" })\n// after\nmcpCallTool({ server_id: \"composio-abc123\", tool: \"GMAIL_SEND_EMAIL\", arguments: { to: \"...\", subject: \"...\" } })","handlingStrategy":"validation","validationCode":"const tool = String(args?.tool ?? \"\").trim();\nif (!tool) throw new Error(\"pick a tool name from sp_mcp_list_tools output\");","typeGuard":"const hasTool = (a) => typeof a?.tool === \"string\" && a.tool.trim().length > 0;","tryCatchPattern":"try { await mcpCallTool(args) } catch (e) { if (e.message === \"tool is required\") { await sp_mcp_list_tools({ server_id: args.server_id }); /* pick tool, retry */ } else throw e }","preventionTips":["Copy tool names verbatim from sp_mcp_list_tools","Trim tool names","Pass per-tool parameters inside `arguments`"],"tags":["validation","missing-argument","mcp"],"backgroundTag":"missing-required-argument","analyzedSha":"4ebf712990fee17eeaf904dacf749b6e96ac9bf3","analyzedAt":"2026-09-01T23:33:43.065Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}