Zenfulfillment MCP by usefulapi

Read Zenfulfillment orders and stock; import or cancel orders and mark returns done.

Should I use this

Quality & Safety

A
Description quality
93%
Schema completeness
96%
Naming quality
73%
Poisoning risk
100%
Permission match
100%
Protocol compliance
100%

Findings (3)

  • LOWTool 'zenfulfillment_list_inventory_shipments' name length outside 3-30 rangein zenfulfillment_list_inventory_shipments
  • LOWTool 'zenfulfillment_get_inventory_shipment' name length outside 3-30 rangein zenfulfillment_get_inventory_shipment
  • LOWTool 'zenfulfillment_mark_return_done' name length outside 3-30 rangein zenfulfillment_mark_return_done

Based on automated analysis of tool definitions and protocol compliance.

Context Cost

~2,829Tokens (tool definitions)
~2.2 KBTypical response size
Significant attention impact (2.21% of 128k context)

This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.

Install

One-Click Install

Add this to your `claude_desktop_config.json` file:

{
  "mcpServers": {
    "zenfulfillment": {
      "url": "https://zenfulfillment.usefulapi.io/mcp"
    }
  }
}

Remote endpoints

https://zenfulfillment.usefulapi.io/mcpstreamable-http

What it can do

Tool inventory

Tools (9)

🟢 Read-only🟡 Write🔴 Delete⚪ Unknown
🟢zenfulfillment_list_orders(status, created_after, created_before, updated_after, updated_before, ...)

List or search the fulfillment orders of this Zenfulfillment account (warehouse pick/pack/ship), with status, order reference, shop order number, totals, shipping and billing address, the products ordered/shipped and shipments (tracking number, carrier). Filter by ONE status, created/updated time or free text. The export has one row per product line; rows are grouped into orders. Paging: pass next_page back as page; an empty page is the end. GET /orders/export.

Input Schema

