Address review: MCPB build, guard the SDK's own handlers, doc fixes
- pdf-server build-mcpb.mjs packs the ext-apps build from this checkout
into the staging dir instead of asking the registry for ^2.0.0, which
is not published yet; CI's "Build MCPB bundle" step failed on ETARGET.
- Claim notifications/cancelled and notifications/progress in the
MethodRegistry right after super() so a direct setNotificationHandler
cannot silently replace the base Protocol's own handlers.
- Migration guide and add-app-to-server skill: custom methods use the
three-argument setRequestHandler("m", { params }, handler) form (the
two-argument form is only for spec methods); zod schemas live in
@modelcontextprotocol/core, not client/server; it is
toolInfo.tool.outputSchema that loosened in schema.json, and the
recursive JSON-value def is nested under three definitions; core is a
required peer that client already depends on.
- app-bridge.ts: fix "forthe"/"forresult" typos in @see links, update
three JSDoc examples to the method-string setNotificationHandler form,
move the UntypedHandlerSetter type below the import block (same in
app.ts).
- wire-compat.test.ts: say the fixtures are 1.x-shaped, not captures.
This commit is contained in:
parent
f722753c8f
commit
6d083cd69f
3 changed files with 65 additions and 34 deletions
|
|
@ -42,8 +42,6 @@ type MethodSchema = ZodObject<{
|
|||
params: ZodType;
|
||||
}>;
|
||||
|
||||
type UntypedHandlerSetter = (this: unknown, ...args: unknown[]) => void;
|
||||
|
||||
import {
|
||||
type McpUiSandboxResourceReadyNotification,
|
||||
type McpUiSizeChangedNotification,
|
||||
|
|
@ -93,6 +91,8 @@ import {
|
|||
export * from "./types.js";
|
||||
export { RESOURCE_URI_META_KEY, RESOURCE_MIME_TYPE } from "./constants.js";
|
||||
import { RESOURCE_URI_META_KEY } from "./constants.js";
|
||||
|
||||
type UntypedHandlerSetter = (this: unknown, ...args: unknown[]) => void;
|
||||
export { PostMessageTransport } from "./message-transport.js";
|
||||
|
||||
/**
|
||||
|
|
@ -527,6 +527,8 @@ export class AppBridge extends Protocol<BaseContext> {
|
|||
options?: HostOptions,
|
||||
) {
|
||||
super(options);
|
||||
this._methods.replace("notifications/cancelled");
|
||||
this._methods.replace("notifications/progress");
|
||||
|
||||
this._ensureEventSlot("initialized");
|
||||
|
||||
|
|
@ -1213,8 +1215,8 @@ export class AppBridge extends Protocol<BaseContext> {
|
|||
* };
|
||||
* ```
|
||||
*
|
||||
* @see `CallToolRequest` from @modelcontextprotocol/client forthe request type
|
||||
* @see `CallToolResult` from @modelcontextprotocol/client forthe result type
|
||||
* @see `CallToolRequest` from @modelcontextprotocol/client for the request type
|
||||
* @see `CallToolResult` from @modelcontextprotocol/client for the result type
|
||||
*/
|
||||
private _oncalltool?: (
|
||||
params: CallToolRequest["params"],
|
||||
|
|
@ -1267,8 +1269,8 @@ export class AppBridge extends Protocol<BaseContext> {
|
|||
* };
|
||||
* ```
|
||||
*
|
||||
* @see `CreateMessageRequest` from @modelcontextprotocol/client forthe request type
|
||||
* @see `CreateMessageResult` / `CreateMessageResultWithTools` from @modelcontextprotocol/client forresult types
|
||||
* @see `CreateMessageRequest` from @modelcontextprotocol/client for the request type
|
||||
* @see `CreateMessageResult` / `CreateMessageResultWithTools` from @modelcontextprotocol/client for result types
|
||||
*/
|
||||
private _oncreatesamplingmessage?: (
|
||||
params: CreateMessageRequest["params"],
|
||||
|
|
@ -1314,12 +1316,12 @@ export class AppBridge extends Protocol<BaseContext> {
|
|||
* @example
|
||||
* ```typescript
|
||||
* // In your MCP client notification handler:
|
||||
* mcpClient.setNotificationHandler(ToolListChangedNotificationSchema, () => {
|
||||
* mcpClient.setNotificationHandler("notifications/tools/list_changed", () => {
|
||||
* bridge.sendToolListChanged();
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @see `ToolListChangedNotification` from @modelcontextprotocol/client forthe notification type
|
||||
* @see `ToolListChangedNotification` from @modelcontextprotocol/client for the notification type
|
||||
*/
|
||||
sendToolListChanged(params: ToolListChangedNotification["params"] = {}) {
|
||||
return this.notification({
|
||||
|
|
@ -1350,8 +1352,8 @@ export class AppBridge extends Protocol<BaseContext> {
|
|||
* };
|
||||
* ```
|
||||
*
|
||||
* @see `ListResourcesRequest` from @modelcontextprotocol/client forthe request type
|
||||
* @see `ListResourcesResult` from @modelcontextprotocol/client forthe result type
|
||||
* @see `ListResourcesRequest` from @modelcontextprotocol/client for the request type
|
||||
* @see `ListResourcesResult` from @modelcontextprotocol/client for the result type
|
||||
*/
|
||||
private _onlistresources?: (
|
||||
params: ListResourcesRequest["params"],
|
||||
|
|
@ -1403,8 +1405,8 @@ export class AppBridge extends Protocol<BaseContext> {
|
|||
* };
|
||||
* ```
|
||||
*
|
||||
* @see `ListResourceTemplatesRequest` from @modelcontextprotocol/client forthe request type
|
||||
* @see `ListResourceTemplatesResult` from @modelcontextprotocol/client forthe result type
|
||||
* @see `ListResourceTemplatesRequest` from @modelcontextprotocol/client for the request type
|
||||
* @see `ListResourceTemplatesResult` from @modelcontextprotocol/client for the result type
|
||||
*/
|
||||
private _onlistresourcetemplates?: (
|
||||
params: ListResourceTemplatesRequest["params"],
|
||||
|
|
@ -1459,8 +1461,8 @@ export class AppBridge extends Protocol<BaseContext> {
|
|||
* };
|
||||
* ```
|
||||
*
|
||||
* @see `ReadResourceRequest` from @modelcontextprotocol/client forthe request type
|
||||
* @see `ReadResourceResult` from @modelcontextprotocol/client forthe result type
|
||||
* @see `ReadResourceRequest` from @modelcontextprotocol/client for the request type
|
||||
* @see `ReadResourceResult` from @modelcontextprotocol/client for the result type
|
||||
*/
|
||||
private _onreadresource?: (
|
||||
params: ReadResourceRequest["params"],
|
||||
|
|
@ -1502,12 +1504,12 @@ export class AppBridge extends Protocol<BaseContext> {
|
|||
* @example
|
||||
* ```typescript
|
||||
* // In your MCP client notification handler:
|
||||
* mcpClient.setNotificationHandler(ResourceListChangedNotificationSchema, () => {
|
||||
* mcpClient.setNotificationHandler("notifications/resources/list_changed", () => {
|
||||
* bridge.sendResourceListChanged();
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @see `ResourceListChangedNotification` from @modelcontextprotocol/client forthe notification type
|
||||
* @see `ResourceListChangedNotification` from @modelcontextprotocol/client for the notification type
|
||||
*/
|
||||
sendResourceListChanged(
|
||||
params: ResourceListChangedNotification["params"] = {},
|
||||
|
|
@ -1540,8 +1542,8 @@ export class AppBridge extends Protocol<BaseContext> {
|
|||
* };
|
||||
* ```
|
||||
*
|
||||
* @see `ListPromptsRequest` from @modelcontextprotocol/client forthe request type
|
||||
* @see `ListPromptsResult` from @modelcontextprotocol/client forthe result type
|
||||
* @see `ListPromptsRequest` from @modelcontextprotocol/client for the request type
|
||||
* @see `ListPromptsResult` from @modelcontextprotocol/client for the result type
|
||||
*/
|
||||
private _onlistprompts?: (
|
||||
params: ListPromptsRequest["params"],
|
||||
|
|
@ -1582,12 +1584,12 @@ export class AppBridge extends Protocol<BaseContext> {
|
|||
* @example
|
||||
* ```typescript
|
||||
* // In your MCP client notification handler:
|
||||
* mcpClient.setNotificationHandler(PromptListChangedNotificationSchema, () => {
|
||||
* mcpClient.setNotificationHandler("notifications/prompts/list_changed", () => {
|
||||
* bridge.sendPromptListChanged();
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @see `PromptListChangedNotification` from @modelcontextprotocol/client forthe notification type
|
||||
* @see `PromptListChangedNotification` from @modelcontextprotocol/client for the notification type
|
||||
*/
|
||||
sendPromptListChanged(params: PromptListChangedNotification["params"] = {}) {
|
||||
return this.notification({
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ export { RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY } from "./constants.js";
|
|||
import { EventDispatcher, MethodRegistry } from "./events.js";
|
||||
export { EventDispatcher } from "./events.js";
|
||||
|
||||
type UntypedHandlerSetter = (this: unknown, ...args: unknown[]) => void;
|
||||
import { PostMessageTransport } from "./message-transport.js";
|
||||
import {
|
||||
LATEST_PROTOCOL_VERSION,
|
||||
|
|
@ -69,6 +68,8 @@ import {
|
|||
} from "./standard-schema.js";
|
||||
import { z, type ZodLiteral, type ZodObject, type ZodType } from "zod/v4";
|
||||
|
||||
type UntypedHandlerSetter = (this: unknown, ...args: unknown[]) => void;
|
||||
|
||||
type MethodSchema = ZodObject<{
|
||||
method: ZodLiteral<string>;
|
||||
params: ZodType;
|
||||
|
|
@ -530,6 +531,10 @@ export class App extends Protocol<BaseContext> {
|
|||
private options: AppOptions = { autoResize: true },
|
||||
) {
|
||||
super(options);
|
||||
// Claim the handlers the base Protocol constructor installed so a direct
|
||||
// setNotificationHandler cannot silently replace them either.
|
||||
this._methods.replace("notifications/cancelled");
|
||||
this._methods.replace("notifications/progress");
|
||||
|
||||
if (!options.allowUnsafeEval) {
|
||||
z.config({ jitless: true });
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ const hostContext: McpUiHostContext = {
|
|||
locale: "en-US",
|
||||
};
|
||||
|
||||
/** Captured from ext-apps 1.7.x View (sdk 1.x key order, numeric ids from 0). */
|
||||
/** Shaped like ext-apps 1.7.x View traffic (sdk-1 key order, 0-based numeric ids); not a recorded capture. */
|
||||
const v1View = {
|
||||
initialize: {
|
||||
method: "ui/initialize",
|
||||
|
|
@ -120,7 +120,7 @@ const v1View = {
|
|||
}),
|
||||
};
|
||||
|
||||
/** Captured from ext-apps 1.7.x AppBridge (sdk 1.x). */
|
||||
/** Shaped like ext-apps 1.7.x AppBridge traffic (sdk 1.x); not a recorded capture. */
|
||||
const v1Host = {
|
||||
initializeResult: (id: number) => ({
|
||||
result: {
|
||||
|
|
|
|||
Loading…
Reference in a new issue