list_orders
Retrieve shop orders ordered by creation date, newest first. Filter by financial status, fulfillment status, date range, tags, and more. Returns key details and pagination cursors for subsequent calls.
Instructions
List orders in the store, newest first by creation date. Returns each order's name (e.g. '#1042'), total price (in shop currency), financial status (paid/pending/refunded), fulfillment status (fulfilled/unfulfilled/partial), and timestamp. Supports Shopify's order query syntax for filtering by status, date range, customer, tags, and more. Cursor-paginated; the last line shows the next cursor when more pages exist. Use this to find order GIDs before calling get_order or list_fulfillment_orders.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| first | No | Page size (1-100). | |
| query | No | Shopify order query syntax. Common filters: 'financial_status:paid' (paid/pending/refunded/voided), 'fulfillment_status:unfulfilled' (unfulfilled/fulfilled/partial), 'status:open' (open/closed/cancelled), 'created_at:>=2026-01-01', 'tag:wholesale', 'name:#1001'. Combine with AND/OR/NOT. | |
| after | No | Cursor from a prior page's pageInfo for pagination. Omit on the first call. |
Implementation Reference
- src/tools/orders.ts:327-348 (handler)Handler function for the 'list_orders' tool. Executes a GraphQL query against the Shopify Admin API to list orders with pagination and filtering, then formats the results as text.
server.tool( "list_orders", "List orders in the store, newest first by creation date. Returns each order's name (e.g. '#1042'), total price (in shop currency), financial status (paid/pending/refunded), fulfillment status (fulfilled/unfulfilled/partial), and timestamp. Supports Shopify's order query syntax for filtering by status, date range, customer, tags, and more. Cursor-paginated; the last line shows the next cursor when more pages exist. Use this to find order GIDs before calling get_order or list_fulfillment_orders.", listOrdersSchema, async (args) => { const data = await client.graphql<{ orders: Connection<Order> }>( LIST_ORDERS_QUERY, { first: args.first, query: args.query, after: args.after }, ); const lines = [ `Found ${data.orders.edges.length} order(s):`, ...data.orders.edges.map(({ node }) => { const amount = node.totalPriceSet.shopMoney; return ` ${node.name} — ${amount.amount} ${amount.currencyCode} — ${node.displayFinancialStatus ?? "?"}/${node.displayFulfillmentStatus ?? "?"} — ${node.createdAt}`; }), data.orders.pageInfo.hasNextPage ? `next cursor: ${data.orders.edges[data.orders.edges.length - 1]?.cursor}` : "(end of results)", ]; return { content: [{ type: "text" as const, text: lines.join("\n") }] }; }, ); - src/tools/orders.ts:110-130 (schema)Input schema for list_orders: 'first' (page size, 1-100, default 20), optional 'query' (Shopify filter syntax), optional 'after' (pagination cursor).
const listOrdersSchema = { first: z .number() .int() .min(1) .max(100) .default(20) .describe("Page size (1-100)."), query: z .string() .optional() .describe( "Shopify order query syntax. Common filters: 'financial_status:paid' (paid/pending/refunded/voided), 'fulfillment_status:unfulfilled' (unfulfilled/fulfilled/partial), 'status:open' (open/closed/cancelled), 'created_at:>=2026-01-01', 'tag:wholesale', 'name:#1001'. Combine with AND/OR/NOT.", ), after: z .string() .optional() .describe( "Cursor from a prior page's pageInfo for pagination. Omit on the first call.", ), }; - src/tools/orders.ts:327-348 (registration)Registration of 'list_orders' on the MCP server via server.tool() in the registerOrderTools function.
server.tool( "list_orders", "List orders in the store, newest first by creation date. Returns each order's name (e.g. '#1042'), total price (in shop currency), financial status (paid/pending/refunded), fulfillment status (fulfilled/unfulfilled/partial), and timestamp. Supports Shopify's order query syntax for filtering by status, date range, customer, tags, and more. Cursor-paginated; the last line shows the next cursor when more pages exist. Use this to find order GIDs before calling get_order or list_fulfillment_orders.", listOrdersSchema, async (args) => { const data = await client.graphql<{ orders: Connection<Order> }>( LIST_ORDERS_QUERY, { first: args.first, query: args.query, after: args.after }, ); const lines = [ `Found ${data.orders.edges.length} order(s):`, ...data.orders.edges.map(({ node }) => { const amount = node.totalPriceSet.shopMoney; return ` ${node.name} — ${amount.amount} ${amount.currencyCode} — ${node.displayFinancialStatus ?? "?"}/${node.displayFulfillmentStatus ?? "?"} — ${node.createdAt}`; }), data.orders.pageInfo.hasNextPage ? `next cursor: ${data.orders.edges[data.orders.edges.length - 1]?.cursor}` : "(end of results)", ]; return { content: [{ type: "text" as const, text: lines.join("\n") }] }; }, ); - src/server.ts:58-58 (registration)Top-level registration call from server.ts that invokes registerOrderTools, which registers list_orders and other order tools.
registerOrderTools(s, shopify); - src/tools/orders.ts:8-26 (helper)GraphQL query used by list_orders to fetch orders, sorted by creation date descending.
const LIST_ORDERS_QUERY = /* GraphQL */ ` query ListOrders($first: Int!, $after: String, $query: String) { orders(first: $first, after: $after, query: $query, sortKey: CREATED_AT, reverse: true) { edges { cursor node { id name email displayFinancialStatus displayFulfillmentStatus totalPriceSet { shopMoney { amount currencyCode } } createdAt } } pageInfo { hasNextPage hasPreviousPage startCursor endCursor } } } `;