maic-server-fs-mcp 1.0.3 → 1.0.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/README.md CHANGED
@@ -16,6 +16,41 @@
16
16
  | `executeCommand` | 在终端中运行命令(同步执行,最长 30 秒超时) | `command` (string) |
17
17
  | `dispatchTask` | 派发特定任务给下属专家(`CODER` 或 `TESTER`) | `worker` ('CODER' \| 'TESTER'), `taskInstruction` (string) |
18
18
  | `humanReview` | 人工审核插桩,用于人工确认 | `message` (string) |
19
+ | `buildCodebaseIndex` | 扫描并为代码库构建本地向量索引(支持 JS/TS/JSX/TSX) | `dirPath` (string, 默认 `.`) |
20
+ | `searchCodebase` | 语义化检索整个代码库,寻找匹配的代码片段 | `query` (string), `topK` (number, 默认 `3`) |
21
+
22
+ ---
23
+
24
+ ## 🧠 本地代码 RAG 功能说明
25
+
26
+ 为了使用 `buildCodebaseIndex` 和 `searchCodebase`(基于 `text-embedding-004` 模型),您需要在使用前配置 `GEMINI_API_KEY` 环境变量:
27
+
28
+ * **命令行启动时设置**:
29
+ ```bash
30
+ export GEMINI_API_KEY="your-gemini-api-key"
31
+ npx -y --package maic-server-fs-mcp mcp-server-fs
32
+ ```
33
+ * **Cursor 编辑器配置**:
34
+ 在 Cursor 设置 MCP 时,您也可以在 Shell 配置文件(如 `~/.zshrc` 或 `~/.bashrc`)中全局导出 `GEMINI_API_KEY`,这样 Cursor 启动的进程可以读取到该变量。
35
+ * **Claude Desktop 配置文件配置 (`claude_desktop_config.json`)**:
36
+ ```json
37
+ "maic-local-filesystem-mcp": {
38
+ "command": "npx",
39
+ "args": [
40
+ "-y",
41
+ "--package",
42
+ "maic-server-fs-mcp",
43
+ "mcp-server-fs"
44
+ ],
45
+ "env": {
46
+ "GEMINI_API_KEY": "your-gemini-api-key"
47
+ }
48
+ }
49
+ ```
50
+
51
+ ### 工作机制:
52
+ 1. **构建索引**:调用 `buildCodebaseIndex` 时,系统将扫描目录内的所有代码文件并按最长 40 行的窗口进行滑动切片,再通过 Gemini Embeddings API 向量化并保存在项目根目录的 `.rag_cache.json` 中。
53
+ 2. **语义化检索**:调用 `searchCodebase` 时,系统向量化您的查询,计算其与本地缓存中所有代码片段的余弦相似度(Cosine Similarity),并返回相似度最高的 `topK` 个真实代码片段。
19
54
 
20
55
  ---
21
56
 
