feat(app): throw helpful error when callServerTool is called with a string (#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 #386
https://claude.ai/code/session_01GqAyN4Ux7svWoU2HqsSLZF
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
parent
0bbbfee8c2
commit
666952980f
3 changed files with 23 additions and 1 deletions
|
|
@ -63,7 +63,10 @@ On some host platforms, tool calls have size limits, so large PDFs cannot be sen
|
||||||
```typescript
|
```typescript
|
||||||
// Load in chunks with progress
|
// Load in chunks with progress
|
||||||
while (hasMore) {
|
while (hasMore) {
|
||||||
const chunk = await app.callServerTool("read_pdf_bytes", { url, offset });
|
const chunk = await app.callServerTool({
|
||||||
|
name: "read_pdf_bytes",
|
||||||
|
arguments: { url, offset },
|
||||||
|
});
|
||||||
chunks.push(base64ToBytes(chunk.bytes));
|
chunks.push(base64ToBytes(chunk.bytes));
|
||||||
offset += chunk.byteCount;
|
offset += chunk.byteCount;
|
||||||
hasMore = chunk.hasMore;
|
hasMore = chunk.hasMore;
|
||||||
|
|
|
||||||
|
|
@ -678,6 +678,19 @@ describe("App <-> AppBridge integration", () => {
|
||||||
expect(result.content).toEqual(resultContent);
|
expect(result.content).toEqual(resultContent);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("callServerTool throws a helpful error when called with a string instead of params object", async () => {
|
||||||
|
await bridge.connect(bridgeTransport);
|
||||||
|
await app.connect(appTransport);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
// @ts-expect-error intentionally testing wrong usage
|
||||||
|
app.callServerTool("my_tool"),
|
||||||
|
).rejects.toThrow(
|
||||||
|
'callServerTool() expects an object as its first argument, but received a string ("my_tool"). ' +
|
||||||
|
'Did you mean: callServerTool({ name: "my_tool", arguments: { ... } })?',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("onlistresources setter registers handler for resources/list requests", async () => {
|
it("onlistresources setter registers handler for resources/list requests", async () => {
|
||||||
const requestParams = {};
|
const requestParams = {};
|
||||||
const resources = [{ uri: "test://resource", name: "Test" }];
|
const resources = [{ uri: "test://resource", name: "Test" }];
|
||||||
|
|
|
||||||
|
|
@ -724,6 +724,12 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
|
||||||
params: CallToolRequest["params"],
|
params: CallToolRequest["params"],
|
||||||
options?: RequestOptions,
|
options?: RequestOptions,
|
||||||
): Promise<CallToolResult> {
|
): Promise<CallToolResult> {
|
||||||
|
if (typeof params === "string") {
|
||||||
|
throw new Error(
|
||||||
|
`callServerTool() expects an object as its first argument, but received a string ("${params}"). ` +
|
||||||
|
`Did you mean: callServerTool({ name: "${params}", arguments: { ... } })?`,
|
||||||
|
);
|
||||||
|
}
|
||||||
return await this.request(
|
return await this.request(
|
||||||
{ method: "tools/call", params },
|
{ method: "tools/call", params },
|
||||||
CallToolResultSchema,
|
CallToolResultSchema,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue