update-customer
Modify customer details in Shopify, including contact information, tags, notes, tax status, and custom fields, using the customer ID.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Shopify customer ID, numeric excluding gid prefix | |
| firstName | No | ||
| lastName | No | ||
| No | |||
| phone | No | ||
| tags | No | ||
| note | No | ||
| taxExempt | No | ||
| metafields | No |
Implementation Reference
- src/tools/updateCustomer.ts:45-144 (handler)The main execute function that implements the update-customer tool logic. It constructs a GraphQL mutation to update customer data, handles the conversion of numeric ID to GID format, validates input, handles errors, and returns the updated customer information with properly formatted metafields.execute: async (input: UpdateCustomerInput) => { try { const { id, acceptsMarketing, ...customerFields } = input; // Convert numeric ID to GID format const customerGid = `gid://shopify/Customer/${id}`; // Log a warning if acceptsMarketing was provided if (acceptsMarketing !== undefined) { console.warn( "The acceptsMarketing field is not supported by the Shopify API and will be ignored" ); } const query = gql` mutation customerUpdate($input: CustomerInput!) { customerUpdate(input: $input) { customer { id firstName lastName email phone tags note taxExempt metafields(first: 10) { edges { node { id namespace key value } } } } userErrors { field message } } } `; const variables = { input: { id: customerGid, ...customerFields } }; const data = (await shopifyClient.request(query, variables)) as { customerUpdate: { customer: any; userErrors: Array<{ field: string; message: string; }>; }; }; // If there are user errors, throw an error if (data.customerUpdate.userErrors.length > 0) { throw new Error( `Failed to update customer: ${data.customerUpdate.userErrors .map((e) => `${e.field}: ${e.message}`) .join(", ")}` ); } // Format and return the updated customer const customer = data.customerUpdate.customer; // Format metafields if they exist const metafields = customer.metafields?.edges.map((edge: any) => edge.node) || []; return { customer: { id: customer.id, firstName: customer.firstName, lastName: customer.lastName, email: customer.email, phone: customer.phone, tags: customer.tags, note: customer.note, taxExempt: customer.taxExempt, metafields } }; } catch (error) { console.error("Error updating customer:", error); throw new Error( `Failed to update customer: ${ error instanceof Error ? error.message : String(error) }` ); } }
- src/tools/updateCustomer.ts:6-28 (schema)Zod schema definition for update-customer input validation. Defines all optional fields including firstName, lastName, email, phone, tags, note, acceptsMarketing (deprecated), taxExempt, and metafields with proper type constraints.const UpdateCustomerInputSchema = z.object({ id: z.string().regex(/^\d+$/, "Customer ID must be numeric"), firstName: z.string().optional(), lastName: z.string().optional(), email: z.string().email().optional(), phone: z.string().optional(), tags: z.array(z.string()).optional(), note: z.string().optional(), // acceptsMarketing field is deprecated as it's not supported in the API acceptsMarketing: z.boolean().optional(), taxExempt: z.boolean().optional(), metafields: z .array( z.object({ id: z.string().optional(), namespace: z.string().optional(), key: z.string().optional(), value: z.string(), type: z.string().optional() }) ) .optional() });
- src/index.ts:219-252 (registration)MCP server registration of the update-customer tool. Registers the tool with its input schema and creates a handler that calls updateCustomer.execute() and returns the result as JSON text content.// Add the updateCustomer tool server.tool( "update-customer", { id: z .string() .regex(/^\d+$/, "Customer ID must be numeric") .describe("Shopify customer ID, numeric excluding gid prefix"), firstName: z.string().optional(), lastName: z.string().optional(), email: z.string().email().optional(), phone: z.string().optional(), tags: z.array(z.string()).optional(), note: z.string().optional(), taxExempt: z.boolean().optional(), metafields: z .array( z.object({ id: z.string().optional(), namespace: z.string().optional(), key: z.string().optional(), value: z.string(), type: z.string().optional() }) ) .optional() }, async (args) => { const result = await updateCustomer.execute(args); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } );
- src/tools/updateCustomer.ts:35-145 (handler)Complete tool object definition including name, description, schema reference, initialize method for GraphQL client setup, and the execute handler containing all business logic.const updateCustomer = { name: "update-customer", description: "Update a customer's information", schema: UpdateCustomerInputSchema, // Add initialize method to set up the GraphQL client initialize(client: GraphQLClient) { shopifyClient = client; }, execute: async (input: UpdateCustomerInput) => { try { const { id, acceptsMarketing, ...customerFields } = input; // Convert numeric ID to GID format const customerGid = `gid://shopify/Customer/${id}`; // Log a warning if acceptsMarketing was provided if (acceptsMarketing !== undefined) { console.warn( "The acceptsMarketing field is not supported by the Shopify API and will be ignored" ); } const query = gql` mutation customerUpdate($input: CustomerInput!) { customerUpdate(input: $input) { customer { id firstName lastName email phone tags note taxExempt metafields(first: 10) { edges { node { id namespace key value } } } } userErrors { field message } } } `; const variables = { input: { id: customerGid, ...customerFields } }; const data = (await shopifyClient.request(query, variables)) as { customerUpdate: { customer: any; userErrors: Array<{ field: string; message: string; }>; }; }; // If there are user errors, throw an error if (data.customerUpdate.userErrors.length > 0) { throw new Error( `Failed to update customer: ${data.customerUpdate.userErrors .map((e) => `${e.field}: ${e.message}`) .join(", ")}` ); } // Format and return the updated customer const customer = data.customerUpdate.customer; // Format metafields if they exist const metafields = customer.metafields?.edges.map((edge: any) => edge.node) || []; return { customer: { id: customer.id, firstName: customer.firstName, lastName: customer.lastName, email: customer.email, phone: customer.phone, tags: customer.tags, note: customer.note, taxExempt: customer.taxExempt, metafields } }; } catch (error) { console.error("Error updating customer:", error); throw new Error( `Failed to update customer: ${ error instanceof Error ? error.message : String(error) }` ); } } };
- src/index.ts:70-70 (registration)Initialization of the updateCustomer tool with the Shopify GraphQL client, which is required before the tool can execute mutations.updateCustomer.initialize(shopifyClient);