> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shorpay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP tool reference

> Shows MCP tools, API routes, inputs, permissions, and confirmed-write behavior.

Shor's MCP server exposes 10 read tools and five write tools over the public API. For customer setup, capabilities, and example prompts, start with [Connect AI assistants](/employer/ai-assistants).

## Connection and API routes

An assistant sends MCP requests to the hosted **`/mcp` endpoint**, using the server address displayed in **Settings → Integrations**. The HTTP routes below are the underlying public API operations on the API origin; they are not separate MCP endpoints or URLs to enter into the assistant.

Hosted connections use OAuth and are scoped to the signed-in Shor workspace. Setup creates the connection automatically for an admin. API keys are for [direct API integrations](/developers/public-api); do not send an assistant's OAuth token directly to `/v1`.

The [OpenAPI reference](/api-reference/openapi.json) defines HTTP request and response schemas. The API also serves its current contract at `GET /v1/openapi.json` without authentication.

## Read tools

Every tool in this table requires **`read`** and allows the current `admin`, `member`, or `viewer` role within the connection's granted access. Reads do not request write confirmation. Initial hosted setup and connection management require an admin.

| MCP tool          | HTTP method and route               | Inputs and result                                                                                                                                      |
| ----------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `get_business`    | `GET /v1/business`                  | No arguments. Returns the current workspace's ID, name, country, business verification status, and timestamps.                                         |
| `list_contracts`  | `GET /v1/contracts`                 | Optional contract filters and pagination. Returns contract summaries.                                                                                  |
| `get_contract`    | `GET /v1/contracts/{id}`            | Required `id`. Returns a contract summary, including worker ID/name, status, and dates.                                                                |
| `list_timesheets` | `GET /v1/timesheets`                | Optional timesheet filters and pagination. Returns work periods, units, rates, totals, payment dates, automatic payment settings, and review versions. |
| `get_timesheet`   | `GET /v1/timesheets/{id}`           | Required `id`. Returns one timesheet, including its `version` and nullable `paymentId`.                                                                |
| `list_milestones` | `GET /v1/contracts/{id}/milestones` | Required `contractId`, mapped to the route's `{id}`. Optional status and pagination. Returns milestones for that contract.                             |
| `get_milestone`   | `GET /v1/milestones/{id}`           | Required `id`. Returns amount, due/payment dates, status, `version`, and nullable `paymentId`.                                                         |
| `list_payments`   | `GET /v1/payments`                  | Optional payment filters and pagination. Returns current payment states, gross/net amounts, and dates.                                                 |
| `get_payment`     | `GET /v1/payments/{id}`             | Required `id`. Returns one payment and its current status.                                                                                             |
| `get_balances`    | `GET /v1/balances`                  | No arguments. Returns available/pending amounts by currency and an `asOf` timestamp.                                                                   |

IDs are UUIDs returned by Shor. Single resources are objects; lists return `{ data, hasMore, nextCursor }`. Money uses `{ amount, currency }`, with `amount` a decimal string. Dates use `YYYY-MM-DD`; timestamps use UTC ISO 8601. The MCP result carries the JSON representation in a text content block.

### List filters and pagination

All four list tools accept numeric `limit` from **1–100**, defaulting to **25 for MCP**. Direct HTTP list calls default to **50**. Continue with `nextCursor` as `cursor` while `hasMore` is true, keeping the other filters unchanged.

| Tool              | Additional filters                                              |
| ----------------- | --------------------------------------------------------------- |
| `list_contracts`  | `status`, `updatedSince`, `includeDeleted`, `externalReference` |
| `list_timesheets` | `status`, `contractId`, `updatedSince`                          |
| `list_milestones` | Required `contractId`; optional `status`                        |
| `list_payments`   | `status`, `contractId`, `updatedSince`                          |

`includeDeleted` is the string `"true"` or `"false"` (default `"false"`), including in MCP arguments. `updatedSince` is an inclusive UTC timestamp. `externalReference` looks up a draft within the same workspace and integration principal.

Timesheet status filters are `submitted`, `approved`, and `rejected`. Milestone filters are `pending`, `submitted`, `approved`, `completed`, `paid`, and `rejected`. Payment filters are `pending`, `processing`, `completed`, `failed`, and `cancelled`. Contract statuses and complete schemas are in the [OpenAPI reference](/api-reference/openapi.json).

For example, the arguments to `list_timesheets` can be:

```json theme={null}
{ "status": "submitted", "limit": 25 }
```

