list_draft_orders
Retrieve draft orders (uncompleted carts/quotes) sorted by most recently updated. Filter by status, customer, tag, or update time to find specific drafts.
Instructions
List draft orders (carts/quotes that haven't yet been completed into real orders), most recently updated first. Returns each draft's name (e.g. 'D1023'), status (OPEN/COMPLETED/INVOICE_SENT), total price, customer name, and whether it's already been converted to an order. Supports Shopify's draft-order query syntax for filtering by status, customer, tag, or update time. Cursor-paginated.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| first | No | Page size (1-100). | |
| query | No | Shopify draft order query syntax. Examples: 'status:OPEN' (not yet completed), 'status:COMPLETED', 'customer_id:1234567890', 'tag:wholesale', 'updated_at:>=2026-01-01'. | |
| after | No | Cursor from the previous page's pageInfo. Omit on the first call. |
Implementation Reference
- src/tools/draft_orders.ts:292-321 (registration)The registerDraftOrderTools function registers all draft order tools including 'list_draft_orders' on the McpServer via server.tool() at line 296.
export function registerDraftOrderTools( server: McpServer, client: ShopifyClient, ): void { server.tool( "list_draft_orders", "List draft orders (carts/quotes that haven't yet been completed into real orders), most recently updated first. Returns each draft's name (e.g. 'D1023'), status (OPEN/COMPLETED/INVOICE_SENT), total price, customer name, and whether it's already been converted to an order. Supports Shopify's draft-order query syntax for filtering by status, customer, tag, or update time. Cursor-paginated.", listDraftOrdersSchema, async (args) => { const data = await client.graphql<{ draftOrders: Connection<DraftOrder>; }>(LIST_DRAFT_ORDERS_QUERY, { first: args.first, after: args.after, query: args.query, }); const lines = [ `Found ${data.draftOrders.edges.length} draft order(s):`, ...data.draftOrders.edges.map(({ node }) => { const total = `${node.totalPriceSet.shopMoney.amount} ${node.totalPriceSet.shopMoney.currencyCode}`; const customer = node.customer?.displayName ?? "(no customer)"; const completed = node.order ? ` → order ${node.order.name}` : ""; return ` ${node.name} [${node.status}] ${total} — ${customer}${completed} — ${node.id}`; }), ]; return { content: [{ type: "text" as const, text: lines.join("\n") }] }; }, ); - src/tools/draft_orders.ts:300-321 (handler)The async handler for list_draft_orders executes the GraphQL query, formats the results into a text summary listing each draft order's name, status, total price, customer, and whether it was converted to an order.
async (args) => { const data = await client.graphql<{ draftOrders: Connection<DraftOrder>; }>(LIST_DRAFT_ORDERS_QUERY, { first: args.first, after: args.after, query: args.query, }); const lines = [ `Found ${data.draftOrders.edges.length} draft order(s):`, ...data.draftOrders.edges.map(({ node }) => { const total = `${node.totalPriceSet.shopMoney.amount} ${node.totalPriceSet.shopMoney.currencyCode}`; const customer = node.customer?.displayName ?? "(no customer)"; const completed = node.order ? ` → order ${node.order.name}` : ""; return ` ${node.name} [${node.status}] ${total} — ${customer}${completed} — ${node.id}`; }), ]; return { content: [{ type: "text" as const, text: lines.join("\n") }] }; }, ); - src/tools/draft_orders.ts:161-179 (schema)Input schema for list_draft_orders: first (page size, 1-100, default 20), query (Shopify draft order query syntax string), after (cursor for pagination).
const listDraftOrdersSchema = { first: z .number() .int() .min(1) .max(100) .default(20) .describe("Page size (1-100)."), query: z .string() .optional() .describe( "Shopify draft order query syntax. Examples: 'status:OPEN' (not yet completed), 'status:COMPLETED', 'customer_id:1234567890', 'tag:wholesale', 'updated_at:>=2026-01-01'.", ), after: z .string() .optional() .describe("Cursor from the previous page's pageInfo. Omit on the first call."), }; - src/tools/draft_orders.ts:33-53 (handler)The GraphQL query used by list_draft_orders to fetch draft orders sorted by UPDATED_AT descending, with pagination via first/after/query parameters.
const LIST_DRAFT_ORDERS_QUERY = /* GraphQL */ ` query ListDraftOrders($first: Int!, $after: String, $query: String) { draftOrders(first: $first, after: $after, query: $query, sortKey: UPDATED_AT, reverse: true) { edges { cursor node { id name status totalPriceSet { shopMoney { amount currencyCode } } customer { id displayName email } createdAt updatedAt completedAt order { id name } } } pageInfo { hasNextPage hasPreviousPage startCursor endCursor } } } `; - src/server.ts:56-62 (helper)Registration call: registerDraftOrderTools(s, shopify) is invoked inside buildContext() to wire the draft order tools into the MCP server.
const s = new McpServer({ name: "shopify-mcp", version: "0.1.0" }); registerProductTools(s, shopify); registerOrderTools(s, shopify); registerInventoryTools(s, shopify); registerCustomerTools(s, shopify); registerMetafieldTools(s, shopify); registerDraftOrderTools(s, shopify);