mcp-use 0.1.20 → 0.3.0
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/dist/chunk-2HFIPY7C.js +429 -0
- package/dist/chunk-4DEFXVWT.js +680 -0
- package/dist/chunk-JXLQRAW2.js +532 -0
- package/dist/chunk-SHUYVCID.js +6 -0
- package/dist/chunk-YUSC6R6V.js +299 -0
- package/dist/index.cjs +5762 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3767 -22
- package/dist/langfuse-YA2S23SM.js +13 -0
- package/dist/src/agents/remote.d.ts.map +1 -1
- package/dist/src/agents/utils/ai_sdk.d.ts.map +1 -1
- package/dist/src/auth/browser-provider.d.ts +52 -0
- package/dist/src/auth/browser-provider.d.ts.map +1 -0
- package/dist/src/auth/callback.d.ts +6 -0
- package/dist/src/auth/callback.d.ts.map +1 -0
- package/dist/src/auth/index.d.ts +7 -0
- package/dist/src/auth/index.d.ts.map +1 -0
- package/dist/src/auth/types.d.ts +18 -0
- package/dist/src/auth/types.d.ts.map +1 -0
- package/dist/src/browser.cjs +323 -0
- package/dist/src/browser.d.ts +8 -0
- package/dist/src/browser.d.ts.map +1 -0
- package/dist/src/browser.js +9 -0
- package/dist/src/client/base.d.ts +32 -0
- package/dist/src/client/base.d.ts.map +1 -0
- package/dist/src/client.d.ts +19 -16
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/logging.d.ts +1 -1
- package/dist/src/logging.d.ts.map +1 -1
- package/dist/src/oauth-helper.d.ts +125 -0
- package/dist/src/oauth-helper.d.ts.map +1 -0
- package/dist/src/react/index.cjs +986 -0
- package/dist/src/react/index.d.ts +9 -0
- package/dist/src/react/index.d.ts.map +1 -0
- package/dist/src/react/index.js +11 -0
- package/dist/src/react/types.d.ts +139 -0
- package/dist/src/react/types.d.ts.map +1 -0
- package/dist/src/react/useMcp.d.ts +3 -0
- package/dist/src/react/useMcp.d.ts.map +1 -0
- package/dist/src/server/index.cjs +566 -0
- package/dist/src/server/index.d.ts +3 -0
- package/dist/src/server/index.d.ts.map +1 -0
- package/dist/src/server/index.js +9 -0
- package/dist/src/server/logging.d.ts +16 -0
- package/dist/src/server/logging.d.ts.map +1 -0
- package/dist/src/server/mcp-server.d.ts +282 -0
- package/dist/src/server/mcp-server.d.ts.map +1 -0
- package/dist/src/server/types.d.ts +47 -0
- package/dist/src/server/types.d.ts.map +1 -0
- package/dist/src/utils/assert.d.ts +8 -0
- package/dist/src/utils/assert.d.ts.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +72 -40
- package/dist/examples/add_server_tool.d.ts +0 -8
- package/dist/examples/add_server_tool.d.ts.map +0 -1
- package/dist/examples/add_server_tool.js +0 -79
- package/dist/examples/ai_sdk_example.d.ts +0 -23
- package/dist/examples/ai_sdk_example.d.ts.map +0 -1
- package/dist/examples/ai_sdk_example.js +0 -213
- package/dist/examples/airbnb_use.d.ts +0 -10
- package/dist/examples/airbnb_use.d.ts.map +0 -1
- package/dist/examples/airbnb_use.js +0 -43
- package/dist/examples/blender_use.d.ts +0 -15
- package/dist/examples/blender_use.d.ts.map +0 -1
- package/dist/examples/blender_use.js +0 -39
- package/dist/examples/browser_use.d.ts +0 -10
- package/dist/examples/browser_use.d.ts.map +0 -1
- package/dist/examples/browser_use.js +0 -46
- package/dist/examples/chat_example.d.ts +0 -10
- package/dist/examples/chat_example.d.ts.map +0 -1
- package/dist/examples/chat_example.js +0 -86
- package/dist/examples/filesystem_use.d.ts +0 -11
- package/dist/examples/filesystem_use.d.ts.map +0 -1
- package/dist/examples/filesystem_use.js +0 -43
- package/dist/examples/http_example.d.ts +0 -18
- package/dist/examples/http_example.d.ts.map +0 -1
- package/dist/examples/http_example.js +0 -37
- package/dist/examples/mcp_everything.d.ts +0 -6
- package/dist/examples/mcp_everything.d.ts.map +0 -1
- package/dist/examples/mcp_everything.js +0 -25
- package/dist/examples/multi_server_example.d.ts +0 -10
- package/dist/examples/multi_server_example.d.ts.map +0 -1
- package/dist/examples/multi_server_example.js +0 -51
- package/dist/examples/observability.d.ts +0 -6
- package/dist/examples/observability.d.ts.map +0 -1
- package/dist/examples/observability.js +0 -50
- package/dist/examples/stream_example.d.ts +0 -12
- package/dist/examples/stream_example.d.ts.map +0 -1
- package/dist/examples/stream_example.js +0 -198
- package/dist/examples/structured_output.d.ts +0 -9
- package/dist/examples/structured_output.d.ts.map +0 -1
- package/dist/examples/structured_output.js +0 -95
- package/dist/src/adapters/base.js +0 -124
- package/dist/src/adapters/index.js +0 -2
- package/dist/src/adapters/langchain_adapter.js +0 -49
- package/dist/src/agents/base.js +0 -9
- package/dist/src/agents/index.js +0 -3
- package/dist/src/agents/mcp_agent.js +0 -1002
- package/dist/src/agents/prompts/system_prompt_builder.js +0 -40
- package/dist/src/agents/prompts/templates.js +0 -39
- package/dist/src/agents/remote.js +0 -264
- package/dist/src/agents/utils/ai_sdk.js +0 -62
- package/dist/src/agents/utils/index.js +0 -1
- package/dist/src/client.js +0 -133
- package/dist/src/config.js +0 -34
- package/dist/src/connectors/base.js +0 -143
- package/dist/src/connectors/http.js +0 -150
- package/dist/src/connectors/index.js +0 -4
- package/dist/src/connectors/stdio.js +0 -68
- package/dist/src/connectors/websocket.js +0 -157
- package/dist/src/logging.js +0 -217
- package/dist/src/managers/index.js +0 -2
- package/dist/src/managers/server_manager.js +0 -106
- package/dist/src/managers/tools/acquire_active_mcp_server.js +0 -17
- package/dist/src/managers/tools/add_server_from_config.js +0 -40
- package/dist/src/managers/tools/base.js +0 -17
- package/dist/src/managers/tools/connect_mcp_server.js +0 -46
- package/dist/src/managers/tools/index.js +0 -5
- package/dist/src/managers/tools/list_mcp_servers.js +0 -33
- package/dist/src/managers/tools/release_mcp_server_connection.js +0 -19
- package/dist/src/observability/index.js +0 -12
- package/dist/src/observability/langfuse.js +0 -211
- package/dist/src/observability/manager.js +0 -199
- package/dist/src/observability/types.js +0 -4
- package/dist/src/session.js +0 -23
- package/dist/src/task_managers/base.js +0 -127
- package/dist/src/task_managers/index.js +0 -5
- package/dist/src/task_managers/sse.js +0 -43
- package/dist/src/task_managers/stdio.js +0 -51
- package/dist/src/task_managers/streamable_http.js +0 -50
- package/dist/src/task_managers/websocket.js +0 -67
- package/dist/src/telemetry/events.js +0 -44
- package/dist/src/telemetry/index.js +0 -8
- package/dist/src/telemetry/telemetry.js +0 -324
- package/dist/src/telemetry/utils.js +0 -39
- package/dist/tests/ai_sdk_compatibility.test.js +0 -214
- package/dist/tests/stream_events.test.js +0 -307
- package/dist/tests/stream_events_simple.test.js +0 -179
- package/dist/vitest.config.js +0 -21
@@ -1,40 +0,0 @@
|
|
1
|
-
import { SystemMessage } from '@langchain/core/messages';
|
2
|
-
export function generateToolDescriptions(tools, disallowedTools) {
|
3
|
-
const disallowedSet = new Set(disallowedTools ?? []);
|
4
|
-
const descriptions = [];
|
5
|
-
for (const tool of tools) {
|
6
|
-
if (disallowedSet.has(tool.name))
|
7
|
-
continue;
|
8
|
-
const escaped = tool.description
|
9
|
-
.replace(/\{/g, '{{')
|
10
|
-
.replace(/\}/g, '}}');
|
11
|
-
descriptions.push(`- ${tool.name}: ${escaped}`);
|
12
|
-
}
|
13
|
-
return descriptions;
|
14
|
-
}
|
15
|
-
export function buildSystemPromptContent(template, toolDescriptionLines, additionalInstructions) {
|
16
|
-
const block = toolDescriptionLines.join('\n');
|
17
|
-
let content;
|
18
|
-
if (template.includes('{tool_descriptions}')) {
|
19
|
-
content = template.replace('{tool_descriptions}', block);
|
20
|
-
}
|
21
|
-
else {
|
22
|
-
console.warn('`{tool_descriptions}` placeholder not found; appending at end.');
|
23
|
-
content = `${template}\n\nAvailable tools:\n${block}`;
|
24
|
-
}
|
25
|
-
if (additionalInstructions) {
|
26
|
-
content += `\n\n${additionalInstructions}`;
|
27
|
-
}
|
28
|
-
return content;
|
29
|
-
}
|
30
|
-
export function createSystemMessage(tools, systemPromptTemplate, serverManagerTemplate, useServerManager, disallowedTools, userProvidedPrompt, additionalInstructions) {
|
31
|
-
if (userProvidedPrompt) {
|
32
|
-
return new SystemMessage({ content: userProvidedPrompt });
|
33
|
-
}
|
34
|
-
const template = useServerManager
|
35
|
-
? serverManagerTemplate
|
36
|
-
: systemPromptTemplate;
|
37
|
-
const toolLines = generateToolDescriptions(tools, disallowedTools);
|
38
|
-
const finalContent = buildSystemPromptContent(template, toolLines, additionalInstructions);
|
39
|
-
return new SystemMessage({ content: finalContent });
|
40
|
-
}
|
@@ -1,39 +0,0 @@
|
|
1
|
-
export const DEFAULT_SYSTEM_PROMPT_TEMPLATE = `You are a helpful AI assistant.
|
2
|
-
You have access to the following tools:
|
3
|
-
|
4
|
-
{tool_descriptions}
|
5
|
-
|
6
|
-
Use the following format:
|
7
|
-
|
8
|
-
Question: the input question you must answer
|
9
|
-
Thought: you should always think about what to do
|
10
|
-
Action: the action to take, should be one of the available tools
|
11
|
-
Action Input: the input to the action
|
12
|
-
Observation: the result of the action
|
13
|
-
... (this Thought/Action/Action Input/Observation can repeat N times)
|
14
|
-
Thought: I now know the final answer
|
15
|
-
Final Answer: the final answer to the original input question`;
|
16
|
-
export const SERVER_MANAGER_SYSTEM_PROMPT_TEMPLATE = `You are a helpful assistant designed to interact with MCP
|
17
|
-
(Model Context Protocol) servers. You can manage connections to different servers and use the tools
|
18
|
-
provided by the currently active server.
|
19
|
-
|
20
|
-
Important: The available tools change depending on which server is active.
|
21
|
-
If a request requires tools not listed below (e.g., file operations, web browsing,
|
22
|
-
image manipulation), you MUST first connect to the appropriate server using
|
23
|
-
'connect_to_mcp_server'.
|
24
|
-
Use 'list_mcp_servers' to find the relevant server if you are unsure.
|
25
|
-
Only after successfully connecting and seeing the new tools listed in
|
26
|
-
the response should you attempt to use those server-specific tools.
|
27
|
-
Before attempting a task that requires specific tools, you should
|
28
|
-
ensure you are connected to the correct server and aware of its
|
29
|
-
available tools. If unsure, use 'list_mcp_servers' to see options
|
30
|
-
or 'get_active_mcp_server' to check the current connection.
|
31
|
-
|
32
|
-
When you connect to a server using 'connect_to_mcp_server',
|
33
|
-
you will be informed about the new tools that become available.
|
34
|
-
You can then use these server-specific tools in subsequent steps.
|
35
|
-
|
36
|
-
Here are the tools *currently* available to you (this list includes server management tools and will
|
37
|
-
change when you connect to a server):
|
38
|
-
{tool_descriptions}
|
39
|
-
`;
|
@@ -1,264 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* Remote agent implementation for executing agents via API.
|
3
|
-
*/
|
4
|
-
import { zodToJsonSchema } from 'zod-to-json-schema';
|
5
|
-
import { logger } from '../logging.js';
|
6
|
-
// API endpoint constants
|
7
|
-
const API_CHATS_ENDPOINT = '/api/v1/chats';
|
8
|
-
const API_CHAT_EXECUTE_ENDPOINT = '/api/v1/chats/{chat_id}/execute';
|
9
|
-
export class RemoteAgent {
|
10
|
-
agentId;
|
11
|
-
apiKey;
|
12
|
-
baseUrl;
|
13
|
-
chatId = null;
|
14
|
-
constructor(options) {
|
15
|
-
this.agentId = options.agentId;
|
16
|
-
this.baseUrl = options.baseUrl ?? 'https://cloud.mcp-use.com';
|
17
|
-
// Handle API key validation
|
18
|
-
const apiKey = options.apiKey ?? process.env.MCP_USE_API_KEY;
|
19
|
-
if (!apiKey) {
|
20
|
-
throw new Error('API key is required for remote execution. '
|
21
|
-
+ 'Please provide it as a parameter or set the MCP_USE_API_KEY environment variable. '
|
22
|
-
+ 'You can get an API key from https://cloud.mcp-use.com');
|
23
|
-
}
|
24
|
-
this.apiKey = apiKey;
|
25
|
-
}
|
26
|
-
pydanticToJsonSchema(schema) {
|
27
|
-
/**
|
28
|
-
* Convert a Zod schema to JSON schema for API transmission.
|
29
|
-
*/
|
30
|
-
return zodToJsonSchema(schema);
|
31
|
-
}
|
32
|
-
parseStructuredResponse(responseData, outputSchema) {
|
33
|
-
/**
|
34
|
-
* Parse the API response into the structured output format.
|
35
|
-
*/
|
36
|
-
let resultData;
|
37
|
-
// Handle different response formats
|
38
|
-
if (typeof responseData === 'object' && responseData !== null) {
|
39
|
-
if ('result' in responseData) {
|
40
|
-
const outerResult = responseData.result;
|
41
|
-
// Check if this is a nested result structure (agent execution response)
|
42
|
-
if (typeof outerResult === 'object' && outerResult !== null && 'result' in outerResult) {
|
43
|
-
// Extract the actual structured output from the nested result
|
44
|
-
resultData = outerResult.result;
|
45
|
-
}
|
46
|
-
else {
|
47
|
-
// Use the outer result directly
|
48
|
-
resultData = outerResult;
|
49
|
-
}
|
50
|
-
}
|
51
|
-
else {
|
52
|
-
resultData = responseData;
|
53
|
-
}
|
54
|
-
}
|
55
|
-
else if (typeof responseData === 'string') {
|
56
|
-
try {
|
57
|
-
resultData = JSON.parse(responseData);
|
58
|
-
}
|
59
|
-
catch {
|
60
|
-
// If it's not valid JSON, try to create the model from the string content
|
61
|
-
resultData = { content: responseData };
|
62
|
-
}
|
63
|
-
}
|
64
|
-
else {
|
65
|
-
resultData = responseData;
|
66
|
-
}
|
67
|
-
// Parse into the Zod schema
|
68
|
-
try {
|
69
|
-
return outputSchema.parse(resultData);
|
70
|
-
}
|
71
|
-
catch (e) {
|
72
|
-
logger.warn(`Failed to parse structured output: ${e}`);
|
73
|
-
// Fallback: try to parse it as raw content if the schema has a content field
|
74
|
-
const schemaShape = outputSchema._def?.shape();
|
75
|
-
if (schemaShape && 'content' in schemaShape) {
|
76
|
-
return outputSchema.parse({ content: String(resultData) });
|
77
|
-
}
|
78
|
-
throw e;
|
79
|
-
}
|
80
|
-
}
|
81
|
-
async createChatSession() {
|
82
|
-
/**
|
83
|
-
* Create a persistent chat session for the agent.
|
84
|
-
*/
|
85
|
-
const chatPayload = {
|
86
|
-
title: `Remote Agent Session - ${this.agentId}`,
|
87
|
-
agent_id: this.agentId,
|
88
|
-
type: 'agent_execution',
|
89
|
-
};
|
90
|
-
const headers = {
|
91
|
-
'Content-Type': 'application/json',
|
92
|
-
'x-api-key': this.apiKey,
|
93
|
-
};
|
94
|
-
const chatUrl = `${this.baseUrl}${API_CHATS_ENDPOINT}`;
|
95
|
-
logger.info(`📝 Creating chat session for agent ${this.agentId}`);
|
96
|
-
try {
|
97
|
-
const response = await fetch(chatUrl, {
|
98
|
-
method: 'POST',
|
99
|
-
headers,
|
100
|
-
body: JSON.stringify(chatPayload),
|
101
|
-
});
|
102
|
-
if (!response.ok) {
|
103
|
-
const responseText = await response.text();
|
104
|
-
const statusCode = response.status;
|
105
|
-
if (statusCode === 404) {
|
106
|
-
throw new Error(`Agent not found: Agent '${this.agentId}' does not exist or you don't have access to it. `
|
107
|
-
+ 'Please verify the agent ID and ensure it exists in your account.');
|
108
|
-
}
|
109
|
-
throw new Error(`Failed to create chat session: ${statusCode} - ${responseText}`);
|
110
|
-
}
|
111
|
-
const chatData = await response.json();
|
112
|
-
const chatId = chatData.id;
|
113
|
-
logger.info(`✅ Chat session created: ${chatId}`);
|
114
|
-
return chatId;
|
115
|
-
}
|
116
|
-
catch (e) {
|
117
|
-
if (e instanceof Error) {
|
118
|
-
throw new TypeError(`Failed to create chat session: ${e.message}`);
|
119
|
-
}
|
120
|
-
throw new Error(`Failed to create chat session: ${String(e)}`);
|
121
|
-
}
|
122
|
-
}
|
123
|
-
async run(query, maxSteps, manageConnector, externalHistory, outputSchema) {
|
124
|
-
/**
|
125
|
-
* Run a query on the remote agent.
|
126
|
-
*/
|
127
|
-
if (externalHistory !== undefined) {
|
128
|
-
logger.warn('External history is not yet supported for remote execution');
|
129
|
-
}
|
130
|
-
try {
|
131
|
-
logger.info(`🌐 Executing query on remote agent ${this.agentId}`);
|
132
|
-
// Step 1: Create a chat session for this agent (only if we don't have one)
|
133
|
-
if (this.chatId === null) {
|
134
|
-
this.chatId = await this.createChatSession();
|
135
|
-
}
|
136
|
-
const chatId = this.chatId;
|
137
|
-
// Step 2: Execute the agent within the chat context
|
138
|
-
const executionPayload = {
|
139
|
-
query,
|
140
|
-
max_steps: maxSteps ?? 10,
|
141
|
-
};
|
142
|
-
// Add structured output schema if provided
|
143
|
-
if (outputSchema) {
|
144
|
-
executionPayload.output_schema = this.pydanticToJsonSchema(outputSchema);
|
145
|
-
logger.info(`🔧 Using structured output with schema`);
|
146
|
-
}
|
147
|
-
const headers = {
|
148
|
-
'Content-Type': 'application/json',
|
149
|
-
'x-api-key': this.apiKey,
|
150
|
-
};
|
151
|
-
const executionUrl = `${this.baseUrl}${API_CHAT_EXECUTE_ENDPOINT.replace('{chat_id}', chatId)}`;
|
152
|
-
logger.info(`🚀 Executing agent in chat ${chatId}`);
|
153
|
-
const response = await fetch(executionUrl, {
|
154
|
-
method: 'POST',
|
155
|
-
headers,
|
156
|
-
body: JSON.stringify(executionPayload),
|
157
|
-
signal: AbortSignal.timeout(300000), // 5 minute timeout
|
158
|
-
});
|
159
|
-
if (!response.ok) {
|
160
|
-
const responseText = await response.text();
|
161
|
-
const statusCode = response.status;
|
162
|
-
// Provide specific error messages based on status code
|
163
|
-
if (statusCode === 401) {
|
164
|
-
logger.error(`❌ Authentication failed: ${responseText}`);
|
165
|
-
throw new Error('Authentication failed: Invalid or missing API key. '
|
166
|
-
+ 'Please check your API key and ensure the MCP_USE_API_KEY environment variable is set correctly.');
|
167
|
-
}
|
168
|
-
else if (statusCode === 403) {
|
169
|
-
logger.error(`❌ Access forbidden: ${responseText}`);
|
170
|
-
throw new Error(`Access denied: You don't have permission to execute agent '${this.agentId}'. `
|
171
|
-
+ 'Check if the agent exists and you have the necessary permissions.');
|
172
|
-
}
|
173
|
-
else if (statusCode === 404) {
|
174
|
-
logger.error(`❌ Agent not found: ${responseText}`);
|
175
|
-
throw new Error(`Agent not found: Agent '${this.agentId}' does not exist or you don't have access to it. `
|
176
|
-
+ 'Please verify the agent ID and ensure it exists in your account.');
|
177
|
-
}
|
178
|
-
else if (statusCode === 422) {
|
179
|
-
logger.error(`❌ Validation error: ${responseText}`);
|
180
|
-
throw new Error(`Request validation failed: ${responseText}. `
|
181
|
-
+ 'Please check your query parameters and output schema format.');
|
182
|
-
}
|
183
|
-
else if (statusCode === 500) {
|
184
|
-
logger.error(`❌ Server error: ${responseText}`);
|
185
|
-
throw new Error('Internal server error occurred during agent execution. '
|
186
|
-
+ 'Please try again later or contact support if the issue persists.');
|
187
|
-
}
|
188
|
-
else {
|
189
|
-
logger.error(`❌ Remote execution failed with status ${statusCode}: ${responseText}`);
|
190
|
-
throw new Error(`Remote agent execution failed: ${statusCode} - ${responseText}`);
|
191
|
-
}
|
192
|
-
}
|
193
|
-
const result = await response.json();
|
194
|
-
logger.info(`🔧 Response: ${JSON.stringify(result)}`);
|
195
|
-
logger.info('✅ Remote execution completed successfully');
|
196
|
-
// Check for error responses (even with 200 status)
|
197
|
-
if (typeof result === 'object' && result !== null) {
|
198
|
-
// Check for actual error conditions (not just presence of error field)
|
199
|
-
if (result.status === 'error' || result.error !== null) {
|
200
|
-
const errorMsg = result.error ?? String(result);
|
201
|
-
logger.error(`❌ Remote agent execution failed: ${errorMsg}`);
|
202
|
-
throw new Error(`Remote agent execution failed: ${errorMsg}`);
|
203
|
-
}
|
204
|
-
// Check if the response indicates agent initialization failure
|
205
|
-
if (String(result).includes('failed to initialize')) {
|
206
|
-
logger.error(`❌ Agent initialization failed: ${result}`);
|
207
|
-
throw new Error('Agent initialization failed on remote server. '
|
208
|
-
+ 'This usually indicates:\n'
|
209
|
-
+ '• Invalid agent configuration (LLM model, system prompt)\n'
|
210
|
-
+ '• Missing or invalid MCP server configurations\n'
|
211
|
-
+ '• Network connectivity issues with MCP servers\n'
|
212
|
-
+ '• Missing environment variables or credentials\n'
|
213
|
-
+ `Raw error: ${result}`);
|
214
|
-
}
|
215
|
-
}
|
216
|
-
// Handle structured output
|
217
|
-
if (outputSchema) {
|
218
|
-
return this.parseStructuredResponse(result, outputSchema);
|
219
|
-
}
|
220
|
-
// Regular string output
|
221
|
-
if (typeof result === 'object' && result !== null && 'result' in result) {
|
222
|
-
return result.result;
|
223
|
-
}
|
224
|
-
else if (typeof result === 'string') {
|
225
|
-
return result;
|
226
|
-
}
|
227
|
-
else {
|
228
|
-
return String(result);
|
229
|
-
}
|
230
|
-
}
|
231
|
-
catch (e) {
|
232
|
-
if (e instanceof Error) {
|
233
|
-
// Check for specific error types
|
234
|
-
if (e.name === 'AbortError') {
|
235
|
-
logger.error(`❌ Remote execution timed out: ${e}`);
|
236
|
-
throw new Error('Remote agent execution timed out. The server may be overloaded or the query is taking too long to '
|
237
|
-
+ 'process. Try again or use a simpler query.');
|
238
|
-
}
|
239
|
-
logger.error(`❌ Remote execution error: ${e}`);
|
240
|
-
throw new Error(`Remote agent execution failed: ${e.message}`);
|
241
|
-
}
|
242
|
-
logger.error(`❌ Remote execution error: ${e}`);
|
243
|
-
throw new Error(`Remote agent execution failed: ${String(e)}`);
|
244
|
-
}
|
245
|
-
}
|
246
|
-
async *stream(query, maxSteps, manageConnector, externalHistory, outputSchema) {
|
247
|
-
/**
|
248
|
-
* Stream implementation for remote agent - currently just wraps run.
|
249
|
-
* In the future, this could be enhanced to support actual streaming from the API.
|
250
|
-
*/
|
251
|
-
const result = await this.run(query, maxSteps, manageConnector, externalHistory, outputSchema);
|
252
|
-
return result;
|
253
|
-
}
|
254
|
-
async close() {
|
255
|
-
/**
|
256
|
-
* Close the remote agent connection.
|
257
|
-
*/
|
258
|
-
logger.info('🔌 Remote agent client closed');
|
259
|
-
// In the future, we might want to delete the chat session here
|
260
|
-
// if (this.chatId) {
|
261
|
-
// await this.deleteChatSession(this.chatId)
|
262
|
-
// }
|
263
|
-
}
|
264
|
-
}
|
@@ -1,62 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* AI SDK Integration Utilities
|
3
|
-
*
|
4
|
-
* Utility functions for integrating MCPAgent's streamEvents with Vercel AI SDK.
|
5
|
-
* These utilities help convert stream events to AI SDK compatible formats.
|
6
|
-
*/
|
7
|
-
/**
|
8
|
-
* Converts streamEvents to AI SDK compatible stream (basic version)
|
9
|
-
* Only yields the actual content tokens from chat model streams
|
10
|
-
*/
|
11
|
-
export async function* streamEventsToAISDK(streamEvents) {
|
12
|
-
for await (const event of streamEvents) {
|
13
|
-
if (event.event === 'on_chat_model_stream' && event.data?.chunk?.text) {
|
14
|
-
const textContent = event.data.chunk.text;
|
15
|
-
if (typeof textContent === 'string' && textContent.length > 0) {
|
16
|
-
yield textContent;
|
17
|
-
}
|
18
|
-
}
|
19
|
-
}
|
20
|
-
}
|
21
|
-
/**
|
22
|
-
* Converts async generator to ReadableStream for AI SDK compatibility
|
23
|
-
*/
|
24
|
-
export function createReadableStreamFromGenerator(generator) {
|
25
|
-
return new ReadableStream({
|
26
|
-
async start(controller) {
|
27
|
-
try {
|
28
|
-
for await (const chunk of generator) {
|
29
|
-
controller.enqueue(chunk);
|
30
|
-
}
|
31
|
-
controller.close();
|
32
|
-
}
|
33
|
-
catch (error) {
|
34
|
-
controller.error(error);
|
35
|
-
}
|
36
|
-
},
|
37
|
-
});
|
38
|
-
}
|
39
|
-
/**
|
40
|
-
* Enhanced adapter that includes tool information along with chat content
|
41
|
-
* Yields both content tokens and tool usage notifications
|
42
|
-
*/
|
43
|
-
export async function* streamEventsToAISDKWithTools(streamEvents) {
|
44
|
-
for await (const event of streamEvents) {
|
45
|
-
switch (event.event) {
|
46
|
-
case 'on_chat_model_stream':
|
47
|
-
if (event.data?.chunk?.text) {
|
48
|
-
const textContent = event.data.chunk.text;
|
49
|
-
if (typeof textContent === 'string' && textContent.length > 0) {
|
50
|
-
yield textContent;
|
51
|
-
}
|
52
|
-
}
|
53
|
-
break;
|
54
|
-
case 'on_tool_start':
|
55
|
-
yield `\n🔧 Using tool: ${event.name}\n`;
|
56
|
-
break;
|
57
|
-
case 'on_tool_end':
|
58
|
-
yield `\n✅ Tool completed: ${event.name}\n`;
|
59
|
-
break;
|
60
|
-
}
|
61
|
-
}
|
62
|
-
}
|
@@ -1 +0,0 @@
|
|
1
|
-
export { createReadableStreamFromGenerator, streamEventsToAISDK, streamEventsToAISDKWithTools, } from './ai_sdk.js';
|
package/dist/src/client.js
DELETED
@@ -1,133 +0,0 @@
|
|
1
|
-
import fs from 'node:fs';
|
2
|
-
import path from 'node:path';
|
3
|
-
import { createConnectorFromConfig, loadConfigFile } from './config.js';
|
4
|
-
import { logger } from './logging.js';
|
5
|
-
import { MCPSession } from './session.js';
|
6
|
-
export class MCPClient {
|
7
|
-
config = {};
|
8
|
-
sessions = {};
|
9
|
-
activeSessions = [];
|
10
|
-
constructor(config) {
|
11
|
-
if (config) {
|
12
|
-
if (typeof config === 'string') {
|
13
|
-
this.config = loadConfigFile(config);
|
14
|
-
}
|
15
|
-
else {
|
16
|
-
this.config = config;
|
17
|
-
}
|
18
|
-
}
|
19
|
-
}
|
20
|
-
static fromDict(cfg) {
|
21
|
-
return new MCPClient(cfg);
|
22
|
-
}
|
23
|
-
static fromConfigFile(path) {
|
24
|
-
return new MCPClient(loadConfigFile(path));
|
25
|
-
}
|
26
|
-
addServer(name, serverConfig) {
|
27
|
-
this.config.mcpServers = this.config.mcpServers || {};
|
28
|
-
this.config.mcpServers[name] = serverConfig;
|
29
|
-
}
|
30
|
-
removeServer(name) {
|
31
|
-
if (this.config.mcpServers?.[name]) {
|
32
|
-
delete this.config.mcpServers[name];
|
33
|
-
this.activeSessions = this.activeSessions.filter(n => n !== name);
|
34
|
-
}
|
35
|
-
}
|
36
|
-
getServerNames() {
|
37
|
-
return Object.keys(this.config.mcpServers ?? {});
|
38
|
-
}
|
39
|
-
getServerConfig(name) {
|
40
|
-
return this.config.mcpServers?.[name];
|
41
|
-
}
|
42
|
-
getConfig() {
|
43
|
-
return this.config ?? {};
|
44
|
-
}
|
45
|
-
saveConfig(filepath) {
|
46
|
-
const dir = path.dirname(filepath);
|
47
|
-
if (!fs.existsSync(dir)) {
|
48
|
-
fs.mkdirSync(dir, { recursive: true });
|
49
|
-
}
|
50
|
-
fs.writeFileSync(filepath, JSON.stringify(this.config, null, 2), 'utf-8');
|
51
|
-
}
|
52
|
-
async createSession(serverName, autoInitialize = true) {
|
53
|
-
const servers = this.config.mcpServers ?? {};
|
54
|
-
if (Object.keys(servers).length === 0) {
|
55
|
-
logger.warn('No MCP servers defined in config');
|
56
|
-
}
|
57
|
-
if (!servers[serverName]) {
|
58
|
-
throw new Error(`Server '${serverName}' not found in config`);
|
59
|
-
}
|
60
|
-
const connector = createConnectorFromConfig(servers[serverName]);
|
61
|
-
const session = new MCPSession(connector);
|
62
|
-
if (autoInitialize) {
|
63
|
-
await session.initialize();
|
64
|
-
}
|
65
|
-
this.sessions[serverName] = session;
|
66
|
-
if (!this.activeSessions.includes(serverName)) {
|
67
|
-
this.activeSessions.push(serverName);
|
68
|
-
}
|
69
|
-
return session;
|
70
|
-
}
|
71
|
-
async createAllSessions(autoInitialize = true) {
|
72
|
-
const servers = this.config.mcpServers ?? {};
|
73
|
-
if (Object.keys(servers).length === 0) {
|
74
|
-
logger.warn('No MCP servers defined in config');
|
75
|
-
}
|
76
|
-
for (const name of Object.keys(servers)) {
|
77
|
-
await this.createSession(name, autoInitialize);
|
78
|
-
}
|
79
|
-
return this.sessions;
|
80
|
-
}
|
81
|
-
getSession(serverName) {
|
82
|
-
const session = this.sessions[serverName];
|
83
|
-
// if (!session) {
|
84
|
-
// throw new Error(`No session exists for server '${serverName}'`)
|
85
|
-
// }
|
86
|
-
if (!session) {
|
87
|
-
return null;
|
88
|
-
}
|
89
|
-
return session;
|
90
|
-
}
|
91
|
-
getAllActiveSessions() {
|
92
|
-
return Object.fromEntries(this.activeSessions.map(n => [n, this.sessions[n]]));
|
93
|
-
}
|
94
|
-
async closeSession(serverName) {
|
95
|
-
const session = this.sessions[serverName];
|
96
|
-
if (!session) {
|
97
|
-
logger.warn(`No session exists for server ${serverName}, nothing to close`);
|
98
|
-
return;
|
99
|
-
}
|
100
|
-
try {
|
101
|
-
logger.debug(`Closing session for server ${serverName}`);
|
102
|
-
await session.disconnect();
|
103
|
-
}
|
104
|
-
catch (e) {
|
105
|
-
logger.error(`Error closing session for server '${serverName}': ${e}`);
|
106
|
-
}
|
107
|
-
finally {
|
108
|
-
delete this.sessions[serverName];
|
109
|
-
this.activeSessions = this.activeSessions.filter(n => n !== serverName);
|
110
|
-
}
|
111
|
-
}
|
112
|
-
async closeAllSessions() {
|
113
|
-
const serverNames = Object.keys(this.sessions);
|
114
|
-
const errors = [];
|
115
|
-
for (const serverName of serverNames) {
|
116
|
-
try {
|
117
|
-
logger.debug(`Closing session for server ${serverName}`);
|
118
|
-
await this.closeSession(serverName);
|
119
|
-
}
|
120
|
-
catch (e) {
|
121
|
-
const errorMsg = `Failed to close session for server '${serverName}': ${e}`;
|
122
|
-
logger.error(errorMsg);
|
123
|
-
errors.push(errorMsg);
|
124
|
-
}
|
125
|
-
}
|
126
|
-
if (errors.length) {
|
127
|
-
logger.error(`Encountered ${errors.length} errors while closing sessions`);
|
128
|
-
}
|
129
|
-
else {
|
130
|
-
logger.debug('All sessions closed successfully');
|
131
|
-
}
|
132
|
-
}
|
133
|
-
}
|
package/dist/src/config.js
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
import { readFileSync } from 'node:fs';
|
2
|
-
import { HttpConnector } from './connectors/http.js';
|
3
|
-
import { StdioConnector } from './connectors/stdio.js';
|
4
|
-
import { WebSocketConnector } from './connectors/websocket.js';
|
5
|
-
export function loadConfigFile(filepath) {
|
6
|
-
const raw = readFileSync(filepath, 'utf-8');
|
7
|
-
return JSON.parse(raw);
|
8
|
-
}
|
9
|
-
export function createConnectorFromConfig(serverConfig) {
|
10
|
-
if ('command' in serverConfig && 'args' in serverConfig) {
|
11
|
-
return new StdioConnector({
|
12
|
-
command: serverConfig.command,
|
13
|
-
args: serverConfig.args,
|
14
|
-
env: serverConfig.env,
|
15
|
-
});
|
16
|
-
}
|
17
|
-
if ('url' in serverConfig) {
|
18
|
-
// HttpConnector automatically handles streamable HTTP with SSE fallback
|
19
|
-
const transport = serverConfig.transport || 'http';
|
20
|
-
return new HttpConnector(serverConfig.url, {
|
21
|
-
headers: serverConfig.headers,
|
22
|
-
authToken: serverConfig.auth_token || serverConfig.authToken,
|
23
|
-
// Only force SSE if explicitly requested
|
24
|
-
preferSse: serverConfig.preferSse || transport === 'sse',
|
25
|
-
});
|
26
|
-
}
|
27
|
-
if ('ws_url' in serverConfig) {
|
28
|
-
return new WebSocketConnector(serverConfig.ws_url, {
|
29
|
-
headers: serverConfig.headers,
|
30
|
-
authToken: serverConfig.auth_token,
|
31
|
-
});
|
32
|
-
}
|
33
|
-
throw new Error('Cannot determine connector type from config');
|
34
|
-
}
|