@uni-helper/mcp 0.0.1

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/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-PRESENT FliPPeDround <https://github.com/FliPPeDround>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,23 @@
1
+ # [WIP]uniapp MCP plugin
2
+
3
+ ## 安装
4
+
5
+ ```bash
6
+ pnpm add @uni-helper/mcp -D
7
+ ```
8
+
9
+ ## 配置
10
+
11
+ 在 `vite.config.ts` 中添加如下配置:
12
+
13
+ ```ts
14
+ import { defineConfig } from 'vite'
15
+ import uni from '@dcloudio/vite-plugin-uni'
16
+ import mcp from '@uni-helper/mcp'
17
+
18
+ export default defineConfig({
19
+ plugins: [uni(), mcp()],
20
+ })
21
+ ```
22
+
23
+
@@ -0,0 +1,79 @@
1
+ import { Plugin } from "vite";
2
+
3
+ //#region node_modules/.pnpm/@langchain+core@1.1.15_openai@6.16.0_ws@8.19.0_zod@4.3.5_/node_modules/@langchain/core/dist/embeddings.d.cts
4
+ interface EmbeddingsInterface<TOutput = number[]> {
5
+ /**
6
+ * An abstract method that takes an array of documents as input and
7
+ * returns a promise that resolves to an array of vectors for each
8
+ * document.
9
+ * @param documents An array of documents to be embedded.
10
+ * @returns A promise that resolves to an array of vectors for each document.
11
+ */
12
+ embedDocuments(documents: string[]): Promise<TOutput[]>;
13
+ /**
14
+ * An abstract method that takes a single document as input and returns a
15
+ * promise that resolves to a vector for the query document.
16
+ * @param document A single document to be embedded.
17
+ * @returns A promise that resolves to a vector for the query document.
18
+ */
19
+ embedQuery(document: string): Promise<TOutput>;
20
+ }
21
+ /**
22
+ * An abstract class that provides methods for embedding documents and
23
+ * queries using LangChain.
24
+ */
25
+ //#endregion
26
+ //#region src/types.d.ts
27
+ type SupportedUpdateConfigType = 'cursor' | 'vscode' | 'windsurf' | 'claude-code' | 'trae-cn' | 'trae';
28
+ type MaybeArray<T> = T | T[];
29
+ interface UniMcpOptions {
30
+ /**
31
+ * 监听的端口,默认为 Vite 开发服务器的端口
32
+ */
33
+ port?: number;
34
+ /**
35
+ * 在控制台打印 MCP 服务器 URL
36
+ *
37
+ * @default true
38
+ */
39
+ printUrl?: boolean;
40
+ /**
41
+ * 自定义的 Embeddings 模型
42
+ *
43
+ * 内置模型为 Qwen3-Embedding-0.6B-ONNX
44
+ *
45
+ * 如果本地运行效率低,可自定义模型
46
+ * - 确保模型支持 1024 维
47
+ * - 支持 langchain 的 Embeddings 格式
48
+ * @default
49
+ * ```ts
50
+ * new HuggingFaceTransformersEmbeddings({
51
+ * model: 'onnx-community/Qwen3-Embedding-0.6B-ONNX',
52
+ * pretrainedOptions: {
53
+ * dtype: 'int8',
54
+ * device: 'cpu',
55
+ * },
56
+ * })
57
+ * ```
58
+ */
59
+ embeddings?: EmbeddingsInterface;
60
+ /**
61
+ * 要更新的配置类型
62
+ *
63
+ * - `auto` - 如果配置文件存在则自动更新
64
+ * - `cursor` - 更新 Cursor 配置文件 `.cursor/mcp.json`
65
+ * - `vscode` - 更新 VSCode 配置文件 `.vscode/settings.json`
66
+ * - `windsurf` - 更新 Windsurf 配置文件 `~/.codeium/windsurf/mcp_config.json`
67
+ * - `claude-code` - 更新 Claude Code 配置文件 `.mcp.json`
68
+ * - `trae-cn` - 更新 Trae 配置文件 `~/trae CN/mcp.json`
69
+ * - `trae` - 更新 Trae 配置文件 `.trae/mcp.json`
70
+ *
71
+ * @default false
72
+ */
73
+ updateConfig?: 'auto' | false | MaybeArray<SupportedUpdateConfigType>;
74
+ }
75
+ //#endregion
76
+ //#region src/index.d.ts
77
+ declare function uniMcp(options?: UniMcpOptions): Plugin;
78
+ //#endregion
79
+ export { uniMcp as default };
package/dist/index.mjs ADDED
@@ -0,0 +1,411 @@
1
+ import { searchForWorkspaceRoot } from "vite";
2
+ import { serve } from "@hono/node-server";
3
+ import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
4
+ import { Hono } from "hono";
5
+ import { cors } from "hono/cors";
6
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
7
+ import { z } from "zod";
8
+ import { dirname, join } from "node:path";
9
+ import { fileURLToPath } from "node:url";
10
+ import { env } from "@huggingface/transformers";
11
+ import { HuggingFaceTransformersEmbeddings } from "@langchain/community/embeddings/huggingface_transformers";
12
+ import { HNSWLib } from "@langchain/community/vectorstores/hnswlib";
13
+ import fs from "fs-extra";
14
+ import { existsSync } from "node:fs";
15
+ import { homedir } from "node:os";
16
+ import consola from "consola";
17
+ import { Buffer as Buffer$1 } from "node:buffer";
18
+ import open from "open";
19
+
20
+ //#region rolldown:runtime
21
+ var __create = Object.create;
22
+ var __defProp = Object.defineProperty;
23
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
24
+ var __getOwnPropNames = Object.getOwnPropertyNames;
25
+ var __getProtoOf = Object.getPrototypeOf;
26
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
27
+ var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
28
+ var __copyProps = (to, from, except, desc) => {
29
+ if (from && typeof from === "object" || typeof from === "function") {
30
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
31
+ key = keys[i];
32
+ if (!__hasOwnProp.call(to, key) && key !== except) {
33
+ __defProp(to, key, {
34
+ get: ((k) => from[k]).bind(null, key),
35
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
36
+ });
37
+ }
38
+ }
39
+ }
40
+ return to;
41
+ };
42
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
43
+ value: mod,
44
+ enumerable: true
45
+ }) : target, mod));
46
+
47
+ //#endregion
48
+ //#region node_modules/.pnpm/ansis@4.2.0/node_modules/ansis/index.cjs
49
+ var require_ansis = /* @__PURE__ */ __commonJSMin(((exports, module) => {
50
+ let e, t, r, { defineProperty: l, setPrototypeOf: n, create: o, keys: s } = Object, i = "", { round: c, max: a } = Math, p = (e) => {
51
+ let t = /([a-f\d]{3,6})/i.exec(e)?.[1], r = t?.length, l = parseInt(6 ^ r ? 3 ^ r ? "0" : t[0] + t[0] + t[1] + t[1] + t[2] + t[2] : t, 16);
52
+ return [
53
+ l >> 16 & 255,
54
+ l >> 8 & 255,
55
+ 255 & l
56
+ ];
57
+ }, u = (e, t, r) => e ^ t || t ^ r ? 16 + 36 * c(e / 51) + 6 * c(t / 51) + c(r / 51) : 8 > e ? 16 : e > 248 ? 231 : c(24 * (e - 8) / 247) + 232, d = (e) => {
58
+ let t, r, l, n, o;
59
+ return 8 > e ? 30 + e : 16 > e ? e - 8 + 90 : (232 > e ? (o = (e -= 16) % 36, t = (e / 36 | 0) / 5, r = (o / 6 | 0) / 5, l = o % 6 / 5) : t = r = l = (10 * (e - 232) + 8) / 255, n = 2 * a(t, r, l), n ? 30 + (c(l) << 2 | c(r) << 1 | c(t)) + (2 ^ n ? 0 : 60) : 30);
60
+ }, f = (() => {
61
+ let r = (e) => o.some(((t) => e.test(t))), l = globalThis, n = l.process ?? {}, o = n.argv ?? [], i = n.env ?? {}, c = -1;
62
+ try {
63
+ e = "," + s(i).join(",");
64
+ } catch (e) {
65
+ i = {}, c = 0;
66
+ }
67
+ let a$1 = "FORCE_COLOR", p = {
68
+ false: 0,
69
+ 0: 0,
70
+ 1: 1,
71
+ 2: 2,
72
+ 3: 3
73
+ }[i[a$1]] ?? -1, u = a$1 in i && p || r(/^--color=?(true|always)?$/);
74
+ return u && (c = p), ~c || (c = ((r$1, l$1, n$1) => (t = r$1.TERM, {
75
+ "24bit": 3,
76
+ truecolor: 3,
77
+ ansi256: 2,
78
+ ansi: 1
79
+ }[r$1.COLORTERM] || (r$1.CI ? /,GITHUB/.test(e) ? 3 : 1 : l$1 && "dumb" !== t ? n$1 ? 3 : /-256/.test(t) ? 2 : 1 : 0)))(i, !!i.PM2_HOME || i.NEXT_RUNTIME?.includes("edge") || !!n.stdout?.isTTY, "win32" === n.platform)), !p || i.NO_COLOR || r(/^--(no-color|color=(false|never))$/) ? 0 : l.window?.chrome || u && !c ? 3 : c;
80
+ })(), g = {
81
+ open: i,
82
+ close: i
83
+ }, h = 39, b = 49, O = {}, m = ({ p: e }, { open: t, close: l }) => {
84
+ let o = (e$1, ...r) => {
85
+ if (!e$1) {
86
+ if (t && t === l) return t;
87
+ if ((e$1 ?? i) === i) return i;
88
+ }
89
+ let n, s$1 = e$1.raw ? String.raw({ raw: e$1 }, ...r) : i + e$1, c$1 = o.p, a$1 = c$1.o, p = c$1.c;
90
+ if (s$1.includes("\x1B")) for (; c$1; c$1 = c$1.p) {
91
+ let { open: e$2, close: t$1 } = c$1, r$1 = t$1.length, l$1 = i, o$1 = 0;
92
+ if (r$1) for (; ~(n = s$1.indexOf(t$1, o$1)); o$1 = n + r$1) l$1 += s$1.slice(o$1, n) + e$2;
93
+ s$1 = l$1 + s$1.slice(o$1);
94
+ }
95
+ return a$1 + (s$1.includes("\n") ? s$1.replace(/(\r?\n)/g, p + "$1" + a$1) : s$1) + p;
96
+ }, s = t, c = l;
97
+ return e && (s = e.o + t, c = l + e.c), n(o, r), o.p = {
98
+ open: t,
99
+ close: l,
100
+ o: s,
101
+ c,
102
+ p: e
103
+ }, o.open = s, o.close = c, o;
104
+ };
105
+ const w = new function e(t = f) {
106
+ let s = {
107
+ Ansis: e,
108
+ level: t,
109
+ isSupported: () => a$1,
110
+ strip: (e$1) => e$1.replace(/[›][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, i),
111
+ extend(e$1) {
112
+ for (let t$1 in e$1) {
113
+ let r = e$1[t$1], l = (typeof r)[0];
114
+ "s" === l ? (c(t$1, T(...p(r))), c(_(t$1), v(...p(r)))) : c(t$1, r, "f" === l);
115
+ }
116
+ return r = o({}, O), n(s, r), s;
117
+ }
118
+ }, c = (e$1, t$1, r) => {
119
+ O[e$1] = { get() {
120
+ let n = r ? (...e$2) => m(this, t$1(...e$2)) : m(this, t$1);
121
+ return l(this, e$1, { value: n }), n;
122
+ } };
123
+ }, a$1 = t > 0, w = (e$1, t$1) => a$1 ? {
124
+ open: `[${e$1}m`,
125
+ close: `[${t$1}m`
126
+ } : g, y = (e$1) => (t$1) => e$1(...p(t$1)), R = (e$1, t$1) => (r, l, n) => w(`${e$1}8;2;${r};${l};${n}`, t$1), $ = (e$1, t$1) => (r, l, n) => w(((e$2, t$2, r$1) => d(u(e$2, t$2, r$1)))(r, l, n) + e$1, t$1), x = (e$1) => (t$1, r, l) => e$1(u(t$1, r, l)), T = R(3, h), v = R(4, b), C = (e$1) => w("38;5;" + e$1, h), E = (e$1) => w("48;5;" + e$1, b);
127
+ 2 === t ? (T = x(C), v = x(E)) : 1 === t && (T = $(0, h), v = $(10, b), C = (e$1) => w(d(e$1), h), E = (e$1) => w(d(e$1) + 10, b));
128
+ let M, I = {
129
+ fg: C,
130
+ bg: E,
131
+ rgb: T,
132
+ bgRgb: v,
133
+ hex: y(T),
134
+ bgHex: y(v),
135
+ visible: g,
136
+ reset: w(0, 0),
137
+ bold: w(1, 22),
138
+ dim: w(2, 22),
139
+ italic: w(3, 23),
140
+ underline: w(4, 24),
141
+ inverse: w(7, 27),
142
+ hidden: w(8, 28),
143
+ strikethrough: w(9, 29)
144
+ }, _ = (e$1) => "bg" + e$1[0].toUpperCase() + e$1.slice(1), k = "Bright";
145
+ return "black,red,green,yellow,blue,magenta,cyan,white,gray".split(",").map(((e$1, t$1) => {
146
+ M = _(e$1), 8 > t$1 ? (I[e$1 + k] = w(90 + t$1, h), I[M + k] = w(100 + t$1, b)) : t$1 = 60, I[e$1] = w(30 + t$1, h), I[M] = w(40 + t$1, b);
147
+ })), s.extend(I);
148
+ }();
149
+ module.exports = w, w.default = w;
150
+ }));
151
+
152
+ //#endregion
153
+ //#region node_modules/.pnpm/ansis@4.2.0/node_modules/ansis/index.mjs
154
+ var import_ansis = /* @__PURE__ */ __toESM(require_ansis(), 1);
155
+ var ansis_default = import_ansis.default;
156
+ const { Ansis, fg, bg, rgb, bgRgb, hex, bgHex, reset, inverse, hidden, visible, bold, dim, italic, underline, strikethrough, black, red, green, yellow, blue, magenta, cyan, white, gray, redBright, greenBright, yellowBright, blueBright, magentaBright, cyanBright, whiteBright, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bgGray, bgRedBright, bgGreenBright, bgYellowBright, bgBlueBright, bgMagentaBright, bgCyanBright, bgWhiteBright } = import_ansis.default;
157
+
158
+ //#endregion
159
+ //#region src/mcpServer/connect.ts
160
+ function connectServer(server, options) {
161
+ const { port = 2515, printUrl = true } = options;
162
+ const transport = new WebStandardStreamableHTTPServerTransport();
163
+ const app = new Hono();
164
+ app.use("*", cors({
165
+ origin: "*",
166
+ allowMethods: [
167
+ "GET",
168
+ "POST",
169
+ "DELETE",
170
+ "OPTIONS"
171
+ ],
172
+ allowHeaders: [
173
+ "Content-Type",
174
+ "mcp-session-id",
175
+ "Last-Event-ID",
176
+ "mcp-protocol-version"
177
+ ],
178
+ exposeHeaders: ["mcp-session-id", "mcp-protocol-version"]
179
+ }));
180
+ app.all("/mcp", (c) => transport.handleRequest(c.req.raw));
181
+ server.connect(transport).then(() => {
182
+ if (printUrl) console.log(`${ansis_default.cyan` ➜ MCP: `}${ansis_default.gray(`server is running at ${ansis_default.green(`http://localhost:${port}/mcp`)}`)}`);
183
+ serve({
184
+ fetch: app.fetch,
185
+ port
186
+ });
187
+ });
188
+ return `http://localhost:${port}/mcp`;
189
+ }
190
+
191
+ //#endregion
192
+ //#region src/docs/index.ts
193
+ const __dirname = dirname(fileURLToPath(import.meta.url));
194
+ async function loadVectorStore(vectorName, _embeddings) {
195
+ const vectorDirMap = { uniapp: join(__dirname, "../", "vectorStore", "uniapp") };
196
+ env.remoteHost = "https://hf-mirror.com";
197
+ const embeddings = _embeddings ?? new HuggingFaceTransformersEmbeddings({
198
+ model: "onnx-community/Qwen3-Embedding-0.6B-ONNX",
199
+ pretrainedOptions: {
200
+ dtype: "int8",
201
+ device: "cpu"
202
+ }
203
+ });
204
+ return await HNSWLib.load(vectorDirMap[vectorName], embeddings);
205
+ }
206
+
207
+ //#endregion
208
+ //#region package.json
209
+ var version = "0.0.1";
210
+
211
+ //#endregion
212
+ //#region src/mcpServer/projectAnalyzer.ts
213
+ async function readFileIfExists(path) {
214
+ const content = await fs.readFile(path, "utf-8").catch(() => void 0);
215
+ return {
216
+ exists: !!content,
217
+ path,
218
+ content
219
+ };
220
+ }
221
+ async function analyzeProject(rootPath) {
222
+ const [pagesJson, manifestJson] = await Promise.all([readFileIfExists(join(rootPath, "src/pages.json")), readFileIfExists(join(rootPath, "src/manifest.json"))]);
223
+ return {
224
+ pagesJson,
225
+ manifestJson
226
+ };
227
+ }
228
+
229
+ //#endregion
230
+ //#region src/mcpServer/server.ts
231
+ async function createMcpServer(config, options) {
232
+ const server = new McpServer({
233
+ name: "uni",
234
+ version
235
+ });
236
+ server.registerTool("get-vite-config", {
237
+ title: "获取 Vite 配置",
238
+ description: "获取 Vite 配置摘要,包括根目录、解析配置、插件和环境名称。"
239
+ }, () => ({ content: [{
240
+ type: "text",
241
+ text: JSON.stringify({
242
+ root: config.root,
243
+ resolve: config.resolve,
244
+ plugins: config.plugins.map((p) => p.name).filter(Boolean),
245
+ environmentNames: Object.keys(config.environments)
246
+ })
247
+ }] }));
248
+ server.registerTool("search-docs-by-Uniapp-official", {
249
+ title: "搜索 Uniapp 官方文档",
250
+ description: "在 Uniapp 文档知识库中进行搜索,可查找相关信息、代码示例、API参考文档和操作指南。当您需要解答关于Uniapp文档的问题、查找特定文档内容、了解功能运作原理或定位实现细节时,可使用此工具。搜索结果将返回带有标题的上下文相关内容,并附有直达文档页面的链接。",
251
+ inputSchema: { query: z.string().describe("用于搜索内容的查询语句") }
252
+ }, async ({ query }) => {
253
+ return { content: (await (await loadVectorStore("uniapp", options.embeddings)).similaritySearch(query, 3)).map((doc) => ({
254
+ type: "text",
255
+ text: JSON.stringify(doc)
256
+ })) };
257
+ });
258
+ server.registerTool("get-project-overview", {
259
+ title: "获取项目概览",
260
+ description: "返回 Uniapp 项目的 pages.json 和 manifest.json 配置文件。"
261
+ }, async () => {
262
+ const overview = await analyzeProject(config.root);
263
+ return { content: [{
264
+ type: "text",
265
+ text: JSON.stringify(overview, null, 2)
266
+ }] };
267
+ });
268
+ return server;
269
+ }
270
+
271
+ //#endregion
272
+ //#region src/updateConfigs/claude.ts
273
+ async function updateClaudeConfig(root, sseUrl, _options) {
274
+ const mcp = existsSync(join(root, ".mcp.json")) ? JSON.parse(await fs.readFile(join(root, ".mcp.json"), "utf-8") || "{}") : {};
275
+ mcp.mcpServers ||= {};
276
+ mcp.mcpServers.uni = {
277
+ type: "http",
278
+ url: sseUrl
279
+ };
280
+ await fs.writeFile(join(root, ".mcp.json"), `${JSON.stringify(mcp, null, 2)}\n`);
281
+ consola.log(`${CONSOLE_LOG_PREFIX}${ansis_default.gray(`Updated config file ${join(root, ".mcp.json")}`)}`);
282
+ }
283
+
284
+ //#endregion
285
+ //#region src/updateConfigs/cursor.ts
286
+ async function updateCursorConfig(root, sseUrl, _options) {
287
+ await fs.mkdir(join(root, ".cursor"), { recursive: true });
288
+ const mcp = existsSync(join(root, ".cursor/mcp.json")) ? JSON.parse(await fs.readFile(join(root, ".cursor/mcp.json"), "utf-8") || "{}") : {};
289
+ mcp.mcpServers ||= {};
290
+ mcp.mcpServers.uni = { url: sseUrl };
291
+ await fs.writeFile(join(root, ".cursor/mcp.json"), `${JSON.stringify(mcp, null, 2)}\n`);
292
+ consola.log(`${CONSOLE_LOG_PREFIX}${ansis_default.gray(`Updated config file ${join(root, ".cursor/mcp.json")}`)}`);
293
+ }
294
+
295
+ //#endregion
296
+ //#region src/updateConfigs/print.ts
297
+ function mcpServersConfig(sseUrl) {
298
+ const code = ansis_default.rgb(206, 145, 120);
299
+ const purple = ansis_default.rgb(218, 112, 214);
300
+ return `
301
+ ${ansis_default.yellow`{`}
302
+ ${code`"mcpServers"`}${ansis_default.white`:`} ${purple`{`}
303
+ ${code`"uni"`}${ansis_default.white`:`} ${ansis_default.blue`{`}
304
+ ${code`"url"`}${ansis_default.white`:`} ${code`"${sseUrl}"`}
305
+ ${ansis_default.blue`}`}
306
+ ${purple`}`}
307
+ ${ansis_default.yellow`}`}
308
+ `;
309
+ }
310
+
311
+ //#endregion
312
+ //#region src/updateConfigs/trae.ts
313
+ async function updateTraeConfig(sseUrl, _options) {
314
+ await open(`trae://trae.ai-ide/mcp-import?type=http&name=uni&config=${Buffer$1.from(JSON.stringify({ url: sseUrl })).toString("base64")}`);
315
+ consola.log(`${CONSOLE_LOG_PREFIX}${ansis_default.gray(`自动配置了trae链接,请在trae中确认`)}`);
316
+ }
317
+
318
+ //#endregion
319
+ //#region src/updateConfigs/trae-cn.ts
320
+ async function updateTraeCNConfig(sseUrl, _options) {
321
+ await open(`trae-cn://trae.ai-ide/mcp-import?type=http&name=uni&config=${Buffer$1.from(JSON.stringify({ url: sseUrl })).toString("base64")}`);
322
+ consola.log(`${CONSOLE_LOG_PREFIX}${ansis_default.gray(`自动配置了trae-cn链接,请在trae-cn中确认`)}`);
323
+ }
324
+
325
+ //#endregion
326
+ //#region src/updateConfigs/vscode.ts
327
+ async function updateVSCodeConfig(root, sseUrl, _options) {
328
+ await fs.mkdir(join(root, ".vscode"), { recursive: true });
329
+ const mcp = existsSync(join(root, ".vscode/mcp.json")) ? JSON.parse(await fs.readFile(join(root, ".vscode/mcp.json"), "utf-8") || "{}") : {};
330
+ mcp.servers ||= {};
331
+ mcp.servers.uni = {
332
+ type: "http",
333
+ url: sseUrl
334
+ };
335
+ await fs.writeFile(join(root, ".vscode/mcp.json"), `${JSON.stringify(mcp, null, 2)}\n`);
336
+ consola.log(`${CONSOLE_LOG_PREFIX}${ansis_default.gray(`Updated config file ${join(root, ".vscode/mcp.json")}`)}`);
337
+ }
338
+
339
+ //#endregion
340
+ //#region src/updateConfigs/windsurf.ts
341
+ async function updateWindsurfConfig(sseUrl, _options) {
342
+ const windsurfDir = join(homedir(), ".codeium", "windsurf");
343
+ const windsurfConfigPath = join(windsurfDir, "mcp_config.json");
344
+ try {
345
+ await fs.mkdir(windsurfDir, { recursive: true });
346
+ const config = existsSync(windsurfConfigPath) ? JSON.parse(await fs.readFile(windsurfConfigPath, "utf-8").catch(() => "{}") || "{}") : {};
347
+ config.mcpServers ||= {};
348
+ config.mcpServers.uni = { serverUrl: sseUrl };
349
+ await fs.writeFile(windsurfConfigPath, `${JSON.stringify(config, null, 2)}\n`);
350
+ consola.log(`${CONSOLE_LOG_PREFIX}${ansis_default.gray(`Updated config file ${windsurfConfigPath}`)}`);
351
+ } catch (e) {
352
+ consola.error(`${CONSOLE_LOG_PREFIX}${ansis_default.red(`Failed to update ${windsurfConfigPath}`)}${e}`);
353
+ }
354
+ }
355
+
356
+ //#endregion
357
+ //#region src/updateConfigs/index.ts
358
+ const CONSOLE_LOG_PREFIX = ansis_default.cyan.bold`[MCP] `;
359
+ async function updateConfigs(root, sseUrl, options) {
360
+ const { updateConfig = false } = options;
361
+ if (updateConfig === false) {
362
+ consola.log(`${CONSOLE_LOG_PREFIX}请手动配置mcpServers`);
363
+ consola.box(mcpServersConfig(sseUrl));
364
+ }
365
+ const configPromises = (updateConfig === "auto" ? [
366
+ existsSync(join(root, ".cursor")) ? "cursor" : null,
367
+ existsSync(join(root, ".vscode")) ? "vscode" : null,
368
+ existsSync(join(homedir(), ".codeium", "windsurf")) ? "windsurf" : null,
369
+ existsSync(join(root, ".mcp.json")) ? "claude-code" : null,
370
+ existsSync(join(homedir(), ".trae-cn")) ? "trae-cn" : null,
371
+ existsSync(join(homedir(), ".trae")) ? "trae" : null
372
+ ].filter((x) => x !== null) : Array.isArray(updateConfig) ? updateConfig : []).map(async (config) => {
373
+ switch (config) {
374
+ case "cursor":
375
+ await updateCursorConfig(root, sseUrl, options);
376
+ break;
377
+ case "vscode":
378
+ await updateVSCodeConfig(root, sseUrl, options);
379
+ break;
380
+ case "windsurf":
381
+ await updateWindsurfConfig(sseUrl, options);
382
+ break;
383
+ case "claude-code":
384
+ await updateClaudeConfig(root, sseUrl, options);
385
+ break;
386
+ case "trae-cn":
387
+ await updateTraeCNConfig(sseUrl, options);
388
+ break;
389
+ case "trae":
390
+ await updateTraeConfig(sseUrl, options);
391
+ break;
392
+ }
393
+ });
394
+ await Promise.all(configPromises);
395
+ }
396
+
397
+ //#endregion
398
+ //#region src/index.ts
399
+ function uniMcp(options = {}) {
400
+ return {
401
+ name: "uni-mcp",
402
+ enforce: "post",
403
+ async configResolved(config) {
404
+ const url = connectServer(await createMcpServer(config, options), options);
405
+ await updateConfigs(searchForWorkspaceRoot(config.root), url, options);
406
+ }
407
+ };
408
+ }
409
+
410
+ //#endregion
411
+ export { uniMcp as default };
package/package.json ADDED
@@ -0,0 +1,106 @@
1
+ {
2
+ "name": "@uni-helper/mcp",
3
+ "type": "module",
4
+ "version": "0.0.1",
5
+ "packageManager": "pnpm@10.6.2",
6
+ "description": "mcp - uniapp也得有ai开发体验",
7
+ "author": "FliPPeDround <flippedround@qq.com>",
8
+ "license": "MIT",
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "funding": "https://afdian.com/a/flippedround",
13
+ "homepage": "https://github.com/uni-helper/mcp#readme",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/uni-helper/mcp.git"
17
+ },
18
+ "bugs": "https://github.com/uni-helper/mcp/issues",
19
+ "keywords": [
20
+ "uni",
21
+ "uni-app",
22
+ "uni-helper",
23
+ "mcp",
24
+ "miniapp"
25
+ ],
26
+ "sideEffects": false,
27
+ "exports": {
28
+ ".": {
29
+ "import": "./dist/index.mjs"
30
+ },
31
+ "./package.json": "./package.json"
32
+ },
33
+ "main": "./dist/index.mjs",
34
+ "module": "./dist/index.mjs",
35
+ "types": "./dist/index.d.mts",
36
+ "files": [
37
+ "dist",
38
+ "vectorStore"
39
+ ],
40
+ "scripts": {
41
+ "build": "tsdown",
42
+ "dev": "tsdown --watch ./src",
43
+ "lint": "eslint",
44
+ "task": "tsx ./tasks/uniappDocs/index.ts",
45
+ "play": "cd playground && pnpm dev",
46
+ "lint:fix": "eslint --fix",
47
+ "inspect": "mcp-inspector",
48
+ "prepublishOnly": "pnpm build",
49
+ "release": "bumpp",
50
+ "test": "vitest",
51
+ "prepare": "simple-git-hooks",
52
+ "postinstall": "node scripts/download-model.cjs"
53
+ },
54
+ "peerDependencies": {
55
+ "uniapp": "*",
56
+ "vite": ">=3.1.0"
57
+ },
58
+ "dependencies": {
59
+ "@hono/node-server": "^1.19.9",
60
+ "@huggingface/transformers": "^3.8.1",
61
+ "@langchain/community": "^1.1.4",
62
+ "@modelcontextprotocol/sdk": "^1.25.2",
63
+ "consola": "^3.2.3",
64
+ "fs-extra": "^11.3.3",
65
+ "hnswlib-node": "^3.0.0",
66
+ "hono": "^4.11.4",
67
+ "langchain": "^1.2.8",
68
+ "local-pkg": "^1.1.2",
69
+ "open": "^11.0.0",
70
+ "pathe": "^2.0.3",
71
+ "zod": "^4.3.5"
72
+ },
73
+ "devDependencies": {
74
+ "@antfu/eslint-config": "^7.0.1",
75
+ "@antfu/utils": "^9.3.0",
76
+ "@langchain/core": "^1.1.15",
77
+ "@langchain/ollama": "^1.2.0",
78
+ "@langchain/textsplitters": "^1.0.1",
79
+ "@modelcontextprotocol/inspector": "^0.18.0",
80
+ "@types/debug": "^4.1.12",
81
+ "@types/fs-extra": "^11.0.4",
82
+ "@types/node": "^25.0.8",
83
+ "@types/turndown": "^5.0.6",
84
+ "ansis": "^4.2.0",
85
+ "bumpp": "^10.4.0",
86
+ "cheerio": "^1.1.2",
87
+ "debug": "^4.4.3",
88
+ "eslint": "^9.39.2",
89
+ "lint-staged": "^16.2.7",
90
+ "simple-git-hooks": "^2.13.1",
91
+ "tinyexec": "^1.0.2",
92
+ "tsdown": "^0.20.0-beta.3",
93
+ "tsx": "^4.21.0",
94
+ "turndown": "^7.2.2",
95
+ "typescript": "^5.9.3",
96
+ "vite": "^7.3.1",
97
+ "vitest": "^4.0.17",
98
+ "vitest-package-exports": "^1.1.2"
99
+ },
100
+ "simple-git-hooks": {
101
+ "pre-commit": "pnpm i --frozen-lockfile --ignore-scripts --offline && npx lint-staged"
102
+ },
103
+ "lint-staged": {
104
+ "*": "eslint --fix"
105
+ }
106
+ }
@@ -0,0 +1 @@
1
+ {"space":"cosine","numDimensions":1024}