-
Notifications
You must be signed in to change notification settings - Fork 1
Add OAuth 2.1 authentication flow for MCP server #21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…client The fetch api client has a bug that causes it to fail to throw an error on non-2xx responses
| // Initialize the Hono app with routes for the OAuth Provider | ||
| const app = new Hono<{ Bindings: Env & { OAUTH_PROVIDER: any } }>(); | ||
| app.get("/authorize", authorize); | ||
| app.post("/authorize/consent", confirmConsent); | ||
| app.get("/callback", callback); | ||
| app.post("/register", registerClient); | ||
|
|
||
| // Root endpoint for basic server info | ||
| app.get("/", (c) => { | ||
| const serverInfo = getServerInfo(); | ||
| return c.json({ | ||
| name: serverInfo.name, | ||
| version: serverInfo.version, | ||
| endpoints: { | ||
| mcp: "/mcp", | ||
| sse: "/sse", | ||
| oauth_authorize: "/authorize", | ||
| oauth_callback: "/callback", | ||
| oauth_token: "/token", | ||
| }, | ||
| }); | ||
| }); | ||
|
|
||
| function createOAuthProviderIfConfigured(env: Env) { | ||
| // Only create OAuth provider if all required variables are set | ||
| if (!env.OAUTH_CLIENT_ID || !env.OAUTH_CLIENT_SECRET || !env.OAUTH_AUTHORIZATION_ENDPOINT) { | ||
| return null; | ||
| } | ||
|
|
||
| return new OAuthProvider({ | ||
| apiHandlers: { | ||
| // @ts-ignore | ||
| "/mcp": GravatarMcpServer.serve("/mcp"), | ||
| // @ts-ignore | ||
| "/sse": GravatarMcpServer.serveSSE("/sse"), | ||
| }, | ||
| // @ts-ignore | ||
| defaultHandler: app, | ||
| authorizeEndpoint: "/authorize", | ||
| tokenEndpoint: "/token", | ||
| tokenExchangeCallback: (options: any) => tokenExchangeCallback(options), | ||
| clientRegistrationEndpoint: "/register", | ||
| }); | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the main part of OAuth support. Most of the rest of the changes are there to support this.
| // @ts-ignore | ||
| "/mcp": GravatarMcpServer.serve("/mcp"), | ||
| // @ts-ignore | ||
| "/sse": GravatarMcpServer.serveSSE("/sse"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These // @ts-ignore are here because I couldn't figure out why TypeScript was complaining. Specifically, the error (which is hard to parse) says that the GravatarMcpServer.serve() function (and the other one) are returning a function signature that is slightly different from what the apiHandlers closure expects.
Yet this exact code checks out fine in Cloudflare's own production MCP servers:
return new OAuthProvider({
apiHandlers: {
'/mcp': DNSAnalyticsMCP.serve('/mcp'),
'/sse': DNSAnalyticsMCP.serveSSE('/sse'),
},
// @ts-ignore
defaultHandler: createAuthHandlers({ scopes: AnalyticsScopes, metrics }),
authorizeEndpoint: '/oauth/authorize',
tokenEndpoint: '/token',
tokenExchangeCallback: (options) =>
handleTokenExchangeCallback(
options,
env.CLOUDFLARE_CLIENT_ID,
env.CLOUDFLARE_CLIENT_SECRET
),
// Cloudflare access token TTL
accessTokenTTL: 3600,
clientRegistrationEndpoint: '/register',
}).fetch(req, env, ctx)
},Note, however that the defaultHandler parameter has a similar problem in Cloudflare's servers, requiring the same comment.
| if (oauthProvider) { | ||
| return oauthProvider.fetch(request, env, ctx); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This conditional logic probably isn't necessary, useful, or even desirable. If the proper OAuth settings aren't available, we should fix that problem rather than booting up a server that just doesn't support OAuth. Especially since many tools require it.
Summary
Key Changes
OAuth Authentication System:
Development Environment:
.dev.vars.exampletemplate with detailed setup instructions.dev.vars) and configuration (wrangler.jsonc)Tool System Improvements:
search-profiles-by-verified-accounttoolConfiguration Management:
wrangler.jsoncTest Plan
npm run dev🤖 Generated with Claude Code