update_customer
Update an existing customer's profile information including email, name, phone, tags, and note. Partial updates allowed—only changed fields are submitted. Tags fully replace existing set; use dedicated mutations for additive tag changes.
Instructions
Update an existing customer's profile fields — email, name, phone, tags, internal note. Only provide fields you want changed; omitted fields stay as-is. Tags is a full replacement (use add_tags / remove_tags for additive/subtractive changes). Email and phone changes still need to satisfy the per-store uniqueness constraint. To change addresses, use Shopify's address-specific mutations (not yet exposed by this server). To change marketing consent, the dedicated customerEmailMarketingConsentUpdate mutation is preferred.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Customer GID or numeric ID. Get one from list_customers. | |
| No | New email. Must remain unique. | ||
| firstName | No | ||
| lastName | No | ||
| phone | No | New phone in E.164 format. | |
| tags | No | New tag set. REPLACES all existing tags. Use add_tags / remove_tags for additive/subtractive changes that preserve other tags. | |
| note | No | New internal staff note. Replaces prior note. |
Implementation Reference
- src/tools/customers.ts:227-260 (handler)The actual handler function for the 'update_customer' tool. It builds the input from args, calls the Shopify GraphQL mutation CUSTOMER_UPDATE_MUTATION, handles user errors, and returns the updated customer info.
async (args) => { const input: Record<string, unknown> = { id: toGid(args.id, "Customer") }; if (args.email !== undefined) input.email = args.email; if (args.firstName !== undefined) input.firstName = args.firstName; if (args.lastName !== undefined) input.lastName = args.lastName; if (args.phone !== undefined) input.phone = args.phone; if (args.tags !== undefined) input.tags = args.tags; if (args.note !== undefined) input.note = args.note; const data = await client.graphql<{ customerUpdate: { customer: Customer | null; userErrors: ShopifyUserError[]; }; }>(CUSTOMER_UPDATE_MUTATION, { input }); throwIfUserErrors(data.customerUpdate.userErrors, "customerUpdate"); const c = data.customerUpdate.customer; if (!c) { return { content: [ { type: "text" as const, text: "customerUpdate returned no customer." }, ], }; } return { content: [ { type: "text" as const, text: `Updated customer ${c.displayName ?? "(no name)"} <${c.email ?? "(no email)"}> — ${c.id}`, }, ], }; }, ); - src/tools/customers.ts:134-149 (schema)Zod schema for update_customer input validation. Defines fields: id (required), email, firstName, lastName, phone, tags, note (all optional).
const updateCustomerSchema = { id: z .string() .describe("Customer GID or numeric ID. Get one from list_customers."), email: z.string().email().optional().describe("New email. Must remain unique."), firstName: z.string().optional(), lastName: z.string().optional(), phone: z.string().optional().describe("New phone in E.164 format."), tags: z .array(z.string()) .optional() .describe( "New tag set. REPLACES all existing tags. Use add_tags / remove_tags for additive/subtractive changes that preserve other tags.", ), note: z.string().optional().describe("New internal staff note. Replaces prior note."), }; - src/tools/customers.ts:223-260 (registration)Registration of the 'update_customer' tool via server.tool(), with its description, schema, and handler function.
server.tool( "update_customer", "Update an existing customer's profile fields — email, name, phone, tags, internal note. Only provide fields you want changed; omitted fields stay as-is. Tags is a full replacement (use add_tags / remove_tags for additive/subtractive changes). Email and phone changes still need to satisfy the per-store uniqueness constraint. To change addresses, use Shopify's address-specific mutations (not yet exposed by this server). To change marketing consent, the dedicated customerEmailMarketingConsentUpdate mutation is preferred.", updateCustomerSchema, async (args) => { const input: Record<string, unknown> = { id: toGid(args.id, "Customer") }; if (args.email !== undefined) input.email = args.email; if (args.firstName !== undefined) input.firstName = args.firstName; if (args.lastName !== undefined) input.lastName = args.lastName; if (args.phone !== undefined) input.phone = args.phone; if (args.tags !== undefined) input.tags = args.tags; if (args.note !== undefined) input.note = args.note; const data = await client.graphql<{ customerUpdate: { customer: Customer | null; userErrors: ShopifyUserError[]; }; }>(CUSTOMER_UPDATE_MUTATION, { input }); throwIfUserErrors(data.customerUpdate.userErrors, "customerUpdate"); const c = data.customerUpdate.customer; if (!c) { return { content: [ { type: "text" as const, text: "customerUpdate returned no customer." }, ], }; } return { content: [ { type: "text" as const, text: `Updated customer ${c.displayName ?? "(no name)"} <${c.email ?? "(no email)"}> — ${c.id}`, }, ], }; }, ); - src/tools/customers.ts:44-57 (handler)The GraphQL mutation used by the update_customer handler to call Shopify's customerUpdate.
const CUSTOMER_UPDATE_MUTATION = /* GraphQL */ ` mutation CustomerUpdate($input: CustomerInput!) { customerUpdate(input: $input) { customer { id displayName email firstName lastName } userErrors { field message } } } `; - src/tools/products.ts:333-336 (helper)The toGid helper function used by the handler to convert a numeric or partial ID to a full Shopify GID (e.g., 'gid://shopify/Customer/123').
export function toGid(id: string, type: string): string { if (id.startsWith("gid://")) return id; return `gid://shopify/${type}/${id}`; }