@midscene/shared 1.9.8-beta-20260618014851.0 → 1.9.8

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.
Files changed (75) hide show
  1. package/dist/es/cli/cli-runner.mjs +1 -1
  2. package/dist/es/env/parse-model-config.mjs +1 -1
  3. package/dist/es/env/types.mjs +5 -3
  4. package/dist/es/mcp/base-server.mjs +295 -0
  5. package/dist/es/{agent-tools → mcp}/base-tools.mjs +8 -1
  6. package/dist/es/{agent-tools → mcp}/chrome-path.mjs +3 -14
  7. package/dist/es/{agent-tools → mcp}/index.mjs +3 -0
  8. package/dist/es/mcp/inject-report-html-plugin.mjs +53 -0
  9. package/dist/es/mcp/launcher-helper.mjs +52 -0
  10. package/dist/es/{agent-tools → mcp}/tool-generator.mjs +3 -3
  11. package/dist/es/utils.mjs +6 -2
  12. package/dist/lib/cli/cli-runner.js +1 -1
  13. package/dist/lib/env/parse-model-config.js +1 -1
  14. package/dist/lib/env/types.js +10 -5
  15. package/dist/lib/mcp/base-server.js +345 -0
  16. package/dist/lib/{agent-tools → mcp}/base-tools.js +8 -1
  17. package/dist/lib/{agent-tools → mcp}/chrome-path.js +2 -13
  18. package/dist/lib/{agent-tools → mcp}/index.js +37 -16
  19. package/dist/lib/mcp/inject-report-html-plugin.js +98 -0
  20. package/dist/lib/mcp/launcher-helper.js +86 -0
  21. package/dist/lib/{agent-tools → mcp}/tool-generator.js +3 -3
  22. package/dist/lib/utils.js +15 -8
  23. package/dist/types/cli/cli-args.d.ts +1 -1
  24. package/dist/types/cli/cli-runner.d.ts +2 -2
  25. package/dist/types/env/types.d.ts +6 -8
  26. package/dist/types/key-alias-utils.d.ts +2 -2
  27. package/dist/types/mcp/base-server.d.ts +106 -0
  28. package/dist/types/{agent-tools → mcp}/base-tools.d.ts +13 -7
  29. package/dist/types/{agent-tools → mcp}/index.d.ts +3 -0
  30. package/dist/types/{agent-tools → mcp}/init-arg-utils.d.ts +3 -3
  31. package/dist/types/mcp/inject-report-html-plugin.d.ts +18 -0
  32. package/dist/types/mcp/launcher-helper.d.ts +94 -0
  33. package/dist/types/{agent-tools → mcp}/tool-defaults.d.ts +6 -5
  34. package/dist/types/{agent-tools → mcp}/tool-generator.d.ts +1 -1
  35. package/dist/types/{agent-tools → mcp}/types.d.ts +9 -4
  36. package/dist/types/utils.d.ts +1 -0
  37. package/package.json +8 -15
  38. package/src/cli/cli-args.ts +1 -1
  39. package/src/cli/cli-runner.ts +4 -4
  40. package/src/env/types.ts +5 -5
  41. package/src/key-alias-utils.ts +2 -2
  42. package/src/mcp/base-server.ts +529 -0
  43. package/src/{agent-tools → mcp}/base-tools.ts +33 -8
  44. package/src/{agent-tools → mcp}/chrome-path.ts +3 -20
  45. package/src/{agent-tools → mcp}/index.ts +3 -0
  46. package/src/{agent-tools → mcp}/init-arg-utils.ts +3 -3
  47. package/src/mcp/inject-report-html-plugin.ts +119 -0
  48. package/src/mcp/launcher-helper.ts +200 -0
  49. package/src/{agent-tools → mcp}/tool-defaults.ts +6 -5
  50. package/src/{agent-tools → mcp}/tool-generator.ts +6 -6
  51. package/src/{agent-tools → mcp}/types.ts +9 -4
  52. package/src/utils.ts +10 -1
  53. /package/dist/es/{agent-tools → mcp}/agent-behavior-init-args.mjs +0 -0
  54. /package/dist/es/{agent-tools → mcp}/cli-report-session.mjs +0 -0
  55. /package/dist/es/{agent-tools → mcp}/error-formatter.mjs +0 -0
  56. /package/dist/es/{agent-tools → mcp}/init-arg-utils.mjs +0 -0
  57. /package/dist/es/{agent-tools → mcp}/tool-defaults.mjs +0 -0
  58. /package/dist/es/{agent-tools → mcp}/types.mjs +0 -0
  59. /package/dist/es/{agent-tools → mcp}/user-prompt.mjs +0 -0
  60. /package/dist/lib/{agent-tools → mcp}/agent-behavior-init-args.js +0 -0
  61. /package/dist/lib/{agent-tools → mcp}/cli-report-session.js +0 -0
  62. /package/dist/lib/{agent-tools → mcp}/error-formatter.js +0 -0
  63. /package/dist/lib/{agent-tools → mcp}/init-arg-utils.js +0 -0
  64. /package/dist/lib/{agent-tools → mcp}/tool-defaults.js +0 -0
  65. /package/dist/lib/{agent-tools → mcp}/types.js +0 -0
  66. /package/dist/lib/{agent-tools → mcp}/user-prompt.js +0 -0
  67. /package/dist/types/{agent-tools → mcp}/agent-behavior-init-args.d.ts +0 -0
  68. /package/dist/types/{agent-tools → mcp}/chrome-path.d.ts +0 -0
  69. /package/dist/types/{agent-tools → mcp}/cli-report-session.d.ts +0 -0
  70. /package/dist/types/{agent-tools → mcp}/error-formatter.d.ts +0 -0
  71. /package/dist/types/{agent-tools → mcp}/user-prompt.d.ts +0 -0
  72. /package/src/{agent-tools → mcp}/agent-behavior-init-args.ts +0 -0
  73. /package/src/{agent-tools → mcp}/cli-report-session.ts +0 -0
  74. /package/src/{agent-tools → mcp}/error-formatter.ts +0 -0
  75. /package/src/{agent-tools → mcp}/user-prompt.ts +0 -0