Milestones have no workspace-wide list or `updatedSince` filter. List contracts first, then scan each relevant contract's milestone pages. For overlap windows, deletion handling, and other reconciliation rules, see [Polling and TypeScript SDK](/developers/polling-and-sdk).

## Write tools

Every write in this table requires **explicit human confirmation** through the MCP host. The scopes listed are required for the MCP tool, and the role is checked against the current membership on every action and replay.

| MCP tool                | HTTP method and route              | Required MCP scopes         | Allowed roles     |
| ----------------------- | ---------------------------------- | --------------------------- | ----------------- |
| `create_contract_draft` | `POST /v1/contracts`               | `contracts:write`           | `admin`, `member` |
| `approve_timesheet`     | `POST /v1/timesheets/{id}/approve` | `read` + `timesheets:write` | `admin`           |
| `reject_timesheet`      | `POST /v1/timesheets/{id}/reject`  | `read` + `timesheets:write` | `admin`           |
| `approve_milestone`     | `POST /v1/milestones/{id}/approve` | `read` + `milestones:write` | `admin`           |
| `reject_milestone`      | `POST /v1/milestones/{id}/reject`  | `read` + `milestones:write` | `admin`           |

Approval/rejection tools require `read` because they fetch the resource and its contract before asking for confirmation. Their HTTP POST routes require the corresponding write scope; direct API clients must separately fetch and review the resource to obtain `expectedVersion`.

### Create a contract draft

`create_contract_draft` requires `title` and `intentId`. Optional inputs are `professionalEmail`, `description`, `employmentType`, `contractType`, `countryOfEmployment`, `startDate`, `endDate`, and `externalReference`. Employee contracts require `countryOfEmployment`, and any supplied employment/contract types must agree.

Example tool arguments using a synthetic intent ID:

```json theme={null}
{
  "title": "Website redesign",
  "externalReference": "example-project-001",
  "intentId": "example-draft-001"
}
```

The confirmation displays the workspace and supplied fields. After confirmation, MCP removes `intentId` from the body and sends it as the HTTP `Idempotency-Key` header. The result is a contract summary; direct HTTP creation returns status `201`.

This initializes a draft for completion in Shor. It does not accept the dashboard's nested compensation payload, sign an agreement, or activate a contract.

### Approve or reject submitted work

The four review tools accept `id` and `intentId`. Rejections also require a trimmed, nonempty `reason` of at most 2,000 characters. They act on submitted work; other states may be rejected by the API.

MCP fetches the timesheet or milestone and its contract, then shows the worker, contract, workspace, amount/currency, and payment date for review. Timesheet reviews also include the work period. Approval shows the timesheet's automatic payment setting or the milestone's immediate processing behavior; rejection shows the reason.

The server retains the fetched resource `version` in signed review state. After confirmation, it sends `{ expectedVersion }` for approval or `{ expectedVersion, reason }` for rejection, with `intentId` in `Idempotency-Key`. Do not supply `expectedVersion` or `confirmed` as tool arguments: those fields are not accepted by these tools.

The result is the updated timesheet or milestone. Approval creates a payment; timesheet processing follows its due date and effective automatic payment setting, while milestone approval attempts processing immediately. Follow a returned `paymentId` with `get_payment` to determine payout status. A successful approval is not a completed payout.

## Confirmation, retries, and stale reviews

For the `2026-07-28` protocol, the first write call returns an input-required response containing signed `requestState` and a confirmation request. A compatible host presents that request to the human and resumes with the signed state and accepted input response. Review state lasts **five minutes** and binds the principal, workspace, tool, arguments, and reviewed resource version where applicable.

A model-generated `confirmed` value does not authorize a write. Changing the arguments or reusing another workspace's review fails validation. Remote hosts that cannot carry the required confirmation can read but receive `CONFIRMATION_UNSUPPORTED` for writes. Verify compatibility with the actual host/version; successful tool discovery does not establish support for confirmed writes.

Every intentional write needs a unique `intentId` of **16–128 letters, digits, underscores, or hyphens**. Retain it and the exact arguments across retries of that operation. Successful API results are retained for **seven days**. Do not reuse the ID after retention. For an intentional new action, generate a new ID.

If the review expires or the resource changes, fetch and confirm current details again. A changed resource version returns `STALE_RESOURCE_VERSION`; use a new intent for the newly reviewed action. For an uncertain prior outcome, reconcile the resource/payment state before creating a new operation. An API replay returns the original operation result, which may differ from current resource state.

