@modelcontextprotocol/ext-apps 0.4.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/src/app.d.ts CHANGED
@@ -7,32 +7,37 @@ export { PostMessageTransport } from "./message-transport";
7
7
  export * from "./types";
8
8
  export { applyHostStyleVariables, applyHostFonts, getDocumentTheme, applyDocumentTheme, } from "./styles";
9
9
  /**
10
- * Metadata key for associating a resource URI with a tool call.
10
+ * Metadata key for associating a UI resource URI with a tool.
11
11
  *
12
- * MCP servers include this key in tool call result metadata to indicate which
13
- * UI resource should be displayed for the tool. When hosts receive a tool result
14
- * containing this metadata, they resolve and render the corresponding {@link App}.
12
+ * MCP servers include this key in tool definition metadata (via `tools/list`)
13
+ * to indicate which UI resource should be displayed when the tool is called.
14
+ * When hosts see a tool with this metadata, they fetch and render the
15
+ * corresponding {@link App `App`}.
15
16
  *
16
- * **Note**: This constant is provided for reference. MCP servers set this metadata
17
- * in their tool handlers; App developers typically don't need to use it directly.
17
+ * **Note**: This constant is provided for reference. App developers typically
18
+ * don't need to use it directly. Prefer using {@link server-helpers!registerAppTool `registerAppTool`}
19
+ * with the `_meta.ui.resourceUri` format instead.
18
20
  *
19
21
  * @example How MCP servers use this key (server-side, not in Apps)
20
- * ```typescript
21
- * // In an MCP server's tool handler:
22
- * return {
23
- * content: [{ type: "text", text: "Result" }],
24
- * _meta: {
25
- * [RESOURCE_URI_META_KEY]: "ui://weather/forecast"
26
- * }
27
- * };
22
+ * ```ts source="./app.examples.ts#RESOURCE_URI_META_KEY_serverSide"
23
+ * server.registerTool(
24
+ * "weather",
25
+ * {
26
+ * description: "Get weather forecast",
27
+ * _meta: {
28
+ * [RESOURCE_URI_META_KEY]: "ui://weather/forecast",
29
+ * },
30
+ * },
31
+ * handler,
32
+ * );
28
33
  * ```
29
34
  *
30
35
  * @example How hosts check for this metadata (host-side)
31
- * ```typescript
32
- * const result = await mcpClient.callTool({ name: "weather", arguments: {} });
33
- * const uiUri = result._meta?.[RESOURCE_URI_META_KEY];
34
- * if (uiUri) {
35
- * // Load and display the UI resource
36
+ * ```ts source="./app.examples.ts#RESOURCE_URI_META_KEY_hostSide"
37
+ * // Check tool definition metadata (from tools/list response):
38
+ * const uiUri = tool._meta?.[RESOURCE_URI_META_KEY];
39
+ * if (typeof uiUri === "string" && uiUri.startsWith("ui://")) {
40
+ * // Fetch the resource and display the UI
36
41
  * }
37
42
  * ```
38
43
  */
@@ -42,11 +47,11 @@ export declare const RESOURCE_URI_META_KEY = "ui/resourceUri";
42
47
  *
43
48
  * Identifies HTML content as an MCP App UI resource.
44
49
  *
45
- * Used by {@link server-helpers!registerAppResource} as the default MIME type for app resources.
50
+ * Used by {@link server-helpers!registerAppResource `registerAppResource`} as the default MIME type for app resources.
46
51
  */
47
52
  export declare const RESOURCE_MIME_TYPE = "text/html;profile=mcp-app";
