Documentation
MCP server reference
Everything needed to connect an AI assistant to a LoadSnap account, and what it can read once connected.
Endpoint
A remote Model Context Protocol server using the Streamable HTTP transport: JSON-RPC 2.0 over a single POST. The server is stateless, so there is no session header and no server-initiated event stream, and a GET returns 405.
Add it to Claude, Claude Code, ChatGPT, Cursor or any other MCP-compatible client as a custom or remote connector, using that URL. There is no API key to paste.
Authentication
OAuth 2.1: authorization code with PKCE, plus Dynamic Client Registration, so a client onboards itself with no manual setup. Discovery works the usual way, an unauthenticated request returning 401 with a WWW-Authenticate header pointing at the protected-resource metadata.
| Protected resource metadata | /.well-known/oauth-protected-resource |
|---|---|
| Authorization server metadata | /.well-known/oauth-authorization-server |
| Dynamic client registration | /api/oauth/register |
| Authorization | /oauth/authorize |
| Token | /api/oauth/token |
The person signs in to LoadSnap and approves the connection on a screen naming the client and their organisation. Access tokens last an hour and are renewed with a refresh token, so the connection keeps working without signing in again.
Access is authorised as a person, not as a key. Organisation membership and plan are re-checked on every request, so removing someone from an organisation ends their connector access with it.
Scope of access
Every query is hard-filtered to the authorised user's organisation, resolved server-side from the token. The client never supplies an organisation, so it cannot request another company's data. Row-level security enforces the same boundary in the database underneath.
15 of the 21 tools only read. The 6 whose names begin with create_ add a record and nothing else: none edits, deletes, files to DEFRA, signs a transfer note, raises an invoice or hands out an office login. Each is marked as writing in its annotations, so a client asks the person before it runs one.
The one exception to organisation scoping is find_waste_codes, which searches the published European Waste Catalogue — the same national list for everybody, and nobody's own data.
Tools
21 tools, every one scoped to the authorised organisation. Each is listed below with the description a client is given and the arguments it accepts. A tool marked writes adds a record; the rest only read.
find_movements
Find waste movements
List or search this organisation's waste movement records (Waste Transfer Notes) and jobs, by producer, customer or carrier name and/or a collection date range. Use this for 'have we done movements for X', 'what did we collect from Y in May', or 'what did we move last week' with no name at all.
| name | optional | Producer, customer or carrier name to search for. Omit to list everything in the date range. |
| date_from | optional | Optional ISO date (YYYY-MM-DD) lower bound |
| date_to | optional | Optional ISO date (YYYY-MM-DD) upper bound |
find_receipts
Find receiving receipts
List or search this organisation's receiving receipts (waste arriving at their own site) by carrier or producer name and/or a received-date range. Omit the name to list everything received in the range.
| name | optional | Carrier or producer name. Omit to list all. |
| date_from | optional | Optional ISO date (YYYY-MM-DD) lower bound |
| date_to | optional | Optional ISO date (YYYY-MM-DD) upper bound |
count_movements
Count waste movements
Count this organisation's waste movements over a date range and total their weight, optionally split inbound or outbound. Use this for 'how many loads did we do last month', 'how much waste did we handle this year', 'how many collections this week'. Counts by collection date.
| date_from | optional | ISO date (YYYY-MM-DD) lower bound on the collection date |
| date_to | optional | ISO date (YYYY-MM-DD) upper bound on the collection date |
| direction | optional | inbound = waste taken in at this org's own site, outbound = waste its lorry took away or sent out. Omit for all. |
defra_filings
DEFRA filings
Count and list this organisation's DEFRA waste tracking submissions over a date range, and list the records still waiting to be filed. Use this for 'how many DEFRA submissions have we filed this week', 'did anything fail with DEFRA', 'what is still outstanding'.
| date_from | optional | ISO date (YYYY-MM-DD) lower bound on the submission date |
| date_to | optional | ISO date (YYYY-MM-DD) upper bound on the submission date |
| include_outstanding | optional | Also return the records that have not been filed with DEFRA yet. Defaults to true. |
find_parties
Find carriers and sites
Resolve a company or site name to the organisation's known carriers and sites.
| name | required | Company or site name |
find_jobs
Find scheduled jobs
List or search this organisation's jobs — work booked in, in progress or done — by customer name and/or a scheduled date range. Use this for 'what are we doing tomorrow', 'is the Carter job booked in', 'what is still unallocated'. Reads forwards from the earliest date, because a job list is a diary.
| name | optional | Customer name to search for. Omit to list everything in range. |
| status | optional | Job status to filter on, for example draft, scheduled, in_progress, completed, cancelled. |
| date_from | optional | Optional ISO date (YYYY-MM-DD) lower bound |
| date_to | optional | Optional ISO date (YYYY-MM-DD) upper bound |
find_invoices
Invoices and money owed
List this organisation's invoices and total what is still owed, optionally only the unpaid ones. Use this for 'who owes us money', 'how much is outstanding', 'is the Carter invoice paid', 'what is overdue'. Totals are in the invoice currency.
| name | optional | Name of the business the invoice was billed to. Omit to list everything in range. |
| status | optional | Invoice status to filter on, for example draft, issued, paid, void. |
| only_unpaid | optional | Only invoices with a balance still to pay. Defaults to false. |
| date_from | optional | Optional ISO date (YYYY-MM-DD) lower bound |
| date_to | optional | Optional ISO date (YYYY-MM-DD) upper bound |
find_vehicles
Vehicles and their paperwork
List this organisation's vehicles with their MOT, tax and insurance expiry, and flag any that have run out. Use this for 'what is on the fleet', 'is anything out of MOT', 'when is the tax due on VX19 ABC'. MOT and tax come from DVLA and are only as fresh as the last check.
| name | optional | Registration or description to search for. Omit to list everything in range. |
| include_inactive | optional | Also return vehicles taken off the fleet. Defaults to false. |
find_people
The team and what they can use
List the people on this organisation's team and which of the three ways in each holds: an office login, the driver app, the weighbridge app. Use this for 'who drives for us', 'has Dave got the driver app', 'who is on the team'.
| name | optional | Person's name or email to search for. Omit to list everything in range. |
| drivers_only | optional | Only people who hold the driver app. Defaults to false. |
compliance_status
Certificates, permits and registrations
List the certificates, permits and registrations this organisation has recorded, with their expiry dates, and say which have already run out. Use this for 'is our waste carrier registration still valid', 'what expires this year', 'have we got an ISO certificate on file'.
| expired_only | optional | Only the ones that have already expired. Defaults to false. |
find_documents
Find a document
Find this organisation's stored documents — waste transfer notes, consignment notes, permits, uploaded paperwork — by type and/or date, with a link to each. Use this for 'send me the transfer note for that load', 'what paperwork have we got on this job'.
| document_type | optional | Document type to filter on, for example wtn, hwcn, annex_vii, permit, upload. |
| movement_id | optional | Only documents attached to this waste movement. |
| job_id | optional | Only documents attached to this job. |
| date_from | optional | Optional ISO date (YYYY-MM-DD) lower bound |
| date_to | optional | Optional ISO date (YYYY-MM-DD) upper bound |
container_stock
Skips and containers
What containers this organisation holds and where they are: the ones tracked one by one with an asset number and state, and the types held as a running total. Use this for 'how many 8 yard skips have we got free', 'where is skip 214', 'what is out on hire'.
| container_type | optional | Container type to filter on, for example skip, roro, bin. |
| container_size | optional | Container size to filter on, for example 8yd. |
| state | optional | State of an individually tracked container, for example in_yard, on_site, in_transit. |
find_contracts
Contracts and season tickets
List this organisation's standing agreements: contracts and season tickets, what waste each covers, the dates it runs and whether both sides have signed. Use this for 'what have we got on contract', 'has that season ticket been signed', 'what runs out this month'.
| site_id | optional | Only agreements for this site. |
| active_only | optional | Only agreements still in force. Defaults to false. |
consignee_returns
Quarterly consignee returns
This organisation's quarterly consignee returns for hazardous waste received: the quarter, what is due when, how many consignments and what weight, and whether it has been sent. Use this for 'is our consignee return done', 'what is due this quarter'. Receivers only; a carrier has none.
| quarter | optional | A quarter label, for example "Q1 2026". |
| status | optional | Status to filter on: not_started, generated, reviewed or submitted. |
find_waste_codes
Look up a waste code
Search the European Waste Catalogue (EWC) by code or by what the waste is, and say whether each code is hazardous or a mirror entry. Use this for 'what code is plasterboard', 'is 17 05 03 hazardous'. This is the published national list, not this organisation's own data.
| query | required | A code or part of one ("17 05"), or words describing the waste ("plasterboard"). |
| hazardous_only | optional | Only hazardous codes. Defaults to false. |
create_customer
Add a customerwrites
Add a customer (a collection site the organisation collects waste from). Answers with what is still needed if anything required is missing, and writes nothing. If a customer of that name and postcode already exists, it returns that one instead of making a second.
| name | required | The company or person the waste belongs to |
| address | required | Where the waste is collected from |
| postcode | required | Postcode of the collection address |
| producer_type | optional | Whether the waste comes from a business or a household. Defaults to business. |
| contact_name | required | Who to ask for on site |
| contact_email | optional | Their email address |
| contact_phone | optional | Their phone number |
| sic_code | optional | The producer's SIC code, if known |
create_receiving_site
Add a receiving sitewrites
Add a receiving site (a tip, transfer station or recycling facility waste is taken to). Answers with what is still needed if anything required is missing, and writes nothing.
| name | required | The site's name |
| address | required | The site address |
| postcode | required | Postcode of the site |
| permit_number | optional | Environmental permit or exemption number |
| contact_name | optional | Who to ask for at the gate |
| contact_email | optional | Their email address |
| contact_phone | optional | Their phone number |
| is_own_site | optional | True only if this is the organisation's own site rather than somebody else's. Defaults to false. |
create_carrier
Add a carrier or brokerwrites
Add a carrier, broker or dealer the organisation works with. Answers with what is still needed if anything required is missing, and writes nothing.
| company_name | required | The carrier or broker's company name |
| registration_number | optional | Their waste carrier registration number, if known |
| contact_name | optional | Who to speak to |
| contact_email | optional | Their email address |
| contact_phone | optional | Their phone number |
| address | optional | Their address |
| postcode | optional | Their postcode |
| notes | optional | Anything worth recording about them |
create_vehicle
Add a vehiclewrites
Add a vehicle to the fleet. Answers with what is still needed if anything required is missing, and writes nothing. A registration already on the fleet returns that vehicle instead of making a second.
| registration | required | The number plate |
| make | optional | Who made it |
| description | optional | Model or description |
| vehicle_type | optional | What sort of vehicle it is, for example skip lorry or tipper |
| mot_expiry | optional | When the MOT runs out (YYYY-MM-DD) |
| tax_expiry | optional | When the tax runs out (YYYY-MM-DD) |
| max_weight_tonnes | optional | Gross weight in tonnes |
create_driver
Add a driverwrites
Add a driver, so they can be given jobs and sign transfer notes in the driver app. Uses one of the plan's driver allowances and refuses if they are all in use. Does not give anybody an office login: that is handed out on the Team page by an owner or an admin. Somebody already on the team gets the driver app added to the record they already have.
| name | required | Their full name |
| required | Their email address, which is where the invite to the driver app goes | |
| phone_number | optional | Their phone number |
| role | optional | What they do, for example HGV driver |
| address | optional | Their home address |
| postcode | optional | Their home postcode |
| licence_expiry | optional | When their licence runs out (YYYY-MM-DD) |
| emergency_contact_name | optional | Who to call in an emergency |
| emergency_contact_phone | optional | That person's phone number |
create_enquiry
Log a collection requestwrites
Log a collection request (an enquiry) from a customer, so the office can quote it. Answers with what is still needed if anything required is missing, and writes nothing.
| company_name | required | The company asking |
| contact_name | required | Who got in touch |
| contact_email | required | Their email address |
| contact_phone | required | Their phone number |
| site_address | required | Where the waste is |
| postcode | optional | Postcode of that address |
| waste_description | required | What the waste is, in their words |
| service_type | optional | What they are asking for, for example a skip or a grab load |
| estimated_weight | optional | Roughly how much, in tonnes |
| preferred_date | optional | When they would like it (YYYY-MM-DD) |
| access_notes | optional | Anything about getting on site |
Writing
The 6 create_ tools add a customer, a receiving site, a carrier or broker, a vehicle, a driver and a collection request. They are how somebody gets data into LoadSnap by describing it in a conversation instead of filling in a form or preparing a spreadsheet.
Nothing is ever half written. A call missing something required writes nothing at all and answers with the list of what is still needed, phrased as questions, so the assistant asks for it and calls again. A call for a record that already exists hands back the record that is there rather than making a second, so running the same request twice cannot leave a duplicate.
A driver added this way uses one of the plan's driver allowances and is refused when they are all in use, exactly as on the Team page, and is matched against the people already on the team so somebody who already works there gets the driver app added to the record they have. Nobody is given an office login: that is a paid seat and a way into the business, and it is handed out on Team by an owner or an admin.
Filing to DEFRA, signing a transfer note, raising an invoice and deleting anything are deliberately not here. They are things a person does in LoadSnap, with their name on them.
Interactive panel
The server publishes an interactive panel as an MCP resource at ui://loadsnap/panel, and every tool points at it. A client that supports the apps extension draws the answer as a panel in the conversation: a table of records, a card for the record just added, or a checklist of what is still needed before something can be saved.
It is one self-contained document with no data of its own, no token and nothing fetched from the network. The client passes the tool's answer into it. Every tool also returns that answer as text, so a client that does not draw panels shows exactly what it always showed.
Limits and formats
Weights are returned in kilograms unless a field name says tonnes. Dates are ISO (YYYY-MM-DD). A search returns the 25 most relevant matches; count_movements reads up to 1,000 rows and reports count_is_capped when it reaches that ceiling, so a capped figure is never presented as an exact total. The same applies to the money owed on find_invoices, which reports totals_are_capped. Records seeded as samples are excluded from every result.
Requirements
A LoadSnap account on the Pro plan or above, and a login that belongs to a LoadSnap organisation. Everyone connecting uses their own login, because the connection is authorised as them.
Questions about the connector? Email info@loadsnap.co.uk, or read the connector overview.