Skip to content

Sapo MCP by usefulapi

io.usefulapi/sapousefulapi.iostreamable-httpv1.1.0Scanned

Read Sapo store products, orders, customers and stock levels; edit order notes and stock.

20 tools: 2 can delete or cancel things, 1 do something that can't be undone and 17 only read.

Tools: 2 delete, 1 irreversible, 0 write, 17 read.
  • Reads private data · 2
  • Reads text others write · 20
  • Can send data out · 0
  • 1 finding

Anlyon alternative

3 of these tools change something. Run those as governed actions.

Declare what an action changes, and Anlyon puts it under a shared limit, binds every approval to the exact request, and grades the outcome. It works on any HTTPS API you can describe as an action.

Anlyon does not run, proxy or govern this MCP server. A tool your own code calls directly is not routed through Anlyon and is not governed by it.

Import an OpenAPI spec →

Tools

Grouped by what each tool does, most consequential first. Open one for its reasons and full description; descriptions are the publisher's own words.

20 tools

Deletes or cancels 2Claude Code: deny
  • sapo_set_inventory_levelWRITE: set the physical stock (on_hand) of one inventory item at one location to an exact quantity, with a reason.Reads text others writeNo findings

    Why it is in this group

    • The name "sapo_set_inventory_level" says "set": a word for a change.
    • The server marks it destructive (destructiveHint: true).

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    WRITE: set the physical stock (on_hand) of one inventory item at one location to an exact quantity, with a reason. This OVERWRITES the current number and is recorded as a stock adjustment: read the level first (sapo_list_inventory_levels). PUT /admin/inventory_levels/set.json.

    Annotations the server declares

    • title: Set stock quantity
    • readOnlyHint: false
    • destructiveHint: true
    • idempotentHint: true
    • openWorldHint: true
  • sapo_update_orderWRITE: set the note and/or the tags of an order (Sapo only lets an order's items and quantities stay fixed after creation).Reads text others writeNo findings

    Why it is in this group

    • The name "sapo_update_order" says "update": a word for a change.
    • The server marks it destructive (destructiveHint: true).

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    WRITE: set the note and/or the tags of an order (Sapo only lets an order's items and quantities stay fixed after creation). The value REPLACES the existing note or tags: read the order first to keep what is there. PUT /admin/orders/{id}.json.

    Annotations the server declares

    • title: Update order note or tags
    • readOnlyHint: false
    • destructiveHint: true
    • idempotentHint: true
    • openWorldHint: true
Can't be undone 1Claude Code: ask
  • sapo_list_order_transactionsThe payment transactions recorded on one order.Reads text others write1 finding

    Why it is in this group

    • The name "sapo_list_order_transactions" says "list": a word for reading.
    • The description's first verb is "payment": a word that usually means money moves, which cannot be taken back.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.

    Findings

    • Warn

      The server marks "sapo_list_order_transactions" read-only (readOnlyHint: true), and its own name, description or input give the class "irreversible".

      Matched text

      annotations: {"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}; The name "sapo_list_order_transactions" says "list": a word for reading.

      What this check looks for
    Description, as the server wrote it
    The payment transactions recorded on one order. GET /admin/orders/{order_id}/transactions.json.

    Annotations the server declares

    • title: List order transactions
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
Only reads 17Show 17 read-only tools
  • sapo_count_customersTotal number of customers.Reads text others writeNo findings

    Why it is in this group

    • The name "sapo_count_customers" says "count": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    Total number of customers. GET /admin/customers/count.json.

    Annotations the server declares

    • title: Count customers
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • sapo_count_ordersNumber of orders matching the filters.Reads text others writeNo findings

    Why it is in this group

    • The name "sapo_count_orders" says "count": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    Number of orders matching the filters. GET /admin/orders/count.json.

    Annotations the server declares

    • title: Count orders
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • sapo_count_productsNumber of products matching the filters.Reads text others writeNo findings

    Why it is in this group

    • The name "sapo_count_products" says "count": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    Number of products matching the filters. GET /admin/products/count.json.

    Annotations the server declares

    • title: Count products
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • sapo_get_customerOne customer by id.Reads text others writeNo findings

    Why it is in this group

    • The name "sapo_get_customer" says "get": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    One customer by id. GET /admin/customers/{id}.json.

    Annotations the server declares

    • title: Get customer
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • sapo_get_orderOne order by id with line items, addresses, discounts, payment and shipping.Reads text others writeNo findings

    Why it is in this group

    • The name "sapo_get_order" says "get": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    One order by id with line items, addresses, discounts, payment and shipping. GET /admin/orders/{id}.json.

    Annotations the server declares

    • title: Get order
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • sapo_get_productOne product by id, with variants and images.Reads text others writeNo findings

    Why it is in this group

    • The name "sapo_get_product" says "get": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    One product by id, with variants and images. GET /admin/products/{id}.json.

    Annotations the server declares

    • title: Get product
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • sapo_get_product_variantOne product variant by id.Reads text others writeNo findings

    Why it is in this group

    • The name "sapo_get_product_variant" says "get": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    One product variant by id. GET /admin/variants/{id}.json.

    Annotations the server declares

    • title: Get product variant
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • sapo_get_storeThe Sapo store this login belongs to: name, domain, currency, timezone, plan and other settings.Reads text others writeNo findings

    Why it is in this group

    • The name "sapo_get_store" says "get": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    The Sapo store this login belongs to: name, domain, currency, timezone, plan and other settings. GET /admin/store.json.

    Annotations the server declares

    • title: Get store
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • sapo_list_custom_collectionsList manual product collections (danh mục thủ công).Reads text others writeNo findings

    Why it is in this group

    • The name "sapo_list_custom_collections" says "list": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    List manual product collections (danh mục thủ công). Paged. GET /admin/custom_collections.json.

    Annotations the server declares

    • title: List collections
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • sapo_list_customersList customers with contact details, addresses, order count and total spent.Reads private dataReads text others writeNo findings

    Why it is in this group

    • The name "sapo_list_customers" says "list": a word for reading.

    What it can reach

    • private-dataThe description's first sentence says "list" and "contact": it reads contacts.
    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    List customers with contact details, addresses, order count and total spent. Paged. GET /admin/customers.json.

    Annotations the server declares

    • title: List customers
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • sapo_list_inventory_itemsList inventory items (one per variant) by SKU/barcode search, variant or product ids.Reads text others writeNo findings

    Why it is in this group

    • The name "sapo_list_inventory_items" says "list": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    List inventory items (one per variant) by SKU/barcode search, variant or product ids. The id is what stock levels use as inventory_item_id. Paged. GET /admin/inventory_items.json.

    Annotations the server declares

    • title: List inventory items
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • sapo_list_inventory_levelsStock per item and location: on_hand, available, committed, incoming, reserved.Reads text others writeNo findings

    Why it is in this group

    • The name "sapo_list_inventory_levels" says "list": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    Stock per item and location: on_hand, available, committed, incoming, reserved. Filter by inventory item or location ids, or by a minimum/maximum available quantity. Sapo documents no paging for this list, so narrow it with ids. GET /admin/inventory_levels.json.

    Annotations the server declares

    • title: List inventory levels
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • sapo_list_locationsList branches, stores and warehouses (id, name, address, whether they track stock).Reads private dataReads text others writeNo findings

    Why it is in this group

    • The name "sapo_list_locations" says "list": a word for reading.

    What it can reach

    • private-dataThe description's first sentence says "list" and "branch": it reads repositories.
    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    List branches, stores and warehouses (id, name, address, whether they track stock). Use the ids for stock levels. Paged. GET /admin/locations.json.

    Annotations the server declares

    • title: List locations
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • sapo_list_ordersList orders with line items, customer, totals, payment and fulfillment status.Reads text others writeNo findings

    Why it is in this group

    • The name "sapo_list_orders" says "list": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    List orders with line items, customer, totals, payment and fulfillment status. Filter by status, tag, customer or dates. Paged: pass next_page as page. GET /admin/orders.json.

    Annotations the server declares

    • title: List orders
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • sapo_list_price_rulesList discount price rules (percentage, fixed amount, fixed price) with validity dates and usage counts.Reads text others writeNo findings

    Why it is in this group

    • The name "sapo_list_price_rules" says "list": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    List discount price rules (percentage, fixed amount, fixed price) with validity dates and usage counts. Paged. GET /admin/price_rules.json.

    Annotations the server declares

    • title: List price rules
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • sapo_list_product_variantsThe variants (size, color, SKU, barcode, price) of one product.Reads text others writeNo findings

    Why it is in this group

    • The name "sapo_list_product_variants" says "list": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    The variants (size, color, SKU, barcode, price) of one product. Paged. GET /admin/products/{product_id}/variants.json.

    Annotations the server declares

    • title: List product variants
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • sapo_list_productsList products with their variants, prices, SKUs and images.Reads text others writeNo findings

    Why it is in this group

    • The name "sapo_list_products" says "list": a word for reading.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    List products with their variants, prices, SKUs and images. Filter by name, vendor, type, collection or created/modified dates. Paged: pass next_page as page. GET /admin/products.json.

    Annotations the server declares

    • title: List products
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true

This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.

Exfil surface

Which tools read private data, which read text someone else can write, and which can send data out. One of each is a path a prompt injection can use.

No private-data, untrusted-input, outbound path in this server alone: no tool is tagged outbound.

Reads private data2
Reads files, mail, messages, databases, secrets, calendars or repositories.
Can send data out0
Can carry data to people or systems: it sends, posts or publishes, or takes a recipient, channel or URL.

Other servers in the same agent add their own tools to these paths. Audit your whole setup to see them together.

Findings

Matches of fixed checks, with the text they matched.

1 warn
  • The server marks "sapo_list_order_transactions" read-only (readOnlyHint: true), and its own name, description or input give the class "irreversible".

    Matched text

    annotations: {"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}; The name "sapo_list_order_transactions" says "list": a word for reading.

    What this check looks for

History

Changes to its tool definitions and to its remote endpoint, newest first.

No change seen yet. Its tools are rescanned every day, and a remote endpoint is looked at once a week.

Install

Pinned to version 1.1.0. Values in angle brackets are yours to fill in.

claude mcp add --transport http sapo https://sapo.usefulapi.io/mcp
claude mcp add --transport http sapo https://sapo.usefulapi.io/mcp

Run in a terminal.

Claude Code permissions

Allow the reads, ask before a change or a way out, deny the deletes. Paste into .claude/settings.json.

.claude/settings.json
{
  "permissions": {
    "allow": [
      "mcp__sapo__sapo_get_store",
      "mcp__sapo__sapo_list_products",
      "mcp__sapo__sapo_count_products",
      "mcp__sapo__sapo_get_product",
      "mcp__sapo__sapo_list_product_variants",
      "mcp__sapo__sapo_get_product_variant",
      "mcp__sapo__sapo_list_custom_collections",
      "mcp__sapo__sapo_list_orders",
      "mcp__sapo__sapo_count_orders",
      "mcp__sapo__sapo_get_order",
      "mcp__sapo__sapo_list_customers",
      "mcp__sapo__sapo_count_customers",
      "mcp__sapo__sapo_get_customer",
      "mcp__sapo__sapo_list_locations",
      "mcp__sapo__sapo_list_inventory_items",
      "mcp__sapo__sapo_list_inventory_levels",
      "mcp__sapo__sapo_list_price_rules"
    ],
    "ask": [
      "mcp__sapo__sapo_list_order_transactions"
    ],
    "deny": [
      "mcp__sapo__sapo_update_order",
      "mcp__sapo__sapo_set_inventory_level"
    ]
  }
}

Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. A read that can send data out (it takes a URL, say) asks first too. It assumes the server is installed as sapo. Review it before you use it.

Capability tags behind 20 rules
  • mcp__sapo__sapo_get_store untrusted-input
  • mcp__sapo__sapo_list_products untrusted-input
  • mcp__sapo__sapo_count_products untrusted-input
  • mcp__sapo__sapo_get_product untrusted-input
  • mcp__sapo__sapo_list_product_variants untrusted-input
  • mcp__sapo__sapo_get_product_variant untrusted-input
  • mcp__sapo__sapo_list_custom_collections untrusted-input
  • mcp__sapo__sapo_list_orders untrusted-input
  • mcp__sapo__sapo_count_orders untrusted-input
  • mcp__sapo__sapo_get_order untrusted-input
  • mcp__sapo__sapo_list_order_transactions untrusted-input
  • mcp__sapo__sapo_list_customers private-data, untrusted-input
  • mcp__sapo__sapo_count_customers untrusted-input
  • mcp__sapo__sapo_get_customer untrusted-input
  • mcp__sapo__sapo_list_locations private-data, untrusted-input
  • mcp__sapo__sapo_list_inventory_items untrusted-input
  • mcp__sapo__sapo_list_inventory_levels untrusted-input
  • mcp__sapo__sapo_list_price_rules untrusted-input
  • mcp__sapo__sapo_update_order untrusted-input
  • mcp__sapo__sapo_set_inventory_level untrusted-input

Pin

Keep the decision: fail CI when the tools change, follow every change, or show a badge.

Pin in CI

Fail a build when the tools you reviewed are not the tools the server serves today.

curl -s "https://anlyon.dev/api/v1/servers/io.usefulapi/sapo/verify?hash=52e3c306764556c551b0e683f359b2a5d6119fd8c447135a4032e7d805e3ccc7" | jq -e '.changed == false'

Pinned hash 52e3c3067645, from Oct 25, 2026, 20:23 UTC.

Watch

Get told when its tools change: a new tool, a new description, a new class.

https://anlyon.dev/servers/io.usefulapi/sapo/changes.xml

An Atom feed. Works in any feed reader or Slack's RSS app.

Badge

anlyon.dev badge for io.usefulapi/sapo
[![anlyon.dev](https://anlyon.dev/badge/io.usefulapi/sapo.svg)](https://anlyon.dev/servers/io.usefulapi/sapo)

Source: MCP Registry · repository. Synced Oct 25, 2026, 21:18 UTC.