48
53
  /**
49
- * Options for configuring {@link App} behavior.
54
+ * Options for configuring {@link App `App`} behavior.
50
55
  *
51
56
  * Extends `ProtocolOptions` from the MCP SDK with `App`-specific configuration.
52
57
  *
@@ -56,7 +61,7 @@ type AppOptions = ProtocolOptions & {
56
61
  /**
57
62
  * Automatically report size changes to the host using `ResizeObserver`.
58
63
  *
59
- * When enabled, the {@link App} monitors `document.body` and `document.documentElement`
64
+ * When enabled, the {@link App `App`} monitors `document.body` and `document.documentElement`
60
65
  * for size changes and automatically sends `ui/notifications/size-changed`
61
66
  * notifications to the host.
62
67
  *
@@ -75,7 +80,7 @@ type RequestHandlerExtra = Parameters<Parameters<App["setRequestHandler"]>[1]>[1
75
80
  *
76
81
  * ## Architecture
77
82
  *
78
- * Guest UIs (Apps) act as MCP clients connecting to the host via {@link PostMessageTransport}.
83
+ * Views (Apps) act as MCP clients connecting to the host via {@link PostMessageTransport `PostMessageTransport`}.
79
84
  * The host proxies requests to the actual MCP server and forwards
80
85
  * responses back to the App.
81
86
  *
@@ -108,40 +113,18 @@ type RequestHandlerExtra = Parameters<Parameters<App["setRequestHandler"]>[1]>[1
108
113
  * Both patterns work; use whichever fits your coding style better.
109
114
  *
110
115
  * @example Basic usage with PostMessageTransport
111
- * ```typescript
112
- * import {
113
- * App,
114
- * PostMessageTransport,
115
- * McpUiToolInputNotificationSchema
116
- * } from '@modelcontextprotocol/ext-apps';
117
- *
116
+ * ```ts source="./app.examples.ts#App_basicUsage"
118
117
  * const app = new App(
119
118
  * { name: "WeatherApp", version: "1.0.0" },
120
- * {} // capabilities
119
+ * {}, // capabilities
121
120
  * );
122
121
  *
123
- * // Register notification handler using setter (simpler)
122
+ * // Register handlers before connecting to ensure no notifications are missed
124
123
  * app.ontoolinput = (params) => {
125
124
  * console.log("Tool arguments:", params.arguments);
126
125
  * };
127
126
  *
128
- * // OR using inherited setNotificationHandler (more explicit)
129
- * app.setNotificationHandler(
130
- * McpUiToolInputNotificationSchema,
131
- * (notification) => {
132
- * console.log("Tool arguments:", notification.params.arguments);
133
- * }
134
- * );
135
- *
136
- * await app.connect(new PostMessageTransport(window.parent, window.parent));
137
- * ```
138
- *
139
- * @example Sending a message to the host's chat
140
- * ```typescript
141
- * await app.sendMessage({
142
- * role: "user",
143
- * content: [{ type: "text", text: "Weather updated!" }]
144
- * });
127
+ * await app.connect();
145
128
  * ```
146
129
  */
