@weapp-vite/mcp 1.1.0 → 1.1.2

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/README.md CHANGED
@@ -11,7 +11,7 @@
11
11
  - 文档/变更记录资源暴露
12
12
  - 调试/改造提示词模板
13
13
 
14
- 默认通过 `stdio` 运行,适合接入任意 MCP Client
14
+ 默认通过 `stdio` 运行,适合接入任意 MCP Client,也支持 `streamable-http`。
15
15
 
16
16
  ## 启动
17
17
 
@@ -19,6 +19,22 @@
19
19
  pnpm --filter @weapp-vite/mcp start
20
20
  ```
21
21
 
22
+ 也可以在 Node 脚本里直接调用:
23
+
24
+ ```ts
25
+ import { startWeappViteMcpServer } from '@weapp-vite/mcp'
26
+
27
+ const handle = await startWeappViteMcpServer({
28
+ workspaceRoot: process.cwd(),
29
+ transport: 'streamable-http',
30
+ host: '127.0.0.1',
31
+ port: 3088,
32
+ endpoint: '/mcp',
33
+ })
34
+
35
+ await handle.close?.()
36
+ ```
37
+
22
38
  ## 主要 Tools
23
39
 
24
40
  - `workspace_catalog`: 输出 `weapp-vite / wevu / wevu-compiler` 目录、版本、脚本
package/dist/index.d.mts CHANGED
@@ -6,16 +6,19 @@ declare const EXPOSED_PACKAGES: {
6
6
  readonly 'weapp-vite': {
7
7
  readonly id: "weapp-vite";
8
8
  readonly label: "weapp-vite";
9
+ readonly packageName: "weapp-vite";
9
10
  readonly relativePath: string;
10
11
  };
11
12
  readonly wevu: {
12
13
  readonly id: "wevu";
13
14
  readonly label: "wevu";
15
+ readonly packageName: "wevu";
14
16
  readonly relativePath: string;
15
17
  };
16
18
  readonly 'wevu-compiler': {
17
19
  readonly id: "wevu-compiler";
18
20
  readonly label: "wevu-compiler";
21
+ readonly packageName: "@wevu/compiler";
19
22
  readonly relativePath: string;
20
23
  };
21
24
  };
@@ -26,7 +29,7 @@ declare const DEFAULT_MAX_FILE_CHARS = 80000;
26
29
  declare const DEFAULT_MAX_RESULTS = 200;
27
30
  declare const SKIPPED_DIR_NAMES: Set<string>;
28
31
 
29
- interface ExposedPackageSummary {
32
+ interface ResolvedExposedPackage {
30
33
  id: ExposedPackageId;
31
34
  label: string;
32
35
  packageName: string;
@@ -38,9 +41,14 @@ interface ExposedPackageSummary {
38
41
  readme?: string;
39
42
  changelog?: string;
40
43
  };
44
+ sourceRoot?: string;
45
+ cliPath?: string;
46
+ }
47
+
48
+ interface ExposedPackageSummary extends ResolvedExposedPackage {
41
49
  }
42
50
  declare function loadPackageSummary(workspaceRoot: string, id: ExposedPackageId): Promise<ExposedPackageSummary>;
43
- declare function loadExposedCatalog(workspaceRoot: string): Promise<ExposedPackageSummary[]>;
51
+ declare function loadExposedCatalog(workspaceRoot: string): Promise<ResolvedExposedPackage[]>;
44
52
 
45
53
  interface CommandResult {
46
54
  command: string;
@@ -85,6 +93,25 @@ declare function createWeappViteMcpServer(options?: CreateServerOptions): Promis
85
93
  workspaceRoot: string;
86
94
  }>;
87
95
 
96
+ declare const DEFAULT_MCP_HOST = "127.0.0.1";
97
+ declare const DEFAULT_MCP_PORT = 3088;
98
+ declare const DEFAULT_MCP_ENDPOINT = "/mcp";
99
+ interface StartMcpServerOptions extends CreateServerOptions {
100
+ transport?: 'stdio' | 'streamable-http';
101
+ host?: string;
102
+ port?: number;
103
+ endpoint?: string;
104
+ unref?: boolean;
105
+ quiet?: boolean;
106
+ onReady?: (message: string) => void;
107
+ }
108
+ interface McpServerHandle {
109
+ transport: 'stdio' | 'streamable-http';
110
+ close?: () => Promise<void>;
111
+ }
112
+ declare function startStdioServer(options?: CreateServerOptions): Promise<void>;
113
+ declare function startWeappViteMcpServer(options?: StartMcpServerOptions): Promise<McpServerHandle>;
114
+
88
115
  declare function formatJson(value: unknown): string;
89
116
  declare function normalizeErrorMessage(error: unknown): string;
90
117
  declare function toToolResult(data: unknown, text?: string): {
@@ -108,7 +135,5 @@ declare function resolveWorkspaceRoot(start?: string): string;
108
135
  declare function assertInsideRoot(root: string, targetPath: string): string;
109
136
  declare function resolveSubPath(root: string, relativePath: string): string;
110
137
 
111
- declare function startStdioServer(): Promise<void>;
112
-
113
- export { DEFAULT_MAX_FILE_CHARS, DEFAULT_MAX_OUTPUT_CHARS, DEFAULT_MAX_RESULTS, DEFAULT_TIMEOUT_MS, EXPOSED_PACKAGES, MCP_SERVER_NAME, MCP_SERVER_VERSION, SKIPPED_DIR_NAMES, assertInsideRoot, createWeappViteMcpServer, formatJson, listFilesInDirectory, loadExposedCatalog, loadPackageSummary, normalizeErrorMessage, readFileContent, resolveSubPath, resolveWorkspaceRoot, runCommand, searchTextInDirectory, startStdioServer, toToolError, toToolResult };
114
- export type { CommandResult, CreateServerOptions, ExposedPackageId, ExposedPackageSummary, SearchMatch };
138
+ export { DEFAULT_MAX_FILE_CHARS, DEFAULT_MAX_OUTPUT_CHARS, DEFAULT_MAX_RESULTS, DEFAULT_MCP_ENDPOINT, DEFAULT_MCP_HOST, DEFAULT_MCP_PORT, DEFAULT_TIMEOUT_MS, EXPOSED_PACKAGES, MCP_SERVER_NAME, MCP_SERVER_VERSION, SKIPPED_DIR_NAMES, assertInsideRoot, createWeappViteMcpServer, formatJson, listFilesInDirectory, loadExposedCatalog, loadPackageSummary, normalizeErrorMessage, readFileContent, resolveSubPath, resolveWorkspaceRoot, runCommand, searchTextInDirectory, startStdioServer, startWeappViteMcpServer, toToolError, toToolResult };
139
+ export type { CommandResult, CreateServerOptions, ExposedPackageId, ExposedPackageSummary, McpServerHandle, SearchMatch, StartMcpServerOptions };
package/dist/index.d.ts CHANGED
@@ -6,16 +6,19 @@ declare const EXPOSED_PACKAGES: {
6
6
  readonly 'weapp-vite': {
7
7
  readonly id: "weapp-vite";
8
8
  readonly label: "weapp-vite";
9
+ readonly packageName: "weapp-vite";
9
10
  readonly relativePath: string;
10
11
  };
11
12
  readonly wevu: {
12
13
  readonly id: "wevu";
13
14
  readonly label: "wevu";
15
+ readonly packageName: "wevu";
14
16
  readonly relativePath: string;
15
17
  };
16
18
  readonly 'wevu-compiler': {
17
19
  readonly id: "wevu-compiler";
18
20
  readonly label: "wevu-compiler";
21
+ readonly packageName: "@wevu/compiler";
19
22
  readonly relativePath: string;
20
23
  };
21
24
  };
@@ -26,7 +29,7 @@ declare const DEFAULT_MAX_FILE_CHARS = 80000;
26
29
  declare const DEFAULT_MAX_RESULTS = 200;
27
30
  declare const SKIPPED_DIR_NAMES: Set<string>;
28
31
 
29
- interface ExposedPackageSummary {
32
+ interface ResolvedExposedPackage {
30
33
  id: ExposedPackageId;
31
34
  label: string;
32
35
  packageName: string;
@@ -38,9 +41,14 @@ interface ExposedPackageSummary {
38
41
  readme?: string;
39
42
  changelog?: string;
40
43
  };
44
+ sourceRoot?: string;
45
+ cliPath?: string;
46
+ }
47
+
48
+ interface ExposedPackageSummary extends ResolvedExposedPackage {
41
49
  }
42
50
  declare function loadPackageSummary(workspaceRoot: string, id: ExposedPackageId): Promise<ExposedPackageSummary>;
43
- declare function loadExposedCatalog(workspaceRoot: string): Promise<ExposedPackageSummary[]>;
51
+ declare function loadExposedCatalog(workspaceRoot: string): Promise<ResolvedExposedPackage[]>;
44
52
 
45
53
  interface CommandResult {
46
54
  command: string;
@@ -85,6 +93,25 @@ declare function createWeappViteMcpServer(options?: CreateServerOptions): Promis
85
93
  workspaceRoot: string;
86
94
  }>;
87
95
 
96
+ declare const DEFAULT_MCP_HOST = "127.0.0.1";
97
+ declare const DEFAULT_MCP_PORT = 3088;
98
+ declare const DEFAULT_MCP_ENDPOINT = "/mcp";
99
+ interface StartMcpServerOptions extends CreateServerOptions {
100
+ transport?: 'stdio' | 'streamable-http';
101
+ host?: string;
102
+ port?: number;
103
+ endpoint?: string;
104
+ unref?: boolean;
105
+ quiet?: boolean;
106
+ onReady?: (message: string) => void;
107
+ }
108
+ interface McpServerHandle {
109
+ transport: 'stdio' | 'streamable-http';
110
+ close?: () => Promise<void>;
111
+ }
112
+ declare function startStdioServer(options?: CreateServerOptions): Promise<void>;
113
+ declare function startWeappViteMcpServer(options?: StartMcpServerOptions): Promise<McpServerHandle>;
114
+
88
115
  declare function formatJson(value: unknown): string;
89
116
  declare function normalizeErrorMessage(error: unknown): string;
90
117
  declare function toToolResult(data: unknown, text?: string): {
@@ -108,7 +135,5 @@ declare function resolveWorkspaceRoot(start?: string): string;
108
135
  declare function assertInsideRoot(root: string, targetPath: string): string;
109
136
  declare function resolveSubPath(root: string, relativePath: string): string;
110
137
 
111
- declare function startStdioServer(): Promise<void>;
112
-
113
- export { DEFAULT_MAX_FILE_CHARS, DEFAULT_MAX_OUTPUT_CHARS, DEFAULT_MAX_RESULTS, DEFAULT_TIMEOUT_MS, EXPOSED_PACKAGES, MCP_SERVER_NAME, MCP_SERVER_VERSION, SKIPPED_DIR_NAMES, assertInsideRoot, createWeappViteMcpServer, formatJson, listFilesInDirectory, loadExposedCatalog, loadPackageSummary, normalizeErrorMessage, readFileContent, resolveSubPath, resolveWorkspaceRoot, runCommand, searchTextInDirectory, startStdioServer, toToolError, toToolResult };
114
- export type { CommandResult, CreateServerOptions, ExposedPackageId, ExposedPackageSummary, SearchMatch };
138
+ export { DEFAULT_MAX_FILE_CHARS, DEFAULT_MAX_OUTPUT_CHARS, DEFAULT_MAX_RESULTS, DEFAULT_MCP_ENDPOINT, DEFAULT_MCP_HOST, DEFAULT_MCP_PORT, DEFAULT_TIMEOUT_MS, EXPOSED_PACKAGES, MCP_SERVER_NAME, MCP_SERVER_VERSION, SKIPPED_DIR_NAMES, assertInsideRoot, createWeappViteMcpServer, formatJson, listFilesInDirectory, loadExposedCatalog, loadPackageSummary, normalizeErrorMessage, readFileContent, resolveSubPath, resolveWorkspaceRoot, runCommand, searchTextInDirectory, startStdioServer, startWeappViteMcpServer, toToolError, toToolResult };
139
+ export type { CommandResult, CreateServerOptions, ExposedPackageId, ExposedPackageSummary, McpServerHandle, SearchMatch, StartMcpServerOptions };
package/dist/index.mjs CHANGED
@@ -1,12 +1,16 @@
1
1
  import process from 'node:process';
2
2
  import { fileURLToPath } from 'node:url';
3
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
3
  import fs$1 from 'node:fs/promises';
4
+ import { createRequire } from 'node:module';
5
5
  import path from 'node:path';
6
- import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
7
- import { z } from 'zod';
8
6
  import fs from 'node:fs';
9
7
  import { spawn } from 'node:child_process';
8
+ import { Buffer } from 'node:buffer';
9
+ import http from 'node:http';
10
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
11
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
12
+ import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
13
+ import { z } from 'zod';
10
14
 
11
15
  const MCP_SERVER_NAME = "@weapp-vite/mcp";
12
16
  const MCP_SERVER_VERSION = "2.0.0";
@@ -14,17 +18,20 @@ const EXPOSED_PACKAGES = {
14
18
  "weapp-vite": {
15
19
  id: "weapp-vite",
16
20
  label: "weapp-vite",
21
+ packageName: "weapp-vite",
17
22
  relativePath: path.join("packages", "weapp-vite")
18
23
  },
19
24
  "wevu": {
20
25
  id: "wevu",
21
26
  label: "wevu",
22
- relativePath: path.join("packages", "wevu")
27
+ packageName: "wevu",
28
+ relativePath: path.join("packages-runtime", "wevu")
23
29
  },
24
30
  "wevu-compiler": {
25
31
  id: "wevu-compiler",
26
32
  label: "wevu-compiler",
27
- relativePath: path.join("packages", "wevu-compiler")
33
+ packageName: "@wevu/compiler",
34
+ relativePath: path.join("packages-runtime", "wevu-compiler")
28
35
  }
29
36
  };
30
37
  const DEFAULT_TIMEOUT_MS = 12e4;
@@ -77,10 +84,6 @@ function resolveSubPath(root, relativePath) {
77
84
  return assertInsideRoot(root, path.resolve(root, relativePath));
78
85
  }
79
86
 
80
- async function readJsonFile(filePath) {
81
- const content = await fs$1.readFile(filePath, "utf8");
82
- return JSON.parse(content);
83
- }
84
87
  async function pathExists(filePath) {
85
88
  try {
86
89
  await fs$1.access(filePath);
@@ -89,17 +92,40 @@ async function pathExists(filePath) {
89
92
  return false;
90
93
  }
91
94
  }
92
- async function loadPackageSummary(workspaceRoot, id) {
95
+ async function toWorkspaceRelativePath(workspaceRoot, absolutePath) {
96
+ const [realWorkspaceRoot, realAbsolutePath] = await Promise.all([
97
+ fs$1.realpath(workspaceRoot),
98
+ fs$1.realpath(absolutePath)
99
+ ]);
100
+ const relativePath = path.relative(realWorkspaceRoot, realAbsolutePath);
101
+ if (!relativePath || relativePath === ".") {
102
+ return ".";
103
+ }
104
+ return relativePath;
105
+ }
106
+ async function readPackageJson(filePath) {
107
+ const content = await fs$1.readFile(filePath, "utf8");
108
+ return JSON.parse(content);
109
+ }
110
+ function createWorkspaceRequire(workspaceRoot) {
111
+ return createRequire(path.join(workspaceRoot, "__weapp_vite_mcp__.cjs"));
112
+ }
113
+ async function resolveMonorepoPackage(workspaceRoot, id) {
93
114
  const config = EXPOSED_PACKAGES[id];
94
115
  const absolutePath = assertInsideRoot(workspaceRoot, path.join(workspaceRoot, config.relativePath));
95
116
  const packageJsonPath = path.join(absolutePath, "package.json");
96
- const packageJson = await readJsonFile(packageJsonPath);
117
+ if (!await pathExists(packageJsonPath)) {
118
+ return void 0;
119
+ }
120
+ const packageJson = await readPackageJson(packageJsonPath);
97
121
  const readmePath = path.join(absolutePath, "README.md");
98
122
  const changelogPath = path.join(absolutePath, "CHANGELOG.md");
123
+ const sourceRoot = await pathExists(path.join(absolutePath, "src")) ? absolutePath : void 0;
124
+ const cliPath = id === "weapp-vite" ? await pathExists(path.join(absolutePath, "bin", "weapp-vite.js")) ? path.join(absolutePath, "bin", "weapp-vite.js") : void 0 : void 0;
99
125
  return {
100
126
  id,
101
127
  label: config.label,
102
- packageName: packageJson.name ?? config.label,
128
+ packageName: packageJson.name ?? config.packageName,
103
129
  version: packageJson.version ?? "0.0.0",
104
130
  absolutePath,
105
131
  relativePath: config.relativePath,
@@ -107,14 +133,73 @@ async function loadPackageSummary(workspaceRoot, id) {
107
133
  docs: {
108
134
  readme: await pathExists(readmePath) ? readmePath : void 0,
109
135
  changelog: await pathExists(changelogPath) ? changelogPath : void 0
136
+ },
137
+ sourceRoot,
138
+ cliPath
139
+ };
140
+ }
141
+ async function resolveInstalledPackage(workspaceRoot, id) {
142
+ const config = EXPOSED_PACKAGES[id];
143
+ const workspaceRequire = createWorkspaceRequire(workspaceRoot);
144
+ let packageJsonPath;
145
+ try {
146
+ packageJsonPath = workspaceRequire.resolve(`${config.packageName}/package.json`);
147
+ } catch {
148
+ return void 0;
149
+ }
150
+ const absolutePath = path.dirname(packageJsonPath);
151
+ const relativePath = await toWorkspaceRelativePath(workspaceRoot, absolutePath);
152
+ const packageJson = await readPackageJson(packageJsonPath);
153
+ const docsRoot = path.join(absolutePath, "dist", "docs");
154
+ const installedReadmePath = path.join(docsRoot, "README.md");
155
+ const installedChangelogPath = path.join(docsRoot, "CHANGELOG.md");
156
+ const sourceRoot = await pathExists(path.join(absolutePath, "src")) ? absolutePath : void 0;
157
+ let cliPath;
158
+ if (id === "weapp-vite") {
159
+ const binEntry = typeof packageJson.bin === "string" ? packageJson.bin : packageJson.bin?.["weapp-vite"];
160
+ if (typeof binEntry === "string" && binEntry.trim()) {
161
+ const resolvedCliPath = path.resolve(absolutePath, binEntry);
162
+ if (await pathExists(resolvedCliPath)) {
163
+ cliPath = resolvedCliPath;
164
+ }
110
165
  }
166
+ }
167
+ return {
168
+ id,
169
+ label: config.label,
170
+ packageName: packageJson.name ?? config.packageName,
171
+ version: packageJson.version ?? "0.0.0",
172
+ absolutePath,
173
+ relativePath,
174
+ scripts: Object.keys(packageJson.scripts ?? {}),
175
+ docs: {
176
+ readme: await pathExists(installedReadmePath) ? installedReadmePath : void 0,
177
+ changelog: await pathExists(installedChangelogPath) ? installedChangelogPath : void 0
178
+ },
179
+ sourceRoot,
180
+ cliPath
111
181
  };
112
182
  }
113
- async function loadExposedCatalog(workspaceRoot) {
114
- const summaries = await Promise.all(
115
- Object.keys(EXPOSED_PACKAGES).map((id) => loadPackageSummary(workspaceRoot, id))
183
+ async function resolveExposedPackage(workspaceRoot, id) {
184
+ return await resolveMonorepoPackage(workspaceRoot, id) ?? await resolveInstalledPackage(workspaceRoot, id) ?? Promise.reject(new Error(`\u672A\u627E\u5230\u66B4\u9732\u5305\uFF1A${id}`));
185
+ }
186
+ async function resolveExposedPackages(workspaceRoot) {
187
+ const resolved = await Promise.allSettled(
188
+ Object.keys(EXPOSED_PACKAGES).map((id) => resolveExposedPackage(workspaceRoot, id))
116
189
  );
117
- return summaries.sort((a, b) => a.id.localeCompare(b.id));
190
+ return resolved.flatMap((result) => {
191
+ if (result.status === "fulfilled") {
192
+ return [result.value];
193
+ }
194
+ return [];
195
+ }).sort((a, b) => a.id.localeCompare(b.id));
196
+ }
197
+
198
+ async function loadPackageSummary(workspaceRoot, id) {
199
+ return resolveExposedPackage(workspaceRoot, id);
200
+ }
201
+ async function loadExposedCatalog(workspaceRoot) {
202
+ return resolveExposedPackages(workspaceRoot);
118
203
  }
119
204
 
120
205
  const ALLOWED_COMMANDS = /* @__PURE__ */ new Set([
@@ -315,8 +400,12 @@ function toToolError(error) {
315
400
 
316
401
  const packageIds = Object.keys(EXPOSED_PACKAGES);
317
402
  const packageIdSchema = z.enum(packageIds);
318
- function resolvePackageRoot(workspaceRoot, packageId) {
319
- return assertInsideRoot(workspaceRoot, path.join(workspaceRoot, EXPOSED_PACKAGES[packageId].relativePath));
403
+ async function resolvePackageRoot(workspaceRoot, packageId) {
404
+ const resolved = await resolveExposedPackage(workspaceRoot, packageId);
405
+ if (!resolved.sourceRoot) {
406
+ throw new Error(`\u5F53\u524D\u5DE5\u4F5C\u533A\u4E2D\u7684 ${packageId} \u4E0D\u5305\u542B\u6E90\u7801\u76EE\u5F55\uFF0C\u8BF7\u6539\u4E3A\u4F18\u5148\u8BFB\u53D6\u672C\u5730\u968F\u5305\u6587\u6863\u3002`);
407
+ }
408
+ return assertInsideRoot(workspaceRoot, resolved.sourceRoot);
320
409
  }
321
410
  function toDocsUri(packageId, fileName) {
322
411
  return `weapp-vite://docs/${packageId}/${fileName}`;
