{"record":{"id":"2ed97fa749a42e0d","repo":"Mintplex-Labs/anything-llm","slug":"mcp-server-command-or-url-is-required","errorCode":null,"errorMessage":"MCP server command or url is required","messagePattern":"MCP server command or url is required","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/utils/MCP/hypervisor/index.js","lineNumber":452,"sourceCode":"        return new SSEClientTransport(url, {\n          requestInit: {\n            headers: server.headers,\n          },\n        });\n    }\n  }\n\n  /**\n   * @private Start a single MCP server by its server definition from the JSON file\n   * @param {string} name - The name of the MCP server to start\n   * @param {Object} server - The server definition\n   * @returns {Promise<boolean>}\n   */\n  async #startMCPServer({ name, server }) {\n    if (!name) throw new Error(\"MCP server name is required\");\n    if (!server) throw new Error(\"MCP server definition is required\");\n    const serverType = this.#parseServerType(server);\n    if (!serverType) throw new Error(\"MCP server command or url is required\");\n\n    this.#validateServerDefinitionByType(name, server, serverType);\n    this.log(`Attempting to start MCP server: ${name}`);\n    const mcp = new Client({ name: name, version: \"1.0.0\" });\n    const transport = await this.#setupServerTransport(server, serverType);\n\n    // Add connection event listeners\n    transport.onclose = () => this.log(`${name} - Transport closed`);\n    transport.onerror = (error) =>\n      this.log(`${name} - Transport error:`, error);\n    transport.onmessage = (message) =>\n      this.log(`${name} - Transport message:`, message);\n\n    // Connect and await the connection with a timeout\n    this.mcps[name] = mcp;\n    const connectionPromise = mcp.connect(transport);\n\n    let timeoutId;","sourceCodeStart":434,"sourceCodeEnd":470,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/server/utils/MCP/hypervisor/index.js#L434-L470","documentation":"Thrown when #parseServerType returns null, meaning the server definition has neither a recognized `type` (sse/streamable/http), nor a `command` property (stdio), nor a `url` property (http). The hypervisor cannot determine which transport to build, so it aborts before constructing a Client or transport. Each MCP server must declare either a stdio `command` or an HTTP `url`.","triggerScenarios":"An mcp_servers.json entry that is an empty object, or one that uses unrecognized keys (e.g. \"cmd\" instead of \"command\", \"endpoint\" instead of \"url\"). Also triggered if the entry exists but only has non-transport fields like env/headers.","commonSituations":"Following a tutorial that uses different key names; copying a config snippet that was truncated; migrating from an older config schema that renamed fields; leaving a stub entry while configuring.","solutions":["For a local/stdio server, add a \"command\" array, e.g. \"command\": [\"npx\", \"-y\", \"@modelcontextprotocol/server-filesystem\", \"/tmp\"].","For a remote server, add a \"url\" string and optionally \"type\": \"sse\" | \"streamable\" | \"http\".","Remove empty/stub entries from mcpServers entirely if the server is not yet configured.","Re-add the server through the AnythingLLM MCP UI so the schema is filled correctly."],"exampleFix":"// before\n\"my-server\": { \"env\": { \"FOO\": \"bar\" } }\n// after (stdio)\n\"my-server\": {\n  \"command\": [\"npx\", \"-y\", \"some-mcp-server\"],\n  \"env\": { \"FOO\": \"bar\" }\n}\n// after (http)\n\"my-server\": { \"url\": \"http://localhost:8080/sse\", \"type\": \"sse\" }","handlingStrategy":"validation","validationCode":"// Validate each definition declares a usable transport BEFORE booting.\nconst REQUIRED_ONE_OF = [\"command\", \"url\"];\nconst VALID_TYPES = [\"sse\", \"streamable\", \"http\"];\nfor (const { name, server } of hypervisor.mcpServerConfigs) {\n  const hasType = VALID_TYPES.includes(server?.type);\n  const hasTransport = REQUIRED_ONE_OF.some((k) =>\n    Object.prototype.hasOwnProperty.call(server || {}, k)\n  );\n  if (!hasType && !hasTransport) {\n    throw new Error(\n      `MCP server \"${name}\" needs either a \"command\" (stdio) or a \"url\"/\"type\" (http)`\n    );\n  }\n}","typeGuard":"function isStdioDef(s) {\n  return !!s && Array.isArray(s.command) && s.command.length > 0;\n}\nfunction isHttpDef(s) {\n  if (!s) return false;\n  if ([\"sse\", \"streamable\", \"http\"].includes(s.type)) return typeof s.url === \"string\";\n  return typeof s.url === \"string\" && s.url.length > 0;\n}\nfunction isValidServerDef(s) {\n  return isStdioDef(s) || isHttpDef(s);\n}","tryCatchPattern":"try {\n  await hypervisor.bootMCPServers();\n} catch (e) {\n  if (/command or url is required/i.test(e.message)) {\n    logger.error(\n      \"One or more MCP servers lack a command/url. Inspect mcp_servers.json.\"\n    );\n  }\n  throw e;\n}","preventionTips":["Add MCP servers through the UI which fills command/url correctly.","For stdio use \"command\": [\"npx\",\"-y\",\"pkg\"]; for HTTP use \"url\": \"http://...\".","Validate mcp_servers.json against a JSON schema on deploy."],"tags":["mcp","configuration","validation","transport"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}