147
130
  export declare class App extends Protocol<AppRequest, AppNotification, AppResult> {
@@ -159,11 +142,11 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
159
142
  * @param options - Configuration options including `autoResize` behavior
160
143
  *
161
144
  * @example
162
- * ```typescript
145
+ * ```ts source="./app.examples.ts#App_constructor_basic"
163
146
  * const app = new App(
164
147
  * { name: "MyApp", version: "1.0.0" },
165
148
  * { tools: { listChanged: true } }, // capabilities
166
- * { autoResize: true } // options
149
+ * { autoResize: true }, // options
167
150
  * );
168
151
  * ```
169
152
  */
@@ -172,49 +155,40 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
172
155
  * Get the host's capabilities discovered during initialization.
173
156
  *
174
157
  * Returns the capabilities that the host advertised during the
175
- * {@link connect} handshake. Returns `undefined` if called before
158
+ * {@link connect `connect`} handshake. Returns `undefined` if called before
176
159
  * connection is established.
177
160
  *
178
161
  * @returns Host capabilities, or `undefined` if not yet connected
179
162
  *
180
163
  * @example Check host capabilities after connection
181
- * ```typescript
182
- * await app.connect(transport);
183
- * const caps = app.getHostCapabilities();
184
- * if (caps === undefined) {
185
- * console.error("Not connected");
186
- * return;
187
- * }
188
- * if (caps.serverTools) {
164
+ * ```ts source="./app.examples.ts#App_getHostCapabilities_checkAfterConnection"
165
+ * await app.connect();
166
+ * if (app.getHostCapabilities()?.serverTools) {
189
167
  * console.log("Host supports server tool calls");
190
168
  * }
191
169
  * ```
192
170
  *
193
- * @see {@link connect} for the initialization handshake
194
- * @see {@link McpUiHostCapabilities} for the capabilities structure
171
+ * @see {@link connect `connect`} for the initialization handshake
172
+ * @see {@link McpUiHostCapabilities `McpUiHostCapabilities`} for the capabilities structure
195
173
  */
196
174
  getHostCapabilities(): McpUiHostCapabilities | undefined;
197
175
  /**
198
176
  * Get the host's implementation info discovered during initialization.
199
177
  *
200
178
  * Returns the host's name and version as advertised during the
201
- * {@link connect} handshake. Returns `undefined` if called before
179
+ * {@link connect `connect`} handshake. Returns `undefined` if called before
202
180
  * connection is established.
203
181
  *
204
182
  * @returns Host implementation info, or `undefined` if not yet connected
205
183
  *
206
184
  * @example Log host information after connection
207
- * ```typescript
185
+ * ```ts source="./app.examples.ts#App_getHostVersion_logAfterConnection"
208
186
  * await app.connect(transport);
209
- * const host = app.getHostVersion();
210
- * if (host === undefined) {
211
- * console.error("Not connected");
212
- * return;
213
- * }
214
- * console.log(`Connected to ${host.name} v${host.version}`);
187
+ * const { name, version } = app.getHostVersion() ?? {};
188
+ * console.log(`Connected to ${name} v${version}`);
215
189
  * ```
216
190
  *
217
- * @see {@link connect} for the initialization handshake
191
+ * @see {@link connect `connect`} for the initialization handshake
218
192
  */
219
193
  getHostVersion(): Implementation | undefined;
220
194
  /**
@@ -230,24 +204,20 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
230
204
  * @returns Host context, or `undefined` if not yet connected
231
205
  *
232
206
  * @example Access host context after connection
233
- * ```typescript
207
+ * ```ts source="./app.examples.ts#App_getHostContext_accessAfterConnection"
234
208
  * await app.connect(transport);
235
209
  * const context = app.getHostContext();
236
- * if (context === undefined) {
237
- * console.error("Not connected");
238
- * return;
239
- * }
240
- * if (context.theme === "dark") {
210
+ * if (context?.theme === "dark") {
241
211
  * document.body.classList.add("dark-theme");
242
212
  * }
243
- * if (context.toolInfo) {
213
+ * if (context?.toolInfo) {
244
214
  * console.log("Tool:", context.toolInfo.tool.name);
245
215
  * }
246
216
  * ```
247
217
  *
248
- * @see {@link connect} for the initialization handshake
249
- * @see {@link onhostcontextchanged} for context change notifications
250
- * @see {@link McpUiHostContext} for the context structure
218
+ * @see {@link connect `connect`} for the initialization handshake
219
+ * @see {@link onhostcontextchanged `onhostcontextchanged`} for context change notifications
220
+ * @see {@link McpUiHostContext `McpUiHostContext`} for the context structure
251
221
  */
252
222
  getHostContext(): McpUiHostContext | undefined;
253
223
  /**
@@ -260,32 +230,22 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
260
230
  * This setter is a convenience wrapper around `setNotificationHandler()` that
261
231
  * automatically handles the notification schema and extracts the params for you.
262
232
  *
263
- * Register handlers before calling {@link connect} to avoid missing notifications.
233
+ * Register handlers before calling {@link connect `connect`} to avoid missing notifications.
264
234
  *
265
- * @param callback - Function called with the tool input params ({@link McpUiToolInputNotification.params})
235
+ * @param callback - Function called with the tool input params ({@link McpUiToolInputNotification.params `McpUiToolInputNotification.params`})
266
236
  *
267
- * @example Using the setter (simpler)
268
- * ```typescript
237
+ * @example
238
+ * ```ts source="./app.examples.ts#App_ontoolinput_setter"
269
239
  * // Register before connecting to ensure no notifications are missed
270
240
  * app.ontoolinput = (params) => {
271
241
  * console.log("Tool:", params.arguments);
272
242
  * // Update your UI with the tool arguments
273
243
  * };
274
- * await app.connect(transport);
275
- * ```
276
- *
277
- * @example Using setNotificationHandler (more explicit)
278
- * ```typescript
279
- * app.setNotificationHandler(
280
- * McpUiToolInputNotificationSchema,
281
- * (notification) => {
282
- * console.log("Tool:", notification.params.arguments);
283
- * }
284
- * );
244
+ * await app.connect();
285
245
  * ```
286
246
  *
287
- * @see {@link setNotificationHandler} for the underlying method
288
- * @see {@link McpUiToolInputNotification} for the notification structure
247
+ * @see {@link setNotificationHandler `setNotificationHandler`} for the underlying method
248
+ * @see {@link McpUiToolInputNotification `McpUiToolInputNotification`} for the notification structure
289
249
  */
290
250
  set ontoolinput(callback: (params: McpUiToolInputNotification["params"]) => void);
291
251
  /**
@@ -295,24 +255,46 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
295
255
  * streams partial tool arguments during tool call initialization. This enables
296
256
  * progressive rendering of tool arguments before they're complete.
297
257
  *
258
+ * **Important:** Partial arguments are "healed" JSON — the host closes unclosed
259
+ * brackets/braces to produce valid JSON. This means objects may be incomplete
260
+ * (e.g., the last item in an array may be truncated). Use partial data only
261
+ * for preview UI, not for critical operations.
262
+ *
298
263
  * This setter is a convenience wrapper around `setNotificationHandler()` that
299
264
  * automatically handles the notification schema and extracts the params for you.
300
265
  *
301
- * Register handlers before calling {@link connect} to avoid missing notifications.
266
+ * Register handlers before calling {@link connect `connect`} to avoid missing notifications.
302
267
  *
303
- * @param callback - Function called with each partial tool input update ({@link McpUiToolInputPartialNotification.params})
268
+ * @param callback - Function called with each partial tool input update ({@link McpUiToolInputPartialNotification.params `McpUiToolInputPartialNotification.params`})
304
269
  *
305
270
  * @example Progressive rendering of tool arguments
306
- * ```typescript
271
+ * ```ts source="./app.examples.ts#App_ontoolinputpartial_progressiveRendering"
272
+ * let toolInputs: Record<string, unknown> | null = null;
273
+ * let toolInputsPartial: Record<string, unknown> | null = null;
274
+ *
307
275
  * app.ontoolinputpartial = (params) => {
308
- * console.log("Partial args:", params.arguments);
309
- * // Update your UI progressively as arguments stream in
276
+ * toolInputsPartial = params.arguments as Record<string, unknown>;
277
+ * render();
278
+ * };
279
+ *
280
+ * app.ontoolinput = (params) => {
281
+ * toolInputs = params.arguments as Record<string, unknown>;
282
+ * toolInputsPartial = null;
283
+ * render();
310
284
  * };
285
+ *
286
+ * function render() {
287
+ * if (toolInputs) {
288
+ * renderFinalUI(toolInputs);
289
+ * } else {
290
+ * renderLoadingUI(toolInputsPartial); // e.g., shimmer with partial preview
291
+ * }
292
+ * }
311
293
  * ```
312
294
  *
313
- * @see {@link setNotificationHandler} for the underlying method
314
- * @see {@link McpUiToolInputPartialNotification} for the notification structure
315
- * @see {@link ontoolinput} for the complete tool input handler
295
+ * @see {@link setNotificationHandler `setNotificationHandler`} for the underlying method
296
+ * @see {@link McpUiToolInputPartialNotification `McpUiToolInputPartialNotification`} for the notification structure
297
+ * @see {@link ontoolinput `ontoolinput`} for the complete tool input handler
316
298
  */
317
299
  set ontoolinputpartial(callback: (params: McpUiToolInputPartialNotification["params"]) => void);
318
300
  /**
@@ -325,25 +307,24 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
325
307
  * This setter is a convenience wrapper around `setNotificationHandler()` that
326
308
  * automatically handles the notification schema and extracts the params for you.
327
309
  *
328
- * Register handlers before calling {@link connect} to avoid missing notifications.
310
+ * Register handlers before calling {@link connect `connect`} to avoid missing notifications.
329
311
  *
330
- * @param callback - Function called with the tool result ({@link McpUiToolResultNotification.params})
312
+ * @param callback - Function called with the tool result ({@link McpUiToolResultNotification.params `McpUiToolResultNotification.params`})
331
313
  *
332
314
  * @example Display tool execution results
333
- * ```typescript
315
+ * ```ts source="./app.examples.ts#App_ontoolresult_displayResults"
334
316
  * app.ontoolresult = (params) => {
335
- * if (params.content) {
336
- * console.log("Tool output:", params.content);
337
- * }
338
317
  * if (params.isError) {
339
- * console.error("Tool execution failed");
318
+ * console.error("Tool execution failed:", params.content);
319
+ * } else if (params.content) {
320
+ * console.log("Tool output:", params.content);
340
321
  * }
341
322
  * };
342
323
  * ```
343
324
  *
344
- * @see {@link setNotificationHandler} for the underlying method
345
- * @see {@link McpUiToolResultNotification} for the notification structure
346
- * @see {@link ontoolinput} for the initial tool input handler
325
+ * @see {@link setNotificationHandler `setNotificationHandler`} for the underlying method
326
+ * @see {@link McpUiToolResultNotification `McpUiToolResultNotification`} for the notification structure
327
+ * @see {@link ontoolinput `ontoolinput`} for the initial tool input handler
347
328
  */
348
329
  set ontoolresult(callback: (params: McpUiToolResultNotification["params"]) => void);
349
330
  /**
@@ -357,21 +338,21 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
357
338
  * This setter is a convenience wrapper around `setNotificationHandler()` that
358
339
  * automatically handles the notification schema and extracts the params for you.
359
340
  *
360
- * Register handlers before calling {@link connect} to avoid missing notifications.
341
+ * Register handlers before calling {@link connect `connect`} to avoid missing notifications.
361
342
  *
362
- * @param callback - Function called when tool execution is cancelled. Receives optional cancellation reason — see {@link McpUiToolCancelledNotification.params}.
343
+ * @param callback - Function called when tool execution is cancelled. Receives optional cancellation reason — see {@link McpUiToolCancelledNotification.params `McpUiToolCancelledNotification.params`}.
363
344
  *
364
345
  * @example Handle tool cancellation
365
- * ```typescript
346
+ * ```ts source="./app.examples.ts#App_ontoolcancelled_handleCancellation"
366
347
  * app.ontoolcancelled = (params) => {
367
348
  * console.log("Tool cancelled:", params.reason);
368
- * showCancelledMessage(params.reason ?? "Operation was cancelled");
349
+ * // Update your UI to show cancellation state
369
350
  * };
370
351
  * ```
371
352
  *
372
- * @see {@link setNotificationHandler} for the underlying method
373
- * @see {@link McpUiToolCancelledNotification} for the notification structure
374
- * @see {@link ontoolresult} for successful tool completion
353
+ * @see {@link setNotificationHandler `setNotificationHandler`} for the underlying method
354
+ * @see {@link McpUiToolCancelledNotification `McpUiToolCancelledNotification`} for the notification structure
355
+ * @see {@link ontoolresult `ontoolresult`} for successful tool completion
375
356
  */
376
357
  set ontoolcancelled(callback: (params: McpUiToolCancelledNotification["params"]) => void);
377
358
  /**
@@ -386,15 +367,15 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
386
367
  * automatically handles the notification schema and extracts the params for you.
387
368
  *
388
369
  * Notification params are automatically merged into the internal host context
389
- * before the callback is invoked. This means {@link getHostContext} will
370
+ * before the callback is invoked. This means {@link getHostContext `getHostContext`} will
390
371
  * return the updated values even before your callback runs.
391
372
  *
392
- * Register handlers before calling {@link connect} to avoid missing notifications.
373
+ * Register handlers before calling {@link connect `connect`} to avoid missing notifications.
393
374
  *
394
375
  * @param callback - Function called with the updated host context
395
376
  *
396
377
  * @example Respond to theme changes
397
- * ```typescript
378
+ * ```ts source="./app.examples.ts#App_onhostcontextchanged_respondToTheme"
398
379
  * app.onhostcontextchanged = (params) => {
399
380
  * if (params.theme === "dark") {
400
381
  * document.body.classList.add("dark-theme");
@@ -404,9 +385,9 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
404
385
  * };
405
386
  * ```
406
387
  *
407
- * @see {@link setNotificationHandler} for the underlying method
408
- * @see {@link McpUiHostContextChangedNotification} for the notification structure
409
- * @see {@link McpUiHostContext} for the full context structure
388
+ * @see {@link setNotificationHandler `setNotificationHandler`} for the underlying method
389
+ * @see {@link McpUiHostContextChangedNotification `McpUiHostContextChangedNotification`} for the notification structure
390
+ * @see {@link McpUiHostContext `McpUiHostContext`} for the full context structure
410
391
  */
411
392
  set onhostcontextchanged(callback: (params: McpUiHostContextChangedNotification["params"]) => void);
412
393
  /**
@@ -422,13 +403,13 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
422
403
  * This setter is a convenience wrapper around `setRequestHandler()` that
423
404
  * automatically handles the request schema.
424
405
  *
425
- * Register handlers before calling {@link connect} to avoid missing requests.
406
+ * Register handlers before calling {@link connect `connect`} to avoid missing requests.
426
407
  *
427
408
  * @param callback - Function called when teardown is requested.
428
409
  * Must return `McpUiResourceTeardownResult` (can be an empty object `{}`) or a Promise resolving to it.
429
410
  *
430
411
  * @example Perform cleanup before teardown
431
- * ```typescript
412
+ * ```ts source="./app.examples.ts#App_onteardown_performCleanup"
432
413
  * app.onteardown = async () => {
433
414
  * await saveState();
434
415
  * closeConnections();
@@ -437,8 +418,8 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
437
418
  * };
438
419
  * ```
439
420
  *
440
- * @see {@link setRequestHandler} for the underlying method
441
- * @see {@link McpUiResourceTeardownRequest} for the request structure
421
+ * @see {@link setRequestHandler `setRequestHandler`} for the underlying method
422
+ * @see {@link McpUiResourceTeardownRequest `McpUiResourceTeardownRequest`} for the request structure
442
423
  */
443
424
  set onteardown(callback: (params: McpUiResourceTeardownRequest["params"], extra: RequestHandlerExtra) => McpUiResourceTeardownResult | Promise<McpUiResourceTeardownResult>);
444
425
  /**
@@ -453,14 +434,14 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
453
434
  * This setter is a convenience wrapper around `setRequestHandler()` that
454
435
  * automatically handles the request schema and extracts the params for you.
455
436
  *
456
- * Register handlers before calling {@link connect} to avoid missing requests.
437
+ * Register handlers before calling {@link connect `connect`} to avoid missing requests.
457
438
  *
458
439
  * @param callback - Async function that executes the tool and returns the result.
459
440
  * The callback will only be invoked if the app declared tool capabilities
460
441
  * in the constructor.
461
442
  *
462
443
  * @example Handle tool calls from the host
463
- * ```typescript
444
+ * ```ts source="./app.examples.ts#App_oncalltool_handleFromHost"
464
445
  * app.oncalltool = async (params, extra) => {
465
446
  * if (params.name === "greet") {
466
447
  * const name = params.arguments?.name ?? "World";
@@ -470,7 +451,7 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
470
451
  * };
471
452
  * ```
472
453
  *
473
- * @see {@link setRequestHandler} for the underlying method
454
+ * @see {@link setRequestHandler `setRequestHandler`} for the underlying method
474
455
  */
475
456
  set oncalltool(callback: (params: CallToolRequest["params"], extra: RequestHandlerExtra) => Promise<CallToolResult>);
476
457
  /**
@@ -485,23 +466,23 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
485
466
  * This setter is a convenience wrapper around `setRequestHandler()` that
486
467
  * automatically handles the request schema and extracts the params for you.
487
468
  *
488
- * Register handlers before calling {@link connect} to avoid missing requests.
469
+ * Register handlers before calling {@link connect `connect`} to avoid missing requests.
489
470
  *
490
471
  * @param callback - Async function that returns tool names as strings (simplified
491
472
  * from full `ListToolsResult` with `Tool` objects). Registration is always
492
473
  * allowed; capability validation occurs when handlers are invoked.
493
474
  *
494
475
  * @example Return available tools
495
- * ```typescript
476
+ * ```ts source="./app.examples.ts#App_onlisttools_returnTools"
496
477
  * app.onlisttools = async (params, extra) => {
497
478
  * return {
498
- * tools: ["calculate", "convert", "format"]
479
+ * tools: ["greet", "calculate", "format"],
499
480
  * };
500
481
  * };
501
482
  * ```
502
483
  *
503
- * @see {@link setRequestHandler} for the underlying method
504
- * @see {@link oncalltool} for handling tool execution
484
+ * @see {@link setRequestHandler `setRequestHandler`} for the underlying method
485
+ * @see {@link oncalltool `oncalltool`} for handling tool execution
505
486
  */
506
487
  set onlisttools(callback: (params: ListToolsRequest["params"], extra: RequestHandlerExtra) => Promise<{
507
488
  tools: string[];
@@ -550,11 +531,11 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
550
531
  * between transport failures (thrown) and tool execution failures (returned).
551
532
  *
552
533
  * @example Fetch updated weather data
553
- * ```typescript
534
+ * ```ts source="./app.examples.ts#App_callServerTool_fetchWeather"
554
535
  * try {
555
536
  * const result = await app.callServerTool({
556
537
  * name: "get_weather",
557
- * arguments: { location: "Tokyo" }
538
+ * arguments: { location: "Tokyo" },
558
539
  * });
559
540
  * if (result.isError) {
560
541
  * console.error("Tool returned error:", result.content);
@@ -575,24 +556,47 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
575
556
  *
576
557
  * @param params - Message role and content
577
558
  * @param options - Request options (timeout, etc.)
578
- * @returns Result indicating success or error (no message content returned)
559
+ * @returns Result with optional `isError` flag indicating host rejection
579
560
  *
580
- * @throws {Error} If the host rejects the message
561
+ * @throws {Error} If the request times out or the connection is lost
581
562
  *
582
563
  * @example Send a text message from user interaction
583
- * ```typescript
564
+ * ```ts source="./app.examples.ts#App_sendMessage_textFromInteraction"
584
565
  * try {
585
- * await app.sendMessage({
566
+ * const result = await app.sendMessage({
586
567
  * role: "user",
587
- * content: [{ type: "text", text: "Show me details for item #42" }]
568
+ * content: [{ type: "text", text: "Show me details for item #42" }],
588
569
  * });
570
+ * if (result.isError) {
571
+ * console.error("Host rejected the message");
572
+ * // Handle rejection appropriately for your app
573
+ * }
589
574
  * } catch (error) {
590
575
  * console.error("Failed to send message:", error);
591
- * // Handle error appropriately for your app
576
+ * // Handle transport/protocol error
592
577
  * }
593
578
  * ```
594
579
  *
595
- * @see {@link McpUiMessageRequest} for request structure
580
+ * @example Send follow-up message after offloading large data to model context
581
+ * ```ts source="./app.examples.ts#App_sendMessage_withLargeContext"
582
+ * const markdown = `---
583
+ * word-count: ${fullTranscript.split(/\s+/).length}
584
+ * speaker-names: ${speakerNames.join(", ")}
585
+ * ---
586
+ *
587
+ * ${fullTranscript}`;
588
+ *
589
+ * // Offload long transcript to model context
590
+ * await app.updateModelContext({ content: [{ type: "text", text: markdown }] });
591
+ *
592
+ * // Send brief trigger message
593
+ * await app.sendMessage({
594
+ * role: "user",
595
+ * content: [{ type: "text", text: "Summarize the key points" }],
596
+ * });
597
+ * ```
598
+ *
599
+ * @see {@link McpUiMessageRequest `McpUiMessageRequest`} for request structure
596
600
  */
597
601
  sendMessage(params: McpUiMessageRequest["params"], options?: RequestOptions): Promise<{
598
602
  [x: string]: unknown;
@@ -607,11 +611,11 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
607
611
  * @param params - Log level and message
608
612
  *
609
613
  * @example Log app state for debugging
610
- * ```typescript
614
+ * ```ts source="./app.examples.ts#App_sendLog_debugState"
611
615
  * app.sendLog({
612
616
  * level: "info",
613
617
  * data: "Weather data refreshed",
614
- * logger: "WeatherApp"
618
+ * logger: "WeatherApp",
615
619
  * });
616
620
  * ```
617
621
  *
@@ -621,31 +625,52 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
621
625
  /**
622
626
  * Update the host's model context with app state.
623
627
  *
624
- * Unlike `sendLog`, which is for debugging/telemetry, context updates
625
- * are intended to be available to the model in future reasoning,
626
- * without requiring a follow-up action (like `sendMessage`).
628
+ * Context updates are intended to be available to the model in future
629
+ * turns, without triggering an immediate model response (unlike {@link sendMessage `sendMessage`}).
627
630
  *
628
631
  * The host will typically defer sending the context to the model until the
629
- * next user message (including `ui/message`), and will only send the last
630
- * update received. Each call overwrites any previous context update.
632
+ * next user message either from the actual user or via `sendMessage`. Only
633
+ * the last update is sent; each call overwrites any previous context.
631
634
  *
632
635
  * @param params - Context content and/or structured content
633
636
  * @param options - Request options (timeout, etc.)
634
637
  *
635
638
  * @throws {Error} If the host rejects the context update (e.g., unsupported content type)
639
+ * @throws {Error} If the request times out or the connection is lost
636
640
  *
637
641
  * @example Update model context with current app state
638
- * ```typescript
642
+ * ```ts source="./app.examples.ts#App_updateModelContext_appState"
643
+ * const markdown = `---
644
+ * item-count: ${itemList.length}
645
+ * total-cost: ${totalCost}
646
+ * currency: ${currency}
647
+ * ---
648
+ *
649
+ * User is viewing their shopping cart with ${itemList.length} items selected:
650
+ *
651
+ * ${itemList.map((item) => `- ${item}`).join("\n")}`;
652
+ *
639
653
  * await app.updateModelContext({
640
- * content: [{ type: "text", text: "User selected 3 items totaling $150.00" }]
654
+ * content: [{ type: "text", text: markdown }],
641
655
  * });
642
656
  * ```
643
657
  *
644
- * @example Update with structured content
645
- * ```typescript
646
- * await app.updateModelContext({
647
- * structuredContent: { selectedItems: 3, total: 150.00, currency: "USD" }
648
- * });
658
+ * @example Report runtime error to model
659
+ * ```ts source="./app.examples.ts#App_updateModelContext_reportError"
660
+ * try {
661
+ * const _stream = await navigator.mediaDevices.getUserMedia({ audio: true });
662
+ * // ... use _stream for transcription
663
+ * } catch (err) {
664
+ * // Inform the model that the app is in a degraded state
665
+ * await app.updateModelContext({
666
+ * content: [
667
+ * {
668
+ * type: "text",
669
+ * text: "Error: transcription unavailable",
670
+ * },
671
+ * ],
672
+ * });
673
+ * }
649
674
  * ```
650
675
  *
651
676
  * @returns Promise that resolves when the context update is acknowledged
@@ -663,32 +688,32 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
663
688
  * Request the host to open an external URL in the default browser.
664
689
  *
665
690
  * The host may deny this request based on user preferences or security policy.
666
- * Apps should handle rejection gracefully.
691
+ * Apps should handle rejection gracefully by checking `result.isError`.
667
692
  *
668
693
  * @param params - URL to open
669
694
  * @param options - Request options (timeout, etc.)
670
- * @returns Result indicating success or error
695
+ * @returns Result with `isError: true` if the host denied the request (e.g., blocked domain, user cancelled)
671
696
  *
672
- * @throws {Error} If the host denies the request (e.g., blocked domain, user cancelled)
673
697
  * @throws {Error} If the request times out or the connection is lost
674
698
  *
675
699
  * @example Open documentation link
676
- * ```typescript
677
- * try {
678
- * await app.openLink({ url: "https://docs.example.com" });
679
- * } catch (error) {
680
- * console.error("Failed to open link:", error);
700
+ * ```ts source="./app.examples.ts#App_openLink_documentation"
701
+ * const { isError } = await app.openLink({ url: "https://docs.example.com" });
702
+ * if (isError) {
703
+ * // Host denied the request (e.g., blocked domain, user cancelled)
681
704
  * // Optionally show fallback: display URL for manual copy
705
+ * console.warn("Link request denied");
682
706
  * }
683
707
  * ```
684
708
  *
685
- * @see {@link McpUiOpenLinkRequest} for request structure
709
+ * @see {@link McpUiOpenLinkRequest `McpUiOpenLinkRequest`} for request structure
710
+ * @see {@link McpUiOpenLinkResult `McpUiOpenLinkResult`} for result structure
686
711
  */
687
712
  openLink(params: McpUiOpenLinkRequest["params"], options?: RequestOptions): Promise<{
688
713
  [x: string]: unknown;
689
714
  isError?: boolean | undefined;
690
715
  }>;
691
- /** @deprecated Use {@link openLink} instead */
716
+ /** @deprecated Use {@link openLink `openLink`} instead */
692
717
  sendOpenLink: App["openLink"];
693
718
  /**
694
719
  * Request a change to the display mode.
@@ -702,17 +727,18 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
702
727
  * @param options - Request options (timeout, etc.)
703
728
  * @returns Result containing the actual display mode that was set
704
729
  *
705
- * @example Request fullscreen mode
706
- * ```typescript
707
- * const context = app.getHostContext();
708
- * if (context?.availableDisplayModes?.includes("fullscreen")) {
709
- * const result = await app.requestDisplayMode({ mode: "fullscreen" });
710
- * console.log("Display mode set to:", result.mode);
730
+ * @example Toggle display mode
731
+ * ```ts source="./app.examples.ts#App_requestDisplayMode_toggle"
732
+ * const ctx = app.getHostContext();
733
+ * if (ctx?.availableDisplayModes?.includes("fullscreen")) {
734
+ * const target = ctx.displayMode === "fullscreen" ? "inline" : "fullscreen";
735
+ * const result = await app.requestDisplayMode({ mode: target });
736
+ * console.log("Now in:", result.mode);
711
737
  * }
712
738
  * ```
713
739
  *
714
- * @see {@link McpUiRequestDisplayModeRequest} for request structure
715
- * @see {@link McpUiHostContext} for checking availableDisplayModes
740
+ * @see {@link McpUiRequestDisplayModeRequest `McpUiRequestDisplayModeRequest`} for request structure
741
+ * @see {@link McpUiHostContext `McpUiHostContext`} for checking availableDisplayModes
716
742
  */
717
743
  requestDisplayMode(params: McpUiRequestDisplayModeRequest["params"], options?: RequestOptions): Promise<{
718
744
  [x: string]: unknown;
@@ -727,16 +753,16 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
727
753
  * @param params - New width and height in pixels
728
754
  *
729
755
  * @example Manually notify host of size change
730
- * ```typescript
756
+ * ```ts source="./app.examples.ts#App_sendSizeChanged_manual"
731
757
  * app.sendSizeChanged({
732
758
  * width: 400,
733
- * height: 600
759
+ * height: 600,
734
760
  * });
735
761
  * ```
736
762
  *
737
763
  * @returns Promise that resolves when the notification is sent
738
764
  *
739
- * @see {@link McpUiSizeChangedNotification} for notification structure
765
+ * @see {@link McpUiSizeChangedNotification `McpUiSizeChangedNotification`} for notification structure
740
766
  */
741
767
  sendSizeChanged(params: McpUiSizeChangedNotification["params"]): Promise<void>;
742
768
  /**
@@ -753,8 +779,12 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
753
779
  * @returns Cleanup function to disconnect the observer
754
780
  *
755
781
  * @example Manual setup for custom scenarios
756
- * ```typescript
757
- * const app = new App(appInfo, capabilities, { autoResize: false });
782
+ * ```ts source="./app.examples.ts#App_setupAutoResize_manual"
783
+ * const app = new App(
784
+ * { name: "MyApp", version: "1.0.0" },
785
+ * {},
786
+ * { autoResize: false },
787
+ * );
758
788
  * await app.connect(transport);
759
789
  *
760
790
  * // Later, enable auto-resize manually
@@ -773,22 +803,19 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
773
803
  * 2. Sends `ui/initialize` request with app info and capabilities
774
804
  * 3. Receives host capabilities and context in response
775
805
  * 4. Sends `ui/notifications/initialized` notification
776
- * 5. Sets up auto-resize using {@link setupSizeChangedNotifications} if enabled (default)
806
+ * 5. Sets up auto-resize using {@link setupSizeChangedNotifications `setupSizeChangedNotifications`} if enabled (default)
777
807
  *
778
808
  * If initialization fails, the connection is automatically closed and an error
779
809
  * is thrown.
780
810
  *
781
- * @param transport - Transport layer (typically {@link PostMessageTransport})
811
+ * @param transport - Transport layer (typically {@link PostMessageTransport `PostMessageTransport`})
782
812
  * @param options - Request options for the initialize request
783
813
  *
784
814
  * @throws {Error} If initialization fails or connection is lost
785
815
  *
786
816
  * @example Connect with PostMessageTransport
787
- * ```typescript
788
- * const app = new App(
789
- * { name: "MyApp", version: "1.0.0" },
790
- * {}
791
- * );
817
+ * ```ts source="./app.examples.ts#App_connect_withPostMessageTransport"
818
+ * const app = new App({ name: "MyApp", version: "1.0.0" }, {});
792
819
  *
793
820
  * try {
794
821
  * await app.connect(new PostMessageTransport(window.parent, window.parent));
@@ -798,9 +825,9 @@ export declare class App extends Protocol<AppRequest, AppNotification, AppResult
798
825
  * }
799
826
  * ```
800
827
  *
801
- * @see {@link McpUiInitializeRequest} for the initialization request structure
802
- * @see {@link McpUiInitializedNotification} for the initialized notification
803
- * @see {@link PostMessageTransport} for the typical transport implementation
828
+ * @see {@link McpUiInitializeRequest `McpUiInitializeRequest`} for the initialization request structure
829
+ * @see {@link McpUiInitializedNotification `McpUiInitializedNotification`} for the initialized notification
830
+ * @see {@link PostMessageTransport `PostMessageTransport`} for the typical transport implementation
804
831
  */
805
832
  connect(transport?: Transport, options?: RequestOptions): Promise<void>;
806
833
  }