Skip to main content
Glama

Square Model Context Protocol Server

by ampcome-mcps
server.ts13.1 kB
#!/usr/bin/env node import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; import express from "express"; import cors from 'cors'; import crypto from 'crypto'; import { Server } from "http" import { typeMap } from './utils/type-map.js'; import { ApiMethodInfo, ApiParameter } from './api-types.js'; import escapeHtml from 'escape-html'; import { ApplePayMethods, ApplePayHandlers } from './services/applepay.js'; import { BankAccountsMethods, BankAccountsHandlers } from './services/bankaccounts.js'; import { BookingCustomAttributesMethods, BookingCustomAttributesHandlers } from './services/bookingcustomattributes.js'; import { BookingsMethods, BookingsHandlers } from './services/bookings.js'; import { CardsMethods, CardsHandlers } from './services/cards.js'; import { CashDrawersMethods, CashDrawersHandlers } from './services/cashdrawers.js'; import { CatalogMethods, CatalogHandlers } from './services/catalog.js'; import { CheckoutMethods, CheckoutHandlers } from './services/checkout.js'; import { CustomerCustomAttributesMethods, CustomerCustomAttributesHandlers } from './services/customercustomattributes.js'; import { CustomerGroupsMethods, CustomerGroupsHandlers } from './services/customergroups.js'; import { CustomerSegmentsMethods, CustomerSegmentsHandlers } from './services/customersegments.js'; import { CustomersMethods, CustomersHandlers } from './services/customers.js'; import { DevicesMethods, DevicesHandlers } from './services/devices.js'; import { DisputesMethods, DisputesHandlers } from './services/disputes.js'; import { EventsMethods, EventsHandlers } from './services/events.js'; import { GiftCardActivitiesMethods, GiftCardActivitiesHandlers } from './services/giftcardactivities.js'; import { GiftCardsMethods, GiftCardsHandlers } from './services/giftcards.js'; import { InventoryMethods, InventoryHandlers } from './services/inventory.js'; import { InvoicesMethods, InvoicesHandlers } from './services/invoices.js'; import { LaborMethods, LaborHandlers } from './services/labor.js'; import { LocationCustomAttributesMethods, LocationCustomAttributesHandlers } from './services/locationcustomattributes.js'; import { LocationsMethods, LocationsHandlers } from './services/locations.js'; import { LoyaltyMethods, LoyaltyHandlers } from './services/loyalty.js'; import { MerchantCustomAttributesMethods, MerchantCustomAttributesHandlers } from './services/merchantcustomattributes.js'; import { MerchantsMethods, MerchantsHandlers } from './services/merchants.js'; import { OAuthMethods, OAuthHandlers } from './services/oauth.js'; import { OrderCustomAttributesMethods, OrderCustomAttributesHandlers } from './services/ordercustomattributes.js'; import { OrdersMethods, OrdersHandlers } from './services/orders.js'; import { PaymentsMethods, PaymentsHandlers } from './services/payments.js'; import { PayoutsMethods, PayoutsHandlers } from './services/payouts.js'; import { RefundsMethods, RefundsHandlers } from './services/refunds.js'; import { SitesMethods, SitesHandlers } from './services/sites.js'; import { SnippetsMethods, SnippetsHandlers } from './services/snippets.js'; import { SubscriptionsMethods, SubscriptionsHandlers } from './services/subscriptions.js'; import { TeamMethods, TeamHandlers } from './services/team.js'; import { TerminalMethods, TerminalHandlers } from './services/terminal.js'; import { VendorsMethods, VendorsHandlers } from './services/vendors.js'; import { WebhookSubscriptionsMethods, WebhookSubscriptionsHandlers } from './services/webhooksubscriptions.js'; // Create MCP server const server = new McpServer( { name: "square-mcp", version: "1.0.0" } ); // Target-specific code /** * PUBLIC API * * This MCP server is designed for public use with the Square API. * It provides a standard interface for accessing Square services * through the Model Context Protocol. * * For questions or support, visit the Square Developer Forum: * https://developer.squareup.com/forums */ const accessToken: string | undefined = process.env.ACCESS_TOKEN; async function getAccessToken(): Promise<string> { return accessToken || ''; } export function setBaseUrl() { let baseUrl = "https://connect.squareup.com"; if (process.env.SANDBOX == "true" && process.env.PRODUCTION == "true") { throw new Error("Both SANDBOX and PRODUCTION env vars are true"); } if (process.env.SANDBOX == "true") { baseUrl = "https://connect.squareupsandbox.com" } return baseUrl } setBaseUrl() // Define types for service maps type ServiceMethods = { [key: string]: { [key: string]: ApiMethodInfo } }; type ServiceHandlers = { [key: string]: { [key: string]: (accessToken: string, args: Record<string, unknown>) => Promise<unknown> } }; // Create a mapping of service methods and handlers export const serviceMethodsMap: ServiceMethods = { "ApplePay": ApplePayMethods, "BankAccounts": BankAccountsMethods, "BookingCustomAttributes": BookingCustomAttributesMethods, "Bookings": BookingsMethods, "Cards": CardsMethods, "CashDrawers": CashDrawersMethods, "Catalog": CatalogMethods, "Checkout": CheckoutMethods, "CustomerCustomAttributes": CustomerCustomAttributesMethods, "CustomerGroups": CustomerGroupsMethods, "CustomerSegments": CustomerSegmentsMethods, "Customers": CustomersMethods, "Devices": DevicesMethods, "Disputes": DisputesMethods, "Events": EventsMethods, "GiftCardActivities": GiftCardActivitiesMethods, "GiftCards": GiftCardsMethods, "Inventory": InventoryMethods, "Invoices": InvoicesMethods, "Labor": LaborMethods, "LocationCustomAttributes": LocationCustomAttributesMethods, "Locations": LocationsMethods, "Loyalty": LoyaltyMethods, "MerchantCustomAttributes": MerchantCustomAttributesMethods, "Merchants": MerchantsMethods, "OAuth": OAuthMethods, "OrderCustomAttributes": OrderCustomAttributesMethods, "Orders": OrdersMethods, "Payments": PaymentsMethods, "Payouts": PayoutsMethods, "Refunds": RefundsMethods, "Sites": SitesMethods, "Snippets": SnippetsMethods, "Subscriptions": SubscriptionsMethods, "Team": TeamMethods, "Terminal": TerminalMethods, "Vendors": VendorsMethods, "WebhookSubscriptions": WebhookSubscriptionsMethods }; export const serviceHandlersMap: ServiceHandlers = { "ApplePay": ApplePayHandlers, "BankAccounts": BankAccountsHandlers, "BookingCustomAttributes": BookingCustomAttributesHandlers, "Bookings": BookingsHandlers, "Cards": CardsHandlers, "CashDrawers": CashDrawersHandlers, "Catalog": CatalogHandlers, "Checkout": CheckoutHandlers, "CustomerCustomAttributes": CustomerCustomAttributesHandlers, "CustomerGroups": CustomerGroupsHandlers, "CustomerSegments": CustomerSegmentsHandlers, "Customers": CustomersHandlers, "Devices": DevicesHandlers, "Disputes": DisputesHandlers, "Events": EventsHandlers, "GiftCardActivities": GiftCardActivitiesHandlers, "GiftCards": GiftCardsHandlers, "Inventory": InventoryHandlers, "Invoices": InvoicesHandlers, "Labor": LaborHandlers, "LocationCustomAttributes": LocationCustomAttributesHandlers, "Locations": LocationsHandlers, "Loyalty": LoyaltyHandlers, "MerchantCustomAttributes": MerchantCustomAttributesHandlers, "Merchants": MerchantsHandlers, "OAuth": OAuthHandlers, "OrderCustomAttributes": OrderCustomAttributesHandlers, "Orders": OrdersHandlers, "Payments": PaymentsHandlers, "Payouts": PayoutsHandlers, "Refunds": RefundsHandlers, "Sites": SitesHandlers, "Snippets": SnippetsHandlers, "Subscriptions": SubscriptionsHandlers, "Team": TeamHandlers, "Terminal": TerminalHandlers, "Vendors": VendorsHandlers, "WebhookSubscriptions": WebhookSubscriptionsHandlers }; // Register unified Square API tool server.tool( "make_api_request", `Unified tool for all Square API operations. Be sure to get types before calling. Available services: ${Object.keys(serviceMethodsMap).map(name => name.toLowerCase()).join(", ")}.`, { service: z.string().describe("The Square API service category (e.g., 'catalog', 'payments')"), method: z.string().describe("The API method to call (e.g., 'list', 'create')"), request: z.object({}).passthrough().optional().describe("The request object for the API call.") }, async (params) => { try { const { service, method, request } = params; const serviceName = service.charAt(0).toUpperCase() + service.slice(1); const methods = serviceMethodsMap[serviceName]; if (!methods) { throw new Error(`Invalid service: ${service}. Available services: ${JSON.stringify(Object.keys(serviceMethodsMap), null, 2)}`); } const handlers = serviceHandlersMap[serviceName]; if (!methods[method]) { throw new Error(`Invalid method ${method} for service ${service}. Available methods: ${JSON.stringify(Object.keys(methods), null, 2)}`); } // Support read-only mode if desired const methodInfo = methods[method]; if (process.env.DISALLOW_WRITES == "true" && methodInfo?.isWrite) { throw new Error(`Write operations are not allowed in this environment. Please set DISALLOW_WRITES to false to enable write operations. Attempted operation: ${service}.${method}`); } const handler = handlers[method]; if (!handler) { throw new Error(`No handler found for ${service}.${method}`); } const token = await getAccessToken(); const result = await handler(token, request || {}); return { content: [{ type: "text", text: result as string }] }; } catch (err: any) { return { content: [{ type: "text", text: JSON.stringify({ error: err.message, details: err.errors || err.stack }, null, 2) }], isError: true }; } }); // Register get_request_type tool server.tool( "get_type_info", "Get type information for a Square API method. You must call this before calling the make_api_request tool.", { service: z.string().describe("The Square API service category (e.g., 'catalog', 'payments')"), method: z.string().describe("The API method to call (e.g., 'list', 'create')") }, async (params) => { try { const { service, method } = params; const serviceName = service.charAt(0).toUpperCase() + service.slice(1); const methods = serviceMethodsMap[serviceName]; if (!methods) { throw new Error(`Invalid service: ${service}. Available services: ${JSON.stringify(Object.keys(serviceMethodsMap), null, 2)}`); } if (!methods[method]) { throw new Error(`Invalid method ${method} for service ${service}. Available methods: ${JSON.stringify(Object.keys(methods), null, 2)}`); } const methodInfo = methods[method]; const requestTypeName = methodInfo.requestType; const typeInfo = typeMap[requestTypeName]; if (!typeInfo) { throw new Error(`Type information not found for ${requestTypeName}`); } return { content: [{ type: "text", text: JSON.stringify(typeInfo, null, 2) }] }; } catch (err: any) { return { content: [{ type: "text", text: JSON.stringify({ error: err.message, details: err.errors || err.stack }, null, 2) }], isError: true }; } } ); // register service info tool server.tool( "get_service_info", "Get information about a Square API service. Call me before trying to get type info", { service: z.string().describe("The Square API service category (e.g., 'catalog', 'payments')") }, async (params) => { try { const { service } = params; const serviceName = service.charAt(0).toUpperCase() + service.slice(1); const methods = serviceMethodsMap[serviceName]; if (!methods) { throw new Error(`Invalid service: ${service}. Available services: ${JSON.stringify(Object.keys(serviceMethodsMap), null, 2)}`); } // Create a map of method names to their descriptions const methodInfo = Object.entries(methods).reduce((acc, [methodName, info]) => { acc[methodName] = { description: info.description }; return acc; }, {} as Record<string, { description: string }>); return { content: [{ type: "text", text: JSON.stringify(methodInfo, null, 2) }] }; } catch (err: any) { return { content: [{ type: "text", text: JSON.stringify({ error: err.message, details: err.errors || err.stack }, null, 2) }], isError: true }; } } ); export async function startServer() { // Connect to the transport and start listening await server.connect(new StdioServerTransport()); }

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/ampcome-mcps/square-mcp'

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