Skip to content

Commit 6669529

Browse files
ochafikclaude
andauthored
feat(app): throw helpful error when callServerTool is called with a string (modelcontextprotocol#449)
Users frequently call callServerTool("tool_name", args) instead of the correct callServerTool({ name: "tool_name", arguments: args }), resulting in a silent/confusing failure. Detect this and throw immediately with a message that shows the correct call shape. Also fixes the incorrect example in examples/pdf-server/README.md that demonstrated this same wrong usage pattern. Fixes modelcontextprotocol#386 https://claude.ai/code/session_01GqAyN4Ux7svWoU2HqsSLZF Co-authored-by: Claude <noreply@anthropic.com>
1 parent 0bbbfee commit 6669529

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

examples/pdf-server/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,10 @@ On some host platforms, tool calls have size limits, so large PDFs cannot be sen
6363
```typescript
6464
// Load in chunks with progress
6565
while (hasMore) {
66-
const chunk = await app.callServerTool("read_pdf_bytes", { url, offset });
66+
const chunk = await app.callServerTool({
67+
name: "read_pdf_bytes",
68+
arguments: { url, offset },
69+
});
6770
chunks.push(base64ToBytes(chunk.bytes));
6871
offset += chunk.byteCount;
6972
hasMore = chunk.hasMore;

src/app-bridge.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,19 @@ describe("App <-> AppBridge integration", () => {
678678
expect(result.content).toEqual(resultContent);
679679
});
680680

681+
it("callServerTool throws a helpful error when called with a string instead of params object", async () => {
682+
await bridge.connect(bridgeTransport);
683+
await app.connect(appTransport);
684+
685+
await expect(
686+
// @ts-expect-error intentionally testing wrong usage
687+
app.callServerTool("my_tool"),
688+
).rejects.toThrow(
689+
'callServerTool() expects an object as its first argument, but received a string ("my_tool"). ' +
690+
'Did you mean: callServerTool({ name: "my_tool", arguments: { ... } })?',
691+
);
692+
});
693+
681694
it("onlistresources setter registers handler for resources/list requests", async () => {
682695
const requestParams = {};
683696
const resources = [{ uri: "test://resource", name: "Test" }];

src/app.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,12 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
724724
params: CallToolRequest["params"],
725725
options?: RequestOptions,
726726
): Promise<CallToolResult> {
727+
if (typeof params === "string") {
728+
throw new Error(
729+
`callServerTool() expects an object as its first argument, but received a string ("${params}"). ` +
730+
`Did you mean: callServerTool({ name: "${params}", arguments: { ... } })?`,
731+
);
732+
}
727733
return await this.request(
728734
{ method: "tools/call", params },
729735
CallToolResultSchema,

0 commit comments

Comments
 (0)