Skip to main content

The MCP server

The endpoint AI apps connect to, the tools it offers, the protocol versions it speaks and how it answers.

AI apps that speak the Model Context Protocol connect to TradeSender at one address:

https://app.tradesender.co.uk/mcp

This page is for someone building or debugging such an app. To connect Claude, ChatGPT or Codex as a user, start at Connect your AI assistant.

Transport

  • Send each JSON-RPC message as its own POST, with Content-Type: application/json. You get one JSON answer. A batch is refused.
  • There are no streams and no sessions. GET and DELETE answer 405 with Allow: POST.
  • A notification (a message with no id) answers 202 with no body.
  • Nothing is remembered between requests, so any request can follow any other.

Protocol versions

The server speaks the stateless revision 2026-07-28, where each request names its version, and the earlier handshake revisions 2025-11-25, 2025-06-18, 2025-03-26 and 2024-11-05 for apps that open with initialize.

On 2026-07-28 each request carries _meta with the protocol version and the client's capabilities, and the MCP-Protocol-Version and Mcp-Method headers must agree with the body (Mcp-Name too on tools/call). server/discover returns the supported versions and the instructions.

Signing in

A request with no token answers 401 with a WWW-Authenticate header that points at the server's metadata:

WWW-Authenticate: Bearer resource_metadata="https://app.tradesender.co.uk/.well-known/oauth-protected-resource/mcp"

From there the app signs the person in with OAuth. See OAuth sign-in for assistants. The token works only at /mcp. An API key does not work here.

The tools

There is one tool for each operation offered, named by its id in the API reference, such as listVisits or createQuote. Its title is the operation's summary, and its description is the operation's description in the reference. A new operation becomes a new tool. tools/list may be kept for five minutes.

A tool takes the operation's path and query parameters by name, and its request body as body, written out in full. A tool that changes something also takes an optional idempotency_key: the tool makes its own when you send none, so send your own and repeat it to retry a change after a timeout. A field the reference marks as nullable may be null in the tool's schema.

Each tool says how far it reaches:

AnnotationTrue for
readOnlyHintEvery tool that only reads.
destructiveHintEvery tool that changes something, except those that only add a record. Sending, recording a payment, finalising or voiding an invoice, editing, archiving and deleting are all destructive, and so is scheduling a visit, which makes a completed job active again.
openWorldHintThe six that email a business's customers: sendQuote, sendInvoice, sendInvoiceReminder, sendVisitOnMyWay, createMonthEndInvoices and moveCalendarDay.

A tool's answer is one text item holding JSON: the same body the API gives. When the operation fails, isError is true and the JSON carries the API's status and its errors, with the same codes as in Requests and conventions. When the call itself is wrong, such as an argument the tool does not take or a missing path parameter, the text is a sentence saying what to send instead.

What is offered

The operations for customers, contacts, properties, services, quotes, jobs, visits, repeating visits, time, time off, invoices and payments, with the day's route, moving a day's visits, the On my way email and the emails sent to a customer. The connection works as one member of one workspace with that member's role, so a technician's assistant is refused what a technician is refused.

Not offered: settings, the team, the plan, sign-in, API keys, connecting Stripe, refunds, collecting an invoice by Direct Debit (collectInvoice), photo uploads, PDFs and website enquiries. Nor is anything a business's customer does for themselves: paying an invoice online and setting up a Direct Debit.

Some fields the apps use are in no tool's description and in no answer:

  • The cost fields: unit_cost_cents on a service and a line, cost_cents on a quote and a job. A cost sent in a body is dropped without an error.
  • direct_debit on a customer: how far their Direct Debit has got and the last four digits of their bank account. An invoice's collect_on, collectable and direct_debit_failed are sent, so an assistant can tell whether and when an invoice will be collected.

An assistant is offered 92 operations. Each one links to its entry in the API reference, which lists what it takes and what it answers with.

Customers

Services

Quotes

Jobs and visits

Calendar and time off

Invoices and payments

Workspace and team

Instructions the server gives

The server's instructions tell the assistant how the records fit together, how money, quantities, tax and times are written, to look for an existing record before making one, and to say what it is about to do and wait for a yes before sendQuote, sendInvoice, sendVisitOnMyWay, sendInvoiceReminder, issueInvoice, createInvoicePayment, createCustomerPayment and voidInvoice. They also name the workspace, the member, their role, the time zone and the currency.

Five operations have instructions of their own:

  • createMonthEndInvoices issues an invoice for every job billed at month end and emails each customer in one go. The assistant is told to say how many jobs and up to which date, and wait for a yes.
  • moveCalendarDay moves every scheduled visit on a day to another day and, with notify_customers, emails each of their customers. The assistant is told to say which day, where to, how many visits and whether the customers are emailed, and wait for a yes.
  • importCustomers writes many customers at once. The assistant is told to call it with dry_run: true first, say what it would do, and wait for a yes.
  • acceptQuote on a quote with a deposit (deposit_cents) issues an invoice for that deposit, due today. The assistant is told to say so with the amount, and wait for a yes.
  • writeOffInvoice settles what a customer still owes without their paying it. The assistant is told to say which invoice, whose it is, how much and the reason, and wait for a yes.

Each tool's description repeats what the assistant is told to say before calling it.

These are instructions to a model. The server does not hold a change back until a person confirms. The annotations above let a client ask the person itself.

Limits

A connection may send 300 requests a minute. Over that, the answer is 429 with Retry-After: 60.

Emails an assistant sends with sendQuote, sendInvoice and sendVisitOnMyWay count towards the workspace's 100 emails a day. Once those are used up, a send fails with the API's status 429 and the code rate_limited until a day has passed. The emails of createMonthEndInvoices are not counted towards the 100, and nor are those of moveCalendarDay, which have a limit of their own: see Rate limits.

Checked against the app on 31 October 2026. Still stuck? Ask usAsk us.