import OAuthProvider from "@cloudflare/workers-oauth-provider";
import { McpAgent } from "agents/mcp";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import { GoogleHandler, type GoogleOAuthProps } from "./google-handler";
// Props type for authenticated user information
type Props = GoogleOAuthProps;
// Define our MCP agent with tools
export class MyMCP extends McpAgent<Env, {}, Props> {
server = new McpServer({
name: "Authenticated Calculator",
version: "1.0.0",
});
async init() {
// Simple addition tool
this.server.tool(
"add",
{ a: z.number(), b: z.number() },
async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }],
}),
);
// Calculator tool with multiple operations
this.server.tool(
"calculate",
{
operation: z.enum(["add", "subtract", "multiply", "divide"]),
a: z.number(),
b: z.number(),
},
async ({ operation, a, b }) => {
let result: number;
switch (operation) {
case "add":
result = a + b;
break;
case "subtract":
result = a - b;
break;
case "multiply":
result = a * b;
break;
case "divide":
if (b === 0)
return {
content: [
{
type: "text",
text: "Error: Cannot divide by zero",
},
],
};
result = a / b;
break;
}
return { content: [{ type: "text", text: String(result) }] };
},
);
// Tool to get current user info (demonstrates auth context usage)
this.server.tool("whoami", {}, async () => {
const userInfo = this.props;
if (!userInfo || !userInfo.email) {
return {
content: [{ type: "text", text: "Not authenticated" }],
};
}
return {
content: [
{
type: "text",
text: `Authenticated as: ${userInfo.name} (${userInfo.email})`,
},
],
};
});
}
}
// Export with OAuthProvider wrapping the MCP handlers
export default new OAuthProvider({
apiHandlers: {
"/sse": MyMCP.serveSSE("/sse"),
"/mcp": MyMCP.serve("/mcp"),
},
defaultHandler: GoogleHandler,
authorizeEndpoint: "/authorize",
tokenEndpoint: "/token",
clientRegistrationEndpoint: "/register",
});