Skip to main content
Glama

Convex MCP server

Official
by get-convex
adversarial.ts11.1 kB
// This file is doing all kinds of wonky things so just turn off eslint /* eslint-disable */ import { api } from "./_generated/api"; import { Id } from "./_generated/dataModel"; import { action, mutation, query } from "./_generated/server"; export const simpleLoop = query(() => { while (1) {} }); export const slow = query(() => { for (let i = 0; i < 120000; i++) { crypto.randomUUID(); } }); export const populate = mutation(async ({ db }) => { for (let i = 0; i < 16; i++) { await db.insert("test", { counter: i }); } }); export const dbLoop = query(async ({ db }) => { let _numRows = 0; while (1) { for await (const _row of db.query("test")) { _numRows += 1; } } }); export const consoleLoop = query(() => { for (let i = 0; i < 258; i++) { console.log("hello there"); } }); export const consoleLoopTimes = query((_ctx, { times }: { times: number }) => { for (let i = 0; i < times; i++) { console.log("are we there yet"); } }); export const consoleLoopFromSubfunction = query(async (ctx) => { await ctx.runQuery(api.adversarial.consoleLoopTimes, { times: 200 }); console.log("we get there when we get there"); await ctx.runQuery(api.adversarial.consoleLoopTimes, { times: 100 }); console.log("we get there when we get there"); }); export const consoleLongLine = query(() => { // We truncate the output of console.log to 32768 bytes, test this // https://en.uncyclopedia.co/wiki/AAAAAAAAA! const longLine = "A".repeat(4511) + "!"; const args = Array(9).fill(longLine); console.log(...args); console.log(args.join(" ")); }); export const consoleLongLineCharBoundary = query(() => { // We truncate the output of console.log to 32768 bytes // Use a 4 byte emoji with different amounts of padding to ensure // that we respect character boundaries when truncating. const longLine = "🙃".repeat(8192); console.log("x" + longLine); console.log("xx" + longLine); console.log("xxx" + longLine); console.log("xxxx" + longLine); }); export const queryLeak = query(async ({ db }) => { while (1) { for await (const _row of db.query("test")) { break; } } }); export const queryATon = query(async ({ db }) => { for (let i = 0; i < 30000; i++) { for await (const _row of db.query("test")) { break; } } }); export const queryTooManyTimes = query(async ({ db }) => { for (let i = 0; i < 10000; i++) { await db .query("test") .withIndex("by_hello", (q) => q.eq("hello", i)) .collect(); } }); export const queryManyTimes = query(async ({ db }) => { for (let i = 0; i < 4000; i++) { await db .query("test") .withIndex("by_hello", (q) => q.eq("hello", i)) .collect(); } }); // Based on https://developer.mozilla.org/en-US/docs/Web/API export const tryUnsupportedAPIs = query(() => { // These should all exist, but be stubbed out when used (see tests lower down) let x: any = setTimeout; x = setInterval; if (typeof Worker !== "undefined") { throw new Error("Worker defined"); } if (typeof RTCPeerConnection !== "undefined") { throw new Error("RTCPeerConnection defined"); } if (typeof WebSocket !== "undefined") { throw new Error("WebSocket defined"); } if (typeof XMLHttpRequest !== "undefined") { throw new Error("XMLHttpRequest defined"); } if (typeof document !== "undefined") { throw new Error("document defined"); } if (typeof window !== "undefined") { throw new Error("window defined"); } if (typeof indexedDB !== "undefined") { throw new Error("indexedDB defined"); } if (typeof caches !== "undefined") { throw new Error("caches defined"); } if (typeof localStorage !== "undefined") { throw new Error("localStorage defined"); } if (typeof sessionStorage !== "undefined") { throw new Error("sessionStorage defined"); } if (typeof queueMicrotask !== "undefined") { throw new Error("queueMicrotask defined"); } if (typeof requestIdleCallback !== "undefined") { throw new Error("requestIdleCallback defined"); } if (typeof requestAnimationFrame !== "undefined") { throw new Error("requestAnimationFrame defined"); } if (typeof setImmediate !== "undefined") { throw new Error("setImmediate defined"); } if (typeof performance !== "undefined") { throw new Error("performance defined"); } }); export const setTimeoutThrows = query(() => { try { setTimeout(() => { console.log("timeout"); }, 1000); } catch (e) { // Error should not be catchable return "Caught an error"; } }); export const setIntervalThrows = query(() => { try { setInterval(() => { console.log("interval"); }, 1000); } catch (e) { // Error should not be catchable return "Caught an error"; } }); export const populateBigRead = mutation(async ({ db }) => { const ids = []; for (let i = 0; i < 4097; i++) { const id = await db.insert("test", { counter: i }); ids.push(id); } return ids; }); export const bigRead = query(async ({ db }, { ids }: { ids: Id<any>[] }) => { for (const id of ids) { await db.get(id); } }); export const readUntilError = query(async ({ db }) => { const documents = []; try { for await (const doc of db.query("test")) { documents.push(doc); } } catch (e: any) {} return documents; }); export const bigWrite = mutation( async ({ db }, { count }: { count: number }) => { const bytes = new ArrayBuffer(262144); const view = new BigInt64Array(bytes); view.fill(1017n); let ids = []; for (let i = 0; i < count; i++) { ids.push(await db.insert("test", { data: bytes })); } return ids; }, ); export const bigDocument = mutation(async (ctx) => { await ctx.db.insert("test", { data: "something small" }); let big = ""; for (let i = 0; i < 1000000; i++) { big += "A"; } const bigId = await ctx.db.insert("test", { data: big }); await ctx.db.insert("test", { data: "something else small" }); return bigId; }); export const nestedDocument = mutation(async (ctx) => { await ctx.db.insert("test", { data: [[[]]] }); let big = ""; for (let i = 0; i < 1000000; i++) { big += "A"; } const nestedId = await ctx.db.insert("test", { data: [[[[[[[[[[[[[[]]]]]]]]]]]]]], }); await ctx.db.insert("test", { data: [[[[[]]]]] }); return nestedId; }); export const oom = query(async ({ db }) => { let s = ""; for (let i = 0; i < 8340000; i++) { s += ("" + i)[0]; } return s.length; }); export const tooManyWrites = mutation(async ({ db }) => { for (let i = 0; i < 16002; i++) { await db.insert("test", { counter: i }); } }); export const manyWrites = mutation(async ({ db }) => { for (let i = 0; i < 15990; i++) { await db.insert("test", { counter: i }); } }); export const returnTooLarge = query(({ db }) => { return Array(9000).fill(1); }); export const iterateTwice = query(async ({ db }) => { const query = db.query("test").fullTableScan(); for await (const _ of query) { } for await (const _ of query) { } }); export const iterateConsumed = query(async ({ db }) => { const query = db.query("test").fullTableScan(); query.take(1); for await (const _ of query) { } }); // export const tryEval = mutation(async () => { // return eval("1 + 1"); // }); export const tryNewFunction = mutation(async () => { return new Function("return 3")(); }); declare const Convex: { syscall: (op: string, jsonArgs: string) => string; asyncSyscall: (op: string, jsonArgs: string) => Promise<string>; jsSyscall: (op: string, args: Record<string, any>) => any; }; export const deleteConvexGlobal = query(async ({ db }) => { // @ts-expect-error -- error TS2790: The operand of a 'delete' operator must be optional. delete Convex.syscall; return await db.query("test").collect(); }); export const throwSystemError = query(async () => { Convex.syscall("throwSystemError", "{}"); }); export const throwSystemErrorAfterAwait = query(async () => { await Promise.resolve(null); Convex.syscall("throwSystemError", "{}"); }); export const throwUncatchableDeveloperError = query(async () => { try { Convex.jsSyscall("idonotexistandicannotlie", {}); } catch (e) { console.log("caught you", e); } }); export const slowSyscall = query(async () => { return JSON.parse(await Convex.asyncSyscall("slowSyscall", "{}")); }); export const reallySlowSyscall = query(async () => { return JSON.parse(await Convex.asyncSyscall("reallySlowSyscall", "{}")); }); export const atomicsWait = query(async () => { const buffer = new SharedArrayBuffer(4); const array = new Int32Array(buffer); Atomics.wait(array, 0, 1); }); export const bigMemoryUsage = query(async () => { // javascript strings are utf16 so 2 bytes per character // max is 64MB but there's a buffer that brings it up to 100MB. // note we can't use `new ArrayBuffer` because ArrayBuffers don't count // as used memory in v8. let ten = "10bts"; let s = ""; for (let i = 0; i < 2 * 1000 * 1000; i++) { s += ten; } return s.length; }); export const useNotImplementedBuiltin = query(async () => { try { const url = new URL("https://baz.qat:8000/qux/quux?foo=bar&baz=12#qat"); // This should throw an uncatchable "Not implemented" error url.password = "foo"; } catch (e) { return "Caught an error!"; } }); export const insertWithCreationTime = mutation(async ({ db }) => { await db.insert("table", { _creationTime: 123, }); }); export const insertWithId = mutation(async ({ db }) => { await db.insert("table", { _id: 123, }); }); export const queryResultSized = query(async (_, { size }: { size: number }) => { let x = new ArrayBuffer(size); return x; }); export const mutationResultSized = mutation( async (_, { size }: { size: number }) => { let x = new ArrayBuffer(size); return x; }, ); export const actionResultSized = action( async (_, { size }: { size: number }) => { let x = new ArrayBuffer(size); return x; }, ); export const allocateArrayBuffers = query( async ( _, { size, count, retain }: { size: number; count: number; retain: number }, ) => { const r = []; for (let i = 0; i < count; i++) { r.push(new ArrayBuffer(size)); if (r.length > retain) r.shift(); } return r.map((buf) => buf.byteLength); }, ); export const simpleQuery = query(async ({ db }) => { return await db.query("test").collect(); }); export const invokeFunctionDirectly = query(async (ctx) => { await (simpleQuery as any)(ctx, {}); }); export const recursiveSubfunction = query( async (ctx, { depth }: { depth: number }): Promise<number> => { if (depth > 0) { return ( 1 + (await ctx.runQuery(api.adversarial.recursiveSubfunction, { depth: depth - 1, })) ); } else { return 0; } }, ); export const paginateTooManyItems = query(async ({ db }) => { await db .query("test") .paginate({ cursor: null, numItems: Number.MAX_SAFE_INTEGER }); });

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