@@ -354,7 +443,7 @@ async function createWeappViteMcpServer(options) {
354
443
  }
355
444
  }, async ({ packageId, directory, maxResults }) => {
356
445
  try {
357
- const packageRoot = resolvePackageRoot(workspaceRoot, packageId);
446
+ const packageRoot = await resolvePackageRoot(workspaceRoot, packageId);
358
447
  const files = await listFilesInDirectory(packageRoot, directory ?? "src", maxResults ?? DEFAULT_MAX_RESULTS);
359
448
  return toToolResult({
360
449
  packageId,
@@ -378,7 +467,7 @@ async function createWeappViteMcpServer(options) {
378
467
  }
379
468
  }, async ({ packageId, filePath, startLine, endLine, maxChars }) => {
380
469
  try {
381
- const packageRoot = resolvePackageRoot(workspaceRoot, packageId);
470
+ const packageRoot = await resolvePackageRoot(workspaceRoot, packageId);
382
471
  const { filePath: absolutePath, content } = await readFileContent(packageRoot, filePath, {
383
472
  startLine,
384
473
  endLine,
@@ -414,7 +503,7 @@ async function createWeappViteMcpServer(options) {
414
503
  if (allMatches.length >= safeMax) {
415
504
  break;
416
505
  }
417
- const packageRoot = resolvePackageRoot(workspaceRoot, id);
506
+ const packageRoot = await resolvePackageRoot(workspaceRoot, id);
418
507
  const matches = await searchTextInDirectory(packageRoot, query, {
419
508
  relativeDirectory: directory ?? "src",
420
509
  maxResults: safeMax - allMatches.length
@@ -444,9 +533,9 @@ async function createWeappViteMcpServer(options) {
444
533
  }
445
534
  }, async ({ packageId, script, args, timeoutMs }) => {
446
535
  try {
447
- const cwdRelative = EXPOSED_PACKAGES[packageId].relativePath;
536
+ const resolvedPackage = await resolveExposedPackage(workspaceRoot, packageId);
448
537
  const result = await runCommand(workspaceRoot, "pnpm", ["run", script, ...args ?? []], {
449
- cwdRelative,
538
+ cwdRelative: resolvedPackage.relativePath,
450
539
  timeoutMs: timeoutMs ?? DEFAULT_TIMEOUT_MS
451
540
  });
452
541
  return toToolResult(result);
@@ -466,7 +555,10 @@ async function createWeappViteMcpServer(options) {
466
555
  }
467
556
  }, async ({ subCommand, projectPath, platform, args, timeoutMs }) => {
468
557
  try {
469
- const cliPath = path.join("packages", "weapp-vite", "bin", "weapp-vite.js");
558
+ const cliPath = (await resolveExposedPackage(workspaceRoot, "weapp-vite")).cliPath;
559
+ if (!cliPath) {
560
+ throw new Error("\u5F53\u524D\u5DE5\u4F5C\u533A\u4E2D\u7684 weapp-vite \u672A\u66B4\u9732 CLI \u5165\u53E3");
561
+ }
470
562
  const finalArgs = [cliPath, subCommand];
471
563
  if (projectPath) {
472
564
  finalArgs.push(resolveSubPath(workspaceRoot, projectPath));
@@ -572,7 +664,7 @@ async function createWeappViteMcpServer(options) {
572
664
  }]
573
665
  };
574
666
  });
575
- const catalog = await loadExposedCatalog(workspaceRoot);
667
+ const catalog = await resolveExposedPackages(workspaceRoot);
576
668
  for (const summary of catalog) {
577
669
  if (summary.docs.readme) {
578
670
  const uri = toDocsUri(summary.id, "README.md");
@@ -616,7 +708,7 @@ async function createWeappViteMcpServer(options) {
616
708
  throw new Error(`\u672A\u77E5 package\uFF1A${packageId}`);
617
709
  }
618
710
  const relativePath = decodeURIComponent(String(variables.path ?? ""));
619
- const packageRoot = resolvePackageRoot(workspaceRoot, packageId);
711
+ const packageRoot = await resolvePackageRoot(workspaceRoot, packageId);
620
712
  const { content } = await readFileContent(packageRoot, relativePath, {
621
713
  maxChars: DEFAULT_MAX_FILE_CHARS
622
714
  });
@@ -643,11 +735,158 @@ async function createWeappViteMcpServer(options) {
643
735
  };
644
736
  }
645
737
 
646
- async function startStdioServer() {
647
- const { server } = await createWeappViteMcpServer();
648
- const transport = new StdioServerTransport();
649
- await server.connect(transport);
738
+ const DEFAULT_MCP_HOST = "127.0.0.1";
739
+ const DEFAULT_MCP_PORT = 3088;
740
+ const DEFAULT_MCP_ENDPOINT = "/mcp";
741
+ function normalizeEndpoint(input) {
742
+ const value = typeof input === "string" ? input.trim() : "";
743
+ if (!value) {
744
+ return DEFAULT_MCP_ENDPOINT;
745
+ }
746
+ return value.startsWith("/") ? value : `/${value}`;
747
+ }
748
+ function normalizePort(input) {
749
+ if (typeof input === "number" && Number.isInteger(input) && input > 0 && input <= 65535) {
750
+ return input;
751
+ }
752
+ return DEFAULT_MCP_PORT;
753
+ }
754
+ async function parseJsonBody(req) {
755
+ if (req.method !== "POST") {
756
+ return void 0;
757
+ }
758
+ const chunks = [];
759
+ for await (const chunk of req) {
760
+ chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
761
+ }
762
+ if (chunks.length === 0) {
763
+ return void 0;
764
+ }
765
+ const raw = Buffer.concat(chunks).toString("utf8").trim();
766
+ if (!raw) {
767
+ return void 0;
768
+ }
769
+ return JSON.parse(raw);
770
+ }
771
+ function writeJson(res, statusCode, payload) {
772
+ if (res.headersSent) {
773
+ return;
774
+ }
775
+ res.statusCode = statusCode;
776
+ res.setHeader("content-type", "application/json");
777
+ res.end(JSON.stringify(payload));
778
+ }
779
+ async function startStdioServer$1(options) {
780
+ const previousCwd = process.cwd();
781
+ if (options?.workspaceRoot) {
782
+ process.chdir(options.workspaceRoot);
783
+ }
784
+ try {
785
+ const { server } = await createWeappViteMcpServer(options);
786
+ const transport = new StdioServerTransport();
787
+ await server.connect(transport);
788
+ } finally {
789
+ if (options?.workspaceRoot) {
790
+ process.chdir(previousCwd);
791
+ }
792
+ }
650
793
  }
794
+ async function startStreamableHttpServer(options) {
795
+ const {
796
+ endpoint = DEFAULT_MCP_ENDPOINT,
797
+ host = DEFAULT_MCP_HOST,
798
+ port = DEFAULT_MCP_PORT,
799
+ workspaceRoot,
800
+ unref = false,
801
+ quiet = false,
802
+ onReady
803
+ } = options;
804
+ const normalizedEndpoint = normalizeEndpoint(endpoint);
805
+ const normalizedPort = normalizePort(port);
806
+ const { server: mcpServer } = await createWeappViteMcpServer({ workspaceRoot });
807
+ const transport = new StreamableHTTPServerTransport({
808
+ sessionIdGenerator: void 0
809
+ });
810
+ await mcpServer.connect(transport);
811
+ const httpServer = http.createServer(async (req, res) => {
812
+ try {
813
+ const hostHeader = req.headers.host ?? `${host}:${normalizedPort}`;
814
+ const url = new URL(req.url ?? "/", `http://${hostHeader}`);
815
+ if (url.pathname !== normalizedEndpoint) {
816
+ writeJson(res, 404, {
817
+ jsonrpc: "2.0",
818
+ error: {
819
+ code: -32004,
820
+ message: `Not Found: ${url.pathname}`
821
+ },
822
+ id: null
823
+ });
824
+ return;
825
+ }
826
+ const method = req.method ?? "GET";
827
+ if (!["GET", "POST", "DELETE"].includes(method)) {
828
+ writeJson(res, 405, {
829
+ jsonrpc: "2.0",
830
+ error: {
831
+ code: -32005,
832
+ message: `Method Not Allowed: ${method}`
833
+ },
834
+ id: null
835
+ });
836
+ return;
837
+ }
838
+ const body = await parseJsonBody(req);
839
+ await transport.handleRequest(req, res, body);
840
+ } catch (error) {
841
+ writeJson(res, 500, {
842
+ jsonrpc: "2.0",
843
+ error: {
844
+ code: -32603,
845
+ message: error instanceof Error ? error.message : String(error)
846
+ },
847
+ id: null
848
+ });
849
+ }
850
+ });
851
+ await new Promise((resolve, reject) => {
852
+ httpServer.once("error", reject);
853
+ httpServer.listen(normalizedPort, host, () => {
854
+ resolve();
855
+ });
856
+ });
857
+ if (unref) {
858
+ httpServer.unref();
859
+ }
860
+ if (!quiet) {
861
+ onReady?.(`[mcp] streamable-http ready at http://${host}:${normalizedPort}${normalizedEndpoint}`);
862
+ }
863
+ return {
864
+ transport: "streamable-http",
865
+ close: async () => {
866
+ await transport.close();
867
+ await new Promise((resolve, reject) => {
868
+ httpServer.close((error) => {
869
+ if (error) {
870
+ reject(error);
871
+ return;
872
+ }
873
+ resolve();
874
+ });
875
+ });
876
+ }
877
+ };
878
+ }
879
+ async function startWeappViteMcpServer(options) {
880
+ const transport = options?.transport ?? "stdio";
881
+ if (transport === "streamable-http") {
882
+ return startStreamableHttpServer(options ?? {});
883
+ }
884
+ await startStdioServer$1(options);
885
+ return {
886
+ transport: "stdio"
887
+ };
888
+ }
889
+
651
890
  function isDirectExecution() {
652
891
  const entry = process.argv[1];
653
892
  if (!entry) {
@@ -665,4 +904,4 @@ ${message}
665
904
  });
666
905
  }
667
906
 
668
- export { DEFAULT_MAX_FILE_CHARS, DEFAULT_MAX_OUTPUT_CHARS, DEFAULT_MAX_RESULTS, DEFAULT_TIMEOUT_MS, EXPOSED_PACKAGES, MCP_SERVER_NAME, MCP_SERVER_VERSION, SKIPPED_DIR_NAMES, assertInsideRoot, createWeappViteMcpServer, formatJson, listFilesInDirectory, loadExposedCatalog, loadPackageSummary, normalizeErrorMessage, readFileContent, resolveSubPath, resolveWorkspaceRoot, runCommand, searchTextInDirectory, startStdioServer, toToolError, toToolResult };
907
+ export { DEFAULT_MAX_FILE_CHARS, DEFAULT_MAX_OUTPUT_CHARS, DEFAULT_MAX_RESULTS, DEFAULT_MCP_ENDPOINT, DEFAULT_MCP_HOST, DEFAULT_MCP_PORT, DEFAULT_TIMEOUT_MS, EXPOSED_PACKAGES, MCP_SERVER_NAME, MCP_SERVER_VERSION, SKIPPED_DIR_NAMES, assertInsideRoot, createWeappViteMcpServer, formatJson, listFilesInDirectory, loadExposedCatalog, loadPackageSummary, normalizeErrorMessage, readFileContent, resolveSubPath, resolveWorkspaceRoot, runCommand, searchTextInDirectory, startStdioServer$1 as startStdioServer, startWeappViteMcpServer, toToolError, toToolResult };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@weapp-vite/mcp",
3
3
  "type": "module",
4
- "version": "1.1.0",
4
+ "version": "1.1.2",
5
5
  "description": "mcp",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "ISC",
@@ -31,7 +31,7 @@
31
31
  "node": "^20.19.0 || >=22.12.0"
32
32
  },
33
33
  "dependencies": {
34
- "@modelcontextprotocol/sdk": "^1.27.1",
34
+ "@modelcontextprotocol/sdk": "^1.29.0",
35
35
  "zod": "^4.3.6"
36
36
  },
37
37
  "scripts": {
@@ -40,6 +40,7 @@
40
40
  "build": "unbuild",
41
41
  "test": "vitest run",
42
42
  "test:dev": "vitest",
43
+ "typecheck": "tsc --noEmit",
43
44
  "release": "pnpm publish",
44
45
  "lint": "eslint .",
45
46
  "lint:fix": "eslint . --fix",