`externalReference` can correlate contract drafts after operation retention, but is scoped to the workspace and integration principal. Separate MCP grants and independently created API keys are different integrations.

MCP uses the typed client's default 15-second deadline and two retries for network failures and 429/502/503/504 responses. Authorization errors and 409 conflicts need caller handling. See [API errors and retries](/developers/public-api#errors-and-retries) for rate limits and HTTP error semantics.

### Error handling

Tool failures use `isError: true` with a JSON error in text content. API-originated errors include `code`, `status`, and available `requestId`/`retryAfterSeconds`; confirmation failures may contain only `code`. Transport or protocol errors can occur before a tool result is produced.

| Code                                        | Next step                                                                                                        |
| ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `CONFIRMATION_UNSUPPORTED`                  | Use a host/version that supports the required confirmation, or perform the action in Shor.                       |
| `CONFIRMATION_DECLINED`                     | No write was authorized. Stop unless the user requests another review.                                           |
| `CONFIRMATION_MISMATCH`                     | Arguments or review state no longer match. Start a fresh review.                                                 |
| `CONFIRMATION_EXPIRED`                      | Legacy confirmation timed out. Review again; invalid modern signed state may instead fail at the protocol layer. |
| `STALE_RESOURCE_VERSION`                    | Fetch and review the latest resource before a new intent.                                                        |
| `INVALID_CREDENTIAL` / `INSUFFICIENT_SCOPE` | Check sign-in, workspace, active connection, scopes, and current role.                                           |
| `INTEGRATION_DISABLED` / `WRITES_DISABLED`  | Check workspace rollout and write availability with Shor.                                                        |
| `IDEMPOTENCY_KEY_REUSED`                    | Retry only the original arguments, or use a new ID for a separate intended action.                               |
| `OPERATION_IN_PROGRESS`                     | Wait and retry the same operation.                                                                               |
| `OPERATION_EXPIRED`                         | Reconcile state before deciding whether another action is needed.                                                |
| `EXTERNAL_REFERENCE_EXISTS`                 | Look up the contract using the same `externalReference`.                                                         |
| `TOOL_FAILED` / `MCP_UNAVAILABLE`           | Inspect current state before retrying an uncertain write; contact Shor if the failure persists.                  |

Retain request IDs for support without logging credentials or sensitive request bodies. A failed balance read must not be interpreted as zero.

## Access and discovery

The tool catalog is filtered by effective scopes. For tokens containing signed Shor API scopes, access is the intersection of those scopes, the connection grant, and the current membership role. Hosted sign-in with identity-only scopes creates an admin-scoped grant; subsequent exchanges synchronize its scopes to the current role's allowed API operations. Missing organization, client, or scope claims fail closed. Refresh discovery after changing access; every underlying API call still checks live authorization.

The server also provides these read-scoped MCP features:

| Feature  | Identifier        | Behavior                                                                                                                                                                  |
| -------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Resource | `shor://business` | Reads the current workspace through `GET /v1/business`.                                                                                                                   |
| Prompt   | `payroll_review`  | Supplies a review checklist covering submitted work, amounts, payment dates, automatic payment settings, and explicit approval confirmation. It performs no write itself. |

Protected-resource discovery is available at both `GET /.well-known/oauth-protected-resource` and `GET /.well-known/oauth-protected-resource/mcp` on the MCP origin. The metadata advertises OAuth identity scopes (`openid`, `profile`, `email`, `offline_access`); Shor API permissions are resolved through the connection rather than requested as identity scopes.

## Remote host configuration

Use the hosted server address from Settings for your environment. These examples show the production address; they do not certify a host's support for confirmed writes.

For Claude Code:

```bash theme={null}
claude mcp add --transport http shor https://mcp.shorpay.com/mcp
```

Complete sign-in through the host's OAuth flow. See [Claude Code MCP configuration](https://code.claude.com/docs/en/mcp).

For Cursor, the remote entry in its MCP configuration is:

```json theme={null}
{
  "mcpServers": {
    "shor": { "url": "https://mcp.shorpay.com/mcp" }
  }
}
```

Complete the OAuth prompt after adding it. See [Cursor MCP configuration](https://cursor.com/docs/mcp). For Claude and ChatGPT setup from the dashboard, use [Connect AI assistants](/employer/ai-assistants).

The current tools exclude signing/activation, standalone payout initiation, arbitrary ledger addresses, full worker profiles, general search, upcoming-payment summaries, and webhooks. Use Shor's application for workflows outside this catalog.