@@ -88,11 +88,11 @@ export function sanitizeNamespacedArgs(
88
88
  }
89
89
 
90
90
  /**
91
- * Build a flat tool schema whose keys are dotted `"<namespace>.<field>"`.
91
+ * Build a flat MCP tool schema whose keys are dotted `"<namespace>.<field>"`.
92
92
  *
93
93
  * We intentionally stay flat (rather than `{ namespace: z.object({...}) }`) so
94
- * that CLI (`--android.device-id`) and `--help` output share the same spelling.
95
- * `readNamespacedArg` understands all three input shapes:
94
+ * that CLI (`--android.device-id`), MCP clients, and `--help` output all share
95
+ * the same spelling. `readNamespacedArg` understands all three input shapes:
96
96
  * nested namespace object, dotted flat key, and bare key fallback.
97
97
  */
98
98
  export function createNamespacedInitArgSchema(
@@ -0,0 +1,119 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ const MAGIC_STRING = 'REPLACE_ME_WITH_REPORT_HTML';
5
+ const REPLACED_MARK = '/*REPORT_HTML_REPLACED*/';
6
+ const REG_EXP_FOR_REPLACE = /\/\*REPORT_HTML_REPLACED\*\/.*/;
7
+
8
+ interface RslibPluginApi {
9
+ onAfterBuild: (callback: () => void) => void;
10
+ }
11
+
12
+ /**
13
+ * Rslib plugin to inject report HTML from @midscene/core dist into MCP bundle.
14
+ * This runs after build and reads the already-injected HTML from core.
15
+ *
16
+ * Prerequisites:
17
+ * - @midscene/report must be in devDependencies to ensure correct build order
18
+ * - @midscene/core dist must exist with injected HTML
19
+ *
20
+ * @param packageDir - The directory of the MCP package (use __dirname)
21
+ */
22
+ export function injectReportHtmlFromCore(packageDir: string) {
23
+ return {
24
+ name: 'inject-report-html-from-core',
25
+ setup(api: RslibPluginApi) {
26
+ api.onAfterBuild(() => {
27
+ const coreUtilsPath = path.resolve(
28
+ packageDir,
29
+ '..',
30
+ 'core',
31
+ 'dist',
32
+ 'lib',
33
+ 'utils.js',
34
+ );
35
+
36
+ if (!fs.existsSync(coreUtilsPath)) {
37
+ console.warn(
38
+ '[inject-report-html] @midscene/core dist not found, skipping',
39
+ );
40
+ return;
41
+ }
42
+
43
+ const coreContent = fs.readFileSync(coreUtilsPath, 'utf-8');
44
+ if (!coreContent.includes(REPLACED_MARK)) {
45
+ console.warn(
46
+ '[inject-report-html] HTML not found in core dist. Ensure report builds first.',
47
+ );
48
+ return;
49
+ }
50
+
51
+ // Extract the JSON string after the marker
52
+ // JSON strings can contain escaped quotes, so we need to properly parse it
53
+ const markerIndex = coreContent.indexOf(REPLACED_MARK);
54
+ const jsonStart = markerIndex + REPLACED_MARK.length;
55
+
56
+ // Find the end of the JSON string by tracking quote escaping
57
+ let jsonEnd = jsonStart;
58
+ if (coreContent[jsonStart] === '"') {
59
+ jsonEnd = jsonStart + 1;
60
+ while (jsonEnd < coreContent.length) {
61
+ if (coreContent[jsonEnd] === '\\') {
62
+ jsonEnd += 2; // Skip escaped character
63
+ } else if (coreContent[jsonEnd] === '"') {
64
+ jsonEnd += 1; // Include closing quote
65
+ break;
66
+ } else {
67
+ jsonEnd += 1;
68
+ }
69
+ }
70
+ }
71
+
72
+ const jsonString = coreContent.slice(jsonStart, jsonEnd);
73
+ if (!jsonString || jsonString.length < 10) {
74
+ console.warn('[inject-report-html] Failed to extract HTML from core');
75
+ return;
76
+ }
77
+
78
+ const finalContent = `${REPLACED_MARK}${jsonString}`;
79
+ const distDir = path.join(packageDir, 'dist');
80
+
81
+ if (!fs.existsSync(distDir)) return;
82
+
83
+ const jsFiles = fs
84
+ .readdirSync(distDir)
85
+ .filter((f) => f.endsWith('.js'));
86
+ let injectedCount = 0;
87
+
88
+ for (const file of jsFiles) {
89
+ const filePath = path.join(distDir, file);
90
+ const content = fs.readFileSync(filePath, 'utf-8');
91
+
92
+ if (content.includes(REPLACED_MARK)) {
93
+ if (REG_EXP_FOR_REPLACE.test(content)) {
94
+ fs.writeFileSync(
95
+ filePath,
96
+ content.replace(REG_EXP_FOR_REPLACE, () => finalContent),
97
+ );
98
+ console.log(`[inject-report-html] Updated: ${file}`);
99
+ injectedCount++;
100
+ }
101
+ } else if (content.includes(`'${MAGIC_STRING}'`)) {
102
+ fs.writeFileSync(
103
+ filePath,
104
+ content.replace(`'${MAGIC_STRING}'`, () => finalContent),
105
+ );
106
+ console.log(`[inject-report-html] Injected: ${file}`);
107
+ injectedCount++;
108
+ }
109
+ }
110
+
111
+ if (injectedCount > 0) {
112
+ console.log(
113
+ `[inject-report-html] Completed: ${injectedCount} file(s)`,
114
+ );
115
+ }
116
+ });
117
+ },
118
+ };
119
+ }
@@ -0,0 +1,200 @@
1
+ import type { BaseMCPServer } from './base-server';
2
+ import type { HttpLaunchOptions, LaunchMCPServerResult } from './base-server';
3
+ import type { IMidsceneTools } from './types';
4
+
5
+ export interface LaunchMCPServerOptions extends HttpLaunchOptions {
6
+ /**
7
+ * Whether to show server logs
8
+ * @default true
9
+ */
10
+ verbose?: boolean;
11
+ }
12
+
13
+ /**
14
+ * Generic agent type (avoid importing from @midscene/core to prevent circular deps)
15
+ */
16
+ export interface GenericAgent<TDevice = any> {
17
+ interface: TDevice;
18
+ constructor: { name: string };
19
+ }
20
+
21
+ /**
22
+ * Additional information for logging server startup
23
+ */
24
+ export interface StartupInfo {
25
+ port?: number;
26
+ host?: string;
27
+ }
28
+
29
+ export interface MCPServerLauncherConfig<
30
+ AgentType extends GenericAgent = GenericAgent,
31
+ ToolsManagerType extends IMidsceneTools = IMidsceneTools,
32
+ > {
33
+ agent: AgentType;
34
+ platformName: string;
35
+ ToolsManagerClass: new (...args: any[]) => ToolsManagerType;
36
+ MCPServerClass: new (toolsManager?: ToolsManagerType) => BaseMCPServer;
37
+ }
38
+
39
+ /**
40
+ * Create a generic MCP server launcher for a given agent, tools manager, and MCP server.
41
+ *
42
+ * This helper centralizes the common wiring logic used by platform-specific launchers:
43
+ * it constructs a tools manager, attaches the provided `agent` to it, then instantiates
44
+ * the `MCPServerClass` and exposes convenience methods to start the server over stdio
45
+ * (`launch`) or HTTP (`launchHttp`).
46
+ *
47
+ * Use this helper when adding a new platform-specific launcher or when you want to
48
+ * avoid duplicating boilerplate code for starting an MCP server. Typically, callers
49
+ * provide:
50
+ * - an `agent` instance that contains the underlying device on its `interface` property
51
+ * - a `ToolsManagerClass` that knows how to expose tools for that agent
52
+ * - an `MCPServerClass` that implements the MCP protocol and supports `launch` and
53
+ * `launchHttp` methods.
54
+ *
55
+ * The returned object has two methods:
56
+ * - `launch(options?)` to start the server using stdio transport
57
+ * - `launchHttp(options)` to start the server using HTTP transport
58
+ * Both methods accept a `verbose` flag to control console logging.
59
+ *
60
+ * @param config Configuration describing the agent, platform name (for logging),
61
+ * tools manager implementation, and MCP server implementation.
62
+ *
63
+ * @returns An object with `launch` and `launchHttp` methods to start the MCP server.
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * import { createMCPServerLauncher } from '@midscene/shared/mcp';
68
+ * import { Agent } from '@midscene/core/agent';
69
+ * import { WebMidsceneTools } from './web-tools';
70
+ * import { WebMCPServer } from './server';
71
+ *
72
+ * const agent = new Agent();
73
+ * const launcher = createMCPServerLauncher({
74
+ * agent,
75
+ * platformName: 'Web',
76
+ * ToolsManagerClass: WebMidsceneTools,
77
+ * MCPServerClass: WebMCPServer,
78
+ * });
79
+ *
80
+ * // Start with stdio
81
+ * await launcher.launch({ verbose: true });
82
+ *
83
+ * // Or start with HTTP
84
+ * await launcher.launchHttp({ port: 3000, host: 'localhost' });
85
+ * ```
86
+ *
87
+ * @internal
88
+ */
89
+ export function createMCPServerLauncher<
90
+ AgentType extends GenericAgent,
91
+ ToolsManagerType extends IMidsceneTools,
92
+ >(config: MCPServerLauncherConfig<AgentType, ToolsManagerType>) {
93
+ const { agent, platformName, ToolsManagerClass, MCPServerClass } = config;
94
+
95
+ /**
96
+ * Validate that the agent has the required interface property
97
+ * @throws {Error} If agent.interface is missing
98
+ */
99
+ function validateAgent(): void {
100
+ const device = agent.interface;
101
+ if (!device) {
102
+ throw new Error(
103
+ `Agent must have an 'interface' property that references the underlying device.
104
+ Please ensure your agent instance is properly initialized with a device interface.
105
+ Expected: agent.interface to be defined, but got: ${typeof device}
106
+ Solution: Check that your agent constructor properly sets the interface property.`,
107
+ );
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Create and configure a tools manager with the agent
113
+ * @returns Configured tools manager instance
114
+ */
115
+ function createToolsManager(): ToolsManagerType {
116
+ const toolsManager = new ToolsManagerClass();
117
+ // Type-safe agent injection: define explicit interface for tools manager with agent
118
+ interface ToolsManagerWithAgent extends IMidsceneTools {
119
+ agent: AgentType;
120
+ }
121
+ (toolsManager as unknown as ToolsManagerWithAgent).agent = agent;
122
+ return toolsManager;
123
+ }
124
+
125
+ /**
126
+ * Log server startup information
127
+ * @param mode - Transport mode ('stdio' or 'HTTP')
128
+ * @param additionalInfo - Additional info to log (e.g., port, host)
129
+ */
130
+ function logStartupInfo(
131
+ mode: 'stdio' | 'HTTP',
132
+ additionalInfo?: StartupInfo,
133
+ ): void {
134
+ const device = agent.interface;
135
+ console.log(`Starting Midscene ${platformName} MCP Server (${mode})...`);
136
+ console.log(`Agent: ${agent.constructor.name}`);
137
+ console.log(`Device: ${device.constructor.name}`);
138
+
139
+ if (additionalInfo?.port !== undefined) {
140
+ console.log(`Port: ${additionalInfo.port}`);
141
+ }
142
+ if (additionalInfo?.host) {
143
+ console.log(`Host: ${additionalInfo.host}`);
144
+ }
145
+ }
146
+
147
+ return {
148
+ /**
149
+ * Launch the MCP server with stdio transport
150
+ */
151
+ async launch(
152
+ options: { verbose?: boolean } = {},
153
+ ): Promise<LaunchMCPServerResult> {
154
+ const { verbose = true } = options;
155
+
156
+ validateAgent();
157
+
158
+ if (verbose) {
159
+ logStartupInfo('stdio');
160
+ }
161
+
162
+ const toolsManager = createToolsManager();
163
+ const server = new MCPServerClass(toolsManager);
164
+ const result = await server.launch();
165
+
166
+ if (verbose) {
167
+ console.log(`${platformName} MCP Server started (stdio mode)`);
168
+ }
169
+
170
+ return result;
171
+ },
172
+
173
+ /**
174
+ * Launch the MCP server with HTTP transport
175
+ */
176
+ async launchHttp(
177
+ options: LaunchMCPServerOptions,
178
+ ): Promise<LaunchMCPServerResult> {
179
+ const { port, host = 'localhost', verbose = true } = options;
180
+
181
+ validateAgent();
182
+
183
+ if (verbose) {
184
+ logStartupInfo('HTTP', { port, host });
185
+ }
186
+
187
+ const toolsManager = createToolsManager();
188
+ const server = new MCPServerClass(toolsManager);
189
+ const result = await server.launchHttp({ port, host });
190
+
191
+ if (verbose) {
192
+ console.log(
193
+ `${platformName} MCP Server started on http://${result.host}:${result.port}/mcp`,
194
+ );
195
+ }
196
+
197
+ return result;
198
+ },
199
+ };
200
+ }
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Unified, declarative mechanism for "force a default option on every tool
3
- * call" behaviors exposed by device and Agent Skill CLIs.
3
+ * call" behaviors exposed by MCP servers and the device / Agent Skill CLIs.
4
4
  *
5
5
  * Adding a new behavior flag (e.g. `--deep-search`) is a one-line change to
6
6
  * {@link TOOL_BEHAVIOR_FLAGS}: declare which default-option "bag" it fills.
7
- * The tool generator, tools managers and CLI parsing are all generic
7
+ * The tool generator, servers, tools managers and CLI parsing are all generic
8
8
  * over {@link ToolDefaults} and never need to learn about individual flags.
9
9
  *
10
10
  * See https://github.com/web-infra-dev/midscene/issues/2446.
@@ -91,12 +91,13 @@ export function resolveToolDefaults(
91
91
  *
92
92
  * Behavior flags (e.g. `--deep-locate`) are global: they may appear anywhere
93
93
  * in argv and are not tied to a specific sub-command. They are recognized by
94
- * exact kebab-case match and removed so a strict per-command parser never sees them. Every other
94
+ * exact kebab-case match the same surface the MCP `parseArgs` config exposes
95
+ * — and removed so a strict per-command parser never sees them. Every other
95
96
  * token is returned untouched and in order for that per-command parser.
96
97
  *
97
98
  * This is the single place that knows how a behavior flag looks on the command
98
- * line; the device / Agent Skill CLI resolves defaults from
99
- * {@link TOOL_BEHAVIOR_FLAGS} through here / {@link resolveToolDefaults}.
99
+ * line; both the device / Agent Skill CLI and the MCP launch path resolve their
100
+ * defaults from {@link TOOL_BEHAVIOR_FLAGS} through here / {@link resolveToolDefaults}.
100
101
  */
101
102
  export function stripBehaviorFlags(argv: readonly string[]): {
102
103
  rawArgs: string[];
@@ -21,10 +21,10 @@ import { composeUserPrompt, promptInputExtraSchema } from './user-prompt';
21
21
  export { composeUserPrompt };
22
22
 
23
23
  /**
24
- * Generate tool description from ActionSpaceItem.
24
+ * Generate MCP tool description from ActionSpaceItem
25
25
  * Format: "actionName action, description. Parameters: param1 (type) - desc; param2 (type) - desc"
26
26
  */
27
- function describeActionForTool(action: ActionSpaceItem): string {
27
+ function describeActionForMCP(action: ActionSpaceItem): string {
28
28
  const actionDesc = action.description || `Execute ${action.name} action`;
29
29
 
30
30
  if (!action.paramSchema) {
@@ -166,7 +166,7 @@ function transformSchemaField(
166
166
  /**
167
167
  * Extract and transform schema from action's paramSchema.
168
168
  *
169
- * CLI tools expose parameters as named fields, so the only schema
169
+ * CLI and MCP both expose parameters as named fields, so the only schema
170
170
  * shapes we can surface are ZodObject (any number of fields) or undefined
171
171
  * (the action takes no parameters). A primitive schema like `z.string()`
172
172
  * silently degraded to leaking the ZodString instance's prototype methods
@@ -188,7 +188,7 @@ function extractActionSchema(
188
188
  (paramSchema as unknown as { _def?: { typeName?: string } })?._def
189
189
  ?.typeName ?? 'unknown';
190
190
  throw new Error(
191
- `Action "${actionName}" declared a non-object paramSchema (${typeName}). CLI tool schemas must be a ZodObject (e.g. z.object({ uri: z.string() })) or undefined. Wrap primitive fields in an object schema.`,
191
+ `Action "${actionName}" declared a non-object paramSchema (${typeName}). CLI and MCP tool schemas must be a ZodObject (e.g. z.object({ uri: z.string() })) or undefined. Wrap primitive fields in an object schema.`,
192
192
  );
193
193
  }
194
194
 
@@ -543,7 +543,7 @@ function mergeToolCliMetadata(
543
543
  }
544
544
 
545
545
  /**
546
- * Converts DeviceAction from actionSpace into ToolDefinition.
546
+ * Converts DeviceAction from actionSpace into MCP ToolDefinition
547
547
  * This is the core logic that removes need for hardcoded tool definitions
548
548
  */
549
549
  export function generateToolsFromActionSpace(
@@ -564,7 +564,7 @@ export function generateToolsFromActionSpace(
564
564
 
565
565
  return {
566
566
  name: action.name,
567
- description: describeActionForTool(action),
567
+ description: describeActionForMCP(action),
568
568
  schema,
569
569
  cli: initArgCliMetadata,
570
570
  handler: async (args: Record<string, unknown>) => {
@@ -1,3 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
1
2
  import type { z } from 'zod';
2
3
  import type { ToolDefaults } from './tool-defaults';
3
4
 
@@ -11,7 +12,7 @@ export const defaultAppLoadingTimeoutMs = 10000;
11
12
  export const defaultAppLoadingCheckIntervalMs = 2000;
12
13
 
13
14
  /**
14
- * Content item types for tool results.
15
+ * Content item types for tool results (MCP compatible)
15
16
  */
16
17
  export type ToolResultContent =
17
18
  | { type: 'text'; text: string }
@@ -25,7 +26,7 @@ export type ToolResultContent =
25
26
  };
26
27
 
27
28
  /**
28
- * Result type for tool execution.
29
+ * Result type for tool execution (MCP compatible)
29
30
  */
30
31
  export interface ToolResult {
31
32
  [x: string]: unknown;
@@ -57,7 +58,7 @@ export interface ToolCliMetadata {
57
58
  }
58
59
 
59
60
  /**
60
- * Tool definition for Midscene CLI and Skill surfaces.
61
+ * Tool definition for MCP server
61
62
  */
62
63
  export interface ToolDefinition<T = Record<string, unknown>> {
63
64
  name: string;
@@ -67,6 +68,9 @@ export interface ToolDefinition<T = Record<string, unknown>> {
67
68
  cli?: ToolCliMetadata;
68
69
  }
69
70
 
71
+ /**
72
+ * Tool type for mcpKitForAgent return value
73
+ */
70
74
  export type Tool = ToolDefinition;
71
75
 
72
76
  /**
@@ -156,9 +160,10 @@ export interface BaseDevice {
156
160
  }
157
161
 
158
162
  /**
159
- * Interface for platform-specific tools manager.
163
+ * Interface for platform-specific MCP tools manager
160
164
  */
161
165
  export interface IMidsceneTools {
166
+ attachToServer(server: McpServer): void;
162
167
  initTools(): Promise<void>;
163
168
  destroy?(): Promise<void>;
164
169
  setToolDefaults?(toolDefaults: ToolDefaults): void;
package/src/utils.ts CHANGED
@@ -64,8 +64,17 @@ export function assert(condition: any, message?: string): asserts condition {
64
64
  }
65
65
  }
66
66
 
67
+ let isMcp = false;
68
+
69
+ export function setIsMcp(value: boolean) {
70
+ isMcp = value;
71
+ }
72
+
73
+ //mcp need use obj format to console msg: https://github.com/modelcontextprotocol/typescript-sdk/issues/244
67
74
  export function logMsg(...message: Parameters<typeof console.log>) {
68
- console.log(...message);
75
+ if (!isMcp) {
76
+ console.log(...message);
77
+ }
69
78
  }
70
79
 
71
80
  export async function repeat(
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes