# io.usefulapi/sortly (remote · sortly.usefulapi.io)

Search inventory items and folders, low-stock alerts, jobs and purchase orders, and update stock.

- Trust score: 77/100 (medium)
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-10-04

## Components

- remote · `sortly.usefulapi.io`: 77/100 (this document), [markdown](https://verifymcp.io/servers/io-usefulapi-sortly/sortly.md), [page](https://verifymcp.io/servers/io-usefulapi-sortly/sortly)

## Channel facts

- Endpoint: `https://sortly.usefulapi.io/mcp`
- Transports: `streamable-http`
- Auth: `none`
- Version: `1.0.0`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-10-04.

- **Endpoint Security**: 89/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation is enforced on tool calls, advertised via RFC 9728 protected-resource metadata. Discovery is public, which costs nothing: no tool can be invoked without a token.
  - HTTPS is enforced; there's no plaintext access path.
  - HSTS check failed: the Strict-Transport-Security header is absent.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
  - The authorisation server offers only Dynamic Client Registration (RFC 7591), which MCP 2026-07-28 deprecated in favour of Client ID Metadata Documents.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 73/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 2989 tokens (~149/item across 20 items; 20 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 13/100
  - Stability observed for 4 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 99% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 20 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 20 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 60/100
  - Spec-recency check failed: implements MCP spec 2025-06-18; the latest is 2026-07-28.

## Install

### How do I install the io.usefulapi/sortly MCP server?

io.usefulapi/sortly is a hosted endpoint at https://sortly.usefulapi.io/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add --transport http io-usefulapi-sortly 'https://sortly.usefulapi.io/mcp'
```

### Cursor

```json
{
  "mcpServers": {
    "io-usefulapi-sortly": {
      "url": "https://sortly.usefulapi.io/mcp"
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "io-usefulapi-sortly": {
      "type": "http",
      "url": "https://sortly.usefulapi.io/mcp"
    }
  }
}
```

### Codex

```toml
[mcp_servers.io-usefulapi-sortly]
url = "https://sortly.usefulapi.io/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "io-usefulapi-sortly": {
      "type": "remote",
      "url": "https://sortly.usefulapi.io/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add io-usefulapi-sortly --url 'https://sortly.usefulapi.io/mcp' --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  io-usefulapi-sortly:
    url: "https://sortly.usefulapi.io/mcp"
```

### Netclaw

```json
{
  "McpServers": {
    "io-usefulapi-sortly": {
      "Transport": "http",
      "Url": "https://sortly.usefulapi.io/mcp"
    }
  }
}
```

### Vellum

```bash
assistant mcp add io-usefulapi-sortly -t streamable-http -u 'https://sortly.usefulapi.io/mcp'
```

### Other

```json
{
  "mcpServers": {
    "io-usefulapi-sortly": {
      "type": "http",
      "url": "https://sortly.usefulapi.io/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-10-03 (score 77, +1)

No change was recorded against any check on this day. Stability & Change Management went from 7 to 10. That category is still filling its 30-day observation window: 2 days of observed history at the previous scan, 3 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-02 (score 76, 0)

- [functional] Server version: 1.3.0 → 1.5.1

### 2026-10-01 (score 76, +5)

- [security improvement] HTTPS: unverified → pass
- [functional improvement] Stability: unverified → 0.03
- [functional] Server version: 1.0.0 → 1.3.0

### 2026-09-30 (score 71, +53)

- [security improvement] Authorization: unverified → pass
- [security improvement] Injection markers: unverified → pass
- [security improvement] Transport: fail → pass
- [security] First check of Judged manipulation: pass
- [security] First check of Authorization: partial
- [functional regression] MCP protocol: unverified → fail
- [functional improvement] Tool coverage: unverified → 100
- [functional] First check of Schema quality: fail
- [functional] First check of Schema quality: excellent
- [functional] First check of Tool coverage: 99
- [functional] First check of Destructive annotations: pass
- [functional] First check of Schema quality: fail

### 2026-09-29 (score 18)

First indexed and scored.

## MCP tools (20)

### `sortly_list_items` (~160 tokens)

List items and folders

List items and folders, newest first. By default the root level; pass folder_id for a folder's direct contents, plus include_subfolders for everything nested under it. Paginated via meta.next_page_url / total_pages. Sortly: GET /api/v1/items.

Input parameters:

- `folder_id` (integer): Only the direct contents of this folder. Omit for the root level.
- `include` (array): Nested associations to embed: custom_attributes and/or photos.
- `include_subfolders` (boolean): With folder_id: also return everything nested beneath it. Default false.
- `page` (integer): Page number, starting at 1.
- `per_page` (integer): Page size, 1-1000 (default 10).

### `sortly_get_item` (~87 tokens)

Get one item or folder

Fetch a single item or folder by numeric id: quantity, min_quantity, price, tags, sid, barcodes, and optionally custom field values and photos. Sortly: GET /api/v1/items/{item_id}.

Input parameters:

- `include` (array): Nested associations to embed: custom_attributes and/or photos.
- `item_id` (integer, required): The item's or folder's numeric id.

### `sortly_search_items` (~191 tokens)

Search inventory

Search items and folders by name, optionally limited to items or folders and scoped to specific folders. Read-only despite being a POST. Paginated: send the same arguments with the next page number. Sortly: POST /api/v1/items/search.

Input parameters:

- `folder_ids` (array): Only search in these folders.
- `include` (array): Nested associations to embed: custom_attributes and/or photos.
- `include_subfolders` (boolean): With folder_ids: also search folders nested under them. Default false.
- `name` (string): Name (or part of it) to search for.
- `page` (integer): Page number, starting at 1.
- `per_page` (integer): Page size, 1-100 (default 100).
- `sort` (string): Sort by name, ascending or descending.
- `type` (string): Limit to items or folders. Default all.

### `sortly_list_recently_updated_items` (~168 tokens)

List recently updated items

List items and folders changed since a Unix timestamp — the incremental-sync read ('what moved since yesterday?'). Without updated_since it behaves like sortly_list_items. Sortly: GET /api/v1/items/recent.

Input parameters:

- `folder_id` (integer): Only the direct contents of this folder. Omit for the root level.
- `include` (array): Nested associations to embed: custom_attributes and/or photos.
- `include_subfolders` (boolean): With folder_id: also return everything nested beneath it. Default false.
- `page` (integer): Page number, starting at 1.
- `per_page` (integer): Page size, 1-100 (default 10).
- `updated_since` (integer): Unix epoch seconds; only items updated after this.

### `sortly_list_custom_fields` (~81 tokens)

List custom fields

List the account's custom fields (id, name, type, applies_to). Call this before writing custom_attribute_values to get the right custom_attribute_id. Sortly: GET /api/v1/custom_fields.

Input parameters:

- `page` (integer): Page number, starting at 1.
- `per_page` (integer): Page size (default 10).

### `sortly_list_units` (~50 tokens)

List units of measure

List the units of measure available to the account (unit_name, unit_type, scale) — the values measured_quantity and purchase-order lines expect. Sortly: GET /api/v1/units.

### `sortly_list_alerts` (~82 tokens)

List alerts

List stock (Quantity) and date (DateReminder) alerts, with is_fired showing which have already triggered — the quick way to find low-stock items. Sortly: GET /api/v1/alerts.

Input parameters:

- `page` (integer): Page number, starting at 1.
- `per_page` (integer): Page size (default 10).

### `sortly_list_jobs` (~138 tokens)

List jobs

List jobs (work orders that pull stock out), most recently updated first, filterable by name prefix and status. Paginated via meta.pagination.has_next. Sortly: GET /api/v1/jobs.

Input parameters:

- `name` (string): Jobs whose name starts with this (case-insensitive).
- `page` (integer): Page number, starting at 1.
- `per_page` (integer): Page size, 1-100 (default 20).
- `sort_by` (string): Sort field. Default updated_at.
- `sort_direction` (string): Default desc.
- `status` (array): Only these statuses. Default all.

### `sortly_get_job` (~65 tokens)

Get one job

Fetch a single job: status, folder_id (where its pulled items sit), dates, notes, custom field values and the version needed for updates. Sortly: GET /api/v1/jobs/{job_id}.

Input parameters:

- `job_id` (integer, required): The job's id.

### `sortly_list_purchase_orders` (~159 tokens)

List purchase orders

List purchase orders, most recently updated first, filterable by PO number and status. The list leaves out notes, terms, sub_total and line_items — use sortly_get_purchase_order for those. Needs Purchase Orders on the plan (else 402). Sortly: GET /api/v1/purchase_orders.

Input parameters:

- `page` (integer): Page number, starting at 1.
- `per_page` (integer): Page size, 1-100 (default 20).
- `purchase_order_number` (string): POs whose number contains this.
- `sort_by` (string): Sort field. Default updated_at.
- `sort_direction` (string): Default desc.
- `status` (array): Only these statuses. Default all.

### `sortly_get_purchase_order` (~66 tokens)

Get one purchase order

Fetch a single purchase order with its line_items (quantity vs received_quantity), vendor, addresses, charges, totals and version. Sortly: GET /api/v1/purchase_orders/{purchase_order_id}.

Input parameters:

- `purchase_order_id` (integer, required): The purchase order's id.

### `sortly_get_purchase_order_receive_status` (~84 tokens)

Get a purchase order's receive status

Report the most recent receive against a purchase order: pending / completed / failed, with the line ids received, pending and failed (and why). Returns 404 until something has been received. Sortly: GET /api/v1/purchase_orders/{purchase_order_id}/receive/status.

Input parameters:

- `purchase_order_id` (integer, required): The purchase order's id.

### `sortly_create_item` (~304 tokens)

Create an item or folder

Create a trackable item (type item) or a folder (type folder), optionally inside a folder via parent_id, with quantity, price, tags, custom fields, barcodes and a measured quantity. WRITE. Sortly: POST /api/v1/items.

Input parameters:

- `custom_attribute_values` (array): Custom field values. Look up ids with sortly_list_custom_fields first.
- `label_url` (string|null): Value encoded in the primary QR code / barcode.
- `label_url_extra` (string|null): Value encoded in the secondary code.
- `label_url_extra_type`: Symbology of the secondary code.
- `label_url_type`: Symbology of the primary code.
- `measured_quantity` (object): For items measured in something other than units.
- `min_quantity` (number|null): Minimum level; a Quantity alert can fire when stock reaches it.
- `name` (string, required): Name, max 190 characters.
- `notes` (string|null): Free-text notes.
- `parent_id`: Folder to create it in. Omit/null = root.
- `photo_ids` (array): Ids of photos already in the account to attach.
- `price` (number|null): Unit price.
- `quantity` (number|null): How many you have.
- `tags` (array): Tag names, e.g. ["furniture", "used"].
- `type` (string, required): item = trackable stock; folder = a container.

### `sortly_update_item` (~330 tokens)

Update an item or folder

Change fields on an existing item or folder — e.g. set a new quantity after a stock count, rename it, or relocate a folder via parent_id. Only the fields you pass change; pass null to clear a nullable field. Sending tags or custom_attribute_values replaces them. WRITE. Sortly: PUT /api/v1/items/{item_id} (returns 204).

Input parameters:

- `custom_attribute_values` (array): Custom field values. Look up ids with sortly_list_custom_fields first.
- `item_id` (integer, required): The item's or folder's numeric id.
- `label_url` (string|null): Value encoded in the primary QR code / barcode.
- `label_url_extra` (string|null): Value encoded in the secondary code.
- `label_url_extra_type`: Symbology of the secondary code.
- `label_url_type`: Symbology of the primary code.
- `measured_quantity` (object): New measured amount for a measured item.
- `min_quantity` (number|null): Minimum level; a Quantity alert can fire when stock reaches it.
- `name` (string): New name.
- `notes` (string|null): Free-text notes.
- `parent_id`: Move into this folder (null = root). To move PART of an item's stock use sortly_move_item.
- `photo_ids` (array): Ids of photos already in the account to attach.
- `price` (number|null): Unit price.
- `quantity` (number|null): How many you have.
- `tags` (array): Tag names, e.g. ["furniture", "used"].

### `sortly_move_item` (~162 tokens)

Move stock to another folder

Move some or all of an item's quantity to another folder (items only — relocate a folder with sortly_update_item parent_id). A partial move splits off a new item with the same sid; a full move relocates the item; a matching item at the destination is merged, and the returned id is the destination's. Undo by moving it back. WRITE. Sortly: POST /api/v1/items/{item_id}/move.

Input parameters:

- `folder_id` (integer): Destination folder. Omit to move to the root level.
- `item_id` (integer, required): The item's numeric id.
- `leave_zero_quantity` (boolean): Keep a zero-quantity record in the source folder. Default false.
- `quantity` (number, required): How much to move.

### `sortly_create_alert` (~220 tokens)

Create an alert

Create a stock alert on an item (type Quantity, e.g. threshold_method quantity_less_than with threshold_value 5, or less_than_or_equal_to_min_quantity), or a DateReminder on a datetime custom field (custom_attribute_id + before/after/same_day + threshold_interval). WRITE. Sortly: POST /api/v1/alerts.

Input parameters:

- `custom_attribute_id` (integer): For DateReminder: the datetime custom field to watch.
- `item_id` (integer, required): The item the alert watches.
- `recipient_groups` (array): Who is notified: owners, admins, members, limited, or a custom role name. Default owners.
- `threshold_interval` (string): Required for DateReminder; omit for Quantity.
- `threshold_method` (string, required): What triggers it: a quantity_* method for Quantity, before/after/same_day for DateReminder.
- `threshold_value` (number): The number compared against (or the interval count).
- `type` (string, required): Quantity = stock threshold; DateReminder = date custom field.

### `sortly_create_job` (~162 tokens)

Create a job

Create a job (and its job folder) in not_started status. Name must be unique in the company. Then use sortly_pull_items_into_job to record the stock it uses. WRITE. Sortly: POST /api/v1/jobs.

Input parameters:

- `custom_field_values` (array): Up to 2 job custom field values.
- `end_date` (string): YYYY-MM-DD.
- `external_job_link` (string): Link to the job in another system.
- `name` (string, required): Unique job name, max 190 characters.
- `notes` (string): Job notes, max 4000 characters.
- `start_date` (string): YYYY-MM-DD.
- `subfolders` (array): Subfolder names to create, up to 25.

### `sortly_pull_items_into_job` (~135 tokens)

Pull items into a job

Move quantities of existing items (from any folders) into a job's folder — how usage on a job is recorded. Up to 100 items per call; items are processed independently, so ALWAYS check data.errors (a partial failure still returns 200). Undo with sortly_return_items_from_job. Returns 403 on a completed job. WRITE. Sortly: POST /api/v1/jobs/{job_id}/items.

Input parameters:

- `items` (array, required): 1-100 items.
- `job_id` (integer, required): The job's id.
- `notes` (string): Optional note kept in each item's history.

### `sortly_return_items_from_job` (~108 tokens)

Return items from a job

Move items off a job's folder back into inventory (destination_folder_id, or All Items if omitted). Up to 100 per call; check data.errors — items are processed one by one. WRITE. Sortly: POST /api/v1/jobs/{job_id}/items/return.

Input parameters:

- `items` (array, required): 1-100 items.
- `job_id` (integer, required): The job's id.
- `notes` (string): Optional note recorded in the item's history.

### `sortly_create_purchase_order` (~237 tokens)

Draft a purchase order

Create a purchase order in draft status (no stock or ordering happens until it is moved on in Sortly). Sortly computes amounts, sub_total and total from the lines; omit purchase_order_number to have one generated. Needs Purchase Orders on the plan (else 402). WRITE. Sortly: POST /api/v1/purchase_orders.

Input parameters:

- `bill_to` (object): Billing address.
- `charges` (object): Order-level charges; each defaults to 0.
- `currency_code` (string, required): ISO 4217 code, e.g. USD.
- `expected_delivery_date` (string): ISO 8601 timestamp, e.g. 2026-08-20T00:00:00Z.
- `line_items` (array): Up to 100 lines.
- `notes` (string)
- `purchase_order_number` (string): Unique PO number, max 20 chars. Omit to auto-generate.
- `ship_to` (object): Shipping address.
- `terms` (string): e.g. Net 30.
- `vendor` (object): The vendor, captured on the PO.

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/io-usefulapi-sortly/sortly#diagnostics

## Score history

- 2026-10-04: 77
- 2026-10-03: 77
- 2026-10-02: 76
- 2026-10-01: 76
- 2026-09-30: 71
- 2026-09-29: 18

## Common questions

### What is the io.usefulapi/sortly MCP server?

io.usefulapi/sortly is an MCP server listed in the public MCP registry as io.usefulapi/sortly. Search inventory items and folders, low-stock alerts, jobs and purchase orders, and update stock. This page covers its hosted endpoint (https://sortly.usefulapi.io/mcp).

### Is the io.usefulapi/sortly MCP server safe to use?

io.usefulapi/sortly scores 77 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the io.usefulapi/sortly MCP server expose?

io.usefulapi/sortly exposes 20 tools: sortly_list_items, sortly_get_item, sortly_search_items, sortly_list_recently_updated_items, sortly_list_custom_fields, and 15 more. Their descriptions and schemas cost roughly 2,989 tokens of context every time the server is loaded.

### Does the io.usefulapi/sortly MCP server require authentication?

Yes. io.usefulapi/sortly asked us for credentials when we connected, so you will need to authorise it in your MCP client before it can do anything.

### Is the io.usefulapi/sortly MCP server still maintained?

io.usefulapi/sortly is still listed as active in the MCP registry. We last reached this channel on 4 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

## Links

- Remote endpoint: https://sortly.usefulapi.io/mcp
- Repository: https://github.com/m190/usefulapi-mcp
- Changelog RSS feed: https://verifymcp.io/servers/io-usefulapi-sortly/sortly.xml
- Changelog JSON feed: https://verifymcp.io/servers/io-usefulapi-sortly/sortly.json
- HTML version of this page: https://verifymcp.io/servers/io-usefulapi-sortly/sortly
