ms-vite-plugin 1.4.15 → 1.4.17

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.
@@ -34,34 +34,9 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.registerHttpApiTools = registerHttpApiTools;
37
- const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
38
37
  const z = __importStar(require("zod/v4"));
39
38
  const httpapi_docs_service_1 = require("./httpapi-docs-service");
40
39
  const tool_utils_1 = require("./tool-utils");
41
- /**
42
- * HTTP API 文档完整资源 URI
43
- */
44
- const HTTP_API_DOC_RESOURCE_URI = "kuaijs://httpapi/api";
45
- const HTTP_API_ENDPOINT_RESOURCE_PREFIX = "kuaijs://httpapi/endpoints";
46
- /**
47
- * 格式化 HTTP API 文档搜索摘要
48
- * @param entry HTTP API 文档条目
49
- * @param index 列表序号
50
- * @returns 返回摘要文本
51
- * @example
52
- * formatHttpApiDocSummary(entry, 0)
53
- */
54
- function formatHttpApiDocSummary(entry, index) {
55
- return [
56
- `${index + 1}. ${entry.title}`,
57
- `method: ${entry.method}`,
58
- `path: ${entry.path}`,
59
- `slug: ${entry.slug}`,
60
- `section: ${entry.section || "未分组"}`,
61
- `lines: ${entry.startLine}-${entry.endLine}`,
62
- `uri: ${HTTP_API_ENDPOINT_RESOURCE_PREFIX}/${entry.slug}`,
63
- ].join("\n");
64
- }
65
40
  /**
66
41
  * 标准化并校验 HTTP API 路径输入
67
42
  * @param apiPath 用户传入路径
@@ -157,127 +132,16 @@ async function readHttpApiResponseText(response, responseFormat) {
157
132
  }
158
133
  }
159
134
  /**
160
- * 注册 HTTP API 文档与通用调用工具
135
+ * 注册通用 HTTP API 调用工具
161
136
  * @param server MCP 服务实例
162
137
  * @returns 无返回值
163
138
  * @example
164
139
  * registerHttpApiTools(server)
165
140
  */
