Skip to main content
Glama

Remote MCP Server with WorkOS AuthKit

by sleepypandu
authkit-handler.ts2.15 kB
import type { AuthRequest, OAuthHelpers, } from "@cloudflare/workers-oauth-provider"; import { Hono } from "hono"; import * as jose from "jose"; import { type AccessToken, type AuthenticationResponse, WorkOS, } from "@workos-inc/node"; import type { Props } from "./props"; const app = new Hono<{ Bindings: Env & { OAUTH_PROVIDER: OAuthHelpers }; Variables: { workOS: WorkOS }; }>(); app.use(async (c, next) => { c.set("workOS", new WorkOS(c.env.WORKOS_CLIENT_SECRET)); await next(); }); app.get("/authorize", async (c) => { const oauthReqInfo = await c.env.OAUTH_PROVIDER.parseAuthRequest(c.req.raw); if (!oauthReqInfo.clientId) { return c.text("Invalid request", 400); } return Response.redirect( c.get("workOS").userManagement.getAuthorizationUrl({ provider: "authkit", clientId: c.env.WORKOS_CLIENT_ID, redirectUri: new URL("/callback", c.req.url).href, state: btoa(JSON.stringify(oauthReqInfo)), }) ); }); app.get("/callback", async (c) => { const workOS = c.get("workOS"); // Get the oathReqInfo out of KV const oauthReqInfo = JSON.parse( atob(c.req.query("state") as string) ) as AuthRequest; if (!oauthReqInfo.clientId) { return c.text("Invalid state", 400); } const code = c.req.query("code"); if (!code) { return c.text("Missing code", 400); } let response: AuthenticationResponse; try { response = await workOS.userManagement.authenticateWithCode({ clientId: c.env.WORKOS_CLIENT_ID, code, }); } catch (error) { console.error("Authentication error:", error); return c.text("Invalid authorization code", 400); } const { accessToken, organizationId, refreshToken, user } = response; const { permissions = [] } = jose.decodeJwt<AccessToken>(accessToken); const { redirectTo } = await c.env.OAUTH_PROVIDER.completeAuthorization({ request: oauthReqInfo, userId: user.id, metadata: {}, scope: permissions, // This will be available on this.props inside MyMCP props: { accessToken, organizationId, permissions, refreshToken, user, } satisfies Props, }); return Response.redirect(redirectTo); }); export const AuthkitHandler = app;

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sleepypandu/remote-mcp-authkit'

If you have feedback or need assistance with the MCP directory API, please join our Discord server