mcp-use 1.9.1-canary.1 → 1.10.0-canary.10
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/README.md +9 -6
- package/dist/.tsbuildinfo +1 -1
- package/dist/chunk-6EYDSXO6.js +942 -0
- package/dist/{chunk-D22NUQTL.js → chunk-BFSVTG6G.js} +213 -12
- package/dist/{chunk-33U4IA4N.js → chunk-BPP5XYP6.js} +99 -5
- package/dist/{chunk-3R5PDYIN.js → chunk-J75I2C26.js} +39 -11
- package/dist/{chunk-MUZ5WYE3.js → chunk-NBSNYHID.js} +22 -13
- package/dist/{chunk-U5BX3ISQ.js → chunk-NRALSDBH.js} +22 -408
- package/dist/{chunk-ZQUCGISK.js → chunk-PL645KUX.js} +21 -5
- package/dist/{chunk-QREDNTLS.js → chunk-ZMA4JG4C.js} +1 -1
- package/dist/index.cjs +854 -122
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +57 -23
- package/dist/src/adapters/langchain_adapter.d.ts +1 -1
- package/dist/src/adapters/langchain_adapter.d.ts.map +1 -1
- package/dist/src/agents/index.cjs +2071 -1620
- package/dist/src/agents/index.js +4 -4
- package/dist/src/agents/mcp_agent.d.ts +5 -0
- package/dist/src/agents/mcp_agent.d.ts.map +1 -1
- package/dist/src/auth/browser-provider.d.ts +2 -2
- package/dist/src/auth/browser-provider.d.ts.map +1 -1
- package/dist/src/auth/callback.d.ts.map +1 -1
- package/dist/src/auth/index.cjs +39 -11
- package/dist/src/auth/index.js +1 -1
- package/dist/src/auth/types.d.ts +1 -1
- package/dist/src/auth/types.d.ts.map +1 -1
- package/dist/src/browser.cjs +3299 -2601
- package/dist/src/browser.d.ts +2 -1
- package/dist/src/browser.d.ts.map +1 -1
- package/dist/src/browser.js +10 -5
- package/dist/src/client/browser.d.ts +5 -0
- package/dist/src/client/browser.d.ts.map +1 -1
- package/dist/src/client/connectors/codeMode.d.ts +1 -1
- package/dist/src/client/connectors/codeMode.d.ts.map +1 -1
- package/dist/src/client/executors/base.d.ts +1 -1
- package/dist/src/client/executors/base.d.ts.map +1 -1
- package/dist/src/client/prompts.cjs +13 -4
- package/dist/src/client/prompts.js +3 -2
- package/dist/src/client.d.ts +7 -1
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/connectors/base.d.ts +56 -6
- package/dist/src/connectors/base.d.ts.map +1 -1
- package/dist/src/connectors/http.d.ts.map +1 -1
- package/dist/src/connectors/stdio.d.ts.map +1 -1
- package/dist/src/connectors/websocket.d.ts +1 -1
- package/dist/src/connectors/websocket.d.ts.map +1 -1
- package/dist/src/oauth-helper.d.ts.map +1 -1
- package/dist/src/react/WidgetControls.d.ts.map +1 -1
- package/dist/src/react/index.cjs +1098 -47
- package/dist/src/react/index.d.ts +1 -1
- package/dist/src/react/index.d.ts.map +1 -1
- package/dist/src/react/index.js +5 -5
- package/dist/src/react/types.d.ts +1 -1
- package/dist/src/react/types.d.ts.map +1 -1
- package/dist/src/react/useMcp.d.ts.map +1 -1
- package/dist/src/server/endpoints/mount-mcp.d.ts +4 -1
- package/dist/src/server/endpoints/mount-mcp.d.ts.map +1 -1
- package/dist/src/server/index.cjs +1723 -274
- package/dist/src/server/index.d.ts +3 -2
- package/dist/src/server/index.d.ts.map +1 -1
- package/dist/src/server/index.js +488 -245
- package/dist/src/server/mcp-server.d.ts +77 -27
- package/dist/src/server/mcp-server.d.ts.map +1 -1
- package/dist/src/server/oauth/middleware.d.ts.map +1 -1
- package/dist/src/server/oauth/providers/auth0.d.ts +1 -1
- package/dist/src/server/oauth/providers/auth0.d.ts.map +1 -1
- package/dist/src/server/oauth/providers/custom.d.ts +4 -2
- package/dist/src/server/oauth/providers/custom.d.ts.map +1 -1
- package/dist/src/server/oauth/providers/keycloak.d.ts +1 -1
- package/dist/src/server/oauth/providers/keycloak.d.ts.map +1 -1
- package/dist/src/server/oauth/providers/supabase.d.ts +1 -1
- package/dist/src/server/oauth/providers/supabase.d.ts.map +1 -1
- package/dist/src/server/oauth/providers/types.d.ts +9 -5
- package/dist/src/server/oauth/providers/types.d.ts.map +1 -1
- package/dist/src/server/oauth/providers.d.ts +27 -9
- package/dist/src/server/oauth/providers.d.ts.map +1 -1
- package/dist/src/server/oauth/setup.d.ts +5 -4
- package/dist/src/server/oauth/setup.d.ts.map +1 -1
- package/dist/src/server/oauth/utils.d.ts +3 -2
- package/dist/src/server/oauth/utils.d.ts.map +1 -1
- package/dist/src/server/prompts/conversion.d.ts +1 -1
- package/dist/src/server/prompts/conversion.d.ts.map +1 -1
- package/dist/src/server/prompts/index.d.ts +6 -5
- package/dist/src/server/prompts/index.d.ts.map +1 -1
- package/dist/src/server/resources/conversion.d.ts +1 -1
- package/dist/src/server/resources/conversion.d.ts.map +1 -1
- package/dist/src/server/resources/index.d.ts +44 -25
- package/dist/src/server/resources/index.d.ts.map +1 -1
- package/dist/src/server/resources/subscriptions.d.ts +1 -1
- package/dist/src/server/resources/subscriptions.d.ts.map +1 -1
- package/dist/src/server/sessions/session-manager.d.ts +11 -5
- package/dist/src/server/sessions/session-manager.d.ts.map +1 -1
- package/dist/src/server/tools/tool-execution-helpers.d.ts +31 -8
- package/dist/src/server/tools/tool-execution-helpers.d.ts.map +1 -1
- package/dist/src/server/tools/tool-registration.d.ts +21 -7
- package/dist/src/server/tools/tool-registration.d.ts.map +1 -1
- package/dist/src/server/types/common.d.ts +25 -9
- package/dist/src/server/types/common.d.ts.map +1 -1
- package/dist/src/server/types/index.d.ts +3 -3
- package/dist/src/server/types/index.d.ts.map +1 -1
- package/dist/src/server/types/prompt.d.ts +3 -2
- package/dist/src/server/types/prompt.d.ts.map +1 -1
- package/dist/src/server/types/resource.d.ts +60 -10
- package/dist/src/server/types/resource.d.ts.map +1 -1
- package/dist/src/server/types/tool-context.d.ts +116 -1
- package/dist/src/server/types/tool-context.d.ts.map +1 -1
- package/dist/src/server/types/tool.d.ts +43 -2
- package/dist/src/server/types/tool.d.ts.map +1 -1
- package/dist/src/server/types/widget.d.ts +11 -1
- package/dist/src/server/types/widget.d.ts.map +1 -1
- package/dist/src/server/utils/response-helpers.d.ts +17 -29
- package/dist/src/server/utils/response-helpers.d.ts.map +1 -1
- package/dist/src/server/widgets/index.d.ts +3 -3
- package/dist/src/server/widgets/index.d.ts.map +1 -1
- package/dist/src/server/widgets/mount-widgets-dev.d.ts.map +1 -1
- package/dist/src/server/widgets/ui-resource-registration.d.ts +13 -25
- package/dist/src/server/widgets/ui-resource-registration.d.ts.map +1 -1
- package/dist/src/server/widgets/widget-helpers.d.ts +11 -6
- package/dist/src/server/widgets/widget-helpers.d.ts.map +1 -1
- package/dist/src/server/widgets/widget-types.d.ts +3 -3
- package/dist/src/server/widgets/widget-types.d.ts.map +1 -1
- package/dist/src/session.d.ts +372 -2
- package/dist/src/session.d.ts.map +1 -1
- package/dist/src/task_managers/sse.d.ts +2 -2
- package/dist/src/task_managers/sse.d.ts.map +1 -1
- package/dist/src/task_managers/stdio.d.ts +2 -2
- package/dist/src/task_managers/stdio.d.ts.map +1 -1
- package/dist/src/task_managers/streamable_http.d.ts +2 -2
- package/dist/src/task_managers/streamable_http.d.ts.map +1 -1
- package/dist/src/telemetry/events.d.ts +219 -0
- package/dist/src/telemetry/events.d.ts.map +1 -1
- package/dist/src/telemetry/index.d.ts +2 -2
- package/dist/src/telemetry/index.d.ts.map +1 -1
- package/dist/src/telemetry/telemetry.d.ts +56 -1
- package/dist/src/telemetry/telemetry.d.ts.map +1 -1
- package/dist/src/telemetry/utils.d.ts +1 -1
- package/dist/src/telemetry/utils.d.ts.map +1 -1
- package/dist/src/version.d.ts +8 -0
- package/dist/src/version.d.ts.map +1 -0
- package/dist/{tool-execution-helpers-BQJTPWPN.js → tool-execution-helpers-XFVBSRXM.js} +3 -2
- package/dist/tsup.config.d.ts.map +1 -1
- package/package.json +6 -5
- package/dist/chunk-MTHLLDCX.js +0 -97
|
@@ -35,9 +35,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
35
35
|
async function getNodeModules() {
|
|
36
36
|
if (typeof process !== "undefined" && process.platform) {
|
|
37
37
|
try {
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
return { fs:
|
|
38
|
+
const fs2 = await import("fs");
|
|
39
|
+
const path2 = await import("path");
|
|
40
|
+
return { fs: fs2.default, path: path2.default };
|
|
41
41
|
} catch {
|
|
42
42
|
return { fs: null, path: null };
|
|
43
43
|
}
|
|
@@ -1055,1929 +1055,2369 @@ __export(agents_exports, {
|
|
|
1055
1055
|
module.exports = __toCommonJS(agents_exports);
|
|
1056
1056
|
|
|
1057
1057
|
// src/connectors/base.ts
|
|
1058
|
-
var import_types = require("@modelcontextprotocol
|
|
1058
|
+
var import_types = require("@mcp-use/modelcontextprotocol-sdk/types.js");
|
|
1059
1059
|
init_logging();
|
|
1060
1060
|
|
|
1061
|
-
// src/
|
|
1062
|
-
var
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
### 1. Tool Discovery Phase
|
|
1068
|
-
**Always start by discovering available tools:**
|
|
1069
|
-
- Tools are organized by server namespace (e.g., \`server_name.tool_name\`)
|
|
1070
|
-
- Use the \`search_tools(query, detail_level)\` function to find available tools
|
|
1071
|
-
- You can access \`__tool_namespaces\` to see all available server namespaces
|
|
1061
|
+
// src/telemetry/telemetry.ts
|
|
1062
|
+
var fs = __toESM(require("fs"), 1);
|
|
1063
|
+
var os = __toESM(require("os"), 1);
|
|
1064
|
+
var path = __toESM(require("path"), 1);
|
|
1065
|
+
var import_posthog_node = require("posthog-node");
|
|
1072
1066
|
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
console.log(\`\${tool.server}.\${tool.name}: \${tool.description}\`);
|
|
1067
|
+
// src/server/utils/runtime.ts
|
|
1068
|
+
var isDeno = typeof globalThis.Deno !== "undefined";
|
|
1069
|
+
function generateUUID() {
|
|
1070
|
+
return globalThis.crypto.randomUUID();
|
|
1078
1071
|
}
|
|
1072
|
+
__name(generateUUID, "generateUUID");
|
|
1079
1073
|
|
|
1080
|
-
//
|
|
1081
|
-
|
|
1082
|
-
\`\`\`
|
|
1083
|
-
|
|
1084
|
-
### 2. Interface Introspection
|
|
1085
|
-
**Understand tool contracts before using them:**
|
|
1086
|
-
- Use \`search_tools\` to get tool descriptions and input schemas
|
|
1087
|
-
- Look for "Access as: server.tool(args)" patterns in descriptions
|
|
1088
|
-
|
|
1089
|
-
### 3. Code Execution Guidelines
|
|
1090
|
-
**When writing code:**
|
|
1091
|
-
- Use \`await server.tool({ param: value })\` syntax for all tool calls
|
|
1092
|
-
- Tools are async functions that return promises
|
|
1093
|
-
- You have access to standard JavaScript globals: \`console\`, \`JSON\`, \`Math\`, \`Date\`, etc.
|
|
1094
|
-
- All console output (\`console.log\`, \`console.error\`, etc.) is automatically captured and returned
|
|
1095
|
-
- Build properly structured input objects based on interface definitions
|
|
1096
|
-
- Handle errors appropriately with try/catch blocks
|
|
1097
|
-
- Chain tool calls by using results from previous calls
|
|
1098
|
-
|
|
1099
|
-
### 4. Best Practices
|
|
1100
|
-
- **Discover first, code second**: Always explore available tools before writing execution code
|
|
1101
|
-
- **Respect namespaces**: Use full \`server.tool\` names to avoid conflicts
|
|
1102
|
-
- **Minimize Context**: Process large data in code, return only essential results
|
|
1103
|
-
- **Error handling**: Wrap tool calls in try/catch for robustness
|
|
1104
|
-
- **Data flow**: Chain tools by passing outputs as inputs to subsequent tools
|
|
1105
|
-
|
|
1106
|
-
### 5. Available Runtime Context
|
|
1107
|
-
- \`search_tools(query, detail_level)\`: Function to discover tools
|
|
1108
|
-
- \`__tool_namespaces\`: Array of available server namespaces
|
|
1109
|
-
- All registered tools as \`server.tool\` functions
|
|
1110
|
-
- Standard JavaScript built-ins for data processing
|
|
1111
|
-
|
|
1112
|
-
### Example Workflow
|
|
1113
|
-
|
|
1114
|
-
\`\`\`javascript
|
|
1115
|
-
// 1. Discover available tools
|
|
1116
|
-
const github_tools = await search_tools("github pull request");
|
|
1117
|
-
console.log(\`Available GitHub PR tools: \${github_tools.map(t => t.name)}\`);
|
|
1118
|
-
|
|
1119
|
-
// 2. Call tools with proper parameters
|
|
1120
|
-
const pr = await github.get_pull_request({
|
|
1121
|
-
owner: "facebook",
|
|
1122
|
-
repo: "react",
|
|
1123
|
-
number: 12345
|
|
1124
|
-
});
|
|
1074
|
+
// src/telemetry/telemetry.ts
|
|
1075
|
+
init_logging();
|
|
1125
1076
|
|
|
1126
|
-
//
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1077
|
+
// src/telemetry/events.ts
|
|
1078
|
+
var BaseTelemetryEvent = class {
|
|
1079
|
+
static {
|
|
1080
|
+
__name(this, "BaseTelemetryEvent");
|
|
1081
|
+
}
|
|
1082
|
+
};
|
|
1083
|
+
var MCPAgentExecutionEvent = class extends BaseTelemetryEvent {
|
|
1084
|
+
constructor(data) {
|
|
1085
|
+
super();
|
|
1086
|
+
this.data = data;
|
|
1087
|
+
}
|
|
1088
|
+
static {
|
|
1089
|
+
__name(this, "MCPAgentExecutionEvent");
|
|
1090
|
+
}
|
|
1091
|
+
get name() {
|
|
1092
|
+
return "mcp_agent_execution";
|
|
1093
|
+
}
|
|
1094
|
+
get properties() {
|
|
1095
|
+
return {
|
|
1096
|
+
// Core execution info
|
|
1097
|
+
execution_method: this.data.executionMethod,
|
|
1098
|
+
query: this.data.query,
|
|
1099
|
+
query_length: this.data.query.length,
|
|
1100
|
+
success: this.data.success,
|
|
1101
|
+
// Agent configuration
|
|
1102
|
+
model_provider: this.data.modelProvider,
|
|
1103
|
+
model_name: this.data.modelName,
|
|
1104
|
+
server_count: this.data.serverCount,
|
|
1105
|
+
server_identifiers: this.data.serverIdentifiers,
|
|
1106
|
+
total_tools_available: this.data.totalToolsAvailable,
|
|
1107
|
+
tools_available_names: this.data.toolsAvailableNames,
|
|
1108
|
+
max_steps_configured: this.data.maxStepsConfigured,
|
|
1109
|
+
memory_enabled: this.data.memoryEnabled,
|
|
1110
|
+
use_server_manager: this.data.useServerManager,
|
|
1111
|
+
// Execution parameters (always include, even if null)
|
|
1112
|
+
max_steps_used: this.data.maxStepsUsed,
|
|
1113
|
+
manage_connector: this.data.manageConnector,
|
|
1114
|
+
external_history_used: this.data.externalHistoryUsed,
|
|
1115
|
+
// Execution results (always include, even if null)
|
|
1116
|
+
steps_taken: this.data.stepsTaken ?? null,
|
|
1117
|
+
tools_used_count: this.data.toolsUsedCount ?? null,
|
|
1118
|
+
tools_used_names: this.data.toolsUsedNames ?? null,
|
|
1119
|
+
response: this.data.response ?? null,
|
|
1120
|
+
response_length: this.data.response ? this.data.response.length : null,
|
|
1121
|
+
execution_time_ms: this.data.executionTimeMs ?? null,
|
|
1122
|
+
error_type: this.data.errorType ?? null,
|
|
1123
|
+
conversation_history_length: this.data.conversationHistoryLength ?? null
|
|
1124
|
+
};
|
|
1125
|
+
}
|
|
1126
|
+
};
|
|
1127
|
+
function createServerRunEventData(server, transport) {
|
|
1128
|
+
const toolRegistrations = Array.from(server.registrations.tools.values());
|
|
1129
|
+
const promptRegistrations = Array.from(server.registrations.prompts.values());
|
|
1130
|
+
const resourceRegistrations = Array.from(
|
|
1131
|
+
server.registrations.resources.values()
|
|
1132
|
+
);
|
|
1133
|
+
const templateRegistrations = Array.from(
|
|
1134
|
+
server.registrations.resourceTemplates.values()
|
|
1135
|
+
);
|
|
1136
|
+
const allResources = resourceRegistrations.map((r) => ({
|
|
1137
|
+
name: r.config.name,
|
|
1138
|
+
title: r.config.title ?? null,
|
|
1139
|
+
description: r.config.description ?? null,
|
|
1140
|
+
uri: r.config.uri ?? null,
|
|
1141
|
+
mime_type: r.config.mimeType ?? null
|
|
1142
|
+
}));
|
|
1143
|
+
const appsSdkResources = allResources.filter(
|
|
1144
|
+
(r) => r.mime_type === "text/html+skybridge"
|
|
1145
|
+
);
|
|
1146
|
+
const mcpUiResources = allResources.filter(
|
|
1147
|
+
(r) => r.mime_type === "text/uri-list" || r.mime_type === "text/html"
|
|
1148
|
+
);
|
|
1149
|
+
const mcpAppsResources = allResources.filter(
|
|
1150
|
+
(r) => r.mime_type === "text/html+mcp"
|
|
1151
|
+
);
|
|
1152
|
+
return {
|
|
1153
|
+
transport,
|
|
1154
|
+
toolsNumber: server.registeredTools.length,
|
|
1155
|
+
resourcesNumber: server.registeredResources.length,
|
|
1156
|
+
promptsNumber: server.registeredPrompts.length,
|
|
1157
|
+
auth: !!server.oauthProvider,
|
|
1158
|
+
name: server.config.name,
|
|
1159
|
+
description: server.config.description ?? null,
|
|
1160
|
+
baseUrl: server.serverBaseUrl ?? null,
|
|
1161
|
+
toolNames: server.registeredTools.length > 0 ? server.registeredTools : null,
|
|
1162
|
+
resourceNames: server.registeredResources.length > 0 ? server.registeredResources : null,
|
|
1163
|
+
promptNames: server.registeredPrompts.length > 0 ? server.registeredPrompts : null,
|
|
1164
|
+
tools: toolRegistrations.length > 0 ? toolRegistrations.map((r) => ({
|
|
1165
|
+
name: r.config.name,
|
|
1166
|
+
title: r.config.title ?? null,
|
|
1167
|
+
description: r.config.description ?? null,
|
|
1168
|
+
input_schema: r.config.schema ? JSON.stringify(r.config.schema) : null,
|
|
1169
|
+
output_schema: r.config.outputSchema ? JSON.stringify(r.config.outputSchema) : null
|
|
1170
|
+
})) : null,
|
|
1171
|
+
resources: allResources.length > 0 ? allResources : null,
|
|
1172
|
+
prompts: promptRegistrations.length > 0 ? promptRegistrations.map((r) => ({
|
|
1173
|
+
name: r.config.name,
|
|
1174
|
+
title: r.config.title ?? null,
|
|
1175
|
+
description: r.config.description ?? null,
|
|
1176
|
+
args: r.config.args ? JSON.stringify(r.config.args) : null
|
|
1177
|
+
})) : null,
|
|
1178
|
+
templates: templateRegistrations.length > 0 ? templateRegistrations.map((r) => ({
|
|
1179
|
+
name: r.config.name,
|
|
1180
|
+
title: r.config.title ?? null,
|
|
1181
|
+
description: r.config.description ?? null
|
|
1182
|
+
})) : null,
|
|
1183
|
+
capabilities: {
|
|
1184
|
+
logging: true,
|
|
1185
|
+
resources: { subscribe: true, listChanged: true }
|
|
1186
|
+
},
|
|
1187
|
+
appsSdkResources: appsSdkResources.length > 0 ? appsSdkResources : null,
|
|
1188
|
+
appsSdkResourcesNumber: appsSdkResources.length,
|
|
1189
|
+
mcpUiResources: mcpUiResources.length > 0 ? mcpUiResources : null,
|
|
1190
|
+
mcpUiResourcesNumber: mcpUiResources.length,
|
|
1191
|
+
mcpAppsResources: mcpAppsResources.length > 0 ? mcpAppsResources : null,
|
|
1192
|
+
mcpAppsResourcesNumber: mcpAppsResources.length
|
|
1193
|
+
};
|
|
1137
1194
|
}
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1195
|
+
__name(createServerRunEventData, "createServerRunEventData");
|
|
1196
|
+
var ServerRunEvent = class extends BaseTelemetryEvent {
|
|
1197
|
+
constructor(data) {
|
|
1198
|
+
super();
|
|
1199
|
+
this.data = data;
|
|
1200
|
+
}
|
|
1201
|
+
static {
|
|
1202
|
+
__name(this, "ServerRunEvent");
|
|
1203
|
+
}
|
|
1204
|
+
get name() {
|
|
1205
|
+
return "server_run";
|
|
1206
|
+
}
|
|
1207
|
+
get properties() {
|
|
1208
|
+
return {
|
|
1209
|
+
transport: this.data.transport,
|
|
1210
|
+
tools_number: this.data.toolsNumber,
|
|
1211
|
+
resources_number: this.data.resourcesNumber,
|
|
1212
|
+
prompts_number: this.data.promptsNumber,
|
|
1213
|
+
auth: this.data.auth,
|
|
1214
|
+
name: this.data.name,
|
|
1215
|
+
description: this.data.description ?? null,
|
|
1216
|
+
base_url: this.data.baseUrl ?? null,
|
|
1217
|
+
tool_names: this.data.toolNames ?? null,
|
|
1218
|
+
resource_names: this.data.resourceNames ?? null,
|
|
1219
|
+
prompt_names: this.data.promptNames ?? null,
|
|
1220
|
+
tools: this.data.tools ?? null,
|
|
1221
|
+
resources: this.data.resources ?? null,
|
|
1222
|
+
prompts: this.data.prompts ?? null,
|
|
1223
|
+
templates: this.data.templates ?? null,
|
|
1224
|
+
capabilities: this.data.capabilities ? JSON.stringify(this.data.capabilities) : null,
|
|
1225
|
+
apps_sdk_resources: this.data.appsSdkResources ? JSON.stringify(this.data.appsSdkResources) : null,
|
|
1226
|
+
apps_sdk_resources_number: this.data.appsSdkResourcesNumber ?? 0,
|
|
1227
|
+
mcp_ui_resources: this.data.mcpUiResources ? JSON.stringify(this.data.mcpUiResources) : null,
|
|
1228
|
+
mcp_ui_resources_number: this.data.mcpUiResourcesNumber ?? 0,
|
|
1229
|
+
mcp_apps_resources: this.data.mcpAppsResources ? JSON.stringify(this.data.mcpAppsResources) : null,
|
|
1230
|
+
mcp_apps_resources_number: this.data.mcpAppsResourcesNumber ?? 0
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
1144
1233
|
};
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1234
|
+
var ServerInitializeEvent = class extends BaseTelemetryEvent {
|
|
1235
|
+
constructor(data) {
|
|
1236
|
+
super();
|
|
1237
|
+
this.data = data;
|
|
1238
|
+
}
|
|
1239
|
+
static {
|
|
1240
|
+
__name(this, "ServerInitializeEvent");
|
|
1241
|
+
}
|
|
1242
|
+
get name() {
|
|
1243
|
+
return "server_initialize_call";
|
|
1244
|
+
}
|
|
1245
|
+
get properties() {
|
|
1246
|
+
return {
|
|
1247
|
+
protocol_version: this.data.protocolVersion,
|
|
1248
|
+
client_info: JSON.stringify(this.data.clientInfo),
|
|
1249
|
+
client_capabilities: JSON.stringify(this.data.clientCapabilities),
|
|
1250
|
+
session_id: this.data.sessionId ?? null
|
|
1251
|
+
};
|
|
1252
|
+
}
|
|
1153
1253
|
};
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1254
|
+
var ServerToolCallEvent = class extends BaseTelemetryEvent {
|
|
1255
|
+
constructor(data) {
|
|
1256
|
+
super();
|
|
1257
|
+
this.data = data;
|
|
1258
|
+
}
|
|
1157
1259
|
static {
|
|
1158
|
-
__name(this, "
|
|
1260
|
+
__name(this, "ServerToolCallEvent");
|
|
1159
1261
|
}
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1262
|
+
get name() {
|
|
1263
|
+
return "server_tool_call";
|
|
1264
|
+
}
|
|
1265
|
+
get properties() {
|
|
1266
|
+
return {
|
|
1267
|
+
tool_name: this.data.toolName,
|
|
1268
|
+
length_input_argument: this.data.lengthInputArgument,
|
|
1269
|
+
success: this.data.success,
|
|
1270
|
+
error_type: this.data.errorType ?? null,
|
|
1271
|
+
execution_time_ms: this.data.executionTimeMs ?? null
|
|
1272
|
+
};
|
|
1166
1273
|
}
|
|
1167
1274
|
};
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
// src/utils/json-schema-to-zod/JSONSchemaToZod.ts
|
|
1174
|
-
var import_zod = require("zod");
|
|
1175
|
-
var JSONSchemaToZod = class {
|
|
1275
|
+
var ServerResourceCallEvent = class extends BaseTelemetryEvent {
|
|
1276
|
+
constructor(data) {
|
|
1277
|
+
super();
|
|
1278
|
+
this.data = data;
|
|
1279
|
+
}
|
|
1176
1280
|
static {
|
|
1177
|
-
__name(this, "
|
|
1281
|
+
__name(this, "ServerResourceCallEvent");
|
|
1178
1282
|
}
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
*
|
|
1182
|
-
* @param {JSONSchema} schema - The JSON schema.
|
|
1183
|
-
* @returns {ZodSchema} - The Zod schema.
|
|
1184
|
-
*/
|
|
1185
|
-
static convert(schema) {
|
|
1186
|
-
return this.parseSchema(schema);
|
|
1283
|
+
get name() {
|
|
1284
|
+
return "server_resource_call";
|
|
1187
1285
|
}
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1286
|
+
get properties() {
|
|
1287
|
+
return {
|
|
1288
|
+
name: this.data.name,
|
|
1289
|
+
description: this.data.description,
|
|
1290
|
+
contents: this.data.contents,
|
|
1291
|
+
success: this.data.success,
|
|
1292
|
+
error_type: this.data.errorType ?? null
|
|
1293
|
+
};
|
|
1294
|
+
}
|
|
1295
|
+
};
|
|
1296
|
+
var ServerPromptCallEvent = class extends BaseTelemetryEvent {
|
|
1297
|
+
constructor(data) {
|
|
1298
|
+
super();
|
|
1299
|
+
this.data = data;
|
|
1300
|
+
}
|
|
1301
|
+
static {
|
|
1302
|
+
__name(this, "ServerPromptCallEvent");
|
|
1303
|
+
}
|
|
1304
|
+
get name() {
|
|
1305
|
+
return "server_prompt_call";
|
|
1306
|
+
}
|
|
1307
|
+
get properties() {
|
|
1308
|
+
return {
|
|
1309
|
+
name: this.data.name,
|
|
1310
|
+
description: this.data.description,
|
|
1311
|
+
success: this.data.success,
|
|
1312
|
+
error_type: this.data.errorType ?? null
|
|
1313
|
+
};
|
|
1314
|
+
}
|
|
1315
|
+
};
|
|
1316
|
+
var ServerContextEvent = class extends BaseTelemetryEvent {
|
|
1317
|
+
constructor(data) {
|
|
1318
|
+
super();
|
|
1319
|
+
this.data = data;
|
|
1320
|
+
}
|
|
1321
|
+
static {
|
|
1322
|
+
__name(this, "ServerContextEvent");
|
|
1323
|
+
}
|
|
1324
|
+
get name() {
|
|
1325
|
+
return `server_context_${this.data.contextType}`;
|
|
1326
|
+
}
|
|
1327
|
+
get properties() {
|
|
1328
|
+
return {
|
|
1329
|
+
context_type: this.data.contextType,
|
|
1330
|
+
notification_type: this.data.notificationType ?? null
|
|
1331
|
+
};
|
|
1332
|
+
}
|
|
1333
|
+
};
|
|
1334
|
+
var MCPClientInitEvent = class extends BaseTelemetryEvent {
|
|
1335
|
+
constructor(data) {
|
|
1336
|
+
super();
|
|
1337
|
+
this.data = data;
|
|
1338
|
+
}
|
|
1339
|
+
static {
|
|
1340
|
+
__name(this, "MCPClientInitEvent");
|
|
1341
|
+
}
|
|
1342
|
+
get name() {
|
|
1343
|
+
return "mcpclient_init";
|
|
1344
|
+
}
|
|
1345
|
+
get properties() {
|
|
1346
|
+
return {
|
|
1347
|
+
code_mode: this.data.codeMode,
|
|
1348
|
+
sandbox: this.data.sandbox,
|
|
1349
|
+
all_callbacks: this.data.allCallbacks,
|
|
1350
|
+
verify: this.data.verify,
|
|
1351
|
+
servers: this.data.servers,
|
|
1352
|
+
num_servers: this.data.numServers
|
|
1353
|
+
};
|
|
1354
|
+
}
|
|
1355
|
+
};
|
|
1356
|
+
var ConnectorInitEvent = class extends BaseTelemetryEvent {
|
|
1357
|
+
constructor(data) {
|
|
1358
|
+
super();
|
|
1359
|
+
this.data = data;
|
|
1360
|
+
}
|
|
1361
|
+
static {
|
|
1362
|
+
__name(this, "ConnectorInitEvent");
|
|
1363
|
+
}
|
|
1364
|
+
get name() {
|
|
1365
|
+
return "connector_init";
|
|
1366
|
+
}
|
|
1367
|
+
get properties() {
|
|
1368
|
+
return {
|
|
1369
|
+
connector_type: this.data.connectorType,
|
|
1370
|
+
server_command: this.data.serverCommand ?? null,
|
|
1371
|
+
server_args: this.data.serverArgs ?? null,
|
|
1372
|
+
server_url: this.data.serverUrl ?? null,
|
|
1373
|
+
public_identifier: this.data.publicIdentifier ?? null
|
|
1374
|
+
};
|
|
1375
|
+
}
|
|
1376
|
+
};
|
|
1377
|
+
|
|
1378
|
+
// src/version.ts
|
|
1379
|
+
var VERSION = "1.10.0-canary.10";
|
|
1380
|
+
function getPackageVersion() {
|
|
1381
|
+
return VERSION;
|
|
1382
|
+
}
|
|
1383
|
+
__name(getPackageVersion, "getPackageVersion");
|
|
1384
|
+
|
|
1385
|
+
// src/telemetry/utils.ts
|
|
1386
|
+
function getModelProvider(llm) {
|
|
1387
|
+
return llm._llm_type || llm.constructor.name.toLowerCase();
|
|
1388
|
+
}
|
|
1389
|
+
__name(getModelProvider, "getModelProvider");
|
|
1390
|
+
function getModelName(llm) {
|
|
1391
|
+
if ("_identifyingParams" in llm) {
|
|
1392
|
+
const identifyingParams = llm._identifyingParams;
|
|
1393
|
+
if (typeof identifyingParams === "object" && identifyingParams !== null) {
|
|
1394
|
+
for (const key of [
|
|
1395
|
+
"model",
|
|
1396
|
+
"modelName",
|
|
1397
|
+
"model_name",
|
|
1398
|
+
"modelId",
|
|
1399
|
+
"model_id",
|
|
1400
|
+
"deploymentName",
|
|
1401
|
+
"deployment_name"
|
|
1402
|
+
]) {
|
|
1403
|
+
if (key in identifyingParams) {
|
|
1404
|
+
return String(identifyingParams[key]);
|
|
1207
1405
|
}
|
|
1208
|
-
continue;
|
|
1209
|
-
}
|
|
1210
|
-
const value = objectData[key];
|
|
1211
|
-
if ("const" in propCondition && value !== propCondition["const"]) {
|
|
1212
|
-
return false;
|
|
1213
|
-
}
|
|
1214
|
-
if ("minimum" in propCondition && typeof value === "number" && value < propCondition["minimum"]) {
|
|
1215
|
-
return false;
|
|
1216
|
-
}
|
|
1217
|
-
if ("maximum" in propCondition && typeof value === "number" && value > propCondition["maximum"]) {
|
|
1218
|
-
return false;
|
|
1219
1406
|
}
|
|
1220
1407
|
}
|
|
1221
|
-
return true;
|
|
1222
|
-
}
|
|
1223
|
-
/**
|
|
1224
|
-
* Validates data against a conditional schema and adds issues to context if validation fails.
|
|
1225
|
-
*
|
|
1226
|
-
* @param {JSONValue} data - The data to validate.
|
|
1227
|
-
* @param {JSONSchema} schema - The conditional schema.
|
|
1228
|
-
* @param {z.RefinementCtx} ctx - The Zod refinement context.
|
|
1229
|
-
*/
|
|
1230
|
-
static validateConditionalSchema(data, schema, ctx) {
|
|
1231
|
-
this.validateRequiredProperties(data, schema, ctx);
|
|
1232
|
-
this.validatePropertyPatterns(data, schema, ctx);
|
|
1233
|
-
this.validateNestedConditions(data, schema, ctx);
|
|
1234
1408
|
}
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1409
|
+
return llm.model || llm.modelName || llm.constructor.name;
|
|
1410
|
+
}
|
|
1411
|
+
__name(getModelName, "getModelName");
|
|
1412
|
+
function extractModelInfo(llm) {
|
|
1413
|
+
return [getModelProvider(llm), getModelName(llm)];
|
|
1414
|
+
}
|
|
1415
|
+
__name(extractModelInfo, "extractModelInfo");
|
|
1416
|
+
|
|
1417
|
+
// src/telemetry/telemetry.ts
|
|
1418
|
+
var USER_ID_STORAGE_KEY = "mcp_use_user_id";
|
|
1419
|
+
function detectRuntimeEnvironment() {
|
|
1420
|
+
try {
|
|
1421
|
+
if (typeof globalThis.Bun !== "undefined") {
|
|
1422
|
+
return "bun";
|
|
1245
1423
|
}
|
|
1246
|
-
if (typeof
|
|
1247
|
-
|
|
1248
|
-
ctx.addIssue({
|
|
1249
|
-
code: import_zod.z.ZodIssueCode.custom,
|
|
1250
|
-
message: `Required property '${requiredProp}' is missing`,
|
|
1251
|
-
path: [requiredProp]
|
|
1252
|
-
});
|
|
1253
|
-
}
|
|
1254
|
-
return;
|
|
1424
|
+
if (typeof globalThis.Deno !== "undefined") {
|
|
1425
|
+
return "deno";
|
|
1255
1426
|
}
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
ctx.addIssue({
|
|
1259
|
-
code: import_zod.z.ZodIssueCode.custom,
|
|
1260
|
-
message: `Required property '${requiredProp}' is missing`,
|
|
1261
|
-
path: [requiredProp]
|
|
1262
|
-
});
|
|
1263
|
-
}
|
|
1427
|
+
if (typeof navigator !== "undefined" && navigator.userAgent?.includes("Cloudflare-Workers")) {
|
|
1428
|
+
return "cloudflare-workers";
|
|
1264
1429
|
}
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
* Validates property patterns for string properties.
|
|
1268
|
-
*
|
|
1269
|
-
* @param {JSONValue} data - The data to validate.
|
|
1270
|
-
* @param {JSONSchema} schema - The schema containing property patterns.
|
|
1271
|
-
* @param {z.RefinementCtx} ctx - The Zod refinement context.
|
|
1272
|
-
*/
|
|
1273
|
-
static validatePropertyPatterns(data, schema, ctx) {
|
|
1274
|
-
if (!schema.properties) {
|
|
1275
|
-
return;
|
|
1430
|
+
if (typeof globalThis.EdgeRuntime !== "undefined") {
|
|
1431
|
+
return "edge";
|
|
1276
1432
|
}
|
|
1277
|
-
if (typeof
|
|
1278
|
-
return;
|
|
1433
|
+
if (typeof process !== "undefined" && typeof process.versions?.node !== "undefined" && typeof fs !== "undefined" && typeof fs.existsSync === "function") {
|
|
1434
|
+
return "node";
|
|
1279
1435
|
}
|
|
1280
|
-
if (
|
|
1281
|
-
return;
|
|
1436
|
+
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
|
1437
|
+
return "browser";
|
|
1282
1438
|
}
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1439
|
+
return "unknown";
|
|
1440
|
+
} catch {
|
|
1441
|
+
return "unknown";
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
__name(detectRuntimeEnvironment, "detectRuntimeEnvironment");
|
|
1445
|
+
function getStorageCapability(env) {
|
|
1446
|
+
switch (env) {
|
|
1447
|
+
case "node":
|
|
1448
|
+
case "bun":
|
|
1449
|
+
return "filesystem";
|
|
1450
|
+
case "browser":
|
|
1451
|
+
try {
|
|
1452
|
+
if (typeof localStorage !== "undefined") {
|
|
1453
|
+
localStorage.setItem("__mcp_use_test__", "1");
|
|
1454
|
+
localStorage.removeItem("__mcp_use_test__");
|
|
1455
|
+
return "localStorage";
|
|
1456
|
+
}
|
|
1457
|
+
} catch {
|
|
1287
1458
|
}
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1459
|
+
return "session-only";
|
|
1460
|
+
case "deno":
|
|
1461
|
+
return "session-only";
|
|
1462
|
+
default:
|
|
1463
|
+
return "session-only";
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
__name(getStorageCapability, "getStorageCapability");
|
|
1467
|
+
var cachedEnvironment = null;
|
|
1468
|
+
function getRuntimeEnvironment() {
|
|
1469
|
+
if (cachedEnvironment === null) {
|
|
1470
|
+
cachedEnvironment = detectRuntimeEnvironment();
|
|
1471
|
+
}
|
|
1472
|
+
return cachedEnvironment;
|
|
1473
|
+
}
|
|
1474
|
+
__name(getRuntimeEnvironment, "getRuntimeEnvironment");
|
|
1475
|
+
function isNodeJSEnvironment2() {
|
|
1476
|
+
const env = getRuntimeEnvironment();
|
|
1477
|
+
return env === "node" || env === "bun";
|
|
1478
|
+
}
|
|
1479
|
+
__name(isNodeJSEnvironment2, "isNodeJSEnvironment");
|
|
1480
|
+
var ScarfEventLogger = class {
|
|
1481
|
+
static {
|
|
1482
|
+
__name(this, "ScarfEventLogger");
|
|
1483
|
+
}
|
|
1484
|
+
endpoint;
|
|
1485
|
+
timeout;
|
|
1486
|
+
constructor(endpoint, timeout = 3e3) {
|
|
1487
|
+
this.endpoint = endpoint;
|
|
1488
|
+
this.timeout = timeout;
|
|
1489
|
+
}
|
|
1490
|
+
async logEvent(properties) {
|
|
1491
|
+
try {
|
|
1492
|
+
const controller = new AbortController();
|
|
1493
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
1494
|
+
const response = await fetch(this.endpoint, {
|
|
1495
|
+
method: "POST",
|
|
1496
|
+
headers: {
|
|
1497
|
+
"Content-Type": "application/json"
|
|
1498
|
+
},
|
|
1499
|
+
body: JSON.stringify(properties),
|
|
1500
|
+
signal: controller.signal
|
|
1501
|
+
});
|
|
1502
|
+
clearTimeout(timeoutId);
|
|
1503
|
+
if (!response.ok) {
|
|
1504
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
1505
|
+
}
|
|
1506
|
+
} catch (error) {
|
|
1507
|
+
logger.debug(`Failed to send Scarf event: ${error}`);
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
};
|
|
1511
|
+
function getCacheHome() {
|
|
1512
|
+
if (!isNodeJSEnvironment2()) {
|
|
1513
|
+
return "/tmp/mcp_use_cache";
|
|
1514
|
+
}
|
|
1515
|
+
const envVar = process.env.XDG_CACHE_HOME;
|
|
1516
|
+
if (envVar && path.isAbsolute(envVar)) {
|
|
1517
|
+
return envVar;
|
|
1518
|
+
}
|
|
1519
|
+
const platform = process.platform;
|
|
1520
|
+
const homeDir = os.homedir();
|
|
1521
|
+
if (platform === "win32") {
|
|
1522
|
+
const appdata = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
1523
|
+
if (appdata) {
|
|
1524
|
+
return appdata;
|
|
1525
|
+
}
|
|
1526
|
+
return path.join(homeDir, "AppData", "Local");
|
|
1527
|
+
} else if (platform === "darwin") {
|
|
1528
|
+
return path.join(homeDir, "Library", "Caches");
|
|
1529
|
+
} else {
|
|
1530
|
+
return path.join(homeDir, ".cache");
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
__name(getCacheHome, "getCacheHome");
|
|
1534
|
+
var Telemetry = class _Telemetry {
|
|
1535
|
+
static {
|
|
1536
|
+
__name(this, "Telemetry");
|
|
1537
|
+
}
|
|
1538
|
+
static instance = null;
|
|
1539
|
+
USER_ID_PATH = path.join(
|
|
1540
|
+
getCacheHome(),
|
|
1541
|
+
"mcp_use_3",
|
|
1542
|
+
"telemetry_user_id"
|
|
1543
|
+
);
|
|
1544
|
+
VERSION_DOWNLOAD_PATH = path.join(
|
|
1545
|
+
getCacheHome(),
|
|
1546
|
+
"mcp_use",
|
|
1547
|
+
"download_version"
|
|
1548
|
+
);
|
|
1549
|
+
PROJECT_API_KEY = "phc_lyTtbYwvkdSbrcMQNPiKiiRWrrM1seyKIMjycSvItEI";
|
|
1550
|
+
HOST = "https://eu.i.posthog.com";
|
|
1551
|
+
SCARF_GATEWAY_URL = "https://mcpuse.gateway.scarf.sh/events-ts";
|
|
1552
|
+
UNKNOWN_USER_ID = "UNKNOWN_USER_ID";
|
|
1553
|
+
_currUserId = null;
|
|
1554
|
+
_posthogClient = null;
|
|
1555
|
+
_scarfClient = null;
|
|
1556
|
+
_runtimeEnvironment;
|
|
1557
|
+
_storageCapability;
|
|
1558
|
+
_source;
|
|
1559
|
+
constructor() {
|
|
1560
|
+
this._runtimeEnvironment = getRuntimeEnvironment();
|
|
1561
|
+
this._storageCapability = getStorageCapability(this._runtimeEnvironment);
|
|
1562
|
+
this._source = typeof process !== "undefined" && process.env?.MCP_USE_TELEMETRY_SOURCE || this._runtimeEnvironment;
|
|
1563
|
+
const telemetryDisabled = typeof process !== "undefined" && process.env?.MCP_USE_ANONYMIZED_TELEMETRY?.toLowerCase() === "false" || false;
|
|
1564
|
+
const canSupportTelemetry = this._runtimeEnvironment !== "unknown";
|
|
1565
|
+
const isServerlessEnvironment = [
|
|
1566
|
+
"cloudflare-workers",
|
|
1567
|
+
"edge",
|
|
1568
|
+
"deno"
|
|
1569
|
+
].includes(this._runtimeEnvironment);
|
|
1570
|
+
if (telemetryDisabled) {
|
|
1571
|
+
this._posthogClient = null;
|
|
1572
|
+
this._scarfClient = null;
|
|
1573
|
+
logger.debug("Telemetry disabled via environment variable");
|
|
1574
|
+
} else if (!canSupportTelemetry) {
|
|
1575
|
+
this._posthogClient = null;
|
|
1576
|
+
this._scarfClient = null;
|
|
1577
|
+
logger.debug(
|
|
1578
|
+
`Telemetry disabled - unknown environment: ${this._runtimeEnvironment}`
|
|
1579
|
+
);
|
|
1580
|
+
} else {
|
|
1581
|
+
logger.info(
|
|
1582
|
+
"Anonymized telemetry enabled. Set MCP_USE_ANONYMIZED_TELEMETRY=false to disable."
|
|
1583
|
+
);
|
|
1584
|
+
if (this._runtimeEnvironment !== "browser") {
|
|
1585
|
+
try {
|
|
1586
|
+
const posthogOptions = {
|
|
1587
|
+
host: this.HOST,
|
|
1588
|
+
disableGeoip: false
|
|
1589
|
+
};
|
|
1590
|
+
if (isServerlessEnvironment) {
|
|
1591
|
+
posthogOptions.flushAt = 1;
|
|
1592
|
+
posthogOptions.flushInterval = 0;
|
|
1593
|
+
}
|
|
1594
|
+
this._posthogClient = new import_posthog_node.PostHog(
|
|
1595
|
+
this.PROJECT_API_KEY,
|
|
1596
|
+
posthogOptions
|
|
1597
|
+
);
|
|
1598
|
+
} catch (e) {
|
|
1599
|
+
logger.warn(`Failed to initialize PostHog telemetry: ${e}`);
|
|
1600
|
+
this._posthogClient = null;
|
|
1297
1601
|
}
|
|
1602
|
+
} else {
|
|
1603
|
+
this._posthogClient = null;
|
|
1604
|
+
}
|
|
1605
|
+
try {
|
|
1606
|
+
this._scarfClient = new ScarfEventLogger(this.SCARF_GATEWAY_URL, 3e3);
|
|
1607
|
+
} catch (e) {
|
|
1608
|
+
logger.warn(`Failed to initialize Scarf telemetry: ${e}`);
|
|
1609
|
+
this._scarfClient = null;
|
|
1298
1610
|
}
|
|
1299
1611
|
}
|
|
1300
1612
|
}
|
|
1301
1613
|
/**
|
|
1302
|
-
*
|
|
1303
|
-
*
|
|
1304
|
-
* @param {JSONValue} data - The data to validate.
|
|
1305
|
-
* @param {JSONSchema} schema - The schema containing if-then-else conditions.
|
|
1306
|
-
* @param {z.RefinementCtx} ctx - The Zod refinement context.
|
|
1614
|
+
* Get the detected runtime environment
|
|
1307
1615
|
*/
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
return;
|
|
1311
|
-
}
|
|
1312
|
-
const matchesIf = this.matchesCondition(data, schema["if"]);
|
|
1313
|
-
if (matchesIf) {
|
|
1314
|
-
this.validateConditionalSchema(data, schema["then"], ctx);
|
|
1315
|
-
} else if (schema["else"]) {
|
|
1316
|
-
this.validateConditionalSchema(data, schema["else"], ctx);
|
|
1317
|
-
}
|
|
1616
|
+
get runtimeEnvironment() {
|
|
1617
|
+
return this._runtimeEnvironment;
|
|
1318
1618
|
}
|
|
1319
1619
|
/**
|
|
1320
|
-
*
|
|
1321
|
-
* This is the main entry point for schema conversion.
|
|
1322
|
-
*
|
|
1323
|
-
* @param {JSONSchema} schema - The JSON schema.
|
|
1324
|
-
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1620
|
+
* Get the storage capability for this environment
|
|
1325
1621
|
*/
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
return this.handleTypeArray(schema);
|
|
1329
|
-
}
|
|
1330
|
-
if (schema.oneOf || schema.anyOf || schema.allOf) {
|
|
1331
|
-
return this.parseCombinator(schema);
|
|
1332
|
-
}
|
|
1333
|
-
if (schema["if"] && schema["then"]) {
|
|
1334
|
-
return this.parseObject(schema);
|
|
1335
|
-
}
|
|
1336
|
-
if (schema.properties && (!schema.type || schema.type === "object")) {
|
|
1337
|
-
return this.parseObject(schema);
|
|
1338
|
-
}
|
|
1339
|
-
return this.handleSingleType(schema);
|
|
1622
|
+
get storageCapability() {
|
|
1623
|
+
return this._storageCapability;
|
|
1340
1624
|
}
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
* @param {JSONSchema} schema - The JSON schema with type array.
|
|
1345
|
-
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1346
|
-
*/
|
|
1347
|
-
static handleTypeArray(schema) {
|
|
1348
|
-
if (!Array.isArray(schema.type)) {
|
|
1349
|
-
throw new Error("Expected schema.type to be an array");
|
|
1350
|
-
}
|
|
1351
|
-
if (schema.type.includes("null")) {
|
|
1352
|
-
return this.handleNullableType(schema);
|
|
1625
|
+
static getInstance() {
|
|
1626
|
+
if (!_Telemetry.instance) {
|
|
1627
|
+
_Telemetry.instance = new _Telemetry();
|
|
1353
1628
|
}
|
|
1354
|
-
return
|
|
1629
|
+
return _Telemetry.instance;
|
|
1355
1630
|
}
|
|
1356
1631
|
/**
|
|
1357
|
-
*
|
|
1358
|
-
*
|
|
1359
|
-
* @param
|
|
1360
|
-
* @returns {ZodTypeAny} - The nullable Zod schema.
|
|
1632
|
+
* Set the source identifier for telemetry events.
|
|
1633
|
+
* This allows tracking usage from different applications.
|
|
1634
|
+
* @param source - The source identifier (e.g., "my-app", "cli", "vs-code-extension")
|
|
1361
1635
|
*/
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
}
|
|
1366
|
-
const nonNullSchema = { ...schema };
|
|
1367
|
-
nonNullSchema.type = schema.type.filter((t) => t !== "null");
|
|
1368
|
-
if (nonNullSchema.type.length === 1) {
|
|
1369
|
-
const singleTypeSchema = this.handleSingleType({
|
|
1370
|
-
...schema,
|
|
1371
|
-
type: nonNullSchema.type[0]
|
|
1372
|
-
});
|
|
1373
|
-
return singleTypeSchema.nullable();
|
|
1374
|
-
}
|
|
1375
|
-
const unionSchema = this.parseSchema(nonNullSchema);
|
|
1376
|
-
return unionSchema.nullable();
|
|
1636
|
+
setSource(source) {
|
|
1637
|
+
this._source = source;
|
|
1638
|
+
logger.debug(`Telemetry source set to: ${source}`);
|
|
1377
1639
|
}
|
|
1378
1640
|
/**
|
|
1379
|
-
*
|
|
1380
|
-
*
|
|
1381
|
-
* @param {string[]} types - Array of type strings.
|
|
1382
|
-
* @param {JSONSchema} baseSchema - The base schema to apply to each type.
|
|
1383
|
-
* @returns {ZodTypeAny} - The union Zod schema.
|
|
1641
|
+
* Get the current source identifier.
|
|
1384
1642
|
*/
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
const singleTypeSchema = { ...baseSchema, type };
|
|
1388
|
-
return this.parseSchema(singleTypeSchema);
|
|
1389
|
-
});
|
|
1390
|
-
return import_zod.z.union(schemas);
|
|
1643
|
+
getSource() {
|
|
1644
|
+
return this._source;
|
|
1391
1645
|
}
|
|
1392
1646
|
/**
|
|
1393
|
-
*
|
|
1394
|
-
*
|
|
1395
|
-
* @param {JSONSchema} schema - The JSON schema with single type.
|
|
1396
|
-
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1647
|
+
* Check if telemetry is enabled.
|
|
1648
|
+
* Returns false if telemetry was disabled via environment variable or if not in Node.js environment.
|
|
1397
1649
|
*/
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1650
|
+
get isEnabled() {
|
|
1651
|
+
return this._posthogClient !== null || this._scarfClient !== null;
|
|
1652
|
+
}
|
|
1653
|
+
get userId() {
|
|
1654
|
+
if (this._currUserId) {
|
|
1655
|
+
return this._currUserId;
|
|
1656
|
+
}
|
|
1657
|
+
try {
|
|
1658
|
+
switch (this._storageCapability) {
|
|
1659
|
+
case "filesystem":
|
|
1660
|
+
this._currUserId = this.getUserIdFromFilesystem();
|
|
1661
|
+
break;
|
|
1662
|
+
case "localStorage":
|
|
1663
|
+
this._currUserId = this.getUserIdFromLocalStorage();
|
|
1664
|
+
break;
|
|
1665
|
+
case "session-only":
|
|
1666
|
+
default:
|
|
1667
|
+
this._currUserId = `session-${generateUUID()}`;
|
|
1668
|
+
logger.debug(
|
|
1669
|
+
`Using session-based user ID (${this._runtimeEnvironment} environment)`
|
|
1670
|
+
);
|
|
1671
|
+
break;
|
|
1402
1672
|
}
|
|
1403
|
-
if (
|
|
1404
|
-
|
|
1673
|
+
if (this._storageCapability === "filesystem" && this._currUserId) {
|
|
1674
|
+
this.trackPackageDownloadInternal(this._currUserId, {
|
|
1675
|
+
triggered_by: "user_id_property"
|
|
1676
|
+
}).catch((e) => logger.debug(`Failed to track package download: ${e}`));
|
|
1405
1677
|
}
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
case "string":
|
|
1410
|
-
return this.parseString(schema);
|
|
1411
|
-
case "number":
|
|
1412
|
-
case "integer":
|
|
1413
|
-
return this.parseNumberSchema(schema);
|
|
1414
|
-
case "boolean":
|
|
1415
|
-
return import_zod.z.boolean();
|
|
1416
|
-
case "array":
|
|
1417
|
-
return this.parseArray(schema);
|
|
1418
|
-
case "object":
|
|
1419
|
-
return this.parseObject(schema);
|
|
1420
|
-
default:
|
|
1421
|
-
throw new Error("Unsupported schema type");
|
|
1678
|
+
} catch (e) {
|
|
1679
|
+
logger.debug(`Failed to get/create user ID: ${e}`);
|
|
1680
|
+
this._currUserId = this.UNKNOWN_USER_ID;
|
|
1422
1681
|
}
|
|
1682
|
+
return this._currUserId;
|
|
1423
1683
|
}
|
|
1424
1684
|
/**
|
|
1425
|
-
*
|
|
1426
|
-
*
|
|
1427
|
-
* @param {JSONSchema} schema - The JSON schema for a number.
|
|
1428
|
-
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1429
|
-
*/
|
|
1430
|
-
static parseNumberSchema(schema) {
|
|
1431
|
-
const numberSchema = import_zod.z.number();
|
|
1432
|
-
let result = numberSchema;
|
|
1433
|
-
result = this.applyNumberBounds(numberSchema, schema);
|
|
1434
|
-
result = this.applyNumberMultipleOf(numberSchema, schema);
|
|
1435
|
-
result = this.applyNumberEnum(numberSchema, schema);
|
|
1436
|
-
result = this.applyIntegerConstraint(numberSchema, schema);
|
|
1437
|
-
return result;
|
|
1438
|
-
}
|
|
1439
|
-
/**
|
|
1440
|
-
* Applies bounds validation to a number schema.
|
|
1441
|
-
*
|
|
1442
|
-
* @param {z.ZodNumber} numberSchema - The base number schema.
|
|
1443
|
-
* @param {JSONSchema} schema - The JSON schema with bounds.
|
|
1444
|
-
* @returns {z.ZodNumber} - The updated schema with bounds validation.
|
|
1685
|
+
* Get or create user ID from filesystem (Node.js/Bun)
|
|
1445
1686
|
*/
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
if (
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1687
|
+
getUserIdFromFilesystem() {
|
|
1688
|
+
const isFirstTime = !fs.existsSync(this.USER_ID_PATH);
|
|
1689
|
+
if (isFirstTime) {
|
|
1690
|
+
logger.debug(`Creating user ID path: ${this.USER_ID_PATH}`);
|
|
1691
|
+
fs.mkdirSync(path.dirname(this.USER_ID_PATH), { recursive: true });
|
|
1692
|
+
const newUserId = generateUUID();
|
|
1693
|
+
fs.writeFileSync(this.USER_ID_PATH, newUserId);
|
|
1694
|
+
logger.debug(`User ID path created: ${this.USER_ID_PATH}`);
|
|
1695
|
+
return newUserId;
|
|
1696
|
+
}
|
|
1697
|
+
return fs.readFileSync(this.USER_ID_PATH, "utf-8").trim();
|
|
1455
1698
|
}
|
|
1456
1699
|
/**
|
|
1457
|
-
*
|
|
1458
|
-
*
|
|
1459
|
-
* @param {z.ZodNumber} numberSchema - The base number schema.
|
|
1460
|
-
* @param {JSONSchema} schema - The JSON schema with multipleOf.
|
|
1461
|
-
* @returns {z.ZodNumber} - The updated schema with multipleOf validation.
|
|
1700
|
+
* Get or create user ID from localStorage (Browser)
|
|
1462
1701
|
*/
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1702
|
+
getUserIdFromLocalStorage() {
|
|
1703
|
+
try {
|
|
1704
|
+
let userId = localStorage.getItem(USER_ID_STORAGE_KEY);
|
|
1705
|
+
if (!userId) {
|
|
1706
|
+
userId = generateUUID();
|
|
1707
|
+
localStorage.setItem(USER_ID_STORAGE_KEY, userId);
|
|
1708
|
+
logger.debug(`Created new browser user ID`);
|
|
1709
|
+
}
|
|
1710
|
+
return userId;
|
|
1711
|
+
} catch (e) {
|
|
1712
|
+
logger.debug(`localStorage access failed: ${e}`);
|
|
1713
|
+
return `session-${generateUUID()}`;
|
|
1466
1714
|
}
|
|
1467
|
-
return numberSchema.refine((val) => val % schema["multipleOf"] === 0, {
|
|
1468
|
-
message: `Number must be a multiple of ${schema["multipleOf"]}`
|
|
1469
|
-
});
|
|
1470
1715
|
}
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
* @param {z.ZodNumber} numberSchema - The base number schema.
|
|
1475
|
-
* @param {JSONSchema} schema - The JSON schema with enum.
|
|
1476
|
-
* @returns {z.ZodNumber} - The updated schema with enum validation.
|
|
1477
|
-
*/
|
|
1478
|
-
static applyNumberEnum(numberSchema, schema) {
|
|
1479
|
-
if (!schema.enum) {
|
|
1480
|
-
return numberSchema;
|
|
1481
|
-
}
|
|
1482
|
-
const numberEnums = schema.enum.filter(
|
|
1483
|
-
(val) => typeof val === "number"
|
|
1716
|
+
async capture(event) {
|
|
1717
|
+
logger.debug(
|
|
1718
|
+
`CAPTURE: posthog: ${this._posthogClient !== null}, scarf: ${this._scarfClient !== null}`
|
|
1484
1719
|
);
|
|
1485
|
-
if (
|
|
1486
|
-
return
|
|
1720
|
+
if (!this._posthogClient && !this._scarfClient) {
|
|
1721
|
+
return;
|
|
1487
1722
|
}
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1723
|
+
if (this._posthogClient) {
|
|
1724
|
+
try {
|
|
1725
|
+
const properties = { ...event.properties };
|
|
1726
|
+
properties.mcp_use_version = getPackageVersion();
|
|
1727
|
+
properties.language = "typescript";
|
|
1728
|
+
properties.source = this._source;
|
|
1729
|
+
properties.runtime = this._runtimeEnvironment;
|
|
1730
|
+
logger.debug(`CAPTURE: PostHog Event ${event.name}`);
|
|
1731
|
+
logger.debug(
|
|
1732
|
+
`CAPTURE: PostHog Properties ${JSON.stringify(properties)}`
|
|
1733
|
+
);
|
|
1734
|
+
this._posthogClient.capture({
|
|
1735
|
+
distinctId: this.userId,
|
|
1736
|
+
event: event.name,
|
|
1737
|
+
properties
|
|
1738
|
+
});
|
|
1739
|
+
} catch (e) {
|
|
1740
|
+
logger.debug(`Failed to track PostHog event ${event.name}: ${e}`);
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
if (this._scarfClient) {
|
|
1744
|
+
try {
|
|
1745
|
+
const properties = {};
|
|
1746
|
+
properties.mcp_use_version = getPackageVersion();
|
|
1747
|
+
properties.user_id = this.userId;
|
|
1748
|
+
properties.event = event.name;
|
|
1749
|
+
properties.language = "typescript";
|
|
1750
|
+
properties.source = this._source;
|
|
1751
|
+
properties.runtime = this._runtimeEnvironment;
|
|
1752
|
+
await this._scarfClient.logEvent(properties);
|
|
1753
|
+
} catch (e) {
|
|
1754
|
+
logger.debug(`Failed to track Scarf event ${event.name}: ${e}`);
|
|
1755
|
+
}
|
|
1502
1756
|
}
|
|
1503
|
-
return numberSchema.refine((val) => Number.isInteger(val), {
|
|
1504
|
-
message: "Number must be an integer"
|
|
1505
|
-
});
|
|
1506
1757
|
}
|
|
1507
1758
|
/**
|
|
1508
|
-
*
|
|
1509
|
-
*
|
|
1510
|
-
* @param {JSONSchema} schema - The JSON schema for a string.
|
|
1511
|
-
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1759
|
+
* Track package download event.
|
|
1760
|
+
* This is a public wrapper that safely accesses userId.
|
|
1512
1761
|
*/
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
let result = stringSchema;
|
|
1516
|
-
if (schema.format) {
|
|
1517
|
-
return this.applyStringFormat(stringSchema, schema);
|
|
1518
|
-
} else {
|
|
1519
|
-
result = this.applyStringPattern(stringSchema, schema);
|
|
1520
|
-
result = this.applyStringLength(stringSchema, schema);
|
|
1521
|
-
result = this.applyStringEnum(stringSchema, schema);
|
|
1522
|
-
}
|
|
1523
|
-
return result;
|
|
1762
|
+
async trackPackageDownload(properties) {
|
|
1763
|
+
return this.trackPackageDownloadInternal(this.userId, properties);
|
|
1524
1764
|
}
|
|
1525
1765
|
/**
|
|
1526
|
-
*
|
|
1527
|
-
*
|
|
1528
|
-
* @param {z.ZodString} stringSchema - The base string schema.
|
|
1529
|
-
* @param {JSONSchema} schema - The JSON schema with format.
|
|
1530
|
-
* @returns {ZodTypeAny} - The updated schema with format validation.
|
|
1766
|
+
* Internal method to track package download with explicit userId.
|
|
1767
|
+
* This avoids circular dependency when called from the userId getter.
|
|
1531
1768
|
*/
|
|
1532
|
-
|
|
1533
|
-
if (!
|
|
1534
|
-
return
|
|
1769
|
+
async trackPackageDownloadInternal(userId, properties) {
|
|
1770
|
+
if (!this._scarfClient) {
|
|
1771
|
+
return;
|
|
1535
1772
|
}
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1773
|
+
if (this._storageCapability !== "filesystem") {
|
|
1774
|
+
return;
|
|
1775
|
+
}
|
|
1776
|
+
try {
|
|
1777
|
+
const currentVersion = getPackageVersion();
|
|
1778
|
+
let shouldTrack = false;
|
|
1779
|
+
let firstDownload = false;
|
|
1780
|
+
if (!fs.existsSync(this.VERSION_DOWNLOAD_PATH)) {
|
|
1781
|
+
shouldTrack = true;
|
|
1782
|
+
firstDownload = true;
|
|
1783
|
+
fs.mkdirSync(path.dirname(this.VERSION_DOWNLOAD_PATH), {
|
|
1784
|
+
recursive: true
|
|
1785
|
+
});
|
|
1786
|
+
fs.writeFileSync(this.VERSION_DOWNLOAD_PATH, currentVersion);
|
|
1787
|
+
} else {
|
|
1788
|
+
const savedVersion = fs.readFileSync(this.VERSION_DOWNLOAD_PATH, "utf-8").trim();
|
|
1789
|
+
if (currentVersion > savedVersion) {
|
|
1790
|
+
shouldTrack = true;
|
|
1791
|
+
firstDownload = false;
|
|
1792
|
+
fs.writeFileSync(this.VERSION_DOWNLOAD_PATH, currentVersion);
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
if (shouldTrack) {
|
|
1796
|
+
logger.debug(
|
|
1797
|
+
`Tracking package download event with properties: ${JSON.stringify(properties)}`
|
|
1798
|
+
);
|
|
1799
|
+
const eventProperties = { ...properties || {} };
|
|
1800
|
+
eventProperties.mcp_use_version = currentVersion;
|
|
1801
|
+
eventProperties.user_id = userId;
|
|
1802
|
+
eventProperties.event = "package_download";
|
|
1803
|
+
eventProperties.first_download = firstDownload;
|
|
1804
|
+
eventProperties.language = "typescript";
|
|
1805
|
+
eventProperties.source = this._source;
|
|
1806
|
+
eventProperties.runtime = this._runtimeEnvironment;
|
|
1807
|
+
await this._scarfClient.logEvent(eventProperties);
|
|
1808
|
+
}
|
|
1809
|
+
} catch (e) {
|
|
1810
|
+
logger.debug(`Failed to track Scarf package_download event: ${e}`);
|
|
1549
1811
|
}
|
|
1550
1812
|
}
|
|
1813
|
+
// ============================================================================
|
|
1814
|
+
// Agent Events
|
|
1815
|
+
// ============================================================================
|
|
1816
|
+
async trackAgentExecution(data) {
|
|
1817
|
+
if (!this.isEnabled) return;
|
|
1818
|
+
const event = new MCPAgentExecutionEvent(data);
|
|
1819
|
+
await this.capture(event);
|
|
1820
|
+
}
|
|
1821
|
+
// ============================================================================
|
|
1822
|
+
// Server Events
|
|
1823
|
+
// ============================================================================
|
|
1551
1824
|
/**
|
|
1552
|
-
*
|
|
1553
|
-
*
|
|
1554
|
-
* @param
|
|
1555
|
-
* @param
|
|
1556
|
-
* @returns {z.ZodString} - The updated schema with pattern validation.
|
|
1825
|
+
* Track server run event directly from an MCPServer instance.
|
|
1826
|
+
* This extracts the necessary data from the server and creates the event.
|
|
1827
|
+
* @param server - The MCPServer instance (or any object conforming to MCPServerTelemetryInfo)
|
|
1828
|
+
* @param transport - The transport type (e.g., "http", "stdio", "supabase")
|
|
1557
1829
|
*/
|
|
1558
|
-
|
|
1559
|
-
if (!
|
|
1560
|
-
|
|
1830
|
+
async trackServerRunFromServer(server, transport) {
|
|
1831
|
+
if (!this.isEnabled) return;
|
|
1832
|
+
const data = createServerRunEventData(server, transport);
|
|
1833
|
+
const event = new ServerRunEvent(data);
|
|
1834
|
+
await this.capture(event);
|
|
1835
|
+
}
|
|
1836
|
+
async trackServerInitialize(data) {
|
|
1837
|
+
if (!this.isEnabled) return;
|
|
1838
|
+
const event = new ServerInitializeEvent(data);
|
|
1839
|
+
await this.capture(event);
|
|
1840
|
+
}
|
|
1841
|
+
async trackServerToolCall(data) {
|
|
1842
|
+
if (!this.isEnabled) return;
|
|
1843
|
+
const event = new ServerToolCallEvent(data);
|
|
1844
|
+
await this.capture(event);
|
|
1845
|
+
}
|
|
1846
|
+
async trackServerResourceCall(data) {
|
|
1847
|
+
if (!this.isEnabled) return;
|
|
1848
|
+
const event = new ServerResourceCallEvent(data);
|
|
1849
|
+
await this.capture(event);
|
|
1850
|
+
}
|
|
1851
|
+
async trackServerPromptCall(data) {
|
|
1852
|
+
if (!this.isEnabled) return;
|
|
1853
|
+
const event = new ServerPromptCallEvent(data);
|
|
1854
|
+
await this.capture(event);
|
|
1855
|
+
}
|
|
1856
|
+
async trackServerContext(data) {
|
|
1857
|
+
if (!this.isEnabled) return;
|
|
1858
|
+
const event = new ServerContextEvent(data);
|
|
1859
|
+
await this.capture(event);
|
|
1860
|
+
}
|
|
1861
|
+
// ============================================================================
|
|
1862
|
+
// Client Events
|
|
1863
|
+
// ============================================================================
|
|
1864
|
+
async trackMCPClientInit(data) {
|
|
1865
|
+
if (!this.isEnabled) return;
|
|
1866
|
+
const event = new MCPClientInitEvent(data);
|
|
1867
|
+
await this.capture(event);
|
|
1868
|
+
}
|
|
1869
|
+
async trackConnectorInit(data) {
|
|
1870
|
+
if (!this.isEnabled) return;
|
|
1871
|
+
const event = new ConnectorInitEvent(data);
|
|
1872
|
+
await this.capture(event);
|
|
1873
|
+
}
|
|
1874
|
+
flush() {
|
|
1875
|
+
if (this._posthogClient) {
|
|
1876
|
+
try {
|
|
1877
|
+
this._posthogClient.flush();
|
|
1878
|
+
logger.debug("PostHog client telemetry queue flushed");
|
|
1879
|
+
} catch (e) {
|
|
1880
|
+
logger.debug(`Failed to flush PostHog client: ${e}`);
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
if (this._scarfClient) {
|
|
1884
|
+
logger.debug("Scarf telemetry events sent immediately (no flush needed)");
|
|
1561
1885
|
}
|
|
1562
|
-
const regex = new RegExp(schema["pattern"]);
|
|
1563
|
-
return stringSchema.regex(regex, {
|
|
1564
|
-
message: `String must match pattern: ${schema["pattern"]}`
|
|
1565
|
-
});
|
|
1566
1886
|
}
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
const result = stringSchema;
|
|
1576
|
-
if (schema["minLength"] !== void 0) {
|
|
1577
|
-
stringSchema = stringSchema.min(schema["minLength"]);
|
|
1887
|
+
shutdown() {
|
|
1888
|
+
if (this._posthogClient) {
|
|
1889
|
+
try {
|
|
1890
|
+
this._posthogClient.shutdown();
|
|
1891
|
+
logger.debug("PostHog client shutdown successfully");
|
|
1892
|
+
} catch (e) {
|
|
1893
|
+
logger.debug(`Error shutting down PostHog client: ${e}`);
|
|
1894
|
+
}
|
|
1578
1895
|
}
|
|
1579
|
-
if (
|
|
1580
|
-
|
|
1896
|
+
if (this._scarfClient) {
|
|
1897
|
+
logger.debug("Scarf telemetry client shutdown (no action needed)");
|
|
1581
1898
|
}
|
|
1582
|
-
return result;
|
|
1583
1899
|
}
|
|
1900
|
+
};
|
|
1901
|
+
|
|
1902
|
+
// src/client/connectors/codeMode.ts
|
|
1903
|
+
var CODE_MODE_AGENT_PROMPT = `
|
|
1904
|
+
## MCP Code Mode Tool Usage Guide
|
|
1905
|
+
|
|
1906
|
+
You have access to an MCP Code Mode Client that allows you to execute JavaScript/TypeScript code with access to registered tools. Follow this workflow:
|
|
1907
|
+
|
|
1908
|
+
### 1. Tool Discovery Phase
|
|
1909
|
+
**Always start by discovering available tools:**
|
|
1910
|
+
- Tools are organized by server namespace (e.g., \`server_name.tool_name\`)
|
|
1911
|
+
- Use the \`search_tools(query, detail_level)\` function to find available tools
|
|
1912
|
+
- You can access \`__tool_namespaces\` to see all available server namespaces
|
|
1913
|
+
|
|
1914
|
+
\`\`\`javascript
|
|
1915
|
+
// Find all GitHub-related tools
|
|
1916
|
+
const tools = await search_tools("github");
|
|
1917
|
+
for (const tool of tools) {
|
|
1918
|
+
console.log(\`\${tool.server}.\${tool.name}: \${tool.description}\`);
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
// Get only tool names for quick overview
|
|
1922
|
+
const tools = await search_tools("", "names");
|
|
1923
|
+
\`\`\`
|
|
1924
|
+
|
|
1925
|
+
### 2. Interface Introspection
|
|
1926
|
+
**Understand tool contracts before using them:**
|
|
1927
|
+
- Use \`search_tools\` to get tool descriptions and input schemas
|
|
1928
|
+
- Look for "Access as: server.tool(args)" patterns in descriptions
|
|
1929
|
+
|
|
1930
|
+
### 3. Code Execution Guidelines
|
|
1931
|
+
**When writing code:**
|
|
1932
|
+
- Use \`await server.tool({ param: value })\` syntax for all tool calls
|
|
1933
|
+
- Tools are async functions that return promises
|
|
1934
|
+
- You have access to standard JavaScript globals: \`console\`, \`JSON\`, \`Math\`, \`Date\`, etc.
|
|
1935
|
+
- All console output (\`console.log\`, \`console.error\`, etc.) is automatically captured and returned
|
|
1936
|
+
- Build properly structured input objects based on interface definitions
|
|
1937
|
+
- Handle errors appropriately with try/catch blocks
|
|
1938
|
+
- Chain tool calls by using results from previous calls
|
|
1939
|
+
|
|
1940
|
+
### 4. Best Practices
|
|
1941
|
+
- **Discover first, code second**: Always explore available tools before writing execution code
|
|
1942
|
+
- **Respect namespaces**: Use full \`server.tool\` names to avoid conflicts
|
|
1943
|
+
- **Minimize Context**: Process large data in code, return only essential results
|
|
1944
|
+
- **Error handling**: Wrap tool calls in try/catch for robustness
|
|
1945
|
+
- **Data flow**: Chain tools by passing outputs as inputs to subsequent tools
|
|
1946
|
+
|
|
1947
|
+
### 5. Available Runtime Context
|
|
1948
|
+
- \`search_tools(query, detail_level)\`: Function to discover tools
|
|
1949
|
+
- \`__tool_namespaces\`: Array of available server namespaces
|
|
1950
|
+
- All registered tools as \`server.tool\` functions
|
|
1951
|
+
- Standard JavaScript built-ins for data processing
|
|
1952
|
+
|
|
1953
|
+
### Example Workflow
|
|
1954
|
+
|
|
1955
|
+
\`\`\`javascript
|
|
1956
|
+
// 1. Discover available tools
|
|
1957
|
+
const github_tools = await search_tools("github pull request");
|
|
1958
|
+
console.log(\`Available GitHub PR tools: \${github_tools.map(t => t.name)}\`);
|
|
1959
|
+
|
|
1960
|
+
// 2. Call tools with proper parameters
|
|
1961
|
+
const pr = await github.get_pull_request({
|
|
1962
|
+
owner: "facebook",
|
|
1963
|
+
repo: "react",
|
|
1964
|
+
number: 12345
|
|
1965
|
+
});
|
|
1966
|
+
|
|
1967
|
+
// 3. Process results
|
|
1968
|
+
let result;
|
|
1969
|
+
if (pr.state === 'open' && pr.labels.some(l => l.name === 'bug')) {
|
|
1970
|
+
// 4. Chain with other tools
|
|
1971
|
+
await slack.post_message({
|
|
1972
|
+
channel: "#bugs",
|
|
1973
|
+
text: \`\u{1F41B} Bug PR needs review: \${pr.title}\`
|
|
1974
|
+
});
|
|
1975
|
+
result = "Notification sent";
|
|
1976
|
+
} else {
|
|
1977
|
+
result = "No action needed";
|
|
1978
|
+
}
|
|
1979
|
+
|
|
1980
|
+
// 5. Return structured results
|
|
1981
|
+
return {
|
|
1982
|
+
pr_number: pr.number,
|
|
1983
|
+
pr_title: pr.title,
|
|
1984
|
+
action_taken: result
|
|
1985
|
+
};
|
|
1986
|
+
\`\`\`
|
|
1987
|
+
|
|
1988
|
+
Remember: Always discover and understand available tools before attempting to use them in code execution.
|
|
1989
|
+
`;
|
|
1990
|
+
|
|
1991
|
+
// src/client/prompts.ts
|
|
1992
|
+
var PROMPTS = {
|
|
1993
|
+
CODE_MODE: CODE_MODE_AGENT_PROMPT
|
|
1994
|
+
};
|
|
1995
|
+
|
|
1996
|
+
// src/agents/base.ts
|
|
1997
|
+
var BaseAgent = class {
|
|
1998
|
+
static {
|
|
1999
|
+
__name(this, "BaseAgent");
|
|
2000
|
+
}
|
|
2001
|
+
session;
|
|
1584
2002
|
/**
|
|
1585
|
-
*
|
|
1586
|
-
*
|
|
1587
|
-
* @param {z.ZodString} stringSchema - The base string schema.
|
|
1588
|
-
* @param {JSONSchema} schema - The JSON schema with enum.
|
|
1589
|
-
* @returns {ZodTypeAny} - The updated schema with enum validation.
|
|
2003
|
+
* @param session MCP session used for tool invocation
|
|
1590
2004
|
*/
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
2005
|
+
constructor(session) {
|
|
2006
|
+
this.session = session;
|
|
2007
|
+
}
|
|
2008
|
+
};
|
|
2009
|
+
|
|
2010
|
+
// src/agents/mcp_agent.ts
|
|
2011
|
+
var import_langchain2 = require("langchain");
|
|
2012
|
+
var import_zod9 = require("zod");
|
|
2013
|
+
|
|
2014
|
+
// src/utils/json-schema-to-zod/JSONSchemaToZod.ts
|
|
2015
|
+
var import_zod = require("zod");
|
|
2016
|
+
var JSONSchemaToZod = class {
|
|
2017
|
+
static {
|
|
2018
|
+
__name(this, "JSONSchemaToZod");
|
|
1598
2019
|
}
|
|
1599
2020
|
/**
|
|
1600
|
-
*
|
|
2021
|
+
* Converts a JSON schema to a Zod schema.
|
|
1601
2022
|
*
|
|
1602
2023
|
* @param {JSONSchema} schema - The JSON schema.
|
|
1603
|
-
* @returns {
|
|
2024
|
+
* @returns {ZodSchema} - The Zod schema.
|
|
1604
2025
|
*/
|
|
1605
|
-
static
|
|
1606
|
-
|
|
1607
|
-
const tupleSchemas = schema.items.map((item) => this.parseSchema(item));
|
|
1608
|
-
return import_zod.z.union(tupleSchemas);
|
|
1609
|
-
}
|
|
1610
|
-
const itemSchema = schema.items ? this.parseSchema(schema.items) : import_zod.z.any();
|
|
1611
|
-
const arraySchema = import_zod.z.array(itemSchema);
|
|
1612
|
-
let result = arraySchema;
|
|
1613
|
-
result = this.applyArrayConstraints(arraySchema, schema);
|
|
1614
|
-
return result;
|
|
2026
|
+
static convert(schema) {
|
|
2027
|
+
return this.parseSchema(schema);
|
|
1615
2028
|
}
|
|
1616
2029
|
/**
|
|
1617
|
-
*
|
|
2030
|
+
* Checks if data matches a condition schema.
|
|
1618
2031
|
*
|
|
1619
|
-
* @param {
|
|
1620
|
-
* @param {JSONSchema}
|
|
1621
|
-
* @returns {
|
|
2032
|
+
* @param {JSONValue} data - The data to check.
|
|
2033
|
+
* @param {JSONSchema} condition - The condition schema.
|
|
2034
|
+
* @returns {boolean} - Whether the data matches the condition.
|
|
1622
2035
|
*/
|
|
1623
|
-
static
|
|
1624
|
-
if (
|
|
1625
|
-
|
|
2036
|
+
static matchesCondition(data, condition) {
|
|
2037
|
+
if (!condition.properties) {
|
|
2038
|
+
return true;
|
|
1626
2039
|
}
|
|
1627
|
-
if (
|
|
1628
|
-
|
|
2040
|
+
if (typeof data !== "object" || data === null || Array.isArray(data)) {
|
|
2041
|
+
return false;
|
|
1629
2042
|
}
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
2043
|
+
const objectData = data;
|
|
2044
|
+
for (const [key, propCondition] of Object.entries(condition.properties)) {
|
|
2045
|
+
if (!(key in objectData)) {
|
|
2046
|
+
if ("const" in propCondition) {
|
|
2047
|
+
return false;
|
|
2048
|
+
}
|
|
2049
|
+
continue;
|
|
2050
|
+
}
|
|
2051
|
+
const value = objectData[key];
|
|
2052
|
+
if ("const" in propCondition && value !== propCondition["const"]) {
|
|
2053
|
+
return false;
|
|
2054
|
+
}
|
|
2055
|
+
if ("minimum" in propCondition && typeof value === "number" && value < propCondition["minimum"]) {
|
|
2056
|
+
return false;
|
|
2057
|
+
}
|
|
2058
|
+
if ("maximum" in propCondition && typeof value === "number" && value > propCondition["maximum"]) {
|
|
2059
|
+
return false;
|
|
2060
|
+
}
|
|
1635
2061
|
}
|
|
1636
|
-
return
|
|
2062
|
+
return true;
|
|
1637
2063
|
}
|
|
1638
2064
|
/**
|
|
1639
|
-
*
|
|
2065
|
+
* Validates data against a conditional schema and adds issues to context if validation fails.
|
|
1640
2066
|
*
|
|
1641
|
-
* @param {
|
|
1642
|
-
* @
|
|
2067
|
+
* @param {JSONValue} data - The data to validate.
|
|
2068
|
+
* @param {JSONSchema} schema - The conditional schema.
|
|
2069
|
+
* @param {z.RefinementCtx} ctx - The Zod refinement context.
|
|
1643
2070
|
*/
|
|
1644
|
-
static
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
const shape = {};
|
|
1649
|
-
this.processObjectProperties(schema, shape);
|
|
1650
|
-
return this.processAdditionalProperties(schema, import_zod.z.object(shape));
|
|
2071
|
+
static validateConditionalSchema(data, schema, ctx) {
|
|
2072
|
+
this.validateRequiredProperties(data, schema, ctx);
|
|
2073
|
+
this.validatePropertyPatterns(data, schema, ctx);
|
|
2074
|
+
this.validateNestedConditions(data, schema, ctx);
|
|
1651
2075
|
}
|
|
1652
2076
|
/**
|
|
1653
|
-
*
|
|
2077
|
+
* Validates that all required properties are present in the data.
|
|
1654
2078
|
*
|
|
1655
|
-
* @param {
|
|
1656
|
-
* @param {
|
|
2079
|
+
* @param {JSONValue} data - The data to validate.
|
|
2080
|
+
* @param {JSONSchema} schema - The schema containing required properties.
|
|
2081
|
+
* @param {z.RefinementCtx} ctx - The Zod refinement context.
|
|
1657
2082
|
*/
|
|
1658
|
-
static
|
|
1659
|
-
|
|
1660
|
-
if (!schema.properties) {
|
|
2083
|
+
static validateRequiredProperties(data, schema, ctx) {
|
|
2084
|
+
if (!schema.required) {
|
|
1661
2085
|
return;
|
|
1662
2086
|
}
|
|
1663
|
-
|
|
1664
|
-
const
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
* @param {z.ZodObject<any, any>} objectSchema - The Zod object schema.
|
|
1673
|
-
* @returns {z.ZodObject<any, any>} - The updated Zod object schema.
|
|
1674
|
-
*/
|
|
1675
|
-
static processAdditionalProperties(schema, objectSchema) {
|
|
1676
|
-
if (schema.additionalProperties === true) {
|
|
1677
|
-
return objectSchema.passthrough();
|
|
1678
|
-
} else if (schema.additionalProperties && typeof schema.additionalProperties === "object") {
|
|
1679
|
-
const additionalPropSchema = this.parseSchema(
|
|
1680
|
-
schema.additionalProperties
|
|
1681
|
-
);
|
|
1682
|
-
return objectSchema.catchall(additionalPropSchema);
|
|
1683
|
-
} else {
|
|
1684
|
-
return objectSchema.strict();
|
|
2087
|
+
if (typeof data !== "object" || data === null) {
|
|
2088
|
+
for (const requiredProp of schema.required) {
|
|
2089
|
+
ctx.addIssue({
|
|
2090
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
2091
|
+
message: `Required property '${requiredProp}' is missing`,
|
|
2092
|
+
path: [requiredProp]
|
|
2093
|
+
});
|
|
2094
|
+
}
|
|
2095
|
+
return;
|
|
1685
2096
|
}
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
static parseConditional(schema) {
|
|
1694
|
-
const zodObject = this.createBaseObjectSchema(schema);
|
|
1695
|
-
const ifCondition = schema["if"];
|
|
1696
|
-
const thenSchema = schema["then"];
|
|
1697
|
-
const elseSchema = schema["else"];
|
|
1698
|
-
return zodObject.superRefine((data, ctx) => {
|
|
1699
|
-
const dataWithDefaults = this.applyDefaultValues(
|
|
1700
|
-
data,
|
|
1701
|
-
schema
|
|
1702
|
-
);
|
|
1703
|
-
if (this.matchesCondition(dataWithDefaults, ifCondition)) {
|
|
1704
|
-
this.validateConditionalSchema(dataWithDefaults, thenSchema, ctx);
|
|
1705
|
-
} else if (elseSchema) {
|
|
1706
|
-
this.validateConditionalSchema(dataWithDefaults, elseSchema, ctx);
|
|
2097
|
+
for (const requiredProp of schema.required) {
|
|
2098
|
+
if (!(requiredProp in data)) {
|
|
2099
|
+
ctx.addIssue({
|
|
2100
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
2101
|
+
message: `Required property '${requiredProp}' is missing`,
|
|
2102
|
+
path: [requiredProp]
|
|
2103
|
+
});
|
|
1707
2104
|
}
|
|
1708
|
-
});
|
|
1709
|
-
}
|
|
1710
|
-
/**
|
|
1711
|
-
* Creates a base object schema from the given JSON schema.
|
|
1712
|
-
*
|
|
1713
|
-
* @param {JSONSchema} schema - The JSON schema.
|
|
1714
|
-
* @returns {z.ZodObject<any, any>} - The base Zod object schema.
|
|
1715
|
-
*/
|
|
1716
|
-
static createBaseObjectSchema(schema) {
|
|
1717
|
-
const shape = {};
|
|
1718
|
-
const required = new Set(schema.required || []);
|
|
1719
|
-
for (const [key, value] of Object.entries(schema.properties || {})) {
|
|
1720
|
-
const zodSchema = this.parseSchema(value);
|
|
1721
|
-
shape[key] = required.has(key) ? zodSchema : zodSchema.optional();
|
|
1722
2105
|
}
|
|
1723
|
-
const zodObject = import_zod.z.object(shape);
|
|
1724
|
-
return this.processAdditionalProperties(schema, zodObject);
|
|
1725
2106
|
}
|
|
1726
2107
|
/**
|
|
1727
|
-
*
|
|
2108
|
+
* Validates property patterns for string properties.
|
|
1728
2109
|
*
|
|
1729
|
-
* @param {JSONValue} data - The
|
|
1730
|
-
* @param {JSONSchema} schema - The schema
|
|
1731
|
-
* @
|
|
2110
|
+
* @param {JSONValue} data - The data to validate.
|
|
2111
|
+
* @param {JSONSchema} schema - The schema containing property patterns.
|
|
2112
|
+
* @param {z.RefinementCtx} ctx - The Zod refinement context.
|
|
1732
2113
|
*/
|
|
1733
|
-
static
|
|
2114
|
+
static validatePropertyPatterns(data, schema, ctx) {
|
|
2115
|
+
if (!schema.properties) {
|
|
2116
|
+
return;
|
|
2117
|
+
}
|
|
1734
2118
|
if (typeof data !== "object" || data === null) {
|
|
1735
|
-
return
|
|
2119
|
+
return;
|
|
1736
2120
|
}
|
|
1737
2121
|
if (Array.isArray(data)) {
|
|
1738
|
-
return
|
|
2122
|
+
return;
|
|
1739
2123
|
}
|
|
1740
2124
|
const objectData = data;
|
|
1741
|
-
const dataWithDefaults = { ...objectData };
|
|
1742
|
-
if (!schema.properties) {
|
|
1743
|
-
return dataWithDefaults;
|
|
1744
|
-
}
|
|
1745
2125
|
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
1746
|
-
if (!(key in
|
|
1747
|
-
|
|
2126
|
+
if (!(key in objectData)) {
|
|
2127
|
+
continue;
|
|
2128
|
+
}
|
|
2129
|
+
const value = objectData[key];
|
|
2130
|
+
if (propSchema["pattern"] && typeof value === "string") {
|
|
2131
|
+
const regex = new RegExp(propSchema["pattern"]);
|
|
2132
|
+
if (!regex.test(value)) {
|
|
2133
|
+
ctx.addIssue({
|
|
2134
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
2135
|
+
message: `String '${value}' does not match pattern '${propSchema["pattern"]}'`,
|
|
2136
|
+
path: [key]
|
|
2137
|
+
});
|
|
2138
|
+
}
|
|
1748
2139
|
}
|
|
1749
2140
|
}
|
|
1750
|
-
return dataWithDefaults;
|
|
1751
2141
|
}
|
|
1752
2142
|
/**
|
|
1753
|
-
*
|
|
1754
|
-
* Delegates to the appropriate combinator parser based on which combinator is present.
|
|
2143
|
+
* Validates nested if-then-else conditions.
|
|
1755
2144
|
*
|
|
1756
|
-
* @param {
|
|
2145
|
+
* @param {JSONValue} data - The data to validate.
|
|
2146
|
+
* @param {JSONSchema} schema - The schema containing if-then-else conditions.
|
|
2147
|
+
* @param {z.RefinementCtx} ctx - The Zod refinement context.
|
|
2148
|
+
*/
|
|
2149
|
+
static validateNestedConditions(data, schema, ctx) {
|
|
2150
|
+
if (!schema["if"] || !schema["then"]) {
|
|
2151
|
+
return;
|
|
2152
|
+
}
|
|
2153
|
+
const matchesIf = this.matchesCondition(data, schema["if"]);
|
|
2154
|
+
if (matchesIf) {
|
|
2155
|
+
this.validateConditionalSchema(data, schema["then"], ctx);
|
|
2156
|
+
} else if (schema["else"]) {
|
|
2157
|
+
this.validateConditionalSchema(data, schema["else"], ctx);
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
/**
|
|
2161
|
+
* Parses a JSON schema and returns the corresponding Zod schema.
|
|
2162
|
+
* This is the main entry point for schema conversion.
|
|
2163
|
+
*
|
|
2164
|
+
* @param {JSONSchema} schema - The JSON schema.
|
|
1757
2165
|
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1758
2166
|
*/
|
|
1759
|
-
static
|
|
1760
|
-
if (schema.
|
|
1761
|
-
return this.
|
|
2167
|
+
static parseSchema(schema) {
|
|
2168
|
+
if (Array.isArray(schema.type)) {
|
|
2169
|
+
return this.handleTypeArray(schema);
|
|
1762
2170
|
}
|
|
1763
|
-
if (schema.anyOf) {
|
|
1764
|
-
return this.
|
|
2171
|
+
if (schema.oneOf || schema.anyOf || schema.allOf) {
|
|
2172
|
+
return this.parseCombinator(schema);
|
|
1765
2173
|
}
|
|
1766
|
-
if (schema
|
|
1767
|
-
return this.
|
|
2174
|
+
if (schema["if"] && schema["then"]) {
|
|
2175
|
+
return this.parseObject(schema);
|
|
1768
2176
|
}
|
|
1769
|
-
|
|
2177
|
+
if (schema.properties && (!schema.type || schema.type === "object")) {
|
|
2178
|
+
return this.parseObject(schema);
|
|
2179
|
+
}
|
|
2180
|
+
return this.handleSingleType(schema);
|
|
1770
2181
|
}
|
|
1771
2182
|
/**
|
|
1772
|
-
*
|
|
2183
|
+
* Handles schemas with an array of types.
|
|
1773
2184
|
*
|
|
1774
|
-
* @param {JSONSchema
|
|
2185
|
+
* @param {JSONSchema} schema - The JSON schema with type array.
|
|
1775
2186
|
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1776
2187
|
*/
|
|
1777
|
-
static
|
|
1778
|
-
|
|
2188
|
+
static handleTypeArray(schema) {
|
|
2189
|
+
if (!Array.isArray(schema.type)) {
|
|
2190
|
+
throw new Error("Expected schema.type to be an array");
|
|
2191
|
+
}
|
|
2192
|
+
if (schema.type.includes("null")) {
|
|
2193
|
+
return this.handleNullableType(schema);
|
|
2194
|
+
}
|
|
2195
|
+
return this.createUnionFromTypes(schema.type, schema);
|
|
1779
2196
|
}
|
|
1780
2197
|
/**
|
|
1781
|
-
*
|
|
2198
|
+
* Handles nullable types by creating a nullable schema.
|
|
1782
2199
|
*
|
|
1783
|
-
* @param {JSONSchema
|
|
1784
|
-
* @returns {ZodTypeAny} - The
|
|
2200
|
+
* @param {JSONSchema} schema - The JSON schema with nullable type.
|
|
2201
|
+
* @returns {ZodTypeAny} - The nullable Zod schema.
|
|
1785
2202
|
*/
|
|
1786
|
-
static
|
|
1787
|
-
|
|
2203
|
+
static handleNullableType(schema) {
|
|
2204
|
+
if (!Array.isArray(schema.type)) {
|
|
2205
|
+
throw new Error("Expected schema.type to be an array");
|
|
2206
|
+
}
|
|
2207
|
+
const nonNullSchema = { ...schema };
|
|
2208
|
+
nonNullSchema.type = schema.type.filter((t) => t !== "null");
|
|
2209
|
+
if (nonNullSchema.type.length === 1) {
|
|
2210
|
+
const singleTypeSchema = this.handleSingleType({
|
|
2211
|
+
...schema,
|
|
2212
|
+
type: nonNullSchema.type[0]
|
|
2213
|
+
});
|
|
2214
|
+
return singleTypeSchema.nullable();
|
|
2215
|
+
}
|
|
2216
|
+
const unionSchema = this.parseSchema(nonNullSchema);
|
|
2217
|
+
return unionSchema.nullable();
|
|
1788
2218
|
}
|
|
1789
2219
|
/**
|
|
1790
|
-
* Creates a union from an array of
|
|
2220
|
+
* Creates a union type from an array of types.
|
|
1791
2221
|
*
|
|
1792
|
-
* @param {
|
|
2222
|
+
* @param {string[]} types - Array of type strings.
|
|
2223
|
+
* @param {JSONSchema} baseSchema - The base schema to apply to each type.
|
|
1793
2224
|
* @returns {ZodTypeAny} - The union Zod schema.
|
|
1794
2225
|
*/
|
|
1795
|
-
static
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
}
|
|
1802
|
-
const zodSchemas = [];
|
|
1803
|
-
for (const subSchema of schemas) {
|
|
1804
|
-
if (subSchema.type === "null") {
|
|
1805
|
-
zodSchemas.push(import_zod.z.null());
|
|
1806
|
-
} else {
|
|
1807
|
-
zodSchemas.push(this.parseSchema(subSchema));
|
|
1808
|
-
}
|
|
1809
|
-
}
|
|
1810
|
-
if (zodSchemas.length >= 2) {
|
|
1811
|
-
return import_zod.z.union(zodSchemas);
|
|
1812
|
-
} else if (zodSchemas.length === 1) {
|
|
1813
|
-
return zodSchemas[0];
|
|
1814
|
-
}
|
|
1815
|
-
return import_zod.z.any();
|
|
2226
|
+
static createUnionFromTypes(types, baseSchema) {
|
|
2227
|
+
const schemas = types.map((type) => {
|
|
2228
|
+
const singleTypeSchema = { ...baseSchema, type };
|
|
2229
|
+
return this.parseSchema(singleTypeSchema);
|
|
2230
|
+
});
|
|
2231
|
+
return import_zod.z.union(schemas);
|
|
1816
2232
|
}
|
|
1817
2233
|
/**
|
|
1818
|
-
*
|
|
2234
|
+
* Handles schemas with a single type.
|
|
1819
2235
|
*
|
|
1820
|
-
* @param {JSONSchema
|
|
2236
|
+
* @param {JSONSchema} schema - The JSON schema with single type.
|
|
1821
2237
|
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1822
2238
|
*/
|
|
1823
|
-
static
|
|
1824
|
-
if (
|
|
2239
|
+
static handleSingleType(schema) {
|
|
2240
|
+
if (schema.type === void 0) {
|
|
2241
|
+
if (schema.oneOf || schema.anyOf || schema.allOf) {
|
|
2242
|
+
return this.parseCombinator(schema);
|
|
2243
|
+
}
|
|
2244
|
+
if (schema.properties) {
|
|
2245
|
+
return this.parseObject(schema);
|
|
2246
|
+
}
|
|
1825
2247
|
return import_zod.z.any();
|
|
1826
2248
|
}
|
|
1827
|
-
|
|
1828
|
-
|
|
2249
|
+
switch (schema.type) {
|
|
2250
|
+
case "string":
|
|
2251
|
+
return this.parseString(schema);
|
|
2252
|
+
case "number":
|
|
2253
|
+
case "integer":
|
|
2254
|
+
return this.parseNumberSchema(schema);
|
|
2255
|
+
case "boolean":
|
|
2256
|
+
return import_zod.z.boolean();
|
|
2257
|
+
case "array":
|
|
2258
|
+
return this.parseArray(schema);
|
|
2259
|
+
case "object":
|
|
2260
|
+
return this.parseObject(schema);
|
|
2261
|
+
default:
|
|
2262
|
+
throw new Error("Unsupported schema type");
|
|
1829
2263
|
}
|
|
1830
|
-
const mergedSchema = schemas.reduce(
|
|
1831
|
-
(acc, currentSchema) => this.mergeSchemas(acc, currentSchema)
|
|
1832
|
-
);
|
|
1833
|
-
return this.parseSchema(mergedSchema);
|
|
1834
2264
|
}
|
|
1835
2265
|
/**
|
|
1836
|
-
*
|
|
2266
|
+
* Parses a number schema.
|
|
1837
2267
|
*
|
|
1838
|
-
* @param {JSONSchema}
|
|
1839
|
-
* @
|
|
1840
|
-
* @returns {JSONSchema} - The merged JSON schema
|
|
2268
|
+
* @param {JSONSchema} schema - The JSON schema for a number.
|
|
2269
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1841
2270
|
*/
|
|
1842
|
-
static
|
|
1843
|
-
const
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
}
|
|
1851
|
-
if (baseSchema.required && addSchema.required) {
|
|
1852
|
-
const mergedRequired = [
|
|
1853
|
-
.../* @__PURE__ */ new Set([...baseSchema.required, ...addSchema.required])
|
|
1854
|
-
];
|
|
1855
|
-
merged.required = mergedRequired;
|
|
1856
|
-
}
|
|
1857
|
-
return merged;
|
|
1858
|
-
}
|
|
1859
|
-
};
|
|
1860
|
-
|
|
1861
|
-
// src/adapters/langchain_adapter.ts
|
|
1862
|
-
var import_tools = require("@langchain/core/tools");
|
|
1863
|
-
var import_zod2 = require("zod");
|
|
1864
|
-
init_logging();
|
|
1865
|
-
|
|
1866
|
-
// src/adapters/base.ts
|
|
1867
|
-
init_logging();
|
|
1868
|
-
var BaseAdapter = class {
|
|
1869
|
-
static {
|
|
1870
|
-
__name(this, "BaseAdapter");
|
|
2271
|
+
static parseNumberSchema(schema) {
|
|
2272
|
+
const numberSchema = import_zod.z.number();
|
|
2273
|
+
let result = numberSchema;
|
|
2274
|
+
result = this.applyNumberBounds(numberSchema, schema);
|
|
2275
|
+
result = this.applyNumberMultipleOf(numberSchema, schema);
|
|
2276
|
+
result = this.applyNumberEnum(numberSchema, schema);
|
|
2277
|
+
result = this.applyIntegerConstraint(numberSchema, schema);
|
|
2278
|
+
return result;
|
|
1871
2279
|
}
|
|
1872
2280
|
/**
|
|
1873
|
-
*
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
*
|
|
1878
|
-
* generated for it.
|
|
2281
|
+
* Applies bounds validation to a number schema.
|
|
2282
|
+
*
|
|
2283
|
+
* @param {z.ZodNumber} numberSchema - The base number schema.
|
|
2284
|
+
* @param {JSONSchema} schema - The JSON schema with bounds.
|
|
2285
|
+
* @returns {z.ZodNumber} - The updated schema with bounds validation.
|
|
1879
2286
|
*/
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
2287
|
+
static applyNumberBounds(numberSchema, schema) {
|
|
2288
|
+
let result = numberSchema;
|
|
2289
|
+
if (schema["minimum"] !== void 0) {
|
|
2290
|
+
result = schema["exclusiveMinimum"] ? result.gt(schema["minimum"]) : result.gte(schema["minimum"]);
|
|
2291
|
+
}
|
|
2292
|
+
if (schema["maximum"] !== void 0) {
|
|
2293
|
+
result = schema["exclusiveMaximum"] ? result.lt(schema["maximum"]) : result.lte(schema["maximum"]);
|
|
2294
|
+
}
|
|
2295
|
+
return result;
|
|
1883
2296
|
}
|
|
1884
2297
|
/**
|
|
1885
|
-
*
|
|
1886
|
-
*
|
|
1887
|
-
* This is the recommended way to create tools from an MCPClient, as it handles
|
|
1888
|
-
* session creation and connector extraction automatically.
|
|
2298
|
+
* Applies multipleOf validation to a number schema.
|
|
1889
2299
|
*
|
|
1890
|
-
* @param
|
|
1891
|
-
* @param
|
|
1892
|
-
* @returns
|
|
2300
|
+
* @param {z.ZodNumber} numberSchema - The base number schema.
|
|
2301
|
+
* @param {JSONSchema} schema - The JSON schema with multipleOf.
|
|
2302
|
+
* @returns {z.ZodNumber} - The updated schema with multipleOf validation.
|
|
1893
2303
|
*/
|
|
1894
|
-
static
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
logger.info("No active sessions found, creating new ones...");
|
|
1898
|
-
await client.createAllSessions();
|
|
2304
|
+
static applyNumberMultipleOf(numberSchema, schema) {
|
|
2305
|
+
if (schema["multipleOf"] === void 0) {
|
|
2306
|
+
return numberSchema;
|
|
1899
2307
|
}
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
);
|
|
1904
|
-
return adapter.createToolsFromConnectors(connectors);
|
|
2308
|
+
return numberSchema.refine((val) => val % schema["multipleOf"] === 0, {
|
|
2309
|
+
message: `Number must be a multiple of ${schema["multipleOf"]}`
|
|
2310
|
+
});
|
|
1905
2311
|
}
|
|
1906
2312
|
/**
|
|
1907
|
-
*
|
|
2313
|
+
* Applies enum validation to a number schema.
|
|
1908
2314
|
*
|
|
1909
|
-
* @param
|
|
1910
|
-
* @
|
|
2315
|
+
* @param {z.ZodNumber} numberSchema - The base number schema.
|
|
2316
|
+
* @param {JSONSchema} schema - The JSON schema with enum.
|
|
2317
|
+
* @returns {z.ZodNumber} - The updated schema with enum validation.
|
|
1911
2318
|
*/
|
|
1912
|
-
|
|
1913
|
-
if (
|
|
1914
|
-
|
|
1915
|
-
logger.debug(`Returning ${cached.length} existing tools for connector`);
|
|
1916
|
-
return cached;
|
|
1917
|
-
}
|
|
1918
|
-
const connectorTools = [];
|
|
1919
|
-
const success = await this.ensureConnectorInitialized(connector);
|
|
1920
|
-
if (!success) {
|
|
1921
|
-
return [];
|
|
1922
|
-
}
|
|
1923
|
-
for (const tool of connector.tools) {
|
|
1924
|
-
const converted = this.convertTool(tool, connector);
|
|
1925
|
-
if (converted) {
|
|
1926
|
-
connectorTools.push(converted);
|
|
1927
|
-
}
|
|
2319
|
+
static applyNumberEnum(numberSchema, schema) {
|
|
2320
|
+
if (!schema.enum) {
|
|
2321
|
+
return numberSchema;
|
|
1928
2322
|
}
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
`Loaded ${connectorTools.length} new tools for connector: ${connectorTools.map((t) => t?.name ?? String(t)).join(", ")}`
|
|
2323
|
+
const numberEnums = schema.enum.filter(
|
|
2324
|
+
(val) => typeof val === "number"
|
|
1932
2325
|
);
|
|
1933
|
-
|
|
2326
|
+
if (numberEnums.length === 0) {
|
|
2327
|
+
return numberSchema;
|
|
2328
|
+
}
|
|
2329
|
+
return numberSchema.refine((val) => numberEnums.includes(val), {
|
|
2330
|
+
message: `Number must be one of: ${numberEnums.join(", ")}`
|
|
2331
|
+
});
|
|
1934
2332
|
}
|
|
1935
2333
|
/**
|
|
1936
|
-
*
|
|
2334
|
+
* Applies integer constraint to a number schema if needed.
|
|
1937
2335
|
*
|
|
1938
|
-
* @param
|
|
1939
|
-
* @
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
tools.push(...connectorTools);
|
|
2336
|
+
* @param {z.ZodNumber} numberSchema - The base number schema.
|
|
2337
|
+
* @param {JSONSchema} schema - The JSON schema.
|
|
2338
|
+
* @returns {z.ZodNumber} - The updated schema with integer validation if needed.
|
|
2339
|
+
*/
|
|
2340
|
+
static applyIntegerConstraint(numberSchema, schema) {
|
|
2341
|
+
if (schema.type !== "integer") {
|
|
2342
|
+
return numberSchema;
|
|
1946
2343
|
}
|
|
1947
|
-
|
|
1948
|
-
|
|
2344
|
+
return numberSchema.refine((val) => Number.isInteger(val), {
|
|
2345
|
+
message: "Number must be an integer"
|
|
2346
|
+
});
|
|
1949
2347
|
}
|
|
1950
2348
|
/**
|
|
1951
|
-
*
|
|
2349
|
+
* Parses a string schema.
|
|
1952
2350
|
*
|
|
1953
|
-
* @param
|
|
1954
|
-
* @returns
|
|
2351
|
+
* @param {JSONSchema} schema - The JSON schema for a string.
|
|
2352
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
1955
2353
|
*/
|
|
1956
|
-
|
|
1957
|
-
|
|
2354
|
+
static parseString(schema) {
|
|
2355
|
+
const stringSchema = import_zod.z.string();
|
|
2356
|
+
let result = stringSchema;
|
|
2357
|
+
if (schema.format) {
|
|
2358
|
+
return this.applyStringFormat(stringSchema, schema);
|
|
2359
|
+
} else {
|
|
2360
|
+
result = this.applyStringPattern(stringSchema, schema);
|
|
2361
|
+
result = this.applyStringLength(stringSchema, schema);
|
|
2362
|
+
result = this.applyStringEnum(stringSchema, schema);
|
|
2363
|
+
}
|
|
2364
|
+
return result;
|
|
1958
2365
|
}
|
|
1959
2366
|
/**
|
|
1960
|
-
*
|
|
2367
|
+
* Applies format validation to a string schema.
|
|
1961
2368
|
*
|
|
1962
|
-
* @param
|
|
1963
|
-
* @
|
|
2369
|
+
* @param {z.ZodString} stringSchema - The base string schema.
|
|
2370
|
+
* @param {JSONSchema} schema - The JSON schema with format.
|
|
2371
|
+
* @returns {ZodTypeAny} - The updated schema with format validation.
|
|
1964
2372
|
*/
|
|
1965
|
-
|
|
1966
|
-
if (!
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
return
|
|
1974
|
-
|
|
2373
|
+
static applyStringFormat(stringSchema, schema) {
|
|
2374
|
+
if (!schema.format) {
|
|
2375
|
+
return stringSchema;
|
|
2376
|
+
}
|
|
2377
|
+
switch (schema.format) {
|
|
2378
|
+
case "email":
|
|
2379
|
+
return stringSchema.email();
|
|
2380
|
+
case "date-time":
|
|
2381
|
+
return stringSchema.datetime();
|
|
2382
|
+
case "uri":
|
|
2383
|
+
return stringSchema.url();
|
|
2384
|
+
case "uuid":
|
|
2385
|
+
return stringSchema.uuid();
|
|
2386
|
+
case "date":
|
|
2387
|
+
return stringSchema.date();
|
|
2388
|
+
default:
|
|
2389
|
+
return stringSchema;
|
|
1975
2390
|
}
|
|
1976
|
-
return true;
|
|
1977
|
-
}
|
|
1978
|
-
};
|
|
1979
|
-
|
|
1980
|
-
// src/adapters/langchain_adapter.ts
|
|
1981
|
-
function schemaToZod(schema) {
|
|
1982
|
-
try {
|
|
1983
|
-
return JSONSchemaToZod.convert(schema);
|
|
1984
|
-
} catch (err) {
|
|
1985
|
-
logger.warn(`Failed to convert JSON schema to Zod: ${err}`);
|
|
1986
|
-
return import_zod2.z.any();
|
|
1987
|
-
}
|
|
1988
|
-
}
|
|
1989
|
-
__name(schemaToZod, "schemaToZod");
|
|
1990
|
-
var LangChainAdapter = class extends BaseAdapter {
|
|
1991
|
-
static {
|
|
1992
|
-
__name(this, "LangChainAdapter");
|
|
1993
|
-
}
|
|
1994
|
-
constructor(disallowedTools = []) {
|
|
1995
|
-
super(disallowedTools);
|
|
1996
2391
|
}
|
|
1997
2392
|
/**
|
|
1998
|
-
*
|
|
2393
|
+
* Applies pattern validation to a string schema.
|
|
2394
|
+
*
|
|
2395
|
+
* @param {z.ZodString} stringSchema - The base string schema.
|
|
2396
|
+
* @param {JSONSchema} schema - The JSON schema with pattern.
|
|
2397
|
+
* @returns {z.ZodString} - The updated schema with pattern validation.
|
|
1999
2398
|
*/
|
|
2000
|
-
|
|
2001
|
-
if (
|
|
2002
|
-
return
|
|
2399
|
+
static applyStringPattern(stringSchema, schema) {
|
|
2400
|
+
if (!schema["pattern"]) {
|
|
2401
|
+
return stringSchema;
|
|
2003
2402
|
}
|
|
2004
|
-
const
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
description: mcpTool.description ?? "",
|
|
2008
|
-
// Blank is acceptable but discouraged.
|
|
2009
|
-
schema: argsSchema,
|
|
2010
|
-
func: /* @__PURE__ */ __name(async (input) => {
|
|
2011
|
-
logger.debug(
|
|
2012
|
-
`MCP tool "${mcpTool.name}" received input: ${JSON.stringify(input)}`
|
|
2013
|
-
);
|
|
2014
|
-
try {
|
|
2015
|
-
const result = await connector.callTool(
|
|
2016
|
-
mcpTool.name,
|
|
2017
|
-
input
|
|
2018
|
-
);
|
|
2019
|
-
return JSON.stringify(result);
|
|
2020
|
-
} catch (err) {
|
|
2021
|
-
logger.error(`Error executing MCP tool: ${err.message}`);
|
|
2022
|
-
return `Error executing MCP tool: ${String(err)}`;
|
|
2023
|
-
}
|
|
2024
|
-
}, "func")
|
|
2403
|
+
const regex = new RegExp(schema["pattern"]);
|
|
2404
|
+
return stringSchema.regex(regex, {
|
|
2405
|
+
message: `String must match pattern: ${schema["pattern"]}`
|
|
2025
2406
|
});
|
|
2026
|
-
return tool;
|
|
2027
|
-
}
|
|
2028
|
-
};
|
|
2029
|
-
|
|
2030
|
-
// src/agents/mcp_agent.ts
|
|
2031
|
-
init_logging();
|
|
2032
|
-
|
|
2033
|
-
// src/managers/server_manager.ts
|
|
2034
|
-
init_logging();
|
|
2035
|
-
|
|
2036
|
-
// src/managers/tools/acquire_active_mcp_server.ts
|
|
2037
|
-
var import_zod3 = require("zod");
|
|
2038
|
-
|
|
2039
|
-
// src/managers/tools/base.ts
|
|
2040
|
-
var import_tools2 = require("@langchain/core/tools");
|
|
2041
|
-
var MCPServerTool = class extends import_tools2.StructuredTool {
|
|
2042
|
-
static {
|
|
2043
|
-
__name(this, "MCPServerTool");
|
|
2044
|
-
}
|
|
2045
|
-
name = "mcp_server_tool";
|
|
2046
|
-
description = "Base tool for MCP server operations.";
|
|
2047
|
-
schema;
|
|
2048
|
-
_manager;
|
|
2049
|
-
constructor(manager) {
|
|
2050
|
-
super();
|
|
2051
|
-
this._manager = manager;
|
|
2052
|
-
}
|
|
2053
|
-
async _call(_arg, _runManager, _parentConfig) {
|
|
2054
|
-
throw new Error("Method not implemented.");
|
|
2055
|
-
}
|
|
2056
|
-
get manager() {
|
|
2057
|
-
return this._manager;
|
|
2058
|
-
}
|
|
2059
|
-
};
|
|
2060
|
-
|
|
2061
|
-
// src/managers/tools/acquire_active_mcp_server.ts
|
|
2062
|
-
var PresentActiveServerSchema = import_zod3.z.object({});
|
|
2063
|
-
var AcquireActiveMCPServerTool = class extends MCPServerTool {
|
|
2064
|
-
static {
|
|
2065
|
-
__name(this, "AcquireActiveMCPServerTool");
|
|
2066
|
-
}
|
|
2067
|
-
name = "get_active_mcp_server";
|
|
2068
|
-
description = "Get the currently active MCP (Model Context Protocol) server";
|
|
2069
|
-
schema = PresentActiveServerSchema;
|
|
2070
|
-
constructor(manager) {
|
|
2071
|
-
super(manager);
|
|
2072
2407
|
}
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2408
|
+
/**
|
|
2409
|
+
* Applies length constraints to a string schema.
|
|
2410
|
+
*
|
|
2411
|
+
* @param {z.ZodString} stringSchema - The base string schema.
|
|
2412
|
+
* @param {JSONSchema} schema - The JSON schema with length constraints.
|
|
2413
|
+
* @returns {z.ZodString} - The updated schema with length validation.
|
|
2414
|
+
*/
|
|
2415
|
+
static applyStringLength(stringSchema, schema) {
|
|
2416
|
+
const result = stringSchema;
|
|
2417
|
+
if (schema["minLength"] !== void 0) {
|
|
2418
|
+
stringSchema = stringSchema.min(schema["minLength"]);
|
|
2076
2419
|
}
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
};
|
|
2080
|
-
|
|
2081
|
-
// src/managers/tools/add_server_from_config.ts
|
|
2082
|
-
var import_tools3 = require("@langchain/core/tools");
|
|
2083
|
-
var import_zod4 = require("zod");
|
|
2084
|
-
init_logging();
|
|
2085
|
-
var AddMCPServerFromConfigTool = class extends import_tools3.StructuredTool {
|
|
2086
|
-
static {
|
|
2087
|
-
__name(this, "AddMCPServerFromConfigTool");
|
|
2088
|
-
}
|
|
2089
|
-
name = "add_mcp_server_from_config";
|
|
2090
|
-
description = "Adds a new MCP server to the client from a configuration object and connects to it, making its tools available.";
|
|
2091
|
-
schema = import_zod4.z.object({
|
|
2092
|
-
serverName: import_zod4.z.string().describe("The name for the new MCP server."),
|
|
2093
|
-
serverConfig: import_zod4.z.any().describe(
|
|
2094
|
-
'The configuration object for the server. This should not include the top-level "mcpServers" key.'
|
|
2095
|
-
)
|
|
2096
|
-
});
|
|
2097
|
-
manager;
|
|
2098
|
-
constructor(manager) {
|
|
2099
|
-
super();
|
|
2100
|
-
this.manager = manager;
|
|
2101
|
-
}
|
|
2102
|
-
async _call({
|
|
2103
|
-
serverName,
|
|
2104
|
-
serverConfig
|
|
2105
|
-
}) {
|
|
2106
|
-
try {
|
|
2107
|
-
this.manager.client.addServer(serverName, serverConfig);
|
|
2108
|
-
let result = `Server '${serverName}' added to the client.`;
|
|
2109
|
-
logger.debug(
|
|
2110
|
-
`Connecting to new server '${serverName}' and discovering tools.`
|
|
2111
|
-
);
|
|
2112
|
-
const session = await this.manager.client.createSession(serverName);
|
|
2113
|
-
const connector = session.connector;
|
|
2114
|
-
const tools = await this.manager.adapter.createToolsFromConnectors([connector]);
|
|
2115
|
-
this.manager.serverTools[serverName] = tools;
|
|
2116
|
-
this.manager.initializedServers[serverName] = true;
|
|
2117
|
-
this.manager.activeServer = serverName;
|
|
2118
|
-
const numTools = tools.length;
|
|
2119
|
-
result += ` Session created and connected. '${serverName}' is now the active server with ${numTools} tools available.`;
|
|
2120
|
-
result += `
|
|
2121
|
-
|
|
2122
|
-
${tools.map((t) => t.name).join("\n")}`;
|
|
2123
|
-
logger.info(result);
|
|
2124
|
-
return result;
|
|
2125
|
-
} catch (e) {
|
|
2126
|
-
logger.error(
|
|
2127
|
-
`Failed to add or connect to server '${serverName}': ${e.message}`
|
|
2128
|
-
);
|
|
2129
|
-
return `Failed to add or connect to server '${serverName}': ${e.message}`;
|
|
2420
|
+
if (schema["maxLength"] !== void 0) {
|
|
2421
|
+
stringSchema = stringSchema.max(schema["maxLength"]);
|
|
2130
2422
|
}
|
|
2423
|
+
return result;
|
|
2131
2424
|
}
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2425
|
+
/**
|
|
2426
|
+
* Applies enum validation to a string schema.
|
|
2427
|
+
*
|
|
2428
|
+
* @param {z.ZodString} stringSchema - The base string schema.
|
|
2429
|
+
* @param {JSONSchema} schema - The JSON schema with enum.
|
|
2430
|
+
* @returns {ZodTypeAny} - The updated schema with enum validation.
|
|
2431
|
+
*/
|
|
2432
|
+
static applyStringEnum(stringSchema, schema) {
|
|
2433
|
+
if (!schema.enum) {
|
|
2434
|
+
return stringSchema;
|
|
2435
|
+
}
|
|
2436
|
+
return stringSchema.refine((val) => schema.enum?.includes(val), {
|
|
2437
|
+
message: `Value must be one of: ${schema.enum?.join(", ")}`
|
|
2438
|
+
});
|
|
2143
2439
|
}
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2440
|
+
/**
|
|
2441
|
+
* Parses a JSON schema of type array and returns the corresponding Zod schema.
|
|
2442
|
+
*
|
|
2443
|
+
* @param {JSONSchema} schema - The JSON schema.
|
|
2444
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
2445
|
+
*/
|
|
2446
|
+
static parseArray(schema) {
|
|
2447
|
+
if (Array.isArray(schema.items)) {
|
|
2448
|
+
const tupleSchemas = schema.items.map((item) => this.parseSchema(item));
|
|
2449
|
+
return import_zod.z.union(tupleSchemas);
|
|
2450
|
+
}
|
|
2451
|
+
const itemSchema = schema.items ? this.parseSchema(schema.items) : import_zod.z.any();
|
|
2452
|
+
const arraySchema = import_zod.z.array(itemSchema);
|
|
2453
|
+
let result = arraySchema;
|
|
2454
|
+
result = this.applyArrayConstraints(arraySchema, schema);
|
|
2455
|
+
return result;
|
|
2149
2456
|
}
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2457
|
+
/**
|
|
2458
|
+
* Applies constraints to an array schema.
|
|
2459
|
+
*
|
|
2460
|
+
* @param {z.ZodArray<any>} arraySchema - The base array schema.
|
|
2461
|
+
* @param {JSONSchema} schema - The JSON schema with array constraints.
|
|
2462
|
+
* @returns {z.ZodTypeAny} - The updated array schema with constraints.
|
|
2463
|
+
*/
|
|
2464
|
+
static applyArrayConstraints(arraySchema, schema) {
|
|
2465
|
+
if (schema["minItems"] !== void 0) {
|
|
2466
|
+
arraySchema = arraySchema.min(schema["minItems"]);
|
|
2155
2467
|
}
|
|
2156
|
-
if (
|
|
2157
|
-
|
|
2468
|
+
if (schema["maxItems"] !== void 0) {
|
|
2469
|
+
arraySchema = arraySchema.max(schema["maxItems"]);
|
|
2158
2470
|
}
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
logger.debug(`Creating new session for server '${serverName}'`);
|
|
2164
|
-
session = await this.manager.client.createSession(serverName);
|
|
2165
|
-
}
|
|
2166
|
-
this.manager.activeServer = serverName;
|
|
2167
|
-
if (this.manager.serverTools[serverName]) {
|
|
2168
|
-
const connector = session.connector;
|
|
2169
|
-
const tools = await this.manager.adapter.createToolsFromConnectors([connector]);
|
|
2170
|
-
this.manager.serverTools[serverName] = tools;
|
|
2171
|
-
this.manager.initializedServers[serverName] = true;
|
|
2172
|
-
}
|
|
2173
|
-
const serverTools = this.manager.serverTools[serverName] || [];
|
|
2174
|
-
const numTools = serverTools.length;
|
|
2175
|
-
return `Connected to MCP server '${serverName}'. ${numTools} tools are now available.`;
|
|
2176
|
-
} catch (error) {
|
|
2177
|
-
logger.error(
|
|
2178
|
-
`Error connecting to server '${serverName}': ${String(error)}`
|
|
2471
|
+
if (schema["uniqueItems"]) {
|
|
2472
|
+
return arraySchema.refine(
|
|
2473
|
+
(items) => new Set(items).size === items.length,
|
|
2474
|
+
{ message: "Array items must be unique" }
|
|
2179
2475
|
);
|
|
2180
|
-
return `Failed to connect to server '${serverName}': ${String(error)}`;
|
|
2181
2476
|
}
|
|
2477
|
+
return arraySchema;
|
|
2182
2478
|
}
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
constructor(manager) {
|
|
2197
|
-
super(manager);
|
|
2479
|
+
/**
|
|
2480
|
+
* Parses an object schema.
|
|
2481
|
+
*
|
|
2482
|
+
* @param {JSONSchema} schema - The JSON schema for an object.
|
|
2483
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
2484
|
+
*/
|
|
2485
|
+
static parseObject(schema) {
|
|
2486
|
+
if (schema["if"] && schema["then"]) {
|
|
2487
|
+
return this.parseConditional(schema);
|
|
2488
|
+
}
|
|
2489
|
+
const shape = {};
|
|
2490
|
+
this.processObjectProperties(schema, shape);
|
|
2491
|
+
return this.processAdditionalProperties(schema, import_zod.z.object(shape));
|
|
2198
2492
|
}
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2493
|
+
/**
|
|
2494
|
+
* Processes object properties and builds the shape object.
|
|
2495
|
+
*
|
|
2496
|
+
* @param {JSONSchema} schema - The JSON schema for an object.
|
|
2497
|
+
* @param {Record<string, ZodTypeAny>} shape - The shape object to populate.
|
|
2498
|
+
*/
|
|
2499
|
+
static processObjectProperties(schema, shape) {
|
|
2500
|
+
const required = new Set(schema.required || []);
|
|
2501
|
+
if (!schema.properties) {
|
|
2502
|
+
return;
|
|
2203
2503
|
}
|
|
2204
|
-
const
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
const activeFlag = isActiveServer ? " (ACTIVE)" : "";
|
|
2208
|
-
outputLines.push(`- ${serverName}${activeFlag}`);
|
|
2209
|
-
try {
|
|
2210
|
-
const serverTools = this.manager.serverTools?.[serverName] ?? [];
|
|
2211
|
-
const numberOfTools = Array.isArray(serverTools) ? serverTools.length : 0;
|
|
2212
|
-
outputLines.push(`${numberOfTools} tools available for this server
|
|
2213
|
-
`);
|
|
2214
|
-
} catch (error) {
|
|
2215
|
-
logger.error(
|
|
2216
|
-
`Unexpected error listing tools for server '${serverName}': ${String(error)}`
|
|
2217
|
-
);
|
|
2218
|
-
}
|
|
2504
|
+
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
2505
|
+
const zodSchema = this.parseSchema(propSchema);
|
|
2506
|
+
shape[key] = required.has(key) ? zodSchema : zodSchema.optional();
|
|
2219
2507
|
}
|
|
2220
|
-
return outputLines.join("\n");
|
|
2221
|
-
}
|
|
2222
|
-
};
|
|
2223
|
-
|
|
2224
|
-
// src/managers/tools/release_mcp_server_connection.ts
|
|
2225
|
-
var import_zod7 = require("zod");
|
|
2226
|
-
var ReleaseConnectionSchema = import_zod7.z.object({});
|
|
2227
|
-
var ReleaseMCPServerConnectionTool = class extends MCPServerTool {
|
|
2228
|
-
static {
|
|
2229
|
-
__name(this, "ReleaseMCPServerConnectionTool");
|
|
2230
|
-
}
|
|
2231
|
-
name = "disconnect_from_mcp_server";
|
|
2232
|
-
description = "Disconnect from the currently active MCP (Model Context Protocol) server";
|
|
2233
|
-
schema = ReleaseConnectionSchema;
|
|
2234
|
-
constructor(manager) {
|
|
2235
|
-
super(manager);
|
|
2236
2508
|
}
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2509
|
+
/**
|
|
2510
|
+
* Processes additionalProperties configuration.
|
|
2511
|
+
*
|
|
2512
|
+
* @param {JSONSchema} schema - The JSON schema for an object.
|
|
2513
|
+
* @param {z.ZodObject<any, any>} objectSchema - The Zod object schema.
|
|
2514
|
+
* @returns {z.ZodObject<any, any>} - The updated Zod object schema.
|
|
2515
|
+
*/
|
|
2516
|
+
static processAdditionalProperties(schema, objectSchema) {
|
|
2517
|
+
if (schema.additionalProperties === true) {
|
|
2518
|
+
return objectSchema.passthrough();
|
|
2519
|
+
} else if (schema.additionalProperties && typeof schema.additionalProperties === "object") {
|
|
2520
|
+
const additionalPropSchema = this.parseSchema(
|
|
2521
|
+
schema.additionalProperties
|
|
2522
|
+
);
|
|
2523
|
+
return objectSchema.catchall(additionalPropSchema);
|
|
2524
|
+
} else {
|
|
2525
|
+
return objectSchema.strict();
|
|
2240
2526
|
}
|
|
2241
|
-
const serverName = this.manager.activeServer;
|
|
2242
|
-
this.manager.activeServer = null;
|
|
2243
|
-
return `Successfully disconnected from MCP server '${serverName}'.`;
|
|
2244
|
-
}
|
|
2245
|
-
};
|
|
2246
|
-
|
|
2247
|
-
// src/managers/server_manager.ts
|
|
2248
|
-
function isEqual(a, b) {
|
|
2249
|
-
if (a === b) return true;
|
|
2250
|
-
if (a == null || b == null) return false;
|
|
2251
|
-
if (typeof a !== typeof b) return false;
|
|
2252
|
-
if (a instanceof Date && b instanceof Date) {
|
|
2253
|
-
return a.getTime() === b.getTime();
|
|
2254
|
-
}
|
|
2255
|
-
if (Array.isArray(a) && Array.isArray(b)) {
|
|
2256
|
-
if (a.length !== b.length) return false;
|
|
2257
|
-
return a.every((item, index) => isEqual(item, b[index]));
|
|
2258
2527
|
}
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2528
|
+
/**
|
|
2529
|
+
* Parses a conditional schema with if-then-else.
|
|
2530
|
+
*
|
|
2531
|
+
* @param {JSONSchema} schema - The JSON schema with conditional validation.
|
|
2532
|
+
* @returns {ZodTypeAny} - The conditional Zod schema.
|
|
2533
|
+
*/
|
|
2534
|
+
static parseConditional(schema) {
|
|
2535
|
+
const zodObject = this.createBaseObjectSchema(schema);
|
|
2536
|
+
const ifCondition = schema["if"];
|
|
2537
|
+
const thenSchema = schema["then"];
|
|
2538
|
+
const elseSchema = schema["else"];
|
|
2539
|
+
return zodObject.superRefine((data, ctx) => {
|
|
2540
|
+
const dataWithDefaults = this.applyDefaultValues(
|
|
2541
|
+
data,
|
|
2542
|
+
schema
|
|
2543
|
+
);
|
|
2544
|
+
if (this.matchesCondition(dataWithDefaults, ifCondition)) {
|
|
2545
|
+
this.validateConditionalSchema(dataWithDefaults, thenSchema, ctx);
|
|
2546
|
+
} else if (elseSchema) {
|
|
2547
|
+
this.validateConditionalSchema(dataWithDefaults, elseSchema, ctx);
|
|
2548
|
+
}
|
|
2265
2549
|
});
|
|
2266
2550
|
}
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
overrideManagementTools;
|
|
2280
|
-
constructor(client, adapter, managementTools) {
|
|
2281
|
-
this.client = client;
|
|
2282
|
-
this.adapter = adapter;
|
|
2283
|
-
this.overrideManagementTools = managementTools;
|
|
2284
|
-
}
|
|
2285
|
-
setManagementTools(tools) {
|
|
2286
|
-
this.overrideManagementTools = tools;
|
|
2287
|
-
logger.info(
|
|
2288
|
-
`Overriding default management tools with a new set of ${tools.length} tools.`
|
|
2289
|
-
);
|
|
2290
|
-
}
|
|
2291
|
-
logState(context) {
|
|
2292
|
-
const allServerNames = this.client.getServerNames();
|
|
2293
|
-
const activeSessionNames = Object.keys(this.client.getAllActiveSessions());
|
|
2294
|
-
if (allServerNames.length === 0) {
|
|
2295
|
-
logger.info("Server Manager State: No servers configured.");
|
|
2296
|
-
return;
|
|
2297
|
-
}
|
|
2298
|
-
const tableData = allServerNames.map((name) => ({
|
|
2299
|
-
"Server Name": name,
|
|
2300
|
-
Connected: activeSessionNames.includes(name) ? "\u2705" : "\u274C",
|
|
2301
|
-
Initialized: this.initializedServers[name] ? "\u2705" : "\u274C",
|
|
2302
|
-
"Tool Count": this.serverTools[name]?.length ?? 0,
|
|
2303
|
-
Active: this.activeServer === name ? "\u2705" : "\u274C"
|
|
2304
|
-
}));
|
|
2305
|
-
logger.info(`Server Manager State: [${context}]`);
|
|
2306
|
-
console.table(tableData);
|
|
2307
|
-
}
|
|
2308
|
-
initialize() {
|
|
2309
|
-
const serverNames = this.client.getServerNames?.();
|
|
2310
|
-
if (serverNames.length === 0) {
|
|
2311
|
-
logger.warn("No MCP servers defined in client configuration");
|
|
2551
|
+
/**
|
|
2552
|
+
* Creates a base object schema from the given JSON schema.
|
|
2553
|
+
*
|
|
2554
|
+
* @param {JSONSchema} schema - The JSON schema.
|
|
2555
|
+
* @returns {z.ZodObject<any, any>} - The base Zod object schema.
|
|
2556
|
+
*/
|
|
2557
|
+
static createBaseObjectSchema(schema) {
|
|
2558
|
+
const shape = {};
|
|
2559
|
+
const required = new Set(schema.required || []);
|
|
2560
|
+
for (const [key, value] of Object.entries(schema.properties || {})) {
|
|
2561
|
+
const zodSchema = this.parseSchema(value);
|
|
2562
|
+
shape[key] = required.has(key) ? zodSchema : zodSchema.optional();
|
|
2312
2563
|
}
|
|
2564
|
+
const zodObject = import_zod.z.object(shape);
|
|
2565
|
+
return this.processAdditionalProperties(schema, zodObject);
|
|
2313
2566
|
}
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
let tools = [];
|
|
2337
|
-
try {
|
|
2338
|
-
tools = await this.adapter.createToolsFromConnectors([connector]);
|
|
2339
|
-
} catch (toolFetchError) {
|
|
2340
|
-
logger.error(
|
|
2341
|
-
`Failed to create tools from connector for server '${serverName}': ${toolFetchError}`
|
|
2342
|
-
);
|
|
2343
|
-
continue;
|
|
2344
|
-
}
|
|
2345
|
-
const cachedTools = this.serverTools[serverName];
|
|
2346
|
-
const toolsChanged = !cachedTools || !isEqual(cachedTools, tools);
|
|
2347
|
-
if (toolsChanged) {
|
|
2348
|
-
this.serverTools[serverName] = tools;
|
|
2349
|
-
this.initializedServers[serverName] = true;
|
|
2350
|
-
logger.debug(
|
|
2351
|
-
`Prefetched ${tools.length} tools for server '${serverName}'.`
|
|
2352
|
-
);
|
|
2353
|
-
} else {
|
|
2354
|
-
logger.debug(
|
|
2355
|
-
`Tools for server '${serverName}' unchanged, using cached version.`
|
|
2356
|
-
);
|
|
2357
|
-
}
|
|
2358
|
-
}
|
|
2359
|
-
} catch (outerError) {
|
|
2360
|
-
logger.error(
|
|
2361
|
-
`Error prefetching tools for server '${serverName}': ${outerError}`
|
|
2362
|
-
);
|
|
2567
|
+
/**
|
|
2568
|
+
* Applies default values from schema properties to data object.
|
|
2569
|
+
*
|
|
2570
|
+
* @param {JSONValue} data - The original data object.
|
|
2571
|
+
* @param {JSONSchema} schema - The schema with default values.
|
|
2572
|
+
* @returns {JSONValue} - The data object with defaults applied.
|
|
2573
|
+
*/
|
|
2574
|
+
static applyDefaultValues(data, schema) {
|
|
2575
|
+
if (typeof data !== "object" || data === null) {
|
|
2576
|
+
return data;
|
|
2577
|
+
}
|
|
2578
|
+
if (Array.isArray(data)) {
|
|
2579
|
+
return data;
|
|
2580
|
+
}
|
|
2581
|
+
const objectData = data;
|
|
2582
|
+
const dataWithDefaults = { ...objectData };
|
|
2583
|
+
if (!schema.properties) {
|
|
2584
|
+
return dataWithDefaults;
|
|
2585
|
+
}
|
|
2586
|
+
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
2587
|
+
if (!(key in dataWithDefaults) && "default" in propSchema) {
|
|
2588
|
+
dataWithDefaults[key] = propSchema["default"];
|
|
2363
2589
|
}
|
|
2364
2590
|
}
|
|
2591
|
+
return dataWithDefaults;
|
|
2365
2592
|
}
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2593
|
+
/**
|
|
2594
|
+
* Parses a schema with combinators (oneOf, anyOf, allOf).
|
|
2595
|
+
* Delegates to the appropriate combinator parser based on which combinator is present.
|
|
2596
|
+
*
|
|
2597
|
+
* @param {JSONSchema} schema - The JSON schema with combinators.
|
|
2598
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
2599
|
+
*/
|
|
2600
|
+
static parseCombinator(schema) {
|
|
2601
|
+
if (schema.oneOf) {
|
|
2602
|
+
return this.parseOneOf(schema.oneOf);
|
|
2369
2603
|
}
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
new ListMCPServersTool(this),
|
|
2373
|
-
new ConnectMCPServerTool(this),
|
|
2374
|
-
new AcquireActiveMCPServerTool(this),
|
|
2375
|
-
new ReleaseMCPServerConnectionTool(this)
|
|
2376
|
-
];
|
|
2377
|
-
if (this.activeServer && this.serverTools[this.activeServer]) {
|
|
2378
|
-
const activeTools = this.serverTools[this.activeServer];
|
|
2379
|
-
logger.debug(
|
|
2380
|
-
`Adding ${activeTools.length} tools from active server '${this.activeServer}'`
|
|
2381
|
-
);
|
|
2382
|
-
return [...managementTools, ...activeTools];
|
|
2604
|
+
if (schema.anyOf) {
|
|
2605
|
+
return this.parseAnyOf(schema.anyOf);
|
|
2383
2606
|
}
|
|
2384
|
-
|
|
2607
|
+
if (schema.allOf) {
|
|
2608
|
+
return this.parseAllOf(schema.allOf);
|
|
2609
|
+
}
|
|
2610
|
+
throw new Error("Unsupported schema type");
|
|
2385
2611
|
}
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
var ObservabilityManager = class {
|
|
2395
|
-
static {
|
|
2396
|
-
__name(this, "ObservabilityManager");
|
|
2612
|
+
/**
|
|
2613
|
+
* Parses a oneOf combinator schema.
|
|
2614
|
+
*
|
|
2615
|
+
* @param {JSONSchema[]} schemas - Array of JSON schemas in the oneOf.
|
|
2616
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
2617
|
+
*/
|
|
2618
|
+
static parseOneOf(schemas) {
|
|
2619
|
+
return this.createUnionFromSchemas(schemas);
|
|
2397
2620
|
}
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
metadataProvider;
|
|
2407
|
-
tagsProvider;
|
|
2408
|
-
constructor(config = {}) {
|
|
2409
|
-
this.customCallbacks = config.customCallbacks;
|
|
2410
|
-
this.verbose = config.verbose ?? false;
|
|
2411
|
-
this.observe = config.observe ?? true;
|
|
2412
|
-
this.agentId = config.agentId;
|
|
2413
|
-
this.metadata = config.metadata;
|
|
2414
|
-
this.metadataProvider = config.metadataProvider;
|
|
2415
|
-
this.tagsProvider = config.tagsProvider;
|
|
2621
|
+
/**
|
|
2622
|
+
* Parses an anyOf combinator schema.
|
|
2623
|
+
*
|
|
2624
|
+
* @param {JSONSchema[]} schemas - Array of JSON schemas in the anyOf.
|
|
2625
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
2626
|
+
*/
|
|
2627
|
+
static parseAnyOf(schemas) {
|
|
2628
|
+
return this.createUnionFromSchemas(schemas);
|
|
2416
2629
|
}
|
|
2417
2630
|
/**
|
|
2418
|
-
*
|
|
2631
|
+
* Creates a union from an array of schemas, handling special cases.
|
|
2632
|
+
*
|
|
2633
|
+
* @param {JSONSchema[]} schemas - Array of JSON schemas to create a union from.
|
|
2634
|
+
* @returns {ZodTypeAny} - The union Zod schema.
|
|
2419
2635
|
*/
|
|
2420
|
-
|
|
2421
|
-
if (
|
|
2422
|
-
return;
|
|
2636
|
+
static createUnionFromSchemas(schemas) {
|
|
2637
|
+
if (schemas.length === 0) {
|
|
2638
|
+
return import_zod.z.any();
|
|
2423
2639
|
}
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
this.metadataProvider,
|
|
2432
|
-
this.tagsProvider
|
|
2433
|
-
);
|
|
2434
|
-
logger.debug(
|
|
2435
|
-
`ObservabilityManager: Reinitialized Langfuse with agent ID: ${this.agentId}, metadata: ${JSON.stringify(this.metadata)}`
|
|
2436
|
-
);
|
|
2640
|
+
if (schemas.length === 1) {
|
|
2641
|
+
return this.parseSchema(schemas[0]);
|
|
2642
|
+
}
|
|
2643
|
+
const zodSchemas = [];
|
|
2644
|
+
for (const subSchema of schemas) {
|
|
2645
|
+
if (subSchema.type === "null") {
|
|
2646
|
+
zodSchemas.push(import_zod.z.null());
|
|
2437
2647
|
} else {
|
|
2438
|
-
|
|
2439
|
-
if (initPromise) {
|
|
2440
|
-
await initPromise;
|
|
2441
|
-
}
|
|
2442
|
-
}
|
|
2443
|
-
const handler = langfuseHandler2();
|
|
2444
|
-
if (handler) {
|
|
2445
|
-
this.availableHandlers.push(handler);
|
|
2446
|
-
this.handlerNames.push("Langfuse");
|
|
2447
|
-
logger.debug("ObservabilityManager: Langfuse handler available");
|
|
2648
|
+
zodSchemas.push(this.parseSchema(subSchema));
|
|
2448
2649
|
}
|
|
2449
|
-
} catch {
|
|
2450
|
-
logger.debug("ObservabilityManager: Langfuse module not available");
|
|
2451
2650
|
}
|
|
2452
|
-
|
|
2651
|
+
if (zodSchemas.length >= 2) {
|
|
2652
|
+
return import_zod.z.union(zodSchemas);
|
|
2653
|
+
} else if (zodSchemas.length === 1) {
|
|
2654
|
+
return zodSchemas[0];
|
|
2655
|
+
}
|
|
2656
|
+
return import_zod.z.any();
|
|
2453
2657
|
}
|
|
2454
2658
|
/**
|
|
2455
|
-
*
|
|
2456
|
-
*
|
|
2659
|
+
* Parses an allOf combinator schema by merging all schemas.
|
|
2660
|
+
*
|
|
2661
|
+
* @param {JSONSchema[]} schemas - Array of JSON schemas in the allOf.
|
|
2662
|
+
* @returns {ZodTypeAny} - The ZodTypeAny schema.
|
|
2457
2663
|
*/
|
|
2458
|
-
|
|
2459
|
-
if (
|
|
2460
|
-
|
|
2461
|
-
"ObservabilityManager: Observability disabled via observe=false"
|
|
2462
|
-
);
|
|
2463
|
-
return [];
|
|
2664
|
+
static parseAllOf(schemas) {
|
|
2665
|
+
if (schemas.length === 0) {
|
|
2666
|
+
return import_zod.z.any();
|
|
2464
2667
|
}
|
|
2465
|
-
if (
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2668
|
+
if (schemas.length === 1) {
|
|
2669
|
+
return this.parseSchema(schemas[0]);
|
|
2670
|
+
}
|
|
2671
|
+
const mergedSchema = schemas.reduce(
|
|
2672
|
+
(acc, currentSchema) => this.mergeSchemas(acc, currentSchema)
|
|
2673
|
+
);
|
|
2674
|
+
return this.parseSchema(mergedSchema);
|
|
2675
|
+
}
|
|
2676
|
+
/**
|
|
2677
|
+
* Merges two JSON schemas together.
|
|
2678
|
+
*
|
|
2679
|
+
* @param {JSONSchema} baseSchema - The base JSON schema.
|
|
2680
|
+
* @param {JSONSchema} addSchema - The JSON schema to add.
|
|
2681
|
+
* @returns {JSONSchema} - The merged JSON schema
|
|
2682
|
+
*/
|
|
2683
|
+
static mergeSchemas(baseSchema, addSchema) {
|
|
2684
|
+
const merged = { ...baseSchema, ...addSchema };
|
|
2685
|
+
if (baseSchema.properties && addSchema.properties) {
|
|
2686
|
+
const mergedProperties = {
|
|
2687
|
+
...baseSchema.properties,
|
|
2688
|
+
...addSchema.properties
|
|
2689
|
+
};
|
|
2690
|
+
merged.properties = mergedProperties;
|
|
2470
2691
|
}
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
} else {
|
|
2477
|
-
logger.debug("ObservabilityManager: No callbacks configured");
|
|
2692
|
+
if (baseSchema.required && addSchema.required) {
|
|
2693
|
+
const mergedRequired = [
|
|
2694
|
+
.../* @__PURE__ */ new Set([...baseSchema.required, ...addSchema.required])
|
|
2695
|
+
];
|
|
2696
|
+
merged.required = mergedRequired;
|
|
2478
2697
|
}
|
|
2479
|
-
return
|
|
2698
|
+
return merged;
|
|
2699
|
+
}
|
|
2700
|
+
};
|
|
2701
|
+
|
|
2702
|
+
// src/adapters/langchain_adapter.ts
|
|
2703
|
+
var import_tools = require("@langchain/core/tools");
|
|
2704
|
+
var import_zod2 = require("zod");
|
|
2705
|
+
init_logging();
|
|
2706
|
+
|
|
2707
|
+
// src/adapters/base.ts
|
|
2708
|
+
init_logging();
|
|
2709
|
+
var BaseAdapter = class {
|
|
2710
|
+
static {
|
|
2711
|
+
__name(this, "BaseAdapter");
|
|
2480
2712
|
}
|
|
2481
2713
|
/**
|
|
2482
|
-
*
|
|
2483
|
-
* @returns List of handler names (e.g., ["Langfuse", "Laminar"])
|
|
2714
|
+
* List of tool names that should not be available.
|
|
2484
2715
|
*/
|
|
2485
|
-
|
|
2486
|
-
if (!this.observe) {
|
|
2487
|
-
return [];
|
|
2488
|
-
}
|
|
2489
|
-
if (this.customCallbacks) {
|
|
2490
|
-
return this.customCallbacks.map((cb) => cb.constructor.name);
|
|
2491
|
-
}
|
|
2492
|
-
await this.collectAvailableHandlers();
|
|
2493
|
-
return this.handlerNames;
|
|
2494
|
-
}
|
|
2716
|
+
disallowedTools;
|
|
2495
2717
|
/**
|
|
2496
|
-
*
|
|
2497
|
-
*
|
|
2718
|
+
* Internal cache that maps a connector instance to the list of tools
|
|
2719
|
+
* generated for it.
|
|
2498
2720
|
*/
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
}
|
|
2503
|
-
const callbacks = await this.getCallbacks();
|
|
2504
|
-
return callbacks.length > 0;
|
|
2721
|
+
connectorToolMap = /* @__PURE__ */ new Map();
|
|
2722
|
+
constructor(disallowedTools) {
|
|
2723
|
+
this.disallowedTools = disallowedTools ?? [];
|
|
2505
2724
|
}
|
|
2506
2725
|
/**
|
|
2507
|
-
*
|
|
2508
|
-
*
|
|
2726
|
+
* Create tools from an MCPClient instance.
|
|
2727
|
+
*
|
|
2728
|
+
* This is the recommended way to create tools from an MCPClient, as it handles
|
|
2729
|
+
* session creation and connector extraction automatically.
|
|
2730
|
+
*
|
|
2731
|
+
* @param client The MCPClient to extract tools from.
|
|
2732
|
+
* @param disallowedTools Optional list of tool names to exclude.
|
|
2733
|
+
* @returns A promise that resolves with a list of converted tools.
|
|
2509
2734
|
*/
|
|
2510
|
-
async
|
|
2511
|
-
const
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
};
|
|
2735
|
+
static async createTools(client, disallowedTools) {
|
|
2736
|
+
const adapter = new this(disallowedTools);
|
|
2737
|
+
if (!client.activeSessions || Object.keys(client.activeSessions).length === 0) {
|
|
2738
|
+
logger.info("No active sessions found, creating new ones...");
|
|
2739
|
+
await client.createAllSessions();
|
|
2740
|
+
}
|
|
2741
|
+
const sessions = client.getAllActiveSessions();
|
|
2742
|
+
const connectors = Object.values(sessions).map(
|
|
2743
|
+
(session) => session.connector
|
|
2744
|
+
);
|
|
2745
|
+
return adapter.createToolsFromConnectors(connectors);
|
|
2522
2746
|
}
|
|
2523
2747
|
/**
|
|
2524
|
-
*
|
|
2525
|
-
*
|
|
2748
|
+
* Dynamically load tools for a specific connector.
|
|
2749
|
+
*
|
|
2750
|
+
* @param connector The connector to load tools for.
|
|
2751
|
+
* @returns The list of tools that were loaded in the target framework's format.
|
|
2526
2752
|
*/
|
|
2527
|
-
|
|
2528
|
-
if (
|
|
2529
|
-
|
|
2753
|
+
async loadToolsForConnector(connector) {
|
|
2754
|
+
if (this.connectorToolMap.has(connector)) {
|
|
2755
|
+
const cached = this.connectorToolMap.get(connector);
|
|
2756
|
+
logger.debug(`Returning ${cached.length} existing tools for connector`);
|
|
2757
|
+
return cached;
|
|
2530
2758
|
}
|
|
2531
|
-
|
|
2759
|
+
const connectorTools = [];
|
|
2760
|
+
const success = await this.ensureConnectorInitialized(connector);
|
|
2761
|
+
if (!success) {
|
|
2762
|
+
return [];
|
|
2763
|
+
}
|
|
2764
|
+
for (const tool of connector.tools) {
|
|
2765
|
+
const converted = this.convertTool(tool, connector);
|
|
2766
|
+
if (converted) {
|
|
2767
|
+
connectorTools.push(converted);
|
|
2768
|
+
}
|
|
2769
|
+
}
|
|
2770
|
+
this.connectorToolMap.set(connector, connectorTools);
|
|
2532
2771
|
logger.debug(
|
|
2533
|
-
`
|
|
2772
|
+
`Loaded ${connectorTools.length} new tools for connector: ${connectorTools.map((t) => t?.name ?? String(t)).join(", ")}`
|
|
2534
2773
|
);
|
|
2774
|
+
return connectorTools;
|
|
2535
2775
|
}
|
|
2536
2776
|
/**
|
|
2537
|
-
*
|
|
2777
|
+
* Create tools from MCP tools in all provided connectors.
|
|
2778
|
+
*
|
|
2779
|
+
* @param connectors List of MCP connectors to create tools from.
|
|
2780
|
+
* @returns A promise that resolves with all converted tools.
|
|
2538
2781
|
*/
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2782
|
+
async createToolsFromConnectors(connectors) {
|
|
2783
|
+
const tools = [];
|
|
2784
|
+
for (const connector of connectors) {
|
|
2785
|
+
const connectorTools = await this.loadToolsForConnector(connector);
|
|
2786
|
+
tools.push(...connectorTools);
|
|
2787
|
+
}
|
|
2788
|
+
logger.debug(`Available tools: ${tools.length}`);
|
|
2789
|
+
return tools;
|
|
2542
2790
|
}
|
|
2543
2791
|
/**
|
|
2544
|
-
*
|
|
2545
|
-
*
|
|
2792
|
+
* Check if a connector is initialized and has tools.
|
|
2793
|
+
*
|
|
2794
|
+
* @param connector The connector to check.
|
|
2795
|
+
* @returns True if the connector is initialized and has tools, false otherwise.
|
|
2546
2796
|
*/
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2797
|
+
checkConnectorInitialized(connector) {
|
|
2798
|
+
return Boolean(connector.tools && connector.tools.length);
|
|
2799
|
+
}
|
|
2800
|
+
/**
|
|
2801
|
+
* Ensure a connector is initialized.
|
|
2802
|
+
*
|
|
2803
|
+
* @param connector The connector to initialize.
|
|
2804
|
+
* @returns True if initialization succeeded, false otherwise.
|
|
2805
|
+
*/
|
|
2806
|
+
async ensureConnectorInitialized(connector) {
|
|
2807
|
+
if (!this.checkConnectorInitialized(connector)) {
|
|
2808
|
+
logger.debug("Connector doesn't have tools, initializing it");
|
|
2809
|
+
try {
|
|
2810
|
+
await connector.initialize();
|
|
2811
|
+
return true;
|
|
2812
|
+
} catch (err) {
|
|
2813
|
+
logger.error(`Error initializing connector: ${err}`);
|
|
2814
|
+
return false;
|
|
2552
2815
|
}
|
|
2553
2816
|
}
|
|
2554
|
-
|
|
2817
|
+
return true;
|
|
2818
|
+
}
|
|
2819
|
+
};
|
|
2820
|
+
|
|
2821
|
+
// src/adapters/langchain_adapter.ts
|
|
2822
|
+
function schemaToZod(schema) {
|
|
2823
|
+
try {
|
|
2824
|
+
return JSONSchemaToZod.convert(schema);
|
|
2825
|
+
} catch (err) {
|
|
2826
|
+
logger.warn(`Failed to convert JSON schema to Zod: ${err}`);
|
|
2827
|
+
return import_zod2.z.any();
|
|
2828
|
+
}
|
|
2829
|
+
}
|
|
2830
|
+
__name(schemaToZod, "schemaToZod");
|
|
2831
|
+
var LangChainAdapter = class extends BaseAdapter {
|
|
2832
|
+
static {
|
|
2833
|
+
__name(this, "LangChainAdapter");
|
|
2834
|
+
}
|
|
2835
|
+
constructor(disallowedTools = []) {
|
|
2836
|
+
super(disallowedTools);
|
|
2555
2837
|
}
|
|
2556
2838
|
/**
|
|
2557
|
-
*
|
|
2839
|
+
* Convert a single MCP tool specification into a LangChainJS structured tool.
|
|
2558
2840
|
*/
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
for (const callback of callbacks) {
|
|
2563
|
-
if ("shutdownAsync" in callback && typeof callback.shutdownAsync === "function") {
|
|
2564
|
-
await callback.shutdownAsync();
|
|
2565
|
-
} else if ("shutdown" in callback && typeof callback.shutdown === "function") {
|
|
2566
|
-
await callback.shutdown();
|
|
2567
|
-
}
|
|
2841
|
+
convertTool(mcpTool, connector) {
|
|
2842
|
+
if (this.disallowedTools.includes(mcpTool.name)) {
|
|
2843
|
+
return null;
|
|
2568
2844
|
}
|
|
2569
|
-
|
|
2845
|
+
const argsSchema = mcpTool.inputSchema ? schemaToZod(mcpTool.inputSchema) : import_zod2.z.object({}).optional();
|
|
2846
|
+
const tool = new import_tools.DynamicStructuredTool({
|
|
2847
|
+
name: mcpTool.name ?? "NO NAME",
|
|
2848
|
+
description: mcpTool.description ?? "",
|
|
2849
|
+
// Blank is acceptable but discouraged.
|
|
2850
|
+
schema: argsSchema,
|
|
2851
|
+
func: /* @__PURE__ */ __name(async (input) => {
|
|
2852
|
+
logger.debug(
|
|
2853
|
+
`MCP tool "${mcpTool.name}" received input: ${JSON.stringify(input)}`
|
|
2854
|
+
);
|
|
2855
|
+
try {
|
|
2856
|
+
const result = await connector.callTool(
|
|
2857
|
+
mcpTool.name,
|
|
2858
|
+
input
|
|
2859
|
+
);
|
|
2860
|
+
return JSON.stringify(result);
|
|
2861
|
+
} catch (err) {
|
|
2862
|
+
logger.error(`Error executing MCP tool: ${err.message}`);
|
|
2863
|
+
return `Error executing MCP tool: ${String(err)}`;
|
|
2864
|
+
}
|
|
2865
|
+
}, "func")
|
|
2866
|
+
});
|
|
2867
|
+
return tool;
|
|
2868
|
+
}
|
|
2869
|
+
};
|
|
2870
|
+
|
|
2871
|
+
// src/agents/mcp_agent.ts
|
|
2872
|
+
init_logging();
|
|
2873
|
+
|
|
2874
|
+
// src/managers/server_manager.ts
|
|
2875
|
+
init_logging();
|
|
2876
|
+
|
|
2877
|
+
// src/managers/tools/acquire_active_mcp_server.ts
|
|
2878
|
+
var import_zod3 = require("zod");
|
|
2879
|
+
|
|
2880
|
+
// src/managers/tools/base.ts
|
|
2881
|
+
var import_tools2 = require("@langchain/core/tools");
|
|
2882
|
+
var MCPServerTool = class extends import_tools2.StructuredTool {
|
|
2883
|
+
static {
|
|
2884
|
+
__name(this, "MCPServerTool");
|
|
2885
|
+
}
|
|
2886
|
+
name = "mcp_server_tool";
|
|
2887
|
+
description = "Base tool for MCP server operations.";
|
|
2888
|
+
schema;
|
|
2889
|
+
_manager;
|
|
2890
|
+
constructor(manager) {
|
|
2891
|
+
super();
|
|
2892
|
+
this._manager = manager;
|
|
2893
|
+
}
|
|
2894
|
+
async _call(_arg, _runManager, _parentConfig) {
|
|
2895
|
+
throw new Error("Method not implemented.");
|
|
2896
|
+
}
|
|
2897
|
+
get manager() {
|
|
2898
|
+
return this._manager;
|
|
2899
|
+
}
|
|
2900
|
+
};
|
|
2901
|
+
|
|
2902
|
+
// src/managers/tools/acquire_active_mcp_server.ts
|
|
2903
|
+
var PresentActiveServerSchema = import_zod3.z.object({});
|
|
2904
|
+
var AcquireActiveMCPServerTool = class extends MCPServerTool {
|
|
2905
|
+
static {
|
|
2906
|
+
__name(this, "AcquireActiveMCPServerTool");
|
|
2570
2907
|
}
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2908
|
+
name = "get_active_mcp_server";
|
|
2909
|
+
description = "Get the currently active MCP (Model Context Protocol) server";
|
|
2910
|
+
schema = PresentActiveServerSchema;
|
|
2911
|
+
constructor(manager) {
|
|
2912
|
+
super(manager);
|
|
2913
|
+
}
|
|
2914
|
+
async _call() {
|
|
2915
|
+
if (!this.manager.activeServer) {
|
|
2916
|
+
return `No MCP server is currently active. Use connect_to_mcp_server to connect to a server.`;
|
|
2578
2917
|
}
|
|
2579
|
-
return
|
|
2918
|
+
return `Currently active MCP server: ${this.manager.activeServer}`;
|
|
2580
2919
|
}
|
|
2581
2920
|
};
|
|
2582
2921
|
|
|
2583
|
-
// src/
|
|
2584
|
-
var
|
|
2585
|
-
var
|
|
2586
|
-
var path2 = __toESM(require("path"), 1);
|
|
2587
|
-
var import_posthog_node = require("posthog-node");
|
|
2588
|
-
|
|
2589
|
-
// src/server/utils/runtime.ts
|
|
2590
|
-
var isDeno = typeof globalThis.Deno !== "undefined";
|
|
2591
|
-
function generateUUID() {
|
|
2592
|
-
return globalThis.crypto.randomUUID();
|
|
2593
|
-
}
|
|
2594
|
-
__name(generateUUID, "generateUUID");
|
|
2595
|
-
|
|
2596
|
-
// src/telemetry/telemetry.ts
|
|
2922
|
+
// src/managers/tools/add_server_from_config.ts
|
|
2923
|
+
var import_tools3 = require("@langchain/core/tools");
|
|
2924
|
+
var import_zod4 = require("zod");
|
|
2597
2925
|
init_logging();
|
|
2598
|
-
|
|
2599
|
-
// src/telemetry/events.ts
|
|
2600
|
-
var BaseTelemetryEvent = class {
|
|
2926
|
+
var AddMCPServerFromConfigTool = class extends import_tools3.StructuredTool {
|
|
2601
2927
|
static {
|
|
2602
|
-
__name(this, "
|
|
2928
|
+
__name(this, "AddMCPServerFromConfigTool");
|
|
2603
2929
|
}
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2930
|
+
name = "add_mcp_server_from_config";
|
|
2931
|
+
description = "Adds a new MCP server to the client from a configuration object and connects to it, making its tools available.";
|
|
2932
|
+
schema = import_zod4.z.object({
|
|
2933
|
+
serverName: import_zod4.z.string().describe("The name for the new MCP server."),
|
|
2934
|
+
serverConfig: import_zod4.z.any().describe(
|
|
2935
|
+
'The configuration object for the server. This should not include the top-level "mcpServers" key.'
|
|
2936
|
+
)
|
|
2937
|
+
});
|
|
2938
|
+
manager;
|
|
2939
|
+
constructor(manager) {
|
|
2607
2940
|
super();
|
|
2608
|
-
this.
|
|
2609
|
-
}
|
|
2610
|
-
static {
|
|
2611
|
-
__name(this, "MCPAgentExecutionEvent");
|
|
2612
|
-
}
|
|
2613
|
-
get name() {
|
|
2614
|
-
return "mcp_agent_execution";
|
|
2941
|
+
this.manager = manager;
|
|
2615
2942
|
}
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
conversation_history_length: this.data.conversationHistoryLength ?? null
|
|
2646
|
-
};
|
|
2943
|
+
async _call({
|
|
2944
|
+
serverName,
|
|
2945
|
+
serverConfig
|
|
2946
|
+
}) {
|
|
2947
|
+
try {
|
|
2948
|
+
this.manager.client.addServer(serverName, serverConfig);
|
|
2949
|
+
let result = `Server '${serverName}' added to the client.`;
|
|
2950
|
+
logger.debug(
|
|
2951
|
+
`Connecting to new server '${serverName}' and discovering tools.`
|
|
2952
|
+
);
|
|
2953
|
+
const session = await this.manager.client.createSession(serverName);
|
|
2954
|
+
const connector = session.connector;
|
|
2955
|
+
const tools = await this.manager.adapter.createToolsFromConnectors([connector]);
|
|
2956
|
+
this.manager.serverTools[serverName] = tools;
|
|
2957
|
+
this.manager.initializedServers[serverName] = true;
|
|
2958
|
+
this.manager.activeServer = serverName;
|
|
2959
|
+
const numTools = tools.length;
|
|
2960
|
+
result += ` Session created and connected. '${serverName}' is now the active server with ${numTools} tools available.`;
|
|
2961
|
+
result += `
|
|
2962
|
+
|
|
2963
|
+
${tools.map((t) => t.name).join("\n")}`;
|
|
2964
|
+
logger.info(result);
|
|
2965
|
+
return result;
|
|
2966
|
+
} catch (e) {
|
|
2967
|
+
logger.error(
|
|
2968
|
+
`Failed to add or connect to server '${serverName}': ${e.message}`
|
|
2969
|
+
);
|
|
2970
|
+
return `Failed to add or connect to server '${serverName}': ${e.message}`;
|
|
2971
|
+
}
|
|
2647
2972
|
}
|
|
2648
2973
|
};
|
|
2649
2974
|
|
|
2650
|
-
// src/
|
|
2651
|
-
var
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf-8"));
|
|
2660
|
-
return packageJson.version || "unknown";
|
|
2661
|
-
} catch {
|
|
2662
|
-
return "unknown";
|
|
2975
|
+
// src/managers/tools/connect_mcp_server.ts
|
|
2976
|
+
var import_zod5 = require("zod");
|
|
2977
|
+
init_logging();
|
|
2978
|
+
var ConnectMCPServerSchema = import_zod5.z.object({
|
|
2979
|
+
serverName: import_zod5.z.string().describe("The name of the MCP server.")
|
|
2980
|
+
});
|
|
2981
|
+
var ConnectMCPServerTool = class extends MCPServerTool {
|
|
2982
|
+
static {
|
|
2983
|
+
__name(this, "ConnectMCPServerTool");
|
|
2663
2984
|
}
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2985
|
+
name = "connect_to_mcp_server";
|
|
2986
|
+
description = "Connect to a specific MCP (Model Context Protocol) server to use its tools. Use this tool to connect to a specific server and use its tools.";
|
|
2987
|
+
schema = ConnectMCPServerSchema;
|
|
2988
|
+
constructor(manager) {
|
|
2989
|
+
super(manager);
|
|
2990
|
+
}
|
|
2991
|
+
async _call({ serverName }) {
|
|
2992
|
+
const serverNames = this.manager.client.getServerNames();
|
|
2993
|
+
if (!serverNames.includes(serverName)) {
|
|
2994
|
+
const available = serverNames.length > 0 ? serverNames.join(", ") : "none";
|
|
2995
|
+
return `Server '${serverName}' not found. Available servers: ${available}`;
|
|
2996
|
+
}
|
|
2997
|
+
if (this.manager.activeServer === serverName) {
|
|
2998
|
+
return `Already connected to MCP server '${serverName}'`;
|
|
2999
|
+
}
|
|
3000
|
+
try {
|
|
3001
|
+
let session = this.manager.client.getSession(serverName);
|
|
3002
|
+
logger.debug(`Using existing session for server '${serverName}'`);
|
|
3003
|
+
if (!session) {
|
|
3004
|
+
logger.debug(`Creating new session for server '${serverName}'`);
|
|
3005
|
+
session = await this.manager.client.createSession(serverName);
|
|
3006
|
+
}
|
|
3007
|
+
this.manager.activeServer = serverName;
|
|
3008
|
+
if (this.manager.serverTools[serverName]) {
|
|
3009
|
+
const connector = session.connector;
|
|
3010
|
+
const tools = await this.manager.adapter.createToolsFromConnectors([connector]);
|
|
3011
|
+
this.manager.serverTools[serverName] = tools;
|
|
3012
|
+
this.manager.initializedServers[serverName] = true;
|
|
2686
3013
|
}
|
|
3014
|
+
const serverTools = this.manager.serverTools[serverName] || [];
|
|
3015
|
+
const numTools = serverTools.length;
|
|
3016
|
+
return `Connected to MCP server '${serverName}'. ${numTools} tools are now available.`;
|
|
3017
|
+
} catch (error) {
|
|
3018
|
+
logger.error(
|
|
3019
|
+
`Error connecting to server '${serverName}': ${String(error)}`
|
|
3020
|
+
);
|
|
3021
|
+
return `Failed to connect to server '${serverName}': ${String(error)}`;
|
|
2687
3022
|
}
|
|
2688
3023
|
}
|
|
2689
|
-
|
|
2690
|
-
}
|
|
2691
|
-
__name(getModelName, "getModelName");
|
|
2692
|
-
function extractModelInfo(llm) {
|
|
2693
|
-
return [getModelProvider(llm), getModelName(llm)];
|
|
2694
|
-
}
|
|
2695
|
-
__name(extractModelInfo, "extractModelInfo");
|
|
3024
|
+
};
|
|
2696
3025
|
|
|
2697
|
-
// src/
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
3026
|
+
// src/managers/tools/list_mcp_servers.ts
|
|
3027
|
+
var import_zod6 = require("zod");
|
|
3028
|
+
init_logging();
|
|
3029
|
+
var EnumerateServersSchema = import_zod6.z.object({});
|
|
3030
|
+
var ListMCPServersTool = class extends MCPServerTool {
|
|
3031
|
+
static {
|
|
3032
|
+
__name(this, "ListMCPServersTool");
|
|
3033
|
+
}
|
|
3034
|
+
name = "list_mcp_servers";
|
|
3035
|
+
description = `Lists all available MCP (Model Context Protocol) servers that can be connected to, along with the tools available on each server. Use this tool to discover servers and see what functionalities they offer.`;
|
|
3036
|
+
schema = EnumerateServersSchema;
|
|
3037
|
+
constructor(manager) {
|
|
3038
|
+
super(manager);
|
|
3039
|
+
}
|
|
3040
|
+
async _call() {
|
|
3041
|
+
const serverNames = this.manager.client.getServerNames();
|
|
3042
|
+
if (serverNames.length === 0) {
|
|
3043
|
+
return `No MCP servers are currently defined.`;
|
|
2702
3044
|
}
|
|
2703
|
-
|
|
2704
|
-
|
|
3045
|
+
const outputLines = ["Available MCP servers:"];
|
|
3046
|
+
for (const serverName of serverNames) {
|
|
3047
|
+
const isActiveServer = serverName === this.manager.activeServer;
|
|
3048
|
+
const activeFlag = isActiveServer ? " (ACTIVE)" : "";
|
|
3049
|
+
outputLines.push(`- ${serverName}${activeFlag}`);
|
|
3050
|
+
try {
|
|
3051
|
+
const serverTools = this.manager.serverTools?.[serverName] ?? [];
|
|
3052
|
+
const numberOfTools = Array.isArray(serverTools) ? serverTools.length : 0;
|
|
3053
|
+
outputLines.push(`${numberOfTools} tools available for this server
|
|
3054
|
+
`);
|
|
3055
|
+
} catch (error) {
|
|
3056
|
+
logger.error(
|
|
3057
|
+
`Unexpected error listing tools for server '${serverName}': ${String(error)}`
|
|
3058
|
+
);
|
|
3059
|
+
}
|
|
2705
3060
|
}
|
|
2706
|
-
|
|
2707
|
-
const hasNodeModules = typeof fs2 !== "undefined" && typeof os !== "undefined" && typeof fs2.existsSync === "function";
|
|
2708
|
-
return hasNodeGlobals && hasNodeModules;
|
|
2709
|
-
} catch {
|
|
2710
|
-
return false;
|
|
3061
|
+
return outputLines.join("\n");
|
|
2711
3062
|
}
|
|
2712
|
-
}
|
|
2713
|
-
|
|
2714
|
-
|
|
3063
|
+
};
|
|
3064
|
+
|
|
3065
|
+
// src/managers/tools/release_mcp_server_connection.ts
|
|
3066
|
+
var import_zod7 = require("zod");
|
|
3067
|
+
var ReleaseConnectionSchema = import_zod7.z.object({});
|
|
3068
|
+
var ReleaseMCPServerConnectionTool = class extends MCPServerTool {
|
|
2715
3069
|
static {
|
|
2716
|
-
__name(this, "
|
|
3070
|
+
__name(this, "ReleaseMCPServerConnectionTool");
|
|
2717
3071
|
}
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
3072
|
+
name = "disconnect_from_mcp_server";
|
|
3073
|
+
description = "Disconnect from the currently active MCP (Model Context Protocol) server";
|
|
3074
|
+
schema = ReleaseConnectionSchema;
|
|
3075
|
+
constructor(manager) {
|
|
3076
|
+
super(manager);
|
|
2723
3077
|
}
|
|
2724
|
-
async
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
2728
|
-
const response = await fetch(this.endpoint, {
|
|
2729
|
-
method: "POST",
|
|
2730
|
-
headers: {
|
|
2731
|
-
"Content-Type": "application/json"
|
|
2732
|
-
},
|
|
2733
|
-
body: JSON.stringify(properties),
|
|
2734
|
-
signal: controller.signal
|
|
2735
|
-
});
|
|
2736
|
-
clearTimeout(timeoutId);
|
|
2737
|
-
if (!response.ok) {
|
|
2738
|
-
throw new Error(`HTTP error! status: ${response.status}`);
|
|
2739
|
-
}
|
|
2740
|
-
} catch (error) {
|
|
2741
|
-
logger.debug(`Failed to send Scarf event: ${error}`);
|
|
3078
|
+
async _call() {
|
|
3079
|
+
if (!this.manager.activeServer) {
|
|
3080
|
+
return `No MCP server is currently active, so there's nothing to disconnect from.`;
|
|
2742
3081
|
}
|
|
3082
|
+
const serverName = this.manager.activeServer;
|
|
3083
|
+
this.manager.activeServer = null;
|
|
3084
|
+
return `Successfully disconnected from MCP server '${serverName}'.`;
|
|
2743
3085
|
}
|
|
2744
3086
|
};
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
3087
|
+
|
|
3088
|
+
// src/managers/server_manager.ts
|
|
3089
|
+
function isEqual(a, b) {
|
|
3090
|
+
if (a === b) return true;
|
|
3091
|
+
if (a == null || b == null) return false;
|
|
3092
|
+
if (typeof a !== typeof b) return false;
|
|
3093
|
+
if (a instanceof Date && b instanceof Date) {
|
|
3094
|
+
return a.getTime() === b.getTime();
|
|
2748
3095
|
}
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
return
|
|
3096
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
3097
|
+
if (a.length !== b.length) return false;
|
|
3098
|
+
return a.every((item, index) => isEqual(item, b[index]));
|
|
2752
3099
|
}
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
return
|
|
2759
|
-
}
|
|
2760
|
-
return path2.join(homeDir, "AppData", "Local");
|
|
2761
|
-
} else if (platform === "darwin") {
|
|
2762
|
-
return path2.join(homeDir, "Library", "Caches");
|
|
2763
|
-
} else {
|
|
2764
|
-
return path2.join(homeDir, ".cache");
|
|
3100
|
+
if (typeof a === "object" && typeof b === "object") {
|
|
3101
|
+
const keysA = Object.keys(a);
|
|
3102
|
+
const keysB = Object.keys(b);
|
|
3103
|
+
if (keysA.length !== keysB.length) return false;
|
|
3104
|
+
return keysA.every((key) => {
|
|
3105
|
+
return Object.prototype.hasOwnProperty.call(b, key) && isEqual(a[key], b[key]);
|
|
3106
|
+
});
|
|
2765
3107
|
}
|
|
3108
|
+
return false;
|
|
2766
3109
|
}
|
|
2767
|
-
__name(
|
|
2768
|
-
var
|
|
3110
|
+
__name(isEqual, "isEqual");
|
|
3111
|
+
var ServerManager = class {
|
|
2769
3112
|
static {
|
|
2770
|
-
__name(this, "
|
|
3113
|
+
__name(this, "ServerManager");
|
|
2771
3114
|
}
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
this.
|
|
2801
|
-
this.
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
logger.warn(`Failed to initialize PostHog telemetry: ${e}`);
|
|
2816
|
-
this._posthogClient = null;
|
|
2817
|
-
}
|
|
3115
|
+
initializedServers = {};
|
|
3116
|
+
serverTools = {};
|
|
3117
|
+
client;
|
|
3118
|
+
adapter;
|
|
3119
|
+
activeServer = null;
|
|
3120
|
+
overrideManagementTools;
|
|
3121
|
+
constructor(client, adapter, managementTools) {
|
|
3122
|
+
this.client = client;
|
|
3123
|
+
this.adapter = adapter;
|
|
3124
|
+
this.overrideManagementTools = managementTools;
|
|
3125
|
+
}
|
|
3126
|
+
setManagementTools(tools) {
|
|
3127
|
+
this.overrideManagementTools = tools;
|
|
3128
|
+
logger.info(
|
|
3129
|
+
`Overriding default management tools with a new set of ${tools.length} tools.`
|
|
3130
|
+
);
|
|
3131
|
+
}
|
|
3132
|
+
logState(context) {
|
|
3133
|
+
const allServerNames = this.client.getServerNames();
|
|
3134
|
+
const activeSessionNames = Object.keys(this.client.getAllActiveSessions());
|
|
3135
|
+
if (allServerNames.length === 0) {
|
|
3136
|
+
logger.info("Server Manager State: No servers configured.");
|
|
3137
|
+
return;
|
|
3138
|
+
}
|
|
3139
|
+
const tableData = allServerNames.map((name) => ({
|
|
3140
|
+
"Server Name": name,
|
|
3141
|
+
Connected: activeSessionNames.includes(name) ? "\u2705" : "\u274C",
|
|
3142
|
+
Initialized: this.initializedServers[name] ? "\u2705" : "\u274C",
|
|
3143
|
+
"Tool Count": this.serverTools[name]?.length ?? 0,
|
|
3144
|
+
Active: this.activeServer === name ? "\u2705" : "\u274C"
|
|
3145
|
+
}));
|
|
3146
|
+
logger.info(`Server Manager State: [${context}]`);
|
|
3147
|
+
console.table(tableData);
|
|
3148
|
+
}
|
|
3149
|
+
initialize() {
|
|
3150
|
+
const serverNames = this.client.getServerNames?.();
|
|
3151
|
+
if (serverNames.length === 0) {
|
|
3152
|
+
logger.warn("No MCP servers defined in client configuration");
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
3155
|
+
async prefetchServerTools() {
|
|
3156
|
+
const servers = this.client.getServerNames();
|
|
3157
|
+
for (const serverName of servers) {
|
|
2818
3158
|
try {
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
logger.
|
|
2822
|
-
|
|
3159
|
+
let session = null;
|
|
3160
|
+
session = this.client.getSession(serverName);
|
|
3161
|
+
logger.debug(
|
|
3162
|
+
`Using existing session for server '${serverName}' to prefetch tools.`
|
|
3163
|
+
);
|
|
3164
|
+
if (!session) {
|
|
3165
|
+
session = await this.client.createSession(serverName).catch((createSessionError) => {
|
|
3166
|
+
logger.warn(
|
|
3167
|
+
`Could not create session for '${serverName}' during prefetch: ${createSessionError}`
|
|
3168
|
+
);
|
|
3169
|
+
return null;
|
|
3170
|
+
});
|
|
3171
|
+
logger.debug(
|
|
3172
|
+
`Temporarily created session for '${serverName}' to prefetch tools.`
|
|
3173
|
+
);
|
|
3174
|
+
}
|
|
3175
|
+
if (session) {
|
|
3176
|
+
const connector = session.connector;
|
|
3177
|
+
let tools = [];
|
|
3178
|
+
try {
|
|
3179
|
+
tools = await this.adapter.createToolsFromConnectors([connector]);
|
|
3180
|
+
} catch (toolFetchError) {
|
|
3181
|
+
logger.error(
|
|
3182
|
+
`Failed to create tools from connector for server '${serverName}': ${toolFetchError}`
|
|
3183
|
+
);
|
|
3184
|
+
continue;
|
|
3185
|
+
}
|
|
3186
|
+
const cachedTools = this.serverTools[serverName];
|
|
3187
|
+
const toolsChanged = !cachedTools || !isEqual(cachedTools, tools);
|
|
3188
|
+
if (toolsChanged) {
|
|
3189
|
+
this.serverTools[serverName] = tools;
|
|
3190
|
+
this.initializedServers[serverName] = true;
|
|
3191
|
+
logger.debug(
|
|
3192
|
+
`Prefetched ${tools.length} tools for server '${serverName}'.`
|
|
3193
|
+
);
|
|
3194
|
+
} else {
|
|
3195
|
+
logger.debug(
|
|
3196
|
+
`Tools for server '${serverName}' unchanged, using cached version.`
|
|
3197
|
+
);
|
|
3198
|
+
}
|
|
3199
|
+
}
|
|
3200
|
+
} catch (outerError) {
|
|
3201
|
+
logger.error(
|
|
3202
|
+
`Error prefetching tools for server '${serverName}': ${outerError}`
|
|
3203
|
+
);
|
|
2823
3204
|
}
|
|
2824
3205
|
}
|
|
2825
3206
|
}
|
|
2826
|
-
|
|
2827
|
-
if (
|
|
2828
|
-
|
|
3207
|
+
get tools() {
|
|
3208
|
+
if (logger.level === "debug") {
|
|
3209
|
+
this.logState("Providing tools to agent");
|
|
2829
3210
|
}
|
|
2830
|
-
|
|
3211
|
+
const managementTools = this.overrideManagementTools ?? [
|
|
3212
|
+
new AddMCPServerFromConfigTool(this),
|
|
3213
|
+
new ListMCPServersTool(this),
|
|
3214
|
+
new ConnectMCPServerTool(this),
|
|
3215
|
+
new AcquireActiveMCPServerTool(this),
|
|
3216
|
+
new ReleaseMCPServerConnectionTool(this)
|
|
3217
|
+
];
|
|
3218
|
+
if (this.activeServer && this.serverTools[this.activeServer]) {
|
|
3219
|
+
const activeTools = this.serverTools[this.activeServer];
|
|
3220
|
+
logger.debug(
|
|
3221
|
+
`Adding ${activeTools.length} tools from active server '${this.activeServer}'`
|
|
3222
|
+
);
|
|
3223
|
+
return [...managementTools, ...activeTools];
|
|
3224
|
+
}
|
|
3225
|
+
return managementTools;
|
|
2831
3226
|
}
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
3227
|
+
};
|
|
3228
|
+
|
|
3229
|
+
// src/observability/index.ts
|
|
3230
|
+
init_langfuse();
|
|
3231
|
+
init_langfuse();
|
|
3232
|
+
|
|
3233
|
+
// src/observability/manager.ts
|
|
3234
|
+
init_logging();
|
|
3235
|
+
var ObservabilityManager = class {
|
|
3236
|
+
static {
|
|
3237
|
+
__name(this, "ObservabilityManager");
|
|
3238
|
+
}
|
|
3239
|
+
customCallbacks;
|
|
3240
|
+
availableHandlers = [];
|
|
3241
|
+
handlerNames = [];
|
|
3242
|
+
initialized = false;
|
|
3243
|
+
verbose;
|
|
3244
|
+
observe;
|
|
3245
|
+
agentId;
|
|
3246
|
+
metadata;
|
|
3247
|
+
metadataProvider;
|
|
3248
|
+
tagsProvider;
|
|
3249
|
+
constructor(config = {}) {
|
|
3250
|
+
this.customCallbacks = config.customCallbacks;
|
|
3251
|
+
this.verbose = config.verbose ?? false;
|
|
3252
|
+
this.observe = config.observe ?? true;
|
|
3253
|
+
this.agentId = config.agentId;
|
|
3254
|
+
this.metadata = config.metadata;
|
|
3255
|
+
this.metadataProvider = config.metadataProvider;
|
|
3256
|
+
this.tagsProvider = config.tagsProvider;
|
|
2840
3257
|
}
|
|
2841
3258
|
/**
|
|
2842
|
-
*
|
|
3259
|
+
* Collect all available observability handlers from configured platforms.
|
|
2843
3260
|
*/
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
get userId() {
|
|
2848
|
-
if (this._currUserId) {
|
|
2849
|
-
return this._currUserId;
|
|
2850
|
-
}
|
|
2851
|
-
if (!isNodeJSEnvironment2()) {
|
|
2852
|
-
this._currUserId = this.UNKNOWN_USER_ID;
|
|
2853
|
-
return this._currUserId;
|
|
3261
|
+
async collectAvailableHandlers() {
|
|
3262
|
+
if (this.initialized) {
|
|
3263
|
+
return;
|
|
2854
3264
|
}
|
|
2855
3265
|
try {
|
|
2856
|
-
const
|
|
2857
|
-
if (
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
3266
|
+
const { langfuseHandler: langfuseHandler2, langfuseInitPromise: langfuseInitPromise2 } = await Promise.resolve().then(() => (init_langfuse(), langfuse_exports));
|
|
3267
|
+
if (this.agentId || this.metadata || this.metadataProvider || this.tagsProvider) {
|
|
3268
|
+
const { initializeLangfuse: initializeLangfuse2 } = await Promise.resolve().then(() => (init_langfuse(), langfuse_exports));
|
|
3269
|
+
await initializeLangfuse2(
|
|
3270
|
+
this.agentId,
|
|
3271
|
+
this.metadata,
|
|
3272
|
+
this.metadataProvider,
|
|
3273
|
+
this.tagsProvider
|
|
3274
|
+
);
|
|
3275
|
+
logger.debug(
|
|
3276
|
+
`ObservabilityManager: Reinitialized Langfuse with agent ID: ${this.agentId}, metadata: ${JSON.stringify(this.metadata)}`
|
|
3277
|
+
);
|
|
2864
3278
|
} else {
|
|
2865
|
-
|
|
3279
|
+
const initPromise = langfuseInitPromise2();
|
|
3280
|
+
if (initPromise) {
|
|
3281
|
+
await initPromise;
|
|
3282
|
+
}
|
|
2866
3283
|
}
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
3284
|
+
const handler = langfuseHandler2();
|
|
3285
|
+
if (handler) {
|
|
3286
|
+
this.availableHandlers.push(handler);
|
|
3287
|
+
this.handlerNames.push("Langfuse");
|
|
3288
|
+
logger.debug("ObservabilityManager: Langfuse handler available");
|
|
3289
|
+
}
|
|
3290
|
+
} catch {
|
|
3291
|
+
logger.debug("ObservabilityManager: Langfuse module not available");
|
|
2873
3292
|
}
|
|
2874
|
-
|
|
3293
|
+
this.initialized = true;
|
|
2875
3294
|
}
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
3295
|
+
/**
|
|
3296
|
+
* Get the list of callbacks to use.
|
|
3297
|
+
* @returns List of callbacks - either custom callbacks if provided, or all available observability handlers.
|
|
3298
|
+
*/
|
|
3299
|
+
async getCallbacks() {
|
|
3300
|
+
if (!this.observe) {
|
|
3301
|
+
logger.debug(
|
|
3302
|
+
"ObservabilityManager: Observability disabled via observe=false"
|
|
3303
|
+
);
|
|
3304
|
+
return [];
|
|
2879
3305
|
}
|
|
2880
|
-
if (this.
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
properties.source = this._source;
|
|
2886
|
-
this._posthogClient.capture({
|
|
2887
|
-
distinctId: this.userId,
|
|
2888
|
-
event: event.name,
|
|
2889
|
-
properties
|
|
2890
|
-
});
|
|
2891
|
-
} catch (e) {
|
|
2892
|
-
logger.debug(`Failed to track PostHog event ${event.name}: ${e}`);
|
|
2893
|
-
}
|
|
3306
|
+
if (this.customCallbacks) {
|
|
3307
|
+
logger.debug(
|
|
3308
|
+
`ObservabilityManager: Using ${this.customCallbacks.length} custom callbacks`
|
|
3309
|
+
);
|
|
3310
|
+
return this.customCallbacks;
|
|
2894
3311
|
}
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
properties.source = this._source;
|
|
2903
|
-
await this._scarfClient.logEvent(properties);
|
|
2904
|
-
} catch (e) {
|
|
2905
|
-
logger.debug(`Failed to track Scarf event ${event.name}: ${e}`);
|
|
2906
|
-
}
|
|
3312
|
+
await this.collectAvailableHandlers();
|
|
3313
|
+
if (this.availableHandlers.length > 0) {
|
|
3314
|
+
logger.debug(
|
|
3315
|
+
`ObservabilityManager: Using ${this.availableHandlers.length} handlers`
|
|
3316
|
+
);
|
|
3317
|
+
} else {
|
|
3318
|
+
logger.debug("ObservabilityManager: No callbacks configured");
|
|
2907
3319
|
}
|
|
3320
|
+
return this.availableHandlers;
|
|
2908
3321
|
}
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
3322
|
+
/**
|
|
3323
|
+
* Get the names of available handlers.
|
|
3324
|
+
* @returns List of handler names (e.g., ["Langfuse", "Laminar"])
|
|
3325
|
+
*/
|
|
3326
|
+
async getHandlerNames() {
|
|
3327
|
+
if (!this.observe) {
|
|
3328
|
+
return [];
|
|
2912
3329
|
}
|
|
2913
|
-
if (
|
|
2914
|
-
return;
|
|
3330
|
+
if (this.customCallbacks) {
|
|
3331
|
+
return this.customCallbacks.map((cb) => cb.constructor.name);
|
|
2915
3332
|
}
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
fs2.writeFileSync(this.VERSION_DOWNLOAD_PATH, currentVersion);
|
|
2927
|
-
} else {
|
|
2928
|
-
const savedVersion = fs2.readFileSync(this.VERSION_DOWNLOAD_PATH, "utf-8").trim();
|
|
2929
|
-
if (currentVersion > savedVersion) {
|
|
2930
|
-
shouldTrack = true;
|
|
2931
|
-
firstDownload = false;
|
|
2932
|
-
fs2.writeFileSync(this.VERSION_DOWNLOAD_PATH, currentVersion);
|
|
2933
|
-
}
|
|
2934
|
-
}
|
|
2935
|
-
if (shouldTrack) {
|
|
2936
|
-
logger.debug(
|
|
2937
|
-
`Tracking package download event with properties: ${JSON.stringify(properties)}`
|
|
2938
|
-
);
|
|
2939
|
-
const eventProperties = { ...properties || {} };
|
|
2940
|
-
eventProperties.mcp_use_version = currentVersion;
|
|
2941
|
-
eventProperties.user_id = this.userId;
|
|
2942
|
-
eventProperties.event = "package_download";
|
|
2943
|
-
eventProperties.first_download = firstDownload;
|
|
2944
|
-
eventProperties.language = "typescript";
|
|
2945
|
-
eventProperties.source = this._source;
|
|
2946
|
-
await this._scarfClient.logEvent(eventProperties);
|
|
2947
|
-
}
|
|
2948
|
-
} catch (e) {
|
|
2949
|
-
logger.debug(`Failed to track Scarf package_download event: ${e}`);
|
|
3333
|
+
await this.collectAvailableHandlers();
|
|
3334
|
+
return this.handlerNames;
|
|
3335
|
+
}
|
|
3336
|
+
/**
|
|
3337
|
+
* Check if any callbacks are available.
|
|
3338
|
+
* @returns True if callbacks are available, False otherwise.
|
|
3339
|
+
*/
|
|
3340
|
+
async hasCallbacks() {
|
|
3341
|
+
if (!this.observe) {
|
|
3342
|
+
return false;
|
|
2950
3343
|
}
|
|
3344
|
+
const callbacks = await this.getCallbacks();
|
|
3345
|
+
return callbacks.length > 0;
|
|
2951
3346
|
}
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
3347
|
+
/**
|
|
3348
|
+
* Get the current observability status including metadata and tags.
|
|
3349
|
+
* @returns Object containing enabled status, callback count, handler names, metadata, and tags.
|
|
3350
|
+
*/
|
|
3351
|
+
async getStatus() {
|
|
3352
|
+
const callbacks = await this.getCallbacks();
|
|
3353
|
+
const handlerNames = await this.getHandlerNames();
|
|
3354
|
+
const currentMetadata = this.metadataProvider ? this.metadataProvider() : this.metadata || {};
|
|
3355
|
+
const currentTags = this.tagsProvider ? this.tagsProvider() : [];
|
|
3356
|
+
return {
|
|
3357
|
+
enabled: this.observe && callbacks.length > 0,
|
|
3358
|
+
callbackCount: callbacks.length,
|
|
3359
|
+
handlerNames,
|
|
3360
|
+
metadata: currentMetadata,
|
|
3361
|
+
tags: currentTags
|
|
3362
|
+
};
|
|
2955
3363
|
}
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
}
|
|
3364
|
+
/**
|
|
3365
|
+
* Add a callback to the custom callbacks list.
|
|
3366
|
+
* @param callback The callback to add.
|
|
3367
|
+
*/
|
|
3368
|
+
addCallback(callback) {
|
|
3369
|
+
if (!this.customCallbacks) {
|
|
3370
|
+
this.customCallbacks = [];
|
|
2964
3371
|
}
|
|
2965
|
-
|
|
2966
|
-
|
|
3372
|
+
this.customCallbacks.push(callback);
|
|
3373
|
+
logger.debug(
|
|
3374
|
+
`ObservabilityManager: Added custom callback: ${callback.constructor.name}`
|
|
3375
|
+
);
|
|
3376
|
+
}
|
|
3377
|
+
/**
|
|
3378
|
+
* Clear all custom callbacks.
|
|
3379
|
+
*/
|
|
3380
|
+
clearCallbacks() {
|
|
3381
|
+
this.customCallbacks = [];
|
|
3382
|
+
logger.debug("ObservabilityManager: Cleared all custom callbacks");
|
|
3383
|
+
}
|
|
3384
|
+
/**
|
|
3385
|
+
* Flush all pending traces to observability platforms.
|
|
3386
|
+
* Important for serverless environments and short-lived processes.
|
|
3387
|
+
*/
|
|
3388
|
+
async flush() {
|
|
3389
|
+
const callbacks = await this.getCallbacks();
|
|
3390
|
+
for (const callback of callbacks) {
|
|
3391
|
+
if ("flushAsync" in callback && typeof callback.flushAsync === "function") {
|
|
3392
|
+
await callback.flushAsync();
|
|
3393
|
+
}
|
|
2967
3394
|
}
|
|
3395
|
+
logger.debug("ObservabilityManager: All traces flushed");
|
|
2968
3396
|
}
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
3397
|
+
/**
|
|
3398
|
+
* Shutdown all handlers gracefully (for serverless environments).
|
|
3399
|
+
*/
|
|
3400
|
+
async shutdown() {
|
|
3401
|
+
await this.flush();
|
|
3402
|
+
const callbacks = await this.getCallbacks();
|
|
3403
|
+
for (const callback of callbacks) {
|
|
3404
|
+
if ("shutdownAsync" in callback && typeof callback.shutdownAsync === "function") {
|
|
3405
|
+
await callback.shutdownAsync();
|
|
3406
|
+
} else if ("shutdown" in callback && typeof callback.shutdown === "function") {
|
|
3407
|
+
await callback.shutdown();
|
|
2976
3408
|
}
|
|
2977
3409
|
}
|
|
2978
|
-
|
|
2979
|
-
|
|
3410
|
+
logger.debug("ObservabilityManager: All handlers shutdown");
|
|
3411
|
+
}
|
|
3412
|
+
/**
|
|
3413
|
+
* String representation of the ObservabilityManager.
|
|
3414
|
+
*/
|
|
3415
|
+
toString() {
|
|
3416
|
+
const names = this.handlerNames;
|
|
3417
|
+
if (names.length > 0) {
|
|
3418
|
+
return `ObservabilityManager(handlers=${names.join(", ")})`;
|
|
2980
3419
|
}
|
|
3420
|
+
return "ObservabilityManager(no handlers)";
|
|
2981
3421
|
}
|
|
2982
3422
|
};
|
|
2983
3423
|
|
|
@@ -3308,6 +3748,13 @@ var MCPAgent = class {
|
|
|
3308
3748
|
static {
|
|
3309
3749
|
__name(this, "MCPAgent");
|
|
3310
3750
|
}
|
|
3751
|
+
/**
|
|
3752
|
+
* Get the mcp-use package version.
|
|
3753
|
+
* Works in all environments (Node.js, browser, Cloudflare Workers, Deno, etc.)
|
|
3754
|
+
*/
|
|
3755
|
+
static getPackageVersion() {
|
|
3756
|
+
return getPackageVersion();
|
|
3757
|
+
}
|
|
3311
3758
|
llm;
|
|
3312
3759
|
client;
|
|
3313
3760
|
connectors;
|
|
@@ -4031,7 +4478,7 @@ var MCPAgent = class {
|
|
|
4031
4478
|
const historyToUse = externalHistory ?? this.conversationHistory;
|
|
4032
4479
|
const langchainHistory = [];
|
|
4033
4480
|
for (const msg of historyToUse) {
|
|
4034
|
-
if (this._isHumanMessageLike(msg) || this._isAIMessageLike(msg)) {
|
|
4481
|
+
if (this._isHumanMessageLike(msg) || this._isAIMessageLike(msg) || this._isToolMessageLike(msg)) {
|
|
4035
4482
|
langchainHistory.push(msg);
|
|
4036
4483
|
}
|
|
4037
4484
|
}
|
|
@@ -4164,9 +4611,9 @@ var MCPAgent = class {
|
|
|
4164
4611
|
}
|
|
4165
4612
|
}
|
|
4166
4613
|
if (this.memoryEnabled) {
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
this.addToHistory(
|
|
4614
|
+
const newMessages = accumulatedMessages.slice(langchainHistory.length);
|
|
4615
|
+
for (const msg of newMessages) {
|
|
4616
|
+
this.addToHistory(msg);
|
|
4170
4617
|
}
|
|
4171
4618
|
}
|
|
4172
4619
|
if (outputSchema && finalOutput) {
|
|
@@ -4601,7 +5048,9 @@ ${formatPrompt}`
|
|
|
4601
5048
|
let chunkCount = 0;
|
|
4602
5049
|
for await (const chunk of stream) {
|
|
4603
5050
|
chunkCount++;
|
|
4604
|
-
logger.
|
|
5051
|
+
logger.debug(
|
|
5052
|
+
`Chunk ${chunkCount}: ${JSON.stringify(chunk, null, 2)}`
|
|
5053
|
+
);
|
|
4605
5054
|
if (typeof chunk === "string") {
|
|
4606
5055
|
try {
|
|
4607
5056
|
structuredResult = JSON.parse(chunk);
|
|
@@ -4618,7 +5067,9 @@ ${formatPrompt}`
|
|
|
4618
5067
|
}
|
|
4619
5068
|
}
|
|
4620
5069
|
if (chunkCount % 10 === 0) {
|
|
4621
|
-
logger.
|
|
5070
|
+
logger.debug(
|
|
5071
|
+
`\u{1F504} Structured output streaming: ${chunkCount} chunks`
|
|
5072
|
+
);
|
|
4622
5073
|
}
|
|
4623
5074
|
}
|
|
4624
5075
|
logger.info(
|