Skip to main content
Glama

Convex MCP server

Official
by get-convex
callback.ts3.1 kB
import { NextApiRequest, NextApiResponse } from "next"; import { WorkOS } from "@workos-inc/node"; import { captureException } from "@sentry/nextjs"; export default async function handler( req: NextApiRequest, res: NextApiResponse, ) { if (req.method !== "GET") { return res.status(405).json({ error: "Method not allowed" }); } const workos = new WorkOS(process.env.WORKOS_API_SECRET, { clientId: process.env.WORKOS_CLIENT_ID, }); // The authorization code returned by AuthKit const code = req.query.code as string; const state = req.query.state as string; // This contains our returnTo URL const { resource_id, path, url } = req.query; let returnTo = state && !state.startsWith("/api") ? state : "/"; // url is a query parameter that is only set by the Vercel auth flow // if it is set, and looks like a redirect to the device-auth flow, // we redirect to the device-auth flow. if (typeof url === "string" && url.startsWith("https://auth.convex.dev")) { returnTo = url; } else if (typeof path === "string" || typeof resource_id === "string") { const key = typeof path === "string" ? "vercelPath" : "projectId"; const value = typeof path === "string" ? path : resource_id; returnTo = addQueryParam(returnTo, key, value as string); } if (!code) { return res.status(400).send("No code provided"); } try { const authenticateResponse = await workos.userManagement.authenticateWithCode({ clientId: process.env.WORKOS_CLIENT_ID || "", code, session: { sealSession: true, cookiePassword: process.env.WORKOS_COOKIE_PASSWORD, }, }); const { sealedSession } = authenticateResponse; // Store the session in a cookie const secure = // We only use secure cookies in production because development environments might use HTTP // (most browsers tolerate secure cookies on localhost, but not Safari) process.env.NODE_ENV === "production" ? " Secure;" : ""; res.setHeader( "Set-Cookie", `wos-session=${sealedSession}; Path=/; HttpOnly;${secure} SameSite=Lax; Max-Age=${60 * 60 * 24 * 14}`, ); // Use the information in `user` for further business logic. // Redirect the user to the homepage res.redirect(returnTo); } catch (error: any) { if ( error.status === 403 && error.rawData?.code === "email_verification_required" ) { res.redirect( `${process.env.WORKOS_LOGIN_URL}/email-verification?` + `email=${error.rawData.email}&` + `pending_authentication_token=${error.rawData?.pending_authentication_token}&` + `state=${state}&` + `redirect_uri=${state || "/"}`, ); return; } captureException(error); // TODO: Figure out what to do here. // res.redirect( // `/login?error=${error?.rawData?.error_description || error.message}`, // ); } } function addQueryParam(url: string, key: string, value: string) { const symbol = url.includes("?") ? "&" : "?"; return `${url}${symbol}${key}=${value}`; }

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/get-convex/convex-backend'

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