Skip to main content
Glama

Convex MCP server

Official
by get-convex
dependentMiddlewareTemplate.ts2.81 kB
import { ObjectType, v } from "convex/values"; import { DatabaseReader } from "../_generated/server"; import { generateQueryWithMiddleware } from "./middlewareUtils"; import { Doc } from "../_generated/dataModel"; // ---------------------------------------------------------------------- // Two middlewares like in `middlewareTemplate.ts` type MyRequiredContextA = { db: DatabaseReader }; type TransformedContextA = { session: Doc<"sessions"> | null }; const myValidatorA = { sessionId: v.id("sessions") }; const myTransformA = async ( ctx: MyRequiredContextA, args: ObjectType<typeof myValidatorA>, ): Promise<TransformedContextA> => { const session = await ctx.db.get(args.sessionId); return { session }; }; // Middleware B depends on middleware A type MyRequiredContextB = { db: DatabaseReader; session: Doc<"sessions"> | null; }; type TransformedContextB = { experiments: Record<string, boolean> }; const myValidatorB = {}; const myTransformB = async ( ctx: MyRequiredContextB, _args: ObjectType<typeof myValidatorB>, ): Promise<TransformedContextB> => { const _sessionId = ctx.session?._id; const experiments = {}; // look up experiments in db according to session ID return { experiments }; }; // Manually merge them // Don't require session since it's provided for middleware B by middleware A type RequiredContextBoth = { db: DatabaseReader }; type TransformedContextBoth = TransformedContextA & TransformedContextB; const myValidatorBoth = { ...myValidatorA, ...myValidatorB }; const myTransformBoth = async ( ctx: RequiredContextBoth, args: ObjectType<typeof myValidatorBoth>, ): Promise<TransformedContextBoth> => { const ctxA = { ...ctx, ...(await myTransformA(ctx, args)), }; return { ...ctxA, ...(await myTransformB(ctxA, args)), }; }; // ---------------------------------------------------------------------- // ---------------------------------------------------------------------- // No need to modify these aside from renaming // Helper function to allow applying this transform to multiple types of `Context` // (e.g. QueryCtx, MutaitonCtx) const myTransformGeneric = async <Ctx extends Record<string, any>>( ctx: Ctx & RequiredContextBoth, args: ObjectType<typeof myValidatorBoth>, ): Promise< Omit<Ctx, keyof TransformedContextBoth> & TransformedContextBoth > => { return { ...ctx, ...(await myTransformBoth(ctx, args)) }; }; export const queryWithMyTransform = generateQueryWithMiddleware( myValidatorBoth, myTransformGeneric, ); // ---------------------------------------------------------------------- // Examples const _q = queryWithMyTransform({ args: { a: v.string() }, handler: async ({ db, experiments, session }, { a }) => { // Do stuff! console.log(experiments, db, a, session); }, });

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