166
141
  function registerHttpApiTools(server) {
167
- server.registerResource("http-api-doc", HTTP_API_DOC_RESOURCE_URI, {
168
- title: "KuaiJS HTTP API document",
169
- mimeType: "text/markdown",
170
- }, async () => ({
171
- contents: [
172
- {
173
- uri: HTTP_API_DOC_RESOURCE_URI,
174
- mimeType: "text/markdown",
175
- text: await (0, httpapi_docs_service_1.readHttpApiMarkdown)(),
176
- },
177
- ],
178
- }));
179
- server.registerResource("http-api-endpoint", new mcp_js_1.ResourceTemplate(`${HTTP_API_ENDPOINT_RESOURCE_PREFIX}/{slug}`, {
180
- list: async () => {
181
- const entries = await (0, httpapi_docs_service_1.getHttpApiDocEntries)();
182
- return {
183
- resources: entries.map((entry) => ({
184
- uri: `${HTTP_API_ENDPOINT_RESOURCE_PREFIX}/${entry.slug}`,
185
- name: `${entry.method} ${entry.path}`,
186
- description: `${entry.title} [${entry.section || "未分组"}]`,
187
- mimeType: "text/markdown",
188
- })),
189
- };
190
- },
191
- }), {
192
- title: "KuaiJS HTTP API endpoint documents",
193
- mimeType: "text/markdown",
194
- }, async (_uri, variables) => {
195
- const slug = String(variables.slug || "");
196
- const entry = await (0, httpapi_docs_service_1.findHttpApiDocEntry)(slug);
197
- if (!entry) {
198
- throw new Error(`HTTP API 文档不存在: ${slug}`);
199
- }
200
- return {
201
- contents: [
202
- {
203
- uri: `${HTTP_API_ENDPOINT_RESOURCE_PREFIX}/${entry.slug}`,
204
- mimeType: "text/markdown",
205
- text: entry.content,
206
- },
207
- ],
208
- };
209
- });
210
- server.registerTool("search_http_api_docs", {
211
- title: "Search HTTP API Docs",
212
- description: "搜索 HTTP API 文档中声明的接口。调用 http_api_call 前应先用本工具确认接口 method、path、参数和 slug。",
213
- inputSchema: {
214
- query: z
215
- .string()
216
- .min(1)
217
- .describe("搜索关键词,例如 click、/api/control/click、截图"),
218
- limit: z
219
- .number()
220
- .int()
221
- .min(1)
222
- .max(20)
223
- .optional()
224
- .default(8)
225
- .describe("返回条数上限,默认 8"),
226
- },
227
- }, async ({ query, limit }) => {
228
- const normalizedQuery = query.toLowerCase();
229
- const entries = await (0, httpapi_docs_service_1.getHttpApiDocEntries)();
230
- const matches = entries
231
- .map((entry) => ({
232
- entry,
233
- score: (0, httpapi_docs_service_1.scoreHttpApiDocEntry)(entry, normalizedQuery),
234
- }))
235
- .filter((item) => item.score > 0)
236
- .sort((a, b) => b.score - a.score ||
237
- a.entry.path.localeCompare(b.entry.path) ||
238
- a.entry.method.localeCompare(b.entry.method))
239
- .slice(0, limit)
240
- .map((item) => item.entry);
241
- return (0, tool_utils_1.createTextToolResult)(matches.length === 0
242
- ? `未找到与 "${query}" 匹配的 HTTP API 文档。`
243
- : [
244
- "HTTP API 文档匹配结果:",
245
- "",
246
- ...matches.map((entry, index) => formatHttpApiDocSummary(entry, index)),
247
- ].join("\n"));
248
- });
249
- server.registerTool("read_http_api_doc", {
250
- title: "Read HTTP API Doc",
251
- description: "按 slug 或 path 读取 HTTP API 文档中的接口片段。调用 http_api_call 前应读取目标接口片段,确认参数位置、类型和返回结构。",
252
- inputSchema: {
253
- identifier: z
254
- .string()
255
- .min(1)
256
- .describe("接口 slug 或 path,例如 get-api-control-click 或 /api/control/click"),
257
- method: z
258
- .enum(["GET", "POST"])
259
- .optional()
260
- .describe("可选 HTTP 方法,用于同路径多方法时消歧"),
261
- },
262
- }, async ({ identifier, method }) => {
263
- const entry = await (0, httpapi_docs_service_1.findHttpApiDocEntry)(identifier, method);
264
- if (!entry) {
265
- return (0, tool_utils_1.createTextToolResult)(`未找到 HTTP API 文档: ${identifier}\n请先调用 search_http_api_docs 搜索可用接口。`, true);
266
- }
267
- return (0, tool_utils_1.createTextToolResult)([
268
- `title: ${entry.title}`,
269
- `method: ${entry.method}`,
270
- `path: ${entry.path}`,
271
- `slug: ${entry.slug}`,
272
- `section: ${entry.section || "未分组"}`,
273
- `lines: ${entry.startLine}-${entry.endLine}`,
274
- "",
275
- entry.content,
276
- ].join("\n"));
277
- });
278
142
  server.registerTool("http_api_call", {
279
143
  title: "HTTP API Call",
280
- description: "调用 HTTP API 文档中已声明的接口。使用前应先调用 search_http_api_docs/read_http_api_doc 获取 docSlug,并确认 method、path、query/body 参数;本工具会拒绝 docSlug、methodpath 不匹配的调用。",
144
+ description: "调用 HTTP API 文档中已声明的接口。使用前应直接读取 get_docs_paths 返回的 HTTP API 文档,确认 method、path、query/body 参数;本工具会拒绝文档中未声明的 method/path",
281
145
  inputSchema: {
282
146
  method: z
283
147
  .enum(["GET", "POST"])
@@ -286,10 +150,6 @@ function registerHttpApiTools(server) {
286
150
  .string()
287
151
  .min(1)
288
152
  .describe("HTTP API 相对路径,例如 /api/control/click;不能包含 query string"),
289
- docSlug: z
290
- .string()
291
- .min(1)
292
- .describe("search_http_api_docs/read_http_api_doc 返回的接口 slug"),
293
153
  query: z
294
154
  .record(z.string(), z.union([z.string(), z.number(), z.boolean(), z.null()]))
295
155
  .optional()
@@ -312,21 +172,13 @@ function registerHttpApiTools(server) {
312
172
  .default(30000)
313
173
  .describe("请求超时时间,默认 30000 毫秒"),
314
174
  },
315
- }, async ({ method, path, docSlug, query, body, responseFormat, timeoutMs, }) => {
175
+ }, async ({ method, path, query, body, responseFormat, timeoutMs, }) => {
316
176
  const apiPath = normalizeHttpApiPath(path);
317
- const entry = await (0, httpapi_docs_service_1.findHttpApiDocEntry)(docSlug);
177
+ const entry = await (0, httpapi_docs_service_1.findHttpApiDocEntry)(apiPath, method);
318
178
  if (!entry) {
319
179
  return (0, tool_utils_1.createTextToolResult)([
320
- `HTTP API 文档中不存在该 docSlug: ${docSlug}`,
321
- "请先调用 search_http_api_docs 搜索可用接口,再调用 read_http_api_doc 确认参数和 slug。",
322
- ].join("\n"), true);
323
- }
324
- if (entry.method !== method || entry.path !== apiPath) {
325
- return (0, tool_utils_1.createTextToolResult)([
326
- "HTTP API 调用与文档条目不匹配。",
327
- `传入: ${method} ${apiPath} (${docSlug})`,
328
- `文档: ${entry.method} ${entry.path} (${entry.slug})`,
329
- "请重新调用 read_http_api_doc 确认目标接口。",
180
+ `HTTP API 文档中不存在该接口: ${method} ${apiPath}`,
181
+ "请直接读取 get_docs_paths 返回的 HTTP API 文档路径,确认接口 method、path 和参数。",
330
182
  ].join("\n"), true);
331
183
  }
332
184
  if (method === "GET" && body !== undefined) {
@@ -349,7 +201,7 @@ function registerHttpApiTools(server) {
349
201
  return (0, tool_utils_1.createTextToolResult)([
350
202
  `HTTP API 调用${response.ok ? "成功" : "失败"}: ${method} ${apiPath}`,
351
203
  `设备: ${target.label}`,
352
- `文档: ${entry.title} (${entry.slug}, lines ${entry.startLine}-${entry.endLine})`,
204
+ `文档: ${entry.title} (lines ${entry.startLine}-${entry.endLine})`,
353
205
  `状态码: ${response.status}`,
354
206
  "",
355
207
  responseText,
@@ -1,4 +1,73 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export type ImageSampleCorner = "topLeft" | "topRight" | "bottomLeft" | "bottomRight";
3
+ /**
4
+ * 裁切本地图片
5
+ * @param imagePath 输入图片路径
6
+ * @param x 裁切起点 x
7
+ * @param y 裁切起点 y
8
+ * @param width 裁切宽度
9
+ * @param height 裁切高度
10
+ * @param outputPath 可选输出路径
11
+ * @returns 返回操作结果文本
12
+ * @example
13
+ * await cropLocalImage("./screen.jpg", 0, 0, 100, 100)
14
+ */
15
+ export declare function cropLocalImage(imagePath: string, x: number, y: number, width: number, height: number, outputPath?: string): Promise<string>;
16
+ /**
17
+ * 裁切设备截图
18
+ * @param target 设备 HTTP 地址
19
+ * @param x 裁切起点 x
20
+ * @param y 裁切起点 y
21
+ * @param width 裁切宽度
22
+ * @param height 裁切高度
23
+ * @param outputPath 可选输出路径
24
+ * @returns 返回操作结果文本
25
+ * @example
26
+ * await cropDeviceScreen({ ip: "192.168.1.10", port: "9800", label: "192.168.1.10:9800" }, 0, 0, 100, 100)
27
+ */
28
+ export declare function cropDeviceScreen(target: {
29
+ ip: string;
30
+ port: string;
31
+ label: string;
32
+ }, x: number, y: number, width: number, height: number, outputPath?: string): Promise<string>;
33
+ /**
34
+ * 读取本地图片颜色
35
+ * @param imagePath 输入图片路径
36
+ * @param x 目标坐标 x
37
+ * @param y 目标坐标 y
38
+ * @param radius 采样半径
39
+ * @returns 返回取色结果文本
40
+ * @example
41
+ * await pickLocalImageColor("./screen.jpg", 10, 10, 0)
42
+ */
43
+ export declare function pickLocalImageColor(imagePath: string, x: number, y: number, radius: number): Promise<string>;
44
+ /**
45
+ * 读取设备截图颜色
46
+ * @param target 设备 HTTP 地址
47
+ * @param x 目标坐标 x
48
+ * @param y 目标坐标 y
49
+ * @param radius 采样半径
50
+ * @returns 返回取色结果文本
51
+ * @example
52
+ * await pickDeviceScreenColor({ ip: "192.168.1.10", port: "9800", label: "192.168.1.10:9800" }, 10, 10, 0)
53
+ */
54
+ export declare function pickDeviceScreenColor(target: {
55
+ ip: string;
56
+ port: string;
57
+ label: string;
58
+ }, x: number, y: number, radius: number): Promise<string>;
59
+ /**
60
+ * 制作本地图片透明图
61
+ * @param imagePath 输入图片路径
62
+ * @param outputPath 可选输出路径
63
+ * @param transparentColor 可选透明色
64
+ * @param sampleCorner 未传透明色时采样的角落
65
+ * @param tolerance 颜色容差
66
+ * @returns 返回操作结果文本
67
+ * @example
68
+ * await makeLocalImageTransparent("./button.png", undefined, "#ffffff", "topLeft", 24)
69
+ */
70
+ export declare function makeLocalImageTransparent(imagePath: string, outputPath: string | undefined, transparentColor: string | undefined, sampleCorner: ImageSampleCorner, tolerance: number): Promise<string>;
2
71
  /**
3
72
  * 注册图片处理 MCP 工具
4
73
  * @param server MCP 服务实例
@@ -36,6 +36,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.cropLocalImage = cropLocalImage;
40
+ exports.cropDeviceScreen = cropDeviceScreen;
41
+ exports.pickLocalImageColor = pickLocalImageColor;
42
+ exports.pickDeviceScreenColor = pickDeviceScreenColor;
43
+ exports.makeLocalImageTransparent = makeLocalImageTransparent;
39
44
  exports.registerImageTools = registerImageTools;
40
45
  const fsExtra = __importStar(require("fs-extra"));
41
46
  const os = __importStar(require("os"));
@@ -247,6 +252,164 @@ function formatPickedColorText(source, x, y, radius, imageWidth, imageHeight, co
247
252
  `rgba: ${color.r},${color.g},${color.b},${color.a}`,
248
253
  ].join("\n");
249
254
  }
255
+ /**
256
+ * 裁切本地图片
257
+ * @param imagePath 输入图片路径
258
+ * @param x 裁切起点 x
259
+ * @param y 裁切起点 y
260
+ * @param width 裁切宽度
261
+ * @param height 裁切高度
262
+ * @param outputPath 可选输出路径
263
+ * @returns 返回操作结果文本
264
+ * @example
265
+ * await cropLocalImage("./screen.jpg", 0, 0, 100, 100)
266
+ */
267
+ async function cropLocalImage(imagePath, x, y, width, height, outputPath) {
268
+ const inputPath = await resolveExistingImagePath(imagePath);
269
+ const targetPath = resolveImageOutputPath(inputPath, outputPath, "crop");
270
+ const metadata = await (0, sharp_1.default)(inputPath).metadata();
271
+ const imageWidth = metadata.width ?? 0;
272
+ const imageHeight = metadata.height ?? 0;
273
+ if (x + width > imageWidth || y + height > imageHeight) {
274
+ throw new Error(`裁切范围超出图片尺寸: image=${imageWidth}x${imageHeight}, crop=${x},${y},${width},${height}`);
275
+ }
276
+ await fsExtra.ensureDir(path.dirname(targetPath));
277
+ const info = await (0, sharp_1.default)(inputPath)
278
+ .extract({ left: x, top: y, width, height })
279
+ .png()
280
+ .toFile(targetPath);
281
+ return [
282
+ "图片裁切成功",
283
+ `input: ${inputPath}`,
284
+ `output: ${targetPath}`,
285
+ `crop: x=${x}, y=${y}, width=${width}, height=${height}`,
286
+ `size: ${info.size} bytes`,
287
+ ].join("\n");
288
+ }
289
+ /**
290
+ * 裁切设备截图
291
+ * @param target 设备 HTTP 地址
292
+ * @param x 裁切起点 x
293
+ * @param y 裁切起点 y
294
+ * @param width 裁切宽度
295
+ * @param height 裁切高度
296
+ * @param outputPath 可选输出路径
297
+ * @returns 返回操作结果文本
298
+ * @example
299
+ * await cropDeviceScreen({ ip: "192.168.1.10", port: "9800", label: "192.168.1.10:9800" }, 0, 0, 100, 100)
300
+ */
301
+ async function cropDeviceScreen(target, x, y, width, height, outputPath) {
302
+ const screenshot = await (0, project_1.getScreenshotOnDevice)({
303
+ ip: target.ip,
304
+ port: target.port,
305
+ transport: "http",
306
+ });
307
+ const metadata = await (0, sharp_1.default)(screenshot).metadata();
308
+ const imageWidth = metadata.width ?? 0;
309
+ const imageHeight = metadata.height ?? 0;
310
+ if (x + width > imageWidth || y + height > imageHeight) {
311
+ throw new Error(`裁切范围超出截图尺寸: image=${imageWidth}x${imageHeight}, crop=${x},${y},${width},${height}`);
312
+ }
313
+ const targetPath = resolveGeneratedImageOutputPath(outputPath, "ms-mcp-screen-crop", "png");
314
+ await fsExtra.ensureDir(path.dirname(targetPath));
315
+ const info = await (0, sharp_1.default)(screenshot)
316
+ .extract({ left: x, top: y, width, height })
317
+ .png()
318
+ .toFile(targetPath);
319
+ return [
320
+ "屏幕裁图成功",
321
+ `device: ${target.label}`,
322
+ `output: ${targetPath}`,
323
+ `screen: ${imageWidth}x${imageHeight}`,
324
+ `crop: x=${x}, y=${y}, width=${width}, height=${height}`,
325
+ `size: ${info.size} bytes`,
326
+ ].join("\n");
327
+ }
328
+ /**
329
+ * 读取本地图片颜色
330
+ * @param imagePath 输入图片路径
331
+ * @param x 目标坐标 x
332
+ * @param y 目标坐标 y
333
+ * @param radius 采样半径
334
+ * @returns 返回取色结果文本
335
+ * @example
336
+ * await pickLocalImageColor("./screen.jpg", 10, 10, 0)
337
+ */
338
+ async function pickLocalImageColor(imagePath, x, y, radius) {
339
+ const inputPath = await resolveExistingImagePath(imagePath);
340
+ const image = await readRgbaImage(inputPath);
341
+ const picked = pickAverageColor(image.data, image.width, image.height, x, y, radius);
342
+ return formatPickedColorText(inputPath, x, y, radius, image.width, image.height, picked.color, picked.sampleCount);
343
+ }
344
+ /**
345
+ * 读取设备截图颜色
346
+ * @param target 设备 HTTP 地址
347
+ * @param x 目标坐标 x
348
+ * @param y 目标坐标 y
349
+ * @param radius 采样半径
350
+ * @returns 返回取色结果文本
351
+ * @example
352
+ * await pickDeviceScreenColor({ ip: "192.168.1.10", port: "9800", label: "192.168.1.10:9800" }, 10, 10, 0)
353
+ */
354
+ async function pickDeviceScreenColor(target, x, y, radius) {
355
+ const screenshot = await (0, project_1.getScreenshotOnDevice)({
356
+ ip: target.ip,
357
+ port: target.port,
358
+ transport: "http",
359
+ });
360
+ const image = await readRgbaImage(screenshot);
361
+ const picked = pickAverageColor(image.data, image.width, image.height, x, y, radius);
362
+ return formatPickedColorText(target.label, x, y, radius, image.width, image.height, picked.color, picked.sampleCount);
363
+ }
364
+ /**
365
+ * 制作本地图片透明图
366
+ * @param imagePath 输入图片路径
367
+ * @param outputPath 可选输出路径
368
+ * @param transparentColor 可选透明色
369
+ * @param sampleCorner 未传透明色时采样的角落
370
+ * @param tolerance 颜色容差
371
+ * @returns 返回操作结果文本
372
+ * @example
373
+ * await makeLocalImageTransparent("./button.png", undefined, "#ffffff", "topLeft", 24)
374
+ */
375
+ async function makeLocalImageTransparent(imagePath, outputPath, transparentColor, sampleCorner, tolerance) {
376
+ const inputPath = await resolveExistingImagePath(imagePath);
377
+ const targetPath = resolveImageOutputPath(inputPath, outputPath, "transparent");
378
+ const { data, info } = await (0, sharp_1.default)(inputPath)
379
+ .ensureAlpha()
380
+ .raw()
381
+ .toBuffer({ resolveWithObject: true });
382
+ const targetColor = transparentColor
383
+ ? parseHexColor(transparentColor)
384
+ : sampleCornerColor(data, info.width, info.height, sampleCorner);
385
+ let transparentPixelCount = 0;
386
+ for (let offset = 0; offset < data.length; offset += 4) {
387
+ if (isColorMatch(data, offset, targetColor, tolerance)) {
388
+ data[offset + 3] = 0;
389
+ transparentPixelCount += 1;
390
+ }
391
+ }
392
+ await fsExtra.ensureDir(path.dirname(targetPath));
393
+ const output = await (0, sharp_1.default)(data, {
394
+ raw: {
395
+ width: info.width,
396
+ height: info.height,
397
+ channels: 4,
398
+ },
399
+ })
400
+ .png()
401
+ .toFile(targetPath);
402
+ return [
403
+ "透明图制作成功",
404
+ `input: ${inputPath}`,
405
+ `output: ${targetPath}`,
406
+ `image: ${info.width}x${info.height}`,
407
+ `transparentColor: ${formatRgbHex(targetColor)}`,
408
+ `tolerance: ${tolerance}`,
409
+ `transparentPixels: ${transparentPixelCount}`,
410
+ `size: ${output.size} bytes`,
411
+ ].join("\n");
412
+ }
250
413
  /**
251
414
  * 注册图片处理 MCP 工具
252
415
  * @param server MCP 服务实例
@@ -1,4 +1,54 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export type OcrEngine = "appleocr" | "paddleocr";
3
+ export type OcrMode = "recognize" | "numbers" | "findText";
4
+ export type ScriptResultResponse = {
5
+ success?: boolean;
6
+ result?: unknown;
7
+ resultType?: string;
8
+ error?: string;
9
+ };
10
+ export type OcrRecognitionOptions = {
11
+ engine: OcrEngine;
12
+ mode: OcrMode;
13
+ input: string;
14
+ x: number;
15
+ y: number;
16
+ ex: number;
17
+ ey: number;
18
+ texts?: string[];
19
+ languages?: string[];
20
+ confidenceThreshold: number;
21
+ exactMatch: boolean;
22
+ outputPath?: string;
23
+ timeoutMs: number;
24
+ };
25
+ export type OcrRecognitionResult = {
26
+ status: number;
27
+ body: ScriptResultResponse;
28
+ text: string;
29
+ };
30
+ export declare const APPLE_OCR_LANGUAGES: readonly ["en-US", "fr-FR", "it-IT", "de-DE", "es-ES", "pt-BR", "zh-Hans", "zh-Hant"];
31
+ /**
32
+ * 格式化 OCR 工具结果
33
+ * @param response runScript 响应
34
+ * @param outputPath 可选输出文件路径
35
+ * @returns 返回 MCP 文本内容
36
+ * @example
37
+ * await formatOcrToolText({ success: true, result: [] })
38
+ */
39
+ export declare function formatOcrToolText(response: ScriptResultResponse, outputPath?: string): Promise<string>;
40
+ /**
41
+ * 在指定 HTTP 设备上执行 OCR 识别
42
+ * @param target 设备 HTTP 地址
43
+ * @param options OCR 参数
44
+ * @returns 返回 HTTP 状态码、原始结果与格式化文本
45
+ * @example
46
+ * await runOcrRecognitionOnDevice({ ip: "192.168.1.10", port: "9800" }, options)
47
+ */
48
+ export declare function runOcrRecognitionOnDevice(target: {
49
+ ip: string;
50
+ port: string;
51
+ }, options: OcrRecognitionOptions): Promise<OcrRecognitionResult>;
2
52
  /**
3
53
  * 注册 OCR MCP 工具
4
54
  * @param server MCP 服务实例