@@ -0,0 +1,11 @@
1
+ export declare const enum toolsName {
2
+ writeFile = "writeFile",
3
+ readDirectory = "readDirectory",
4
+ readFile = "readFile",
5
+ executeCommand = "executeCommand",
6
+ dispatchTask = "dispatchTask",
7
+ humanReview = "humanReview",
8
+ searchCodebase = "searchCodebase",
9
+ buildCodebaseIndex = "buildCodebaseIndex"
10
+ }
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../const/index.ts"],"names":[],"mappings":"AAAA,0BAAkB,SAAS;IACvB,SAAS,cAAc;IACvB,aAAa,kBAAkB;IAC/B,QAAQ,aAAa;IACrB,cAAc,mBAAmB;IACjC,YAAY,iBAAiB;IAC7B,WAAW,gBAAgB;IAC3B,cAAc,mBAAmB;IACjC,kBAAkB,uBAAuB;CAC5C"}
@@ -0,0 +1,12 @@
1
+ export var toolsName;
2
+ (function (toolsName) {
3
+ toolsName["writeFile"] = "writeFile";
4
+ toolsName["readDirectory"] = "readDirectory";
5
+ toolsName["readFile"] = "readFile";
6
+ toolsName["executeCommand"] = "executeCommand";
7
+ toolsName["dispatchTask"] = "dispatchTask";
8
+ toolsName["humanReview"] = "humanReview";
9
+ toolsName["searchCodebase"] = "searchCodebase";
10
+ toolsName["buildCodebaseIndex"] = "buildCodebaseIndex";
11
+ })(toolsName || (toolsName = {}));
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../const/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAkB,SASjB;AATD,WAAkB,SAAS;IACvB,oCAAuB,CAAA;IACvB,4CAA+B,CAAA;IAC/B,kCAAqB,CAAA;IACrB,8CAAiC,CAAA;IACjC,0CAA6B,CAAA;IAC7B,wCAA2B,CAAA;IAC3B,8CAAiC,CAAA;IACjC,sDAAyC,CAAA;AAC7C,CAAC,EATiB,SAAS,KAAT,SAAS,QAS1B"}
@@ -0,0 +1,120 @@
1
+ import { toolsName } from "../const/index.js";
2
+ export declare const readFileDeclaration: {
3
+ name: toolsName;
4
+ description: string;
5
+ inputSchema: {
6
+ type: string;
7
+ properties: {
8
+ filePath: {
9
+ type: string;
10
+ description: string;
11
+ };
12
+ };
13
+ required: string[];
14
+ };
15
+ };
16
+ export declare const writeFileDeclaration: {
17
+ name: toolsName;
18
+ description: string;
19
+ inputSchema: {
20
+ type: string;
21
+ properties: {
22
+ filePath: {
23
+ type: string;
24
+ description: string;
25
+ };
26
+ content: {
27
+ type: string;
28
+ description: string;
29
+ };
30
+ };
31
+ required: string[];
32
+ };
33
+ };
34
+ export declare const readDirectoryDeclaration: {
35
+ name: toolsName;
36
+ description: string;
37
+ inputSchema: {
38
+ type: string;
39
+ properties: {
40
+ filePath: {
41
+ type: string;
42
+ description: string;
43
+ default: string;
44
+ };
45
+ };
46
+ required: string[];
47
+ };
48
+ };
49
+ export declare const execCommandDeclaration: {
50
+ name: toolsName;
51
+ description: string;
52
+ inputSchema: {
53
+ type: string;
54
+ properties: {
55
+ command: {
56
+ type: string;
57
+ description: string;
58
+ };
59
+ timeoutMs: {
60
+ type: string;
61
+ description: string;
62
+ default: number;
63
+ };
64
+ };
65
+ required: string[];
66
+ };
67
+ };
68
+ export declare const dispatchTaskDeclaration: {
69
+ name: toolsName;
70
+ description: string;
71
+ inputSchema: {
72
+ type: string;
73
+ properties: {
74
+ worker: {
75
+ type: string;
76
+ description: string;
77
+ };
78
+ taskInstruction: {
79
+ type: string;
80
+ description: string;
81
+ };
82
+ };
83
+ required: string[];
84
+ };
85
+ };
86
+ export declare const searchCodebaseDeclaration: {
87
+ name: toolsName;
88
+ description: string;
89
+ inputSchema: {
90
+ type: string;
91
+ properties: {
92
+ query: {
93
+ type: string;
94
+ description: string;
95
+ };
96
+ topK: {
97
+ type: string;
98
+ description: string;
99
+ default: number;
100
+ };
101
+ };
102
+ required: string[];
103
+ };
104
+ };
105
+ export declare const buildCodebaseIndexDeclaration: {
106
+ name: toolsName;
107
+ description: string;
108
+ inputSchema: {
109
+ type: string;
110
+ properties: {
111
+ dirPath: {
112
+ type: string;
113
+ description: string;
114
+ default: string;
115
+ };
116
+ };
117
+ required: never[];
118
+ };
119
+ };
120
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../mcp-declaration/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAC7C,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;CAc/B,CAAA;AACD,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;CAWhC,CAAA;AAED,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;CAepC,CAAA;AAED,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;CAYlC,CAAA;AAED,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;CAiBnC,CAAA;AAGD,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;CAWrC,CAAC;AAGF,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;CAczC,CAAC"}
@@ -0,0 +1,102 @@
1
+ import { toolsName } from "../const/index.js";
2
+ export const readFileDeclaration = {
3
+ name: toolsName.readFile,
4
+ description: "读取指定路径的本地文件内容,允许 AI 查看文件代码或文本。",
5
+ inputSchema: {
6
+ type: "object",
7
+ properties: {
8
+ filePath: {
9
+ type: "string",
10
+ description: "相对或绝对路径,例如 'package.json' 或 'src/index.js'",
11
+ },
12
+ },
13
+ required: ["filePath"],
14
+ },
15
+ };
16
+ export const writeFileDeclaration = {
17
+ name: toolsName.writeFile,
18
+ description: "向指定路径写入或覆盖文件内容,常用于生成/修改代码,允许 AI 修改文件代码或文本。",
19
+ inputSchema: {
20
+ type: "object",
21
+ properties: {
22
+ filePath: { type: "STRING", description: "目标文件路径,相对或绝对路径,例如 'package.json' 或 'src/index.js'" },
23
+ content: { type: "STRING", description: "要写入文件的内容" },
24
+ },
25
+ required: ["filePath", "content"],
26
+ },
27
+ };
28
+ export const readDirectoryDeclaration = {
29
+ name: toolsName.readDirectory,
30
+ description: "列出指定目录下的所有文件和文件夹名称(已自动忽略 node_modules 等大文件夹)。当你不确定项目结构、找不到某个文件在哪里时,必须先调用此工具,辅助 AI 了解项目结构。",
31
+ inputSchema: {
32
+ type: "object",
33
+ properties: {
34
+ filePath: {
35
+ type: "STRING",
36
+ description: "要扫描的目录路径,支持相对路径,绝对路径,(默认当前项目根)",
37
+ default: ".",
38
+ },
39
+ },
40
+ required: ["filePath"],
41
+ },
42
+ };
43
+ export const execCommandDeclaration = {
44
+ name: toolsName.executeCommand,
45
+ description: "在本地终端安全运行 shell 命令(如 npm test, git status, npm run build)。当修改代码后需要验证是否报错,或者需要安装依赖、运行构建时使用此工具。",
46
+ inputSchema: {
47
+ type: "object",
48
+ properties: {
49
+ command: { type: "STRING", description: "要执行的 Shell 命令" },
50
+ timeoutMs: { type: "STRING", description: "命令超时时间(毫秒)", default: 60000 },
51
+ },
52
+ required: ["command"],
53
+ },
54
+ };
55
+ export const dispatchTaskDeclaration = {
56
+ name: toolsName.dispatchTask,
57
+ description: "当需要安排下属专家执行具体工作时调用此工具。每次只能派发一个任务,等下属汇报结果后,再派发下一个。",
58
+ inputSchema: {
59
+ type: "object",
60
+ properties: {
61
+ worker: {
62
+ type: "STRING",
63
+ description: "接收任务的专家。'CODER' 负责读写代码文件;'TESTER' 负责运行终端编译或测试命令。",
64
+ },
65
+ taskInstruction: {
66
+ type: "STRING",
67
+ description: "具体要这个专家执行的详细指令。例如:'帮我查看 src/index.ts 的内容并修复其中的类型 Bug'。",
68
+ },
69
+ },
70
+ required: ["worker", "taskInstruction"],
71
+ },
72
+ };
73
+ // 定义 searchCodebase 的工具格式
74
+ export const searchCodebaseDeclaration = {
75
+ name: toolsName.searchCodebase,
76
+ description: "语义化检索整个本地代码库。当不知道某段功能、组件、路由在哪里时,调用此工具通过关键词或功能描述找出最相关的真实代码片段。",
77
+ inputSchema: {
78
+ type: "object",
79
+ properties: {
80
+ query: { type: "string", description: "搜索词或代码功能描述,例如 'JWT 鉴权拦截器' 或 'Button 组件'" },
81
+ topK: { type: "integer", description: "返回的最相关的代码片段数量,默认为 3", default: 3 }
82
+ },
83
+ required: ["query"]
84
+ }
85
+ };
86
+ // 定义 buildCodebaseIndex 的工具格式
87
+ export const buildCodebaseIndexDeclaration = {
88
+ name: toolsName.buildCodebaseIndex,
89
+ description: "扫描整个本地代码库(js/ts/jsx/tsx文件),调用 Gemini Embedding API 构建/重构本地向量索引。当项目代码发生重大变化后,或者首次使用 searchCodebase 前,必须调用此工具构建索引。",
90
+ inputSchema: {
91
+ type: "object",
92
+ properties: {
93
+ dirPath: {
94
+ type: "string",
95
+ description: "要扫描和索引的根目录路径,支持相对路径,默认当前项目根目录 '.'",
96
+ default: "."
97
+ }
98
+ },
99
+ required: []
100
+ }
101
+ };
102
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../mcp-declaration/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import { GoogleGenAI } from "@google/genai";
2
+ export declare class LocalCodeRagService {
3
+ private ai;
4
+ private vectorStore;
5
+ private cachePath;
6
+ constructor(ai: GoogleGenAI);
7
+ private chunkCode;
8
+ buildIndex(dirPath: string): Promise<{
9
+ content: {
10
+ type: string;
11
+ text: string;
12
+ }[];
13
+ }>;
14
+ private loadIndex;
15
+ search({ query, topK }: {
16
+ query: string;
17
+ topK?: number | undefined;
18
+ }): Promise<{
19
+ content: Array<{
20
+ type: string;
21
+ text: string;
22
+ }>;
23
+ }>;
24
+ }
25
+ export declare const searchCodebaseTool: ({ query, topK }: {
26
+ query: string;
27
+ topK?: number;
28
+ }) => Promise<{
29
+ content: Array<{
30
+ type: string;
31
+ text: string;
32
+ }>;
33
+ } | {
34
+ content: {
35
+ type: string;
36
+ text: string;
37
+ }[];
38
+ isError: boolean;
39
+ }>;
40
+ export declare const buildCodebaseIndexTool: ({ dirPath }: {
41
+ dirPath?: string;
42
+ }) => Promise<{
43
+ content: {
44
+ type: string;
45
+ text: string;
46
+ }[];
47
+ } | {
48
+ content: {
49
+ type: string;
50
+ text: string;
51
+ }[];
52
+ isError: boolean;
53
+ }>;
54
+ //# sourceMappingURL=LocalCodeRagTool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalCodeRagTool.d.ts","sourceRoot":"","sources":["../../mcp-tool/LocalCodeRagTool.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAiB5C,qBAAa,mBAAmB;IAC5B,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,WAAW,CAAmB;IACtC,OAAO,CAAC,SAAS,CAAkD;gBAEvD,EAAE,EAAE,WAAW;IAM3B,OAAO,CAAC,SAAS;IAiBJ,UAAU,CAAC,OAAO,EAAE,MAAM;;;;;;IA2EvC,OAAO,CAAC,SAAS;IAaJ,MAAM,CAAC,EAAE,KAAK,EAAE,IAAQ,EAAE,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;CAmDtJ;AAgBD,eAAO,MAAM,kBAAkB,GAAU,iBAAiB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE;aAnEqB,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;;;;;;;EA+EnJ,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAU,aAAmB;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;EAanF,CAAC"}
@@ -0,0 +1,214 @@
1
+ // RAG 检索增强生成
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+ import { GoogleGenAI } from "@google/genai";
5
+ // 简单实现一个余弦相似度计算
6
+ function cosineSimilarity(vecA, vecB) {
7
+ const dotProduct = vecA.reduce((sum, a, i) => sum + a * (vecB[i] ?? 0), 0);
8
+ const normA = Math.sqrt(vecA.reduce((sum, a) => sum + a * a, 0));
9
+ const normB = Math.sqrt(vecB.reduce((sum, b) => sum + b * b, 0));
10
+ if (normA === 0 || normB === 0)
11
+ return 0;
12
+ return dotProduct / (normA * normB);
13
+ }
14
+ export class LocalCodeRagService {
15
+ ai;
16
+ vectorStore = [];
17
+ cachePath = path.resolve(process.cwd(), ".rag_cache.json");
18
+ constructor(ai) {
19
+ this.ai = ai;
20
+ this.loadIndex();
21
+ }
22
+ // 1. 简单的代码切块逻辑(按行数或者固定字符数切块,保持上下文)
23
+ chunkCode(filePath, content) {
24
+ const lines = content.split("\n");
25
+ const chunks = [];
26
+ const chunkSize = 40; // 每个代码块最多40行
27
+ const overlap = 10; // 允许10行重叠
28
+ for (let i = 0; i < lines.length; i += (chunkSize - overlap)) {
29
+ const chunkLines = lines.slice(i, i + chunkSize);
30
+ if (chunkLines.length > 5) { // 过滤掉太短的碎片
31
+ chunks.push(`// File: ${filePath}\n` + chunkLines.join("\n"));
32
+ }
33
+ if (i + chunkSize >= lines.length)
34
+ break;
35
+ }
36
+ return chunks;
37
+ }
38
+ // 2. 扫描并构建整个 codebase 的向量索引
39
+ async buildIndex(dirPath) {
40
+ console.error(`\n🔍 [RAG Indexing] 开始扫描目录并构建代码向量库: ${dirPath}...`);
41
+ const filesToScan = [];
42
+ const scanDir = (dir) => {
43
+ try {
44
+ const list = fs.readdirSync(dir);
45
+ list.forEach((file) => {
46
+ try {
47
+ const fullPath = path.join(dir, file);
48
+ const stat = fs.statSync(fullPath);
49
+ if (stat.isDirectory()) {
50
+ if (!file.startsWith(".") &&
51
+ file !== "node_modules" &&
52
+ file !== "dist" &&
53
+ file !== "build" &&
54
+ file !== "out" &&
55
+ file !== "coverage") {
56
+ scanDir(fullPath);
57
+ }
58
+ }
59
+ else if (/\.(js|ts|tsx|jsx)$/.test(file)) {
60
+ filesToScan.push(fullPath);
61
+ }
62
+ }
63
+ catch (e) {
64
+ console.error(`⚠️ [RAG Indexing] 读取文件或目录属性失败: ${file}, 错误: ${e instanceof Error ? e.message : e}`);
65
+ }
66
+ });
67
+ }
68
+ catch (e) {
69
+ console.error(`⚠️ [RAG Indexing] 读取目录失败: ${dir}, 错误: ${e instanceof Error ? e.message : e}`);
70
+ }
71
+ };
72
+ scanDir(dirPath);
73
+ const newStore = [];
74
+ for (const filePath of filesToScan) {
75
+ try {
76
+ const content = fs.readFileSync(filePath, "utf-8");
77
+ const chunks = this.chunkCode(path.relative(process.cwd(), filePath), content);
78
+ for (const chunk of chunks) {
79
+ try {
80
+ // 调用 Gemini 官方推荐的 Embedding 模型
81
+ const response = await this.ai.models.embedContent({
82
+ model: "text-embedding-004",
83
+ contents: chunk,
84
+ });
85
+ const embedding = response.embeddings?.[0]?.values;
86
+ if (embedding) {
87
+ newStore.push({ filePath, content: chunk, embedding });
88
+ }
89
+ }
90
+ catch (chunkError) {
91
+ console.error(`⚠️ [RAG Indexing] 向量化代码块失败 (文件: ${filePath}):`, chunkError.message || chunkError);
92
+ }
93
+ }
94
+ }
95
+ catch (fileError) {
96
+ console.error(`⚠️ [RAG Indexing] 读取文件内容失败 ${filePath}:`, fileError.message || fileError);
97
+ }
98
+ }
99
+ this.vectorStore = newStore;
100
+ fs.writeFileSync(this.cachePath, JSON.stringify(this.vectorStore, null, 2), "utf-8");
101
+ console.error(`✨ [RAG Indexing] 向量库构建完毕!共切分并向量化 ${this.vectorStore.length} 个代码块。`);
102
+ return {
103
+ content: [
104
+ {
105
+ type: "text",
106
+ text: `✅ 向量库构建完毕!共扫描并向量化 ${this.vectorStore.length} 个代码块。缓存已保存至: ${this.cachePath}`
107
+ }
108
+ ]
109
+ };
110
+ }
111
+ loadIndex() {
112
+ try {
113
+ if (fs.existsSync(this.cachePath)) {
114
+ this.vectorStore = JSON.parse(fs.readFileSync(this.cachePath, "utf-8"));
115
+ console.error(`📊 [RAG] 成功从本地缓存加载了 ${this.vectorStore.length} 条代码向量。`);
116
+ }
117
+ }
118
+ catch (error) {
119
+ console.error(`⚠️ [RAG] 加载本地缓存向量索引失败,初始化为空向量库:`, error.message || error);
120
+ this.vectorStore = [];
121
+ }
122
+ }
123
+ // 3. 向量检索核心
124
+ async search({ query, topK = 3 }) {
125
+ if (this.vectorStore.length === 0) {
126
+ return {
127
+ content: [
128
+ { type: "text", text: "⚠️ 警告:本地 RAG 向量库为空,请先运行 buildCodebaseIndex 工具构建索引。" }
129
+ ]
130
+ };
131
+ }
132
+ // 将用户的提问向量化
133
+ let queryEmbedding;
134
+ try {
135
+ const response = await this.ai.models.embedContent({
136
+ model: "text-embedding-004",
137
+ contents: query,
138
+ });
139
+ queryEmbedding = response.embeddings?.[0]?.values;
140
+ }
141
+ catch (error) {
142
+ return {
143
+ content: [
144
+ { type: "text", text: `❌ 错误:生成查询向量失败。原因: ${error.message}` }
145
+ ]
146
+ };
147
+ }
148
+ if (!queryEmbedding) {
149
+ return {
150
+ content: [
151
+ { type: "text", text: "❌ 错误:未能获取到有效的查询向量。" }
152
+ ]
153
+ };
154
+ }
155
+ // 计算相似度并排序
156
+ const results = this.vectorStore
157
+ .map((chunk) => ({
158
+ content: chunk.content,
159
+ similarity: cosineSimilarity(queryEmbedding, chunk.embedding),
160
+ }))
161
+ .sort((a, b) => b.similarity - a.similarity)
162
+ .slice(0, topK);
163
+ return {
164
+ content: [
165
+ {
166
+ type: "text",
167
+ text: results.map((r) => `[相似度: ${r.similarity.toFixed(4)}]\n${r.content}`).join("\n\n---\n\n"),
168
+ }
169
+ ]
170
+ };
171
+ }
172
+ }
173
+ let serviceInstance = null;
174
+ function getRagService() {
175
+ if (!serviceInstance) {
176
+ const apiKey = process.env.GEMINI_API_KEY;
177
+ if (!apiKey) {
178
+ throw new Error("未检测到环境变量 GEMINI_API_KEY,无法使用 RAG 搜索/索引功能。请在启动前设置此环境变量。");
179
+ }
180
+ const ai = new GoogleGenAI({ apiKey });
181
+ serviceInstance = new LocalCodeRagService(ai);
182
+ }
183
+ return serviceInstance;
184
+ }
185
+ export const searchCodebaseTool = async ({ query, topK }) => {
186
+ try {
187
+ const service = getRagService();
188
+ return await service.search({ query, ...(topK !== undefined ? { topK } : {}) });
189
+ }
190
+ catch (error) {
191
+ return {
192
+ content: [
193
+ { type: "text", text: `❌ 搜索代码库出错: ${error.message}` }
194
+ ],
195
+ isError: true
196
+ };
197
+ }
198
+ };
199
+ export const buildCodebaseIndexTool = async ({ dirPath = "." }) => {
200
+ try {
201
+ const service = getRagService();
202
+ const resolvedPath = path.resolve(process.cwd(), dirPath);
203
+ return await service.buildIndex(resolvedPath);
204
+ }
205
+ catch (error) {
206
+ return {
207
+ content: [
208
+ { type: "text", text: `❌ 构建向量库出错: ${error.message}` }
209
+ ],
210
+ isError: true
211
+ };
212
+ }
213
+ };
214
+ //# sourceMappingURL=LocalCodeRagTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalCodeRagTool.js","sourceRoot":"","sources":["../../mcp-tool/LocalCodeRagTool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ import { toolsName } from "../const/index.js";
2
+ export declare const humanReviewTool: {
3
+ name: toolsName;
4
+ description: string;
5
+ parameters: {
6
+ type: string;
7
+ properties: {
8
+ message: {
9
+ type: string;
10
+ description: string;
11
+ };
12
+ };
13
+ required: string[];
14
+ };
15
+ };
16
+ export declare const readfileTool: ({ filePath }: {
17
+ filePath: string;
18
+ }) => {
19
+ content: {
20
+ type: string;
21
+ text: string;
22
+ }[];
23
+ isError: boolean;
24
+ } | {
25
+ content: {
26
+ type: string;
27
+ text: string;
28
+ }[];
29
+ isError?: never;
30
+ };
31
+ export declare const writefileTool: ({ filePath, content, }: {
32
+ filePath: string;
33
+ content: string;
34
+ }) => {
35
+ content: {
36
+ type: string;
37
+ text: string;
38
+ }[];
39
+ isError?: never;
40
+ } | {
41
+ content: {
42
+ type: string;
43
+ text: string;
44
+ }[];
45
+ isError: boolean;
46
+ };
47
+ export declare const readDirectoryTool: ({ dirPath }: {
48
+ dirPath?: string;
49
+ }) => string | {
50
+ content: {
51
+ type: string;
52
+ text: string;
53
+ }[];
54
+ isError?: never;
55
+ } | {
56
+ content: {
57
+ type: string;
58
+ text: string;
59
+ }[];
60
+ isError: boolean;
61
+ };
62
+ export declare const execCommandTool: ({ command }: {
63
+ command: string;
64
+ }) => {
65
+ content: {
66
+ type: string;
67
+ text: string;
68
+ }[];
69
+ isError?: never;
70
+ } | {
71
+ content: {
72
+ type: string;
73
+ text: string;
74
+ }[];
75
+ isError: boolean;
76
+ };
77
+ export declare const toolMap: Map<string, Function>;
78
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../mcp-tool/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAK9C,eAAO,MAAM,eAAe;;;;;;;;;;;;;CAa3B,CAAC;AAGF,eAAO,MAAM,YAAY,GAAI,cAAc;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;CAuB9D,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,wBAG3B;IACC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACnB;;;;;;;;;;;;CAyBA,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,aAAmB;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;CAmCxE,CAAC;AAGF,eAAO,MAAM,eAAe,GAAI,aAAa;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;CAsB/D,CAAC;AAEF,eAAO,MAAM,OAAO,uBAOlB,CAAA"}
@@ -0,0 +1,139 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import { execSync } from "child_process";
4
+ import { toolsName } from "../const/index.js";
5
+ import { searchCodebaseTool, buildCodebaseIndexTool } from "./LocalCodeRagTool.js";
6
+ // 定义人类审阅工具(无实际执行逻辑,仅用于触发对话)
7
+ export const humanReviewTool = {
8
+ name: toolsName.humanReview,
9
+ description: "需要人工审核或确认时调用。",
10
+ parameters: {
11
+ type: "object",
12
+ properties: {
13
+ message: {
14
+ type: "string",
15
+ description: "给人类的留言或请求确认的内容。",
16
+ }
17
+ },
18
+ required: ["message"]
19
+ }
20
+ };
21
+ export const readfileTool = ({ filePath }) => {
22
+ try {
23
+ const fullPath = path.resolve(process.cwd(), filePath);
24
+ if (!fs.existsSync(fullPath)) {
25
+ return {
26
+ content: [
27
+ { type: "text", text: `Error: File ${fullPath} does not exist.` },
28
+ ],
29
+ isError: true,
30
+ };
31
+ }
32
+ const fileContent = fs.readFileSync(fullPath, "utf-8");
33
+ return {
34
+ content: [{ type: "text", text: fileContent }],
35
+ };
36
+ }
37
+ catch (error) {
38
+ return {
39
+ content: [
40
+ { type: "text", text: `Error reading file: ${error.message}` },
41
+ ],
42
+ isError: true,
43
+ };
44
+ }
45
+ };
46
+ export const writefileTool = ({ filePath, content, }) => {
47
+ try {
48
+ const fullPath = path.resolve(process.cwd(), filePath);
49
+ // 确保目标文件的父级文件夹存在(可选,防错)
50
+ const dir = path.dirname(fullPath);
51
+ if (!fs.existsSync(dir)) {
52
+ fs.mkdirSync(dir, { recursive: true });
53
+ }
54
+ fs.writeFileSync(fullPath, content, "utf-8");
55
+ return {
56
+ content: [
57
+ { type: 'text', text: `✅ Successfully wrote ${content.length} characters to: ${fullPath}` }
58
+ ],
59
+ };
60
+ }
61
+ catch (error) {
62
+ return {
63
+ content: [
64
+ {
65
+ type: 'text',
66
+ text: `❌ Error writing file: ${error.message}`
67
+ }
68
+ ],
69
+ isError: true,
70
+ };
71
+ }
72
+ };
73
+ export const readDirectoryTool = ({ dirPath = "." }) => {
74
+ try {
75
+ const fullPath = path.resolve(process.cwd(), dirPath);
76
+ if (!fs.existsSync(fullPath)) {
77
+ return `❌ Error: Directory ${fullPath} does not exist.`;
78
+ }
79
+ // 读取当前目录下的所有文件和文件夹
80
+ const files = fs.readdirSync(fullPath, { withFileTypes: true });
81
+ // 过滤掉不必要的庞大文件夹(如 node_modules, .git),否则数据太多会干扰 AI
82
+ const ignoredDirs = ["node_modules", ".git", ".next", "dist"];
83
+ const resultList = files
84
+ .filter((file) => !ignoredDirs.includes(file.name))
85
+ .map((file) => {
86
+ return `${file.isDirectory() ? "📁" : "📄"} ${file.name}`;
87
+ });
88
+ return {
89
+ content: [
90
+ { type: 'text', text: `📁 Current Directory: ${dirPath}\n` + resultList.join("\n") }
91
+ ],
92
+ };
93
+ }
94
+ catch (error) {
95
+ return {
96
+ content: [
97
+ {
98
+ type: 'text',
99
+ text: `❌ Error reading directory: ${error.message}`
100
+ }
101
+ ],
102
+ isError: true,
103
+ };
104
+ }
105
+ };
106
+ // 修复工具函数:执行命令行指令
107
+ export const execCommandTool = ({ command }) => {
108
+ try {
109
+ console.error(`\n⚠️ [⚠️安全警告] Agent 正在本地终端执行命令: ${command}`);
110
+ // 在当前目录下同步执行命令,并捕获标准输出
111
+ const output = execSync(command, { encoding: "utf-8", timeout: 30000 });
112
+ return {
113
+ content: [
114
+ { type: 'text', text: `ℹ️ Command Executed Successfully. Output:\n${output}` }
115
+ ],
116
+ };
117
+ }
118
+ catch (error) {
119
+ // 如果命令报错(比如编译挂了),把报错信息完整吐给 AI,AI 会根据报错自己修 Bug!
120
+ return {
121
+ content: [
122
+ {
123
+ type: 'text',
124
+ text: `❌ Command Failed with Error:\n${error.stdout || error.message}`
125
+ }
126
+ ],
127
+ isError: true,
128
+ };
129
+ }
130
+ };
131
+ export const toolMap = new Map([
132
+ [toolsName.readFile, readfileTool],
133
+ [toolsName.writeFile, writefileTool],
134
+ [toolsName.readDirectory, readDirectoryTool],
135
+ [toolsName.executeCommand, execCommandTool],
136
+ [toolsName.searchCodebase, searchCodebaseTool],
137
+ [toolsName.buildCodebaseIndex, buildCodebaseIndexTool]
138
+ ]);
139
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../mcp-tool/index.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts CHANGED
@@ -1,78 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { toolsName } from "./const.js";
3
- export declare const humanReviewTool: {
4
- name: toolsName;
5
- description: string;
6
- parameters: {
7
- type: string;
8
- properties: {
9
- message: {
10
- type: string;
11
- description: string;
12
- };
13
- };
14
- required: string[];
15
- };
16
- };
17
- export declare const readfileTool: ({ filePath }: {
18
- filePath: string;
19
- }) => {
20
- content: {
21
- type: string;
22
- text: string;
23
- }[];
24
- isError: boolean;
25
- } | {
26
- content: {
27
- type: string;
28
- text: string;
29
- }[];
30
- isError?: never;
31
- };
32
- export declare const writefileTool: ({ filePath, content, }: {
33
- filePath: string;
34
- content: string;
35
- }) => {
36
- content: {
37
- type: string;
38
- text: string;
39
- }[];
40
- isError?: never;
41
- } | {
42
- content: {
43
- type: string;
44
- text: string;
45
- }[];
46
- isError: boolean;
47
- };
48
- export declare const readDirectoryTool: ({ dirPath }: {
49
- dirPath?: string;
50
- }) => string | {
51
- content: {
52
- type: string;
53
- text: string;
54
- }[];
55
- isError?: never;
56
- } | {
57
- content: {
58
- type: string;
59
- text: string;
60
- }[];
61
- isError: boolean;
62
- };
63
- export declare const execCommandTool: ({ command }: {
64
- command: string;
65
- }) => {
66
- content: {
67
- type: string;
68
- text: string;
69
- }[];
70
- isError?: never;
71
- } | {
72
- content: {
73
- type: string;
74
- text: string;
75
- }[];
76
- isError: boolean;
77
- };
2
+ export {};
78
3
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../server.ts"],"names":[],"mappings":";AAYA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA0GvC,eAAO,MAAM,eAAe;;;;;;;;;;;;;CAa3B,CAAC;AAGF,eAAO,MAAM,YAAY,GAAI,cAAc;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;CAuB9D,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,wBAG3B;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;;;;;;;;;;;;CAyBA,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,aAAmB;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;CAmCxE,CAAC;AAGF,eAAO,MAAM,eAAe,GAAI,aAAa;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;CAsB/D,CAAC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../server.ts"],"names":[],"mappings":""}
package/dist/server.js CHANGED
@@ -2,10 +2,8 @@
2
2
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
4
  import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
