Skip to main content
Glama

Convex MCP server

Official
by get-convex
simple_client.test.ts3.2 kB
import { test, expect } from "vitest"; import { withInMemoryWebSocket } from "./sync/client_node_test_helpers.js"; import { DefaultFunctionArgs, getFunctionName, makeFunctionReference, } from "../server/index.js"; // This Node.js build sets up the WebSocket dependency automatically. import { ConvexClient } from "./simple_client-node.js"; const apiQueryFunc = makeFunctionReference< "query", DefaultFunctionArgs, string >("jeans style"); const apiMutationFunc = makeFunctionReference< "mutation", DefaultFunctionArgs, string >("jeans style"); test("Subscriptions are deduplicated", async () => { // The actual implementation of this dedupliation logic is in BaseConvexClient. await withInMemoryWebSocket(async ({ address, receive }) => { const client = new ConvexClient(address, { unsavedChangesWarning: false, }); expect((await receive()).type).toEqual("Connect"); expect((await receive()).type).toEqual("ModifyQuerySet"); const { unsubscribe: unsub1 } = client.onUpdate( apiQueryFunc, {}, () => null, ); expect((await receive()).type).toEqual("ModifyQuerySet"); // The second subscribe to the same query should not send another query request. const { unsubscribe: unsub2 } = client.onUpdate( apiQueryFunc, {}, () => null, ); unsub1(); void client.mutation(apiMutationFunc, {}); // Receiving a mutation next means no third or fourth ModifyQuerySet. expect((await receive()).type).toEqual("Mutation"); // Unsubscribing the second time should trigger the unsubscribe. unsub2(); expect((await receive()).type).toEqual("ModifyQuerySet"); await client.close(); }); }); test("Optimistic updates are applied", async () => { await withInMemoryWebSocket(async ({ address, receive }) => { const client = new ConvexClient(address, { unsavedChangesWarning: false, }); expect((await receive()).type).toEqual("Connect"); expect((await receive()).type).toEqual("ModifyQuerySet"); let updateCount = 0; let updateValue = ""; let optimisticUpdateRan = 0; // Subscribe to a query, which *does not* immediately trigger an update. const { unsubscribe } = client.onUpdate(apiQueryFunc, {}, (value) => { updateCount++; updateValue = value; }); expect((await receive()).type).toEqual("ModifyQuerySet"); expect(client.client.localQueryResult(getFunctionName(apiQueryFunc))).toBe( undefined, ); void client.mutation( apiMutationFunc, {}, { optimisticUpdate: (localStore) => { optimisticUpdateRan++; localStore.setQuery(apiQueryFunc, {}, "optimisticValue"); }, }, ); expect((await receive()).type).toEqual("Mutation"); // The mutation also updates the local cache expect(optimisticUpdateRan).toBe(1); expect(updateCount).toBe(1); expect(updateValue).toBe("optimisticValue"); expect(client.client.localQueryResult(getFunctionName(apiQueryFunc))).toBe( "optimisticValue", ); unsubscribe(); expect((await receive()).type).toEqual("ModifyQuerySet"); await client.close(); }); });

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