{"version":3,"sources":["/home/runner/work/fastmcp/fastmcp/dist/bin/fastmcp.cjs","../../src/bin/fastmcp.ts","../../src/bin/devCommand.ts"],"names":["yargs"],"mappings":"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","file":"/home/runner/work/fastmcp/fastmcp/dist/bin/fastmcp.cjs","sourcesContent":[null,"#!/usr/bin/env node\n\nimport { execa } from \"execa\";\nimport { mkdtemp, rm, writeFile } from \"fs/promises\";\nimport { tmpdir } from \"os\";\nimport { join } from \"path\";\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\n\nimport { buildDevCommand, buildDevConfig } from \"./devCommand.js\";\n\nawait yargs(hideBin(process.argv))\n  .scriptName(\"fastmcp\")\n  .command(\n    \"dev <file>\",\n    \"Start a development server\",\n    (yargs) => {\n      return yargs\n        .positional(\"file\", {\n          demandOption: true,\n          describe: \"The path to the server file\",\n          type: \"string\",\n        })\n\n        .option(\"args\", {\n          describe:\n            \"JSON arguments passed to the tool (requires --tool), e.g. '{\\\"a\\\":1}'\",\n          type: \"string\",\n        })\n\n        .option(\"tool\", {\n          alias: \"t\",\n          describe:\n            \"Call a tool non-interactively instead of launching the inspector\",\n          type: \"string\",\n        })\n\n        .option(\"watch\", {\n          alias: \"w\",\n          default: false,\n          describe: \"Watch for file changes and restart server\",\n          type: \"boolean\",\n        })\n\n        .option(\"verbose\", {\n          alias: \"v\",\n          default: false,\n          describe: \"Enable verbose logging\",\n          type: \"boolean\",\n        });\n    },\n\n    async (argv) => {\n      let configDir: string | undefined;\n\n      try {\n        if (argv.args !== undefined && !argv.tool) {\n          console.error(\"[FastMCP Error] --args requires --tool\");\n          process.exitCode = 1;\n          return;\n        }\n\n        if (argv.tool && argv.watch) {\n          console.warn(\n            \"[FastMCP] --watch is ignored when calling a tool with --tool: the server runs for a single call.\",\n          );\n        }\n\n        let configPath: string | undefined;\n\n        if (argv.tool) {\n          configDir = await mkdtemp(join(tmpdir(), \"fastmcp-dev-\"));\n          configPath = join(configDir, \"mcp-cli.json\");\n          await writeFile(configPath, buildDevConfig(argv.file), \"utf8\");\n        }\n\n        const [command, ...commandArgs] = buildDevCommand({\n          configPath,\n          file: argv.file,\n          tool: argv.tool,\n          toolArgs: argv.args,\n          watch: argv.watch,\n        });\n\n        if (argv.verbose) {\n          console.log(\n            `[FastMCP] Starting server: ${[command, ...commandArgs].join(\" \")}`,\n          );\n          console.log(`[FastMCP] File: ${argv.file}`);\n          console.log(\n            `[FastMCP] Watch mode: ${argv.watch ? \"enabled\" : \"disabled\"}`,\n          );\n\n          if (argv.tool) {\n            console.log(`[FastMCP] Tool: ${argv.tool}`);\n          }\n        }\n\n        await execa(command, commandArgs, {\n          stderr: \"inherit\",\n          stdin: \"inherit\",\n          stdout: \"inherit\",\n        });\n      } catch (error) {\n        console.error(\n          \"[FastMCP Error] Failed to start development server:\",\n          error instanceof Error ? error.message : String(error),\n        );\n\n        if (argv.verbose && error instanceof Error && error.stack) {\n          console.error(\"[FastMCP Debug] Stack trace:\", error.stack);\n        }\n\n        // Not process.exit(): that would skip the `finally` block below and\n        // leak the temporary config directory on every failed tool call.\n        process.exitCode = 1;\n      } finally {\n        if (configDir) {\n          await rm(configDir, { force: true, recursive: true });\n        }\n      }\n    },\n  )\n\n  .command(\n    \"inspect <file>\",\n    \"Inspect a server file\",\n    (yargs) => {\n      return yargs.positional(\"file\", {\n        demandOption: true,\n        describe: \"The path to the server file\",\n        type: \"string\",\n      });\n    },\n\n    async (argv) => {\n      try {\n        await execa({\n          stderr: \"inherit\",\n          stdout: \"inherit\",\n        })`npx @modelcontextprotocol/inspector npx tsx ${argv.file}`;\n      } catch (error) {\n        console.error(\n          \"[FastMCP Error] Failed to inspect server:\",\n          error instanceof Error ? error.message : String(error),\n        );\n\n        process.exit(1);\n      }\n    },\n  )\n\n  .command(\n    \"validate <file>\",\n    \"Validate a FastMCP server file for syntax and basic structure\",\n    (yargs) => {\n      return yargs\n        .positional(\"file\", {\n          demandOption: true,\n          describe: \"The path to the server file\",\n          type: \"string\",\n        })\n\n        .option(\"strict\", {\n          alias: \"s\",\n          default: false,\n          describe: \"Enable strict validation (type checking)\",\n          type: \"boolean\",\n        });\n    },\n\n    async (argv) => {\n      try {\n        const { existsSync } = await import(\"fs\");\n        const { resolve } = await import(\"path\");\n        const filePath = resolve(argv.file);\n\n        if (!existsSync(filePath)) {\n          console.error(`[FastMCP Error] File not found: ${filePath}`);\n          process.exit(1);\n        }\n\n        console.log(`[FastMCP] Validating server file: ${filePath}`);\n\n        const command = argv.strict\n          ? `npx tsc --noEmit --strict ${filePath}`\n          : `npx tsc --noEmit ${filePath}`;\n\n        try {\n          await execa({\n            shell: true,\n            stderr: \"pipe\",\n            stdout: \"pipe\",\n          })`${command}`;\n\n          console.log(\"[FastMCP] ✓ TypeScript compilation successful\");\n        } catch (tsError) {\n          console.error(\"[FastMCP] ✗ TypeScript compilation failed\");\n\n          if (tsError instanceof Error && \"stderr\" in tsError) {\n            console.error(tsError.stderr);\n          }\n\n          process.exit(1);\n        }\n\n        try {\n          await execa({\n            shell: true,\n            stderr: \"pipe\",\n            stdout: \"pipe\",\n          })`node -e \"\n            (async () => {\n              try {\n                const { FastMCP } = await import('fastmcp');\n                await import('file://${filePath}');\n                console.log('[FastMCP] ✓ Server structure validation passed');\n              } catch (error) {\n                console.error('[FastMCP] ✗ Server structure validation failed:', error.message);\n                process.exit(1);\n              }\n            })();\n          \"`;\n        } catch {\n          console.error(\"[FastMCP] ✗ Server structure validation failed\");\n          console.error(\"Make sure the file properly imports and uses FastMCP\");\n\n          process.exit(1);\n        }\n\n        console.log(\n          \"[FastMCP] ✓ All validations passed! Server file looks good.\",\n        );\n      } catch (error) {\n        console.error(\n          \"[FastMCP Error] Validation failed:\",\n          error instanceof Error ? error.message : String(error),\n        );\n\n        process.exit(1);\n      }\n    },\n  )\n\n  .help()\n  .parseAsync();\n","export type DevCommandOptions = {\n  /**\n   * Path to a temporary mcp-cli config file that registers the dev server.\n   * Only used in non-interactive mode (when `tool` is set).\n   */\n  configPath?: string;\n  /**\n   * Path to the server file to run.\n   */\n  file: string;\n  /**\n   * Name of the tool to call non-interactively. When omitted, the dev\n   * command launches the interactive mcp-cli inspector instead.\n   */\n  tool?: string;\n  /**\n   * JSON string of arguments forwarded to the tool via mcp-cli `--args`.\n   * Only used in non-interactive mode.\n   */\n  toolArgs?: string;\n  /**\n   * Watch the file for changes and restart the server. Only used in\n   * interactive mode; a non-interactive call runs the server once.\n   */\n  watch?: boolean;\n};\n\n/**\n * The server name registered in the generated mcp-cli config. mcp-cli\n * addresses non-interactive targets as `<server-name>:<tool>`.\n */\nexport const DEV_SERVER_NAME = \"dev\";\n\n/**\n * Build the JSON config that registers the dev server with mcp-cli so it can\n * be invoked non-interactively. mcp-cli's non-interactive mode resolves the\n * server by name from a config file's `mcpServers` map, so an inline command\n * cannot be passed directly alongside `call-tool`.\n *\n * The server is never started in watch mode here: a non-interactive call\n * connects, calls one tool, and exits, so there is nothing to restart into.\n */\nexport const buildDevConfig = (file: string): string =>\n  JSON.stringify(\n    {\n      mcpServers: {\n        [DEV_SERVER_NAME]: {\n          args: [\"tsx\", file],\n          command: \"npx\",\n        },\n      },\n    },\n    null,\n    2,\n  );\n\n/**\n * Build the argv that the dev command runs.\n *\n * This is an argv array rather than a shell string so that nothing has to be\n * quoted: file paths, tool names and JSON `--args` are passed to the child\n * process verbatim. Quoting through a shell would be wrong on Windows, where\n * cmd.exe treats single quotes as literal characters rather than as quoting.\n *\n * - Without `tool`: launches the interactive @wong2/mcp-cli inspector\n *   against an inline `npx tsx <file>` server (existing behaviour).\n * - With `tool`: runs @wong2/mcp-cli in non-interactive mode against a\n *   generated config file, calling the named tool and forwarding `--args`.\n */\nexport const buildDevCommand = (\n  options: DevCommandOptions,\n): [string, ...string[]] => {\n  const { configPath, file, tool, toolArgs, watch = false } = options;\n\n  if (tool) {\n    if (!configPath) {\n      throw new Error(\n        \"configPath is required when calling a tool non-interactively\",\n      );\n    }\n\n    return [\n      \"npx\",\n      \"@wong2/mcp-cli\",\n      \"-c\",\n      configPath,\n      \"call-tool\",\n      `${DEV_SERVER_NAME}:${tool}`,\n      ...(toolArgs === undefined ? [] : [\"--args\", toolArgs]),\n    ];\n  }\n\n  return [\n    \"npx\",\n    \"@wong2/mcp-cli\",\n    \"npx\",\n    \"tsx\",\n    ...(watch ? [\"--watch\"] : []),\n    file,\n  ];\n};\n"]}