add_npx_mcp
Install npm-published MCP servers into obot by adding them as npx commands. Specify the package, display name, and optional environment variables.
Instructions
Install a new MCP server in obot that runs as npx <package> (stdio). Use this for npm-published MCP servers.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Display name shown in obot UI. | |
| package | Yes | npm package name, e.g. n8n-mcp or @scope/foo. | |
| shortDescription | No | ||
| env | No | Env vars passed to the MCP process. Keys go in manifest.env[]. Mark secrets via sensitiveKeys. | |
| sensitiveKeys | No | Keys in `env` that should be marked sensitive (API keys, tokens). | |
| alias | No | Optional short alias used in URLs/logs. |
Implementation Reference
- src/index.ts:169-203 (handler)The handler for the 'add_npx_mcp' tool. Constructs a manifest with runtime='npx' and npxConfig containing the package name, builds the env list from args and sensitiveKeys, optionally adds an alias, POSTs to /api/mcp-servers, and returns the created server's id, connectURL, configured state, missing env vars, and a hint.
case "add_npx_mcp": { const body: Record<string, any> = { manifest: { name: args.name, shortDescription: args.shortDescription ?? "", runtime: "npx", npxConfig: { package: args.package }, env: buildEnvList(args.env, args.sensitiveKeys), }, }; if (args.alias) body.alias = args.alias; const data = await obotFetch("/api/mcp-servers", { method: "POST", body: JSON.stringify(body), }); return { content: [ { type: "text", text: JSON.stringify( { id: data.id, connectURL: data.connectURL, configured: data.configured, missingRequiredEnvVars: data.missingRequiredEnvVars ?? [], hint: "Add the connectURL to claude.ai as a custom connector. If missingRequiredEnvVars is non-empty, set them via the obot UI or another tool call.", }, null, 2, ), }, ], }; } - src/index.ts:71-99 (schema)The tool definition / input schema for 'add_npx_mcp'. Declares the tool name, description, and JSON Schema with properties: name (required, string), package (required, string), shortDescription, env (object), sensitiveKeys (array of strings), and alias (string).
{ name: "add_npx_mcp", description: "Install a new MCP server in obot that runs as `npx <package>` (stdio). Use this for npm-published MCP servers.", inputSchema: { type: "object", properties: { name: { type: "string", description: "Display name shown in obot UI." }, package: { type: "string", description: "npm package name, e.g. n8n-mcp or @scope/foo." }, shortDescription: { type: "string" }, env: { type: "object", description: "Env vars passed to the MCP process. Keys go in manifest.env[]. Mark secrets via sensitiveKeys.", additionalProperties: { type: "string" }, }, sensitiveKeys: { type: "array", items: { type: "string" }, description: "Keys in `env` that should be marked sensitive (API keys, tokens).", }, alias: { type: "string", description: "Optional short alias used in URLs/logs.", }, }, required: ["name", "package"], additionalProperties: false, }, - src/index.ts:54-143 (registration)The tool is registered in the 'tools' array (lines 54-136) along with other tools. This array is returned by the ListToolsRequestSchema handler (line 143) and matched by name in the CallToolRequestSchema switch (line 169).
const tools: Tool[] = [ { name: "list_mcp_servers", description: "List MCP servers currently registered in obot. Returns id, name, runtime, configured-state, and the connectURL you'd hand to claude.ai.", inputSchema: { type: "object", properties: {}, additionalProperties: false }, }, { name: "get_mcp_server", description: "Get full details of one MCP server by id (including manifest, env, missingRequiredEnvVars).", inputSchema: { type: "object", properties: { id: { type: "string", description: "MCP server id, e.g. ms1mwrmr" } }, required: ["id"], additionalProperties: false, }, }, { name: "add_npx_mcp", description: "Install a new MCP server in obot that runs as `npx <package>` (stdio). Use this for npm-published MCP servers.", inputSchema: { type: "object", properties: { name: { type: "string", description: "Display name shown in obot UI." }, package: { type: "string", description: "npm package name, e.g. n8n-mcp or @scope/foo." }, shortDescription: { type: "string" }, env: { type: "object", description: "Env vars passed to the MCP process. Keys go in manifest.env[]. Mark secrets via sensitiveKeys.", additionalProperties: { type: "string" }, }, sensitiveKeys: { type: "array", items: { type: "string" }, description: "Keys in `env` that should be marked sensitive (API keys, tokens).", }, alias: { type: "string", description: "Optional short alias used in URLs/logs.", }, }, required: ["name", "package"], additionalProperties: false, }, }, { name: "add_remote_mcp", description: "Register a remote MCP server URL so obot proxies it. Use for HTTP/SSE MCPs hosted elsewhere.", inputSchema: { type: "object", properties: { name: { type: "string" }, url: { type: "string", description: "Remote MCP endpoint URL." }, shortDescription: { type: "string" }, alias: { type: "string" }, }, required: ["name", "url"], additionalProperties: false, }, }, { name: "delete_mcp_server", description: "Delete an MCP server from obot by id. Irreversible.", inputSchema: { type: "object", properties: { id: { type: "string" } }, required: ["id"], additionalProperties: false, }, }, { name: "list_catalog_entries", description: "List MCP catalog entries available in obot's default catalog. Optional substring filter on name/id.", inputSchema: { type: "object", properties: { search: { type: "string" } }, additionalProperties: false, }, }, ]; const server = new Server( { name: "obot-admin-mcp", version: "0.1.0" }, { capabilities: { tools: {} } }, ); server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools })); - src/index.ts:44-52 (helper)The buildEnvList helper used by the handler to transform env map and sensitiveKeys array into the manifest.env format.
function buildEnvList(env: EnvMap | undefined, sensitive: string[] | undefined) { const sens = new Set(sensitive ?? []); return Object.entries(env ?? {}).map(([key, value]) => ({ key, value: String(value), required: true, sensitive: sens.has(key), })); }