@mcp-use/cli 3.1.0-canary.2 → 3.1.0-canary.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/index.cjs +581 -179
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +576 -174
- package/dist/index.js.map +1 -1
- package/dist/shims/next-shims-cjs.cjs +42 -0
- package/dist/shims/next-shims-loader.mjs +119 -0
- package/dist/shims/next-shims-noop.cjs +146 -0
- package/dist/shims/next-shims-register.mjs +14 -0
- package/dist/shims/next-shims-registry.json +11 -0
- package/dist/utils/next-shims.d.ts +77 -0
- package/dist/utils/next-shims.d.ts.map +1 -0
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -526,11 +526,11 @@ var source_default = chalk;
|
|
|
526
526
|
var import_commander6 = require("commander");
|
|
527
527
|
var import_config8 = require("dotenv/config");
|
|
528
528
|
var import_node_child_process9 = require("child_process");
|
|
529
|
-
var
|
|
529
|
+
var import_node_fs11 = require("fs");
|
|
530
530
|
var import_promises7 = require("fs/promises");
|
|
531
531
|
var import_node_module2 = require("module");
|
|
532
|
-
var
|
|
533
|
-
var
|
|
532
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
533
|
+
var import_node_url3 = require("url");
|
|
534
534
|
|
|
535
535
|
// ../../node_modules/.pnpm/open@11.0.0/node_modules/open/index.js
|
|
536
536
|
var import_node_process8 = __toESM(require("process"), 1);
|
|
@@ -716,15 +716,15 @@ var wslDefaultBrowser = async () => {
|
|
|
716
716
|
const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
|
|
717
717
|
return stdout.trim();
|
|
718
718
|
};
|
|
719
|
-
var convertWslPathToWindows = async (
|
|
720
|
-
if (/^[a-z]+:\/\//i.test(
|
|
721
|
-
return
|
|
719
|
+
var convertWslPathToWindows = async (path8) => {
|
|
720
|
+
if (/^[a-z]+:\/\//i.test(path8)) {
|
|
721
|
+
return path8;
|
|
722
722
|
}
|
|
723
723
|
try {
|
|
724
|
-
const { stdout } = await execFile2("wslpath", ["-aw",
|
|
724
|
+
const { stdout } = await execFile2("wslpath", ["-aw", path8], { encoding: "utf8" });
|
|
725
725
|
return stdout.trim();
|
|
726
726
|
} catch {
|
|
727
|
-
return
|
|
727
|
+
return path8;
|
|
728
728
|
}
|
|
729
729
|
};
|
|
730
730
|
|
|
@@ -1374,8 +1374,8 @@ var McpUseAPI = class _McpUseAPI {
|
|
|
1374
1374
|
return this.request(`/servers${q ? `?${q}` : ""}`);
|
|
1375
1375
|
}
|
|
1376
1376
|
async getServer(idOrSlug) {
|
|
1377
|
-
const
|
|
1378
|
-
return this.request(`/servers/${
|
|
1377
|
+
const path8 = encodeURIComponent(idOrSlug);
|
|
1378
|
+
return this.request(`/servers/${path8}`);
|
|
1379
1379
|
}
|
|
1380
1380
|
async deleteServer(id) {
|
|
1381
1381
|
await this.request(
|
|
@@ -3595,12 +3595,16 @@ async function deployCommand(options) {
|
|
|
3595
3595
|
}
|
|
3596
3596
|
let api = await McpUseAPI.create();
|
|
3597
3597
|
let resolvedOrgId;
|
|
3598
|
+
let resolvedOrgName;
|
|
3599
|
+
let resolvedOrgSlug;
|
|
3598
3600
|
if (options.org) {
|
|
3599
3601
|
const authInfo = await api.testAuth();
|
|
3600
3602
|
const match = resolveOrgFromOption(authInfo.orgs ?? [], options.org);
|
|
3601
3603
|
if (match) {
|
|
3602
3604
|
api.setOrgId(match.id);
|
|
3603
3605
|
resolvedOrgId = match.id;
|
|
3606
|
+
resolvedOrgName = match.name;
|
|
3607
|
+
resolvedOrgSlug = match.slug ?? void 0;
|
|
3604
3608
|
const slug = match.slug ? source_default.gray(` (${match.slug})`) : "";
|
|
3605
3609
|
console.log(
|
|
3606
3610
|
source_default.gray("Organization: ") + source_default.cyan(match.name) + slug
|
|
@@ -3640,6 +3644,8 @@ async function deployCommand(options) {
|
|
|
3640
3644
|
}
|
|
3641
3645
|
api.setOrgId(selectedOrg.id);
|
|
3642
3646
|
resolvedOrgId = selectedOrg.id;
|
|
3647
|
+
resolvedOrgName = selectedOrg.name;
|
|
3648
|
+
resolvedOrgSlug = selectedOrg.slug ?? void 0;
|
|
3643
3649
|
await writeConfig({
|
|
3644
3650
|
...config,
|
|
3645
3651
|
orgId: selectedOrg.id,
|
|
@@ -3651,6 +3657,8 @@ async function deployCommand(options) {
|
|
|
3651
3657
|
);
|
|
3652
3658
|
} else {
|
|
3653
3659
|
resolvedOrgId = config.orgId;
|
|
3660
|
+
resolvedOrgName = config.orgName;
|
|
3661
|
+
resolvedOrgSlug = config.orgSlug;
|
|
3654
3662
|
api.setOrgId(config.orgId);
|
|
3655
3663
|
if (config.orgName) {
|
|
3656
3664
|
const slug = config.orgSlug ? source_default.gray(` (${config.orgSlug})`) : "";
|
|
@@ -4047,6 +4055,22 @@ async function deployCommand(options) {
|
|
|
4047
4055
|
}
|
|
4048
4056
|
const existingLink = !options.new ? await getProjectLink(cwd) : null;
|
|
4049
4057
|
let serverId = existingLink?.serverId;
|
|
4058
|
+
if (serverId && resolvedOrgId) {
|
|
4059
|
+
try {
|
|
4060
|
+
const linkedServer = await api.getServer(serverId);
|
|
4061
|
+
if (linkedServer.organizationId !== resolvedOrgId) {
|
|
4062
|
+
const target = resolvedOrgName ? `${resolvedOrgName}${resolvedOrgSlug ? ` (${resolvedOrgSlug})` : ""}` : resolvedOrgId;
|
|
4063
|
+
console.log(
|
|
4064
|
+
source_default.yellow(
|
|
4065
|
+
`\u26A0\uFE0F Linked server belongs to a different organization. Creating a new server in ${target}...
|
|
4066
|
+
`
|
|
4067
|
+
)
|
|
4068
|
+
);
|
|
4069
|
+
serverId = void 0;
|
|
4070
|
+
}
|
|
4071
|
+
} catch {
|
|
4072
|
+
}
|
|
4073
|
+
}
|
|
4050
4074
|
if (existingLink && serverId) {
|
|
4051
4075
|
try {
|
|
4052
4076
|
const existingDep = await api.getDeployment(existingLink.deploymentId);
|
|
@@ -5250,7 +5274,7 @@ async function addSkillsToProject(projectPath) {
|
|
|
5250
5274
|
import_node_stream.Readable.fromWeb(response.body),
|
|
5251
5275
|
(0, import_tar.extract)({
|
|
5252
5276
|
cwd: tempDir,
|
|
5253
|
-
filter: (
|
|
5277
|
+
filter: (path8) => path8.includes("/skills/"),
|
|
5254
5278
|
strip: 1
|
|
5255
5279
|
})
|
|
5256
5280
|
);
|
|
@@ -5315,14 +5339,114 @@ function createSkillsCommand() {
|
|
|
5315
5339
|
return skills;
|
|
5316
5340
|
}
|
|
5317
5341
|
|
|
5318
|
-
// src/utils/
|
|
5342
|
+
// src/utils/next-shims.ts
|
|
5319
5343
|
var import_node_fs9 = require("fs");
|
|
5344
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
5345
|
+
var import_node_url2 = require("url");
|
|
5346
|
+
async function detectNextJsProject(projectPath) {
|
|
5347
|
+
try {
|
|
5348
|
+
const pkgPath = import_node_path7.default.join(projectPath, "package.json");
|
|
5349
|
+
const content = await import_node_fs9.promises.readFile(pkgPath, "utf-8");
|
|
5350
|
+
const pkg = JSON.parse(content);
|
|
5351
|
+
const deps = pkg.dependencies ?? {};
|
|
5352
|
+
const devDeps = pkg.devDependencies ?? {};
|
|
5353
|
+
return "next" in deps || "next" in devDeps;
|
|
5354
|
+
} catch {
|
|
5355
|
+
return false;
|
|
5356
|
+
}
|
|
5357
|
+
}
|
|
5358
|
+
async function loadNextJsEnvFiles(projectPath) {
|
|
5359
|
+
const files = [
|
|
5360
|
+
".env",
|
|
5361
|
+
".env.development",
|
|
5362
|
+
".env.local",
|
|
5363
|
+
".env.development.local"
|
|
5364
|
+
];
|
|
5365
|
+
const dotenv = await import("dotenv");
|
|
5366
|
+
for (const file of files) {
|
|
5367
|
+
const abs = import_node_path7.default.join(projectPath, file);
|
|
5368
|
+
try {
|
|
5369
|
+
await import_node_fs9.promises.access(abs);
|
|
5370
|
+
} catch {
|
|
5371
|
+
continue;
|
|
5372
|
+
}
|
|
5373
|
+
dotenv.config({ path: abs, override: true, quiet: true });
|
|
5374
|
+
}
|
|
5375
|
+
}
|
|
5376
|
+
function getThisDir() {
|
|
5377
|
+
if (typeof __dirname === "string") return __dirname;
|
|
5378
|
+
const url = importMetaUrl;
|
|
5379
|
+
return import_node_path7.default.dirname((0, import_node_url2.fileURLToPath)(url));
|
|
5380
|
+
}
|
|
5381
|
+
function resolveShimPath(filename) {
|
|
5382
|
+
const thisDir = getThisDir();
|
|
5383
|
+
const candidates = [
|
|
5384
|
+
// Production: `dist/` next to this module
|
|
5385
|
+
import_node_path7.default.join(thisDir, "shims", filename),
|
|
5386
|
+
// Test / dev: one level up (e.g., from `dist/utils/` back to `src/shims/`)
|
|
5387
|
+
import_node_path7.default.join(thisDir, "..", "shims", filename),
|
|
5388
|
+
import_node_path7.default.join(thisDir, "..", "..", "src", "shims", filename),
|
|
5389
|
+
import_node_path7.default.join(thisDir, "..", "src", "shims", filename)
|
|
5390
|
+
];
|
|
5391
|
+
for (const candidate of candidates) {
|
|
5392
|
+
if ((0, import_node_fs9.existsSync)(candidate)) return candidate;
|
|
5393
|
+
}
|
|
5394
|
+
return void 0;
|
|
5395
|
+
}
|
|
5396
|
+
function getShimRegisterPath() {
|
|
5397
|
+
return resolveShimPath("next-shims-register.mjs");
|
|
5398
|
+
}
|
|
5399
|
+
function getShimLoaderPath() {
|
|
5400
|
+
return resolveShimPath("next-shims-loader.mjs");
|
|
5401
|
+
}
|
|
5402
|
+
function getShimCjsPreloadPath() {
|
|
5403
|
+
return resolveShimPath("next-shims-cjs.cjs");
|
|
5404
|
+
}
|
|
5405
|
+
async function registerNextShimsInProcess() {
|
|
5406
|
+
let anyRegistered = false;
|
|
5407
|
+
const cjsPath = getShimCjsPreloadPath();
|
|
5408
|
+
if (cjsPath) {
|
|
5409
|
+
const { createRequire: createRequire3 } = await import("module");
|
|
5410
|
+
const req = createRequire3((0, import_node_url2.pathToFileURL)(getThisDir() + import_node_path7.default.sep).href);
|
|
5411
|
+
req(cjsPath);
|
|
5412
|
+
anyRegistered = true;
|
|
5413
|
+
}
|
|
5414
|
+
const loaderPath = getShimLoaderPath();
|
|
5415
|
+
if (loaderPath) {
|
|
5416
|
+
const { register } = await import("module");
|
|
5417
|
+
const loaderUrl = (0, import_node_url2.pathToFileURL)(loaderPath).href;
|
|
5418
|
+
register(loaderUrl, (0, import_node_url2.pathToFileURL)(getThisDir() + import_node_path7.default.sep).href);
|
|
5419
|
+
anyRegistered = true;
|
|
5420
|
+
}
|
|
5421
|
+
return anyRegistered;
|
|
5422
|
+
}
|
|
5423
|
+
function withNextShimsEnv(baseEnv) {
|
|
5424
|
+
const additions = [];
|
|
5425
|
+
const cjsPath = getShimCjsPreloadPath();
|
|
5426
|
+
if (cjsPath) additions.push(`-r ${quoteNodeOption(cjsPath)}`);
|
|
5427
|
+
const registerPath = getShimRegisterPath();
|
|
5428
|
+
if (registerPath)
|
|
5429
|
+
additions.push(`--import=${(0, import_node_url2.pathToFileURL)(registerPath).href}`);
|
|
5430
|
+
if (additions.length === 0) return baseEnv;
|
|
5431
|
+
const existing = baseEnv.NODE_OPTIONS ?? "";
|
|
5432
|
+
const prepended = additions.join(" ");
|
|
5433
|
+
return {
|
|
5434
|
+
...baseEnv,
|
|
5435
|
+
NODE_OPTIONS: existing ? `${prepended} ${existing}` : prepended
|
|
5436
|
+
};
|
|
5437
|
+
}
|
|
5438
|
+
function quoteNodeOption(value) {
|
|
5439
|
+
return /\s/.test(value) ? `"${value}"` : value;
|
|
5440
|
+
}
|
|
5441
|
+
|
|
5442
|
+
// src/utils/update-check.ts
|
|
5443
|
+
var import_node_fs10 = require("fs");
|
|
5320
5444
|
var import_promises6 = require("fs/promises");
|
|
5321
5445
|
var import_node_module = require("module");
|
|
5322
5446
|
var import_node_os6 = __toESM(require("os"), 1);
|
|
5323
|
-
var
|
|
5324
|
-
var CACHE_DIR =
|
|
5325
|
-
var CACHE_FILE =
|
|
5447
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
5448
|
+
var CACHE_DIR = import_node_path8.default.join(import_node_os6.default.homedir(), ".mcp-use");
|
|
5449
|
+
var CACHE_FILE = import_node_path8.default.join(CACHE_DIR, "update-check.json");
|
|
5326
5450
|
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
5327
5451
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
5328
5452
|
var PACKAGE_NAME = "mcp-use";
|
|
@@ -5405,16 +5529,16 @@ function resolveInstalledVersion(projectPath) {
|
|
|
5405
5529
|
if (projectPath) {
|
|
5406
5530
|
attempts.push(() => {
|
|
5407
5531
|
const projectRequire = (0, import_node_module.createRequire)(
|
|
5408
|
-
|
|
5532
|
+
import_node_path8.default.join(projectPath, "package.json")
|
|
5409
5533
|
);
|
|
5410
5534
|
return projectRequire.resolve(`${PACKAGE_NAME}/package.json`);
|
|
5411
5535
|
});
|
|
5412
5536
|
}
|
|
5413
|
-
attempts.push(() =>
|
|
5537
|
+
attempts.push(() => import_node_path8.default.join(__dirname, "../../mcp-use/package.json"));
|
|
5414
5538
|
for (const attempt of attempts) {
|
|
5415
5539
|
try {
|
|
5416
5540
|
const pkgPath = attempt();
|
|
5417
|
-
const json = JSON.parse((0,
|
|
5541
|
+
const json = JSON.parse((0, import_node_fs10.readFileSync)(pkgPath, "utf-8"));
|
|
5418
5542
|
if (typeof json.version === "string") return json.version;
|
|
5419
5543
|
} catch {
|
|
5420
5544
|
}
|
|
@@ -5447,8 +5571,8 @@ A new release of ${source_default.bold(PACKAGE_NAME)} is available: ${source_def
|
|
|
5447
5571
|
|
|
5448
5572
|
// src/index.ts
|
|
5449
5573
|
var program = new import_commander6.Command();
|
|
5450
|
-
var packageContent = (0,
|
|
5451
|
-
|
|
5574
|
+
var packageContent = (0, import_node_fs11.readFileSync)(
|
|
5575
|
+
import_node_path9.default.join(__dirname, "../package.json"),
|
|
5452
5576
|
"utf-8"
|
|
5453
5577
|
);
|
|
5454
5578
|
var packageJson = JSON.parse(packageContent);
|
|
@@ -5479,16 +5603,16 @@ function displayPackageVersions(projectPath) {
|
|
|
5479
5603
|
if (projectPath) {
|
|
5480
5604
|
try {
|
|
5481
5605
|
const projectRequire = (0, import_node_module2.createRequire)(
|
|
5482
|
-
|
|
5606
|
+
import_node_path9.default.join(projectPath, "package.json")
|
|
5483
5607
|
);
|
|
5484
5608
|
pkgPath = projectRequire.resolve(`${pkg.name}/package.json`);
|
|
5485
5609
|
} catch (resolveError) {
|
|
5486
|
-
pkgPath =
|
|
5610
|
+
pkgPath = import_node_path9.default.join(__dirname, pkg.relativePath);
|
|
5487
5611
|
}
|
|
5488
5612
|
} else {
|
|
5489
|
-
pkgPath =
|
|
5613
|
+
pkgPath = import_node_path9.default.join(__dirname, pkg.relativePath);
|
|
5490
5614
|
}
|
|
5491
|
-
const pkgContent = (0,
|
|
5615
|
+
const pkgContent = (0, import_node_fs11.readFileSync)(pkgPath, "utf-8");
|
|
5492
5616
|
const pkgJson = JSON.parse(pkgContent);
|
|
5493
5617
|
const version = pkgJson.version || "unknown";
|
|
5494
5618
|
if (pkg.highlight) {
|
|
@@ -5638,20 +5762,92 @@ async function startTunnel(port, subdomain) {
|
|
|
5638
5762
|
}, 3e4);
|
|
5639
5763
|
});
|
|
5640
5764
|
}
|
|
5641
|
-
async function
|
|
5765
|
+
async function resolveEntryFile(projectPath, cliEntry, mcpDir) {
|
|
5766
|
+
if (cliEntry) {
|
|
5767
|
+
await (0, import_promises7.access)(import_node_path9.default.join(projectPath, cliEntry)).catch(() => {
|
|
5768
|
+
throw new Error(`File not found: ${cliEntry}`);
|
|
5769
|
+
});
|
|
5770
|
+
return cliEntry;
|
|
5771
|
+
}
|
|
5772
|
+
if (mcpDir) {
|
|
5773
|
+
const mcpCandidates = [
|
|
5774
|
+
import_node_path9.default.join(mcpDir, "index.ts"),
|
|
5775
|
+
import_node_path9.default.join(mcpDir, "index.tsx"),
|
|
5776
|
+
import_node_path9.default.join(mcpDir, "server.ts"),
|
|
5777
|
+
import_node_path9.default.join(mcpDir, "server.tsx")
|
|
5778
|
+
];
|
|
5779
|
+
for (const candidate of mcpCandidates) {
|
|
5780
|
+
try {
|
|
5781
|
+
await (0, import_promises7.access)(import_node_path9.default.join(projectPath, candidate));
|
|
5782
|
+
return candidate;
|
|
5783
|
+
} catch {
|
|
5784
|
+
continue;
|
|
5785
|
+
}
|
|
5786
|
+
}
|
|
5787
|
+
throw new Error(
|
|
5788
|
+
`No entry file found inside ${mcpDir}.
|
|
5789
|
+
|
|
5790
|
+
Expected one of: ${mcpCandidates.map((c) => import_node_path9.default.relative(projectPath, import_node_path9.default.join(projectPath, c))).join(", ")}
|
|
5791
|
+
|
|
5792
|
+
Fix this by either:
|
|
5793
|
+
1. Creating ${import_node_path9.default.join(mcpDir, "index.ts")}, or
|
|
5794
|
+
2. Passing --entry <file> on the command line`
|
|
5795
|
+
);
|
|
5796
|
+
}
|
|
5642
5797
|
const candidates = ["index.ts", "src/index.ts", "server.ts", "src/server.ts"];
|
|
5643
5798
|
for (const candidate of candidates) {
|
|
5644
5799
|
try {
|
|
5645
|
-
await (0, import_promises7.access)(
|
|
5800
|
+
await (0, import_promises7.access)(import_node_path9.default.join(projectPath, candidate));
|
|
5646
5801
|
return candidate;
|
|
5647
5802
|
} catch {
|
|
5648
5803
|
continue;
|
|
5649
5804
|
}
|
|
5650
5805
|
}
|
|
5651
|
-
throw new Error(
|
|
5806
|
+
throw new Error(
|
|
5807
|
+
`No entry file found.
|
|
5808
|
+
|
|
5809
|
+
Expected one of: ${candidates.join(", ")}
|
|
5810
|
+
|
|
5811
|
+
Fix this by either:
|
|
5812
|
+
1. Creating one of the default entry files above, or
|
|
5813
|
+
2. Passing --entry <file> or --mcp-dir <dir> on the command line`
|
|
5814
|
+
);
|
|
5815
|
+
}
|
|
5816
|
+
function resolveWidgetsDir(cliWidgetsDir, mcpDir) {
|
|
5817
|
+
if (cliWidgetsDir) return cliWidgetsDir;
|
|
5818
|
+
if (mcpDir) return import_node_path9.default.join(mcpDir, "resources");
|
|
5819
|
+
return "resources";
|
|
5820
|
+
}
|
|
5821
|
+
function makeWidgetServerOnlyGuard(widgetName) {
|
|
5822
|
+
const rejected = /* @__PURE__ */ new Set([
|
|
5823
|
+
"server-only",
|
|
5824
|
+
"client-only",
|
|
5825
|
+
"next/cache",
|
|
5826
|
+
"next/headers",
|
|
5827
|
+
"next/navigation",
|
|
5828
|
+
"next/server"
|
|
5829
|
+
]);
|
|
5830
|
+
return {
|
|
5831
|
+
name: "mcp-use-widget-server-only-guard",
|
|
5832
|
+
enforce: "pre",
|
|
5833
|
+
resolveId(id, importer) {
|
|
5834
|
+
if (!rejected.has(id)) return null;
|
|
5835
|
+
const from = importer ? ` (imported from ${importer})` : "";
|
|
5836
|
+
throw new Error(
|
|
5837
|
+
`Widget "${widgetName}" imports "${id}"${from}, which is a Next.js server-only module. Widgets run in a browser iframe and cannot use server APIs.
|
|
5838
|
+
|
|
5839
|
+
To fix:
|
|
5840
|
+
\u2022 Remove the import from the widget (or from any module the widget transitively imports)
|
|
5841
|
+
\u2022 If the widget needs data from ${id}, read it inside an MCP tool in your server and pass the result through the widget's props`
|
|
5842
|
+
);
|
|
5843
|
+
}
|
|
5844
|
+
};
|
|
5845
|
+
}
|
|
5846
|
+
async function findServerFile(projectPath, cliEntry, cliMcpDir) {
|
|
5847
|
+
return resolveEntryFile(projectPath, cliEntry, cliMcpDir);
|
|
5652
5848
|
}
|
|
5653
5849
|
async function generateToolRegistryTypesForServer(projectPath, serverFileRelative) {
|
|
5654
|
-
const serverFile =
|
|
5850
|
+
const serverFile = import_node_path9.default.join(projectPath, serverFileRelative);
|
|
5655
5851
|
const serverFileExists = await (0, import_promises7.access)(serverFile).then(() => true).catch(() => false);
|
|
5656
5852
|
if (!serverFileExists) {
|
|
5657
5853
|
throw new Error(`Server file not found: ${serverFile}`);
|
|
@@ -5660,19 +5856,48 @@ async function generateToolRegistryTypesForServer(projectPath, serverFileRelativ
|
|
|
5660
5856
|
try {
|
|
5661
5857
|
globalThis.__mcpUseHmrMode = true;
|
|
5662
5858
|
globalThis.__mcpUseLastServer = void 0;
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
5859
|
+
if (await detectNextJsProject(projectPath)) {
|
|
5860
|
+
await loadNextJsEnvFiles(projectPath);
|
|
5861
|
+
await registerNextShimsInProcess();
|
|
5862
|
+
}
|
|
5863
|
+
const projectTsconfigPath = import_node_path9.default.join(projectPath, "tsconfig.json");
|
|
5864
|
+
const hasTsconfig = await (0, import_promises7.access)(projectTsconfigPath).then(() => true).catch(() => false);
|
|
5865
|
+
if (hasTsconfig) {
|
|
5866
|
+
process.env.TSX_TSCONFIG_PATH = projectTsconfigPath;
|
|
5867
|
+
}
|
|
5868
|
+
const previousCwd = process.cwd();
|
|
5869
|
+
if (previousCwd !== projectPath) process.chdir(projectPath);
|
|
5870
|
+
try {
|
|
5871
|
+
const projectRequire = (0, import_node_module2.createRequire)(
|
|
5872
|
+
import_node_path9.default.join(projectPath, "package.json")
|
|
5873
|
+
);
|
|
5874
|
+
const tsxEsmApiPath = projectRequire.resolve("tsx/esm/api");
|
|
5875
|
+
const tsxEsmApi = await import((0, import_node_url3.pathToFileURL)(tsxEsmApiPath).href);
|
|
5876
|
+
if (typeof tsxEsmApi.register === "function") {
|
|
5877
|
+
tsxEsmApi.register({
|
|
5878
|
+
tsconfig: hasTsconfig ? projectTsconfigPath : void 0
|
|
5879
|
+
});
|
|
5880
|
+
}
|
|
5881
|
+
try {
|
|
5882
|
+
const tsxCjsApiPath = projectRequire.resolve("tsx/cjs/api");
|
|
5883
|
+
const tsxCjsApi = await import((0, import_node_url3.pathToFileURL)(tsxCjsApiPath).href);
|
|
5884
|
+
if (typeof tsxCjsApi.register === "function") {
|
|
5885
|
+
tsxCjsApi.register();
|
|
5886
|
+
}
|
|
5887
|
+
} catch {
|
|
5888
|
+
}
|
|
5889
|
+
await import(`${(0, import_node_url3.pathToFileURL)(serverFile).href}?t=${Date.now()}`);
|
|
5890
|
+
} finally {
|
|
5891
|
+
if (process.cwd() !== previousCwd) process.chdir(previousCwd);
|
|
5892
|
+
}
|
|
5668
5893
|
const server = globalThis.__mcpUseLastServer;
|
|
5669
5894
|
if (!server) {
|
|
5670
5895
|
throw new Error(
|
|
5671
5896
|
"No MCPServer instance found. Make sure your server file creates an MCPServer instance."
|
|
5672
5897
|
);
|
|
5673
5898
|
}
|
|
5674
|
-
const mcpUsePath =
|
|
5675
|
-
const { generateToolRegistryTypes } = await import((0,
|
|
5899
|
+
const mcpUsePath = import_node_path9.default.join(projectPath, "node_modules", "mcp-use");
|
|
5900
|
+
const { generateToolRegistryTypes } = await import((0, import_node_url3.pathToFileURL)(import_node_path9.default.join(mcpUsePath, "dist", "src", "server", "index.js")).href).then((mod) => mod);
|
|
5676
5901
|
if (!generateToolRegistryTypes) {
|
|
5677
5902
|
throw new Error("generateToolRegistryTypes not found in mcp-use package");
|
|
5678
5903
|
}
|
|
@@ -5687,21 +5912,24 @@ async function generateToolRegistryTypesForServer(projectPath, serverFileRelativ
|
|
|
5687
5912
|
}
|
|
5688
5913
|
async function buildWidgets(projectPath, options = {}) {
|
|
5689
5914
|
const { inline = true } = options;
|
|
5690
|
-
const { promises:
|
|
5915
|
+
const { promises: fs11 } = await import("fs");
|
|
5691
5916
|
const { build } = await import("vite");
|
|
5692
|
-
const
|
|
5917
|
+
const widgetsDirRelative = options.widgetsDir ?? "resources";
|
|
5918
|
+
const resourcesDir = import_node_path9.default.resolve(projectPath, widgetsDirRelative);
|
|
5693
5919
|
const mcpUrl = process.env.MCP_URL;
|
|
5694
5920
|
try {
|
|
5695
5921
|
await (0, import_promises7.access)(resourcesDir);
|
|
5696
5922
|
} catch {
|
|
5697
5923
|
console.log(
|
|
5698
|
-
source_default.gray(
|
|
5924
|
+
source_default.gray(
|
|
5925
|
+
`No ${widgetsDirRelative}/ directory found - skipping widget build`
|
|
5926
|
+
)
|
|
5699
5927
|
);
|
|
5700
5928
|
return [];
|
|
5701
5929
|
}
|
|
5702
5930
|
const entries = [];
|
|
5703
5931
|
try {
|
|
5704
|
-
const files = await
|
|
5932
|
+
const files = await fs11.readdir(resourcesDir, { withFileTypes: true });
|
|
5705
5933
|
for (const dirent of files) {
|
|
5706
5934
|
if (dirent.name.startsWith("._") || dirent.name.startsWith(".DS_Store")) {
|
|
5707
5935
|
continue;
|
|
@@ -5709,12 +5937,12 @@ async function buildWidgets(projectPath, options = {}) {
|
|
|
5709
5937
|
if (dirent.isFile() && (dirent.name.endsWith(".tsx") || dirent.name.endsWith(".ts"))) {
|
|
5710
5938
|
entries.push({
|
|
5711
5939
|
name: dirent.name.replace(/\.tsx?$/, ""),
|
|
5712
|
-
path:
|
|
5940
|
+
path: import_node_path9.default.join(resourcesDir, dirent.name)
|
|
5713
5941
|
});
|
|
5714
5942
|
} else if (dirent.isDirectory()) {
|
|
5715
|
-
const widgetPath =
|
|
5943
|
+
const widgetPath = import_node_path9.default.join(resourcesDir, dirent.name, "widget.tsx");
|
|
5716
5944
|
try {
|
|
5717
|
-
await
|
|
5945
|
+
await fs11.access(widgetPath);
|
|
5718
5946
|
entries.push({
|
|
5719
5947
|
name: dirent.name,
|
|
5720
5948
|
path: widgetPath
|
|
@@ -5724,11 +5952,15 @@ async function buildWidgets(projectPath, options = {}) {
|
|
|
5724
5952
|
}
|
|
5725
5953
|
}
|
|
5726
5954
|
} catch (error) {
|
|
5727
|
-
console.log(
|
|
5955
|
+
console.log(
|
|
5956
|
+
source_default.gray(`No widgets found in ${widgetsDirRelative}/ directory`)
|
|
5957
|
+
);
|
|
5728
5958
|
return [];
|
|
5729
5959
|
}
|
|
5730
5960
|
if (entries.length === 0) {
|
|
5731
|
-
console.log(
|
|
5961
|
+
console.log(
|
|
5962
|
+
source_default.gray(`No widgets found in ${widgetsDirRelative}/ directory`)
|
|
5963
|
+
);
|
|
5732
5964
|
return [];
|
|
5733
5965
|
}
|
|
5734
5966
|
console.log(
|
|
@@ -5738,10 +5970,17 @@ async function buildWidgets(projectPath, options = {}) {
|
|
|
5738
5970
|
);
|
|
5739
5971
|
const react = (await import("@vitejs/plugin-react")).default;
|
|
5740
5972
|
const tailwindcss = (await import("@tailwindcss/vite")).default;
|
|
5741
|
-
const
|
|
5973
|
+
const projectTsconfigPath = import_node_path9.default.join(projectPath, "tsconfig.json");
|
|
5974
|
+
let hasProjectTsconfig = false;
|
|
5975
|
+
try {
|
|
5976
|
+
await (0, import_promises7.access)(projectTsconfigPath);
|
|
5977
|
+
hasProjectTsconfig = true;
|
|
5978
|
+
} catch {
|
|
5979
|
+
}
|
|
5980
|
+
const packageJsonPath = import_node_path9.default.join(projectPath, "package.json");
|
|
5742
5981
|
let favicon = "";
|
|
5743
5982
|
try {
|
|
5744
|
-
const pkgContent = await
|
|
5983
|
+
const pkgContent = await fs11.readFile(packageJsonPath, "utf-8");
|
|
5745
5984
|
const pkg = JSON.parse(pkgContent);
|
|
5746
5985
|
favicon = pkg.mcpUse?.favicon || "";
|
|
5747
5986
|
} catch {
|
|
@@ -5750,18 +5989,27 @@ async function buildWidgets(projectPath, options = {}) {
|
|
|
5750
5989
|
const widgetName = entry.name;
|
|
5751
5990
|
const entryPath = entry.path.replace(/\\/g, "/");
|
|
5752
5991
|
console.log(source_default.gray(` - Building ${widgetName}...`));
|
|
5753
|
-
const tempDir =
|
|
5754
|
-
await
|
|
5755
|
-
const relativeResourcesPath =
|
|
5756
|
-
const mcpUsePath =
|
|
5757
|
-
const relativeMcpUsePath =
|
|
5992
|
+
const tempDir = import_node_path9.default.join(projectPath, ".mcp-use", widgetName);
|
|
5993
|
+
await fs11.mkdir(tempDir, { recursive: true });
|
|
5994
|
+
const relativeResourcesPath = import_node_path9.default.relative(tempDir, resourcesDir).replace(/\\/g, "/");
|
|
5995
|
+
const mcpUsePath = import_node_path9.default.join(projectPath, "node_modules", "mcp-use");
|
|
5996
|
+
const relativeMcpUsePath = import_node_path9.default.relative(tempDir, mcpUsePath).replace(/\\/g, "/");
|
|
5997
|
+
const projectSrcDir = import_node_path9.default.join(projectPath, "src");
|
|
5998
|
+
let projectSrcSourceLine = "";
|
|
5999
|
+
try {
|
|
6000
|
+
await (0, import_promises7.access)(projectSrcDir);
|
|
6001
|
+
const relativeProjectSrcPath = import_node_path9.default.relative(tempDir, projectSrcDir).replace(/\\/g, "/");
|
|
6002
|
+
projectSrcSourceLine = `@source "${relativeProjectSrcPath}";
|
|
6003
|
+
`;
|
|
6004
|
+
} catch {
|
|
6005
|
+
}
|
|
5758
6006
|
const cssContent = `@import "tailwindcss";
|
|
5759
6007
|
|
|
5760
6008
|
/* Configure Tailwind to scan the resources directory and mcp-use package */
|
|
5761
6009
|
@source "${relativeResourcesPath}";
|
|
5762
6010
|
@source "${relativeMcpUsePath}/**/*.{ts,tsx,js,jsx}";
|
|
5763
|
-
`;
|
|
5764
|
-
await
|
|
6011
|
+
${projectSrcSourceLine}`;
|
|
6012
|
+
await fs11.writeFile(import_node_path9.default.join(tempDir, "styles.css"), cssContent, "utf8");
|
|
5765
6013
|
const entryContent = `import React from 'react'
|
|
5766
6014
|
import { createRoot } from 'react-dom/client'
|
|
5767
6015
|
import './styles.css'
|
|
@@ -5786,9 +6034,9 @@ if (container && Component) {
|
|
|
5786
6034
|
<script type="module" src="/entry.tsx"></script>
|
|
5787
6035
|
</body>
|
|
5788
6036
|
</html>`;
|
|
5789
|
-
await
|
|
5790
|
-
await
|
|
5791
|
-
const outDir =
|
|
6037
|
+
await fs11.writeFile(import_node_path9.default.join(tempDir, "entry.tsx"), entryContent, "utf8");
|
|
6038
|
+
await fs11.writeFile(import_node_path9.default.join(tempDir, "index.html"), htmlContent, "utf8");
|
|
6039
|
+
const outDir = import_node_path9.default.join(
|
|
5792
6040
|
projectPath,
|
|
5793
6041
|
"dist",
|
|
5794
6042
|
"resources",
|
|
@@ -5798,12 +6046,12 @@ if (container && Component) {
|
|
|
5798
6046
|
const baseUrl = mcpUrl ? `${mcpUrl}/${widgetName}/` : `/mcp-use/widgets/${widgetName}/`;
|
|
5799
6047
|
let widgetMetadata = {};
|
|
5800
6048
|
try {
|
|
5801
|
-
const metadataTempDir =
|
|
6049
|
+
const metadataTempDir = import_node_path9.default.join(
|
|
5802
6050
|
projectPath,
|
|
5803
6051
|
".mcp-use",
|
|
5804
6052
|
`${widgetName}-metadata`
|
|
5805
6053
|
);
|
|
5806
|
-
await
|
|
6054
|
+
await fs11.mkdir(metadataTempDir, { recursive: true });
|
|
5807
6055
|
const { createServer } = await import("vite");
|
|
5808
6056
|
const nodeStubsPlugin = {
|
|
5809
6057
|
name: "node-stubs",
|
|
@@ -5831,15 +6079,16 @@ export default PostHog;
|
|
|
5831
6079
|
return null;
|
|
5832
6080
|
}
|
|
5833
6081
|
};
|
|
6082
|
+
const serverOnlyGuard = makeWidgetServerOnlyGuard(widgetName);
|
|
5834
6083
|
const metadataServer = await createServer({
|
|
5835
6084
|
root: metadataTempDir,
|
|
5836
|
-
cacheDir:
|
|
5837
|
-
plugins: [nodeStubsPlugin, tailwindcss(), react()],
|
|
5838
|
-
|
|
5839
|
-
|
|
5840
|
-
|
|
5841
|
-
|
|
5842
|
-
},
|
|
6085
|
+
cacheDir: import_node_path9.default.join(metadataTempDir, ".vite-cache"),
|
|
6086
|
+
plugins: [serverOnlyGuard, nodeStubsPlugin, tailwindcss(), react()],
|
|
6087
|
+
// When the project has a tsconfig, enable Vite's native tsconfig-paths
|
|
6088
|
+
// resolver so `@/*` (or any custom alias) resolves through the
|
|
6089
|
+
// project's own paths config. Without a tsconfig, fall back to the
|
|
6090
|
+
// legacy hardcoded alias.
|
|
6091
|
+
resolve: hasProjectTsconfig ? { tsconfigPaths: true } : { alias: { "@": resourcesDir } },
|
|
5843
6092
|
server: {
|
|
5844
6093
|
middlewareMode: true
|
|
5845
6094
|
},
|
|
@@ -5918,7 +6167,7 @@ export default PostHog;
|
|
|
5918
6167
|
} finally {
|
|
5919
6168
|
await metadataServer.close();
|
|
5920
6169
|
try {
|
|
5921
|
-
await
|
|
6170
|
+
await fs11.rm(metadataTempDir, { recursive: true, force: true });
|
|
5922
6171
|
} catch {
|
|
5923
6172
|
}
|
|
5924
6173
|
}
|
|
@@ -6013,12 +6262,14 @@ export default {
|
|
|
6013
6262
|
return null;
|
|
6014
6263
|
}
|
|
6015
6264
|
};
|
|
6265
|
+
const buildServerOnlyGuard = makeWidgetServerOnlyGuard(widgetName);
|
|
6016
6266
|
const buildPlugins = inline ? [
|
|
6267
|
+
buildServerOnlyGuard,
|
|
6017
6268
|
buildNodeStubsPlugin,
|
|
6018
6269
|
tailwindcss(),
|
|
6019
6270
|
react(),
|
|
6020
6271
|
(0, import_vite_plugin_singlefile.viteSingleFile)({ removeViteModuleLoader: true })
|
|
6021
|
-
] : [buildNodeStubsPlugin, tailwindcss(), react()];
|
|
6272
|
+
] : [buildServerOnlyGuard, buildNodeStubsPlugin, tailwindcss(), react()];
|
|
6022
6273
|
await build({
|
|
6023
6274
|
root: tempDir,
|
|
6024
6275
|
base: baseUrl,
|
|
@@ -6037,11 +6288,10 @@ export default {
|
|
|
6037
6288
|
}
|
|
6038
6289
|
}
|
|
6039
6290
|
},
|
|
6040
|
-
resolve
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
},
|
|
6291
|
+
// When a tsconfig exists, enable Vite's native `resolve.tsconfigPaths`
|
|
6292
|
+
// so the project's path aliases resolve naturally. Otherwise fall
|
|
6293
|
+
// back to the legacy `@` → resourcesDir alias.
|
|
6294
|
+
resolve: hasProjectTsconfig ? { tsconfigPaths: true } : { alias: { "@": resourcesDir } },
|
|
6045
6295
|
optimizeDeps: {
|
|
6046
6296
|
// Exclude Node.js-only packages from browser bundling
|
|
6047
6297
|
exclude: ["posthog-node"]
|
|
@@ -6063,7 +6313,7 @@ export default {
|
|
|
6063
6313
|
// Inline all assets under 100MB (effectively all)
|
|
6064
6314
|
} : {},
|
|
6065
6315
|
rolldownOptions: {
|
|
6066
|
-
input:
|
|
6316
|
+
input: import_node_path9.default.join(tempDir, "index.html"),
|
|
6067
6317
|
external: (id) => {
|
|
6068
6318
|
return false;
|
|
6069
6319
|
}
|
|
@@ -6071,12 +6321,12 @@ export default {
|
|
|
6071
6321
|
}
|
|
6072
6322
|
});
|
|
6073
6323
|
try {
|
|
6074
|
-
const assetsDir =
|
|
6075
|
-
const assetFiles = await
|
|
6324
|
+
const assetsDir = import_node_path9.default.join(outDir, "assets");
|
|
6325
|
+
const assetFiles = await fs11.readdir(assetsDir);
|
|
6076
6326
|
const jsFiles = assetFiles.filter((f) => f.endsWith(".js"));
|
|
6077
6327
|
for (const jsFile of jsFiles) {
|
|
6078
|
-
const jsPath =
|
|
6079
|
-
let content = await
|
|
6328
|
+
const jsPath = import_node_path9.default.join(assetsDir, jsFile);
|
|
6329
|
+
let content = await fs11.readFile(jsPath, "utf8");
|
|
6080
6330
|
const zodConfigPatterns = [
|
|
6081
6331
|
// Non-minified: export const globalConfig = {}
|
|
6082
6332
|
/export\s+const\s+globalConfig\s*=\s*\{\s*\}/g,
|
|
@@ -6095,7 +6345,7 @@ export default {
|
|
|
6095
6345
|
}
|
|
6096
6346
|
}
|
|
6097
6347
|
if (patched) {
|
|
6098
|
-
await
|
|
6348
|
+
await fs11.writeFile(jsPath, content, "utf8");
|
|
6099
6349
|
console.log(source_default.gray(` \u2192 Patched Zod JIT in ${jsFile}`));
|
|
6100
6350
|
}
|
|
6101
6351
|
}
|
|
@@ -6107,8 +6357,8 @@ export default {
|
|
|
6107
6357
|
const mcpServerUrl = process.env.MCP_SERVER_URL;
|
|
6108
6358
|
if (mcpServerUrl) {
|
|
6109
6359
|
try {
|
|
6110
|
-
const htmlPath =
|
|
6111
|
-
let html = await
|
|
6360
|
+
const htmlPath = import_node_path9.default.join(outDir, "index.html");
|
|
6361
|
+
let html = await fs11.readFile(htmlPath, "utf8");
|
|
6112
6362
|
const injectionScript = `<script>window.__getFile = (filename) => { return "${mcpUrl}/${widgetName}/"+filename }; window.__mcpPublicUrl = "${mcpServerUrl}/mcp-use/public"; window.__mcpPublicAssetsUrl = "${mcpUrl}/public";</script>`;
|
|
6113
6363
|
if (!html.includes("window.__mcpPublicUrl")) {
|
|
6114
6364
|
html = html.replace(
|
|
@@ -6129,7 +6379,7 @@ export default {
|
|
|
6129
6379
|
<base href="${mcpServerUrl}">`
|
|
6130
6380
|
);
|
|
6131
6381
|
}
|
|
6132
|
-
await
|
|
6382
|
+
await fs11.writeFile(htmlPath, html, "utf8");
|
|
6133
6383
|
console.log(
|
|
6134
6384
|
source_default.gray(` \u2192 Injected MCP_SERVER_URL into ${widgetName}`)
|
|
6135
6385
|
);
|
|
@@ -6143,22 +6393,32 @@ export default {
|
|
|
6143
6393
|
}
|
|
6144
6394
|
}
|
|
6145
6395
|
console.log(source_default.green(` \u2713 Built ${widgetName}`));
|
|
6146
|
-
return {
|
|
6396
|
+
return {
|
|
6397
|
+
status: "built",
|
|
6398
|
+
name: widgetName,
|
|
6399
|
+
metadata: widgetMetadata
|
|
6400
|
+
};
|
|
6147
6401
|
} catch (error) {
|
|
6148
6402
|
console.error(source_default.red(` \u2717 Failed to build ${widgetName}:`), error);
|
|
6149
|
-
return
|
|
6403
|
+
return { status: "failed", name: widgetName };
|
|
6150
6404
|
}
|
|
6151
6405
|
};
|
|
6152
6406
|
const buildResults = await Promise.all(
|
|
6153
6407
|
entries.map((entry) => buildSingleWidget(entry))
|
|
6154
6408
|
);
|
|
6155
|
-
const
|
|
6156
|
-
|
|
6409
|
+
const failed = buildResults.filter((r) => r.status === "failed");
|
|
6410
|
+
if (failed.length > 0) {
|
|
6411
|
+
const names = failed.map((f) => f.name).join(", ");
|
|
6412
|
+
throw new Error(
|
|
6413
|
+
`${failed.length} widget(s) failed to build: ${names}. See errors above.`
|
|
6414
|
+
);
|
|
6415
|
+
}
|
|
6416
|
+
return buildResults.flatMap(
|
|
6417
|
+
(r) => r.status === "built" ? [{ name: r.name, metadata: r.metadata }] : []
|
|
6157
6418
|
);
|
|
6158
|
-
return builtWidgets;
|
|
6159
6419
|
}
|
|
6160
6420
|
async function collectTsFiles(projectPath, includePatterns, excludePatterns) {
|
|
6161
|
-
const { promises:
|
|
6421
|
+
const { promises: fs11 } = await import("fs");
|
|
6162
6422
|
const literalFiles = [];
|
|
6163
6423
|
const dirPrefixes = [];
|
|
6164
6424
|
for (const pattern of includePatterns) {
|
|
@@ -6173,7 +6433,7 @@ async function collectTsFiles(projectPath, includePatterns, excludePatterns) {
|
|
|
6173
6433
|
for (const file of literalFiles) {
|
|
6174
6434
|
if (/\.tsx?$/.test(file) && !file.endsWith(".d.ts")) {
|
|
6175
6435
|
try {
|
|
6176
|
-
await (0, import_promises7.access)(
|
|
6436
|
+
await (0, import_promises7.access)(import_node_path9.default.join(projectPath, file));
|
|
6177
6437
|
files.push(file);
|
|
6178
6438
|
} catch {
|
|
6179
6439
|
}
|
|
@@ -6181,13 +6441,13 @@ async function collectTsFiles(projectPath, includePatterns, excludePatterns) {
|
|
|
6181
6441
|
}
|
|
6182
6442
|
const excludeSet = new Set(excludePatterns.map((e) => e.replace(/\*+/g, "")));
|
|
6183
6443
|
for (const prefix of dirPrefixes) {
|
|
6184
|
-
const dirPath =
|
|
6444
|
+
const dirPath = import_node_path9.default.join(projectPath, prefix);
|
|
6185
6445
|
try {
|
|
6186
|
-
const entries = await
|
|
6446
|
+
const entries = await fs11.readdir(dirPath, { recursive: true });
|
|
6187
6447
|
for (const entry of entries) {
|
|
6188
6448
|
const entryStr = String(entry);
|
|
6189
|
-
const rel =
|
|
6190
|
-
if (/\.tsx?$/.test(entryStr) && !entryStr.endsWith(".d.ts") && !excludeSet.has(rel.split(
|
|
6449
|
+
const rel = import_node_path9.default.join(prefix, entryStr);
|
|
6450
|
+
if (/\.tsx?$/.test(entryStr) && !entryStr.endsWith(".d.ts") && !excludeSet.has(rel.split(import_node_path9.default.sep)[0])) {
|
|
6191
6451
|
files.push(rel);
|
|
6192
6452
|
}
|
|
6193
6453
|
}
|
|
@@ -6198,11 +6458,11 @@ async function collectTsFiles(projectPath, includePatterns, excludePatterns) {
|
|
|
6198
6458
|
}
|
|
6199
6459
|
async function transpileWithEsbuild(projectPath) {
|
|
6200
6460
|
const esbuild = await import("esbuild");
|
|
6201
|
-
const { promises:
|
|
6202
|
-
const tsconfigPath =
|
|
6461
|
+
const { promises: fs11 } = await import("fs");
|
|
6462
|
+
const tsconfigPath = import_node_path9.default.join(projectPath, "tsconfig.json");
|
|
6203
6463
|
let tsconfig = {};
|
|
6204
6464
|
try {
|
|
6205
|
-
const raw = await
|
|
6465
|
+
const raw = await fs11.readFile(tsconfigPath, "utf-8");
|
|
6206
6466
|
tsconfig = JSON.parse(raw);
|
|
6207
6467
|
} catch {
|
|
6208
6468
|
}
|
|
@@ -6229,10 +6489,10 @@ async function transpileWithEsbuild(projectPath) {
|
|
|
6229
6489
|
const target = (compilerOptions.target || "ES2022").toLowerCase();
|
|
6230
6490
|
const moduleStr = (compilerOptions.module || "ESNext").toLowerCase();
|
|
6231
6491
|
const format = moduleStr.includes("commonjs") ? "cjs" : "esm";
|
|
6232
|
-
const outbase = compilerOptions.rootDir ?
|
|
6492
|
+
const outbase = compilerOptions.rootDir ? import_node_path9.default.resolve(projectPath, compilerOptions.rootDir) : projectPath;
|
|
6233
6493
|
await esbuild.build({
|
|
6234
|
-
entryPoints: files.map((f) =>
|
|
6235
|
-
outdir:
|
|
6494
|
+
entryPoints: files.map((f) => import_node_path9.default.join(projectPath, f)),
|
|
6495
|
+
outdir: import_node_path9.default.join(projectPath, outDir),
|
|
6236
6496
|
outbase,
|
|
6237
6497
|
bundle: false,
|
|
6238
6498
|
format,
|
|
@@ -6244,21 +6504,42 @@ async function transpileWithEsbuild(projectPath) {
|
|
|
6244
6504
|
logLevel: "warning"
|
|
6245
6505
|
});
|
|
6246
6506
|
}
|
|
6247
|
-
program.command("build").description("Build TypeScript and MCP UI widgets").option("-p, --path <path>", "Path to project directory", process.cwd()).option(
|
|
6507
|
+
program.command("build").description("Build TypeScript and MCP UI widgets").option("-p, --path <path>", "Path to project directory", process.cwd()).option(
|
|
6508
|
+
"--entry <file>",
|
|
6509
|
+
"Path to MCP server entry file (relative to project)"
|
|
6510
|
+
).option(
|
|
6511
|
+
"--widgets-dir <dir>",
|
|
6512
|
+
"Path to widgets directory (relative to project)"
|
|
6513
|
+
).option(
|
|
6514
|
+
"--mcp-dir <dir>",
|
|
6515
|
+
"Folder holding the MCP entry + resources (e.g. 'src/mcp' for Next.js apps)"
|
|
6516
|
+
).option("--with-inspector", "Include inspector in production build").option(
|
|
6248
6517
|
"--inline",
|
|
6249
6518
|
"Inline all JS/CSS into HTML (required for VS Code MCP Apps)"
|
|
6250
6519
|
).option("--no-inline", "Keep JS/CSS as separate files (default)").option("--no-typecheck", "Skip TypeScript type checking (faster builds)").action(async (options) => {
|
|
6251
6520
|
try {
|
|
6252
|
-
const projectPath =
|
|
6253
|
-
const { promises:
|
|
6521
|
+
const projectPath = import_node_path9.default.resolve(options.path);
|
|
6522
|
+
const { promises: fs11 } = await import("fs");
|
|
6254
6523
|
displayPackageVersions(projectPath);
|
|
6524
|
+
const mcpDir = options.mcpDir;
|
|
6525
|
+
const widgetsDir = resolveWidgetsDir(options.widgetsDir, mcpDir);
|
|
6255
6526
|
const builtWidgets = await buildWidgets(projectPath, {
|
|
6256
|
-
inline: options.inline ?? false
|
|
6527
|
+
inline: options.inline ?? false,
|
|
6528
|
+
widgetsDir
|
|
6257
6529
|
});
|
|
6258
6530
|
let sourceServerFile;
|
|
6259
6531
|
try {
|
|
6260
|
-
sourceServerFile = await findServerFile(
|
|
6261
|
-
|
|
6532
|
+
sourceServerFile = await findServerFile(
|
|
6533
|
+
projectPath,
|
|
6534
|
+
options.entry,
|
|
6535
|
+
options.mcpDir
|
|
6536
|
+
);
|
|
6537
|
+
} catch (err) {
|
|
6538
|
+
console.log(
|
|
6539
|
+
source_default.yellow(
|
|
6540
|
+
`\u26A0 Could not locate a server entry file: ${err instanceof Error ? err.message : String(err)}`
|
|
6541
|
+
)
|
|
6542
|
+
);
|
|
6262
6543
|
}
|
|
6263
6544
|
if (sourceServerFile) {
|
|
6264
6545
|
console.log(source_default.gray("Generating tool registry types..."));
|
|
@@ -6276,17 +6557,25 @@ program.command("build").description("Build TypeScript and MCP UI widgets").opti
|
|
|
6276
6557
|
);
|
|
6277
6558
|
}
|
|
6278
6559
|
}
|
|
6279
|
-
|
|
6280
|
-
|
|
6281
|
-
|
|
6282
|
-
|
|
6560
|
+
if (!mcpDir) {
|
|
6561
|
+
console.log(source_default.gray("Building TypeScript..."));
|
|
6562
|
+
await transpileWithEsbuild(projectPath);
|
|
6563
|
+
console.log(source_default.green("\u2713 TypeScript build complete!"));
|
|
6564
|
+
} else {
|
|
6565
|
+
console.log(
|
|
6566
|
+
source_default.gray(
|
|
6567
|
+
"Skipping TypeScript transpile (--mcp-dir mode runs source via tsx at start time)"
|
|
6568
|
+
)
|
|
6569
|
+
);
|
|
6570
|
+
}
|
|
6571
|
+
if (options.typecheck !== false && !mcpDir) {
|
|
6283
6572
|
console.log(source_default.gray("Type checking..."));
|
|
6284
6573
|
try {
|
|
6285
6574
|
await runCommand(
|
|
6286
6575
|
"node",
|
|
6287
6576
|
[
|
|
6288
6577
|
"--max-old-space-size=4096",
|
|
6289
|
-
|
|
6578
|
+
import_node_path9.default.join(
|
|
6290
6579
|
projectPath,
|
|
6291
6580
|
"node_modules",
|
|
6292
6581
|
"typescript",
|
|
@@ -6307,39 +6596,43 @@ program.command("build").description("Build TypeScript and MCP UI widgets").opti
|
|
|
6307
6596
|
}
|
|
6308
6597
|
let entryPoint;
|
|
6309
6598
|
if (sourceServerFile) {
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6599
|
+
if (mcpDir) {
|
|
6600
|
+
entryPoint = sourceServerFile;
|
|
6601
|
+
} else {
|
|
6602
|
+
const baseName = import_node_path9.default.basename(sourceServerFile, ".ts") + ".js";
|
|
6603
|
+
const possibleOutputs = [
|
|
6604
|
+
`dist/${baseName}`,
|
|
6605
|
+
// rootDir set to project root or src
|
|
6606
|
+
`dist/src/${baseName}`,
|
|
6607
|
+
// no rootDir, source in src/
|
|
6608
|
+
`dist/${sourceServerFile.replace(/\.ts$/, ".js")}`
|
|
6609
|
+
// exact path preserved
|
|
6610
|
+
];
|
|
6611
|
+
for (const candidate of possibleOutputs) {
|
|
6612
|
+
try {
|
|
6613
|
+
await (0, import_promises7.access)(import_node_path9.default.join(projectPath, candidate));
|
|
6614
|
+
entryPoint = candidate;
|
|
6615
|
+
break;
|
|
6616
|
+
} catch {
|
|
6617
|
+
continue;
|
|
6618
|
+
}
|
|
6326
6619
|
}
|
|
6327
6620
|
}
|
|
6328
6621
|
}
|
|
6329
|
-
const publicDir =
|
|
6622
|
+
const publicDir = import_node_path9.default.join(projectPath, "public");
|
|
6330
6623
|
try {
|
|
6331
|
-
await
|
|
6624
|
+
await fs11.access(publicDir);
|
|
6332
6625
|
console.log(source_default.gray("Copying public assets..."));
|
|
6333
|
-
await
|
|
6626
|
+
await fs11.cp(publicDir, import_node_path9.default.join(projectPath, "dist", "public"), {
|
|
6334
6627
|
recursive: true
|
|
6335
6628
|
});
|
|
6336
6629
|
console.log(source_default.green("\u2713 Public assets copied"));
|
|
6337
6630
|
} catch {
|
|
6338
6631
|
}
|
|
6339
|
-
const manifestPath =
|
|
6632
|
+
const manifestPath = import_node_path9.default.join(projectPath, "dist", "mcp-use.json");
|
|
6340
6633
|
let existingManifest = {};
|
|
6341
6634
|
try {
|
|
6342
|
-
const existingContent = await
|
|
6635
|
+
const existingContent = await fs11.readFile(manifestPath, "utf-8");
|
|
6343
6636
|
existingManifest = JSON.parse(existingContent);
|
|
6344
6637
|
} catch {
|
|
6345
6638
|
}
|
|
@@ -6361,8 +6654,8 @@ program.command("build").description("Build TypeScript and MCP UI widgets").opti
|
|
|
6361
6654
|
// Server entry point for `mcp-use start`
|
|
6362
6655
|
widgets: widgetsData
|
|
6363
6656
|
};
|
|
6364
|
-
await
|
|
6365
|
-
await
|
|
6657
|
+
await fs11.mkdir(import_node_path9.default.dirname(manifestPath), { recursive: true });
|
|
6658
|
+
await fs11.writeFile(
|
|
6366
6659
|
manifestPath,
|
|
6367
6660
|
JSON.stringify(manifest, null, 2),
|
|
6368
6661
|
"utf8"
|
|
@@ -6382,14 +6675,23 @@ program.command("build").description("Build TypeScript and MCP UI widgets").opti
|
|
|
6382
6675
|
process.exit(1);
|
|
6383
6676
|
}
|
|
6384
6677
|
});
|
|
6385
|
-
program.command("dev").description("Run development server with auto-reload and inspector").option("-p, --path <path>", "Path to project directory", process.cwd()).option(
|
|
6678
|
+
program.command("dev").description("Run development server with auto-reload and inspector").option("-p, --path <path>", "Path to project directory", process.cwd()).option(
|
|
6679
|
+
"--entry <file>",
|
|
6680
|
+
"Path to MCP server entry file (relative to project)"
|
|
6681
|
+
).option(
|
|
6682
|
+
"--widgets-dir <dir>",
|
|
6683
|
+
"Path to widgets directory (relative to project)"
|
|
6684
|
+
).option(
|
|
6685
|
+
"--mcp-dir <dir>",
|
|
6686
|
+
"Folder holding the MCP entry + resources (e.g. 'src/mcp' for Next.js apps)"
|
|
6687
|
+
).option("--port <port>", "Server port", "3000").option(
|
|
6386
6688
|
"--host <host>",
|
|
6387
6689
|
"Server host (use 0.0.0.0 to listen on all interfaces)",
|
|
6388
6690
|
"0.0.0.0"
|
|
6389
6691
|
).option("--no-open", "Do not auto-open inspector").option("--no-hmr", "Disable hot module reloading (use tsx watch instead)").option("--tunnel", "Expose server through a tunnel").action(async (options) => {
|
|
6390
6692
|
try {
|
|
6391
6693
|
process.env.MCP_USE_CLI_DEV = "1";
|
|
6392
|
-
const projectPath =
|
|
6694
|
+
const projectPath = import_node_path9.default.resolve(options.path);
|
|
6393
6695
|
let port = parseInt(options.port, 10);
|
|
6394
6696
|
const host = options.host;
|
|
6395
6697
|
const useHmr = options.hmr !== false;
|
|
@@ -6400,13 +6702,24 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
6400
6702
|
console.log(source_default.green.bold(`\u2713 Using port ${availablePort} instead`));
|
|
6401
6703
|
port = availablePort;
|
|
6402
6704
|
}
|
|
6403
|
-
const serverFile = await findServerFile(
|
|
6705
|
+
const serverFile = await findServerFile(
|
|
6706
|
+
projectPath,
|
|
6707
|
+
options.entry,
|
|
6708
|
+
options.mcpDir
|
|
6709
|
+
);
|
|
6710
|
+
{
|
|
6711
|
+
const devMcpDir = options.mcpDir;
|
|
6712
|
+
const devWidgetsDir = resolveWidgetsDir(options.widgetsDir, devMcpDir);
|
|
6713
|
+
if (devWidgetsDir !== "resources") {
|
|
6714
|
+
process.env.MCP_USE_WIDGETS_DIR = devWidgetsDir;
|
|
6715
|
+
}
|
|
6716
|
+
}
|
|
6404
6717
|
let tunnelProcess = void 0;
|
|
6405
6718
|
let tunnelSubdomain = void 0;
|
|
6406
6719
|
let tunnelUrl = void 0;
|
|
6407
6720
|
if (options.tunnel) {
|
|
6408
6721
|
try {
|
|
6409
|
-
const manifestPath =
|
|
6722
|
+
const manifestPath = import_node_path9.default.join(projectPath, "dist", "mcp-use.json");
|
|
6410
6723
|
let existingSubdomain;
|
|
6411
6724
|
try {
|
|
6412
6725
|
const manifestContent = await (0, import_promises7.readFile)(manifestPath, "utf-8");
|
|
@@ -6455,7 +6768,7 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
6455
6768
|
manifest.tunnel = {};
|
|
6456
6769
|
}
|
|
6457
6770
|
manifest.tunnel.subdomain = tunnelSubdomain;
|
|
6458
|
-
await (0, import_promises7.mkdir)(
|
|
6771
|
+
await (0, import_promises7.mkdir)(import_node_path9.default.dirname(manifestPath), { recursive: true });
|
|
6459
6772
|
await (0, import_promises7.writeFile)(
|
|
6460
6773
|
manifestPath,
|
|
6461
6774
|
JSON.stringify(manifest, null, 2),
|
|
@@ -6482,22 +6795,35 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
6482
6795
|
} else if (!process.env.MCP_URL) {
|
|
6483
6796
|
process.env.MCP_URL = mcpUrl;
|
|
6484
6797
|
}
|
|
6798
|
+
const isNextJsProject = await detectNextJsProject(projectPath);
|
|
6799
|
+
if (isNextJsProject) {
|
|
6800
|
+
console.log(
|
|
6801
|
+
source_default.gray(
|
|
6802
|
+
"Next.js detected \u2014 installing server-runtime shims (server-only, next/cache, next/headers, next/navigation, next/server)"
|
|
6803
|
+
)
|
|
6804
|
+
);
|
|
6805
|
+
await loadNextJsEnvFiles(projectPath);
|
|
6806
|
+
}
|
|
6485
6807
|
if (!useHmr) {
|
|
6486
6808
|
console.log(source_default.gray("HMR disabled, using tsx watch (full restart)"));
|
|
6487
6809
|
const processes = [];
|
|
6488
|
-
const
|
|
6810
|
+
const baseEnv = {
|
|
6811
|
+
// Inherit parent env (PATH, HOME, etc.) — without it, tsx can't
|
|
6812
|
+
// resolve its own tooling in some setups.
|
|
6813
|
+
...process.env,
|
|
6489
6814
|
PORT: String(port),
|
|
6490
6815
|
HOST: host,
|
|
6491
6816
|
NODE_ENV: "development",
|
|
6492
6817
|
// Preserve user-provided MCP_URL (e.g., for reverse proxy setups)
|
|
6493
6818
|
MCP_URL: process.env.MCP_URL || mcpUrl
|
|
6494
6819
|
};
|
|
6820
|
+
const env2 = isNextJsProject ? withNextShimsEnv(baseEnv) : baseEnv;
|
|
6495
6821
|
const { createRequire: createRequire4 } = await import("module");
|
|
6496
6822
|
let cmd;
|
|
6497
6823
|
let args;
|
|
6498
6824
|
try {
|
|
6499
6825
|
const projectRequire = createRequire4(
|
|
6500
|
-
|
|
6826
|
+
import_node_path9.default.join(projectPath, "package.json")
|
|
6501
6827
|
);
|
|
6502
6828
|
const tsxPkgPath = projectRequire.resolve("tsx/package.json");
|
|
6503
6829
|
const tsxPkg = JSON.parse(await (0, import_promises7.readFile)(tsxPkgPath, "utf-8"));
|
|
@@ -6509,7 +6835,7 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
6509
6835
|
} else {
|
|
6510
6836
|
throw new Error("No bin field found in tsx package.json");
|
|
6511
6837
|
}
|
|
6512
|
-
const tsxBin =
|
|
6838
|
+
const tsxBin = import_node_path9.default.resolve(import_node_path9.default.dirname(tsxPkgPath), binPath);
|
|
6513
6839
|
cmd = "node";
|
|
6514
6840
|
args = [tsxBin, "watch", serverFile];
|
|
6515
6841
|
} catch (error) {
|
|
@@ -6584,18 +6910,56 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
6584
6910
|
"HMR enabled - changes will hot reload without dropping connections"
|
|
6585
6911
|
)
|
|
6586
6912
|
);
|
|
6913
|
+
if (isNextJsProject) {
|
|
6914
|
+
const registered = await registerNextShimsInProcess();
|
|
6915
|
+
if (!registered) {
|
|
6916
|
+
console.warn(
|
|
6917
|
+
source_default.yellow(
|
|
6918
|
+
"[HMR] Warning: Next.js shim loader could not be found on disk. Importing server-only / next/cache / etc. will throw. Reinstall @mcp-use/cli to fix."
|
|
6919
|
+
)
|
|
6920
|
+
);
|
|
6921
|
+
}
|
|
6922
|
+
}
|
|
6587
6923
|
const chokidarModule = await import("chokidar");
|
|
6588
6924
|
const chokidar = chokidarModule.default || chokidarModule;
|
|
6589
|
-
const { fileURLToPath:
|
|
6925
|
+
const { fileURLToPath: fileURLToPath3 } = await import("url");
|
|
6590
6926
|
const { createRequire: createRequire3 } = await import("module");
|
|
6591
|
-
|
|
6927
|
+
const projectTsconfigPath = import_node_path9.default.join(projectPath, "tsconfig.json");
|
|
6928
|
+
let tsconfigAvailable = false;
|
|
6929
|
+
try {
|
|
6930
|
+
await (0, import_promises7.access)(projectTsconfigPath);
|
|
6931
|
+
tsconfigAvailable = true;
|
|
6932
|
+
process.env.TSX_TSCONFIG_PATH = projectTsconfigPath;
|
|
6933
|
+
if (process.cwd() !== projectPath) process.chdir(projectPath);
|
|
6934
|
+
} catch {
|
|
6935
|
+
}
|
|
6936
|
+
let tsxLoaderActive = false;
|
|
6592
6937
|
try {
|
|
6593
6938
|
const projectRequire = createRequire3(
|
|
6594
|
-
|
|
6939
|
+
import_node_path9.default.join(projectPath, "package.json")
|
|
6595
6940
|
);
|
|
6596
|
-
const
|
|
6597
|
-
const
|
|
6598
|
-
|
|
6941
|
+
const tsxEsmApiPath = projectRequire.resolve("tsx/esm/api");
|
|
6942
|
+
const tsxEsmApi = await import((0, import_node_url3.pathToFileURL)(tsxEsmApiPath).href);
|
|
6943
|
+
if (typeof tsxEsmApi.register === "function") {
|
|
6944
|
+
tsxEsmApi.register({
|
|
6945
|
+
tsconfig: tsconfigAvailable ? projectTsconfigPath : void 0,
|
|
6946
|
+
onImport: (url) => {
|
|
6947
|
+
const filePath = url.startsWith("file://") ? fileURLToPath3(url) : url;
|
|
6948
|
+
if (!filePath.includes("node_modules") && filePath.startsWith(projectPath)) {
|
|
6949
|
+
console.debug(`[HMR] Loaded: ${url}`);
|
|
6950
|
+
}
|
|
6951
|
+
}
|
|
6952
|
+
});
|
|
6953
|
+
tsxLoaderActive = true;
|
|
6954
|
+
}
|
|
6955
|
+
try {
|
|
6956
|
+
const tsxCjsApiPath = projectRequire.resolve("tsx/cjs/api");
|
|
6957
|
+
const tsxCjsApi = await import((0, import_node_url3.pathToFileURL)(tsxCjsApiPath).href);
|
|
6958
|
+
if (typeof tsxCjsApi.register === "function") {
|
|
6959
|
+
tsxCjsApi.register();
|
|
6960
|
+
}
|
|
6961
|
+
} catch {
|
|
6962
|
+
}
|
|
6599
6963
|
} catch {
|
|
6600
6964
|
console.log(
|
|
6601
6965
|
source_default.yellow(
|
|
@@ -6603,25 +6967,15 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
6603
6967
|
)
|
|
6604
6968
|
);
|
|
6605
6969
|
}
|
|
6606
|
-
const serverFilePath =
|
|
6607
|
-
const serverFileUrl = (0,
|
|
6970
|
+
const serverFilePath = import_node_path9.default.join(projectPath, serverFile);
|
|
6971
|
+
const serverFileUrl = (0, import_node_url3.pathToFileURL)(serverFilePath).href;
|
|
6608
6972
|
globalThis.__mcpUseHmrMode = true;
|
|
6609
6973
|
const importServerModule = async () => {
|
|
6610
6974
|
const previousServer = globalThis.__mcpUseLastServer;
|
|
6611
6975
|
globalThis.__mcpUseLastServer = null;
|
|
6612
|
-
if (
|
|
6613
|
-
await tsImport(`${serverFileUrl}?t=${Date.now()}`, {
|
|
6614
|
-
parentURL: importMetaUrl,
|
|
6615
|
-
onImport: (file) => {
|
|
6616
|
-
const filePath = file.startsWith("file://") ? fileURLToPath2(file) : file;
|
|
6617
|
-
if (!filePath.includes("node_modules") && filePath.startsWith(projectPath)) {
|
|
6618
|
-
console.debug(`[HMR] Loaded: ${file}`);
|
|
6619
|
-
}
|
|
6620
|
-
}
|
|
6621
|
-
});
|
|
6622
|
-
} else {
|
|
6623
|
-
await import(`${serverFileUrl}?t=${Date.now()}`);
|
|
6976
|
+
if (!tsxLoaderActive) {
|
|
6624
6977
|
}
|
|
6978
|
+
await import(`${serverFileUrl}?t=${Date.now()}`);
|
|
6625
6979
|
const instance = globalThis.__mcpUseLastServer;
|
|
6626
6980
|
if (!instance) {
|
|
6627
6981
|
globalThis.__mcpUseLastServer = previousServer;
|
|
@@ -6635,7 +6989,7 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
6635
6989
|
if (instance === previousServer) {
|
|
6636
6990
|
console.warn(
|
|
6637
6991
|
source_default.yellow(
|
|
6638
|
-
"[HMR] Warning: Module re-import returned the same server instance. The module may not have been re-evaluated. " + (!
|
|
6992
|
+
"[HMR] Warning: Module re-import returned the same server instance. The module may not have been re-evaluated. " + (!tsxLoaderActive ? "Install tsx as a devDependency for reliable TypeScript HMR." : "This may be a module cache issue.")
|
|
6639
6993
|
)
|
|
6640
6994
|
);
|
|
6641
6995
|
return null;
|
|
@@ -6710,8 +7064,8 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
6710
7064
|
}
|
|
6711
7065
|
let watcher = chokidar.watch(".", {
|
|
6712
7066
|
cwd: projectPath,
|
|
6713
|
-
ignored: (
|
|
6714
|
-
const normalizedPath =
|
|
7067
|
+
ignored: (path8, stats) => {
|
|
7068
|
+
const normalizedPath = path8.replace(/\\/g, "/");
|
|
6715
7069
|
if (/(^|\/)\.[^/]/.test(normalizedPath)) {
|
|
6716
7070
|
return true;
|
|
6717
7071
|
}
|
|
@@ -6885,7 +7239,7 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
6885
7239
|
}
|
|
6886
7240
|
tunnelUrl = void 0;
|
|
6887
7241
|
if (withTunnel) {
|
|
6888
|
-
const manifestPath =
|
|
7242
|
+
const manifestPath = import_node_path9.default.join(projectPath, "dist", "mcp-use.json");
|
|
6889
7243
|
let existingSubdomain;
|
|
6890
7244
|
try {
|
|
6891
7245
|
const manifestContent = await (0, import_promises7.readFile)(manifestPath, "utf-8");
|
|
@@ -6922,7 +7276,7 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
6922
7276
|
tunnelSubdomain = tunnelInfo.subdomain;
|
|
6923
7277
|
process.env.MCP_URL = tunnelUrl;
|
|
6924
7278
|
try {
|
|
6925
|
-
const mPath =
|
|
7279
|
+
const mPath = import_node_path9.default.join(projectPath, "dist", "mcp-use.json");
|
|
6926
7280
|
let manifest = {};
|
|
6927
7281
|
try {
|
|
6928
7282
|
manifest = JSON.parse(await (0, import_promises7.readFile)(mPath, "utf-8"));
|
|
@@ -6930,7 +7284,7 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
6930
7284
|
}
|
|
6931
7285
|
if (!manifest.tunnel) manifest.tunnel = {};
|
|
6932
7286
|
manifest.tunnel.subdomain = tunnelSubdomain;
|
|
6933
|
-
await (0, import_promises7.mkdir)(
|
|
7287
|
+
await (0, import_promises7.mkdir)(import_node_path9.default.dirname(mPath), { recursive: true });
|
|
6934
7288
|
await (0, import_promises7.writeFile)(mPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
6935
7289
|
} catch {
|
|
6936
7290
|
}
|
|
@@ -7026,9 +7380,15 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7026
7380
|
process.exit(1);
|
|
7027
7381
|
}
|
|
7028
7382
|
});
|
|
7029
|
-
program.command("start").description("Start production server").option("-p, --path <path>", "Path to project directory", process.cwd()).option(
|
|
7383
|
+
program.command("start").description("Start production server").option("-p, --path <path>", "Path to project directory", process.cwd()).option(
|
|
7384
|
+
"--entry <file>",
|
|
7385
|
+
"Path to MCP server entry file (relative to project)"
|
|
7386
|
+
).option(
|
|
7387
|
+
"--mcp-dir <dir>",
|
|
7388
|
+
"Folder holding the MCP entry + resources (e.g. 'src/mcp' for Next.js apps)"
|
|
7389
|
+
).option("--port <port>", "Server port", "3000").option("--tunnel", "Expose server through a tunnel").action(async (options) => {
|
|
7030
7390
|
try {
|
|
7031
|
-
const projectPath =
|
|
7391
|
+
const projectPath = import_node_path9.default.resolve(options.path);
|
|
7032
7392
|
const portFlagProvided = process.argv.includes("--port") || process.argv.includes("-p") || process.argv.some((arg) => arg.startsWith("--port=")) || process.argv.some((arg) => arg.startsWith("-p="));
|
|
7033
7393
|
let port = portFlagProvided ? parseInt(options.port, 10) : parseInt(process.env.PORT || options.port || "3000", 10);
|
|
7034
7394
|
if (!await isPortAvailable(port)) {
|
|
@@ -7046,7 +7406,7 @@ program.command("start").description("Start production server").option("-p, --pa
|
|
|
7046
7406
|
let tunnelSubdomain = void 0;
|
|
7047
7407
|
if (options.tunnel) {
|
|
7048
7408
|
try {
|
|
7049
|
-
const manifestPath2 =
|
|
7409
|
+
const manifestPath2 = import_node_path9.default.join(projectPath, "dist", "mcp-use.json");
|
|
7050
7410
|
let existingSubdomain;
|
|
7051
7411
|
try {
|
|
7052
7412
|
const manifestContent = await (0, import_promises7.readFile)(manifestPath2, "utf-8");
|
|
@@ -7101,7 +7461,7 @@ program.command("start").description("Start production server").option("-p, --pa
|
|
|
7101
7461
|
manifest.tunnel = {};
|
|
7102
7462
|
}
|
|
7103
7463
|
manifest.tunnel.subdomain = subdomain;
|
|
7104
|
-
await (0, import_promises7.mkdir)(
|
|
7464
|
+
await (0, import_promises7.mkdir)(import_node_path9.default.dirname(manifestPath2), { recursive: true });
|
|
7105
7465
|
await (0, import_promises7.writeFile)(
|
|
7106
7466
|
manifestPath2,
|
|
7107
7467
|
JSON.stringify(manifest, null, 2),
|
|
@@ -7120,18 +7480,25 @@ program.command("start").description("Start production server").option("-p, --pa
|
|
|
7120
7480
|
}
|
|
7121
7481
|
}
|
|
7122
7482
|
let serverFile;
|
|
7123
|
-
const manifestPath =
|
|
7483
|
+
const manifestPath = import_node_path9.default.join(projectPath, "dist", "mcp-use.json");
|
|
7124
7484
|
try {
|
|
7125
7485
|
const manifestContent = await (0, import_promises7.readFile)(manifestPath, "utf-8");
|
|
7126
7486
|
const manifest = JSON.parse(manifestContent);
|
|
7127
7487
|
if (manifest.entryPoint) {
|
|
7128
|
-
await (0, import_promises7.access)(
|
|
7488
|
+
await (0, import_promises7.access)(import_node_path9.default.join(projectPath, manifest.entryPoint));
|
|
7129
7489
|
serverFile = manifest.entryPoint;
|
|
7130
7490
|
}
|
|
7131
7491
|
} catch {
|
|
7132
7492
|
}
|
|
7133
7493
|
if (!serverFile) {
|
|
7494
|
+
const startMcpDir = options.mcpDir;
|
|
7134
7495
|
const serverCandidates = [
|
|
7496
|
+
...startMcpDir ? [
|
|
7497
|
+
`${startMcpDir}/index.ts`,
|
|
7498
|
+
`${startMcpDir}/index.tsx`,
|
|
7499
|
+
`dist/${startMcpDir}/index.js`,
|
|
7500
|
+
`dist/${startMcpDir}/server.js`
|
|
7501
|
+
] : [],
|
|
7135
7502
|
"dist/index.js",
|
|
7136
7503
|
"dist/server.js",
|
|
7137
7504
|
"dist/src/index.js",
|
|
@@ -7139,7 +7506,7 @@ program.command("start").description("Start production server").option("-p, --pa
|
|
|
7139
7506
|
];
|
|
7140
7507
|
for (const candidate of serverCandidates) {
|
|
7141
7508
|
try {
|
|
7142
|
-
await (0, import_promises7.access)(
|
|
7509
|
+
await (0, import_promises7.access)(import_node_path9.default.join(projectPath, candidate));
|
|
7143
7510
|
serverFile = candidate;
|
|
7144
7511
|
break;
|
|
7145
7512
|
} catch {
|
|
@@ -7163,18 +7530,53 @@ Looked for:
|
|
|
7163
7530
|
process.exit(1);
|
|
7164
7531
|
}
|
|
7165
7532
|
console.log("Starting production server...");
|
|
7166
|
-
const
|
|
7533
|
+
const isNextJsProject = await detectNextJsProject(projectPath);
|
|
7534
|
+
if (isNextJsProject) {
|
|
7535
|
+
console.log(
|
|
7536
|
+
source_default.gray(
|
|
7537
|
+
"Next.js detected \u2014 installing server-runtime shims for the production server"
|
|
7538
|
+
)
|
|
7539
|
+
);
|
|
7540
|
+
await loadNextJsEnvFiles(projectPath);
|
|
7541
|
+
}
|
|
7542
|
+
const baseEnv = {
|
|
7167
7543
|
...process.env,
|
|
7168
7544
|
PORT: String(port),
|
|
7169
7545
|
NODE_ENV: "production"
|
|
7170
7546
|
};
|
|
7171
7547
|
if (mcpUrl) {
|
|
7172
|
-
|
|
7548
|
+
baseEnv.MCP_URL = mcpUrl;
|
|
7173
7549
|
console.log(source_default.whiteBright(`Tunnel: ${mcpUrl}/mcp`));
|
|
7174
|
-
} else if (!
|
|
7175
|
-
|
|
7550
|
+
} else if (!baseEnv.MCP_URL) {
|
|
7551
|
+
baseEnv.MCP_URL = `http://localhost:${port}`;
|
|
7552
|
+
}
|
|
7553
|
+
const env2 = isNextJsProject ? withNextShimsEnv(baseEnv) : baseEnv;
|
|
7554
|
+
const isTsEntry = /\.(ts|tsx|mts|cts)$/.test(serverFile);
|
|
7555
|
+
let spawnCmd = "node";
|
|
7556
|
+
let spawnArgs = [serverFile];
|
|
7557
|
+
if (isTsEntry) {
|
|
7558
|
+
try {
|
|
7559
|
+
const projectRequire = (0, import_node_module2.createRequire)(
|
|
7560
|
+
import_node_path9.default.join(projectPath, "package.json")
|
|
7561
|
+
);
|
|
7562
|
+
const tsxPkgPath = projectRequire.resolve("tsx/package.json");
|
|
7563
|
+
const tsxPkg = JSON.parse(await (0, import_promises7.readFile)(tsxPkgPath, "utf-8"));
|
|
7564
|
+
const binField = typeof tsxPkg.bin === "string" ? tsxPkg.bin : tsxPkg.bin?.tsx ?? Object.values(tsxPkg.bin ?? {})[0];
|
|
7565
|
+
if (!binField) throw new Error("tsx bin entry not found");
|
|
7566
|
+
const tsxBin = import_node_path9.default.resolve(import_node_path9.default.dirname(tsxPkgPath), binField);
|
|
7567
|
+
spawnCmd = "node";
|
|
7568
|
+
spawnArgs = [tsxBin, serverFile];
|
|
7569
|
+
} catch (error) {
|
|
7570
|
+
console.log(
|
|
7571
|
+
source_default.yellow(
|
|
7572
|
+
`Could not resolve local tsx (${error instanceof Error ? error.message : String(error)}); falling back to npx`
|
|
7573
|
+
)
|
|
7574
|
+
);
|
|
7575
|
+
spawnCmd = "npx";
|
|
7576
|
+
spawnArgs = ["tsx", serverFile];
|
|
7577
|
+
}
|
|
7176
7578
|
}
|
|
7177
|
-
const serverProc = (0, import_node_child_process9.spawn)(
|
|
7579
|
+
const serverProc = (0, import_node_child_process9.spawn)(spawnCmd, spawnArgs, {
|
|
7178
7580
|
cwd: projectPath,
|
|
7179
7581
|
stdio: "inherit",
|
|
7180
7582
|
env: env2
|
|
@@ -7310,7 +7712,7 @@ program.addCommand(createSkillsCommand());
|
|
|
7310
7712
|
program.command("generate-types").description(
|
|
7311
7713
|
"Generate TypeScript type definitions for tools (writes .mcp-use/tool-registry.d.ts)"
|
|
7312
7714
|
).option("-p, --path <path>", "Path to project directory", process.cwd()).option("--server <file>", "Server entry file", "index.ts").action(async (options) => {
|
|
7313
|
-
const projectPath =
|
|
7715
|
+
const projectPath = import_node_path9.default.resolve(options.path);
|
|
7314
7716
|
try {
|
|
7315
7717
|
console.log(source_default.blue("Generating tool registry types..."));
|
|
7316
7718
|
const success = await generateToolRegistryTypesForServer(
|