Skip to main content
Glama

Shopify Storefront MCP Server

shopify-client.ts3.11 kB
import { createStorefrontApiClient } from "@shopify/storefront-api-client"; import { getStoreConfig, getEnabledStoreConfigs, type StoreConfig } from "../config/stores.js"; // Client cache to avoid recreating clients const clientCache = new Map<string, ReturnType<typeof createStorefrontApiClient>>(); function getStorefrontClient(storeId: string) { if (clientCache.has(storeId)) { return clientCache.get(storeId)!; } const config = getStoreConfig(storeId); if (!config) { throw new Error(`Store configuration not found for storeId: ${storeId}`); } if (!config.enabled) { throw new Error(`Store is disabled: ${storeId}`); } if (!config.domain || !config.storefrontAccessToken) { throw new Error(`Incomplete configuration for store: ${storeId} (${config.name})`); } const client = createStorefrontApiClient({ storeDomain: config.domain, apiVersion: config.apiVersion, publicAccessToken: config.storefrontAccessToken, }); clientCache.set(storeId, client); return client; } export async function requestStorefrontApi({ storeId, query, variables, }: { storeId: string; query: string; variables?: Record<string, unknown>; }) { const store = getStoreConfig(storeId); if (!store) { throw new Error(`Store configuration not found for storeId: ${storeId}`); } const client = getStorefrontClient(storeId); console.info( `[${new Date().toISOString()}] INFO: Running query on store ${storeId} (${store.name}): ${query} with variables: ${JSON.stringify( variables, null, 2, )}`, ); const { data, errors } = await client.request(query, { variables, }); return { data, errors }; } export function listAvailableStores(): string[] { return getEnabledStoreConfigs().map(store => { return `${store.id}: ${store.name} (${store.domain})`; }); } // --- Define Content Block Types --- // Only TextContentBlock needed export type TextContentBlock = { type: "text"; text: string; }; // Define the overall result structure export type McpToolResult = { content: TextContentBlock[] }; // --- Helper Functions --- function textResult(text: string): McpToolResult { return { content: [{ type: "text", text }] }; } export function handleStorefrontApiResult(proxyResult: { data: unknown; errors?: unknown; }) { if (!proxyResult.errors) { return jsonResult(proxyResult.data); } const errors = Array.isArray(proxyResult.errors) ? proxyResult.errors : [proxyResult.errors]; // Log the full error details console.error( `[${new Date().toISOString()}] ERROR: GraphQL Errors:`, JSON.stringify(errors, null, 2), ); const message = (errors[0] as { message?: string })?.message || "Tool execution failed via proxy."; throw new Error(message); } function jsonResult(data: unknown): McpToolResult { try { const jsonString = JSON.stringify(data, null, 2); return { content: [{ type: "text", text: `\`\`\`json\n${jsonString}\n\`\`\`` }], }; } catch (e) { console.error( `[${new Date().toISOString()}] ERROR: Failed to stringify result data:`, e, ); return textResult("Error: Could not serialize result data."); } }

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/volticscontent/axios_mcp'

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