Skip to main content
Glama

Convex MCP server

Official
by get-convex
users.ts1.77 kB
import { internalMutation, query, QueryCtx } from "./_generated/server"; import { UserJSON } from "@clerk/backend"; import { v, Validator } from "convex/values"; export const current = query({ args: {}, handler: async (ctx) => { return await getCurrentUser(ctx); }, }); export const upsertFromClerk = internalMutation({ args: { data: v.any() as Validator<UserJSON> }, // no runtime validation, trust Clerk async handler(ctx, { data }) { const userAttributes = { name: `${data.first_name} ${data.last_name}`, externalId: data.id, }; const user = await userByExternalId(ctx, data.id); if (user === null) { await ctx.db.insert("users", userAttributes); } else { await ctx.db.patch(user._id, userAttributes); } }, }); export const deleteFromClerk = internalMutation({ args: { clerkUserId: v.string() }, async handler(ctx, { clerkUserId }) { const user = await userByExternalId(ctx, clerkUserId); if (user !== null) { await ctx.db.delete(user._id); } else { console.warn( `Can't delete user, there is none for Clerk user ID: ${clerkUserId}`, ); } }, }); export async function getCurrentUserOrThrow(ctx: QueryCtx) { const userRecord = await getCurrentUser(ctx); if (!userRecord) throw new Error("Can't get current user"); return userRecord; } export async function getCurrentUser(ctx: QueryCtx) { const identity = await ctx.auth.getUserIdentity(); if (identity === null) { return null; } return await userByExternalId(ctx, identity.subject); } async function userByExternalId(ctx: QueryCtx, externalId: string) { return await ctx.db .query("users") .withIndex("byExternalId", (q) => q.eq("externalId", externalId)) .unique(); }

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