Skip to content

Commit

Permalink
feat: add UserError
Browse files Browse the repository at this point in the history
  • Loading branch information
punkpeye committed Dec 27, 2024
1 parent adf1f01 commit 60b0ae7
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,29 @@ server.addTool({
});
```

#### Errors

The errors that are meant to be shown to the user should be thrown as `UserError` instances:

```js
import { UserError } from "fastmcp";

server.addTool({
name: "download",
description: "Download a file",
parameters: z.object({
url: z.string(),
}),
execute: async (args) => {
if (args.url.startsWith("https://example.com")) {
throw new UserError("This URL is not allowed");
}

return "done";
},
});
```

#### Progress

Tools can report progress by calling `reportProgress` in the context object:
Expand Down
8 changes: 4 additions & 4 deletions src/FastMCP.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FastMCP } from "./FastMCP.js";
import { FastMCP, UserError } from "./FastMCP.js";
import { z } from "zod";
import { test, expect, vi } from "vitest";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
Expand Down Expand Up @@ -138,7 +138,7 @@ test("calls a tool", async () => {
});
});

test("handles tool errors", async () => {
test("handles UserError errors", async () => {
await runWithTestServer({
start: async () => {
const server = new FastMCP({
Expand All @@ -154,7 +154,7 @@ test("handles tool errors", async () => {
b: z.number(),
}),
execute: async (args) => {
throw new Error("Something went wrong");
throw new UserError("Something went wrong");
},
});

Expand All @@ -170,7 +170,7 @@ test("handles tool errors", async () => {
},
}),
).toEqual({
content: [{ type: "text", text: "Error: Error: Something went wrong" }],
content: [{ type: "text", text: "Something went wrong" }],
isError: true,
});
},
Expand Down
30 changes: 30 additions & 0 deletions src/FastMCP.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,29 @@ import { zodToJsonSchema } from "zod-to-json-schema";
import type { z } from "zod";
import http from "http";

abstract class FastMCPError extends Error {
public constructor(message?: string) {
super(message);
this.name = new.target.name;
}
}

type Extra = unknown;

type Extras = Record<string, Extra>;

class UnexpectedStateError extends FastMCPError {
public extras?: Extras;

public constructor(message: string, extras?: Extras) {
super(message);
this.name = new.target.name;
this.extras = extras;
}
}

export class UserError extends UnexpectedStateError {}

type ToolParameters = z.ZodTypeAny;

type Progress = {
Expand Down Expand Up @@ -181,6 +204,13 @@ export class FastMCP {
reportProgress,
});
} catch (error) {
if (error instanceof UserError) {
return {
content: [{ type: "text", text: error.message }],
isError: true,
};
}

return {
content: [{ type: "text", text: `Error: ${error}` }],
isError: true,
Expand Down

0 comments on commit 60b0ae7

Please sign in to comment.