Skip to main content
Glama

list_fulfillment_orders

View fulfillment orders for a Shopify order, revealing per-location line item quantities, locations, and destinations to identify which items to fulfill.

Instructions

List the fulfillment orders attached to a Shopify order. A fulfillment order groups line items by the location that will ship them — a single order can have multiple fulfillment orders if items split across warehouses. Each one tracks per-line remaining quantity (totalQuantity minus what's already shipped/cancelled). Returns the assigned location, destination address, and line-item progress for each. This is the primary read tool you'll call before create_fulfillment to figure out which fulfillmentOrderLineItem IDs and quantities to mark as shipped.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
orderIdYesOrder GID to list fulfillment orders for (e.g. gid://shopify/Order/123).

Implementation Reference

  • Tool registration via server.tool() — registers 'list_fulfillment_orders' on the McpServer with its schema and handler callback.
    server.tool(
      "list_fulfillment_orders",
      "List the fulfillment orders attached to a Shopify order. A fulfillment order groups line items by the location that will ship them — a single order can have multiple fulfillment orders if items split across warehouses. Each one tracks per-line remaining quantity (totalQuantity minus what's already shipped/cancelled). Returns the assigned location, destination address, and line-item progress for each. This is the primary read tool you'll call before create_fulfillment to figure out which fulfillmentOrderLineItem IDs and quantities to mark as shipped.",
      listFulfillmentOrdersSchema,
      async (args) => {
        const data = await client.graphql<{
          order:
            | {
                id: string;
                name: string;
                fulfillmentOrders: {
                  edges: Array<{ node: FulfillmentOrderNode }>;
                };
              }
            | null;
        }>(LIST_FULFILLMENT_ORDERS_QUERY, { orderId: args.orderId });
        if (!data.order) {
          return {
            content: [
              { type: "text" as const, text: `Order not found: ${args.orderId}` },
            ],
          };
        }
        const fos = data.order.fulfillmentOrders.edges;
        if (fos.length === 0) {
          return {
            content: [
              {
                type: "text" as const,
                text: `Order ${data.order.name} has no fulfillment orders.`,
              },
            ],
          };
        }
        const lines: string[] = [
          `Order ${data.order.name} has ${fos.length} fulfillment order(s):`,
        ];
        for (const { node } of fos) {
          lines.push(...summarizeFulfillmentOrder(node));
        }
        return {
          content: [{ type: "text" as const, text: lines.join("\n") }],
        };
      },
    );
  • Handler function (async callback) that executes the tool logic: queries Shopify GraphQL API for fulfillment orders of a given orderId, processes the response, and returns formatted text content.
    async (args) => {
      const data = await client.graphql<{
        order:
          | {
              id: string;
              name: string;
              fulfillmentOrders: {
                edges: Array<{ node: FulfillmentOrderNode }>;
              };
            }
          | null;
      }>(LIST_FULFILLMENT_ORDERS_QUERY, { orderId: args.orderId });
      if (!data.order) {
        return {
          content: [
            { type: "text" as const, text: `Order not found: ${args.orderId}` },
          ],
        };
      }
      const fos = data.order.fulfillmentOrders.edges;
      if (fos.length === 0) {
        return {
          content: [
            {
              type: "text" as const,
              text: `Order ${data.order.name} has no fulfillment orders.`,
            },
          ],
        };
      }
      const lines: string[] = [
        `Order ${data.order.name} has ${fos.length} fulfillment order(s):`,
      ];
      for (const { node } of fos) {
        lines.push(...summarizeFulfillmentOrder(node));
      }
      return {
        content: [{ type: "text" as const, text: lines.join("\n") }],
      };
    },
  • Input schema (Zod) for the tool — defines 'orderId' as a required string described as the order GID.
    const listFulfillmentOrdersSchema = {
      orderId: z
        .string()
        .describe("Order GID to list fulfillment orders for (e.g. gid://shopify/Order/123)."),
    };
  • GraphQL query string LIST_FULFILLMENT_ORDERS_QUERY used by the handler to fetch fulfillment orders from Shopify.
    const LIST_FULFILLMENT_ORDERS_QUERY = /* GraphQL */ `
      query ListFulfillmentOrders($orderId: ID!) {
        order(id: $orderId) {
          id
          name
          fulfillmentOrders(first: 50) {
            edges {
              node {
                id
                status
                requestStatus
                assignedLocation { name location { id } }
                destination { address1 city countryCode zip }
                lineItems(first: 50) {
                  edges {
                    node {
                      id
                      totalQuantity
                      remainingQuantity
                      lineItem { id title sku }
                    }
                  }
                  pageInfo { hasNextPage }
                }
                createdAt
              }
            }
          }
        }
      }
    `;
  • Helper function summarizeFulfillmentOrder used to format a FulfillmentOrderNode into human-readable text lines for the response.
    function summarizeFulfillmentOrder(fo: FulfillmentOrderNode): string[] {
      const lines: string[] = [
        `  ${fo.id} [${fo.status}/${fo.requestStatus}] at ${fo.assignedLocation.name}`,
      ];
      if (fo.destination) {
        const d = fo.destination;
        lines.push(
          `    ship to: ${[d.address1, d.city, d.zip, d.countryCode].filter(Boolean).join(", ") || "(no address)"}`,
        );
      }
      for (const edge of fo.lineItems.edges) {
        const li = edge.node;
        lines.push(
          `    - ${li.lineItem.title}${li.lineItem.sku ? ` (SKU ${li.lineItem.sku})` : ""} — ${li.remainingQuantity}/${li.totalQuantity} remaining — ${li.id}`,
        );
      }
      if (fo.lineItems.pageInfo.hasNextPage) {
        lines.push("    (more line items available)");
      }
      return lines;
    }
  • src/server.ts:65-65 (registration)
    Top-level registration call: registerFulfillmentTools(s, shopify) invoked in buildContext() to wire all fulfillment tools onto the server.
    registerFulfillmentTools(s, shopify);
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Even without annotations, the description discloses key behaviors: multiple fulfillment orders can exist per order, remaining quantity calculation, and returned fields (location, destination, line-item progress).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is detailed yet concise, front-loading the primary action and providing necessary context in a structured manner without unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with one parameter and no output schema, the description adequately explains the purpose, usage flow, and return values, making it complete for the AI agent to select and invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema has 100% coverage with a clear description and example for orderId. The description adds some context but does not significantly enhance parameter understanding beyond what the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists fulfillment orders for a Shopify order, explains what fulfillment orders are, and distinguishes it from related tools like create_fulfillment and get_fulfillment_order.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly positions this as the primary read tool before create_fulfillment, providing clear context for when to use it, though it does not explicitly state when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

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/miller-joe/shopify-mcp'

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