mcp-use 1.9.1-canary.0 → 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-KHTTBIRP.js → chunk-BPP5XYP6.js} +156 -5
- package/dist/{chunk-3R5PDYIN.js → chunk-J75I2C26.js} +39 -11
- package/dist/{chunk-5URNFWCQ.js → chunk-LWVK6RXA.js} +8 -3
- 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/{context-storage-TXQ4DVSS.js → context-storage-NA4MHWOZ.js} +3 -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/context-storage.d.ts +8 -1
- package/dist/src/server/context-storage.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 +2162 -287
- package/dist/src/server/index.d.ts +4 -3
- package/dist/src/server/index.d.ts.map +1 -1
- package/dist/src/server/index.js +870 -261
- package/dist/src/server/mcp-server.d.ts +107 -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 +45 -25
- package/dist/src/server/resources/index.d.ts.map +1 -1
- package/dist/src/server/resources/subscriptions.d.ts +54 -0
- package/dist/src/server/resources/subscriptions.d.ts.map +1 -0
- package/dist/src/server/sessions/session-manager.d.ts +17 -5
- package/dist/src/server/sessions/session-manager.d.ts.map +1 -1
- package/dist/src/server/tools/tool-execution-helpers.d.ts +59 -23
- 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 +132 -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 +65 -33
- 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-IVUDHXMK.js → tool-execution-helpers-XFVBSRXM.js} +9 -2
- package/dist/tsup.config.d.ts.map +1 -1
- package/package.json +6 -5
- package/dist/chunk-MTHLLDCX.js +0 -97
|
@@ -55,48 +55,48 @@ var init_runtime = __esm({
|
|
|
55
55
|
__name(getEnv, "getEnv");
|
|
56
56
|
__name(getCwd, "getCwd");
|
|
57
57
|
fsHelpers = {
|
|
58
|
-
async readFileSync(
|
|
58
|
+
async readFileSync(path2, encoding = "utf8") {
|
|
59
59
|
if (isDeno) {
|
|
60
|
-
return await globalThis.Deno.readTextFile(
|
|
60
|
+
return await globalThis.Deno.readTextFile(path2);
|
|
61
61
|
}
|
|
62
|
-
const { readFileSync } = await import("fs");
|
|
63
|
-
const result =
|
|
62
|
+
const { readFileSync: readFileSync2 } = await import("fs");
|
|
63
|
+
const result = readFileSync2(path2, encoding);
|
|
64
64
|
return typeof result === "string" ? result : result.toString(encoding);
|
|
65
65
|
},
|
|
66
|
-
async readFile(
|
|
66
|
+
async readFile(path2) {
|
|
67
67
|
if (isDeno) {
|
|
68
|
-
const data = await globalThis.Deno.readFile(
|
|
68
|
+
const data = await globalThis.Deno.readFile(path2);
|
|
69
69
|
return data.buffer;
|
|
70
70
|
}
|
|
71
|
-
const { readFileSync } = await import("fs");
|
|
72
|
-
const buffer =
|
|
71
|
+
const { readFileSync: readFileSync2 } = await import("fs");
|
|
72
|
+
const buffer = readFileSync2(path2);
|
|
73
73
|
return buffer.buffer.slice(
|
|
74
74
|
buffer.byteOffset,
|
|
75
75
|
buffer.byteOffset + buffer.byteLength
|
|
76
76
|
);
|
|
77
77
|
},
|
|
78
|
-
async existsSync(
|
|
78
|
+
async existsSync(path2) {
|
|
79
79
|
if (isDeno) {
|
|
80
80
|
try {
|
|
81
|
-
await globalThis.Deno.stat(
|
|
81
|
+
await globalThis.Deno.stat(path2);
|
|
82
82
|
return true;
|
|
83
83
|
} catch {
|
|
84
84
|
return false;
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
-
const { existsSync } = await import("fs");
|
|
88
|
-
return
|
|
87
|
+
const { existsSync: existsSync2 } = await import("fs");
|
|
88
|
+
return existsSync2(path2);
|
|
89
89
|
},
|
|
90
|
-
async readdirSync(
|
|
90
|
+
async readdirSync(path2) {
|
|
91
91
|
if (isDeno) {
|
|
92
92
|
const entries = [];
|
|
93
|
-
for await (const entry of globalThis.Deno.readDir(
|
|
93
|
+
for await (const entry of globalThis.Deno.readDir(path2)) {
|
|
94
94
|
entries.push(entry.name);
|
|
95
95
|
}
|
|
96
96
|
return entries;
|
|
97
97
|
}
|
|
98
98
|
const { readdirSync } = await import("fs");
|
|
99
|
-
return readdirSync(
|
|
99
|
+
return readdirSync(path2);
|
|
100
100
|
}
|
|
101
101
|
};
|
|
102
102
|
pathHelpers = {
|
|
@@ -122,18 +122,1137 @@ var init_runtime = __esm({
|
|
|
122
122
|
}
|
|
123
123
|
});
|
|
124
124
|
|
|
125
|
+
// src/logging.ts
|
|
126
|
+
async function getNodeModules() {
|
|
127
|
+
if (typeof process !== "undefined" && process.platform) {
|
|
128
|
+
try {
|
|
129
|
+
const fs2 = await import("fs");
|
|
130
|
+
const path2 = await import("path");
|
|
131
|
+
return { fs: fs2.default, path: path2.default };
|
|
132
|
+
} catch {
|
|
133
|
+
return { fs: null, path: null };
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return { fs: null, path: null };
|
|
137
|
+
}
|
|
138
|
+
function loadWinstonSync() {
|
|
139
|
+
if (typeof require !== "undefined") {
|
|
140
|
+
try {
|
|
141
|
+
winston = require("winston");
|
|
142
|
+
} catch {
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async function getWinston() {
|
|
147
|
+
if (!winston) {
|
|
148
|
+
winston = await import("winston");
|
|
149
|
+
}
|
|
150
|
+
return winston;
|
|
151
|
+
}
|
|
152
|
+
function isNodeJSEnvironment() {
|
|
153
|
+
try {
|
|
154
|
+
if (typeof navigator !== "undefined" && navigator.userAgent?.includes("Cloudflare-Workers")) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
if (typeof globalThis.EdgeRuntime !== "undefined" || typeof globalThis.Deno !== "undefined") {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
const hasNodeGlobals = typeof process !== "undefined" && typeof process.platform !== "undefined" && typeof __dirname !== "undefined";
|
|
161
|
+
return hasNodeGlobals;
|
|
162
|
+
} catch {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
function resolveLevel(env) {
|
|
167
|
+
const envValue = typeof process !== "undefined" && process.env ? env : void 0;
|
|
168
|
+
switch (envValue?.trim()) {
|
|
169
|
+
case "2":
|
|
170
|
+
return "debug";
|
|
171
|
+
case "1":
|
|
172
|
+
return "info";
|
|
173
|
+
default:
|
|
174
|
+
return "info";
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
var winston, DEFAULT_LOGGER_NAME, SimpleConsoleLogger, Logger, logger;
|
|
178
|
+
var init_logging = __esm({
|
|
179
|
+
"src/logging.ts"() {
|
|
180
|
+
"use strict";
|
|
181
|
+
__name(getNodeModules, "getNodeModules");
|
|
182
|
+
winston = null;
|
|
183
|
+
__name(loadWinstonSync, "loadWinstonSync");
|
|
184
|
+
__name(getWinston, "getWinston");
|
|
185
|
+
DEFAULT_LOGGER_NAME = "mcp-use";
|
|
186
|
+
__name(isNodeJSEnvironment, "isNodeJSEnvironment");
|
|
187
|
+
SimpleConsoleLogger = class {
|
|
188
|
+
static {
|
|
189
|
+
__name(this, "SimpleConsoleLogger");
|
|
190
|
+
}
|
|
191
|
+
_level;
|
|
192
|
+
name;
|
|
193
|
+
constructor(name = DEFAULT_LOGGER_NAME, level = "info") {
|
|
194
|
+
this.name = name;
|
|
195
|
+
this._level = level;
|
|
196
|
+
}
|
|
197
|
+
shouldLog(level) {
|
|
198
|
+
const levels = [
|
|
199
|
+
"error",
|
|
200
|
+
"warn",
|
|
201
|
+
"info",
|
|
202
|
+
"http",
|
|
203
|
+
"verbose",
|
|
204
|
+
"debug",
|
|
205
|
+
"silly"
|
|
206
|
+
];
|
|
207
|
+
const currentIndex = levels.indexOf(this._level);
|
|
208
|
+
const messageIndex = levels.indexOf(level);
|
|
209
|
+
return messageIndex <= currentIndex;
|
|
210
|
+
}
|
|
211
|
+
formatMessage(level, message) {
|
|
212
|
+
const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false });
|
|
213
|
+
return `${timestamp} [${this.name}] ${level}: ${message}`;
|
|
214
|
+
}
|
|
215
|
+
error(message) {
|
|
216
|
+
if (this.shouldLog("error")) {
|
|
217
|
+
console.error(this.formatMessage("error", message));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
warn(message) {
|
|
221
|
+
if (this.shouldLog("warn")) {
|
|
222
|
+
console.warn(this.formatMessage("warn", message));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
info(message) {
|
|
226
|
+
if (this.shouldLog("info")) {
|
|
227
|
+
console.info(this.formatMessage("info", message));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
debug(message) {
|
|
231
|
+
if (this.shouldLog("debug")) {
|
|
232
|
+
console.debug(this.formatMessage("debug", message));
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
http(message) {
|
|
236
|
+
if (this.shouldLog("http")) {
|
|
237
|
+
console.log(this.formatMessage("http", message));
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
verbose(message) {
|
|
241
|
+
if (this.shouldLog("verbose")) {
|
|
242
|
+
console.log(this.formatMessage("verbose", message));
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
silly(message) {
|
|
246
|
+
if (this.shouldLog("silly")) {
|
|
247
|
+
console.log(this.formatMessage("silly", message));
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// Make it compatible with Winston interface
|
|
251
|
+
get level() {
|
|
252
|
+
return this._level;
|
|
253
|
+
}
|
|
254
|
+
set level(newLevel) {
|
|
255
|
+
this._level = newLevel;
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
__name(resolveLevel, "resolveLevel");
|
|
259
|
+
Logger = class {
|
|
260
|
+
static {
|
|
261
|
+
__name(this, "Logger");
|
|
262
|
+
}
|
|
263
|
+
static instances = {};
|
|
264
|
+
static simpleInstances = {};
|
|
265
|
+
static currentFormat = "minimal";
|
|
266
|
+
static get(name = DEFAULT_LOGGER_NAME) {
|
|
267
|
+
if (!isNodeJSEnvironment()) {
|
|
268
|
+
if (!this.simpleInstances[name]) {
|
|
269
|
+
const debugEnv = typeof process !== "undefined" && process.env?.DEBUG || void 0;
|
|
270
|
+
this.simpleInstances[name] = new SimpleConsoleLogger(
|
|
271
|
+
name,
|
|
272
|
+
resolveLevel(debugEnv)
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
return this.simpleInstances[name];
|
|
276
|
+
}
|
|
277
|
+
if (!this.instances[name]) {
|
|
278
|
+
if (!winston) {
|
|
279
|
+
throw new Error("Winston not loaded - call Logger.configure() first");
|
|
280
|
+
}
|
|
281
|
+
const { createLogger, format } = winston;
|
|
282
|
+
const { combine, timestamp, label, colorize, splat } = format;
|
|
283
|
+
this.instances[name] = createLogger({
|
|
284
|
+
level: resolveLevel(process.env.DEBUG),
|
|
285
|
+
format: combine(
|
|
286
|
+
colorize(),
|
|
287
|
+
splat(),
|
|
288
|
+
label({ label: name }),
|
|
289
|
+
timestamp({ format: "HH:mm:ss" }),
|
|
290
|
+
this.getFormatter()
|
|
291
|
+
),
|
|
292
|
+
transports: []
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
return this.instances[name];
|
|
296
|
+
}
|
|
297
|
+
static getFormatter() {
|
|
298
|
+
if (!winston) {
|
|
299
|
+
throw new Error("Winston not loaded");
|
|
300
|
+
}
|
|
301
|
+
const { format } = winston;
|
|
302
|
+
const { printf } = format;
|
|
303
|
+
const minimalFormatter = printf(({ level, message, label, timestamp }) => {
|
|
304
|
+
return `${timestamp} [${label}] ${level}: ${message}`;
|
|
305
|
+
});
|
|
306
|
+
const detailedFormatter = printf(({ level, message, label, timestamp }) => {
|
|
307
|
+
return `${timestamp} [${label}] ${level.toUpperCase()}: ${message}`;
|
|
308
|
+
});
|
|
309
|
+
const emojiFormatter = printf(({ level, message, label, timestamp }) => {
|
|
310
|
+
return `${timestamp} [${label}] ${level.toUpperCase()}: ${message}`;
|
|
311
|
+
});
|
|
312
|
+
switch (this.currentFormat) {
|
|
313
|
+
case "minimal":
|
|
314
|
+
return minimalFormatter;
|
|
315
|
+
case "detailed":
|
|
316
|
+
return detailedFormatter;
|
|
317
|
+
case "emoji":
|
|
318
|
+
return emojiFormatter;
|
|
319
|
+
default:
|
|
320
|
+
return minimalFormatter;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
static async configure(options = {}) {
|
|
324
|
+
const { level, console: console2 = true, file, format = "minimal" } = options;
|
|
325
|
+
const debugEnv = typeof process !== "undefined" && process.env?.DEBUG || void 0;
|
|
326
|
+
const resolvedLevel = level ?? resolveLevel(debugEnv);
|
|
327
|
+
this.currentFormat = format;
|
|
328
|
+
if (!isNodeJSEnvironment()) {
|
|
329
|
+
Object.values(this.simpleInstances).forEach((logger2) => {
|
|
330
|
+
logger2.level = resolvedLevel;
|
|
331
|
+
});
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
await getWinston();
|
|
335
|
+
if (!winston) {
|
|
336
|
+
throw new Error("Failed to load winston");
|
|
337
|
+
}
|
|
338
|
+
const root = this.get();
|
|
339
|
+
root.level = resolvedLevel;
|
|
340
|
+
const winstonRoot = root;
|
|
341
|
+
winstonRoot.clear();
|
|
342
|
+
if (console2) {
|
|
343
|
+
winstonRoot.add(new winston.transports.Console());
|
|
344
|
+
}
|
|
345
|
+
if (file) {
|
|
346
|
+
const { fs: nodeFs, path: nodePath } = await getNodeModules();
|
|
347
|
+
if (nodeFs && nodePath) {
|
|
348
|
+
const dir = nodePath.dirname(nodePath.resolve(file));
|
|
349
|
+
if (!nodeFs.existsSync(dir)) {
|
|
350
|
+
nodeFs.mkdirSync(dir, { recursive: true });
|
|
351
|
+
}
|
|
352
|
+
winstonRoot.add(new winston.transports.File({ filename: file }));
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
const { format: winstonFormat } = winston;
|
|
356
|
+
const { combine, timestamp, label, colorize, splat } = winstonFormat;
|
|
357
|
+
Object.values(this.instances).forEach((logger2) => {
|
|
358
|
+
if (logger2 && "format" in logger2) {
|
|
359
|
+
logger2.level = resolvedLevel;
|
|
360
|
+
logger2.format = combine(
|
|
361
|
+
colorize(),
|
|
362
|
+
splat(),
|
|
363
|
+
label({ label: DEFAULT_LOGGER_NAME }),
|
|
364
|
+
timestamp({ format: "HH:mm:ss" }),
|
|
365
|
+
this.getFormatter()
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
static setDebug(enabled) {
|
|
371
|
+
let level;
|
|
372
|
+
if (enabled === 2 || enabled === true) level = "debug";
|
|
373
|
+
else if (enabled === 1) level = "info";
|
|
374
|
+
else level = "info";
|
|
375
|
+
Object.values(this.simpleInstances).forEach((logger2) => {
|
|
376
|
+
logger2.level = level;
|
|
377
|
+
});
|
|
378
|
+
Object.values(this.instances).forEach((logger2) => {
|
|
379
|
+
if (logger2) {
|
|
380
|
+
logger2.level = level;
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
if (typeof process !== "undefined" && process.env) {
|
|
384
|
+
process.env.DEBUG = enabled ? enabled === true ? "2" : String(enabled) : "0";
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
static setFormat(format) {
|
|
388
|
+
this.currentFormat = format;
|
|
389
|
+
this.configure({ format });
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
if (isNodeJSEnvironment()) {
|
|
393
|
+
loadWinstonSync();
|
|
394
|
+
if (winston) {
|
|
395
|
+
Logger.configure();
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
logger = Logger.get();
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
// src/telemetry/events.ts
|
|
403
|
+
function createServerRunEventData(server, transport) {
|
|
404
|
+
const toolRegistrations = Array.from(server.registrations.tools.values());
|
|
405
|
+
const promptRegistrations = Array.from(server.registrations.prompts.values());
|
|
406
|
+
const resourceRegistrations = Array.from(
|
|
407
|
+
server.registrations.resources.values()
|
|
408
|
+
);
|
|
409
|
+
const templateRegistrations = Array.from(
|
|
410
|
+
server.registrations.resourceTemplates.values()
|
|
411
|
+
);
|
|
412
|
+
const allResources = resourceRegistrations.map((r) => ({
|
|
413
|
+
name: r.config.name,
|
|
414
|
+
title: r.config.title ?? null,
|
|
415
|
+
description: r.config.description ?? null,
|
|
416
|
+
uri: r.config.uri ?? null,
|
|
417
|
+
mime_type: r.config.mimeType ?? null
|
|
418
|
+
}));
|
|
419
|
+
const appsSdkResources = allResources.filter(
|
|
420
|
+
(r) => r.mime_type === "text/html+skybridge"
|
|
421
|
+
);
|
|
422
|
+
const mcpUiResources = allResources.filter(
|
|
423
|
+
(r) => r.mime_type === "text/uri-list" || r.mime_type === "text/html"
|
|
424
|
+
);
|
|
425
|
+
const mcpAppsResources = allResources.filter(
|
|
426
|
+
(r) => r.mime_type === "text/html+mcp"
|
|
427
|
+
);
|
|
428
|
+
return {
|
|
429
|
+
transport,
|
|
430
|
+
toolsNumber: server.registeredTools.length,
|
|
431
|
+
resourcesNumber: server.registeredResources.length,
|
|
432
|
+
promptsNumber: server.registeredPrompts.length,
|
|
433
|
+
auth: !!server.oauthProvider,
|
|
434
|
+
name: server.config.name,
|
|
435
|
+
description: server.config.description ?? null,
|
|
436
|
+
baseUrl: server.serverBaseUrl ?? null,
|
|
437
|
+
toolNames: server.registeredTools.length > 0 ? server.registeredTools : null,
|
|
438
|
+
resourceNames: server.registeredResources.length > 0 ? server.registeredResources : null,
|
|
439
|
+
promptNames: server.registeredPrompts.length > 0 ? server.registeredPrompts : null,
|
|
440
|
+
tools: toolRegistrations.length > 0 ? toolRegistrations.map((r) => ({
|
|
441
|
+
name: r.config.name,
|
|
442
|
+
title: r.config.title ?? null,
|
|
443
|
+
description: r.config.description ?? null,
|
|
444
|
+
input_schema: r.config.schema ? JSON.stringify(r.config.schema) : null,
|
|
445
|
+
output_schema: r.config.outputSchema ? JSON.stringify(r.config.outputSchema) : null
|
|
446
|
+
})) : null,
|
|
447
|
+
resources: allResources.length > 0 ? allResources : null,
|
|
448
|
+
prompts: promptRegistrations.length > 0 ? promptRegistrations.map((r) => ({
|
|
449
|
+
name: r.config.name,
|
|
450
|
+
title: r.config.title ?? null,
|
|
451
|
+
description: r.config.description ?? null,
|
|
452
|
+
args: r.config.args ? JSON.stringify(r.config.args) : null
|
|
453
|
+
})) : null,
|
|
454
|
+
templates: templateRegistrations.length > 0 ? templateRegistrations.map((r) => ({
|
|
455
|
+
name: r.config.name,
|
|
456
|
+
title: r.config.title ?? null,
|
|
457
|
+
description: r.config.description ?? null
|
|
458
|
+
})) : null,
|
|
459
|
+
capabilities: {
|
|
460
|
+
logging: true,
|
|
461
|
+
resources: { subscribe: true, listChanged: true }
|
|
462
|
+
},
|
|
463
|
+
appsSdkResources: appsSdkResources.length > 0 ? appsSdkResources : null,
|
|
464
|
+
appsSdkResourcesNumber: appsSdkResources.length,
|
|
465
|
+
mcpUiResources: mcpUiResources.length > 0 ? mcpUiResources : null,
|
|
466
|
+
mcpUiResourcesNumber: mcpUiResources.length,
|
|
467
|
+
mcpAppsResources: mcpAppsResources.length > 0 ? mcpAppsResources : null,
|
|
468
|
+
mcpAppsResourcesNumber: mcpAppsResources.length
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
var BaseTelemetryEvent, MCPAgentExecutionEvent, ServerRunEvent, ServerInitializeEvent, ServerToolCallEvent, ServerResourceCallEvent, ServerPromptCallEvent, ServerContextEvent, MCPClientInitEvent, ConnectorInitEvent;
|
|
472
|
+
var init_events = __esm({
|
|
473
|
+
"src/telemetry/events.ts"() {
|
|
474
|
+
"use strict";
|
|
475
|
+
BaseTelemetryEvent = class {
|
|
476
|
+
static {
|
|
477
|
+
__name(this, "BaseTelemetryEvent");
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
MCPAgentExecutionEvent = class extends BaseTelemetryEvent {
|
|
481
|
+
constructor(data) {
|
|
482
|
+
super();
|
|
483
|
+
this.data = data;
|
|
484
|
+
}
|
|
485
|
+
static {
|
|
486
|
+
__name(this, "MCPAgentExecutionEvent");
|
|
487
|
+
}
|
|
488
|
+
get name() {
|
|
489
|
+
return "mcp_agent_execution";
|
|
490
|
+
}
|
|
491
|
+
get properties() {
|
|
492
|
+
return {
|
|
493
|
+
// Core execution info
|
|
494
|
+
execution_method: this.data.executionMethod,
|
|
495
|
+
query: this.data.query,
|
|
496
|
+
query_length: this.data.query.length,
|
|
497
|
+
success: this.data.success,
|
|
498
|
+
// Agent configuration
|
|
499
|
+
model_provider: this.data.modelProvider,
|
|
500
|
+
model_name: this.data.modelName,
|
|
501
|
+
server_count: this.data.serverCount,
|
|
502
|
+
server_identifiers: this.data.serverIdentifiers,
|
|
503
|
+
total_tools_available: this.data.totalToolsAvailable,
|
|
504
|
+
tools_available_names: this.data.toolsAvailableNames,
|
|
505
|
+
max_steps_configured: this.data.maxStepsConfigured,
|
|
506
|
+
memory_enabled: this.data.memoryEnabled,
|
|
507
|
+
use_server_manager: this.data.useServerManager,
|
|
508
|
+
// Execution parameters (always include, even if null)
|
|
509
|
+
max_steps_used: this.data.maxStepsUsed,
|
|
510
|
+
manage_connector: this.data.manageConnector,
|
|
511
|
+
external_history_used: this.data.externalHistoryUsed,
|
|
512
|
+
// Execution results (always include, even if null)
|
|
513
|
+
steps_taken: this.data.stepsTaken ?? null,
|
|
514
|
+
tools_used_count: this.data.toolsUsedCount ?? null,
|
|
515
|
+
tools_used_names: this.data.toolsUsedNames ?? null,
|
|
516
|
+
response: this.data.response ?? null,
|
|
517
|
+
response_length: this.data.response ? this.data.response.length : null,
|
|
518
|
+
execution_time_ms: this.data.executionTimeMs ?? null,
|
|
519
|
+
error_type: this.data.errorType ?? null,
|
|
520
|
+
conversation_history_length: this.data.conversationHistoryLength ?? null
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
__name(createServerRunEventData, "createServerRunEventData");
|
|
525
|
+
ServerRunEvent = class extends BaseTelemetryEvent {
|
|
526
|
+
constructor(data) {
|
|
527
|
+
super();
|
|
528
|
+
this.data = data;
|
|
529
|
+
}
|
|
530
|
+
static {
|
|
531
|
+
__name(this, "ServerRunEvent");
|
|
532
|
+
}
|
|
533
|
+
get name() {
|
|
534
|
+
return "server_run";
|
|
535
|
+
}
|
|
536
|
+
get properties() {
|
|
537
|
+
return {
|
|
538
|
+
transport: this.data.transport,
|
|
539
|
+
tools_number: this.data.toolsNumber,
|
|
540
|
+
resources_number: this.data.resourcesNumber,
|
|
541
|
+
prompts_number: this.data.promptsNumber,
|
|
542
|
+
auth: this.data.auth,
|
|
543
|
+
name: this.data.name,
|
|
544
|
+
description: this.data.description ?? null,
|
|
545
|
+
base_url: this.data.baseUrl ?? null,
|
|
546
|
+
tool_names: this.data.toolNames ?? null,
|
|
547
|
+
resource_names: this.data.resourceNames ?? null,
|
|
548
|
+
prompt_names: this.data.promptNames ?? null,
|
|
549
|
+
tools: this.data.tools ?? null,
|
|
550
|
+
resources: this.data.resources ?? null,
|
|
551
|
+
prompts: this.data.prompts ?? null,
|
|
552
|
+
templates: this.data.templates ?? null,
|
|
553
|
+
capabilities: this.data.capabilities ? JSON.stringify(this.data.capabilities) : null,
|
|
554
|
+
apps_sdk_resources: this.data.appsSdkResources ? JSON.stringify(this.data.appsSdkResources) : null,
|
|
555
|
+
apps_sdk_resources_number: this.data.appsSdkResourcesNumber ?? 0,
|
|
556
|
+
mcp_ui_resources: this.data.mcpUiResources ? JSON.stringify(this.data.mcpUiResources) : null,
|
|
557
|
+
mcp_ui_resources_number: this.data.mcpUiResourcesNumber ?? 0,
|
|
558
|
+
mcp_apps_resources: this.data.mcpAppsResources ? JSON.stringify(this.data.mcpAppsResources) : null,
|
|
559
|
+
mcp_apps_resources_number: this.data.mcpAppsResourcesNumber ?? 0
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
};
|
|
563
|
+
ServerInitializeEvent = class extends BaseTelemetryEvent {
|
|
564
|
+
constructor(data) {
|
|
565
|
+
super();
|
|
566
|
+
this.data = data;
|
|
567
|
+
}
|
|
568
|
+
static {
|
|
569
|
+
__name(this, "ServerInitializeEvent");
|
|
570
|
+
}
|
|
571
|
+
get name() {
|
|
572
|
+
return "server_initialize_call";
|
|
573
|
+
}
|
|
574
|
+
get properties() {
|
|
575
|
+
return {
|
|
576
|
+
protocol_version: this.data.protocolVersion,
|
|
577
|
+
client_info: JSON.stringify(this.data.clientInfo),
|
|
578
|
+
client_capabilities: JSON.stringify(this.data.clientCapabilities),
|
|
579
|
+
session_id: this.data.sessionId ?? null
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
ServerToolCallEvent = class extends BaseTelemetryEvent {
|
|
584
|
+
constructor(data) {
|
|
585
|
+
super();
|
|
586
|
+
this.data = data;
|
|
587
|
+
}
|
|
588
|
+
static {
|
|
589
|
+
__name(this, "ServerToolCallEvent");
|
|
590
|
+
}
|
|
591
|
+
get name() {
|
|
592
|
+
return "server_tool_call";
|
|
593
|
+
}
|
|
594
|
+
get properties() {
|
|
595
|
+
return {
|
|
596
|
+
tool_name: this.data.toolName,
|
|
597
|
+
length_input_argument: this.data.lengthInputArgument,
|
|
598
|
+
success: this.data.success,
|
|
599
|
+
error_type: this.data.errorType ?? null,
|
|
600
|
+
execution_time_ms: this.data.executionTimeMs ?? null
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
ServerResourceCallEvent = class extends BaseTelemetryEvent {
|
|
605
|
+
constructor(data) {
|
|
606
|
+
super();
|
|
607
|
+
this.data = data;
|
|
608
|
+
}
|
|
609
|
+
static {
|
|
610
|
+
__name(this, "ServerResourceCallEvent");
|
|
611
|
+
}
|
|
612
|
+
get name() {
|
|
613
|
+
return "server_resource_call";
|
|
614
|
+
}
|
|
615
|
+
get properties() {
|
|
616
|
+
return {
|
|
617
|
+
name: this.data.name,
|
|
618
|
+
description: this.data.description,
|
|
619
|
+
contents: this.data.contents,
|
|
620
|
+
success: this.data.success,
|
|
621
|
+
error_type: this.data.errorType ?? null
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
};
|
|
625
|
+
ServerPromptCallEvent = class extends BaseTelemetryEvent {
|
|
626
|
+
constructor(data) {
|
|
627
|
+
super();
|
|
628
|
+
this.data = data;
|
|
629
|
+
}
|
|
630
|
+
static {
|
|
631
|
+
__name(this, "ServerPromptCallEvent");
|
|
632
|
+
}
|
|
633
|
+
get name() {
|
|
634
|
+
return "server_prompt_call";
|
|
635
|
+
}
|
|
636
|
+
get properties() {
|
|
637
|
+
return {
|
|
638
|
+
name: this.data.name,
|
|
639
|
+
description: this.data.description,
|
|
640
|
+
success: this.data.success,
|
|
641
|
+
error_type: this.data.errorType ?? null
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
};
|
|
645
|
+
ServerContextEvent = class extends BaseTelemetryEvent {
|
|
646
|
+
constructor(data) {
|
|
647
|
+
super();
|
|
648
|
+
this.data = data;
|
|
649
|
+
}
|
|
650
|
+
static {
|
|
651
|
+
__name(this, "ServerContextEvent");
|
|
652
|
+
}
|
|
653
|
+
get name() {
|
|
654
|
+
return `server_context_${this.data.contextType}`;
|
|
655
|
+
}
|
|
656
|
+
get properties() {
|
|
657
|
+
return {
|
|
658
|
+
context_type: this.data.contextType,
|
|
659
|
+
notification_type: this.data.notificationType ?? null
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
};
|
|
663
|
+
MCPClientInitEvent = class extends BaseTelemetryEvent {
|
|
664
|
+
constructor(data) {
|
|
665
|
+
super();
|
|
666
|
+
this.data = data;
|
|
667
|
+
}
|
|
668
|
+
static {
|
|
669
|
+
__name(this, "MCPClientInitEvent");
|
|
670
|
+
}
|
|
671
|
+
get name() {
|
|
672
|
+
return "mcpclient_init";
|
|
673
|
+
}
|
|
674
|
+
get properties() {
|
|
675
|
+
return {
|
|
676
|
+
code_mode: this.data.codeMode,
|
|
677
|
+
sandbox: this.data.sandbox,
|
|
678
|
+
all_callbacks: this.data.allCallbacks,
|
|
679
|
+
verify: this.data.verify,
|
|
680
|
+
servers: this.data.servers,
|
|
681
|
+
num_servers: this.data.numServers
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
};
|
|
685
|
+
ConnectorInitEvent = class extends BaseTelemetryEvent {
|
|
686
|
+
constructor(data) {
|
|
687
|
+
super();
|
|
688
|
+
this.data = data;
|
|
689
|
+
}
|
|
690
|
+
static {
|
|
691
|
+
__name(this, "ConnectorInitEvent");
|
|
692
|
+
}
|
|
693
|
+
get name() {
|
|
694
|
+
return "connector_init";
|
|
695
|
+
}
|
|
696
|
+
get properties() {
|
|
697
|
+
return {
|
|
698
|
+
connector_type: this.data.connectorType,
|
|
699
|
+
server_command: this.data.serverCommand ?? null,
|
|
700
|
+
server_args: this.data.serverArgs ?? null,
|
|
701
|
+
server_url: this.data.serverUrl ?? null,
|
|
702
|
+
public_identifier: this.data.publicIdentifier ?? null
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
// src/version.ts
|
|
710
|
+
function getPackageVersion() {
|
|
711
|
+
return VERSION;
|
|
712
|
+
}
|
|
713
|
+
var VERSION;
|
|
714
|
+
var init_version = __esm({
|
|
715
|
+
"src/version.ts"() {
|
|
716
|
+
"use strict";
|
|
717
|
+
VERSION = "1.10.0-canary.10";
|
|
718
|
+
__name(getPackageVersion, "getPackageVersion");
|
|
719
|
+
}
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
// src/telemetry/utils.ts
|
|
723
|
+
var init_utils = __esm({
|
|
724
|
+
"src/telemetry/utils.ts"() {
|
|
725
|
+
"use strict";
|
|
726
|
+
init_version();
|
|
727
|
+
}
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
// src/telemetry/telemetry.ts
|
|
731
|
+
function detectRuntimeEnvironment() {
|
|
732
|
+
try {
|
|
733
|
+
if (typeof globalThis.Bun !== "undefined") {
|
|
734
|
+
return "bun";
|
|
735
|
+
}
|
|
736
|
+
if (typeof globalThis.Deno !== "undefined") {
|
|
737
|
+
return "deno";
|
|
738
|
+
}
|
|
739
|
+
if (typeof navigator !== "undefined" && navigator.userAgent?.includes("Cloudflare-Workers")) {
|
|
740
|
+
return "cloudflare-workers";
|
|
741
|
+
}
|
|
742
|
+
if (typeof globalThis.EdgeRuntime !== "undefined") {
|
|
743
|
+
return "edge";
|
|
744
|
+
}
|
|
745
|
+
if (typeof process !== "undefined" && typeof process.versions?.node !== "undefined" && typeof fs !== "undefined" && typeof fs.existsSync === "function") {
|
|
746
|
+
return "node";
|
|
747
|
+
}
|
|
748
|
+
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
|
749
|
+
return "browser";
|
|
750
|
+
}
|
|
751
|
+
return "unknown";
|
|
752
|
+
} catch {
|
|
753
|
+
return "unknown";
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
function getStorageCapability(env) {
|
|
757
|
+
switch (env) {
|
|
758
|
+
case "node":
|
|
759
|
+
case "bun":
|
|
760
|
+
return "filesystem";
|
|
761
|
+
case "browser":
|
|
762
|
+
try {
|
|
763
|
+
if (typeof localStorage !== "undefined") {
|
|
764
|
+
localStorage.setItem("__mcp_use_test__", "1");
|
|
765
|
+
localStorage.removeItem("__mcp_use_test__");
|
|
766
|
+
return "localStorage";
|
|
767
|
+
}
|
|
768
|
+
} catch {
|
|
769
|
+
}
|
|
770
|
+
return "session-only";
|
|
771
|
+
case "deno":
|
|
772
|
+
return "session-only";
|
|
773
|
+
default:
|
|
774
|
+
return "session-only";
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
function getRuntimeEnvironment() {
|
|
778
|
+
if (cachedEnvironment === null) {
|
|
779
|
+
cachedEnvironment = detectRuntimeEnvironment();
|
|
780
|
+
}
|
|
781
|
+
return cachedEnvironment;
|
|
782
|
+
}
|
|
783
|
+
function isNodeJSEnvironment2() {
|
|
784
|
+
const env = getRuntimeEnvironment();
|
|
785
|
+
return env === "node" || env === "bun";
|
|
786
|
+
}
|
|
787
|
+
function getCacheHome() {
|
|
788
|
+
if (!isNodeJSEnvironment2()) {
|
|
789
|
+
return "/tmp/mcp_use_cache";
|
|
790
|
+
}
|
|
791
|
+
const envVar = process.env.XDG_CACHE_HOME;
|
|
792
|
+
if (envVar && path.isAbsolute(envVar)) {
|
|
793
|
+
return envVar;
|
|
794
|
+
}
|
|
795
|
+
const platform = process.platform;
|
|
796
|
+
const homeDir = os.homedir();
|
|
797
|
+
if (platform === "win32") {
|
|
798
|
+
const appdata = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
799
|
+
if (appdata) {
|
|
800
|
+
return appdata;
|
|
801
|
+
}
|
|
802
|
+
return path.join(homeDir, "AppData", "Local");
|
|
803
|
+
} else if (platform === "darwin") {
|
|
804
|
+
return path.join(homeDir, "Library", "Caches");
|
|
805
|
+
} else {
|
|
806
|
+
return path.join(homeDir, ".cache");
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
var fs, os, path, import_posthog_node, USER_ID_STORAGE_KEY, cachedEnvironment, ScarfEventLogger, Telemetry;
|
|
810
|
+
var init_telemetry = __esm({
|
|
811
|
+
"src/telemetry/telemetry.ts"() {
|
|
812
|
+
"use strict";
|
|
813
|
+
fs = __toESM(require("fs"), 1);
|
|
814
|
+
os = __toESM(require("os"), 1);
|
|
815
|
+
path = __toESM(require("path"), 1);
|
|
816
|
+
import_posthog_node = require("posthog-node");
|
|
817
|
+
init_runtime();
|
|
818
|
+
init_logging();
|
|
819
|
+
init_events();
|
|
820
|
+
init_utils();
|
|
821
|
+
USER_ID_STORAGE_KEY = "mcp_use_user_id";
|
|
822
|
+
__name(detectRuntimeEnvironment, "detectRuntimeEnvironment");
|
|
823
|
+
__name(getStorageCapability, "getStorageCapability");
|
|
824
|
+
cachedEnvironment = null;
|
|
825
|
+
__name(getRuntimeEnvironment, "getRuntimeEnvironment");
|
|
826
|
+
__name(isNodeJSEnvironment2, "isNodeJSEnvironment");
|
|
827
|
+
ScarfEventLogger = class {
|
|
828
|
+
static {
|
|
829
|
+
__name(this, "ScarfEventLogger");
|
|
830
|
+
}
|
|
831
|
+
endpoint;
|
|
832
|
+
timeout;
|
|
833
|
+
constructor(endpoint, timeout = 3e3) {
|
|
834
|
+
this.endpoint = endpoint;
|
|
835
|
+
this.timeout = timeout;
|
|
836
|
+
}
|
|
837
|
+
async logEvent(properties) {
|
|
838
|
+
try {
|
|
839
|
+
const controller = new AbortController();
|
|
840
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
841
|
+
const response = await fetch(this.endpoint, {
|
|
842
|
+
method: "POST",
|
|
843
|
+
headers: {
|
|
844
|
+
"Content-Type": "application/json"
|
|
845
|
+
},
|
|
846
|
+
body: JSON.stringify(properties),
|
|
847
|
+
signal: controller.signal
|
|
848
|
+
});
|
|
849
|
+
clearTimeout(timeoutId);
|
|
850
|
+
if (!response.ok) {
|
|
851
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
852
|
+
}
|
|
853
|
+
} catch (error2) {
|
|
854
|
+
logger.debug(`Failed to send Scarf event: ${error2}`);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
};
|
|
858
|
+
__name(getCacheHome, "getCacheHome");
|
|
859
|
+
Telemetry = class _Telemetry {
|
|
860
|
+
static {
|
|
861
|
+
__name(this, "Telemetry");
|
|
862
|
+
}
|
|
863
|
+
static instance = null;
|
|
864
|
+
USER_ID_PATH = path.join(
|
|
865
|
+
getCacheHome(),
|
|
866
|
+
"mcp_use_3",
|
|
867
|
+
"telemetry_user_id"
|
|
868
|
+
);
|
|
869
|
+
VERSION_DOWNLOAD_PATH = path.join(
|
|
870
|
+
getCacheHome(),
|
|
871
|
+
"mcp_use",
|
|
872
|
+
"download_version"
|
|
873
|
+
);
|
|
874
|
+
PROJECT_API_KEY = "phc_lyTtbYwvkdSbrcMQNPiKiiRWrrM1seyKIMjycSvItEI";
|
|
875
|
+
HOST = "https://eu.i.posthog.com";
|
|
876
|
+
SCARF_GATEWAY_URL = "https://mcpuse.gateway.scarf.sh/events-ts";
|
|
877
|
+
UNKNOWN_USER_ID = "UNKNOWN_USER_ID";
|
|
878
|
+
_currUserId = null;
|
|
879
|
+
_posthogClient = null;
|
|
880
|
+
_scarfClient = null;
|
|
881
|
+
_runtimeEnvironment;
|
|
882
|
+
_storageCapability;
|
|
883
|
+
_source;
|
|
884
|
+
constructor() {
|
|
885
|
+
this._runtimeEnvironment = getRuntimeEnvironment();
|
|
886
|
+
this._storageCapability = getStorageCapability(this._runtimeEnvironment);
|
|
887
|
+
this._source = typeof process !== "undefined" && process.env?.MCP_USE_TELEMETRY_SOURCE || this._runtimeEnvironment;
|
|
888
|
+
const telemetryDisabled = typeof process !== "undefined" && process.env?.MCP_USE_ANONYMIZED_TELEMETRY?.toLowerCase() === "false" || false;
|
|
889
|
+
const canSupportTelemetry = this._runtimeEnvironment !== "unknown";
|
|
890
|
+
const isServerlessEnvironment = [
|
|
891
|
+
"cloudflare-workers",
|
|
892
|
+
"edge",
|
|
893
|
+
"deno"
|
|
894
|
+
].includes(this._runtimeEnvironment);
|
|
895
|
+
if (telemetryDisabled) {
|
|
896
|
+
this._posthogClient = null;
|
|
897
|
+
this._scarfClient = null;
|
|
898
|
+
logger.debug("Telemetry disabled via environment variable");
|
|
899
|
+
} else if (!canSupportTelemetry) {
|
|
900
|
+
this._posthogClient = null;
|
|
901
|
+
this._scarfClient = null;
|
|
902
|
+
logger.debug(
|
|
903
|
+
`Telemetry disabled - unknown environment: ${this._runtimeEnvironment}`
|
|
904
|
+
);
|
|
905
|
+
} else {
|
|
906
|
+
logger.info(
|
|
907
|
+
"Anonymized telemetry enabled. Set MCP_USE_ANONYMIZED_TELEMETRY=false to disable."
|
|
908
|
+
);
|
|
909
|
+
if (this._runtimeEnvironment !== "browser") {
|
|
910
|
+
try {
|
|
911
|
+
const posthogOptions = {
|
|
912
|
+
host: this.HOST,
|
|
913
|
+
disableGeoip: false
|
|
914
|
+
};
|
|
915
|
+
if (isServerlessEnvironment) {
|
|
916
|
+
posthogOptions.flushAt = 1;
|
|
917
|
+
posthogOptions.flushInterval = 0;
|
|
918
|
+
}
|
|
919
|
+
this._posthogClient = new import_posthog_node.PostHog(
|
|
920
|
+
this.PROJECT_API_KEY,
|
|
921
|
+
posthogOptions
|
|
922
|
+
);
|
|
923
|
+
} catch (e) {
|
|
924
|
+
logger.warn(`Failed to initialize PostHog telemetry: ${e}`);
|
|
925
|
+
this._posthogClient = null;
|
|
926
|
+
}
|
|
927
|
+
} else {
|
|
928
|
+
this._posthogClient = null;
|
|
929
|
+
}
|
|
930
|
+
try {
|
|
931
|
+
this._scarfClient = new ScarfEventLogger(this.SCARF_GATEWAY_URL, 3e3);
|
|
932
|
+
} catch (e) {
|
|
933
|
+
logger.warn(`Failed to initialize Scarf telemetry: ${e}`);
|
|
934
|
+
this._scarfClient = null;
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
/**
|
|
939
|
+
* Get the detected runtime environment
|
|
940
|
+
*/
|
|
941
|
+
get runtimeEnvironment() {
|
|
942
|
+
return this._runtimeEnvironment;
|
|
943
|
+
}
|
|
944
|
+
/**
|
|
945
|
+
* Get the storage capability for this environment
|
|
946
|
+
*/
|
|
947
|
+
get storageCapability() {
|
|
948
|
+
return this._storageCapability;
|
|
949
|
+
}
|
|
950
|
+
static getInstance() {
|
|
951
|
+
if (!_Telemetry.instance) {
|
|
952
|
+
_Telemetry.instance = new _Telemetry();
|
|
953
|
+
}
|
|
954
|
+
return _Telemetry.instance;
|
|
955
|
+
}
|
|
956
|
+
/**
|
|
957
|
+
* Set the source identifier for telemetry events.
|
|
958
|
+
* This allows tracking usage from different applications.
|
|
959
|
+
* @param source - The source identifier (e.g., "my-app", "cli", "vs-code-extension")
|
|
960
|
+
*/
|
|
961
|
+
setSource(source) {
|
|
962
|
+
this._source = source;
|
|
963
|
+
logger.debug(`Telemetry source set to: ${source}`);
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* Get the current source identifier.
|
|
967
|
+
*/
|
|
968
|
+
getSource() {
|
|
969
|
+
return this._source;
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* Check if telemetry is enabled.
|
|
973
|
+
* Returns false if telemetry was disabled via environment variable or if not in Node.js environment.
|
|
974
|
+
*/
|
|
975
|
+
get isEnabled() {
|
|
976
|
+
return this._posthogClient !== null || this._scarfClient !== null;
|
|
977
|
+
}
|
|
978
|
+
get userId() {
|
|
979
|
+
if (this._currUserId) {
|
|
980
|
+
return this._currUserId;
|
|
981
|
+
}
|
|
982
|
+
try {
|
|
983
|
+
switch (this._storageCapability) {
|
|
984
|
+
case "filesystem":
|
|
985
|
+
this._currUserId = this.getUserIdFromFilesystem();
|
|
986
|
+
break;
|
|
987
|
+
case "localStorage":
|
|
988
|
+
this._currUserId = this.getUserIdFromLocalStorage();
|
|
989
|
+
break;
|
|
990
|
+
case "session-only":
|
|
991
|
+
default:
|
|
992
|
+
this._currUserId = `session-${generateUUID()}`;
|
|
993
|
+
logger.debug(
|
|
994
|
+
`Using session-based user ID (${this._runtimeEnvironment} environment)`
|
|
995
|
+
);
|
|
996
|
+
break;
|
|
997
|
+
}
|
|
998
|
+
if (this._storageCapability === "filesystem" && this._currUserId) {
|
|
999
|
+
this.trackPackageDownloadInternal(this._currUserId, {
|
|
1000
|
+
triggered_by: "user_id_property"
|
|
1001
|
+
}).catch((e) => logger.debug(`Failed to track package download: ${e}`));
|
|
1002
|
+
}
|
|
1003
|
+
} catch (e) {
|
|
1004
|
+
logger.debug(`Failed to get/create user ID: ${e}`);
|
|
1005
|
+
this._currUserId = this.UNKNOWN_USER_ID;
|
|
1006
|
+
}
|
|
1007
|
+
return this._currUserId;
|
|
1008
|
+
}
|
|
1009
|
+
/**
|
|
1010
|
+
* Get or create user ID from filesystem (Node.js/Bun)
|
|
1011
|
+
*/
|
|
1012
|
+
getUserIdFromFilesystem() {
|
|
1013
|
+
const isFirstTime = !fs.existsSync(this.USER_ID_PATH);
|
|
1014
|
+
if (isFirstTime) {
|
|
1015
|
+
logger.debug(`Creating user ID path: ${this.USER_ID_PATH}`);
|
|
1016
|
+
fs.mkdirSync(path.dirname(this.USER_ID_PATH), { recursive: true });
|
|
1017
|
+
const newUserId = generateUUID();
|
|
1018
|
+
fs.writeFileSync(this.USER_ID_PATH, newUserId);
|
|
1019
|
+
logger.debug(`User ID path created: ${this.USER_ID_PATH}`);
|
|
1020
|
+
return newUserId;
|
|
1021
|
+
}
|
|
1022
|
+
return fs.readFileSync(this.USER_ID_PATH, "utf-8").trim();
|
|
1023
|
+
}
|
|
1024
|
+
/**
|
|
1025
|
+
* Get or create user ID from localStorage (Browser)
|
|
1026
|
+
*/
|
|
1027
|
+
getUserIdFromLocalStorage() {
|
|
1028
|
+
try {
|
|
1029
|
+
let userId = localStorage.getItem(USER_ID_STORAGE_KEY);
|
|
1030
|
+
if (!userId) {
|
|
1031
|
+
userId = generateUUID();
|
|
1032
|
+
localStorage.setItem(USER_ID_STORAGE_KEY, userId);
|
|
1033
|
+
logger.debug(`Created new browser user ID`);
|
|
1034
|
+
}
|
|
1035
|
+
return userId;
|
|
1036
|
+
} catch (e) {
|
|
1037
|
+
logger.debug(`localStorage access failed: ${e}`);
|
|
1038
|
+
return `session-${generateUUID()}`;
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
async capture(event) {
|
|
1042
|
+
logger.debug(
|
|
1043
|
+
`CAPTURE: posthog: ${this._posthogClient !== null}, scarf: ${this._scarfClient !== null}`
|
|
1044
|
+
);
|
|
1045
|
+
if (!this._posthogClient && !this._scarfClient) {
|
|
1046
|
+
return;
|
|
1047
|
+
}
|
|
1048
|
+
if (this._posthogClient) {
|
|
1049
|
+
try {
|
|
1050
|
+
const properties = { ...event.properties };
|
|
1051
|
+
properties.mcp_use_version = getPackageVersion();
|
|
1052
|
+
properties.language = "typescript";
|
|
1053
|
+
properties.source = this._source;
|
|
1054
|
+
properties.runtime = this._runtimeEnvironment;
|
|
1055
|
+
logger.debug(`CAPTURE: PostHog Event ${event.name}`);
|
|
1056
|
+
logger.debug(
|
|
1057
|
+
`CAPTURE: PostHog Properties ${JSON.stringify(properties)}`
|
|
1058
|
+
);
|
|
1059
|
+
this._posthogClient.capture({
|
|
1060
|
+
distinctId: this.userId,
|
|
1061
|
+
event: event.name,
|
|
1062
|
+
properties
|
|
1063
|
+
});
|
|
1064
|
+
} catch (e) {
|
|
1065
|
+
logger.debug(`Failed to track PostHog event ${event.name}: ${e}`);
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
if (this._scarfClient) {
|
|
1069
|
+
try {
|
|
1070
|
+
const properties = {};
|
|
1071
|
+
properties.mcp_use_version = getPackageVersion();
|
|
1072
|
+
properties.user_id = this.userId;
|
|
1073
|
+
properties.event = event.name;
|
|
1074
|
+
properties.language = "typescript";
|
|
1075
|
+
properties.source = this._source;
|
|
1076
|
+
properties.runtime = this._runtimeEnvironment;
|
|
1077
|
+
await this._scarfClient.logEvent(properties);
|
|
1078
|
+
} catch (e) {
|
|
1079
|
+
logger.debug(`Failed to track Scarf event ${event.name}: ${e}`);
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
/**
|
|
1084
|
+
* Track package download event.
|
|
1085
|
+
* This is a public wrapper that safely accesses userId.
|
|
1086
|
+
*/
|
|
1087
|
+
async trackPackageDownload(properties) {
|
|
1088
|
+
return this.trackPackageDownloadInternal(this.userId, properties);
|
|
1089
|
+
}
|
|
1090
|
+
/**
|
|
1091
|
+
* Internal method to track package download with explicit userId.
|
|
1092
|
+
* This avoids circular dependency when called from the userId getter.
|
|
1093
|
+
*/
|
|
1094
|
+
async trackPackageDownloadInternal(userId, properties) {
|
|
1095
|
+
if (!this._scarfClient) {
|
|
1096
|
+
return;
|
|
1097
|
+
}
|
|
1098
|
+
if (this._storageCapability !== "filesystem") {
|
|
1099
|
+
return;
|
|
1100
|
+
}
|
|
1101
|
+
try {
|
|
1102
|
+
const currentVersion = getPackageVersion();
|
|
1103
|
+
let shouldTrack = false;
|
|
1104
|
+
let firstDownload = false;
|
|
1105
|
+
if (!fs.existsSync(this.VERSION_DOWNLOAD_PATH)) {
|
|
1106
|
+
shouldTrack = true;
|
|
1107
|
+
firstDownload = true;
|
|
1108
|
+
fs.mkdirSync(path.dirname(this.VERSION_DOWNLOAD_PATH), {
|
|
1109
|
+
recursive: true
|
|
1110
|
+
});
|
|
1111
|
+
fs.writeFileSync(this.VERSION_DOWNLOAD_PATH, currentVersion);
|
|
1112
|
+
} else {
|
|
1113
|
+
const savedVersion = fs.readFileSync(this.VERSION_DOWNLOAD_PATH, "utf-8").trim();
|
|
1114
|
+
if (currentVersion > savedVersion) {
|
|
1115
|
+
shouldTrack = true;
|
|
1116
|
+
firstDownload = false;
|
|
1117
|
+
fs.writeFileSync(this.VERSION_DOWNLOAD_PATH, currentVersion);
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
if (shouldTrack) {
|
|
1121
|
+
logger.debug(
|
|
1122
|
+
`Tracking package download event with properties: ${JSON.stringify(properties)}`
|
|
1123
|
+
);
|
|
1124
|
+
const eventProperties = { ...properties || {} };
|
|
1125
|
+
eventProperties.mcp_use_version = currentVersion;
|
|
1126
|
+
eventProperties.user_id = userId;
|
|
1127
|
+
eventProperties.event = "package_download";
|
|
1128
|
+
eventProperties.first_download = firstDownload;
|
|
1129
|
+
eventProperties.language = "typescript";
|
|
1130
|
+
eventProperties.source = this._source;
|
|
1131
|
+
eventProperties.runtime = this._runtimeEnvironment;
|
|
1132
|
+
await this._scarfClient.logEvent(eventProperties);
|
|
1133
|
+
}
|
|
1134
|
+
} catch (e) {
|
|
1135
|
+
logger.debug(`Failed to track Scarf package_download event: ${e}`);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
// ============================================================================
|
|
1139
|
+
// Agent Events
|
|
1140
|
+
// ============================================================================
|
|
1141
|
+
async trackAgentExecution(data) {
|
|
1142
|
+
if (!this.isEnabled) return;
|
|
1143
|
+
const event = new MCPAgentExecutionEvent(data);
|
|
1144
|
+
await this.capture(event);
|
|
1145
|
+
}
|
|
1146
|
+
// ============================================================================
|
|
1147
|
+
// Server Events
|
|
1148
|
+
// ============================================================================
|
|
1149
|
+
/**
|
|
1150
|
+
* Track server run event directly from an MCPServer instance.
|
|
1151
|
+
* This extracts the necessary data from the server and creates the event.
|
|
1152
|
+
* @param server - The MCPServer instance (or any object conforming to MCPServerTelemetryInfo)
|
|
1153
|
+
* @param transport - The transport type (e.g., "http", "stdio", "supabase")
|
|
1154
|
+
*/
|
|
1155
|
+
async trackServerRunFromServer(server, transport) {
|
|
1156
|
+
if (!this.isEnabled) return;
|
|
1157
|
+
const data = createServerRunEventData(server, transport);
|
|
1158
|
+
const event = new ServerRunEvent(data);
|
|
1159
|
+
await this.capture(event);
|
|
1160
|
+
}
|
|
1161
|
+
async trackServerInitialize(data) {
|
|
1162
|
+
if (!this.isEnabled) return;
|
|
1163
|
+
const event = new ServerInitializeEvent(data);
|
|
1164
|
+
await this.capture(event);
|
|
1165
|
+
}
|
|
1166
|
+
async trackServerToolCall(data) {
|
|
1167
|
+
if (!this.isEnabled) return;
|
|
1168
|
+
const event = new ServerToolCallEvent(data);
|
|
1169
|
+
await this.capture(event);
|
|
1170
|
+
}
|
|
1171
|
+
async trackServerResourceCall(data) {
|
|
1172
|
+
if (!this.isEnabled) return;
|
|
1173
|
+
const event = new ServerResourceCallEvent(data);
|
|
1174
|
+
await this.capture(event);
|
|
1175
|
+
}
|
|
1176
|
+
async trackServerPromptCall(data) {
|
|
1177
|
+
if (!this.isEnabled) return;
|
|
1178
|
+
const event = new ServerPromptCallEvent(data);
|
|
1179
|
+
await this.capture(event);
|
|
1180
|
+
}
|
|
1181
|
+
async trackServerContext(data) {
|
|
1182
|
+
if (!this.isEnabled) return;
|
|
1183
|
+
const event = new ServerContextEvent(data);
|
|
1184
|
+
await this.capture(event);
|
|
1185
|
+
}
|
|
1186
|
+
// ============================================================================
|
|
1187
|
+
// Client Events
|
|
1188
|
+
// ============================================================================
|
|
1189
|
+
async trackMCPClientInit(data) {
|
|
1190
|
+
if (!this.isEnabled) return;
|
|
1191
|
+
const event = new MCPClientInitEvent(data);
|
|
1192
|
+
await this.capture(event);
|
|
1193
|
+
}
|
|
1194
|
+
async trackConnectorInit(data) {
|
|
1195
|
+
if (!this.isEnabled) return;
|
|
1196
|
+
const event = new ConnectorInitEvent(data);
|
|
1197
|
+
await this.capture(event);
|
|
1198
|
+
}
|
|
1199
|
+
flush() {
|
|
1200
|
+
if (this._posthogClient) {
|
|
1201
|
+
try {
|
|
1202
|
+
this._posthogClient.flush();
|
|
1203
|
+
logger.debug("PostHog client telemetry queue flushed");
|
|
1204
|
+
} catch (e) {
|
|
1205
|
+
logger.debug(`Failed to flush PostHog client: ${e}`);
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
if (this._scarfClient) {
|
|
1209
|
+
logger.debug("Scarf telemetry events sent immediately (no flush needed)");
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
shutdown() {
|
|
1213
|
+
if (this._posthogClient) {
|
|
1214
|
+
try {
|
|
1215
|
+
this._posthogClient.shutdown();
|
|
1216
|
+
logger.debug("PostHog client shutdown successfully");
|
|
1217
|
+
} catch (e) {
|
|
1218
|
+
logger.debug(`Error shutting down PostHog client: ${e}`);
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
if (this._scarfClient) {
|
|
1222
|
+
logger.debug("Scarf telemetry client shutdown (no action needed)");
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
};
|
|
1226
|
+
}
|
|
1227
|
+
});
|
|
1228
|
+
|
|
1229
|
+
// src/telemetry/index.ts
|
|
1230
|
+
var init_telemetry2 = __esm({
|
|
1231
|
+
"src/telemetry/index.ts"() {
|
|
1232
|
+
"use strict";
|
|
1233
|
+
init_telemetry();
|
|
1234
|
+
init_events();
|
|
1235
|
+
init_telemetry();
|
|
1236
|
+
init_utils();
|
|
1237
|
+
}
|
|
1238
|
+
});
|
|
1239
|
+
|
|
125
1240
|
// src/server/context-storage.ts
|
|
126
1241
|
var context_storage_exports = {};
|
|
127
1242
|
__export(context_storage_exports, {
|
|
128
1243
|
getRequestContext: () => getRequestContext,
|
|
1244
|
+
getSessionId: () => getSessionId,
|
|
129
1245
|
hasRequestContext: () => hasRequestContext,
|
|
130
1246
|
runWithContext: () => runWithContext
|
|
131
1247
|
});
|
|
132
|
-
async function runWithContext(context, fn) {
|
|
133
|
-
return requestContextStorage.run(context, fn);
|
|
1248
|
+
async function runWithContext(context, fn, sessionId) {
|
|
1249
|
+
return requestContextStorage.run({ honoContext: context, sessionId }, fn);
|
|
134
1250
|
}
|
|
135
1251
|
function getRequestContext() {
|
|
136
|
-
return requestContextStorage.getStore();
|
|
1252
|
+
return requestContextStorage.getStore()?.honoContext;
|
|
1253
|
+
}
|
|
1254
|
+
function getSessionId() {
|
|
1255
|
+
return requestContextStorage.getStore()?.sessionId;
|
|
137
1256
|
}
|
|
138
1257
|
function hasRequestContext() {
|
|
139
1258
|
return requestContextStorage.getStore() !== void 0;
|
|
@@ -146,6 +1265,7 @@ var init_context_storage = __esm({
|
|
|
146
1265
|
requestContextStorage = new import_node_async_hooks.AsyncLocalStorage();
|
|
147
1266
|
__name(runWithContext, "runWithContext");
|
|
148
1267
|
__name(getRequestContext, "getRequestContext");
|
|
1268
|
+
__name(getSessionId, "getSessionId");
|
|
149
1269
|
__name(hasRequestContext, "hasRequestContext");
|
|
150
1270
|
}
|
|
151
1271
|
});
|
|
@@ -174,13 +1294,16 @@ var init_errors = __esm({
|
|
|
174
1294
|
// src/server/tools/tool-execution-helpers.ts
|
|
175
1295
|
var tool_execution_helpers_exports = {};
|
|
176
1296
|
__export(tool_execution_helpers_exports, {
|
|
1297
|
+
VALID_LOG_LEVELS: () => VALID_LOG_LEVELS,
|
|
177
1298
|
createElicitMethod: () => createElicitMethod,
|
|
178
1299
|
createEnhancedContext: () => createEnhancedContext,
|
|
179
1300
|
createReportProgressMethod: () => createReportProgressMethod,
|
|
180
1301
|
createSampleMethod: () => createSampleMethod,
|
|
181
1302
|
findSessionContext: () => findSessionContext,
|
|
1303
|
+
isValidLogLevel: () => isValidLogLevel,
|
|
182
1304
|
parseElicitParams: () => parseElicitParams,
|
|
183
1305
|
sendProgressNotification: () => sendProgressNotification,
|
|
1306
|
+
shouldLogMessage: () => shouldLogMessage,
|
|
184
1307
|
withTimeout: () => withTimeout
|
|
185
1308
|
});
|
|
186
1309
|
function findSessionContext(sessions, initialRequestContext, extraProgressToken, extraSendNotification) {
|
|
@@ -365,6 +1488,9 @@ function createSampleMethod(createMessage, progressToken, sendNotification2) {
|
|
|
365
1488
|
`Sampling timed out after ${timeout}ms`
|
|
366
1489
|
);
|
|
367
1490
|
console.log("[SAMPLING DEBUG] Got result:", result);
|
|
1491
|
+
Telemetry.getInstance().trackServerContext({
|
|
1492
|
+
contextType: "sample"
|
|
1493
|
+
}).catch((e) => console.debug(`Failed to track sample context: ${e}`));
|
|
368
1494
|
return result;
|
|
369
1495
|
} catch (error2) {
|
|
370
1496
|
console.error("[SAMPLING DEBUG] Error during sampling:", error2);
|
|
@@ -387,6 +1513,9 @@ function createElicitMethod(elicitInput) {
|
|
|
387
1513
|
const { timeout } = options ?? {};
|
|
388
1514
|
const sdkTimeout = timeout && timeout !== Infinity ? timeout : 2147483647;
|
|
389
1515
|
const result = await elicitInput(sdkParams, { timeout: sdkTimeout });
|
|
1516
|
+
Telemetry.getInstance().trackServerContext({
|
|
1517
|
+
contextType: "elicit"
|
|
1518
|
+
}).catch((e) => console.debug(`Failed to track elicit context: ${e}`));
|
|
390
1519
|
if (zodSchema && result.action === "accept" && result.data) {
|
|
391
1520
|
try {
|
|
392
1521
|
const validatedData = zodSchema.parse(result.data);
|
|
@@ -395,9 +1524,10 @@ function createElicitMethod(elicitInput) {
|
|
|
395
1524
|
data: validatedData
|
|
396
1525
|
};
|
|
397
1526
|
} catch (error2) {
|
|
1527
|
+
const err = error2;
|
|
398
1528
|
throw new ElicitationValidationError(
|
|
399
|
-
`Elicitation data validation failed: ${
|
|
400
|
-
|
|
1529
|
+
`Elicitation data validation failed: ${err.message}`,
|
|
1530
|
+
err
|
|
401
1531
|
);
|
|
402
1532
|
}
|
|
403
1533
|
}
|
|
@@ -418,7 +1548,103 @@ function createReportProgressMethod(progressToken, sendNotification2) {
|
|
|
418
1548
|
}
|
|
419
1549
|
return void 0;
|
|
420
1550
|
}
|
|
421
|
-
function
|
|
1551
|
+
function isValidLogLevel(level) {
|
|
1552
|
+
return VALID_LOG_LEVELS.includes(level);
|
|
1553
|
+
}
|
|
1554
|
+
function shouldLogMessage(messageLevel, minLevel) {
|
|
1555
|
+
if (!minLevel) {
|
|
1556
|
+
return true;
|
|
1557
|
+
}
|
|
1558
|
+
if (!isValidLogLevel(messageLevel) || !isValidLogLevel(minLevel)) {
|
|
1559
|
+
return true;
|
|
1560
|
+
}
|
|
1561
|
+
return LOG_LEVELS[messageLevel] >= LOG_LEVELS[minLevel];
|
|
1562
|
+
}
|
|
1563
|
+
function createLogMethod(sendNotification2, minLogLevel) {
|
|
1564
|
+
if (!sendNotification2) {
|
|
1565
|
+
return void 0;
|
|
1566
|
+
}
|
|
1567
|
+
return async (level, message, logger2) => {
|
|
1568
|
+
if (!shouldLogMessage(level, minLogLevel)) {
|
|
1569
|
+
return;
|
|
1570
|
+
}
|
|
1571
|
+
await sendNotification2({
|
|
1572
|
+
method: "notifications/message",
|
|
1573
|
+
params: {
|
|
1574
|
+
level,
|
|
1575
|
+
data: message,
|
|
1576
|
+
logger: logger2 || "tool"
|
|
1577
|
+
}
|
|
1578
|
+
});
|
|
1579
|
+
Telemetry.getInstance().trackServerContext({
|
|
1580
|
+
contextType: "notification",
|
|
1581
|
+
notificationType: "message"
|
|
1582
|
+
}).catch(
|
|
1583
|
+
(e) => console.debug(`Failed to track notification context: ${e}`)
|
|
1584
|
+
);
|
|
1585
|
+
};
|
|
1586
|
+
}
|
|
1587
|
+
function createClientCapabilityChecker(clientCapabilities) {
|
|
1588
|
+
const caps = clientCapabilities || {};
|
|
1589
|
+
return {
|
|
1590
|
+
can(capability) {
|
|
1591
|
+
return capability in caps;
|
|
1592
|
+
},
|
|
1593
|
+
capabilities() {
|
|
1594
|
+
return { ...caps };
|
|
1595
|
+
}
|
|
1596
|
+
};
|
|
1597
|
+
}
|
|
1598
|
+
function createSendNotificationMethod(sessionId, sessions) {
|
|
1599
|
+
if (!sessionId || !sessions) {
|
|
1600
|
+
return void 0;
|
|
1601
|
+
}
|
|
1602
|
+
return async (method, params) => {
|
|
1603
|
+
const session = sessions.get(sessionId);
|
|
1604
|
+
if (!session?.sendNotification) {
|
|
1605
|
+
console.warn(
|
|
1606
|
+
`[MCP] Cannot send notification to session ${sessionId} - no sendNotification function`
|
|
1607
|
+
);
|
|
1608
|
+
return;
|
|
1609
|
+
}
|
|
1610
|
+
try {
|
|
1611
|
+
await session.sendNotification({
|
|
1612
|
+
method,
|
|
1613
|
+
params: params || {}
|
|
1614
|
+
});
|
|
1615
|
+
} catch (error2) {
|
|
1616
|
+
console.error(
|
|
1617
|
+
`[MCP] Error sending notification to session ${sessionId}:`,
|
|
1618
|
+
error2
|
|
1619
|
+
);
|
|
1620
|
+
}
|
|
1621
|
+
};
|
|
1622
|
+
}
|
|
1623
|
+
function createSendNotificationToSessionMethod(sessions) {
|
|
1624
|
+
if (!sessions) {
|
|
1625
|
+
return void 0;
|
|
1626
|
+
}
|
|
1627
|
+
return async (sessionId, method, params) => {
|
|
1628
|
+
const session = sessions.get(sessionId);
|
|
1629
|
+
if (!session?.sendNotification) {
|
|
1630
|
+
return false;
|
|
1631
|
+
}
|
|
1632
|
+
try {
|
|
1633
|
+
await session.sendNotification({
|
|
1634
|
+
method,
|
|
1635
|
+
params: params || {}
|
|
1636
|
+
});
|
|
1637
|
+
return true;
|
|
1638
|
+
} catch (error2) {
|
|
1639
|
+
console.error(
|
|
1640
|
+
`[MCP] Error sending notification to session ${sessionId}:`,
|
|
1641
|
+
error2
|
|
1642
|
+
);
|
|
1643
|
+
return false;
|
|
1644
|
+
}
|
|
1645
|
+
};
|
|
1646
|
+
}
|
|
1647
|
+
function createEnhancedContext(baseContext, createMessage, elicitInput, progressToken, sendNotification2, minLogLevel, clientCapabilities, sessionId, sessions) {
|
|
422
1648
|
const enhancedContext = baseContext ? Object.create(baseContext) : {};
|
|
423
1649
|
enhancedContext.sample = createSampleMethod(
|
|
424
1650
|
createMessage,
|
|
@@ -430,15 +1656,34 @@ function createEnhancedContext(baseContext, createMessage, elicitInput, progress
|
|
|
430
1656
|
progressToken,
|
|
431
1657
|
sendNotification2
|
|
432
1658
|
);
|
|
1659
|
+
enhancedContext.log = createLogMethod(sendNotification2, minLogLevel);
|
|
1660
|
+
enhancedContext.client = createClientCapabilityChecker(clientCapabilities);
|
|
1661
|
+
if (sessionId) {
|
|
1662
|
+
enhancedContext.session = {
|
|
1663
|
+
sessionId
|
|
1664
|
+
};
|
|
1665
|
+
}
|
|
1666
|
+
const sendNotificationMethod = createSendNotificationMethod(
|
|
1667
|
+
sessionId,
|
|
1668
|
+
sessions
|
|
1669
|
+
);
|
|
1670
|
+
if (sendNotificationMethod) {
|
|
1671
|
+
enhancedContext.sendNotification = sendNotificationMethod;
|
|
1672
|
+
}
|
|
1673
|
+
const sendNotificationToSessionMethod = createSendNotificationToSessionMethod(sessions);
|
|
1674
|
+
if (sendNotificationToSessionMethod) {
|
|
1675
|
+
enhancedContext.sendNotificationToSession = sendNotificationToSessionMethod;
|
|
1676
|
+
}
|
|
433
1677
|
return enhancedContext;
|
|
434
1678
|
}
|
|
435
|
-
var import_zod_json_schema_compat;
|
|
1679
|
+
var import_zod_json_schema_compat, LOG_LEVELS, VALID_LOG_LEVELS;
|
|
436
1680
|
var init_tool_execution_helpers = __esm({
|
|
437
1681
|
"src/server/tools/tool-execution-helpers.ts"() {
|
|
438
1682
|
"use strict";
|
|
439
|
-
import_zod_json_schema_compat = require("@modelcontextprotocol
|
|
1683
|
+
import_zod_json_schema_compat = require("@mcp-use/modelcontextprotocol-sdk/server/zod-json-schema-compat.js");
|
|
440
1684
|
init_errors();
|
|
441
1685
|
init_runtime();
|
|
1686
|
+
init_telemetry2();
|
|
442
1687
|
__name(findSessionContext, "findSessionContext");
|
|
443
1688
|
__name(sendProgressNotification, "sendProgressNotification");
|
|
444
1689
|
__name(withTimeout, "withTimeout");
|
|
@@ -446,6 +1691,32 @@ var init_tool_execution_helpers = __esm({
|
|
|
446
1691
|
__name(createSampleMethod, "createSampleMethod");
|
|
447
1692
|
__name(createElicitMethod, "createElicitMethod");
|
|
448
1693
|
__name(createReportProgressMethod, "createReportProgressMethod");
|
|
1694
|
+
LOG_LEVELS = {
|
|
1695
|
+
debug: 0,
|
|
1696
|
+
info: 1,
|
|
1697
|
+
notice: 2,
|
|
1698
|
+
warning: 3,
|
|
1699
|
+
error: 4,
|
|
1700
|
+
critical: 5,
|
|
1701
|
+
alert: 6,
|
|
1702
|
+
emergency: 7
|
|
1703
|
+
};
|
|
1704
|
+
VALID_LOG_LEVELS = [
|
|
1705
|
+
"debug",
|
|
1706
|
+
"info",
|
|
1707
|
+
"notice",
|
|
1708
|
+
"warning",
|
|
1709
|
+
"error",
|
|
1710
|
+
"critical",
|
|
1711
|
+
"alert",
|
|
1712
|
+
"emergency"
|
|
1713
|
+
];
|
|
1714
|
+
__name(isValidLogLevel, "isValidLogLevel");
|
|
1715
|
+
__name(shouldLogMessage, "shouldLogMessage");
|
|
1716
|
+
__name(createLogMethod, "createLogMethod");
|
|
1717
|
+
__name(createClientCapabilityChecker, "createClientCapabilityChecker");
|
|
1718
|
+
__name(createSendNotificationMethod, "createSendNotificationMethod");
|
|
1719
|
+
__name(createSendNotificationToSessionMethod, "createSendNotificationToSessionMethod");
|
|
449
1720
|
__name(createEnhancedContext, "createEnhancedContext");
|
|
450
1721
|
}
|
|
451
1722
|
});
|
|
@@ -643,9 +1914,12 @@ var init_conversion2 = __esm({
|
|
|
643
1914
|
// src/server/index.ts
|
|
644
1915
|
var server_exports = {};
|
|
645
1916
|
__export(server_exports, {
|
|
1917
|
+
MCPServer: () => MCPServer,
|
|
1918
|
+
VERSION: () => VERSION,
|
|
646
1919
|
adaptConnectMiddleware: () => adaptConnectMiddleware,
|
|
647
1920
|
adaptMiddleware: () => adaptMiddleware,
|
|
648
1921
|
array: () => array,
|
|
1922
|
+
audio: () => audio,
|
|
649
1923
|
binary: () => binary,
|
|
650
1924
|
buildWidgetUrl: () => buildWidgetUrl,
|
|
651
1925
|
createExternalUrlResource: () => createExternalUrlResource,
|
|
@@ -656,6 +1930,7 @@ __export(server_exports, {
|
|
|
656
1930
|
css: () => css,
|
|
657
1931
|
error: () => error,
|
|
658
1932
|
getAuth: () => getAuth,
|
|
1933
|
+
getPackageVersion: () => getPackageVersion,
|
|
659
1934
|
getRequestContext: () => getRequestContext,
|
|
660
1935
|
hasAnyScope: () => hasAnyScope,
|
|
661
1936
|
hasRequestContext: () => hasRequestContext,
|
|
@@ -683,12 +1958,17 @@ __export(server_exports, {
|
|
|
683
1958
|
module.exports = __toCommonJS(server_exports);
|
|
684
1959
|
|
|
685
1960
|
// src/server/mcp-server.ts
|
|
686
|
-
var import_mcp2 = require("@modelcontextprotocol
|
|
1961
|
+
var import_mcp2 = require("@mcp-use/modelcontextprotocol-sdk/server/mcp.js");
|
|
1962
|
+
var import_types2 = require("@mcp-use/modelcontextprotocol-sdk/types.js");
|
|
1963
|
+
var import_zod2 = require("zod");
|
|
1964
|
+
init_telemetry2();
|
|
1965
|
+
init_version();
|
|
687
1966
|
|
|
688
1967
|
// src/server/widgets/index.ts
|
|
689
1968
|
init_runtime();
|
|
690
1969
|
|
|
691
1970
|
// src/server/utils/response-helpers.ts
|
|
1971
|
+
init_runtime();
|
|
692
1972
|
function text(content) {
|
|
693
1973
|
return {
|
|
694
1974
|
content: [
|
|
@@ -719,7 +1999,109 @@ function image(data, mimeType = "image/png") {
|
|
|
719
1999
|
};
|
|
720
2000
|
}
|
|
721
2001
|
__name(image, "image");
|
|
722
|
-
function
|
|
2002
|
+
function getAudioMimeType(filename) {
|
|
2003
|
+
const ext = filename.split(".").pop()?.toLowerCase();
|
|
2004
|
+
switch (ext) {
|
|
2005
|
+
case "wav":
|
|
2006
|
+
return "audio/wav";
|
|
2007
|
+
case "mp3":
|
|
2008
|
+
return "audio/mpeg";
|
|
2009
|
+
case "ogg":
|
|
2010
|
+
return "audio/ogg";
|
|
2011
|
+
case "m4a":
|
|
2012
|
+
return "audio/mp4";
|
|
2013
|
+
case "webm":
|
|
2014
|
+
return "audio/webm";
|
|
2015
|
+
case "flac":
|
|
2016
|
+
return "audio/flac";
|
|
2017
|
+
case "aac":
|
|
2018
|
+
return "audio/aac";
|
|
2019
|
+
default:
|
|
2020
|
+
return "audio/wav";
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
__name(getAudioMimeType, "getAudioMimeType");
|
|
2024
|
+
function arrayBufferToBase64(buffer) {
|
|
2025
|
+
if (isDeno) {
|
|
2026
|
+
const bytes = new Uint8Array(buffer);
|
|
2027
|
+
let binary2 = "";
|
|
2028
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
2029
|
+
binary2 += String.fromCharCode(bytes[i]);
|
|
2030
|
+
}
|
|
2031
|
+
return btoa(binary2);
|
|
2032
|
+
} else {
|
|
2033
|
+
return Buffer.from(buffer).toString("base64");
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
__name(arrayBufferToBase64, "arrayBufferToBase64");
|
|
2037
|
+
function audio(dataOrPath, mimeType) {
|
|
2038
|
+
const isFilePath = dataOrPath.includes("/") || dataOrPath.includes("\\") || dataOrPath.includes(".");
|
|
2039
|
+
if (isFilePath && dataOrPath.length < 1e3) {
|
|
2040
|
+
return (async () => {
|
|
2041
|
+
const buffer = await fsHelpers.readFile(dataOrPath);
|
|
2042
|
+
const base64Data = arrayBufferToBase64(buffer);
|
|
2043
|
+
const inferredMimeType = mimeType || getAudioMimeType(dataOrPath);
|
|
2044
|
+
return {
|
|
2045
|
+
content: [
|
|
2046
|
+
{
|
|
2047
|
+
type: "audio",
|
|
2048
|
+
data: base64Data,
|
|
2049
|
+
mimeType: inferredMimeType
|
|
2050
|
+
}
|
|
2051
|
+
],
|
|
2052
|
+
_meta: {
|
|
2053
|
+
mimeType: inferredMimeType,
|
|
2054
|
+
isAudio: true
|
|
2055
|
+
}
|
|
2056
|
+
};
|
|
2057
|
+
})();
|
|
2058
|
+
}
|
|
2059
|
+
const finalMimeType = mimeType || "audio/wav";
|
|
2060
|
+
return {
|
|
2061
|
+
content: [
|
|
2062
|
+
{
|
|
2063
|
+
type: "audio",
|
|
2064
|
+
data: dataOrPath,
|
|
2065
|
+
mimeType: finalMimeType
|
|
2066
|
+
}
|
|
2067
|
+
],
|
|
2068
|
+
_meta: {
|
|
2069
|
+
mimeType: finalMimeType,
|
|
2070
|
+
isAudio: true
|
|
2071
|
+
}
|
|
2072
|
+
};
|
|
2073
|
+
}
|
|
2074
|
+
__name(audio, "audio");
|
|
2075
|
+
function resource(uri, mimeTypeOrContent, text2) {
|
|
2076
|
+
if (typeof mimeTypeOrContent === "object" && mimeTypeOrContent !== null && "content" in mimeTypeOrContent) {
|
|
2077
|
+
const contentResult = mimeTypeOrContent;
|
|
2078
|
+
let extractedText;
|
|
2079
|
+
let extractedMimeType;
|
|
2080
|
+
if (contentResult._meta && typeof contentResult._meta === "object") {
|
|
2081
|
+
const meta = contentResult._meta;
|
|
2082
|
+
if (meta.mimeType && typeof meta.mimeType === "string") {
|
|
2083
|
+
extractedMimeType = meta.mimeType;
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
if (contentResult.content && contentResult.content.length > 0) {
|
|
2087
|
+
const firstContent = contentResult.content[0];
|
|
2088
|
+
if (firstContent.type === "text" && "text" in firstContent) {
|
|
2089
|
+
extractedText = firstContent.text;
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
2092
|
+
const resourceContent2 = {
|
|
2093
|
+
type: "resource",
|
|
2094
|
+
resource: {
|
|
2095
|
+
uri,
|
|
2096
|
+
...extractedMimeType && { mimeType: extractedMimeType },
|
|
2097
|
+
...extractedText && { text: extractedText }
|
|
2098
|
+
}
|
|
2099
|
+
};
|
|
2100
|
+
return {
|
|
2101
|
+
content: [resourceContent2]
|
|
2102
|
+
};
|
|
2103
|
+
}
|
|
2104
|
+
const mimeType = mimeTypeOrContent;
|
|
723
2105
|
const resourceContent = {
|
|
724
2106
|
type: "resource",
|
|
725
2107
|
resource: {
|
|
@@ -858,37 +2240,12 @@ function binary(base64Data, mimeType) {
|
|
|
858
2240
|
}
|
|
859
2241
|
__name(binary, "binary");
|
|
860
2242
|
function widget(config) {
|
|
861
|
-
const {
|
|
862
|
-
name,
|
|
863
|
-
data,
|
|
864
|
-
message,
|
|
865
|
-
invoking,
|
|
866
|
-
invoked,
|
|
867
|
-
widgetAccessible = true,
|
|
868
|
-
resultCanProduceWidget = true,
|
|
869
|
-
buildId
|
|
870
|
-
} = config;
|
|
871
|
-
const randomId = Math.random().toString(36).substring(2, 15);
|
|
872
|
-
const buildIdPart = buildId ? `-${buildId}` : "";
|
|
873
|
-
const uniqueUri = `ui://widget/${name}${buildIdPart}-${randomId}.html`;
|
|
874
|
-
const metadata = {
|
|
875
|
-
"openai/outputTemplate": uniqueUri,
|
|
876
|
-
"openai/widgetAccessible": widgetAccessible,
|
|
877
|
-
"openai/resultCanProduceWidget": resultCanProduceWidget
|
|
878
|
-
};
|
|
879
|
-
if (invoking) {
|
|
880
|
-
metadata["openai/toolInvocation/invoking"] = invoking;
|
|
881
|
-
}
|
|
882
|
-
if (invoked) {
|
|
883
|
-
metadata["openai/toolInvocation/invoked"] = invoked;
|
|
884
|
-
}
|
|
885
|
-
const displayMessage = message || `Displaying ${name}`;
|
|
2243
|
+
const { data, message } = config;
|
|
886
2244
|
return {
|
|
887
|
-
_meta: metadata,
|
|
888
2245
|
content: [
|
|
889
2246
|
{
|
|
890
2247
|
type: "text",
|
|
891
|
-
text:
|
|
2248
|
+
text: message || ""
|
|
892
2249
|
}
|
|
893
2250
|
],
|
|
894
2251
|
// structuredContent will be injected as window.openai.toolOutput by Apps SDK
|
|
@@ -998,7 +2355,7 @@ function parseTemplateUri(template, uri) {
|
|
|
998
2355
|
const params = {};
|
|
999
2356
|
let regexPattern = template.replace(/[.*+?^$()[\]\\|]/g, "\\$&");
|
|
1000
2357
|
const paramNames = [];
|
|
1001
|
-
regexPattern = regexPattern.replace(
|
|
2358
|
+
regexPattern = regexPattern.replace(/\{([^}]+)\}/g, (_, paramName) => {
|
|
1002
2359
|
paramNames.push(paramName);
|
|
1003
2360
|
return "([^/]+)";
|
|
1004
2361
|
});
|
|
@@ -1272,11 +2629,11 @@ function createHonoProxy(target, app) {
|
|
|
1272
2629
|
if (prop === "use") {
|
|
1273
2630
|
return async (...args) => {
|
|
1274
2631
|
const hasPath = typeof args[0] === "string";
|
|
1275
|
-
const
|
|
2632
|
+
const path2 = hasPath ? args[0] : "*";
|
|
1276
2633
|
const handlers = hasPath ? args.slice(1) : args;
|
|
1277
2634
|
const adaptedHandlers = handlers.map((handler) => {
|
|
1278
2635
|
if (isExpressMiddleware(handler)) {
|
|
1279
|
-
return { __isExpressMiddleware: true, handler, path };
|
|
2636
|
+
return { __isExpressMiddleware: true, handler, path: path2 };
|
|
1280
2637
|
}
|
|
1281
2638
|
return handler;
|
|
1282
2639
|
});
|
|
@@ -1292,13 +2649,13 @@ function createHonoProxy(target, app) {
|
|
|
1292
2649
|
h.path
|
|
1293
2650
|
);
|
|
1294
2651
|
if (hasPath) {
|
|
1295
|
-
app.use(
|
|
2652
|
+
app.use(path2, adapted);
|
|
1296
2653
|
} else {
|
|
1297
2654
|
app.use(adapted);
|
|
1298
2655
|
}
|
|
1299
2656
|
} else {
|
|
1300
2657
|
if (hasPath) {
|
|
1301
|
-
app.use(
|
|
2658
|
+
app.use(path2, h);
|
|
1302
2659
|
} else {
|
|
1303
2660
|
app.use(h);
|
|
1304
2661
|
}
|
|
@@ -1566,6 +2923,7 @@ function createWidgetRegistration(widgetName, metadata, html2, serverConfig, isD
|
|
|
1566
2923
|
const props = metadata.inputs || {};
|
|
1567
2924
|
const description = metadata.description || `Widget: ${widgetName}`;
|
|
1568
2925
|
const title = metadata.title || widgetName;
|
|
2926
|
+
const exposeAsTool = metadata.exposeAsTool !== void 0 ? metadata.exposeAsTool : true;
|
|
1569
2927
|
const mcp_connect_domain = serverConfig.serverBaseUrl ? new URL(serverConfig.serverBaseUrl || "").origin : null;
|
|
1570
2928
|
return {
|
|
1571
2929
|
name: widgetName,
|
|
@@ -1581,7 +2939,8 @@ function createWidgetRegistration(widgetName, metadata, html2, serverConfig, isD
|
|
|
1581
2939
|
type: "appsSdk",
|
|
1582
2940
|
props,
|
|
1583
2941
|
html: html2,
|
|
1584
|
-
dev: isDev
|
|
2942
|
+
dev: isDev,
|
|
2943
|
+
exposeAsTool
|
|
1585
2944
|
},
|
|
1586
2945
|
...metadata._meta || {}
|
|
1587
2946
|
},
|
|
@@ -1707,12 +3066,12 @@ __name(setupPublicRoutes, "setupPublicRoutes");
|
|
|
1707
3066
|
// src/server/widgets/mount-widgets-dev.ts
|
|
1708
3067
|
var TMP_MCP_USE_DIR = ".mcp-use";
|
|
1709
3068
|
async function mountWidgetsDev(app, serverConfig, registerWidget, options) {
|
|
1710
|
-
const { promises:
|
|
3069
|
+
const { promises: fs2 } = await import("fs");
|
|
1711
3070
|
const baseRoute = options?.baseRoute || "/mcp-use/widgets";
|
|
1712
3071
|
const resourcesDir = options?.resourcesDir || "resources";
|
|
1713
3072
|
const srcDir = pathHelpers.join(getCwd(), resourcesDir);
|
|
1714
3073
|
try {
|
|
1715
|
-
await
|
|
3074
|
+
await fs2.access(srcDir);
|
|
1716
3075
|
} catch (error2) {
|
|
1717
3076
|
console.log(
|
|
1718
3077
|
`[WIDGETS] No ${resourcesDir}/ directory found - skipping widget serving`
|
|
@@ -1721,7 +3080,7 @@ async function mountWidgetsDev(app, serverConfig, registerWidget, options) {
|
|
|
1721
3080
|
}
|
|
1722
3081
|
const entries = [];
|
|
1723
3082
|
try {
|
|
1724
|
-
const files = await
|
|
3083
|
+
const files = await fs2.readdir(srcDir, { withFileTypes: true });
|
|
1725
3084
|
for (const dirent of files) {
|
|
1726
3085
|
if (dirent.name.startsWith("._") || dirent.name.startsWith(".DS_Store")) {
|
|
1727
3086
|
continue;
|
|
@@ -1734,7 +3093,7 @@ async function mountWidgetsDev(app, serverConfig, registerWidget, options) {
|
|
|
1734
3093
|
} else if (dirent.isDirectory()) {
|
|
1735
3094
|
const widgetPath = pathHelpers.join(srcDir, dirent.name, "widget.tsx");
|
|
1736
3095
|
try {
|
|
1737
|
-
await
|
|
3096
|
+
await fs2.access(widgetPath);
|
|
1738
3097
|
entries.push({
|
|
1739
3098
|
name: dirent.name,
|
|
1740
3099
|
path: widgetPath
|
|
@@ -1752,7 +3111,7 @@ async function mountWidgetsDev(app, serverConfig, registerWidget, options) {
|
|
|
1752
3111
|
return;
|
|
1753
3112
|
}
|
|
1754
3113
|
const tempDir = pathHelpers.join(getCwd(), TMP_MCP_USE_DIR);
|
|
1755
|
-
await
|
|
3114
|
+
await fs2.mkdir(tempDir, { recursive: true }).catch(() => {
|
|
1756
3115
|
});
|
|
1757
3116
|
let createServer;
|
|
1758
3117
|
let react;
|
|
@@ -1786,7 +3145,7 @@ async function mountWidgetsDev(app, serverConfig, registerWidget, options) {
|
|
|
1786
3145
|
});
|
|
1787
3146
|
for (const widget2 of widgets) {
|
|
1788
3147
|
const widgetTempDir = pathHelpers.join(tempDir, widget2.name);
|
|
1789
|
-
await
|
|
3148
|
+
await fs2.mkdir(widgetTempDir, { recursive: true });
|
|
1790
3149
|
const resourcesPath = pathHelpers.join(getCwd(), resourcesDir);
|
|
1791
3150
|
const relativeResourcesPath = pathHelpers.relative(widgetTempDir, resourcesPath).replace(/\\/g, "/");
|
|
1792
3151
|
const cssContent = `@import "tailwindcss";
|
|
@@ -1794,7 +3153,7 @@ async function mountWidgetsDev(app, serverConfig, registerWidget, options) {
|
|
|
1794
3153
|
/* Configure Tailwind to scan the resources directory */
|
|
1795
3154
|
@source "${relativeResourcesPath}";
|
|
1796
3155
|
`;
|
|
1797
|
-
await
|
|
3156
|
+
await fs2.writeFile(
|
|
1798
3157
|
pathHelpers.join(widgetTempDir, "styles.css"),
|
|
1799
3158
|
cssContent,
|
|
1800
3159
|
"utf8"
|
|
@@ -1822,12 +3181,12 @@ if (container && Component) {
|
|
|
1822
3181
|
<script type="module" src="${baseRoute}/${widget2.name}/entry.tsx"></script>
|
|
1823
3182
|
</body>
|
|
1824
3183
|
</html>`;
|
|
1825
|
-
await
|
|
3184
|
+
await fs2.writeFile(
|
|
1826
3185
|
pathHelpers.join(widgetTempDir, "entry.tsx"),
|
|
1827
3186
|
entryContent,
|
|
1828
3187
|
"utf8"
|
|
1829
3188
|
);
|
|
1830
|
-
await
|
|
3189
|
+
await fs2.writeFile(
|
|
1831
3190
|
pathHelpers.join(widgetTempDir, "index.html"),
|
|
1832
3191
|
htmlContent,
|
|
1833
3192
|
"utf8"
|
|
@@ -1861,10 +3220,42 @@ if (container && Component) {
|
|
|
1861
3220
|
console.log(`[WIDGETS] Watching resources directory: ${resourcesPath}`);
|
|
1862
3221
|
}
|
|
1863
3222
|
};
|
|
3223
|
+
const nodeStubsPlugin = {
|
|
3224
|
+
name: "node-stubs",
|
|
3225
|
+
enforce: "pre",
|
|
3226
|
+
resolveId(id) {
|
|
3227
|
+
if (id === "posthog-node" || id.startsWith("posthog-node/")) {
|
|
3228
|
+
return "\0virtual:posthog-node-stub";
|
|
3229
|
+
}
|
|
3230
|
+
return null;
|
|
3231
|
+
},
|
|
3232
|
+
load(id) {
|
|
3233
|
+
if (id === "\0virtual:posthog-node-stub") {
|
|
3234
|
+
return `
|
|
3235
|
+
export class PostHog {
|
|
3236
|
+
constructor() {}
|
|
3237
|
+
capture() {}
|
|
3238
|
+
identify() {}
|
|
3239
|
+
alias() {}
|
|
3240
|
+
flush() { return Promise.resolve(); }
|
|
3241
|
+
shutdown() { return Promise.resolve(); }
|
|
3242
|
+
}
|
|
3243
|
+
export default PostHog;
|
|
3244
|
+
`;
|
|
3245
|
+
}
|
|
3246
|
+
return null;
|
|
3247
|
+
}
|
|
3248
|
+
};
|
|
1864
3249
|
const viteServer = await createServer({
|
|
1865
3250
|
root: tempDir,
|
|
1866
3251
|
base: baseRoute + "/",
|
|
1867
|
-
plugins: [
|
|
3252
|
+
plugins: [
|
|
3253
|
+
nodeStubsPlugin,
|
|
3254
|
+
ssrCssPlugin,
|
|
3255
|
+
watchResourcesPlugin,
|
|
3256
|
+
tailwindcss(),
|
|
3257
|
+
react()
|
|
3258
|
+
],
|
|
1868
3259
|
resolve: {
|
|
1869
3260
|
alias: {
|
|
1870
3261
|
"@": pathHelpers.join(getCwd(), resourcesDir)
|
|
@@ -1885,12 +3276,15 @@ if (container && Component) {
|
|
|
1885
3276
|
// Explicitly tell Vite to watch files outside root
|
|
1886
3277
|
// This is needed because widget entry files import from resources directory
|
|
1887
3278
|
optimizeDeps: {
|
|
1888
|
-
//
|
|
1889
|
-
|
|
3279
|
+
// Exclude Node.js-only packages from browser bundling
|
|
3280
|
+
// posthog-node is for server-side telemetry and doesn't work in browser
|
|
3281
|
+
exclude: ["posthog-node"]
|
|
1890
3282
|
},
|
|
1891
3283
|
ssr: {
|
|
1892
3284
|
// Force Vite to transform these packages in SSR instead of using external requires
|
|
1893
|
-
noExternal: ["@openai/apps-sdk-ui", "react-router"]
|
|
3285
|
+
noExternal: ["@openai/apps-sdk-ui", "react-router"],
|
|
3286
|
+
// Mark Node.js-only packages as external in SSR mode
|
|
3287
|
+
external: ["posthog-node"]
|
|
1894
3288
|
},
|
|
1895
3289
|
define: {
|
|
1896
3290
|
// Define process.env for SSR context
|
|
@@ -2149,25 +3543,31 @@ function setupWidgetRoutes(app, serverConfig) {
|
|
|
2149
3543
|
__name(setupWidgetRoutes, "setupWidgetRoutes");
|
|
2150
3544
|
|
|
2151
3545
|
// src/server/widgets/ui-resource-registration.ts
|
|
2152
|
-
function uiResourceRegistration(definition) {
|
|
3546
|
+
function uiResourceRegistration(server, definition) {
|
|
2153
3547
|
const displayName = definition.title || definition.name;
|
|
3548
|
+
if (definition.type === "appsSdk" && definition._meta) {
|
|
3549
|
+
server.widgetDefinitions.set(
|
|
3550
|
+
definition.name,
|
|
3551
|
+
definition._meta
|
|
3552
|
+
);
|
|
3553
|
+
}
|
|
2154
3554
|
let resourceUri;
|
|
2155
3555
|
let mimeType;
|
|
2156
3556
|
switch (definition.type) {
|
|
2157
3557
|
case "externalUrl":
|
|
2158
|
-
resourceUri = generateWidgetUri(definition.widget,
|
|
3558
|
+
resourceUri = generateWidgetUri(definition.widget, server.buildId);
|
|
2159
3559
|
mimeType = "text/uri-list";
|
|
2160
3560
|
break;
|
|
2161
3561
|
case "rawHtml":
|
|
2162
|
-
resourceUri = generateWidgetUri(definition.name,
|
|
3562
|
+
resourceUri = generateWidgetUri(definition.name, server.buildId);
|
|
2163
3563
|
mimeType = "text/html";
|
|
2164
3564
|
break;
|
|
2165
3565
|
case "remoteDom":
|
|
2166
|
-
resourceUri = generateWidgetUri(definition.name,
|
|
3566
|
+
resourceUri = generateWidgetUri(definition.name, server.buildId);
|
|
2167
3567
|
mimeType = "application/vnd.mcp-ui.remote-dom+javascript";
|
|
2168
3568
|
break;
|
|
2169
3569
|
case "appsSdk":
|
|
2170
|
-
resourceUri = generateWidgetUri(definition.name,
|
|
3570
|
+
resourceUri = generateWidgetUri(definition.name, server.buildId, ".html");
|
|
2171
3571
|
mimeType = "text/html+skybridge";
|
|
2172
3572
|
break;
|
|
2173
3573
|
default:
|
|
@@ -2176,12 +3576,12 @@ function uiResourceRegistration(definition) {
|
|
|
2176
3576
|
);
|
|
2177
3577
|
}
|
|
2178
3578
|
const serverConfig = {
|
|
2179
|
-
serverHost:
|
|
2180
|
-
serverPort:
|
|
2181
|
-
serverBaseUrl:
|
|
2182
|
-
buildId:
|
|
3579
|
+
serverHost: server.serverHost,
|
|
3580
|
+
serverPort: server.serverPort || 3e3,
|
|
3581
|
+
serverBaseUrl: server.serverBaseUrl,
|
|
3582
|
+
buildId: server.buildId
|
|
2183
3583
|
};
|
|
2184
|
-
|
|
3584
|
+
server.resource({
|
|
2185
3585
|
name: definition.name,
|
|
2186
3586
|
uri: resourceUri,
|
|
2187
3587
|
title: definition.title,
|
|
@@ -2203,9 +3603,9 @@ function uiResourceRegistration(definition) {
|
|
|
2203
3603
|
}, "readCallback")
|
|
2204
3604
|
});
|
|
2205
3605
|
if (definition.type === "appsSdk") {
|
|
2206
|
-
const buildIdPart =
|
|
3606
|
+
const buildIdPart = server.buildId ? `-${server.buildId}` : "";
|
|
2207
3607
|
const uriTemplate = `ui://widget/${definition.name}${buildIdPart}-{id}.html`;
|
|
2208
|
-
|
|
3608
|
+
server.resourceTemplate({
|
|
2209
3609
|
name: `${definition.name}-dynamic`,
|
|
2210
3610
|
resourceTemplate: {
|
|
2211
3611
|
uriTemplate,
|
|
@@ -2230,70 +3630,77 @@ function uiResourceRegistration(definition) {
|
|
|
2230
3630
|
}, "readCallback")
|
|
2231
3631
|
});
|
|
2232
3632
|
}
|
|
2233
|
-
const
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
const
|
|
2237
|
-
|
|
2238
|
-
"openai/
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
3633
|
+
const widgetMetadata = definition._meta?.["mcp-use/widget"];
|
|
3634
|
+
const exposeAsTool = definition.exposeAsTool ?? widgetMetadata?.exposeAsTool ?? true;
|
|
3635
|
+
if (exposeAsTool) {
|
|
3636
|
+
const toolMetadata = definition._meta || {};
|
|
3637
|
+
if (definition.type === "appsSdk" && definition.appsSdkMetadata) {
|
|
3638
|
+
toolMetadata["openai/outputTemplate"] = resourceUri;
|
|
3639
|
+
const toolMetadataFields = [
|
|
3640
|
+
"openai/toolInvocation/invoking",
|
|
3641
|
+
"openai/toolInvocation/invoked",
|
|
3642
|
+
"openai/widgetAccessible",
|
|
3643
|
+
"openai/resultCanProduceWidget"
|
|
3644
|
+
];
|
|
3645
|
+
for (const field of toolMetadataFields) {
|
|
3646
|
+
if (definition.appsSdkMetadata[field] !== void 0) {
|
|
3647
|
+
toolMetadata[field] = definition.appsSdkMetadata[field];
|
|
3648
|
+
}
|
|
2245
3649
|
}
|
|
2246
3650
|
}
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
const randomId = Math.random().toString(36).substring(2, 15);
|
|
2262
|
-
const uniqueUri = generateWidgetUri(
|
|
2263
|
-
definition.name,
|
|
2264
|
-
this.buildId,
|
|
2265
|
-
".html",
|
|
2266
|
-
randomId
|
|
3651
|
+
server.tool(
|
|
3652
|
+
{
|
|
3653
|
+
name: definition.name,
|
|
3654
|
+
title: definition.title,
|
|
3655
|
+
description: definition.description,
|
|
3656
|
+
inputs: convertPropsToInputs(definition.props),
|
|
3657
|
+
annotations: definition.toolAnnotations,
|
|
3658
|
+
_meta: Object.keys(toolMetadata).length > 0 ? toolMetadata : void 0
|
|
3659
|
+
},
|
|
3660
|
+
async (params) => {
|
|
3661
|
+
const uiResource = await createWidgetUIResource(
|
|
3662
|
+
definition,
|
|
3663
|
+
params,
|
|
3664
|
+
serverConfig
|
|
2267
3665
|
);
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
3666
|
+
if (definition.type === "appsSdk") {
|
|
3667
|
+
const randomId = Math.random().toString(36).substring(2, 15);
|
|
3668
|
+
const uniqueUri = generateWidgetUri(
|
|
3669
|
+
definition.name,
|
|
3670
|
+
server.buildId,
|
|
3671
|
+
".html",
|
|
3672
|
+
randomId
|
|
3673
|
+
);
|
|
3674
|
+
const uniqueToolMetadata = {
|
|
3675
|
+
...toolMetadata,
|
|
3676
|
+
"openai/outputTemplate": uniqueUri
|
|
3677
|
+
};
|
|
3678
|
+
return {
|
|
3679
|
+
_meta: uniqueToolMetadata,
|
|
3680
|
+
content: [
|
|
3681
|
+
{
|
|
3682
|
+
type: "text",
|
|
3683
|
+
text: `Displaying ${displayName}`
|
|
3684
|
+
}
|
|
3685
|
+
],
|
|
3686
|
+
// structuredContent will be injected as window.openai.toolOutput by Apps SDK
|
|
3687
|
+
structuredContent: params
|
|
3688
|
+
};
|
|
3689
|
+
}
|
|
2272
3690
|
return {
|
|
2273
|
-
_meta: uniqueToolMetadata,
|
|
2274
3691
|
content: [
|
|
2275
3692
|
{
|
|
2276
3693
|
type: "text",
|
|
2277
|
-
text: `Displaying ${displayName}
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
3694
|
+
text: `Displaying ${displayName}`,
|
|
3695
|
+
description: `Show MCP-UI widget for ${displayName}`
|
|
3696
|
+
},
|
|
3697
|
+
uiResource
|
|
3698
|
+
]
|
|
2282
3699
|
};
|
|
2283
3700
|
}
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
type: "text",
|
|
2288
|
-
text: `Displaying ${displayName}`,
|
|
2289
|
-
description: `Show MCP-UI widget for ${displayName}`
|
|
2290
|
-
},
|
|
2291
|
-
uiResource
|
|
2292
|
-
]
|
|
2293
|
-
};
|
|
2294
|
-
}, "cb")
|
|
2295
|
-
});
|
|
2296
|
-
return this;
|
|
3701
|
+
);
|
|
3702
|
+
}
|
|
3703
|
+
return server;
|
|
2297
3704
|
}
|
|
2298
3705
|
__name(uiResourceRegistration, "uiResourceRegistration");
|
|
2299
3706
|
|
|
@@ -2431,7 +3838,7 @@ function toolRegistration(toolDefinition, callback) {
|
|
|
2431
3838
|
const initialRequestContext = getRequestContext();
|
|
2432
3839
|
const extraProgressToken = extra?._meta?.progressToken;
|
|
2433
3840
|
const extraSendNotification = extra?.sendNotification;
|
|
2434
|
-
const { requestContext, progressToken, sendNotification: sendNotification2 } = findSessionContext(
|
|
3841
|
+
const { requestContext, session, progressToken, sendNotification: sendNotification2 } = findSessionContext(
|
|
2435
3842
|
this.sessions,
|
|
2436
3843
|
initialRequestContext,
|
|
2437
3844
|
extraProgressToken,
|
|
@@ -2442,7 +3849,9 @@ function toolRegistration(toolDefinition, callback) {
|
|
|
2442
3849
|
this.createMessage.bind(this),
|
|
2443
3850
|
this.server.server.elicitInput.bind(this.server.server),
|
|
2444
3851
|
progressToken,
|
|
2445
|
-
sendNotification2
|
|
3852
|
+
sendNotification2,
|
|
3853
|
+
session?.logLevel,
|
|
3854
|
+
session?.clientCapabilities
|
|
2446
3855
|
);
|
|
2447
3856
|
const executeCallback = /* @__PURE__ */ __name(async () => {
|
|
2448
3857
|
if (actualCallback.length >= 2) {
|
|
@@ -2465,8 +3874,154 @@ __name(toolRegistration, "toolRegistration");
|
|
|
2465
3874
|
init_tool_execution_helpers();
|
|
2466
3875
|
|
|
2467
3876
|
// src/server/resources/index.ts
|
|
2468
|
-
var import_mcp = require("@modelcontextprotocol
|
|
3877
|
+
var import_mcp = require("@mcp-use/modelcontextprotocol-sdk/server/mcp.js");
|
|
2469
3878
|
init_conversion();
|
|
3879
|
+
|
|
3880
|
+
// src/server/resources/subscriptions.ts
|
|
3881
|
+
var import_types = require("@mcp-use/modelcontextprotocol-sdk/types.js");
|
|
3882
|
+
init_context_storage();
|
|
3883
|
+
var ResourceSubscriptionManager = class {
|
|
3884
|
+
static {
|
|
3885
|
+
__name(this, "ResourceSubscriptionManager");
|
|
3886
|
+
}
|
|
3887
|
+
/**
|
|
3888
|
+
* Tracks resource subscriptions per session
|
|
3889
|
+
* Map structure: uri -> Set<sessionId>
|
|
3890
|
+
*/
|
|
3891
|
+
subscriptions = /* @__PURE__ */ new Map();
|
|
3892
|
+
/**
|
|
3893
|
+
* Register subscription handlers with an MCP server instance
|
|
3894
|
+
*
|
|
3895
|
+
* @param server - The native MCP server instance
|
|
3896
|
+
* @param sessions - Map of active sessions
|
|
3897
|
+
*/
|
|
3898
|
+
registerHandlers(server, sessions) {
|
|
3899
|
+
server.server.setRequestHandler(
|
|
3900
|
+
import_types.SubscribeRequestSchema,
|
|
3901
|
+
async (request) => {
|
|
3902
|
+
const { uri } = request.params;
|
|
3903
|
+
const sessionId = this.getSessionIdFromContext(sessions, server);
|
|
3904
|
+
if (!sessionId) {
|
|
3905
|
+
console.warn(
|
|
3906
|
+
`[MCP] Could not determine session ID for resource subscription to ${uri}`
|
|
3907
|
+
);
|
|
3908
|
+
return {};
|
|
3909
|
+
}
|
|
3910
|
+
if (!this.subscriptions.has(uri)) {
|
|
3911
|
+
this.subscriptions.set(uri, /* @__PURE__ */ new Set());
|
|
3912
|
+
}
|
|
3913
|
+
this.subscriptions.get(uri).add(sessionId);
|
|
3914
|
+
console.log(
|
|
3915
|
+
`[MCP] Session ${sessionId} subscribed to resource: ${uri}`
|
|
3916
|
+
);
|
|
3917
|
+
return {};
|
|
3918
|
+
}
|
|
3919
|
+
);
|
|
3920
|
+
server.server.setRequestHandler(
|
|
3921
|
+
import_types.UnsubscribeRequestSchema,
|
|
3922
|
+
async (request) => {
|
|
3923
|
+
const { uri } = request.params;
|
|
3924
|
+
const sessionId = this.getSessionIdFromContext(sessions, server);
|
|
3925
|
+
if (!sessionId) {
|
|
3926
|
+
console.warn(
|
|
3927
|
+
`[MCP] Could not determine session ID for resource unsubscribe from ${uri}`
|
|
3928
|
+
);
|
|
3929
|
+
return {};
|
|
3930
|
+
}
|
|
3931
|
+
const subscribers = this.subscriptions.get(uri);
|
|
3932
|
+
if (subscribers) {
|
|
3933
|
+
subscribers.delete(sessionId);
|
|
3934
|
+
if (subscribers.size === 0) {
|
|
3935
|
+
this.subscriptions.delete(uri);
|
|
3936
|
+
}
|
|
3937
|
+
console.log(
|
|
3938
|
+
`[MCP] Session ${sessionId} unsubscribed from resource: ${uri}`
|
|
3939
|
+
);
|
|
3940
|
+
}
|
|
3941
|
+
return {};
|
|
3942
|
+
}
|
|
3943
|
+
);
|
|
3944
|
+
}
|
|
3945
|
+
/**
|
|
3946
|
+
* Get session ID from request context or sessions map
|
|
3947
|
+
*
|
|
3948
|
+
* @param sessions - Map of active sessions
|
|
3949
|
+
* @param server - The server instance to match against
|
|
3950
|
+
* @returns The session ID, or undefined if not found
|
|
3951
|
+
*/
|
|
3952
|
+
getSessionIdFromContext(sessions, server) {
|
|
3953
|
+
const requestContext = getRequestContext();
|
|
3954
|
+
let sessionId;
|
|
3955
|
+
if (requestContext) {
|
|
3956
|
+
sessionId = requestContext.req.header("mcp-session-id");
|
|
3957
|
+
}
|
|
3958
|
+
if (!sessionId) {
|
|
3959
|
+
for (const [sid, session] of sessions.entries()) {
|
|
3960
|
+
if (session.server === server) {
|
|
3961
|
+
sessionId = sid;
|
|
3962
|
+
break;
|
|
3963
|
+
}
|
|
3964
|
+
}
|
|
3965
|
+
}
|
|
3966
|
+
return sessionId;
|
|
3967
|
+
}
|
|
3968
|
+
/**
|
|
3969
|
+
* Notify subscribed clients that a resource has been updated
|
|
3970
|
+
*
|
|
3971
|
+
* This method sends a `notifications/resources/updated` notification to all
|
|
3972
|
+
* sessions that have subscribed to the specified resource URI.
|
|
3973
|
+
*
|
|
3974
|
+
* @param uri - The URI of the resource that changed
|
|
3975
|
+
* @param sessions - Map of active sessions
|
|
3976
|
+
* @returns Promise that resolves when all notifications have been sent
|
|
3977
|
+
*/
|
|
3978
|
+
async notifyResourceUpdated(uri, sessions) {
|
|
3979
|
+
const subscribers = this.subscriptions.get(uri);
|
|
3980
|
+
if (!subscribers || subscribers.size === 0) {
|
|
3981
|
+
return;
|
|
3982
|
+
}
|
|
3983
|
+
console.log(
|
|
3984
|
+
`[MCP] Notifying ${subscribers.size} subscriber(s) of resource update: ${uri}`
|
|
3985
|
+
);
|
|
3986
|
+
for (const sessionId of subscribers) {
|
|
3987
|
+
const session = sessions.get(sessionId);
|
|
3988
|
+
if (session?.server) {
|
|
3989
|
+
try {
|
|
3990
|
+
await session.server.server.sendResourceUpdated({ uri });
|
|
3991
|
+
console.log(
|
|
3992
|
+
`[MCP] Sent resource update notification to session ${sessionId}`
|
|
3993
|
+
);
|
|
3994
|
+
} catch (error2) {
|
|
3995
|
+
console.error(
|
|
3996
|
+
`[MCP] Failed to send resource update notification to session ${sessionId}:`,
|
|
3997
|
+
error2
|
|
3998
|
+
);
|
|
3999
|
+
}
|
|
4000
|
+
}
|
|
4001
|
+
}
|
|
4002
|
+
}
|
|
4003
|
+
/**
|
|
4004
|
+
* Clean up resource subscriptions for a closed session
|
|
4005
|
+
*
|
|
4006
|
+
* This method is called automatically when a session is closed to remove
|
|
4007
|
+
* all resource subscriptions associated with that session.
|
|
4008
|
+
*
|
|
4009
|
+
* @param sessionId - The session ID to clean up
|
|
4010
|
+
*/
|
|
4011
|
+
cleanupSession(sessionId) {
|
|
4012
|
+
for (const [uri, subscribers] of this.subscriptions) {
|
|
4013
|
+
subscribers.delete(sessionId);
|
|
4014
|
+
if (subscribers.size === 0) {
|
|
4015
|
+
this.subscriptions.delete(uri);
|
|
4016
|
+
}
|
|
4017
|
+
}
|
|
4018
|
+
console.log(
|
|
4019
|
+
`[MCP] Cleaned up resource subscriptions for session ${sessionId}`
|
|
4020
|
+
);
|
|
4021
|
+
}
|
|
4022
|
+
};
|
|
4023
|
+
|
|
4024
|
+
// src/server/resources/index.ts
|
|
2470
4025
|
function registerResource(resourceDefinition, callback) {
|
|
2471
4026
|
const actualCallback = callback || resourceDefinition.readCallback;
|
|
2472
4027
|
if (!actualCallback) {
|
|
@@ -2525,24 +4080,25 @@ function registerResourceTemplate(resourceTemplateDefinition, callback) {
|
|
|
2525
4080
|
`Resource template '${resourceTemplateDefinition.name}' must have either a readCallback property or a callback parameter`
|
|
2526
4081
|
);
|
|
2527
4082
|
}
|
|
2528
|
-
const
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
4083
|
+
const isFlatStructure = "uriTemplate" in resourceTemplateDefinition;
|
|
4084
|
+
const uriTemplate = isFlatStructure ? resourceTemplateDefinition.uriTemplate : resourceTemplateDefinition.resourceTemplate.uriTemplate;
|
|
4085
|
+
const mimeType = isFlatStructure ? resourceTemplateDefinition.mimeType : resourceTemplateDefinition.resourceTemplate.mimeType;
|
|
4086
|
+
const templateDescription = isFlatStructure ? void 0 : resourceTemplateDefinition.resourceTemplate.description;
|
|
4087
|
+
const template = new import_mcp.ResourceTemplate(uriTemplate, {
|
|
4088
|
+
list: void 0,
|
|
4089
|
+
// Optional: callback to list all matching resources
|
|
4090
|
+
complete: void 0
|
|
4091
|
+
// Optional: callback for auto-completion
|
|
4092
|
+
});
|
|
2537
4093
|
const metadata = {};
|
|
2538
4094
|
if (resourceTemplateDefinition.title) {
|
|
2539
4095
|
metadata.title = resourceTemplateDefinition.title;
|
|
2540
4096
|
}
|
|
2541
|
-
if (resourceTemplateDefinition.description ||
|
|
2542
|
-
metadata.description = resourceTemplateDefinition.description ||
|
|
4097
|
+
if (resourceTemplateDefinition.description || templateDescription) {
|
|
4098
|
+
metadata.description = resourceTemplateDefinition.description || templateDescription;
|
|
2543
4099
|
}
|
|
2544
|
-
if (
|
|
2545
|
-
metadata.mimeType =
|
|
4100
|
+
if (mimeType) {
|
|
4101
|
+
metadata.mimeType = mimeType;
|
|
2546
4102
|
}
|
|
2547
4103
|
if (resourceTemplateDefinition.annotations) {
|
|
2548
4104
|
metadata.annotations = resourceTemplateDefinition.annotations;
|
|
@@ -2552,10 +4108,7 @@ function registerResourceTemplate(resourceTemplateDefinition, callback) {
|
|
|
2552
4108
|
template,
|
|
2553
4109
|
metadata,
|
|
2554
4110
|
async (uri) => {
|
|
2555
|
-
const params = this.parseTemplateUri(
|
|
2556
|
-
resourceTemplateDefinition.resourceTemplate.uriTemplate,
|
|
2557
|
-
uri.toString()
|
|
2558
|
-
);
|
|
4111
|
+
const params = this.parseTemplateUri(uriTemplate, uri.toString());
|
|
2559
4112
|
const { getRequestContext: getRequestContext2, runWithContext: runWithContext2 } = await Promise.resolve().then(() => (init_context_storage(), context_storage_exports));
|
|
2560
4113
|
const { findSessionContext: findSessionContext2 } = await Promise.resolve().then(() => (init_tool_execution_helpers(), tool_execution_helpers_exports));
|
|
2561
4114
|
const initialRequestContext = getRequestContext2();
|
|
@@ -2570,8 +4123,12 @@ function registerResourceTemplate(resourceTemplateDefinition, callback) {
|
|
|
2570
4123
|
const executeCallback = /* @__PURE__ */ __name(async () => {
|
|
2571
4124
|
if (actualCallback.length >= 3) {
|
|
2572
4125
|
return await actualCallback(uri, params, enhancedContext);
|
|
4126
|
+
} else if (actualCallback.length === 2) {
|
|
4127
|
+
return await actualCallback(uri, params);
|
|
4128
|
+
} else if (actualCallback.length === 1) {
|
|
4129
|
+
return await actualCallback(uri);
|
|
2573
4130
|
}
|
|
2574
|
-
return await actualCallback(
|
|
4131
|
+
return await actualCallback();
|
|
2575
4132
|
}, "executeCallback");
|
|
2576
4133
|
const result = requestContext ? await runWithContext2(requestContext, executeCallback) : await executeCallback();
|
|
2577
4134
|
if ("contents" in result && Array.isArray(result.contents)) {
|
|
@@ -2602,8 +4159,10 @@ function registerPrompt(promptDefinition, callback) {
|
|
|
2602
4159
|
argsSchema = this.convertZodSchemaToParams(
|
|
2603
4160
|
promptDefinition.schema
|
|
2604
4161
|
);
|
|
4162
|
+
} else if (promptDefinition.args && promptDefinition.args.length > 0) {
|
|
4163
|
+
argsSchema = this.createParamsSchema(promptDefinition.args);
|
|
2605
4164
|
} else {
|
|
2606
|
-
argsSchema =
|
|
4165
|
+
argsSchema = void 0;
|
|
2607
4166
|
}
|
|
2608
4167
|
const wrappedCallback = /* @__PURE__ */ __name(async (params, extra) => {
|
|
2609
4168
|
const { getRequestContext: getRequestContext2, runWithContext: runWithContext2 } = await Promise.resolve().then(() => (init_context_storage(), context_storage_exports));
|
|
@@ -2886,7 +4445,7 @@ init_tool_execution_helpers();
|
|
|
2886
4445
|
init_context_storage();
|
|
2887
4446
|
|
|
2888
4447
|
// src/server/sessions/session-manager.ts
|
|
2889
|
-
function startIdleCleanup(sessions, idleTimeoutMs) {
|
|
4448
|
+
function startIdleCleanup(sessions, idleTimeoutMs, mcpServerInstance) {
|
|
2890
4449
|
if (idleTimeoutMs <= 0) {
|
|
2891
4450
|
return void 0;
|
|
2892
4451
|
}
|
|
@@ -2904,6 +4463,7 @@ function startIdleCleanup(sessions, idleTimeoutMs) {
|
|
|
2904
4463
|
);
|
|
2905
4464
|
for (const sessionId of expiredSessions) {
|
|
2906
4465
|
sessions.delete(sessionId);
|
|
4466
|
+
mcpServerInstance?.cleanupSessionSubscriptions?.(sessionId);
|
|
2907
4467
|
}
|
|
2908
4468
|
}
|
|
2909
4469
|
}, 6e4);
|
|
@@ -2912,13 +4472,18 @@ __name(startIdleCleanup, "startIdleCleanup");
|
|
|
2912
4472
|
|
|
2913
4473
|
// src/server/endpoints/mount-mcp.ts
|
|
2914
4474
|
init_runtime();
|
|
4475
|
+
init_telemetry2();
|
|
2915
4476
|
async function mountMcp(app, mcpServerInstance, sessions, config, isProductionMode2) {
|
|
2916
|
-
const { FetchStreamableHTTPServerTransport } = await import("@modelcontextprotocol
|
|
4477
|
+
const { FetchStreamableHTTPServerTransport } = await import("@mcp-use/modelcontextprotocol-sdk/experimental/fetch-streamable-http/index.js");
|
|
2917
4478
|
const idleTimeoutMs = config.sessionIdleTimeoutMs ?? 3e5;
|
|
2918
4479
|
const transports = /* @__PURE__ */ new Map();
|
|
2919
4480
|
let idleCleanupInterval;
|
|
2920
4481
|
if (idleTimeoutMs > 0) {
|
|
2921
|
-
idleCleanupInterval = startIdleCleanup(
|
|
4482
|
+
idleCleanupInterval = startIdleCleanup(
|
|
4483
|
+
sessions,
|
|
4484
|
+
idleTimeoutMs,
|
|
4485
|
+
mcpServerInstance
|
|
4486
|
+
);
|
|
2922
4487
|
}
|
|
2923
4488
|
const handleRequest = /* @__PURE__ */ __name(async (c) => {
|
|
2924
4489
|
const sessionId = c.req.header("mcp-session-id");
|
|
@@ -2945,11 +4510,33 @@ async function mountMcp(app, mcpServerInstance, sessions, config, isProductionMo
|
|
|
2945
4510
|
context: c,
|
|
2946
4511
|
honoContext: c
|
|
2947
4512
|
});
|
|
4513
|
+
server.server.oninitialized = () => {
|
|
4514
|
+
const clientCapabilities = server.server.getClientCapabilities();
|
|
4515
|
+
const clientInfo = server.server.getClientInfo?.() || {};
|
|
4516
|
+
const protocolVersion = server.server.getProtocolVersion?.() || "unknown";
|
|
4517
|
+
if (clientCapabilities && sessions.has(sid)) {
|
|
4518
|
+
const session = sessions.get(sid);
|
|
4519
|
+
session.clientCapabilities = clientCapabilities;
|
|
4520
|
+
console.log(
|
|
4521
|
+
`[MCP] Captured client capabilities for session ${sid}:`,
|
|
4522
|
+
Object.keys(clientCapabilities)
|
|
4523
|
+
);
|
|
4524
|
+
}
|
|
4525
|
+
Telemetry.getInstance().trackServerInitialize({
|
|
4526
|
+
protocolVersion: String(protocolVersion),
|
|
4527
|
+
clientInfo: clientInfo || {},
|
|
4528
|
+
clientCapabilities: clientCapabilities || {},
|
|
4529
|
+
sessionId: sid
|
|
4530
|
+
}).catch(
|
|
4531
|
+
(e) => console.debug(`Failed to track server initialize: ${e}`)
|
|
4532
|
+
);
|
|
4533
|
+
};
|
|
2948
4534
|
}, "onsessioninitialized"),
|
|
2949
4535
|
onsessionclosed: /* @__PURE__ */ __name((sid) => {
|
|
2950
4536
|
console.log(`[MCP] Session closed: ${sid}`);
|
|
2951
4537
|
transports.delete(sid);
|
|
2952
4538
|
sessions.delete(sid);
|
|
4539
|
+
mcpServerInstance.cleanupSessionSubscriptions?.(sid);
|
|
2953
4540
|
}, "onsessionclosed")
|
|
2954
4541
|
});
|
|
2955
4542
|
await server.connect(transport);
|
|
@@ -3187,12 +4774,13 @@ function createBearerAuthMiddleware(provider, baseUrl) {
|
|
|
3187
4774
|
const result = await provider.verifyToken(token);
|
|
3188
4775
|
const payload = result.payload;
|
|
3189
4776
|
const user = provider.getUserInfo(payload);
|
|
4777
|
+
const scope = payload.scope;
|
|
3190
4778
|
const authInfo = {
|
|
3191
4779
|
user,
|
|
3192
4780
|
payload,
|
|
3193
4781
|
accessToken: token,
|
|
3194
4782
|
// Extract scopes from scope claim (OAuth standard)
|
|
3195
|
-
scopes:
|
|
4783
|
+
scopes: scope ? scope.split(" ") : [],
|
|
3196
4784
|
// Extract permissions (Auth0 style, or custom)
|
|
3197
4785
|
permissions: payload.permissions || []
|
|
3198
4786
|
};
|
|
@@ -3240,9 +4828,16 @@ async function setupOAuthForServer(app, oauthProvider, baseUrl, state) {
|
|
|
3240
4828
|
__name(setupOAuthForServer, "setupOAuthForServer");
|
|
3241
4829
|
|
|
3242
4830
|
// src/server/mcp-server.ts
|
|
3243
|
-
var
|
|
4831
|
+
var MCPServerClass = class {
|
|
3244
4832
|
static {
|
|
3245
|
-
__name(this, "
|
|
4833
|
+
__name(this, "MCPServerClass");
|
|
4834
|
+
}
|
|
4835
|
+
/**
|
|
4836
|
+
* Get the mcp-use package version.
|
|
4837
|
+
* Works in all environments (Node.js, browser, Cloudflare Workers, Deno, etc.)
|
|
4838
|
+
*/
|
|
4839
|
+
static getPackageVersion() {
|
|
4840
|
+
return getPackageVersion();
|
|
3246
4841
|
}
|
|
3247
4842
|
/**
|
|
3248
4843
|
* Native MCP server instance from @modelcontextprotocol/sdk
|
|
@@ -3266,8 +4861,6 @@ var McpServer = class {
|
|
|
3266
4861
|
buildId;
|
|
3267
4862
|
sessions = /* @__PURE__ */ new Map();
|
|
3268
4863
|
idleCleanupInterval;
|
|
3269
|
-
oauthConfig;
|
|
3270
|
-
// Store OAuth config for lazy initialization
|
|
3271
4864
|
oauthSetupState = {
|
|
3272
4865
|
complete: false,
|
|
3273
4866
|
provider: void 0,
|
|
@@ -3276,15 +4869,37 @@ var McpServer = class {
|
|
|
3276
4869
|
oauthProvider;
|
|
3277
4870
|
oauthMiddleware;
|
|
3278
4871
|
/**
|
|
3279
|
-
* Storage for
|
|
4872
|
+
* Storage for registrations that can be replayed on new server instances
|
|
3280
4873
|
* Following the official SDK pattern where each session gets its own server instance
|
|
4874
|
+
* @internal Exposed for telemetry purposes
|
|
3281
4875
|
*/
|
|
3282
|
-
|
|
4876
|
+
registrations = {
|
|
3283
4877
|
tools: /* @__PURE__ */ new Map(),
|
|
3284
4878
|
prompts: /* @__PURE__ */ new Map(),
|
|
3285
4879
|
resources: /* @__PURE__ */ new Map(),
|
|
3286
4880
|
resourceTemplates: /* @__PURE__ */ new Map()
|
|
3287
4881
|
};
|
|
4882
|
+
/**
|
|
4883
|
+
* Storage for widget definitions, used to inject metadata into tool responses
|
|
4884
|
+
* when using the widget() helper with returnsWidget option
|
|
4885
|
+
*/
|
|
4886
|
+
widgetDefinitions = /* @__PURE__ */ new Map();
|
|
4887
|
+
/**
|
|
4888
|
+
* Resource subscription manager for tracking and notifying resource updates
|
|
4889
|
+
*/
|
|
4890
|
+
subscriptionManager = new ResourceSubscriptionManager();
|
|
4891
|
+
/**
|
|
4892
|
+
* Clean up resource subscriptions for a closed session
|
|
4893
|
+
*
|
|
4894
|
+
* This method is called automatically when a session is closed to remove
|
|
4895
|
+
* all resource subscriptions associated with that session.
|
|
4896
|
+
*
|
|
4897
|
+
* @param sessionId - The session ID to clean up
|
|
4898
|
+
* @internal
|
|
4899
|
+
*/
|
|
4900
|
+
cleanupSessionSubscriptions(sessionId) {
|
|
4901
|
+
this.subscriptionManager.cleanupSession(sessionId);
|
|
4902
|
+
}
|
|
3288
4903
|
/**
|
|
3289
4904
|
* Creates a new MCP server instance with Hono integration
|
|
3290
4905
|
*
|
|
@@ -3293,23 +4908,34 @@ var McpServer = class {
|
|
|
3293
4908
|
* access to Hono methods while preserving MCP server functionality.
|
|
3294
4909
|
*
|
|
3295
4910
|
* @param config - Server configuration including name, version, and description
|
|
3296
|
-
* @returns A proxied
|
|
4911
|
+
* @returns A proxied MCPServer instance that supports both MCP and Hono methods
|
|
3297
4912
|
*/
|
|
3298
4913
|
constructor(config) {
|
|
3299
4914
|
this.config = config;
|
|
3300
4915
|
this.serverHost = config.host || "localhost";
|
|
3301
4916
|
this.serverBaseUrl = config.baseUrl;
|
|
3302
|
-
this.nativeServer = new import_mcp2.McpServer(
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
4917
|
+
this.nativeServer = new import_mcp2.McpServer(
|
|
4918
|
+
{
|
|
4919
|
+
name: config.name,
|
|
4920
|
+
version: config.version
|
|
4921
|
+
},
|
|
4922
|
+
{
|
|
4923
|
+
capabilities: {
|
|
4924
|
+
logging: {},
|
|
4925
|
+
resources: {
|
|
4926
|
+
subscribe: true,
|
|
4927
|
+
listChanged: true
|
|
4928
|
+
}
|
|
4929
|
+
}
|
|
4930
|
+
}
|
|
4931
|
+
);
|
|
3306
4932
|
this.app = createHonoApp(requestLogger);
|
|
3307
|
-
this.
|
|
4933
|
+
this.oauthProvider = config.oauth;
|
|
3308
4934
|
this.wrapRegistrationMethods();
|
|
3309
4935
|
return createHonoProxy(this, this.app);
|
|
3310
4936
|
}
|
|
3311
4937
|
/**
|
|
3312
|
-
* Wrap registration methods to capture
|
|
4938
|
+
* Wrap registration methods to capture registrations following official SDK pattern.
|
|
3313
4939
|
* Each session will get a fresh server instance with all registrations replayed.
|
|
3314
4940
|
*/
|
|
3315
4941
|
wrapRegistrationMethods() {
|
|
@@ -3319,50 +4945,113 @@ var McpServer = class {
|
|
|
3319
4945
|
const originalResourceTemplate = registerResourceTemplate;
|
|
3320
4946
|
const self = this;
|
|
3321
4947
|
this.tool = ((toolDefinition, callback) => {
|
|
3322
|
-
const
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
4948
|
+
const widgetConfig = toolDefinition.widget;
|
|
4949
|
+
const widgetName = widgetConfig?.name;
|
|
4950
|
+
if (widgetConfig && widgetName) {
|
|
4951
|
+
const buildIdPart = self.buildId ? `-${self.buildId}` : "";
|
|
4952
|
+
const outputTemplate = `ui://widget/${widgetName}${buildIdPart}.html`;
|
|
4953
|
+
toolDefinition._meta = {
|
|
4954
|
+
...toolDefinition._meta,
|
|
4955
|
+
"openai/outputTemplate": outputTemplate,
|
|
4956
|
+
"openai/toolInvocation/invoking": widgetConfig.invoking ?? `Loading ${widgetName}...`,
|
|
4957
|
+
"openai/toolInvocation/invoked": widgetConfig.invoked ?? `${widgetName} ready`,
|
|
4958
|
+
"openai/widgetAccessible": widgetConfig.widgetAccessible ?? true,
|
|
4959
|
+
"openai/resultCanProduceWidget": widgetConfig.resultCanProduceWidget ?? true
|
|
4960
|
+
};
|
|
4961
|
+
}
|
|
4962
|
+
let actualCallback = callback || toolDefinition.cb;
|
|
4963
|
+
if (widgetConfig && widgetName && actualCallback) {
|
|
4964
|
+
const originalCallback = actualCallback;
|
|
4965
|
+
actualCallback = /* @__PURE__ */ __name((async (params, ctx) => {
|
|
4966
|
+
const result = await originalCallback(params, ctx);
|
|
4967
|
+
const widgetDef = self.widgetDefinitions.get(widgetName);
|
|
4968
|
+
if (result && typeof result === "object") {
|
|
4969
|
+
const randomId = Math.random().toString(36).substring(2, 15);
|
|
4970
|
+
const buildIdPart = self.buildId ? `-${self.buildId}` : "";
|
|
4971
|
+
const uniqueUri = `ui://widget/${widgetName}${buildIdPart}-${randomId}.html`;
|
|
4972
|
+
const responseMeta = {
|
|
4973
|
+
...widgetDef || {},
|
|
4974
|
+
// Include mcp-use/widget and other widget metadata
|
|
4975
|
+
"openai/outputTemplate": uniqueUri,
|
|
4976
|
+
"openai/toolInvocation/invoking": widgetConfig.invoking ?? `Loading ${widgetName}...`,
|
|
4977
|
+
"openai/toolInvocation/invoked": widgetConfig.invoked ?? `${widgetName} ready`,
|
|
4978
|
+
"openai/widgetAccessible": widgetConfig.widgetAccessible ?? true,
|
|
4979
|
+
"openai/resultCanProduceWidget": widgetConfig.resultCanProduceWidget ?? true
|
|
4980
|
+
};
|
|
4981
|
+
result._meta = responseMeta;
|
|
4982
|
+
if (result.content?.[0]?.type === "text" && !result.content[0].text) {
|
|
4983
|
+
result.content[0].text = `Displaying ${widgetName}`;
|
|
4984
|
+
}
|
|
4985
|
+
}
|
|
4986
|
+
return result;
|
|
4987
|
+
}), "actualCallback");
|
|
4988
|
+
}
|
|
4989
|
+
if (actualCallback) {
|
|
4990
|
+
self.registrations.tools.set(toolDefinition.name, {
|
|
4991
|
+
config: toolDefinition,
|
|
4992
|
+
handler: actualCallback
|
|
4993
|
+
});
|
|
4994
|
+
}
|
|
4995
|
+
return originalTool.call(self, toolDefinition, actualCallback);
|
|
3328
4996
|
});
|
|
3329
|
-
this.prompt =
|
|
4997
|
+
this.prompt = ((promptDefinition, callback) => {
|
|
3330
4998
|
const actualCallback = callback || promptDefinition.cb;
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
4999
|
+
if (actualCallback) {
|
|
5000
|
+
self.registrations.prompts.set(promptDefinition.name, {
|
|
5001
|
+
config: promptDefinition,
|
|
5002
|
+
handler: actualCallback
|
|
5003
|
+
});
|
|
5004
|
+
}
|
|
5005
|
+
return originalPrompt.call(
|
|
5006
|
+
self,
|
|
5007
|
+
promptDefinition,
|
|
5008
|
+
callback
|
|
5009
|
+
);
|
|
5010
|
+
});
|
|
5011
|
+
this.resource = ((resourceDefinition, callback) => {
|
|
3338
5012
|
const actualCallback = callback || resourceDefinition.readCallback;
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
5013
|
+
if (actualCallback) {
|
|
5014
|
+
const resourceKey = `${resourceDefinition.name}:${resourceDefinition.uri}`;
|
|
5015
|
+
self.registrations.resources.set(resourceKey, {
|
|
5016
|
+
config: resourceDefinition,
|
|
5017
|
+
handler: actualCallback
|
|
5018
|
+
});
|
|
5019
|
+
}
|
|
3344
5020
|
return originalResource.call(self, resourceDefinition, callback);
|
|
3345
|
-
};
|
|
3346
|
-
this.resourceTemplate =
|
|
5021
|
+
});
|
|
5022
|
+
this.resourceTemplate = ((templateDefinition, callback) => {
|
|
3347
5023
|
const actualCallback = callback || templateDefinition.readCallback;
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
5024
|
+
if (actualCallback) {
|
|
5025
|
+
self.registrations.resourceTemplates.set(templateDefinition.name, {
|
|
5026
|
+
config: templateDefinition,
|
|
5027
|
+
handler: actualCallback
|
|
5028
|
+
});
|
|
5029
|
+
}
|
|
5030
|
+
return originalResourceTemplate.call(
|
|
5031
|
+
self,
|
|
5032
|
+
templateDefinition,
|
|
5033
|
+
callback
|
|
5034
|
+
);
|
|
5035
|
+
});
|
|
3354
5036
|
}
|
|
3355
5037
|
/**
|
|
3356
5038
|
* Create a new server instance for a session following official SDK pattern.
|
|
3357
5039
|
* This is called for each initialize request to create an isolated server.
|
|
3358
5040
|
*/
|
|
3359
5041
|
getServerForSession() {
|
|
3360
|
-
const newServer = new import_mcp2.McpServer(
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
5042
|
+
const newServer = new import_mcp2.McpServer(
|
|
5043
|
+
{
|
|
5044
|
+
name: this.config.name,
|
|
5045
|
+
version: this.config.version
|
|
5046
|
+
},
|
|
5047
|
+
{
|
|
5048
|
+
capabilities: {
|
|
5049
|
+
logging: {}
|
|
5050
|
+
}
|
|
5051
|
+
}
|
|
5052
|
+
);
|
|
5053
|
+
for (const [name, registration] of this.registrations.tools) {
|
|
5054
|
+
const { config, handler: actualCallback } = registration;
|
|
3366
5055
|
let inputSchema;
|
|
3367
5056
|
if (config.schema) {
|
|
3368
5057
|
inputSchema = this.convertZodSchemaToParams(config.schema);
|
|
@@ -3375,12 +5064,21 @@ var McpServer = class {
|
|
|
3375
5064
|
const initialRequestContext = getRequestContext();
|
|
3376
5065
|
const extraProgressToken = extra?._meta?.progressToken;
|
|
3377
5066
|
const extraSendNotification = extra?.sendNotification;
|
|
3378
|
-
const { requestContext, progressToken, sendNotification: sendNotification2 } = findSessionContext(
|
|
5067
|
+
const { requestContext, session, progressToken, sendNotification: sendNotification2 } = findSessionContext(
|
|
3379
5068
|
this.sessions,
|
|
3380
5069
|
initialRequestContext,
|
|
3381
5070
|
extraProgressToken,
|
|
3382
5071
|
extraSendNotification
|
|
3383
5072
|
);
|
|
5073
|
+
let sessionId;
|
|
5074
|
+
if (session) {
|
|
5075
|
+
for (const [id, s] of this.sessions.entries()) {
|
|
5076
|
+
if (s === session) {
|
|
5077
|
+
sessionId = id;
|
|
5078
|
+
break;
|
|
5079
|
+
}
|
|
5080
|
+
}
|
|
5081
|
+
}
|
|
3384
5082
|
const createMessageWithLogging = /* @__PURE__ */ __name(async (params2, options) => {
|
|
3385
5083
|
console.log("[createMessage] About to call server.createMessage");
|
|
3386
5084
|
console.log("[createMessage] Has server:", !!newServer);
|
|
@@ -3392,11 +5090,12 @@ var McpServer = class {
|
|
|
3392
5090
|
console.log("[createMessage] Got result successfully");
|
|
3393
5091
|
return result;
|
|
3394
5092
|
} catch (err) {
|
|
5093
|
+
const error2 = err;
|
|
3395
5094
|
console.error(
|
|
3396
5095
|
"[createMessage] Error:",
|
|
3397
|
-
|
|
5096
|
+
error2.message,
|
|
3398
5097
|
"Code:",
|
|
3399
|
-
|
|
5098
|
+
error2.code
|
|
3400
5099
|
);
|
|
3401
5100
|
throw err;
|
|
3402
5101
|
}
|
|
@@ -3406,7 +5105,11 @@ var McpServer = class {
|
|
|
3406
5105
|
createMessageWithLogging,
|
|
3407
5106
|
newServer.server.elicitInput.bind(newServer.server),
|
|
3408
5107
|
progressToken,
|
|
3409
|
-
sendNotification2
|
|
5108
|
+
sendNotification2,
|
|
5109
|
+
session?.logLevel,
|
|
5110
|
+
session?.clientCapabilities,
|
|
5111
|
+
sessionId,
|
|
5112
|
+
this.sessions
|
|
3410
5113
|
);
|
|
3411
5114
|
const executeCallback = /* @__PURE__ */ __name(async () => {
|
|
3412
5115
|
if (actualCallback.length >= 2) {
|
|
@@ -3414,10 +5117,26 @@ var McpServer = class {
|
|
|
3414
5117
|
}
|
|
3415
5118
|
return await actualCallback(params);
|
|
3416
5119
|
}, "executeCallback");
|
|
3417
|
-
|
|
3418
|
-
|
|
5120
|
+
const startTime = Date.now();
|
|
5121
|
+
let success = true;
|
|
5122
|
+
let errorType = null;
|
|
5123
|
+
try {
|
|
5124
|
+
const result = requestContext ? await runWithContext(requestContext, executeCallback) : await executeCallback();
|
|
5125
|
+
return result;
|
|
5126
|
+
} catch (err) {
|
|
5127
|
+
success = false;
|
|
5128
|
+
errorType = err instanceof Error ? err.name : "unknown_error";
|
|
5129
|
+
throw err;
|
|
5130
|
+
} finally {
|
|
5131
|
+
const executionTimeMs = Date.now() - startTime;
|
|
5132
|
+
Telemetry.getInstance().trackServerToolCall({
|
|
5133
|
+
toolName: name,
|
|
5134
|
+
lengthInputArgument: JSON.stringify(params).length,
|
|
5135
|
+
success,
|
|
5136
|
+
errorType,
|
|
5137
|
+
executionTimeMs
|
|
5138
|
+
}).catch((e) => console.debug(`Failed to track tool call: ${e}`));
|
|
3419
5139
|
}
|
|
3420
|
-
return await executeCallback();
|
|
3421
5140
|
}, "wrappedHandler");
|
|
3422
5141
|
newServer.registerTool(
|
|
3423
5142
|
name,
|
|
@@ -3431,21 +5150,38 @@ var McpServer = class {
|
|
|
3431
5150
|
wrappedHandler
|
|
3432
5151
|
);
|
|
3433
5152
|
}
|
|
3434
|
-
for (const [name,
|
|
3435
|
-
const { config, handler } =
|
|
5153
|
+
for (const [name, registration] of this.registrations.prompts) {
|
|
5154
|
+
const { config, handler } = registration;
|
|
3436
5155
|
let argsSchema;
|
|
3437
5156
|
if (config.schema) {
|
|
3438
5157
|
argsSchema = this.convertZodSchemaToParams(config.schema);
|
|
5158
|
+
} else if (config.args && config.args.length > 0) {
|
|
5159
|
+
argsSchema = this.createParamsSchema(config.args);
|
|
3439
5160
|
} else {
|
|
3440
|
-
argsSchema =
|
|
5161
|
+
argsSchema = void 0;
|
|
3441
5162
|
}
|
|
3442
|
-
const wrappedHandler = /* @__PURE__ */ __name(async (params) => {
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
5163
|
+
const wrappedHandler = /* @__PURE__ */ __name(async (params, extra) => {
|
|
5164
|
+
let success = true;
|
|
5165
|
+
let errorType = null;
|
|
5166
|
+
try {
|
|
5167
|
+
const result = await handler(params, extra);
|
|
5168
|
+
if ("messages" in result && Array.isArray(result.messages)) {
|
|
5169
|
+
return result;
|
|
5170
|
+
}
|
|
5171
|
+
const { convertToolResultToPromptResult: convertToolResultToPromptResult2 } = await Promise.resolve().then(() => (init_conversion2(), conversion_exports2));
|
|
5172
|
+
return convertToolResultToPromptResult2(result);
|
|
5173
|
+
} catch (err) {
|
|
5174
|
+
success = false;
|
|
5175
|
+
errorType = err instanceof Error ? err.name : "unknown_error";
|
|
5176
|
+
throw err;
|
|
5177
|
+
} finally {
|
|
5178
|
+
Telemetry.getInstance().trackServerPromptCall({
|
|
5179
|
+
name,
|
|
5180
|
+
description: config.description ?? null,
|
|
5181
|
+
success,
|
|
5182
|
+
errorType
|
|
5183
|
+
}).catch((e) => console.debug(`Failed to track prompt call: ${e}`));
|
|
3446
5184
|
}
|
|
3447
|
-
const { convertToolResultToPromptResult: convertToolResultToPromptResult2 } = await Promise.resolve().then(() => (init_conversion2(), conversion_exports2));
|
|
3448
|
-
return convertToolResultToPromptResult2(result);
|
|
3449
5185
|
}, "wrappedHandler");
|
|
3450
5186
|
newServer.registerPrompt(
|
|
3451
5187
|
name,
|
|
@@ -3457,15 +5193,42 @@ var McpServer = class {
|
|
|
3457
5193
|
wrappedHandler
|
|
3458
5194
|
);
|
|
3459
5195
|
}
|
|
3460
|
-
for (const [_key,
|
|
3461
|
-
const { config, handler } =
|
|
3462
|
-
const wrappedHandler = /* @__PURE__ */ __name(async () => {
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
5196
|
+
for (const [_key, registration] of this.registrations.resources) {
|
|
5197
|
+
const { config, handler } = registration;
|
|
5198
|
+
const wrappedHandler = /* @__PURE__ */ __name(async (extra) => {
|
|
5199
|
+
let success = true;
|
|
5200
|
+
let errorType = null;
|
|
5201
|
+
let contents = [];
|
|
5202
|
+
try {
|
|
5203
|
+
const result = await handler(extra);
|
|
5204
|
+
if ("contents" in result && Array.isArray(result.contents)) {
|
|
5205
|
+
contents = result.contents;
|
|
5206
|
+
return result;
|
|
5207
|
+
}
|
|
5208
|
+
const { convertToolResultToResourceResult: convertToolResultToResourceResult2 } = await Promise.resolve().then(() => (init_conversion(), conversion_exports));
|
|
5209
|
+
const converted = convertToolResultToResourceResult2(
|
|
5210
|
+
config.uri,
|
|
5211
|
+
result
|
|
5212
|
+
);
|
|
5213
|
+
contents = converted.contents || [];
|
|
5214
|
+
return converted;
|
|
5215
|
+
} catch (err) {
|
|
5216
|
+
success = false;
|
|
5217
|
+
errorType = err instanceof Error ? err.name : "unknown_error";
|
|
5218
|
+
throw err;
|
|
5219
|
+
} finally {
|
|
5220
|
+
Telemetry.getInstance().trackServerResourceCall({
|
|
5221
|
+
name: config.name,
|
|
5222
|
+
description: config.description ?? null,
|
|
5223
|
+
contents: contents.map((c) => ({
|
|
5224
|
+
mime_type: c.mimeType ?? null,
|
|
5225
|
+
text: c.text ? `[text: ${c.text.length} chars]` : null,
|
|
5226
|
+
blob: c.blob ? `[blob: ${c.blob.length} bytes]` : null
|
|
5227
|
+
})),
|
|
5228
|
+
success,
|
|
5229
|
+
errorType
|
|
5230
|
+
}).catch((e) => console.debug(`Failed to track resource call: ${e}`));
|
|
3466
5231
|
}
|
|
3467
|
-
const { convertToolResultToResourceResult: convertToolResultToResourceResult2 } = await Promise.resolve().then(() => (init_conversion(), conversion_exports));
|
|
3468
|
-
return convertToolResultToResourceResult2(config.uri, result);
|
|
3469
5232
|
}, "wrappedHandler");
|
|
3470
5233
|
newServer.registerResource(
|
|
3471
5234
|
config.name,
|
|
@@ -3478,24 +5241,25 @@ var McpServer = class {
|
|
|
3478
5241
|
wrappedHandler
|
|
3479
5242
|
);
|
|
3480
5243
|
}
|
|
3481
|
-
for (const [_name,
|
|
3482
|
-
const { config, handler } =
|
|
3483
|
-
const
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
5244
|
+
for (const [_name, registration] of this.registrations.resourceTemplates) {
|
|
5245
|
+
const { config, handler } = registration;
|
|
5246
|
+
const isFlatStructure = "uriTemplate" in config;
|
|
5247
|
+
const uriTemplate = isFlatStructure ? config.uriTemplate : config.resourceTemplate.uriTemplate;
|
|
5248
|
+
const mimeType = isFlatStructure ? config.mimeType : config.resourceTemplate.mimeType;
|
|
5249
|
+
const templateDescription = isFlatStructure ? void 0 : config.resourceTemplate.description;
|
|
5250
|
+
const template = new import_mcp2.ResourceTemplate(uriTemplate, {
|
|
5251
|
+
list: void 0,
|
|
5252
|
+
complete: void 0
|
|
5253
|
+
});
|
|
3490
5254
|
const metadata = {};
|
|
3491
5255
|
if (config.title) {
|
|
3492
5256
|
metadata.title = config.title;
|
|
3493
5257
|
}
|
|
3494
|
-
if (config.description ||
|
|
3495
|
-
metadata.description = config.description ||
|
|
5258
|
+
if (config.description || templateDescription) {
|
|
5259
|
+
metadata.description = config.description || templateDescription;
|
|
3496
5260
|
}
|
|
3497
|
-
if (
|
|
3498
|
-
metadata.mimeType =
|
|
5261
|
+
if (mimeType) {
|
|
5262
|
+
metadata.mimeType = mimeType;
|
|
3499
5263
|
}
|
|
3500
5264
|
if (config.annotations) {
|
|
3501
5265
|
metadata.annotations = config.annotations;
|
|
@@ -3504,20 +5268,90 @@ var McpServer = class {
|
|
|
3504
5268
|
config.name,
|
|
3505
5269
|
template,
|
|
3506
5270
|
metadata,
|
|
3507
|
-
async (uri) => {
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
5271
|
+
async (uri, extra) => {
|
|
5272
|
+
let success = true;
|
|
5273
|
+
let errorType = null;
|
|
5274
|
+
let contents = [];
|
|
5275
|
+
try {
|
|
5276
|
+
const params = this.parseTemplateUri(uriTemplate, uri.toString());
|
|
5277
|
+
const result = await handler(uri, params, extra);
|
|
5278
|
+
if ("contents" in result && Array.isArray(result.contents)) {
|
|
5279
|
+
contents = result.contents;
|
|
5280
|
+
return result;
|
|
5281
|
+
}
|
|
5282
|
+
const { convertToolResultToResourceResult: convertToolResultToResourceResult2 } = await Promise.resolve().then(() => (init_conversion(), conversion_exports));
|
|
5283
|
+
const converted = convertToolResultToResourceResult2(
|
|
5284
|
+
uri.toString(),
|
|
5285
|
+
result
|
|
5286
|
+
);
|
|
5287
|
+
contents = converted.contents || [];
|
|
5288
|
+
return converted;
|
|
5289
|
+
} catch (err) {
|
|
5290
|
+
success = false;
|
|
5291
|
+
errorType = err instanceof Error ? err.name : "unknown_error";
|
|
5292
|
+
throw err;
|
|
5293
|
+
} finally {
|
|
5294
|
+
Telemetry.getInstance().trackServerResourceCall({
|
|
5295
|
+
name: config.name,
|
|
5296
|
+
description: config.description ?? null,
|
|
5297
|
+
contents: contents.map((c) => ({
|
|
5298
|
+
mimeType: c.mimeType ?? null,
|
|
5299
|
+
text: c.text ? `[text: ${c.text.length} chars]` : null,
|
|
5300
|
+
blob: c.blob ? `[blob: ${c.blob.length} bytes]` : null
|
|
5301
|
+
})),
|
|
5302
|
+
success,
|
|
5303
|
+
errorType
|
|
5304
|
+
}).catch(
|
|
5305
|
+
(e) => console.debug(`Failed to track resource template call: ${e}`)
|
|
5306
|
+
);
|
|
3515
5307
|
}
|
|
3516
|
-
const { convertToolResultToResourceResult: convertToolResultToResourceResult2 } = await Promise.resolve().then(() => (init_conversion(), conversion_exports));
|
|
3517
|
-
return convertToolResultToResourceResult2(uri.toString(), result);
|
|
3518
5308
|
}
|
|
3519
5309
|
);
|
|
3520
5310
|
}
|
|
5311
|
+
newServer.server.setRequestHandler(
|
|
5312
|
+
import_zod2.z.object({ method: import_zod2.z.literal("logging/setLevel") }).passthrough(),
|
|
5313
|
+
(async (request, extra) => {
|
|
5314
|
+
const level = request.params?.level;
|
|
5315
|
+
if (!level) {
|
|
5316
|
+
throw new import_types2.McpError(
|
|
5317
|
+
import_types2.ErrorCode.InvalidParams,
|
|
5318
|
+
"Missing 'level' parameter"
|
|
5319
|
+
);
|
|
5320
|
+
}
|
|
5321
|
+
if (!isValidLogLevel(level)) {
|
|
5322
|
+
throw new import_types2.McpError(
|
|
5323
|
+
import_types2.ErrorCode.InvalidParams,
|
|
5324
|
+
`Invalid log level '${level}'. Must be one of: debug, info, notice, warning, error, critical, alert, emergency`
|
|
5325
|
+
);
|
|
5326
|
+
}
|
|
5327
|
+
const requestContext = getRequestContext();
|
|
5328
|
+
if (requestContext) {
|
|
5329
|
+
const sessionId = requestContext.req.header("mcp-session-id");
|
|
5330
|
+
if (sessionId && this.sessions.has(sessionId)) {
|
|
5331
|
+
const session = this.sessions.get(sessionId);
|
|
5332
|
+
session.logLevel = level;
|
|
5333
|
+
console.log(
|
|
5334
|
+
`[MCP] Set log level to '${level}' for session ${sessionId}`
|
|
5335
|
+
);
|
|
5336
|
+
return {};
|
|
5337
|
+
}
|
|
5338
|
+
}
|
|
5339
|
+
for (const [sessionId, session] of this.sessions.entries()) {
|
|
5340
|
+
if (session.server === newServer) {
|
|
5341
|
+
session.logLevel = level;
|
|
5342
|
+
console.log(
|
|
5343
|
+
`[MCP] Set log level to '${level}' for session ${sessionId}`
|
|
5344
|
+
);
|
|
5345
|
+
return {};
|
|
5346
|
+
}
|
|
5347
|
+
}
|
|
5348
|
+
console.warn(
|
|
5349
|
+
"[MCP] Could not find session for logging/setLevel request"
|
|
5350
|
+
);
|
|
5351
|
+
throw new import_types2.McpError(import_types2.ErrorCode.InternalError, "Could not find session");
|
|
5352
|
+
})
|
|
5353
|
+
);
|
|
5354
|
+
this.subscriptionManager.registerHandlers(newServer, this.sessions);
|
|
3521
5355
|
return newServer;
|
|
3522
5356
|
}
|
|
3523
5357
|
/**
|
|
@@ -3531,23 +5365,43 @@ var McpServer = class {
|
|
|
3531
5365
|
this.serverPort
|
|
3532
5366
|
);
|
|
3533
5367
|
}
|
|
3534
|
-
// Tool registration helper
|
|
3535
|
-
tool
|
|
5368
|
+
// Tool registration helper - type is set in wrapRegistrationMethods
|
|
5369
|
+
tool;
|
|
3536
5370
|
// Schema conversion helpers (used by tool registration)
|
|
3537
5371
|
convertZodSchemaToParams = convertZodSchemaToParams;
|
|
3538
5372
|
createParamsSchema = createParamsSchema;
|
|
3539
5373
|
// Template URI parsing helper (used by resource templates)
|
|
3540
5374
|
parseTemplateUri = parseTemplateUri;
|
|
3541
|
-
// Resource registration helpers
|
|
3542
|
-
resource
|
|
3543
|
-
resourceTemplate
|
|
3544
|
-
// Prompt registration helper
|
|
3545
|
-
prompt
|
|
5375
|
+
// Resource registration helpers - types are set in wrapRegistrationMethods
|
|
5376
|
+
resource;
|
|
5377
|
+
resourceTemplate;
|
|
5378
|
+
// Prompt registration helper - type is set in wrapRegistrationMethods
|
|
5379
|
+
prompt;
|
|
3546
5380
|
// Notification helpers
|
|
3547
5381
|
getActiveSessions = getActiveSessions;
|
|
3548
5382
|
sendNotification = sendNotification;
|
|
3549
5383
|
sendNotificationToSession = sendNotificationToSession2;
|
|
3550
|
-
|
|
5384
|
+
/**
|
|
5385
|
+
* Notify subscribed clients that a resource has been updated
|
|
5386
|
+
*
|
|
5387
|
+
* This method sends a `notifications/resources/updated` notification to all
|
|
5388
|
+
* sessions that have subscribed to the specified resource URI.
|
|
5389
|
+
*
|
|
5390
|
+
* @param uri - The URI of the resource that changed
|
|
5391
|
+
* @returns Promise that resolves when all notifications have been sent
|
|
5392
|
+
*
|
|
5393
|
+
* @example
|
|
5394
|
+
* ```typescript
|
|
5395
|
+
* // After updating a resource, notify subscribers
|
|
5396
|
+
* await server.notifyResourceUpdated("file:///path/to/resource.txt");
|
|
5397
|
+
* ```
|
|
5398
|
+
*/
|
|
5399
|
+
async notifyResourceUpdated(uri) {
|
|
5400
|
+
return this.subscriptionManager.notifyResourceUpdated(uri, this.sessions);
|
|
5401
|
+
}
|
|
5402
|
+
uiResource = /* @__PURE__ */ __name((definition) => {
|
|
5403
|
+
return uiResourceRegistration(this, definition);
|
|
5404
|
+
}, "uiResource");
|
|
3551
5405
|
/**
|
|
3552
5406
|
* Mount MCP server endpoints at /mcp and /sse
|
|
3553
5407
|
*
|
|
@@ -3572,7 +5426,7 @@ var McpServer = class {
|
|
|
3572
5426
|
const result = await mountMcp(
|
|
3573
5427
|
this.app,
|
|
3574
5428
|
this,
|
|
3575
|
-
// Pass the
|
|
5429
|
+
// Pass the MCPServer instance so mountMcp can call getServerForSession()
|
|
3576
5430
|
this.sessions,
|
|
3577
5431
|
this.config,
|
|
3578
5432
|
isProductionMode()
|
|
@@ -3630,7 +5484,12 @@ var McpServer = class {
|
|
|
3630
5484
|
if (hostEnv) {
|
|
3631
5485
|
this.serverHost = hostEnv;
|
|
3632
5486
|
}
|
|
3633
|
-
|
|
5487
|
+
this.serverBaseUrl = getServerBaseUrl(
|
|
5488
|
+
this.serverBaseUrl,
|
|
5489
|
+
this.serverHost,
|
|
5490
|
+
this.serverPort
|
|
5491
|
+
);
|
|
5492
|
+
if (this.oauthProvider && !this.oauthSetupState.complete) {
|
|
3634
5493
|
await setupOAuthForServer(
|
|
3635
5494
|
this.app,
|
|
3636
5495
|
this.oauthProvider,
|
|
@@ -3645,10 +5504,14 @@ var McpServer = class {
|
|
|
3645
5504
|
await this.mountMcp();
|
|
3646
5505
|
await this.mountInspector();
|
|
3647
5506
|
this.logRegisteredItems();
|
|
5507
|
+
this._trackServerRun("http");
|
|
3648
5508
|
await startServer(this.app, this.serverPort, this.serverHost, {
|
|
3649
5509
|
onDenoRequest: rewriteSupabaseRequest
|
|
3650
5510
|
});
|
|
3651
5511
|
}
|
|
5512
|
+
_trackServerRun(transport) {
|
|
5513
|
+
Telemetry.getInstance().trackServerRunFromServer(this, transport).catch((e) => console.debug(`Failed to track server run: ${e}`));
|
|
5514
|
+
}
|
|
3652
5515
|
/**
|
|
3653
5516
|
* Get the fetch handler for the server after mounting all endpoints
|
|
3654
5517
|
*
|
|
@@ -3667,7 +5530,7 @@ var McpServer = class {
|
|
|
3667
5530
|
* @example
|
|
3668
5531
|
* ```typescript
|
|
3669
5532
|
* // For Supabase Edge Functions (handles path rewriting automatically)
|
|
3670
|
-
* const server =
|
|
5533
|
+
* const server = new MCPServer({ name: 'my-server', version: '1.0.0' });
|
|
3671
5534
|
* server.tool({ ... });
|
|
3672
5535
|
* const handler = await server.getHandler({ provider: 'supabase' });
|
|
3673
5536
|
* Deno.serve(handler);
|
|
@@ -3676,14 +5539,14 @@ var McpServer = class {
|
|
|
3676
5539
|
* @example
|
|
3677
5540
|
* ```typescript
|
|
3678
5541
|
* // For Cloudflare Workers
|
|
3679
|
-
* const server =
|
|
5542
|
+
* const server = new MCPServer({ name: 'my-server', version: '1.0.0' });
|
|
3680
5543
|
* server.tool({ ... });
|
|
3681
5544
|
* const handler = await server.getHandler();
|
|
3682
5545
|
* export default { fetch: handler };
|
|
3683
5546
|
* ```
|
|
3684
5547
|
*/
|
|
3685
5548
|
async getHandler(options) {
|
|
3686
|
-
if (this.
|
|
5549
|
+
if (this.oauthProvider && !this.oauthSetupState.complete) {
|
|
3687
5550
|
await setupOAuthForServer(
|
|
3688
5551
|
this.app,
|
|
3689
5552
|
this.oauthProvider,
|
|
@@ -3702,6 +5565,8 @@ var McpServer = class {
|
|
|
3702
5565
|
console.log("[MCP] Mounting inspector");
|
|
3703
5566
|
await this.mountInspector();
|
|
3704
5567
|
console.log("[MCP] Mounted inspector");
|
|
5568
|
+
const provider = options?.provider || "fetch";
|
|
5569
|
+
this._trackServerRun(provider);
|
|
3705
5570
|
const fetchHandler = this.app.fetch.bind(this.app);
|
|
3706
5571
|
if (options?.provider === "supabase") {
|
|
3707
5572
|
return async (req) => {
|
|
@@ -3753,8 +5618,9 @@ var McpServer = class {
|
|
|
3753
5618
|
}
|
|
3754
5619
|
}
|
|
3755
5620
|
};
|
|
5621
|
+
var MCPServer = MCPServerClass;
|
|
3756
5622
|
function createMCPServer(name, config = {}) {
|
|
3757
|
-
const instance = new
|
|
5623
|
+
const instance = new MCPServerClass({
|
|
3758
5624
|
name,
|
|
3759
5625
|
version: config.version || "1.0.0",
|
|
3760
5626
|
description: config.description,
|
|
@@ -3770,6 +5636,7 @@ function createMCPServer(name, config = {}) {
|
|
|
3770
5636
|
__name(createMCPServer, "createMCPServer");
|
|
3771
5637
|
|
|
3772
5638
|
// src/server/index.ts
|
|
5639
|
+
init_version();
|
|
3773
5640
|
init_context_storage();
|
|
3774
5641
|
|
|
3775
5642
|
// src/server/oauth/providers/supabase.ts
|
|
@@ -3836,12 +5703,13 @@ var SupabaseOAuthProvider = class {
|
|
|
3836
5703
|
}
|
|
3837
5704
|
}
|
|
3838
5705
|
getUserInfo(payload) {
|
|
5706
|
+
const userMetadata = payload.user_metadata;
|
|
3839
5707
|
return {
|
|
3840
5708
|
userId: payload.sub || payload.user_id,
|
|
3841
5709
|
email: payload.email,
|
|
3842
|
-
name:
|
|
3843
|
-
username:
|
|
3844
|
-
picture:
|
|
5710
|
+
name: userMetadata?.name || userMetadata?.full_name,
|
|
5711
|
+
username: userMetadata?.username,
|
|
5712
|
+
picture: userMetadata?.avatar_url,
|
|
3845
5713
|
roles: payload.role ? [payload.role] : [],
|
|
3846
5714
|
permissions: payload.aal ? [`aal:${payload.aal}`] : [],
|
|
3847
5715
|
// Include Supabase-specific claims
|
|
@@ -3914,6 +5782,7 @@ var Auth0OAuthProvider = class {
|
|
|
3914
5782
|
}
|
|
3915
5783
|
}
|
|
3916
5784
|
getUserInfo(payload) {
|
|
5785
|
+
const scope = payload.scope;
|
|
3917
5786
|
return {
|
|
3918
5787
|
userId: payload.sub,
|
|
3919
5788
|
email: payload.email,
|
|
@@ -3926,7 +5795,7 @@ var Auth0OAuthProvider = class {
|
|
|
3926
5795
|
// Auth0 can include roles (if configured)
|
|
3927
5796
|
roles: payload.roles || payload["https://your-app.com/roles"] || [],
|
|
3928
5797
|
// Include scope as well
|
|
3929
|
-
scopes:
|
|
5798
|
+
scopes: scope ? scope.split(" ") : [],
|
|
3930
5799
|
// Additional Auth0-specific claims
|
|
3931
5800
|
email_verified: payload.email_verified,
|
|
3932
5801
|
updated_at: payload.updated_at
|
|
@@ -3998,8 +5867,10 @@ var KeycloakOAuthProvider = class {
|
|
|
3998
5867
|
}
|
|
3999
5868
|
}
|
|
4000
5869
|
getUserInfo(payload) {
|
|
4001
|
-
const
|
|
4002
|
-
const
|
|
5870
|
+
const realmAccess = payload.realm_access;
|
|
5871
|
+
const realmRoles = realmAccess?.roles || [];
|
|
5872
|
+
const resourceAccess = payload.resource_access;
|
|
5873
|
+
const clientRoles = this.config.clientId && (resourceAccess?.[this.config.clientId]?.roles || []) || [];
|
|
4003
5874
|
const allRoles = [...realmRoles, ...clientRoles];
|
|
4004
5875
|
const permissions = [];
|
|
4005
5876
|
if (payload.resource_access) {
|
|
@@ -4013,6 +5884,7 @@ var KeycloakOAuthProvider = class {
|
|
|
4013
5884
|
}
|
|
4014
5885
|
);
|
|
4015
5886
|
}
|
|
5887
|
+
const scope = payload.scope;
|
|
4016
5888
|
return {
|
|
4017
5889
|
userId: payload.sub,
|
|
4018
5890
|
email: payload.email,
|
|
@@ -4023,7 +5895,7 @@ var KeycloakOAuthProvider = class {
|
|
|
4023
5895
|
roles: allRoles,
|
|
4024
5896
|
permissions,
|
|
4025
5897
|
// Include scope as well
|
|
4026
|
-
scopes:
|
|
5898
|
+
scopes: scope ? scope.split(" ") : [],
|
|
4027
5899
|
// Keycloak-specific claims
|
|
4028
5900
|
email_verified: payload.email_verified,
|
|
4029
5901
|
given_name: payload.given_name,
|
|
@@ -4152,7 +6024,7 @@ var CustomOAuthProvider = class {
|
|
|
4152
6024
|
async verifyToken(token) {
|
|
4153
6025
|
try {
|
|
4154
6026
|
const result = await this.config.verifyToken(token);
|
|
4155
|
-
return
|
|
6027
|
+
return result;
|
|
4156
6028
|
} catch (error2) {
|
|
4157
6029
|
throw new Error(`Custom OAuth verification failed: ${error2}`);
|
|
4158
6030
|
}
|
|
@@ -4161,16 +6033,19 @@ var CustomOAuthProvider = class {
|
|
|
4161
6033
|
if (this.config.getUserInfo) {
|
|
4162
6034
|
return this.config.getUserInfo(payload);
|
|
4163
6035
|
}
|
|
6036
|
+
const scope = payload.scope;
|
|
6037
|
+
const roles = payload.roles;
|
|
6038
|
+
const permissions = payload.permissions;
|
|
4164
6039
|
return {
|
|
4165
6040
|
userId: payload.sub || payload.user_id || payload.id,
|
|
4166
|
-
email: payload.email,
|
|
4167
|
-
name: payload.name,
|
|
4168
|
-
username: payload.username || payload.preferred_username,
|
|
4169
|
-
nickname: payload.nickname,
|
|
4170
|
-
picture: payload.picture || payload.avatar_url,
|
|
4171
|
-
roles:
|
|
4172
|
-
permissions:
|
|
4173
|
-
scopes:
|
|
6041
|
+
email: payload.email ? payload.email : void 0,
|
|
6042
|
+
name: payload.name ? payload.name : void 0,
|
|
6043
|
+
username: payload.username || payload.preferred_username ? payload.username || payload.preferred_username : void 0,
|
|
6044
|
+
nickname: payload.nickname ? payload.nickname : void 0,
|
|
6045
|
+
picture: payload.picture || payload.avatar_url ? payload.picture || payload.avatar_url : void 0,
|
|
6046
|
+
roles: Array.isArray(roles) ? roles : [],
|
|
6047
|
+
permissions: Array.isArray(permissions) ? permissions : [],
|
|
6048
|
+
scopes: scope ? scope.split(" ") : []
|
|
4174
6049
|
};
|
|
4175
6050
|
}
|
|
4176
6051
|
getIssuer() {
|