Skip to main content
Glama

Crossmint Checkout MCP Server

Official
by Crossmint
index.ts6.52 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; import dotenv from "dotenv"; dotenv.config(); const isProduction = process.env.ENVIRONMENT === 'prod'; const CROSSMINT_API_BASE = isProduction ? "https://www.crossmint.com/api" : "https://staging.crossmint.com/api"; const CHAIN = isProduction ? 'ethereum' : 'ethereum-sepolia'; const TOKEN = 'credit'; const USER_AGENT = "crossmint-checkout/1.0"; // Create server instance const server = new McpServer({ name: "crossmint-checkout", version: "1.0.0", capabilities: { resources: {}, tools: {}, }, }); // Helper function for making Crossmint API requests async function makeCrossmintRequest( endpoint: string, method: string = "GET", body?: any ): Promise<any | null> { const headers = { "User-Agent": USER_AGENT, "Content-Type": "application/json", "X-API-KEY": process.env.CROSSMINT_API_KEY || "", }; try { const response = await fetch(`${CROSSMINT_API_BASE}/2022-06-09${endpoint}`, { method, headers, body: body ? JSON.stringify(body) : undefined, }); if (!response.ok) { try { const json = await response.json(); throw new Error(`HTTP error! status: ${json.message}, message: ${json.message}`); } catch (error) { throw new Error(`HTTP error! status: ${response.status}`); } } return await response.json(); } catch (error) { throw error; } } // Helper function to sign and submit transaction via Crossmint API async function createTransaction(serializedTx: string): Promise<string | null> { if (!process.env.CROSSMINT_API_KEY || !process.env.AGENT_WALLET_ADDRESS) { return null; } try { const response = await fetch( `${CROSSMINT_API_BASE}/2022-06-09/wallets/${process.env.AGENT_WALLET_ADDRESS}/transactions`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-KEY': process.env.CROSSMINT_API_KEY, }, body: JSON.stringify({ params: { calls:[{ transaction: serializedTx }], chain: CHAIN } }) } ); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); return data.status; } catch (error) { console.error("Error submitting transaction via Crossmint:", error); return null; } } // Register crossmint checkout tool to create orders server.tool( "create-order", "Create a new order for a product", { lineItems: z.array( z.object({ productLocator: z.string() .describe("The product locator. Ex: 'amazon:<amazon_product_url>', 'amazon:<asin>', 'shopify:<product-url>:<variant-id>'"), }) ).length(1).describe("Item to purchase") }, async ({ lineItems }) => { try { const envRecipient = { email: process.env.RECIPIENT_EMAIL, physicalAddress: { name: process.env.RECIPIENT_NAME, line1: process.env.RECIPIENT_ADDRESS_LINE1, line2: process.env.RECIPIENT_ADDRESS_LINE2 || '', city: process.env.RECIPIENT_CITY, state: process.env.RECIPIENT_STATE, postalCode: process.env.RECIPIENT_POSTAL_CODE, country: process.env.RECIPIENT_COUNTRY, } }; const orderData = { recipient: envRecipient, payment: { method: CHAIN, currency: TOKEN, payerAddress: process.env.AGENT_WALLET_ADDRESS, receiptEmail: process.env.RECIPIENT_EMAIL, }, lineItems, }; const response = await makeCrossmintRequest("/orders", "POST", orderData); const serializedTx = response.order.payment.preparation.serializedTransaction; const orderId = response.order.orderId; const status = await createTransaction(serializedTx); return { content: [ { type: "text", text: `Your request was successfully submitted! Order ID: ${orderId}. Order status: ${status}`, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Failed to process order: ${JSON.stringify(error, null, 2)}`, }, ], }; } } ); server.tool( "check-order", "Check the status of an existing order", { orderId: z.string().describe("The order ID to check"), }, async ({ orderId }) => { try { const response = await makeCrossmintRequest(`/orders/${orderId}`); return { content: [ { type: "text", text: `Status: \n - Order is ${JSON.stringify(response.phase, null, 2)} \n - Payment is ${JSON.stringify(response.lineItems[0].delivery.status, null, 2)}`, }, ], }; } catch (error) { return { content: [ { type: "text", text: "Failed to retrieve order status", }, ], }; } } ); // Get balance tool server.tool( "get-usd-balance", "Get the USD balance of the wallet", {}, async () => { try { const address = process.env.AGENT_WALLET_ADDRESS; const response = await fetch( `${CROSSMINT_API_BASE}/v1-alpha2/wallets/${address}/balances?tokens=${TOKEN}&chains=${CHAIN}`, { headers: { "X-API-KEY": process.env.CROSSMINT_API_KEY || "", }, } ); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); return { content: [ { type: "text", text: `USD Balance: ${JSON.stringify(data, null, 2)}`, }, ], }; } catch (error) { return { content: [ { type: "text", text: `Failed to get USD balance: ${JSON.stringify(error, null, 2)}`, }, ], }; } } ); async function main() { if (!process.env.CROSSMINT_API_KEY) { process.exit(1); } if (!process.env.AGENT_WALLET_ADDRESS) { process.exit(1); } const transport = new StdioServerTransport(); await server.connect(transport); } main().catch((error) => { console.error(error); process.exit(1); });

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/Crossmint/mcp-crossmint-checkout'

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