5
- import * as fs from "fs";
6
- import * as path from "path";
7
- import { execSync } from "child_process";
8
- import { toolsName } from "./const.js";
5
+ import { toolMap } from "./mcp-tool/index.js";
6
+ import { readFileDeclaration, writeFileDeclaration, readDirectoryDeclaration, execCommandDeclaration, dispatchTaskDeclaration, searchCodebaseDeclaration, buildCodebaseIndexDeclaration } from "./mcp-declaration/index.js";
9
7
  // 1. 初始化 MCP 服务端实例,声明你的服务名称和版本
10
8
  const server = new Server({
11
9
  name: "maic-local-filesystem-mcp",
@@ -19,218 +17,16 @@ const server = new Server({
19
17
  server.setRequestHandler(ListToolsRequestSchema, async () => {
20
18
  return {
21
19
  tools: [
22
- {
23
- name: toolsName.readFile,
24
- description: "读取指定路径的本地文件内容,允许 AI 查看文件代码或文本。",
25
- inputSchema: {
26
- type: "object",
27
- properties: {
28
- filePath: {
29
- type: "string",
30
- description: "相对或绝对路径,例如 'package.json' 或 'src/index.js'",
31
- },
32
- },
33
- required: ["filePath"],
34
- },
35
- },
36
- {
37
- name: toolsName.writeFile,
38
- description: "写入指定路径的本地文件内容,允许 AI 修改文件代码或文本。",
39
- inputSchema: {
40
- type: "object",
41
- properties: {
42
- filePath: {
43
- type: "STRING",
44
- description: "相对或绝对路径,例如 'package.json' 或 'src/index.js'",
45
- },
46
- content: {
47
- type: "STRING",
48
- description: "要写入文件的内容",
49
- },
50
- },
51
- required: ["filePath", "content"],
52
- },
53
- },
54
- {
55
- name: toolsName.readDirectory,
56
- description: "列出指定目录下的所有文件和文件夹名称(已自动忽略 node_modules 等大文件夹)。当你不确定项目结构、找不到某个文件在哪里时,必须先调用此工具。",
57
- inputSchema: {
58
- type: "object",
59
- properties: {
60
- filePath: {
61
- type: "STRING",
62
- description: "要查询的目录路径,默认是当前根目录 '.',或者例如 'src/components'",
63
- },
64
- },
65
- required: ['filePath']
66
- }
67
- },
68
- {
69
- name: toolsName.executeCommand,
70
- description: "在本地终端安全运行 shell 命令(如 npm test, git status, npm run build)。当修改代码后需要验证是否报错,或者需要安装依赖、运行构建时使用此工具。",
71
- inputSchema: {
72
- type: "object",
73
- properties: {
74
- command: {
75
- type: "STRING",
76
- description: "需要执行的完整命令,例如 'npm run build' 或 'node test.js'",
77
- },
78
- },
79
- required: ["command"],
80
- }
81
- },
82
- {
83
- name: toolsName.dispatchTask,
84
- description: "当需要安排下属专家执行具体工作时调用此工具。每次只能派发一个任务,等下属汇报结果后,再派发下一个。",
85
- inputSchema: {
86
- type: "object",
87
- properties: {
88
- worker: {
89
- type: "STRING",
90
- description: "接收任务的专家。'CODER' 负责读写代码文件;'TESTER' 负责运行终端编译或测试命令。",
91
- },
92
- taskInstruction: {
93
- type: "STRING",
94
- description: "具体要这个专家执行的详细指令。例如:'帮我查看 src/index.ts 的内容并修复其中的类型 Bug'。",
95
- },
96
- },
97
- required: ["worker", "taskInstruction"]
98
- }
99
- }
20
+ readFileDeclaration,
21
+ writeFileDeclaration,
22
+ readDirectoryDeclaration,
23
+ execCommandDeclaration,
24
+ dispatchTaskDeclaration,
25
+ searchCodebaseDeclaration,
26
+ buildCodebaseIndexDeclaration
100
27
  ],
101
28
  };
102
29
  });
103
- // 定义人类审阅工具(无实际执行逻辑,仅用于触发对话)
104
- export const humanReviewTool = {
105
- name: toolsName.humanReview,
106
- description: "需要人工审核或确认时调用。",
107
- parameters: {
108
- type: "object",
109
- properties: {
110
- message: {
111
- type: "string",
112
- description: "给人类的留言或请求确认的内容。",
113
- }
114
- },
115
- required: ["message"]
116
- }
117
- };
118
- export const readfileTool = ({ filePath }) => {
119
- try {
120
- const fullPath = path.resolve(process.cwd(), filePath);
121
- if (!fs.existsSync(fullPath)) {
122
- return {
123
- content: [
124
- { type: "text", text: `Error: File ${fullPath} does not exist.` },
125
- ],
126
- isError: true,
127
- };
128
- }
129
- const fileContent = fs.readFileSync(fullPath, "utf-8");
130
- return {
131
- content: [{ type: "text", text: fileContent }],
132
- };
133
- }
134
- catch (error) {
135
- return {
136
- content: [
137
- { type: "text", text: `Error reading file: ${error.message}` },
138
- ],
139
- isError: true,
140
- };
141
- }
142
- };
143
- export const writefileTool = ({ filePath, content, }) => {
144
- try {
145
- const fullPath = path.resolve(process.cwd(), filePath);
146
- // 确保目标文件的父级文件夹存在(可选,防错)
147
- const dir = path.dirname(fullPath);
148
- if (!fs.existsSync(dir)) {
149
- fs.mkdirSync(dir, { recursive: true });
150
- }
151
- fs.writeFileSync(fullPath, content, "utf-8");
152
- return {
153
- content: [
154
- { type: 'text', text: `✅ Successfully wrote ${content.length} characters to: ${fullPath}` }
155
- ],
156
- };
157
- }
158
- catch (error) {
159
- return {
160
- content: [
161
- {
162
- type: 'text',
163
- text: `❌ Error writing file: ${error.message}`
164
- }
165
- ],
166
- isError: true,
167
- };
168
- }
169
- };
170
- export const readDirectoryTool = ({ dirPath = "." }) => {
171
- try {
172
- const fullPath = path.resolve(process.cwd(), dirPath);
173
- if (!fs.existsSync(fullPath)) {
174
- return `❌ Error: Directory ${fullPath} does not exist.`;
175
- }
176
- // 读取当前目录下的所有文件和文件夹
177
- const files = fs.readdirSync(fullPath, { withFileTypes: true });
178
- // 过滤掉不必要的庞大文件夹(如 node_modules, .git),否则数据太多会干扰 AI
179
- const ignoredDirs = ["node_modules", ".git", ".next", "dist"];
180
- const resultList = files
181
- .filter((file) => !ignoredDirs.includes(file.name))
182
- .map((file) => {
183
- return `${file.isDirectory() ? "📁" : "📄"} ${file.name}`;
184
- });
185
- return {
186
- content: [
187
- { type: 'text', text: `📁 Current Directory: ${dirPath}\n` + resultList.join("\n") }
188
- ],
189
- };
190
- }
191
- catch (error) {
192
- return {
193
- content: [
194
- {
195
- type: 'text',
196
- text: `❌ Error reading directory: ${error.message}`
197
- }
198
- ],
199
- isError: true,
200
- };
201
- }
202
- };
203
- // 修复工具函数:执行命令行指令
204
- export const execCommandTool = ({ command }) => {
205
- try {
206
- console.log(`\n⚠️ [⚠️安全警告] Agent 正在本地终端执行命令: ${command}`);
207
- // 在当前目录下同步执行命令,并捕获标准输出
208
- const output = execSync(command, { encoding: "utf-8", timeout: 30000 });
209
- return {
210
- content: [
211
- { type: 'text', text: `ℹ️ Command Executed Successfully. Output:\n${output}` }
212
- ],
213
- };
214
- }
215
- catch (error) {
216
- // 如果命令报错(比如编译挂了),把报错信息完整吐给 AI,AI 会根据报错自己修 Bug!
217
- return {
218
- content: [
219
- {
220
- type: 'text',
221
- text: `❌ Command Failed with Error:\n${error.stdout || error.message}`
222
- }
223
- ],
224
- isError: true,
225
- };
226
- }
227
- };
228
- const toolMap = new Map([
229
- [toolsName.readFile, readfileTool],
230
- [toolsName.writeFile, writefileTool],
231
- [toolsName.readDirectory, readDirectoryTool],
232
- [toolsName.executeCommand, execCommandTool],
233
- ]);
234
30
  // 3. 注册工具执行核心:当 AI 真正要调用工具时,执行你原本的 Node.js 物理逻辑
235
31
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
236
32
  const { name, arguments: args } = request.params;
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../server.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EACvB,yBAAyB,EACzB,6BAA6B,EAC9B,MAAM,4BAA4B,CAAA;AAEnC,+BAA+B;AAC/B,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;IACE,IAAI,EAAE,2BAA2B;IACjC,OAAO,EAAE,OAAO;CACjB,EACD;IACE,YAAY,EAAE;QACZ,KAAK,EAAE,EAAE,EAAE,iCAAiC;KAC7C;CACF,CACF,CAAC;AAEF,6DAA6D;AAC7D,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;IAC1D,OAAO;QACL,KAAK,EAAE;YACL,mBAAmB;YACnB,oBAAoB;YACpB,wBAAwB;YACxB,sBAAsB;YACtB,uBAAuB;YACvB,yBAAyB;YACzB,6BAA6B;SAC9B;KACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAIH,gDAAgD;AAChD,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAChE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAEjD,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC7B,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IACnC,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,mCAAmC;AACnC,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAC/C,iFAAiF;AACnF,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;IACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "maic-server-fs-mcp",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "一个用于读取本地文件的自定义标准 MCP 服务端",
5
5
  "main": "./dist/server.js",
6
6
  "bin": {
@@ -33,6 +33,7 @@
33
33
  "homepage": "https://github.com/maicFir/server-fs-mcp#readme",
34
34
  "type": "module",
35
35
  "dependencies": {
36
+ "@google/genai": "^2.9.0",
36
37
  "@modelcontextprotocol/sdk": "^1.29.0"
37
38
  },
38
39
  "devDependencies": {