Skip to content

Commit 2dd223b

Browse files
ochafikclaude
andauthored
refactor: rename request methods to remove send prefix (#161)
* refactor: rename request methods to remove send prefix Following the MCP TS SDK convention where request methods don't have the "send" prefix (reserved for notifications): - App.sendMessage() → App.message() - App.sendOpenLink() → App.openLink() - AppBridge.sendResourceTeardown() → AppBridge.resourceTeardown() The old method names are kept as deprecated aliases for backwards compatibility. Updated all examples to use the new method names. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * test: add tests for deprecated method aliases - Update existing tests to use new method names (message, openLink) - Add tests verifying deprecated aliases are same reference as new methods - Add tests verifying deprecated aliases still work functionally 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * refactor: rename message→sendMessage, resourceTeardown→teardownResource - App.message() → App.sendMessage() (with deprecated message alias) - AppBridge.resourceTeardown() → AppBridge.teardownResource() (with deprecated aliases) This better follows the pattern where methods that send data have 'send' or action verb prefix. * fix: update examples to use sendMessage instead of message * fix: update basic-host to use teardownResource * fix: update threejs-server to use sendMessage * refactor: remove deprecated app.message alias The app.message alias was removed since sendMessage is the correct name. sendResourceTeardown already exists in AppBridge. * refactor: remove resourceTeardown alias, keep only sendResourceTeardown --------- Co-authored-by: Claude <[email protected]>
1 parent 37aab03 commit 2dd223b

File tree

14 files changed

+59
-259
lines changed

14 files changed

+59
-259
lines changed

examples/basic-host/src/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ function AppIFramePanel({ toolCallInfo, isDestroying, onTeardownComplete }: AppI
289289
}
290290

291291
log.info("Sending teardown notification to MCP App");
292-
appBridgeRef.current.sendResourceTeardown({})
292+
appBridgeRef.current.teardownResource({})
293293
.catch((err) => {
294294
log.warn("Teardown request failed (app may have already closed):", err);
295295
})

examples/basic-server-react/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ An MCP App example with a React UI.
99

1010
- Tool registration with a linked UI resource
1111
- React UI using the [`useApp()`](https://modelcontextprotocol.github.io/ext-apps/api/functions/_modelcontextprotocol_ext-apps_react.useApp.html) hook
12-
- App communication APIs: [`callServerTool`](https://modelcontextprotocol.github.io/ext-apps/api/classes/app.App.html#callservertool), [`sendMessage`](https://modelcontextprotocol.github.io/ext-apps/api/classes/app.App.html#sendmessage), [`sendLog`](https://modelcontextprotocol.github.io/ext-apps/api/classes/app.App.html#sendlog), [`sendOpenLink`](https://modelcontextprotocol.github.io/ext-apps/api/classes/app.App.html#sendopenlink)
12+
- App communication APIs: [`callServerTool`](https://modelcontextprotocol.github.io/ext-apps/api/classes/app.App.html#callservertool), [`sendMessage`](https://modelcontextprotocol.github.io/ext-apps/api/classes/app.App.html#sendmessage), [`sendLog`](https://modelcontextprotocol.github.io/ext-apps/api/classes/app.App.html#sendlog), [`openLink`](https://modelcontextprotocol.github.io/ext-apps/api/classes/app.App.html#openlink)
1313

1414
## Key Files
1515

examples/basic-server-react/src/mcp-app.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ function GetTimeAppInner({ app, toolResult }: GetTimeAppInnerProps) {
110110

111111
const handleOpenLink = useCallback(async () => {
112112
log.info("Sending open link request to Host:", linkUrl);
113-
const { isError } = await app.sendOpenLink({ url: linkUrl });
113+
const { isError } = await app.openLink({ url: linkUrl });
114114
log.info("Open link request", isError ? "rejected" : "accepted");
115115
}, [app, linkUrl]);
116116

examples/basic-server-vanillajs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ An MCP App example with a vanilla JavaScript UI (no framework).
99

1010
- Tool registration with a linked UI resource
1111
- Vanilla JS UI using the [`App`](https://modelcontextprotocol.github.io/ext-apps/api/classes/app.App.html) class directly
12-
- App communication APIs: [`callServerTool`](https://modelcontextprotocol.github.io/ext-apps/api/classes/app.App.html#callservertool), [`sendMessage`](https://modelcontextprotocol.github.io/ext-apps/api/classes/app.App.html#sendmessage), [`sendLog`](https://modelcontextprotocol.github.io/ext-apps/api/classes/app.App.html#sendlog), [`sendOpenLink`](https://modelcontextprotocol.github.io/ext-apps/api/classes/app.App.html#sendopenlink)
12+
- App communication APIs: [`callServerTool`](https://modelcontextprotocol.github.io/ext-apps/api/classes/app.App.html#callservertool), [`sendMessage`](https://modelcontextprotocol.github.io/ext-apps/api/classes/app.App.html#sendmessage), [`sendLog`](https://modelcontextprotocol.github.io/ext-apps/api/classes/app.App.html#sendlog), [`openLink`](https://modelcontextprotocol.github.io/ext-apps/api/classes/app.App.html#openlink)
1313

1414
## Key Files
1515

examples/basic-server-vanillajs/src/mcp-app.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ sendLogBtn.addEventListener("click", async () => {
9292

9393
openLinkBtn.addEventListener("click", async () => {
9494
log.info("Sending open link request to Host:", linkUrl.value);
95-
const { isError } = await app.sendOpenLink({ url: linkUrl.value });
95+
const { isError } = await app.openLink({ url: linkUrl.value });
9696
log.info("Open link request", isError ? "rejected" : "accepted");
9797
});
9898

examples/threejs-server/src/mcp-app-wrapper.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export interface WidgetProps<TToolInput = Record<string, unknown>> {
3232
/** Send a message to the host's chat */
3333
sendMessage: App["sendMessage"];
3434
/** Request the host to open a URL */
35-
sendOpenLink: App["sendOpenLink"];
35+
openLink: App["openLink"];
3636
/** Send log messages to the host */
3737
sendLog: App["sendLog"];
3838
}
@@ -81,8 +81,8 @@ function McpAppWrapper() {
8181
(params, options) => app!.sendMessage(params, options),
8282
[app],
8383
);
84-
const sendOpenLink = useCallback<App["sendOpenLink"]>(
85-
(params, options) => app!.sendOpenLink(params, options),
84+
const openLink = useCallback<App["openLink"]>(
85+
(params, options) => app!.openLink(params, options),
8686
[app],
8787
);
8888
const sendLog = useCallback<App["sendLog"]>(
@@ -106,7 +106,7 @@ function McpAppWrapper() {
106106
hostContext={hostContext}
107107
callServerTool={callServerTool}
108108
sendMessage={sendMessage}
109-
sendOpenLink={sendOpenLink}
109+
openLink={openLink}
110110
sendLog={sendLog}
111111
/>
112112
);

examples/threejs-server/src/threejs-app.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export default function ThreeJSApp({
143143
hostContext: _hostContext,
144144
callServerTool: _callServerTool,
145145
sendMessage: _sendMessage,
146-
sendOpenLink: _sendOpenLink,
146+
openLink: _openLink,
147147
sendLog: _sendLog,
148148
}: ThreeJSAppProps) {
149149
const [error, setError] = useState<string | null>(null);

examples/wiki-explorer-server/src/mcp-app.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ resetBtn.addEventListener("click", async () => {
270270
// Open button - opens the Wikipedia page in browser
271271
openBtn.addEventListener("click", async () => {
272272
if (selectedNodeUrl) {
273-
await app.sendOpenLink({ url: selectedNodeUrl });
273+
await app.openLink({ url: selectedNodeUrl });
274274
hidePopup();
275275
}
276276
});

src/app-bridge.test.ts

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -373,20 +373,20 @@ describe("App <-> AppBridge integration", () => {
373373
await newBridgeTransport.close();
374374
});
375375

376-
it("sendResourceTeardown triggers app.onteardown", async () => {
376+
it("teardownResource triggers app.onteardown", async () => {
377377
let teardownCalled = false;
378378
app.onteardown = async () => {
379379
teardownCalled = true;
380380
return {};
381381
};
382382

383383
await app.connect(appTransport);
384-
await bridge.sendResourceTeardown({});
384+
await bridge.teardownResource({});
385385

386386
expect(teardownCalled).toBe(true);
387387
});
388388

389-
it("sendResourceTeardown waits for async cleanup", async () => {
389+
it("teardownResource waits for async cleanup", async () => {
390390
const cleanupSteps: string[] = [];
391391
app.onteardown = async () => {
392392
cleanupSteps.push("start");
@@ -396,7 +396,7 @@ describe("App <-> AppBridge integration", () => {
396396
};
397397

398398
await app.connect(appTransport);
399-
await bridge.sendResourceTeardown({});
399+
await bridge.teardownResource({});
400400

401401
expect(cleanupSteps).toEqual(["start", "done"]);
402402
});
@@ -481,32 +481,59 @@ describe("App <-> AppBridge integration", () => {
481481
expect(result.isError).toBe(true);
482482
});
483483

484-
it("app.sendOpenLink triggers bridge.onopenlink and returns result", async () => {
484+
it("app.openLink triggers bridge.onopenlink and returns result", async () => {
485485
const receivedLinks: string[] = [];
486486
bridge.onopenlink = async (params) => {
487487
receivedLinks.push(params.url);
488488
return {};
489489
};
490490

491491
await app.connect(appTransport);
492-
const result = await app.sendOpenLink({ url: "https://example.com" });
492+
const result = await app.openLink({ url: "https://example.com" });
493493

494494
expect(receivedLinks).toEqual(["https://example.com"]);
495495
expect(result).toEqual({});
496496
});
497497

498-
it("app.sendOpenLink returns error when host denies", async () => {
498+
it("app.openLink returns error when host denies", async () => {
499499
bridge.onopenlink = async () => {
500500
return { isError: true };
501501
};
502502

503503
await app.connect(appTransport);
504-
const result = await app.sendOpenLink({ url: "https://blocked.com" });
504+
const result = await app.openLink({ url: "https://blocked.com" });
505505

506506
expect(result.isError).toBe(true);
507507
});
508508
});
509509

510+
describe("deprecated method aliases", () => {
511+
beforeEach(async () => {
512+
await bridge.connect(bridgeTransport);
513+
await app.connect(appTransport);
514+
});
515+
516+
it("app.sendOpenLink is an alias for app.openLink", async () => {
517+
expect(app.sendOpenLink).toBe(app.openLink);
518+
});
519+
520+
it("bridge.sendResourceTeardown is a deprecated alias for bridge.teardownResource", () => {
521+
expect(bridge.sendResourceTeardown).toBe(bridge.teardownResource);
522+
});
523+
524+
it("app.sendOpenLink works as deprecated alias", async () => {
525+
const receivedLinks: string[] = [];
526+
bridge.onopenlink = async (params) => {
527+
receivedLinks.push(params.url);
528+
return {};
529+
};
530+
531+
await app.sendOpenLink({ url: "https://example.com" });
532+
533+
expect(receivedLinks).toEqual(["https://example.com"]);
534+
});
535+
});
536+
510537
describe("ping", () => {
511538
it("App responds to ping from bridge", async () => {
512539
await bridge.connect(bridgeTransport);

src/app-bridge.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ type RequestHandlerExtra = Parameters<
176176
* 2. **Connect**: Call `connect()` with transport to establish communication
177177
* 3. **Wait for init**: Guest UI sends initialize request, bridge responds
178178
* 4. **Send data**: Call `sendToolInput()`, `sendToolResult()`, etc.
179-
* 5. **Teardown**: Call `sendResourceTeardown()` before unmounting iframe
179+
* 5. **Teardown**: Call `teardownResource()` before unmounting iframe
180180
*
181181
* @example Basic usage
182182
* ```typescript
@@ -1219,15 +1219,15 @@ export class AppBridge extends Protocol<
12191219
* @example
12201220
* ```typescript
12211221
* try {
1222-
* await bridge.sendResourceTeardown({});
1222+
* await bridge.teardownResource({});
12231223
* // Guest UI is ready, safe to unmount iframe
12241224
* iframe.remove();
12251225
* } catch (error) {
12261226
* console.error("Teardown failed:", error);
12271227
* }
12281228
* ```
12291229
*/
1230-
sendResourceTeardown(
1230+
teardownResource(
12311231
params: McpUiResourceTeardownRequest["params"],
12321232
options?: RequestOptions,
12331233
) {
@@ -1241,6 +1241,9 @@ export class AppBridge extends Protocol<
12411241
);
12421242
}
12431243

1244+
/** @deprecated Use {@link teardownResource} instead */
1245+
sendResourceTeardown: AppBridge["teardownResource"] = this.teardownResource;
1246+
12441247
/**
12451248
* Connect to the Guest UI via transport and optionally set up message forwarding.
12461249
*

0 commit comments

Comments
 (0)