mcp-use 1.34.2 → 1.34.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/{chunk-QNMWBM3V.js → chunk-4GUL52TF.js} +1 -1
- package/dist/{chunk-3L7F47SI.js → chunk-BJIP3NFE.js} +4 -4
- package/dist/{chunk-Z3NHDOLS.js → chunk-CQPVGLM4.js} +1 -1
- package/dist/{chunk-P2JIVJY6.js → chunk-CXHJETCQ.js} +4 -4
- package/dist/{chunk-VJAQ2A7N.js → chunk-GTLSCTCO.js} +1 -1
- package/dist/{chunk-EJOL74UE.js → chunk-J67NWN5H.js} +1 -1
- package/dist/{chunk-6DJM56C3.js → chunk-KWYZMUVB.js} +2 -2
- package/dist/chunk-KX7P6L43.js +171 -0
- package/dist/{chunk-VT4KQHJI.js → chunk-MCYFETK3.js} +2 -2
- package/dist/{chunk-DENFIIV2.js → chunk-NJPLVA2I.js} +1 -1
- package/dist/chunk-NQYSWKWJ.js +2609 -0
- package/dist/{chunk-OYFQOSSW.js → chunk-NYIMA6MZ.js} +1 -1
- package/dist/chunk-PJB2MFKZ.js +954 -0
- package/dist/chunk-PSD6ATRG.js +562 -0
- package/dist/{chunk-T3QVQIYU.js → chunk-QLKY4PK3.js} +5 -5
- package/dist/chunk-SUVUANZ3.js +594 -0
- package/dist/chunk-XHP35F4S.js +204 -0
- package/dist/chunk-ZLHL3BY6.js +2690 -0
- package/dist/{client-24ODJASB.js → client-VKWZPQCL.js} +4 -4
- package/dist/index.cjs +1 -1
- package/dist/index.js +6 -6
- package/dist/src/agents/index.cjs +1 -1
- package/dist/src/agents/index.js +4 -4
- package/dist/src/browser-agent.cjs +1 -1
- package/dist/src/browser-agent.js +2 -2
- package/dist/src/browser.cjs +1 -1
- package/dist/src/browser.js +4 -4
- package/dist/src/client.cjs +1 -1
- package/dist/src/client.js +4 -4
- package/dist/src/react/index.cjs +1 -1
- package/dist/src/react/index.js +4 -4
- package/dist/src/server/index.cjs +1 -1
- package/dist/src/server/index.js +7 -7
- package/dist/src/version.d.ts +1 -1
- package/dist/{stdio-CG6YESIU.js → stdio-37X7ETM7.js} +3 -3
- package/dist/{stdio-KZLWEEYB.js → stdio-CSGVA5IJ.js} +2 -2
- package/dist/stdio-FUBSRH66.js +13 -0
- package/dist/{tool-execution-helpers-GVP22F32.js → tool-execution-helpers-4LIAFMYM.js} +2 -2
- package/dist/tool-execution-helpers-HPVG5WVB.js +27 -0
- package/package.json +3 -3
|
@@ -0,0 +1,594 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getRequestContext
|
|
3
|
+
} from "./chunk-G7JEMXJW.js";
|
|
4
|
+
import {
|
|
5
|
+
ElicitationValidationError
|
|
6
|
+
} from "./chunk-KUEVOU4M.js";
|
|
7
|
+
import {
|
|
8
|
+
Telemetry
|
|
9
|
+
} from "./chunk-BJIP3NFE.js";
|
|
10
|
+
import {
|
|
11
|
+
generateUUID
|
|
12
|
+
} from "./chunk-MTHLLDCX.js";
|
|
13
|
+
import {
|
|
14
|
+
__name
|
|
15
|
+
} from "./chunk-3GQAWCBQ.js";
|
|
16
|
+
|
|
17
|
+
// src/server/tools/tool-execution-helpers.ts
|
|
18
|
+
import { toJsonSchemaCompat } from "@modelcontextprotocol/sdk/server/zod-json-schema-compat.js";
|
|
19
|
+
function extractContextData(honoCtx) {
|
|
20
|
+
const data = {};
|
|
21
|
+
try {
|
|
22
|
+
const varObj = honoCtx.var;
|
|
23
|
+
if (varObj && typeof varObj === "object") {
|
|
24
|
+
for (const [key, value] of Object.entries(varObj)) {
|
|
25
|
+
data[key] = value;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
} catch {
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const auth = honoCtx.get("auth");
|
|
32
|
+
if (auth) data.auth = auth;
|
|
33
|
+
} catch {
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
data.req = honoCtx.req;
|
|
37
|
+
} catch {
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
data.env = honoCtx.env;
|
|
41
|
+
} catch {
|
|
42
|
+
}
|
|
43
|
+
data.get = (key) => data[key];
|
|
44
|
+
data.set = (key, value) => {
|
|
45
|
+
data[key] = value;
|
|
46
|
+
};
|
|
47
|
+
return data;
|
|
48
|
+
}
|
|
49
|
+
__name(extractContextData, "extractContextData");
|
|
50
|
+
function normalizeUserContext(rawMeta) {
|
|
51
|
+
if (!rawMeta) return void 0;
|
|
52
|
+
const userAgent = rawMeta["openai/userAgent"];
|
|
53
|
+
const locale = rawMeta["openai/locale"];
|
|
54
|
+
const rawLocation = rawMeta["openai/userLocation"];
|
|
55
|
+
const timezoneOffsetMinutes = typeof rawMeta["timezone_offset_minutes"] === "number" ? rawMeta["timezone_offset_minutes"] : void 0;
|
|
56
|
+
const subject = rawMeta["openai/subject"];
|
|
57
|
+
const conversationId = rawMeta["openai/session"];
|
|
58
|
+
const location = rawLocation ? {
|
|
59
|
+
city: rawLocation.city,
|
|
60
|
+
region: rawLocation.region,
|
|
61
|
+
country: rawLocation.country,
|
|
62
|
+
timezone: rawLocation.timezone,
|
|
63
|
+
latitude: rawLocation.latitude,
|
|
64
|
+
longitude: rawLocation.longitude
|
|
65
|
+
} : void 0;
|
|
66
|
+
const hasAnyField = userAgent !== void 0 || locale !== void 0 || location !== void 0 || timezoneOffsetMinutes !== void 0 || subject !== void 0 || conversationId !== void 0;
|
|
67
|
+
if (!hasAnyField) return void 0;
|
|
68
|
+
return {
|
|
69
|
+
...userAgent !== void 0 && { userAgent },
|
|
70
|
+
...locale !== void 0 && { locale },
|
|
71
|
+
...location !== void 0 && { location },
|
|
72
|
+
...timezoneOffsetMinutes !== void 0 && { timezoneOffsetMinutes },
|
|
73
|
+
...subject !== void 0 && { subject },
|
|
74
|
+
...conversationId !== void 0 && { conversationId }
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
__name(normalizeUserContext, "normalizeUserContext");
|
|
78
|
+
function findSessionContext(sessions, initialRequestContext, extraProgressToken, extraSendNotification) {
|
|
79
|
+
const requestContext = initialRequestContext;
|
|
80
|
+
let session;
|
|
81
|
+
let progressToken = extraProgressToken;
|
|
82
|
+
let sendNotification = extraSendNotification;
|
|
83
|
+
if (requestContext) {
|
|
84
|
+
for (const [, s] of sessions.entries()) {
|
|
85
|
+
if (s.context === requestContext) {
|
|
86
|
+
session = s;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (session) {
|
|
92
|
+
if (!progressToken && session.progressToken) {
|
|
93
|
+
progressToken = session.progressToken;
|
|
94
|
+
}
|
|
95
|
+
if (!sendNotification && session.sendNotification) {
|
|
96
|
+
sendNotification = session.sendNotification;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return { requestContext, session, progressToken, sendNotification };
|
|
100
|
+
}
|
|
101
|
+
__name(findSessionContext, "findSessionContext");
|
|
102
|
+
async function sendProgressNotification(sendNotification, progressToken, progress, total, message) {
|
|
103
|
+
if (sendNotification && progressToken !== void 0) {
|
|
104
|
+
try {
|
|
105
|
+
await sendNotification({
|
|
106
|
+
method: "notifications/progress",
|
|
107
|
+
params: {
|
|
108
|
+
progressToken,
|
|
109
|
+
progress,
|
|
110
|
+
total,
|
|
111
|
+
message
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
} catch {
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
__name(sendProgressNotification, "sendProgressNotification");
|
|
119
|
+
async function withTimeout(promise, timeout, errorMessage) {
|
|
120
|
+
if (timeout && timeout !== Infinity) {
|
|
121
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
122
|
+
setTimeout(() => reject(new Error(errorMessage)), timeout);
|
|
123
|
+
});
|
|
124
|
+
return await Promise.race([promise, timeoutPromise]);
|
|
125
|
+
}
|
|
126
|
+
return await promise;
|
|
127
|
+
}
|
|
128
|
+
__name(withTimeout, "withTimeout");
|
|
129
|
+
function parseElicitParams(messageOrParams, schemaOrUrlOrOptions, maybeOptions) {
|
|
130
|
+
let sdkParams;
|
|
131
|
+
let zodSchema = null;
|
|
132
|
+
let options;
|
|
133
|
+
if (typeof messageOrParams === "string") {
|
|
134
|
+
const message = messageOrParams;
|
|
135
|
+
if (typeof schemaOrUrlOrOptions === "string") {
|
|
136
|
+
options = maybeOptions;
|
|
137
|
+
const elicitationId = `elicit-${generateUUID()}`;
|
|
138
|
+
sdkParams = {
|
|
139
|
+
mode: "url",
|
|
140
|
+
message,
|
|
141
|
+
url: schemaOrUrlOrOptions,
|
|
142
|
+
elicitationId
|
|
143
|
+
};
|
|
144
|
+
} else if (schemaOrUrlOrOptions && typeof schemaOrUrlOrOptions === "object" && "_def" in schemaOrUrlOrOptions) {
|
|
145
|
+
options = maybeOptions;
|
|
146
|
+
zodSchema = schemaOrUrlOrOptions;
|
|
147
|
+
const jsonSchema = toJsonSchemaCompat(schemaOrUrlOrOptions);
|
|
148
|
+
sdkParams = {
|
|
149
|
+
mode: "form",
|
|
150
|
+
message,
|
|
151
|
+
requestedSchema: jsonSchema
|
|
152
|
+
};
|
|
153
|
+
} else {
|
|
154
|
+
throw new Error(
|
|
155
|
+
"Invalid elicit signature: second parameter must be a Zod schema or URL string"
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
options = schemaOrUrlOrOptions;
|
|
160
|
+
const params = messageOrParams;
|
|
161
|
+
if (params.mode === "url") {
|
|
162
|
+
const elicitationId = `elicit-${generateUUID()}`;
|
|
163
|
+
sdkParams = {
|
|
164
|
+
mode: "url",
|
|
165
|
+
message: params.message,
|
|
166
|
+
url: params.url,
|
|
167
|
+
elicitationId
|
|
168
|
+
};
|
|
169
|
+
} else {
|
|
170
|
+
sdkParams = {
|
|
171
|
+
mode: "form",
|
|
172
|
+
message: params.message,
|
|
173
|
+
requestedSchema: params.requestedSchema
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return { sdkParams, zodSchema, options };
|
|
178
|
+
}
|
|
179
|
+
__name(parseElicitParams, "parseElicitParams");
|
|
180
|
+
function createSampleMethod(createMessage, progressToken, sendNotification) {
|
|
181
|
+
return async (promptOrParams, options) => {
|
|
182
|
+
let sampleParams;
|
|
183
|
+
if (typeof promptOrParams === "string") {
|
|
184
|
+
sampleParams = {
|
|
185
|
+
messages: [
|
|
186
|
+
{
|
|
187
|
+
role: "user",
|
|
188
|
+
content: {
|
|
189
|
+
type: "text",
|
|
190
|
+
text: promptOrParams
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
],
|
|
194
|
+
maxTokens: options?.maxTokens || 1e3,
|
|
195
|
+
...options?.modelPreferences && {
|
|
196
|
+
modelPreferences: options.modelPreferences
|
|
197
|
+
},
|
|
198
|
+
...options?.systemPrompt && { systemPrompt: options.systemPrompt },
|
|
199
|
+
...options?.temperature !== void 0 && {
|
|
200
|
+
temperature: options.temperature
|
|
201
|
+
},
|
|
202
|
+
...options?.stopSequences && { stopSequences: options.stopSequences },
|
|
203
|
+
...options?.metadata && { metadata: options.metadata }
|
|
204
|
+
};
|
|
205
|
+
} else {
|
|
206
|
+
sampleParams = promptOrParams;
|
|
207
|
+
}
|
|
208
|
+
const { timeout, progressIntervalMs = 5e3, onProgress } = options ?? {};
|
|
209
|
+
let progressCount = 0;
|
|
210
|
+
let completed = false;
|
|
211
|
+
let progressInterval = null;
|
|
212
|
+
if (progressToken !== void 0 && sendNotification) {
|
|
213
|
+
progressInterval = setInterval(async () => {
|
|
214
|
+
if (completed) return;
|
|
215
|
+
progressCount++;
|
|
216
|
+
const progressData = {
|
|
217
|
+
progress: progressCount,
|
|
218
|
+
total: void 0,
|
|
219
|
+
message: `Waiting for LLM response... (${progressCount * Math.round(progressIntervalMs / 1e3)}s elapsed)`
|
|
220
|
+
};
|
|
221
|
+
if (onProgress) {
|
|
222
|
+
try {
|
|
223
|
+
onProgress(progressData);
|
|
224
|
+
} catch {
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
await sendProgressNotification(
|
|
228
|
+
sendNotification,
|
|
229
|
+
progressToken,
|
|
230
|
+
progressData.progress,
|
|
231
|
+
progressData.total,
|
|
232
|
+
progressData.message
|
|
233
|
+
);
|
|
234
|
+
}, progressIntervalMs);
|
|
235
|
+
}
|
|
236
|
+
try {
|
|
237
|
+
console.log("[SAMPLING DEBUG] Calling createMessage...");
|
|
238
|
+
const sdkTimeout = timeout && timeout !== Infinity ? timeout : 2147483647;
|
|
239
|
+
const samplePromise = createMessage(sampleParams, {
|
|
240
|
+
timeout: sdkTimeout
|
|
241
|
+
});
|
|
242
|
+
console.log("[SAMPLING DEBUG] Waiting for response...");
|
|
243
|
+
const result = await withTimeout(
|
|
244
|
+
samplePromise,
|
|
245
|
+
timeout,
|
|
246
|
+
`Sampling timed out after ${timeout}ms`
|
|
247
|
+
);
|
|
248
|
+
console.log("[SAMPLING DEBUG] Got result:", result);
|
|
249
|
+
Telemetry.getInstance().trackServerContext({
|
|
250
|
+
contextType: "sample"
|
|
251
|
+
}).catch((e) => console.debug(`Failed to track sample context: ${e}`));
|
|
252
|
+
return result;
|
|
253
|
+
} catch (error) {
|
|
254
|
+
console.error("[SAMPLING DEBUG] Error during sampling:", error);
|
|
255
|
+
throw error;
|
|
256
|
+
} finally {
|
|
257
|
+
completed = true;
|
|
258
|
+
if (progressInterval) {
|
|
259
|
+
clearInterval(progressInterval);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
__name(createSampleMethod, "createSampleMethod");
|
|
265
|
+
function createElicitMethod(elicitInput) {
|
|
266
|
+
return async (messageOrParams, schemaOrUrlOrOptions, maybeOptions) => {
|
|
267
|
+
const { sdkParams, zodSchema, options } = parseElicitParams(
|
|
268
|
+
messageOrParams,
|
|
269
|
+
schemaOrUrlOrOptions,
|
|
270
|
+
maybeOptions
|
|
271
|
+
);
|
|
272
|
+
const { timeout } = options ?? {};
|
|
273
|
+
const sdkTimeout = timeout && timeout !== Infinity ? timeout : 2147483647;
|
|
274
|
+
const result = await elicitInput(sdkParams, { timeout: sdkTimeout });
|
|
275
|
+
Telemetry.getInstance().trackServerContext({
|
|
276
|
+
contextType: "elicit"
|
|
277
|
+
}).catch((e) => console.debug(`Failed to track elicit context: ${e}`));
|
|
278
|
+
const inputData = result.data ?? result.content;
|
|
279
|
+
if (zodSchema && result.action === "accept" && inputData) {
|
|
280
|
+
try {
|
|
281
|
+
const validatedData = zodSchema.parse(inputData);
|
|
282
|
+
return {
|
|
283
|
+
...result,
|
|
284
|
+
data: validatedData
|
|
285
|
+
};
|
|
286
|
+
} catch (error) {
|
|
287
|
+
const err = error;
|
|
288
|
+
throw new ElicitationValidationError(
|
|
289
|
+
`Elicitation data validation failed: ${err.message}`,
|
|
290
|
+
err
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (!zodSchema && result.action === "accept" && inputData) {
|
|
295
|
+
return {
|
|
296
|
+
...result,
|
|
297
|
+
data: inputData
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
return result;
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
__name(createElicitMethod, "createElicitMethod");
|
|
304
|
+
function createReportProgressMethod(progressToken, sendNotification) {
|
|
305
|
+
if (progressToken !== void 0 && sendNotification) {
|
|
306
|
+
return async (progress, total, message) => {
|
|
307
|
+
await sendProgressNotification(
|
|
308
|
+
sendNotification,
|
|
309
|
+
progressToken,
|
|
310
|
+
progress,
|
|
311
|
+
total,
|
|
312
|
+
message
|
|
313
|
+
);
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
return void 0;
|
|
317
|
+
}
|
|
318
|
+
__name(createReportProgressMethod, "createReportProgressMethod");
|
|
319
|
+
var LOG_LEVELS = {
|
|
320
|
+
debug: 0,
|
|
321
|
+
info: 1,
|
|
322
|
+
notice: 2,
|
|
323
|
+
warning: 3,
|
|
324
|
+
error: 4,
|
|
325
|
+
critical: 5,
|
|
326
|
+
alert: 6,
|
|
327
|
+
emergency: 7
|
|
328
|
+
};
|
|
329
|
+
var VALID_LOG_LEVELS = [
|
|
330
|
+
"debug",
|
|
331
|
+
"info",
|
|
332
|
+
"notice",
|
|
333
|
+
"warning",
|
|
334
|
+
"error",
|
|
335
|
+
"critical",
|
|
336
|
+
"alert",
|
|
337
|
+
"emergency"
|
|
338
|
+
];
|
|
339
|
+
function isValidLogLevel(level) {
|
|
340
|
+
return VALID_LOG_LEVELS.includes(level);
|
|
341
|
+
}
|
|
342
|
+
__name(isValidLogLevel, "isValidLogLevel");
|
|
343
|
+
function shouldLogMessage(messageLevel, minLevel) {
|
|
344
|
+
if (!minLevel) {
|
|
345
|
+
return true;
|
|
346
|
+
}
|
|
347
|
+
if (!isValidLogLevel(messageLevel) || !isValidLogLevel(minLevel)) {
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
350
|
+
return LOG_LEVELS[messageLevel] >= LOG_LEVELS[minLevel];
|
|
351
|
+
}
|
|
352
|
+
__name(shouldLogMessage, "shouldLogMessage");
|
|
353
|
+
function createLogMethod(sendNotification, minLogLevel) {
|
|
354
|
+
if (!sendNotification) {
|
|
355
|
+
return void 0;
|
|
356
|
+
}
|
|
357
|
+
return async (level, message, logger) => {
|
|
358
|
+
if (!shouldLogMessage(level, minLogLevel)) {
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
await sendNotification({
|
|
362
|
+
method: "notifications/message",
|
|
363
|
+
params: {
|
|
364
|
+
level,
|
|
365
|
+
data: message,
|
|
366
|
+
logger: logger || "tool"
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
Telemetry.getInstance().trackServerContext({
|
|
370
|
+
contextType: "notification",
|
|
371
|
+
notificationType: "message"
|
|
372
|
+
}).catch(
|
|
373
|
+
(e) => console.debug(`Failed to track notification context: ${e}`)
|
|
374
|
+
);
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
__name(createLogMethod, "createLogMethod");
|
|
378
|
+
var MCP_UI_EXTENSION_ID = "io.modelcontextprotocol/ui";
|
|
379
|
+
var MCP_UI_MIME_TYPE = "text/html;profile=mcp-app";
|
|
380
|
+
function supportsApps(clientCapabilities) {
|
|
381
|
+
return clientCapabilities?.extensions?.[MCP_UI_EXTENSION_ID]?.mimeTypes?.includes(MCP_UI_MIME_TYPE) ?? false;
|
|
382
|
+
}
|
|
383
|
+
__name(supportsApps, "supportsApps");
|
|
384
|
+
function createClientCapabilityChecker(clientCapabilities, clientInfo, requestMeta) {
|
|
385
|
+
const caps = clientCapabilities || {};
|
|
386
|
+
return {
|
|
387
|
+
can(capability) {
|
|
388
|
+
return capability in caps;
|
|
389
|
+
},
|
|
390
|
+
capabilities() {
|
|
391
|
+
return { ...caps };
|
|
392
|
+
},
|
|
393
|
+
/**
|
|
394
|
+
* Returns the name and version of the connecting client as advertised
|
|
395
|
+
* in the MCP initialize handshake.
|
|
396
|
+
*/
|
|
397
|
+
info() {
|
|
398
|
+
return { ...clientInfo };
|
|
399
|
+
},
|
|
400
|
+
/**
|
|
401
|
+
* Returns the settings object for a specific extension (SEP-1724).
|
|
402
|
+
* Returns `undefined` if the client did not advertise that extension.
|
|
403
|
+
*
|
|
404
|
+
* @example
|
|
405
|
+
* ```typescript
|
|
406
|
+
* // Check for MCP Apps support (SEP-1865)
|
|
407
|
+
* const uiExt = ctx.client.extension("io.modelcontextprotocol/ui");
|
|
408
|
+
* if (uiExt?.mimeTypes?.includes("text/html;profile=mcp-app")) { ... }
|
|
409
|
+
*
|
|
410
|
+
* // Or use the convenience method:
|
|
411
|
+
* if (ctx.client.supportsApps()) { ... }
|
|
412
|
+
* ```
|
|
413
|
+
*/
|
|
414
|
+
extension(id) {
|
|
415
|
+
return caps?.extensions?.[id];
|
|
416
|
+
},
|
|
417
|
+
/**
|
|
418
|
+
* Returns `true` if the client advertises support for MCP Apps
|
|
419
|
+
* (SEP-1865, extension identifier `io.modelcontextprotocol/ui`).
|
|
420
|
+
*
|
|
421
|
+
* Use this to conditionally register widget-enabled tool variants
|
|
422
|
+
* or return widget-aware responses.
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* ```typescript
|
|
426
|
+
* if (ctx.client.supportsApps()) {
|
|
427
|
+
* return widget({ uri: "ui://my-widget", props: result });
|
|
428
|
+
* }
|
|
429
|
+
* return text(result.summary);
|
|
430
|
+
* ```
|
|
431
|
+
*/
|
|
432
|
+
supportsApps() {
|
|
433
|
+
return supportsApps(caps);
|
|
434
|
+
},
|
|
435
|
+
/**
|
|
436
|
+
* Returns normalized end-user context from `params._meta` sent by the
|
|
437
|
+
* client on this specific tool invocation.
|
|
438
|
+
*
|
|
439
|
+
* **Scope:** Per-invocation — unlike other `ctx.client` methods which
|
|
440
|
+
* are stable for the lifetime of the MCP session, `user()` can return
|
|
441
|
+
* a different value on every tool call.
|
|
442
|
+
*
|
|
443
|
+
* **Returns `undefined`** when the client does not include user metadata
|
|
444
|
+
* (e.g. Inspector, Claude Desktop, CLI, most non-ChatGPT clients).
|
|
445
|
+
*
|
|
446
|
+
* **Advisory only:** This data is self-reported by the client and
|
|
447
|
+
* unverified. For verified identity use `ctx.auth` (requires OAuth).
|
|
448
|
+
*
|
|
449
|
+
* **ChatGPT multi-tenant model:**
|
|
450
|
+
* ChatGPT uses a single MCP session for all users of your app. Use
|
|
451
|
+
* `subject` to identify the human and `conversationId` to identify the
|
|
452
|
+
* chat thread — both vary per invocation within the same MCP session:
|
|
453
|
+
*
|
|
454
|
+
* ```
|
|
455
|
+
* 1 MCP session (ctx.session.sessionId) — shared across all users
|
|
456
|
+
* N subjects (ctx.client.user()?.subject) — one per ChatGPT user
|
|
457
|
+
* M threads (ctx.client.user()?.conversationId) — one per chat
|
|
458
|
+
* ```
|
|
459
|
+
*
|
|
460
|
+
* @example
|
|
461
|
+
* ```typescript
|
|
462
|
+
* server.tool({ name: "greet", schema: z.object({}) }, async (_p, ctx) => {
|
|
463
|
+
* const caller = ctx.client.user();
|
|
464
|
+
* if (caller) {
|
|
465
|
+
* // Personalise by locale or location
|
|
466
|
+
* const greeting = caller.locale?.startsWith("it") ? "Ciao" : "Hello";
|
|
467
|
+
* const city = caller.location?.city ?? "there";
|
|
468
|
+
* return text(`${greeting} from ${city}!`);
|
|
469
|
+
* }
|
|
470
|
+
* return text("Hello!");
|
|
471
|
+
* });
|
|
472
|
+
* ```
|
|
473
|
+
*/
|
|
474
|
+
user() {
|
|
475
|
+
return normalizeUserContext(requestMeta);
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
__name(createClientCapabilityChecker, "createClientCapabilityChecker");
|
|
480
|
+
function createSendNotificationMethod(sessionId, sessions) {
|
|
481
|
+
if (!sessionId || !sessions) {
|
|
482
|
+
return void 0;
|
|
483
|
+
}
|
|
484
|
+
return async (method, params) => {
|
|
485
|
+
const session = sessions.get(sessionId);
|
|
486
|
+
if (!session?.sendNotification) {
|
|
487
|
+
console.warn(
|
|
488
|
+
`[MCP] Cannot send notification to session ${sessionId} - no sendNotification function`
|
|
489
|
+
);
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
try {
|
|
493
|
+
await session.sendNotification({
|
|
494
|
+
method,
|
|
495
|
+
params: params || {}
|
|
496
|
+
});
|
|
497
|
+
} catch (error) {
|
|
498
|
+
console.error(
|
|
499
|
+
`[MCP] Error sending notification to session ${sessionId}:`,
|
|
500
|
+
error
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
__name(createSendNotificationMethod, "createSendNotificationMethod");
|
|
506
|
+
function createSendNotificationToSessionMethod(sessions) {
|
|
507
|
+
if (!sessions) {
|
|
508
|
+
return void 0;
|
|
509
|
+
}
|
|
510
|
+
return async (sessionId, method, params) => {
|
|
511
|
+
const session = sessions.get(sessionId);
|
|
512
|
+
if (!session?.sendNotification) {
|
|
513
|
+
return false;
|
|
514
|
+
}
|
|
515
|
+
try {
|
|
516
|
+
await session.sendNotification({
|
|
517
|
+
method,
|
|
518
|
+
params: params || {}
|
|
519
|
+
});
|
|
520
|
+
return true;
|
|
521
|
+
} catch (error) {
|
|
522
|
+
console.error(
|
|
523
|
+
`[MCP] Error sending notification to session ${sessionId}:`,
|
|
524
|
+
error
|
|
525
|
+
);
|
|
526
|
+
return false;
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
__name(createSendNotificationToSessionMethod, "createSendNotificationToSessionMethod");
|
|
531
|
+
function createEnhancedContext(baseContext, createMessage, elicitInput, progressToken, sendNotification, minLogLevel, clientCapabilities, sessionId, sessions, clientInfo, requestMeta) {
|
|
532
|
+
const enhancedContext = baseContext ? extractContextData(baseContext) : {};
|
|
533
|
+
enhancedContext.sample = createSampleMethod(
|
|
534
|
+
createMessage,
|
|
535
|
+
progressToken,
|
|
536
|
+
sendNotification
|
|
537
|
+
);
|
|
538
|
+
enhancedContext.elicit = createElicitMethod(elicitInput);
|
|
539
|
+
enhancedContext.reportProgress = createReportProgressMethod(
|
|
540
|
+
progressToken,
|
|
541
|
+
sendNotification
|
|
542
|
+
);
|
|
543
|
+
enhancedContext.log = createLogMethod(sendNotification, minLogLevel);
|
|
544
|
+
enhancedContext.client = createClientCapabilityChecker(
|
|
545
|
+
clientCapabilities,
|
|
546
|
+
clientInfo,
|
|
547
|
+
requestMeta
|
|
548
|
+
);
|
|
549
|
+
if (sessionId) {
|
|
550
|
+
enhancedContext.session = {
|
|
551
|
+
sessionId
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
const sendNotificationMethod = createSendNotificationMethod(
|
|
555
|
+
sessionId,
|
|
556
|
+
sessions
|
|
557
|
+
);
|
|
558
|
+
if (sendNotificationMethod) {
|
|
559
|
+
enhancedContext.sendNotification = sendNotificationMethod;
|
|
560
|
+
}
|
|
561
|
+
const sendNotificationToSessionMethod = createSendNotificationToSessionMethod(sessions);
|
|
562
|
+
if (sendNotificationToSessionMethod) {
|
|
563
|
+
enhancedContext.sendNotificationToSession = sendNotificationToSessionMethod;
|
|
564
|
+
}
|
|
565
|
+
return enhancedContext;
|
|
566
|
+
}
|
|
567
|
+
__name(createEnhancedContext, "createEnhancedContext");
|
|
568
|
+
function buildHandlerContext(sessionId, sessions) {
|
|
569
|
+
const session = sessionId ? sessions.get(sessionId) : void 0;
|
|
570
|
+
const requestContext = getRequestContext() || session?.context;
|
|
571
|
+
const enhancedCtx = requestContext ? extractContextData(requestContext) : {};
|
|
572
|
+
Object.defineProperty(enhancedCtx, "client", {
|
|
573
|
+
value: createClientCapabilityChecker(
|
|
574
|
+
session?.clientCapabilities,
|
|
575
|
+
session?.clientInfo
|
|
576
|
+
),
|
|
577
|
+
writable: true,
|
|
578
|
+
enumerable: true,
|
|
579
|
+
configurable: true
|
|
580
|
+
});
|
|
581
|
+
return { session, enhancedCtx };
|
|
582
|
+
}
|
|
583
|
+
__name(buildHandlerContext, "buildHandlerContext");
|
|
584
|
+
|
|
585
|
+
export {
|
|
586
|
+
findSessionContext,
|
|
587
|
+
createSampleMethod,
|
|
588
|
+
createElicitMethod,
|
|
589
|
+
isValidLogLevel,
|
|
590
|
+
supportsApps,
|
|
591
|
+
createClientCapabilityChecker,
|
|
592
|
+
createEnhancedContext,
|
|
593
|
+
buildHandlerContext
|
|
594
|
+
};
|