Skip to content

Commit eb62d54

Browse files
committed
refactor(agent-infra): mcp-client esm to cjs
1 parent 8d3c795 commit eb62d54

File tree

11 files changed

+341
-386
lines changed

11 files changed

+341
-386
lines changed

apps/agent-tars/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"devDependencies": {
5252
"jsonrepair": "3.12.0",
5353
"serialize-javascript": "6.0.2",
54-
"@modelcontextprotocol/sdk": "^1.10.0",
54+
"@modelcontextprotocol/sdk": "^1.10.2",
5555
"@electron-toolkit/preload": "^3.0.1",
5656
"@electron-toolkit/utils": "^4.0.0",
5757
"@electron/asar": "^3.2.18",

apps/agent-tars/src/renderer/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"path-browserify": "1.0.1"
4646
},
4747
"devDependencies": {
48-
"@modelcontextprotocol/sdk": "^1.10.0",
48+
"@modelcontextprotocol/sdk": "^1.10.2",
4949
"typescript": "^5.7.3",
5050
"@types/react": "^18.3.18",
5151
"@types/react-dom": "^18.3.5",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
/*
2+
* Copyright (c) 2025 Bytedance, Inc. and its affiliates.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
import { AzureOpenAI } from 'openai';
6+
import { MCPClient, MCPTool } from '../src/index';
7+
import {
8+
ChatCompletionMessageParam,
9+
ChatCompletionTool,
10+
} from 'openai/resources/index.mjs';
11+
import {
12+
client as mcpBrowserClient,
13+
// setInitialBrowser,
14+
} from '@agent-infra/mcp-server-browser';
15+
import { client as mcpCommandsClient } from '@agent-infra/mcp-server-commands';
16+
import {
17+
client as mcpFilesystemClient,
18+
setAllowedDirectories,
19+
} from '@agent-infra/mcp-server-filesystem';
20+
import path from 'node:path';
21+
22+
const currentDir = path.join(__dirname, '../');
23+
const PLANNING_SYSTEM_PROMPT = `
24+
You are an expert Planning Agent tasked with solving problems efficiently through structured plans.
25+
Your job is:
26+
1. Analyze requests to understand the task scope
27+
2. Create a clear, actionable plan that makes meaningful progress with the \`planning\` tool
28+
3. Execute steps using available tools as needed
29+
4. Track progress and adapt plans when necessary
30+
5. Use \`finish\` to conclude immediately when the task is complete
31+
32+
33+
Available tools will vary by task but may include:
34+
- \`planning\`: Create, update, and track plans (commands: create, update, mark_step, etc.)
35+
- \`finish\`: End the task when complete
36+
Break tasks into logical steps with clear outcomes. Avoid excessive detail or sub-steps.
37+
Think about dependencies and verification methods.
38+
Know when to conclude - don't continue thinking once objectives are met.
39+
`;
40+
41+
const NEXT_STEP_PROMPT = `
42+
Based on the current state, what's your next action?
43+
Choose the most efficient path forward:
44+
1. Is the plan sufficient, or does it need refinement?
45+
2. Can you execute the next step immediately?
46+
3. Is the task complete? If so, use \`finish\` right away.
47+
48+
Be concise in your reasoning, then select the appropriate tool or action.
49+
`;
50+
51+
const supportedAttributes = [
52+
'type',
53+
'nullable',
54+
'required',
55+
// 'format',
56+
'description',
57+
'properties',
58+
'items',
59+
'enum',
60+
'anyOf',
61+
];
62+
function filterPropertieAttributes(tool: MCPTool) {
63+
const roperties = tool.inputSchema.properties;
64+
const getSubMap = (obj: Record<string, any>, keys: string[]) => {
65+
return Object.fromEntries(
66+
Object.entries(obj).filter(([key]) => keys.includes(key)),
67+
);
68+
};
69+
70+
for (const [key, val] of Object.entries(roperties as any)) {
71+
// @ts-ignore
72+
roperties[key] = getSubMap(val as any, supportedAttributes);
73+
}
74+
return roperties;
75+
}
76+
77+
function mcpToolsToOpenAITools(mcpTools: MCPTool[]): Array<ChatCompletionTool> {
78+
return mcpTools.map((tool) => ({
79+
type: 'function',
80+
function: {
81+
name: tool.name,
82+
description: tool.description,
83+
parameters: {
84+
type: 'object',
85+
properties: filterPropertieAttributes(tool),
86+
},
87+
},
88+
}));
89+
}
90+
91+
function mcpToolsToAnthropicTools(mcpTools: MCPTool[]): Array<any> {
92+
return mcpTools.map((tool) => {
93+
const t = {
94+
name: tool.id,
95+
description: tool.description,
96+
// @ts-ignore no check
97+
input_schema: tool.inputSchema,
98+
};
99+
return t;
100+
});
101+
}
102+
103+
function mcpToolsToAzureTools(mcpTools: MCPTool[]): Array<any> {
104+
return mcpTools.map((tool) => {
105+
const t = {
106+
type: 'function',
107+
function: {
108+
name: tool.name,
109+
description: tool.description,
110+
// @ts-ignore no check
111+
parameters: tool.inputSchema,
112+
},
113+
};
114+
return t;
115+
});
116+
}
117+
118+
function toolUseToMcpTool(
119+
mcpTools: MCPTool[] | undefined,
120+
toolUse: any,
121+
): MCPTool | undefined {
122+
if (!mcpTools) return undefined;
123+
const tool = mcpTools.find((tool) => tool.name === toolUse.function.name);
124+
if (!tool) {
125+
return undefined;
126+
}
127+
// @ts-ignore ignore type as it it unknow
128+
tool.inputSchema = JSON.parse(toolUse.function.arguments);
129+
return tool;
130+
}
131+
132+
(async () => {
133+
const client = new MCPClient(
134+
[
135+
// {
136+
// name: 'browser',
137+
// description: 'web browser tools',
138+
// localClient: mcpBrowserClient,
139+
// },
140+
// {
141+
// name: 'filesystem',
142+
// description: 'filesystem tools',
143+
// localClient: mcpFilesystemClient,
144+
// },
145+
{
146+
name: 'add_function',
147+
description: 'add function',
148+
type: 'sse',
149+
url: 'https://6vknhcia.mcp.bytedance.net/sse',
150+
headers: {
151+
Authorization: 'Bearer user@example.com:foo:bar',
152+
},
153+
},
154+
// {
155+
// name: 'filesystem',
156+
// command: 'npx',
157+
// args: [
158+
// '-y',
159+
// '@agent-infra/mcp-server-filesystem',
160+
// path.join(__dirname, '../'),
161+
// ],
162+
// },
163+
// {
164+
// name: 'commands',
165+
// description: 'commands tools',
166+
// localClient: mcpCommandsClient,
167+
// },
168+
// {
169+
// name: 'browser',
170+
// command: 'npx',
171+
// args: ['-y', '@agent-infra/mcp-server-browser'],
172+
// },
173+
],
174+
{
175+
isDebug: true,
176+
},
177+
);
178+
179+
// await client.init();
180+
181+
setAllowedDirectories([currentDir]);
182+
183+
// setInitialBrowser(your_browser, your_page);
184+
185+
const tools = await client.listTools();
186+
console.log('toolstools', tools);
187+
188+
// const openai = new AzureOpenAI({
189+
// endpoint: process.env.AZURE_OPENAI_ENDPOINT,
190+
// apiVersion: process.env.AZURE_OPENAI_API_VERSION,
191+
// apiKey: process.env.AZURE_OPENAI_API_KEY,
192+
// });
193+
194+
// const azureTools = mcpToolsToAzureTools(tools);
195+
// console.log('azureTools', azureTools);
196+
197+
// const messages: ChatCompletionMessageParam[] = [
198+
// {
199+
// role: 'system',
200+
// content: PLANNING_SYSTEM_PROMPT,
201+
// },
202+
// {
203+
// role: 'user',
204+
// content: `将 \"hello world\" 写入到文件 todo.md 中,用户当前目录是 ${currentDir}`,
205+
// },
206+
// ];
207+
208+
// const pcScreenshotName = 'pc_screenshot';
209+
210+
// while (true) {
211+
// if (messages.length > 0) {
212+
// if (messages[messages.length - 1].role === 'tool') {
213+
// const screenshotResule = await client.callTool({
214+
// client: 'browser',
215+
// name: 'browser_screenshot',
216+
// args: {
217+
// name: pcScreenshotName,
218+
// },
219+
// });
220+
// messages.push({
221+
// role: 'user',
222+
// content: [
223+
// ...((screenshotResule.content as any).map((item: any) => {
224+
// if (item.type === 'image') {
225+
// return {
226+
// type: 'image_url',
227+
// image_url: {
228+
// url: `data:image/png;base64,aaaa`,
229+
// },
230+
// };
231+
// }
232+
// return item;
233+
// }) || []),
234+
// {
235+
// type: 'text',
236+
// text: NEXT_STEP_PROMPT,
237+
// },
238+
// ],
239+
// });
240+
// } else if (messages[messages.length - 1].role === 'assistant') {
241+
// messages.push({
242+
// role: 'user',
243+
// content: NEXT_STEP_PROMPT,
244+
// });
245+
// }
246+
// }
247+
248+
// console.log('messages', JSON.stringify(messages, null, 4));
249+
250+
// const response = await openai.chat.completions.create({
251+
// model: process.env.AZURE_OPENAI_MODEL || '',
252+
// messages,
253+
// tools: azureTools,
254+
// tool_choice: 'auto',
255+
// max_tokens: 5120,
256+
// stream: false,
257+
// });
258+
259+
// console.log('response.choices', response.choices);
260+
261+
// const choice = response.choices[0];
262+
// if (!choice.message) continue;
263+
264+
// const responseMessage = response.choices[0].message;
265+
// messages.push({
266+
// role: responseMessage.role,
267+
// content: responseMessage.content,
268+
// });
269+
270+
// console.log('choice.message', choice.message.tool_calls);
271+
272+
// if (response.choices.length > 0) {
273+
// const toolResults = [];
274+
// for (const responseChoice of response.choices) {
275+
// for (const toolCall of responseChoice.message?.tool_calls || []) {
276+
// console.log(
277+
// `调用函数${toolCall.id}: ${toolCall.function.name}(${toolCall.function.arguments})`,
278+
// );
279+
// const mcpTool = toolUseToMcpTool(tools, toolCall);
280+
// if (mcpTool) {
281+
// const result = await client.callTool({
282+
// client: mcpTool?.serverName as 'commands' | 'browser',
283+
// name: mcpTool?.name,
284+
// args: mcpTool?.inputSchema,
285+
// });
286+
// console.log('result', result);
287+
// const { content } = result as any;
288+
// console.log('content', content);
289+
// toolResults.push({
290+
// name: mcpTool?.name,
291+
// role: 'tool' as const,
292+
// tool_call_id: toolCall.id,
293+
// content: JSON.stringify(content),
294+
// });
295+
// }
296+
// }
297+
// }
298+
299+
// messages.push(...toolResults);
300+
// console.log('messages_after_tool_call', messages);
301+
// }
302+
// }
303+
304+
await client.cleanup();
305+
})();

packages/agent-infra/mcp-client/package.json

+4-5
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@
33
"version": "0.4.3",
44
"description": "An MCP Client to run servers for Electron apps, support same-process approaching",
55
"private": false,
6-
"type": "module",
76
"types": "./dist/index.d.ts",
8-
"main": "./dist/index.cjs",
9-
"module": "./dist/index.js",
7+
"main": "./dist/index.js",
8+
"module": "./dist/index.mjs",
109
"files": [
1110
"dist"
1211
],
1312
"scripts": {
14-
"dev": "tsx src/test.ts",
13+
"dev": "tsx examples/test.ts",
1514
"clean": "rm -rf dist",
1615
"build": "rslib build",
1716
"prepare": "npm run build",
@@ -21,7 +20,7 @@
2120
"test:integration": "vitest tests/integration"
2221
},
2322
"dependencies": {
24-
"@modelcontextprotocol/sdk": "^1.10.0",
23+
"@modelcontextprotocol/sdk": "^1.10.2",
2524
"@agent-infra/mcp-shared": "workspace:*",
2625
"zod": "^3.23.8",
2726
"uuid": "^11.1.0"

0 commit comments

Comments
 (0)