@autobest-ui/agent 1.0.1 → 1.0.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.
@@ -5,7 +5,8 @@
5
5
 
6
6
  export const nodesTool = {
7
7
  name: 'figma_get_nodes',
8
- description: 'Get detailed information about specific Figma nodes by their IDs. Returns node properties including type, position, size, fills, strokes, auto-layout (including layoutWrap and counterAxisSpacing), clipsContent, node-level boundVariables, explicitVariableModes, and more.',
8
+ description:
9
+ 'Get detailed information about specific Figma nodes by their IDs. Returns node properties including type, position, size, fills, strokes, auto-layout (including layoutWrap and counterAxisSpacing), clipsContent, node-level boundVariables, explicitVariableModes, and more.',
9
10
  inputSchema: {
10
11
  type: 'object',
11
12
  properties: {
@@ -22,15 +23,21 @@ export const nodesTool = {
22
23
  export async function handleGetNodes(bridge, args) {
23
24
  if (!bridge.isConnected()) {
24
25
  return {
25
- content: [{
26
- type: 'text',
27
- text: JSON.stringify({
28
- error: {
29
- code: 'NOT_CONNECTED',
30
- message: 'Figma plugin is not connected. Please open Figma and run the Autobest Figma Plugin.'
31
- }
32
- }, null, 2)
33
- }],
26
+ content: [
27
+ {
28
+ type: 'text',
29
+ text: JSON.stringify(
30
+ {
31
+ error: {
32
+ code: 'NOT_CONNECTED',
33
+ message: 'Figma plugin is not connected. Please open Figma and run the Autobest Figma Plugin.'
34
+ }
35
+ },
36
+ null,
37
+ 2
38
+ )
39
+ }
40
+ ],
34
41
  isError: true
35
42
  };
36
43
  }
@@ -39,15 +46,21 @@ export async function handleGetNodes(bridge, args) {
39
46
 
40
47
  if (!nodeIds || !Array.isArray(nodeIds) || nodeIds.length === 0) {
41
48
  return {
42
- content: [{
43
- type: 'text',
44
- text: JSON.stringify({
45
- error: {
46
- code: 'INVALID_PARAMS',
47
- message: 'nodeIds must be a non-empty array of node IDs'
48
- }
49
- }, null, 2)
50
- }],
49
+ content: [
50
+ {
51
+ type: 'text',
52
+ text: JSON.stringify(
53
+ {
54
+ error: {
55
+ code: 'INVALID_PARAMS',
56
+ message: 'nodeIds must be a non-empty array of node IDs'
57
+ }
58
+ },
59
+ null,
60
+ 2
61
+ )
62
+ }
63
+ ],
51
64
  isError: true
52
65
  };
53
66
  }
@@ -56,22 +69,30 @@ export async function handleGetNodes(bridge, args) {
56
69
  const result = await bridge.sendCommand('get_nodes', { nodeIds, depth });
57
70
 
58
71
  return {
59
- content: [{
60
- type: 'text',
61
- text: JSON.stringify(result, null, 2)
62
- }]
72
+ content: [
73
+ {
74
+ type: 'text',
75
+ text: JSON.stringify(result, null, 2)
76
+ }
77
+ ]
63
78
  };
64
79
  } catch (error) {
65
80
  return {
66
- content: [{
67
- type: 'text',
68
- text: JSON.stringify({
69
- error: {
70
- code: error.code || 'UNKNOWN_ERROR',
71
- message: error.message
72
- }
73
- }, null, 2)
74
- }],
81
+ content: [
82
+ {
83
+ type: 'text',
84
+ text: JSON.stringify(
85
+ {
86
+ error: {
87
+ code: error.code || 'UNKNOWN_ERROR',
88
+ message: error.message
89
+ }
90
+ },
91
+ null,
92
+ 2
93
+ )
94
+ }
95
+ ],
75
96
  isError: true
76
97
  };
77
98
  }
@@ -5,7 +5,8 @@
5
5
 
6
6
  export const pagesTool = {
7
7
  name: 'figma_list_pages',
8
- description: 'List all pages in the current Figma document. Returns page IDs, names, and indicates which page is currently active.',
8
+ description:
9
+ 'List all pages in the current Figma document. Returns page IDs, names, and indicates which page is currently active.',
9
10
  inputSchema: {
10
11
  type: 'object',
11
12
  properties: {},
@@ -16,15 +17,21 @@ export const pagesTool = {
16
17
  export async function handleListPages(bridge) {
17
18
  if (!bridge.isConnected()) {
18
19
  return {
19
- content: [{
20
- type: 'text',
21
- text: JSON.stringify({
22
- error: {
23
- code: 'NOT_CONNECTED',
24
- message: 'Figma plugin is not connected. Please open Figma and run the Autobest Figma Plugin.'
25
- }
26
- }, null, 2)
27
- }],
20
+ content: [
21
+ {
22
+ type: 'text',
23
+ text: JSON.stringify(
24
+ {
25
+ error: {
26
+ code: 'NOT_CONNECTED',
27
+ message: 'Figma plugin is not connected. Please open Figma and run the Autobest Figma Plugin.'
28
+ }
29
+ },
30
+ null,
31
+ 2
32
+ )
33
+ }
34
+ ],
28
35
  isError: true
29
36
  };
30
37
  }
@@ -33,22 +40,30 @@ export async function handleListPages(bridge) {
33
40
  const result = await bridge.sendCommand('list_pages', {});
34
41
 
35
42
  return {
36
- content: [{
37
- type: 'text',
38
- text: JSON.stringify(result, null, 2)
39
- }]
43
+ content: [
44
+ {
45
+ type: 'text',
46
+ text: JSON.stringify(result, null, 2)
47
+ }
48
+ ]
40
49
  };
41
50
  } catch (error) {
42
51
  return {
43
- content: [{
44
- type: 'text',
45
- text: JSON.stringify({
46
- error: {
47
- code: error.code || 'UNKNOWN_ERROR',
48
- message: error.message
49
- }
50
- }, null, 2)
51
- }],
52
+ content: [
53
+ {
54
+ type: 'text',
55
+ text: JSON.stringify(
56
+ {
57
+ error: {
58
+ code: error.code || 'UNKNOWN_ERROR',
59
+ message: error.message
60
+ }
61
+ },
62
+ null,
63
+ 2
64
+ )
65
+ }
66
+ ],
52
67
  isError: true
53
68
  };
54
69
  }
@@ -7,7 +7,7 @@
7
7
  先启动 PRD Knowledge HTTP API。直接在终端验证时,必须在同一条命令中提供 API 根地址:
8
8
 
9
9
  ```bash
10
- RAG_API_BASE_URL="http://127.0.0.1:3000/api/knowledge" \
10
+ RAG_API_BASE_URL="http://192.168.1.12:3000/api/knowledge" \
11
11
  npx --yes \
12
12
  --package=@autobest-ui/agent@latest \
13
13
  autobest-rag-mcp
@@ -26,7 +26,7 @@ tool_timeout_sec = 120
26
26
  enabled = true
27
27
 
28
28
  [mcp_servers.rag-mcp-bridge.env]
29
- RAG_API_BASE_URL = "http://127.0.0.1:3000/api/knowledge"
29
+ RAG_API_BASE_URL = "http://192.168.1.12:3000/api/knowledge"
30
30
  RAG_MCP_HTTP_TIMEOUT_MS = "120000"
31
31
  ```
32
32
 
@@ -7,6 +7,6 @@ enabled = true
7
7
 
8
8
  [mcp_servers.rag-mcp-bridge.env]
9
9
  # 必填:按实际部署地址修改,MCP 服务本身不提供默认地址。
10
- RAG_API_BASE_URL = "http://127.0.0.1:3000/api/knowledge"
10
+ RAG_API_BASE_URL = "http://192.168.1.12:3000/api/knowledge"
11
11
  # 可选:单次 HTTP 请求超时,单位为毫秒。
12
12
  RAG_MCP_HTTP_TIMEOUT_MS = "120000"
@@ -10,40 +10,37 @@
10
10
  * Database access, Markdown parsing, embeddings, and RAG stay in Express.
11
11
  */
12
12
 
13
- import { readdir, stat } from "node:fs/promises";
14
- import path from "node:path";
15
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
16
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
17
- import { z } from "zod";
13
+ import { readdir, stat } from 'node:fs/promises';
14
+ import path from 'node:path';
15
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
16
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
17
+ import { z } from 'zod';
18
18
 
19
19
  const DEFAULT_HTTP_TIMEOUT_MS = 120_000;
20
20
 
21
21
  function apiBaseUrlFromEnvironment() {
22
22
  const configuredUrl = process.env.RAG_API_BASE_URL?.trim();
23
23
  if (!configuredUrl) {
24
- throw new Error(
25
- "RAG_API_BASE_URL is required; configure it in the MCP server environment",
26
- );
24
+ throw new Error('RAG_API_BASE_URL is required; configure it in the MCP server environment');
27
25
  }
28
26
 
29
27
  let url;
30
28
  try {
31
29
  url = new URL(configuredUrl);
32
30
  } catch {
33
- throw new Error("RAG_API_BASE_URL must be a valid URL");
31
+ throw new Error('RAG_API_BASE_URL must be a valid URL');
34
32
  }
35
- if (url.protocol !== "http:" && url.protocol !== "https:") {
36
- throw new Error("RAG_API_BASE_URL must use http or https");
33
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
34
+ throw new Error('RAG_API_BASE_URL must use http or https');
37
35
  }
38
- return url.toString().replace(/\/$/, "");
36
+ return url.toString().replace(/\/$/, '');
39
37
  }
40
38
 
41
39
  function httpTimeoutFromEnvironment() {
42
- const configuredTimeout =
43
- process.env.RAG_MCP_HTTP_TIMEOUT_MS ?? String(DEFAULT_HTTP_TIMEOUT_MS);
40
+ const configuredTimeout = process.env.RAG_MCP_HTTP_TIMEOUT_MS ?? String(DEFAULT_HTTP_TIMEOUT_MS);
44
41
  const timeout = Number(configuredTimeout);
45
42
  if (!Number.isSafeInteger(timeout) || timeout <= 0) {
46
- throw new Error("RAG_MCP_HTTP_TIMEOUT_MS must be a positive integer");
43
+ throw new Error('RAG_MCP_HTTP_TIMEOUT_MS must be a positive integer');
47
44
  }
48
45
  return timeout;
49
46
  }
@@ -52,31 +49,18 @@ const API_BASE_URL = apiBaseUrlFromEnvironment();
52
49
  const HTTP_TIMEOUT_MS = httpTimeoutFromEnvironment();
53
50
 
54
51
  const pathsSchema = z
55
- .union([
56
- z.string().min(1),
57
- z.array(z.string().min(1)).min(1),
58
- ])
59
- .describe("单个Markdown文件、Markdown文件数组或文件夹的绝对路径");
52
+ .union([z.string().min(1), z.array(z.string().min(1)).min(1)])
53
+ .describe('单个Markdown文件、Markdown文件数组或文件夹的绝对路径');
60
54
  const platformSchema = z
61
- .enum(["app", "california-web", "shared"])
62
- .describe("知识所属平台;必须明确指定,防止APP与加州网站需求串库");
63
- const moduleSchema = z
64
- .string()
65
- .min(1)
66
- .optional()
67
- .describe("可选业务模块标识,例如vehicle-selector");
55
+ .enum(['app', 'california-web', 'shared'])
56
+ .describe('知识所属平台;必须明确指定,防止APP与加州网站需求串库');
57
+ const moduleSchema = z.string().min(1).optional().describe('可选业务模块标识,例如vehicle-selector');
68
58
  const pageSchema = z
69
59
  .string()
70
60
  .min(1)
71
61
  .optional()
72
- .describe(
73
- "业务页面键,例如home、pl、pn、pd、name-search;录入多个文件时不要传,由后端按文件名分别推断",
74
- );
75
- const docKeySchema = z
76
- .string()
77
- .min(1)
78
- .optional()
79
- .describe("需要限定到单一文档时传knowledge_doc.doc_key绝对路径");
62
+ .describe('业务页面键,例如home、pl、pn、pd、name-search;录入多个文件时不要传,由后端按文件名分别推断');
63
+ const docKeySchema = z.string().min(1).optional().describe('需要限定到单一文档时传knowledge_doc.doc_key绝对路径');
80
64
 
81
65
  /** Recursively collects Markdown files from a directory in stable order. */
82
66
  async function scanMarkdownDirectory(directoryPath) {
@@ -88,7 +72,7 @@ async function scanMarkdownDirectory(directoryPath) {
88
72
  const entryPath = path.join(directoryPath, entry.name);
89
73
  if (entry.isDirectory()) {
90
74
  markdownFiles.push(...(await scanMarkdownDirectory(entryPath)));
91
- } else if (entry.isFile() && path.extname(entry.name).toLowerCase() === ".md") {
75
+ } else if (entry.isFile() && path.extname(entry.name).toLowerCase() === '.md') {
92
76
  markdownFiles.push(path.resolve(entryPath));
93
77
  }
94
78
  }
@@ -101,8 +85,8 @@ async function expandMarkdownPaths(pathsInput) {
101
85
  const markdownFiles = [];
102
86
 
103
87
  for (const input of inputs) {
104
- if (typeof input !== "string" || !input.trim()) {
105
- throw new Error("paths中的每一项都必须是非空字符串");
88
+ if (typeof input !== 'string' || !input.trim()) {
89
+ throw new Error('paths中的每一项都必须是非空字符串');
106
90
  }
107
91
  if (!path.isAbsolute(input.trim())) {
108
92
  throw new Error(`必须使用绝对路径: ${input}`);
@@ -112,21 +96,16 @@ async function expandMarkdownPaths(pathsInput) {
112
96
  const pathStat = await stat(absolutePath);
113
97
  if (pathStat.isDirectory()) {
114
98
  markdownFiles.push(...(await scanMarkdownDirectory(absolutePath)));
115
- } else if (
116
- pathStat.isFile() &&
117
- path.extname(absolutePath).toLowerCase() === ".md"
118
- ) {
99
+ } else if (pathStat.isFile() && path.extname(absolutePath).toLowerCase() === '.md') {
119
100
  markdownFiles.push(absolutePath);
120
101
  } else {
121
102
  throw new Error(`路径不是Markdown文件或文件夹: ${absolutePath}`);
122
103
  }
123
104
  }
124
105
 
125
- const uniquePaths = [...new Set(markdownFiles)].sort((left, right) =>
126
- left.localeCompare(right),
127
- );
106
+ const uniquePaths = [...new Set(markdownFiles)].sort((left, right) => left.localeCompare(right));
128
107
  if (uniquePaths.length === 0) {
129
- throw new Error("指定路径中没有找到任何.md文件");
108
+ throw new Error('指定路径中没有找到任何.md文件');
130
109
  }
131
110
  return uniquePaths;
132
111
  }
@@ -134,10 +113,10 @@ async function expandMarkdownPaths(pathsInput) {
134
113
  /** Posts JSON to Express and returns its parsed response body. */
135
114
  async function postJson(endpoint, body) {
136
115
  const response = await fetch(`${API_BASE_URL}${endpoint}`, {
137
- method: "POST",
138
- headers: { "content-type": "application/json" },
116
+ method: 'POST',
117
+ headers: { 'content-type': 'application/json' },
139
118
  body: JSON.stringify(body),
140
- signal: AbortSignal.timeout(HTTP_TIMEOUT_MS),
119
+ signal: AbortSignal.timeout(HTTP_TIMEOUT_MS)
141
120
  });
142
121
  const responseText = await response.text();
143
122
  let responseBody;
@@ -148,10 +127,7 @@ async function postJson(endpoint, body) {
148
127
  }
149
128
 
150
129
  if (!response.ok) {
151
- const details =
152
- typeof responseBody === "string"
153
- ? responseBody
154
- : JSON.stringify(responseBody);
130
+ const details = typeof responseBody === 'string' ? responseBody : JSON.stringify(responseBody);
155
131
  throw new Error(`Express后端返回HTTP ${response.status}: ${details}`);
156
132
  }
157
133
  return responseBody;
@@ -161,12 +137,12 @@ async function postJson(endpoint, body) {
161
137
  async function getJson(endpoint, query) {
162
138
  const url = new URL(`${API_BASE_URL}${endpoint}`);
163
139
  for (const [name, value] of Object.entries(query)) {
164
- if (value === undefined || value === null || value === "") continue;
140
+ if (value === undefined || value === null || value === '') continue;
165
141
  url.searchParams.set(name, value);
166
142
  }
167
143
  const response = await fetch(url, {
168
- method: "GET",
169
- signal: AbortSignal.timeout(HTTP_TIMEOUT_MS),
144
+ method: 'GET',
145
+ signal: AbortSignal.timeout(HTTP_TIMEOUT_MS)
170
146
  });
171
147
  const responseText = await response.text();
172
148
  let responseBody;
@@ -176,10 +152,7 @@ async function getJson(endpoint, query) {
176
152
  responseBody = responseText;
177
153
  }
178
154
  if (!response.ok) {
179
- const details =
180
- typeof responseBody === "string"
181
- ? responseBody
182
- : JSON.stringify(responseBody);
155
+ const details = typeof responseBody === 'string' ? responseBody : JSON.stringify(responseBody);
183
156
  throw new Error(`Express后端返回HTTP ${response.status}: ${details}`);
184
157
  }
185
158
  return responseBody;
@@ -189,10 +162,10 @@ function toolSuccess(payload) {
189
162
  return {
190
163
  content: [
191
164
  {
192
- type: "text",
193
- text: JSON.stringify(payload, null, 2),
194
- },
195
- ],
165
+ type: 'text',
166
+ text: JSON.stringify(payload, null, 2)
167
+ }
168
+ ]
196
169
  };
197
170
  }
198
171
 
@@ -200,154 +173,136 @@ function toolError(error) {
200
173
  const message = error instanceof Error ? error.message : String(error);
201
174
  return {
202
175
  isError: true,
203
- content: [{ type: "text", text: message }],
176
+ content: [{ type: 'text', text: message }]
204
177
  };
205
178
  }
206
179
 
207
180
  const server = new McpServer(
208
- { name: "rag-mcp-bridge", version: "1.0.0" },
181
+ { name: 'rag-mcp-bridge', version: '1.0.0' },
209
182
  {
210
183
  instructions:
211
- "Use retrieve_knowledge before implementing requirement-sensitive code. " +
212
- "Every tool call requires an explicit platform: app, california-web, or shared. " +
213
- "add_prd_file and update_spec_file accept one file, an array of files, or a directory. " +
214
- "Only call update_spec_file after the PR is merged and leader review confirms the spec is effective.",
215
- },
184
+ 'Use retrieve_knowledge before implementing requirement-sensitive code. ' +
185
+ 'Every tool call requires an explicit platform: app, california-web, or shared. ' +
186
+ 'add_prd_file and update_spec_file accept one file, an array of files, or a directory. ' +
187
+ 'Only call update_spec_file after the PR is merged and leader review confirms the spec is effective.'
188
+ }
216
189
  );
217
190
 
218
191
  server.registerTool(
219
- "add_prd_file",
192
+ 'add_prd_file',
220
193
  {
221
- title: "录入或更新PRD基线",
194
+ title: '录入或更新PRD基线',
222
195
  description:
223
- "录入/更新PRD基线。paths支持单个md绝对路径、md绝对路径数组或文件夹绝对路径;文件夹会递归扫描全部.md文件。后端负责解析截图并将旧文档标记为作废。",
196
+ '录入/更新PRD基线。paths支持单个md绝对路径、md绝对路径数组或文件夹绝对路径;文件夹会递归扫描全部.md文件。后端负责解析截图并将旧文档标记为作废。',
224
197
  inputSchema: {
225
198
  paths: pathsSchema,
226
199
  platform: platformSchema,
227
200
  module: moduleSchema,
228
- page: pageSchema,
201
+ page: pageSchema
229
202
  },
230
203
  annotations: {
231
204
  readOnlyHint: false,
232
205
  destructiveHint: false,
233
206
  idempotentHint: false,
234
- openWorldHint: false,
235
- },
207
+ openWorldHint: false
208
+ }
236
209
  },
237
210
  async ({ paths, platform, module, page }) => {
238
211
  try {
239
212
  const expandedPaths = await expandMarkdownPaths(paths);
240
213
  return toolSuccess(
241
- await postJson("/add-prd", {
214
+ await postJson('/add-prd', {
242
215
  paths: expandedPaths,
243
216
  platform,
244
217
  module,
245
- page,
246
- }),
218
+ page
219
+ })
247
220
  );
248
221
  } catch (error) {
249
222
  return toolError(error);
250
223
  }
251
- },
224
+ }
252
225
  );
253
226
 
254
227
  server.registerTool(
255
- "update_spec_file",
228
+ 'update_spec_file',
256
229
  {
257
- title: "录入迭代变更Spec",
230
+ title: '录入迭代变更Spec',
258
231
  description:
259
- "仅在PR合并且leader review确认生效后调用。paths支持单个spec.md绝对路径、路径数组或文件夹;只需传改动spec。sprintVersion必须递增,数值越大需求越新。",
232
+ '仅在PR合并且leader review确认生效后调用。paths支持单个spec.md绝对路径、路径数组或文件夹;只需传改动spec。sprintVersion必须递增,数值越大需求越新。',
260
233
  inputSchema: {
261
234
  paths: pathsSchema,
262
235
  sprintVersion: z.number().int().positive(),
263
236
  iterationTag: z.string().min(1),
264
237
  platform: platformSchema,
265
238
  module: moduleSchema,
266
- page: pageSchema,
239
+ page: pageSchema
267
240
  },
268
241
  annotations: {
269
242
  readOnlyHint: false,
270
243
  destructiveHint: false,
271
244
  idempotentHint: false,
272
- openWorldHint: false,
273
- },
245
+ openWorldHint: false
246
+ }
274
247
  },
275
248
  async ({ paths, sprintVersion, iterationTag, platform, module, page }) => {
276
249
  try {
277
250
  const expandedPaths = await expandMarkdownPaths(paths);
278
251
  return toolSuccess(
279
- await postJson("/add-spec", {
252
+ await postJson('/add-spec', {
280
253
  paths: expandedPaths,
281
254
  sprintVersion,
282
255
  iterationTag,
283
256
  platform,
284
257
  module,
285
- page,
286
- }),
258
+ page
259
+ })
287
260
  );
288
261
  } catch (error) {
289
262
  return toolError(error);
290
263
  }
291
- },
264
+ }
292
265
  );
293
266
 
294
267
  server.registerTool(
295
- "retrieve_knowledge",
268
+ 'retrieve_knowledge',
296
269
  {
297
- title: "检索PRD与迭代Spec",
270
+ title: '检索PRD与迭代Spec',
298
271
  description:
299
- "Codex编写需求相关代码前调用。后端执行向量+BM25-RRF混合检索并按sprint_version业务排序。enableStruct=true时才生成结构化PRD;includeImages=true时才保留图片并替换为数据库图片URL,两者默认均为false。",
272
+ 'Codex编写需求相关代码前调用。后端执行向量+BM25-RRF混合检索并按sprint_version业务排序。enableStruct=true时才生成结构化PRD;includeImages=true时才保留图片并替换为数据库图片URL,两者默认均为false。',
300
273
  inputSchema: {
301
274
  query: z.string().min(1),
302
275
  platform: platformSchema,
303
- module: moduleSchema.describe(
304
- "可选业务模块硬过滤,例如vehicle-selector",
305
- ),
306
- page: pageSchema.describe(
307
- "可选页面硬过滤,例如首页传home;不传时后端会从明确的查询词自动推断",
308
- ),
276
+ module: moduleSchema.describe('可选业务模块硬过滤,例如vehicle-selector'),
277
+ page: pageSchema.describe('可选页面硬过滤,例如首页传home;不传时后端会从明确的查询词自动推断'),
309
278
  docKey: docKeySchema,
310
- enableStruct: z
311
- .boolean()
312
- .default(false)
313
- .describe("是否调用LLM生成structuredPrd,默认false"),
314
- includeImages: z
315
- .boolean()
316
- .default(false)
317
- .describe("是否返回可供UI显示的数据库图片URL,默认false"),
279
+ enableStruct: z.boolean().default(false).describe('是否调用LLM生成structuredPrd,默认false'),
280
+ includeImages: z.boolean().default(false).describe('是否返回可供UI显示的数据库图片URL,默认false')
318
281
  },
319
282
  annotations: {
320
283
  readOnlyHint: true,
321
284
  destructiveHint: false,
322
285
  idempotentHint: true,
323
- openWorldHint: false,
324
- },
286
+ openWorldHint: false
287
+ }
325
288
  },
326
- async ({
327
- query,
328
- platform,
329
- module,
330
- page,
331
- docKey,
332
- enableStruct = false,
333
- includeImages = false,
334
- }) => {
289
+ async ({ query, platform, module, page, docKey, enableStruct = false, includeImages = false }) => {
335
290
  try {
336
291
  return toolSuccess(
337
- await getJson("/search", {
292
+ await getJson('/search', {
338
293
  query: query.trim(),
339
294
  platform,
340
295
  module,
341
296
  page,
342
297
  docKey,
343
298
  enableStruct: String(enableStruct === true),
344
- includeImages: String(includeImages === true),
345
- }),
299
+ includeImages: String(includeImages === true)
300
+ })
346
301
  );
347
302
  } catch (error) {
348
303
  return toolError(error);
349
304
  }
350
- },
305
+ }
351
306
  );
352
307
 
353
308
  async function main() {
@@ -355,7 +310,7 @@ async function main() {
355
310
  await server.connect(transport);
356
311
  }
357
312
 
358
- main().catch((error) => {
359
- console.error("Failed to start rag-mcp-bridge:", error);
313
+ main().catch(error => {
314
+ console.error('Failed to start rag-mcp-bridge:', error);
360
315
  process.exitCode = 1;
361
316
  });