{
  "type": "object",
  "properties": {
    "status": {
      "description": "Only orders in this status (one at a time).",
      "type": "string",
      "enum": [
        "UNKNOWN",
        "NOT_PAID",
        "INVALID_ADDRESS",
        "PENDING",
        "PROCESSING",
        "PICKED",
        "PACKING",
        "PACKED",
        "SHIPPED",
        "CANCELLED"
      ]
    },
    "created_after": {
      "description": "Only orders created at or after this time.",
      "type": "string"
    },
    "created_before": {
      "description": "Only orders created at or before this time.",
      "type": "string"
    },
    "updated_after": {
      "description": "Lower bound on the last update time (updatedAtMin).",
      "type": "string"
    },
    "updated_before": {
      "description": "Upper bound on the last update time (updatedAtMax).",
      "type": "string"
    },
    "query": {
      "description": "Free-text search: shipping street, city, country, zip, customer name, order number or ZF number.",
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "page": {
      "description": "Page number, from 1 (default 1). Use the previous reply's next_page.",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 100000
    },
    "per_page": {
      "description": "Results per page, 10-50 (default 25).",
      "type": "integer",
      "minimum": 10,
      "maximum": 50
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢zenfulfillment_get_order(reference)

One order by its EXTERNAL reference, i.e. the order number from the connected shop or from your own import (for example 332-11-5599), with addresses, products with quantities (ordered, shipped, returned, refunded) and shipments with tracking numbers. Not the ZF reference: use zenfulfillment_list_orders with query for that. GET /orders/external/{reference}.

Input Schema

{
  "type": "object",
  "properties": {
    "reference": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200,
      "description": "External order reference (the shop's order number)."
    }
  },
  "required": [
    "reference"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢zenfulfillment_list_stock(sku_contains, max_quantity, limit)

Stock on hand in the Zenfulfillment warehouse per SKU (sku, quantity_on_stock). Filter by SKU text and/or a maximum quantity to find low stock (then sorted lowest first). GET /products/export.

Input Schema

{
  "type": "object",
  "properties": {
    "sku_contains": {
      "description": "Only SKUs containing this text (case-insensitive).",
      "type": "string",
      "minLength": 1,
      "maxLength": 100
    },
    "max_quantity": {
      "description": "Only SKUs with at most this many units on stock (use for low-stock checks).",
      "type": "integer",
      "minimum": 0,
      "maximum": 1000000
    },
    "limit": {
      "description": "Most SKUs to return (default 200).",
      "type": "integer",
      "minimum": 1,
      "maximum": 1000
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢zenfulfillment_list_inventory_shipments(status, created_after, created_before, updated_after, updated_before, ...)

List inbound inventory shipments (goods you sent to the warehouse) with reference, SKU lines, announced quantity, quantity arrived and note. Filter by ONE status, created/updated time or free text (ZF number, tracking code, type). Rows are grouped per shipment. Paging as in list_orders. GET /inventory_shipments/export.

Input Schema

{
  "type": "object",
  "properties": {
    "status": {
      "description": "Only shipments in this status (one at a time).",
      "type": "string",
      "enum": [
        "PENDING",
        "CANCELLED",
        "STORED",
        "PARTIALLY_STORED",
        "PROCESSING",
        "RECEIVED"
      ]
    },
    "created_after": {
      "description": "Only shipments created at or after this time.",
      "type": "string"
    },
    "created_before": {
      "description": "Only shipments created at or before this time.",
      "type": "string"
    },
    "updated_after": {
      "description": "Lower bound on the last update time (updatedAtMin).",
      "type": "string"
    },
    "updated_before": {
      "description": "Upper bound on the last update time (updatedAtMax).",
      "type": "string"
    },
    "query": {
      "description": "Free-text search: ZF number, tracking code, type.",
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "page": {
      "description": "Page number, from 1 (default 1). Use the previous reply's next_page.",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 100000
    },
    "per_page": {
      "description": "Results per page, 10-50 (default 25).",
      "type": "integer",
      "minimum": 10,
      "maximum": 50
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢zenfulfillment_get_inventory_shipment(reference)

One inbound inventory shipment by its ZF reference (for example ZF01123700): SKU lines with announced and arrived quantities and the note. GET /inventory_shipments/export/{reference}/reference.

Input Schema

{
  "type": "object",
  "properties": {
    "reference": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "description": "Inventory shipment ZF reference, e.g. ZF01123700."
    }
  },
  "required": [
    "reference"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢zenfulfillment_list_returns(status, created_after, created_before, updated_after, updated_before, ...)

List returns processed by the warehouse (PROCESSED = received, DONE = marked refunded), with the return's `_id` (needed by zenfulfillment_mark_return_done), ZF reference, note, products with quantity, reason, condition and whether they were actually returned, and the original order. Filter by ONE status, time or free text. Paging as in list_orders. GET /returns/export.

Input Schema

{
  "type": "object",
  "properties": {
    "status": {
      "description": "Only returns in this status.",
      "type": "string",
      "enum": [
        "PROCESSED",
        "DONE"
      ]
    },
    "created_after": {
      "description": "Only returns created at or after this time.",
      "type": "string"
    },
    "created_before": {
      "description": "Only returns created at or before this time.",
      "type": "string"
    },
    "updated_after": {
      "description": "Lower bound on the last update time (updatedAtMin).",
      "type": "string"
    },
    "updated_before": {
      "description": "Upper bound on the last update time (updatedAtMax).",
      "type": "string"
    },
    "query": {
      "description": "Free-text search: street, city, country, zip, customer name, order number or ZF number.",
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "page": {
      "description": "Page number, from 1 (default 1). Use the previous reply's next_page.",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 100000
    },
    "per_page": {
      "description": "Results per page, 10-50 (default 25).",
      "type": "integer",
      "minimum": 10,
      "maximum": 50
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🔴zenfulfillment_import_order(reference, order_date, name, company, street, ...)

WRITE: send ONE order to the Zenfulfillment warehouse for picking, packing and shipping to the given address (fulfillment and shipping fees apply per the contract). The reference is your own order number: a reference that already exists UPDATES that order instead of creating a new one. Each item becomes one CSV row (Reference;Date;Name;Company;Street1;Street2;Zip Code;City;Region;Country;Email;Phone;SKU;Quantity). Use SKUs from zenfulfillment_list_stock. Check the address with the user first. In test mode nothing ships. POST /orders/import.

Input Schema

{
  "type": "object",
  "properties": {
    "reference": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64,
      "pattern": "^[^;\"\\r\\n\\t=+\\-@\\s][^;\"\\r\\n\\t]*$",
      "description": "Your own order reference/number (for example Bestellung1). An existing reference updates that order."
    },
    "order_date": {
      "description": "Order date, yyyy-mm-dd (default today, UTC).",
      "type": "string",
      "pattern": "^(\\d{4})-(\\d{2})-(\\d{2})$"
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "description": "Recipient name."
    },
    "company": {
      "description": "Recipient company.",
      "type": "string",
      "maxLength": 100
    },
    "street": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "description": "Street and house number."
    },
    "street2": {
      "description": "Address line 2 (c/o, floor...).",
      "type": "string",
      "maxLength": 100
    },
    "zip": {
      "type": "string",
      "minLength": 1,
      "maxLength": 20,
      "description": "Postal code."
    },
    "city": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "description": "City."
    },
    "region": {
      "description": "Region/state.",
      "type": "string",
      "maxLength": 100
    },
    "country": {
      "type": "string",
      "pattern": "^[A-Za-z]{2}$",
      "description": "2-letter ISO country code, e.g. DE."
    },
    "email": {
      "description": "Recipient email (carriers use it for tracking notices).",
      "type": "string",
      "maxLength": 200,
      "pattern": "^[A-Za-z0-9][^\\s@;\"<>]*@[^\\s@;\"<>]+\\.[^\\s@;\"<>]+$"
    },
    "phone": {
      "description": "Recipient phone number. A leading + is sent as 00 (international prefix) so spreadsheets never read it as a formula.",
      "type": "string",
      "maxLength": 30,
      "pattern": "^\\+?[0-9][0-9 ()/.-]{4,29}$"
    },
    "items": {
      "minItems": 1,
      "maxItems": 100,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "sku": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[^;\"\\r\\n\\t=+\\-@\\s][^;\"\\r\\n\\t]*$",
            "description": "SKU exactly as in the warehouse (see zenfulfillment_list_stock)."
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100000,
            "description": "Units."
          }
        },
        "required": [
          "sku",
          "quantity"
        ]
      },
      "description": "The products to ship."
    }
  },
  "required": [
    "reference",
    "name",
    "street",
    "zip",
    "city",
    "country",
    "items"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🔴zenfulfillment_cancel_orders(references)

WRITE, cannot be undone: cancel orders by reference (up to 50). Only orders that can still be cancelled (before the warehouse has packed or shipped them) are cancelled; the others come back in `errors`. Confirm the references with the user first. POST /orders/cancel.

Input Schema

{
  "type": "object",
  "properties": {
    "references": {
      "minItems": 1,
      "maxItems": 50,
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1,
        "maxLength": 64,
        "pattern": "^[^;\"\\r\\n\\t=+\\-@\\s][^;\"\\r\\n\\t]*$"
      },
      "description": "Order references to cancel (as in the Reference column, e.g. the ZF reference or your own order number)."
    }
  },
  "required": [
    "references"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🔴zenfulfillment_mark_return_done(return_id)

WRITE: set a return's status to DONE (refunded) in Zenfulfillment. Zenfulfillment only records the status; refund the customer in your shop yourself. Use the `_id` from zenfulfillment_list_returns (not the ZF reference). Cannot be set back through the API. POST /returns/{returnId}/done.

Input Schema

{
  "type": "object",
  "properties": {
    "return_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "description": "The return's `_id` from zenfulfillment_list_returns."
    }
  },
  "required": [
    "return_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}

Community

Rate this Server

Evidence

Recent observations

verifiedversion not recorded9 tools