Skip to content

Commit 19b498e

Browse files
committed
clean up tools
1 parent e826805 commit 19b498e

1 file changed

Lines changed: 23 additions & 14 deletions

File tree

  • examples/example-express-mcp/src

examples/example-express-mcp/src/tools.ts

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,15 @@ export const SCOPES_SUPPORTED = ["tool:whoami", "tool:greet"];
1515
*/
1616
export function requireScopes<T extends ZodRawShape>(
1717
requiredScopes: readonly string[],
18-
handler: ToolCallback<T>
18+
handler: (args: T, extra: { authInfo: Auth }) => Promise<CallToolResult>
1919
): ToolCallback<T> {
20-
return (async (args, context) => {
20+
return (async (args, extra) => {
21+
// To support both context-only and payload+context handlers
22+
let context = extra;
23+
if (!extra) {
24+
context = args as Parameters<ToolCallback<T>>[1];
25+
}
26+
2127
if (!context.authInfo) {
2228
throw new Error(
2329
"Authentication information is required to execute this tool."
@@ -32,7 +38,7 @@ export function requireScopes<T extends ZodRawShape>(
3238
throw new Error(`Missing required scopes: ${requiredScopes.join(", ")}`);
3339
}
3440

35-
return handler(args, context);
41+
return handler(args as T, { authInfo: context.authInfo as Auth });
3642
}) as ToolCallback<T>;
3743
}
3844

@@ -57,10 +63,9 @@ export const tools = [
5763
},
5864
handler: requireScopes<typeof greetToolInputSchema>(
5965
["tool:greet"],
60-
async (payload, context) => {
61-
const { name } = payload;
62-
const authInfo = context.authInfo as Auth;
63-
const userId = authInfo.extra?.sub;
66+
async (payload, { authInfo }) => {
67+
const name = payload.name || "World";
68+
const userId = authInfo.extra.sub;
6469
return {
6570
content: [
6671
{
@@ -76,18 +81,22 @@ export const tools = [
7681
name: "whoami",
7782
config: {
7883
title: "Whoami Tool",
79-
description: "Greets a user",
84+
description: "Returns the authenticated user's information",
8085
annotations: { readOnlyHint: false },
8186
},
82-
handler: requireScopes(["tool:greet"], async (payload, context) => {
83-
const name = payload.name ?? "World";
84-
const authInfo = context.authInfo as Auth;
85-
const userId = authInfo?.extra?.sub;
87+
handler: requireScopes(["tool:whoami"], async (_payload, { authInfo }) => {
8688
return {
8789
content: [
8890
{
89-
type: "text",
90-
text: `Hello, ${name}! You are authenticated as: ${userId}`,
91+
type: "text" as const,
92+
text: JSON.stringify(
93+
{
94+
user: authInfo.extra,
95+
scopes: authInfo.scopes,
96+
},
97+
null,
98+
2
99+
),
91100
},
92101
],
93102
};

0 commit comments

Comments
 (0)