Skip to main content
Glama
dragosh29

Pitchup.com MCP server

by dragosh29

Pitchup.com MCP server

An MCP server that lets Claude, ChatGPT and other MCP clients work with a campsite's Pitchup.com supplier account: campsites, pitch types, pitches, charge types, prices and stay rules, allocation, extras and bookings, and (when enabled) setting allocation, prices and charge types. It is built from Pitchup's public API Integration Guide, which is published as one OpenAPI 3.0.3 document (docs.pitchup.com/api/pitchup-api-openapi.yaml, 24 operations, 14 schemas, with the whole guide in its description).

Once it's connected, a site owner or manager can ask things like:

  • "Who's arriving on Saturday, how many people and dogs, and does anyone have special requests?"

  • "What bookings came in or changed since yesterday morning?"

  • "What's the nightly price for electric pitches in August, and which days are closed to arrivals?"

  • "Is there allocation for the bell tent from 14 to 18 July?"

  • With writes enabled: "Set max allocation to 3 for electric pitches for all of August, and put weekend prices up to £28."

Tools

Tool

What it does

API calls

api_root

The resources the key can reach, plus the environment and API version the server is using. A quick key check.

GET /rest/api/

list_campsites

Campsites: slug, name, state, currency, categories, pitch type IDs, availability.

GET /rest/api/campsite/

get_campsite

One campsite: languages, child and infant ages, arrival and departure times, opening dates, rating, notices and policies.

GET /rest/api/campsite/{slug}/

list_pitch_types

Pitch types with capacity, persons included, pricing method, pitch count, lead price, facilities, charge type and pitch IDs. Optional campsite filter, applied by this server.

GET /rest/api/pitchtype/ (documented in the guide's "Pitch type" section, not in the spec's paths)

get_pitch_type

One pitch type. An answer that does not carry the requested ID is treated as not found.

GET /rest/api/pitchtype/{pk}/

list_pitches

Pitches (units): pitch type, name, bookable by Pitchup, priority, your external ID, calendar sync status. Filters: external_id (API), pitch type (this server).

GET /rest/api/pitch/

list_charge_types

Charge types (tariffs) with pitch type, active flag and status. Optional pitch type filter, applied by this server.

GET /rest/api/chargetype/

get_charge_type

One charge type.

GET /rest/api/chargetype/{chargetype_id}/

get_pricing

Prices and stay rules from arrival days: pitch, adult, child and infant prices, pricing period, minimum and maximum stay, closed to arrival or departure, status, pitches sold and left. Filters: date, after, before (API); charge type or pitch type (this server). Read-only: Pitchup's POST .../pricing/ endpoint sets prices and is used only by set_pricing.

GET /rest/api/arrival/, and GET /rest/api/pitchtype/{pk}/ for the pitch type filter

list_bookings

Bookings with dates, status, lead guest name, party size, pitch, unit, extras, special requests and amounts. Every documented filter: after, before, modified_after, modified_before, arrive, depart and their __gt, __gte, __lt, __lte forms, status (sent as its documented numeric key), first_name, last_name, campsite, pitch, external_id.

GET /rest/api/booking/

list_arrivals

Who arrives on one date: confirmed and reserved bookings by default (others are counted; the status is compared case-insensitively), sorted by pitch type and name, with party totals. The dog total only counts bookings that carry a dog count, and is null with a note when none does (see Status).

GET /rest/api/booking/?arrive=…

list_allocations

Allocation days: max allocation and pitches left to sell per date and pitch type. Filters: date, after, before (sent to the API; named in the guide's general filtering section, not in its allocation section, so unconfirmed for allocation days); pitch type (this server).

GET /rest/api/allocation/

check_availability

For one pitch type and a stay, the allocation of every night (nights without an allocation day and nights with nothing left are named) and the arrival days on the arrival date for that pitch type's charge types. It does not reproduce Pitchup's pitch assignment or price calculation.

GET /rest/api/pitchtype/{pk}/, /allocation/, /arrival/

list_extras

Extras with price, pricing type and period, maximum quantity, compulsory flag and charge types; optionally the dated prices of variable-priced extras.

GET /rest/api/extra/, /extraprice/

set_allocation

Sets max_allocation for one pitch type on up to 90 dates (the documented limit), overwriting existing allocation days. Reads the pitch type first and uses its own url in the body; nothing is sent unless that record carries the requested ID and its url ends in /pitchtype/{pk}/. Writes only.

GET /rest/api/pitchtype/{pk}/, POST /rest/api/allocation/

set_pitch_type_allocation

Sets either max_allocation or allocation for one pitch type from start to end, as a Pitchup background job; returns its task_id. Writes only.

POST /rest/api/pitchtype/{pk}/allocation/

set_pricing

Updates prices and stay rules of one charge type from start to end, optionally on some weekdays only; only the fields given change, as documented. Background job; returns its task_id. Writes only.

POST /rest/api/chargetype/{chargetype_id}/pricing/

update_charge_type

Renames a charge type, changes its internal description or switches its pricing on or off. Reads the charge type first and sends it back whole, because the documented update is a PUT. Writes only.

GET and PUT /rest/api/chargetype/{chargetype_id}/

Not covered on purpose: every DELETE (charge types, bookings, pitches, webhooks), creating or amending bookings and Reserved bookings, creating pitches and charge types, POST /rest/api/arrival/ (single arrival days; set_pricing covers ranges), PATCH /rest/api/extra/, webhooks, and the currency and language lists.

Related MCP server: Amiqus MCP server

Setup

Requires Node 18 or later.

npm install
npm run build

You need an API key: in the Pitchup Manager Portal, open My details and copy the key from the API key section. Sandbox and Live keys are different, and the sandbox needs its own sign-up at www.sandbox.pitchup.com/supplier2/signup/. The key is sent as Authorization: Token <key>; a key pasted with its Token prefix is accepted and the prefix dropped.

Claude Desktop: add this to claude_desktop_config.json:

{
  "mcpServers": {
    "pitchup": {
      "command": "node",
      "args": ["/absolute/path/to/pitchup-mcp/dist/index.js"],
      "env": { "PITCHUP_API_KEY": "your-sandbox-key", "PITCHUP_ENV": "sandbox" }
    }
  }
}

Claude Code:

claude mcp add pitchup -e PITCHUP_API_KEY=your-sandbox-key -e PITCHUP_ENV=sandbox -- node /absolute/path/to/pitchup-mcp/dist/index.js

Variable

Required

Meaning

PITCHUP_API_KEY

yes

Your API key from My details, sent as Authorization: Token <key>.

PITCHUP_ENV

no

sandbox (default, https://www.sandbox.pitchup.com) or live (https://www.pitchup.com), the two servers in the spec. Anything else stops the server at start-up.

PITCHUP_API_VERSION

no

The API version sent in the Accept header, as the guide recommends. Defaults to 2023-08-25, the newest dated version the guide lists; prerelease or another dated version can be set.

PITCHUP_ALLOW_WRITES

no

true to register set_allocation, set_pitch_type_allocation, set_pricing and update_charge_type. Off by default.

PITCHUP_BASE_URL

no

Overrides the host (the server adds /rest/api/). Used by the tests. Must not contain a username or password.

Safety defaults

  • Read-only unless PITCHUP_ALLOW_WRITES=true. Read tools carry the MCP readOnlyHint annotation. The four write tools are marked destructiveHint: true (each overwrites existing allocation days, prices or charge type fields; setting allocation to 0 stops sales on those dates) and idempotentHint: true. Nothing is ever deleted: the server has no tool that sends DELETE or PATCH, and the test suite asserts that no such request is made.

  • Sandbox by default. PITCHUP_ENV=live has to be set on purpose.

  • Guests: the lead guest's name, party size, dates, pitch, unit, extras, special requests and amounts are returned by default. The booking's structured contact fields (email, telephone, postal address with street, city, county, postcode and country, names_of_all_party_members, car_registration_number and child_ages) are only returned when a tool is called with include_contact_details=true.

  • Free text is not withheld, only redacted, and the redaction is a heuristic. A campsite can require guests to write their vehicle registration and the names of everyone in the party in the special requests field (the pitch type's require_car_registration and require_party_names, which the spec describes as "included in the special requests field"), and guests can type anything else there. By default, in special requests, the unit description, group name and cancellation reason: email addresses become [email redacted]; phone-number-like sequences become [phone redacted] (international numbers written with + or 00, including +44 (0)7700 …, UK numbers with a bracketed area code, UK-style numbers starting with 0, and 10-digit numbers starting with 7, a UK mobile without its 0; other such digit strings may be redacted too, while IDs, dates and amounts are left alone); upper-case UK postcodes become [postcode redacted]; and current-format UK registrations (AB12 CDE) become [registration redacted]. Names (such as the party names a campsite asks for), street addresses, lower-case postcodes, older or foreign registration formats and dates of birth written in free text are returned as typed. The test suite checks this with a booking on a pitch type that requires both.

  • Payment data is never returned, even on request: the card type and number, charge_id, token_id, stripe_charge_id and the data field of a booking, and the campsite's payment_email, stripe_token, card_types and payment timings. Only the payment status word (pending, paid …) and its due date are passed on. A card number a guest types into free text (13 to 19 digits starting with 1 to 9, grouped or not) is replaced with [card number redacted] in every case, with or without include_contact_details; this is a pattern match, so a card number written in some other way (split by words, say) would not be caught.

  • The campsite's own email, the manager's email, its phone numbers and postal address are only returned with include_contact_details; its notices, useful info and cancellation policy have emails, phone numbers, UK postcodes and UK registrations redacted by default, as above.

  • Pitch calendar links are only returned with include_contact_details: the guide describes the Pitchup feed (pitchup_calendar_feed) as a signed link whose events carry the customer's name, telephone, email and address, and external feed links often carry their own tokens. By default a pitch shows how many external feeds it has and their sync status. Nothing is ever downloaded.

  • Input is checked before any call: pitch type, pitch and charge type IDs must be positive whole numbers (the spec types them as numbers), campsite slugs letters, digits, _ and -, dates real YYYY-MM-DD dates, booking creation and modification filters a date or YYYY-MM-DD HH:MM[:SS] (the guide's datetime example), prices decimal strings such as 10.50. Write tools refuse locally a range that ends before it starts, a repeated date, min_days above max_days, both or neither of allocation and max_allocation, and a pricing request with nothing to change.

  • Pagination follows the next link exactly as Pitchup returns it, as the guide asks, with page_size=100 (the documented maximum) on the first request, until next is null or the tool's max_results is reached; an empty page with a next link is followed too. A list cut short says so with complete: false and a note, whether it was cut by Pitchup's paging limit or by max_results after a filter this server applies itself (pitch type, charge type, campsite). A 200 whose JSON is not a list (no results array) is an error, not an empty list. A next link on another host is not followed, so the API key is only ever sent to the configured Pitchup host.

  • check_availability reads at most 30 pages of allocation days (7.5 seconds of request spacing plus Pitchup's own response time), to stay within the MCP client's default 60-second request timeout in case Pitchup ignores after/before on allocation days; when it stops early it says so and does not claim that a night it did not find has no allocation day.

  • Rate limits: the guide documents none; its best-practice list only says failed requests should be retried "on a reasonable schedule". Requests are spaced 250 ms apart (about four per second, a guess on the polite side). A 429 is retried at most twice for any method, on the assumption that a rate-limited request was not processed, waiting for Retry-After (whole or fractional seconds, or an HTTP-date; 2 s before the second attempt and 4 s before the third when the header is absent). Each wait is capped at 10 seconds; if Pitchup asks for longer, the call gives up at once and says how long to wait.

  • 502, 503 and 504 are retried the same way for GET only; after three failures the error says the service may be unavailable, without the gateway's HTML. A write is never retried after a gateway error, because Pitchup may already have queued the job; the error says to check the current values with the matching list tool first.

  • A 200 whose body is not JSON (a proxy or login page) is an error described by content type and size, never an empty list. A rejected key produces a message naming PITCHUP_API_KEY, the environment in use and the Sandbox/Live difference. Error messages pass on only JSON fields from Pitchup (at most six), with contact details redacted and the API key scrubbed.

Tests

npm test

The test suite (30 checks, about 195 requests to the mock, about 60 seconds):

  1. Validates every fixture record against the schemas in Pitchup's published OpenAPI document with Ajv (strict: false, ajv-formats, plus the spec's decimal format): CampsiteBase; the GET /pitchtype/{pk}/ results item (with all 44 keys it marks required) and PitchTypeBase; the POST /pitch/ response and PitchBase; ChargeTypeBase and the GET /chargetype/{chargetype_id}/ response; the GET /arrival/ results item and ArrivalBase; AllocationBase; ExtraBase; ExtraPriceBase; the POST /booking/ response and BookingBase; and the API root. The spec is downloaded from docs.pitchup.com/api/pitchup-api-openapi.yaml to spec.yaml on the first run. Where a component schema disagrees with the guide's own examples, the disagreeing properties are left out of that one check and the suite proves the list is exact (every error the full schema reports is on a listed property, and every listed property does fail): BookingBase types adults, party, extras, payment_status, price and taxes as strings while the guide's booking example and the POST /booking/ response schema show numbers, objects and arrays (the fixtures follow the example and pass that response schema in full); PitchTypeBase types pitches and lead_price as strings and ground_type as non-nullable, where the GET /pitchtype/{pk}/ schema and example use an array, a number and null; PitchBase types calendar_feeds as a string where the guide and the POST /pitch/ schema use an array.

  2. Starts a local mock of the API under /rest/api/ that serves those fixtures with the documented Authorization: Token <key> check and DRF-style pagination (next/previous links, count on page-number lists, a cursor on bookings as in the guide's booking example, page_size honoured up to 100, booking pages capped at 3 by the mock so the suite pages), 401s with the guide's messages for a missing key, a wrong key and "Token" typed twice, 404 Not found. for unknown IDs, 405 for other methods, and injected 429s, 5xx gateway pages, a 400 and an HTML 200. The mock's list, detail and write responses are validated against the spec's response schemas (list envelopes with next/previous allowed to be null, as the guide's "Pagination" section says), the write request examples from the spec are posted to it, and its error bodies are validated against a schema written by hand (test/schemas.mjs), because the spec documents no error response: the messages are the ones the guide's troubleshooting table quotes, and the suite checks each one appears in the spec.

  3. Starts the built server and drives it over stdio with the official MCP client: 27 checks covering tools/list and the annotations (14 read tools read-only; 4 write tools destructive and idempotent), every read tool, pagination following next across three pages of 100 arrival days and four cursor pages of bookings to a null next, an empty page with a next link followed, a 200 with non-list JSON reported as an error, the booking filters (the names are read from the guide's "Filtering bookings" section and compared with the tool's inputs, and each of the 20 is passed through exactly: status as its numeric key, pitch as the pitch ID, a datetime with a space sent as %20), a list cut short by max_results saying so (unfiltered, and after this server's own pitch type, charge type and campsite filters in all five tools that have one), a GET /pitchtype/{pk}/ answer holding another pitch type (as a list and as an object) refused by get_pitch_type, get_pricing, check_availability and set_allocation with no request after it, and set_allocation refusing a record whose url points at another pitch type, requests within one tool call spaced at least 240 ms apart, the date/after/before filters on arrival and allocation days, the external_id filter on pitches, the spec's list-shaped GET /pitchtype/{pk}/ answer and a plain object, redaction of guest and campsite contact details and calendar links by default and their return on request (including phone numbers written (01632) 960555, +44 (0)7700 …, 0044 … and 7700900123 in free text), a booking on a pitch type that requires the registration and party names in special requests (registration, postcode, card number and mobile redacted by default, names and street returned as typed, the card number redacted even on request), card and payment fields never returned in either case, list_arrivals filtering and totals (a Confirmed status counted as confirmed, a booking without party.dogs not counted as 0 dogs, and a null dog total when no booking has one), check_availability naming a night without an allocation day and a night with nothing left, refusing 91 nights and accepting 90, stopping after 30 pages of allocation days and then reporting the result as partial, list_extras capping the variable prices at max_results, the write gate with the variable unset and false, every write body validated against the spec's request schema (POST /allocation/ as one object and as a list, POST /pitchtype/{pk}/allocation/ with max_allocation and with allocation, POST .../pricing/ against its request schema and ChargeTypePricingBase, the whole-record PUT /chargetype/{id}/), local refusals before any call (reversed ranges, a repeated date, min_days above max_days, both or neither allocation field, nothing to change, a price that is not a decimal string), bad IDs and dates rejected before any call, the 404 and 401 messages (a 401 sent once, not retried), a 400 passed on redacted, an error body that echoes the key passed on with the key scrubbed and at most six messages, the 429 retry waiting for Retry-After in the whole-seconds, fractional-seconds and HTTP-date forms and 2 s then 4 s when it is absent, giving up after three attempts and at once above the cap, a 429 on a write retried once, a 502 retried for GET and a 503 on a write not retried, a GET failing three times reported without the HTML, a non-JSON 200 reported as an error without quoting it, a next link on another host not followed, a key pasted with Token sent once, and that every request carried Authorization: Token <key>, Accept: application/json; version=2023-08-25 and a documented method and path (the spec's paths plus GET /rest/api/pitchtype/, which the suite checks is written in the guide). One more check reads the environment rules (sandbox default, live, bad values refused) from the built dist/config.js without any network call.

The fixtures avoid null in fields the spec does not mark nullable, although the guide's examples show null in several of them (external_id, arrival_time, cancelled_at, name and notes on pitches, many campsite fields); the server treats null, an empty string and the string "null" the same way.

Status

This is a working prototype. It has not yet been run against the live API or the sandbox, because it was built without a Pitchup account. Everything below is taken from the published guide and should be confirmed on a sandbox account (the sandbox sign-up is self-serve; test bookings need Pitchup to activate the listing):

  • The error responses: the status codes and bodies for a missing or wrong key (the mock answers 401 {"detail": "Invalid token."}), for an unknown ID (404 Not found.), for validation errors (the 400 body shape is not documented; the server reads any JSON strings in it) and for rate limiting (no 429 is documented at all).

  • The API version: that Accept: application/json; version=2023-08-25 is honoured, and which field names and status values come back under it (the guide's booking example shows "status": "paid", which version 2019-01-21 says became confirmed).

  • GET /rest/api/pitchtype/: it is documented in the guide's text and the API root's example, not in the spec's paths. Whether it accepts a campsite filter (the guide says "optionally filtered by campsite" without naming the parameter; this server filters by the campsite link itself).

  • GET /rest/api/pitchtype/{pk}/: the spec documents a paginated list as its answer (and whether that list can hold other pitch types is not said); the server takes the record with the requested ID from results, or accepts a plain object with that ID, and treats an answer without that ID as not found.

  • Pagination: that page_size up to 100 is honoured on every list, that next links point to the same host the request went to (on the sandbox, the sandbox host; the guide's examples all use www.pitchup.com), which lists use cursors and which page numbers, and whether the API root answers an object (spec schema) or a one-element array (guide example); both are handled.

  • Filter semantics: whether after and before on arrival and allocation days compare the date and include it (check_availability asks for one day more on each side and picks the nights itself, so either reading works); whether allocation days accept date, after and before at all (the guide documents them for arrival days and names them in its general filtering section, but its allocation section lists no filters); that booking after/before compare the creation date, as the guide says, whether they include the given time, and that they accept YYYY-MM-DD HH:MM:SS; that status takes the numeric key (the guide's example is status=3) and pitch the pitch ID; that first_name/last_name match "containing" case-insensitively.

  • Booking status spelling: the status values list and the 2019-01-21 changelog write confirmed, the booking response table's example value is "Confirmed"; list_arrivals compares case-insensitively, so either works, and shows the status as sent.

  • Dogs: the guide lists dogs in party under "What's new in version prerelease", and this server pins 2023-08-25 by default, so the booking API may send no dog count at all. list_arrivals then reports the number of dogs as unknown (null, or a total of the bookings that do carry one, with a note) rather than 0. Whether party.dogs comes back under 2023-08-25 is unconfirmed; PITCHUP_API_VERSION=prerelease should include it.

  • Booking field shapes: party, payment_status, extras and taxes as objects and arrays, as in the guide's example and the POST /booking/ schema rather than BookingBase. The shape of an item in extras is not shown anywhere (the example list is empty; the response table names extra, extra price and quantity); the server reads extra or name, quantity and price, extra price or extra_price.

  • The schema disagreements listed under Tests (BookingBase, PitchTypeBase, PitchBase), the ExtraBase status enum (active, deleted, disabled) against the guide's example value inactive, and which fields are really nullable.

  • Writes, all untested on a real account: that POST /rest/api/allocation/ accepts the pitch type's own url as pitchtype and a JSON list of up to 90 days, and what it answers for a list (the guide's example response is a paginated list; the server accepts a list, a paginated list or one object); that POST /pitchtype/{pk}/allocation/ accepts max_allocation (documented in the guide's text and response table, not in the request schema); that POST .../pricing/ takes is_soft_close and closed_to_departure as JSON booleans and weekdays as integers (the guide's examples quote them as strings, the spec's example quotes weekdays as strings); that the task_id jobs apply as described (a job's result can only be queried in the prerelease version); and that PUT /chargetype/{id}/ accepts name, description, pitchtype and is_active alone, and what it does to status when is_active changes.

  • Past dates: the guide says updates to arrival and allocation days in the past are refused, using Europe/London time; the server does not check this itself.

  • How many requests per second the API tolerates; nothing is documented, so the 250 ms spacing is a guess.

Going to production

This version runs locally over stdio, with the site owner's own API key. For site owners to connect from claude.ai or ChatGPT without handling keys, the next step is a remote server (Streamable HTTP) behind OAuth, hosted by Pitchup, and then a listing in the Claude and ChatGPT connector directories. A production version, tested on a sandbox site with an activated listing, would also cover the booking amendment and Reserved-booking endpoints, the task_id status check once it leaves prerelease, and webhooks for new bookings and cancellations.

Licence

MIT. Built by Alexandru Dragoș (alexandru.dragos96@gmail.com) with an AI agent (Claude) working under his direction.

Available Tools

14 tools
api_rootAPI rootA
Read-only

The resources this API key can reach (GET /rest/api/), plus which Pitchup environment and API version this server is using. A quick way to check the key works.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so safety is covered. The description adds real value beyond them: it discloses the response contents (reachable resources, environment, API version) and that the call doubles as a credential validity check, implying auth failure behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, no filler, with the primary payload (what the endpoint returns) front-loaded ahead of the secondary use case.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only root endpoint with no output schema, the description covers what comes back and why to call it. It could say slightly more about error/status behavior when a key is invalid, but nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; the schema is empty and fully consistent with the description. Baseline of 4 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (returns/reveals) and resource set: the resources the API key can reach, plus the environment and API version. It is clearly distinguishable from every sibling, which are all domain list/get tools (campsites, bookings, pricing).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"A quick way to check the key works" gives a concrete use case, so the agent knows when to reach for it rather than a domain tool. It stops short of naming alternatives or when-not-to-use conditions, but the context is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_availabilityCheck allocation for a stayA
Read-only

For one pitch type and a stay (arrive to depart), the allocation of every night and the arrival-day rules on the arrival date for that pitch type's charge types. The guide says a stay is bookable when every night has allocation, a pitch is free for the whole stay and prices cover the period: this tool checks the first and shows the arrival-date rules, but does not reproduce Pitchup's pitch assignment or price calculation.

ParametersJSON Schema
NameRequiredDescriptionDefault
arriveYesArrival date
departYesDeparture date (the last night is the day before)
pitch_type_idYesPitch type ID (a positive whole number)

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already supply readOnlyHint and openWorldHint, so the safety profile is covered. The description adds real value beyond that by disclosing a behavioral boundary: it does not reproduce Pitchup's pitch assignment or price calculation. It still says nothing about the shape of the returned allocation data or how absence of allocation is signalled.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence is a fragment with no main verb, so the reader must infer the action, and the second is a long clause-chained sentence. Both carry useful information, but front-loading is weak and the phrasing is denser than it needs to be.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description must carry the return-value burden, and it does indicate the two things returned: per-night allocation and arrival-date rules. It leaves the ambiguity of how 'no allocation' is represented unresolved, which is the main gap for a check-style tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and all three parameters are documented, including the subtle 'last night is the day before' departure convention. The description restates the stay as '(arrive to depart)' and the single-pitch-type scope, but adds no syntax, date-format, or ID-lookup guidance beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description identifies a specific resource (nightly allocation plus arrival-day rules for one pitch type over a stay) and implicitly distinguishes itself from get_pricing and list_pitches by saying it does not reproduce pitch assignment or price calculation. The open is a verbless noun phrase rather than a clear verb+resource statement, which costs it the top mark, but the scope is still understandable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It frames the tool against the documented bookability rule ('bookable when every night has allocation, a pitch is free... and prices cover the period') and states it checks only the first of those, explicitly naming what it does not do. That is a clear use boundary, though it never names the sibling tools (e.g. get_pricing, list_pitches) an agent should reach for instead.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_campsiteGet a campsiteA
Read-only

One campsite by slug: state, currency, pitch types, languages, child and infant age limits, arrival and departure times, opening dates, rating, notices and policies. Payment settings are never returned.

ParametersJSON Schema
NameRequiredDescriptionDefault
slugYesCampsite slug (from list_campsites)
include_contact_detailsNoInclude the campsite's email, manager email, phone numbers and postal address, and stop redacting emails, phone numbers, UK postcodes and UK registrations in notices and policies

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so safety is covered. The description adds genuine behavioral context annotations do not carry: the explicit exclusion 'Payment settings are never returned' and a preview of the returned field set (state, currency, times, ratings, notices/policies).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with zero filler; the scope ('one campsite by slug') comes first and the field list second. The field enumeration is dense but every item is substantive information about the result.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully previews the returned shape and flags the payment-settings exclusion, which an agent would otherwise have to discover empirically. It omits any note on invalid-slug behavior or the contact-detail toggle's effect, though the schema covers the latter.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters (including include_contact_details and its redaction implications) are fully documented in the schema. The description's 'by slug' adds nothing beyond that, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb/resource pairing ('One campsite by slug') and enumerates the returned facets, making it immediately distinguishable from sibling list tools like list_campsites and list_pitch_types without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The singular 'One campsite by slug' implies this is the single-item lookup versus list_campsites, but the description never explicitly states when to use it or names an alternative. Usage is inferable only from the noun phrasing and the required slug parameter.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_charge_typeGet a charge typeC
Read-only

One charge type by ID.

ParametersJSON Schema
NameRequiredDescriptionDefault
charge_type_idYesCharge type ID (a positive whole number)

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds nothing beyond that: it doesn't say what happens if the ID doesn't exist, whether the result is cached, or anything about the response.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Extremely short and front-loaded with zero filler, but it is a verbless fragment rather than a complete statement, which slightly limits clarity for no gain in brevity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter getter with no output schema, the description should at least indicate what a charge type represents or what is returned. It provides only the bare lookup intent, leaving the agent to guess the payload.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with charge_type_id documented as 'a positive whole number' including min/max bounds. Baseline 3 applies since the schema fully carries parameter meaning and the description adds none.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The fragment "One charge type by ID" names the resource and the lookup key, and 'by ID' implicitly distinguishes it from the sibling list_charge_types. It is clear but doesn't explicitly say 'retrieve' or name the alternative, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this versus list_charge_types or get_pricing; the agent must infer that a known ID means use this tool. No prerequisites or exclusions are stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_pitch_typeGet a pitch typeA
Read-only

One pitch type by ID, with its charge type and pitch IDs, capacity, pricing method and facilities.

ParametersJSON Schema
NameRequiredDescriptionDefault
pitch_type_idYesPitch type ID (a positive whole number)

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint. The description adds no auth, error, or rate-limit behavior; its field list is primarily output content rather than behavioral disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no wasted words. It states scope and returned fields immediately.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given low complexity, full schema coverage, and read-only annotations, the description is nearly complete. It lists returned fields but omits not-found or error behavior, a minor gap for a simple getter.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single parameter is already documented. The description reinforces the ID key but adds no syntax or format meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description identifies the resource and scoping key ('One pitch type by ID') and enumerates returned data such as charge type, capacity, and facilities. It does not explicitly name list_pitch_types as the plural alternative, so sibling differentiation is implicit rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by 'by ID'; there is no explicit when-to-use or exclusion telling the agent to prefer list_pitch_types when the ID is unknown or to use this only after a listing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_pricingGet prices and stay rulesA
Read-only

Prices and stay rules from arrival days (GET /rest/api/arrival/): for each date and charge type, the pitch price and extra adult, child and infant prices, the pricing period, minimum and maximum stay, closed to arrival or departure, status, and pitches sold and left. The API only returns future arrival days. Filter by date (one day) or after/before, and by charge type or pitch type.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNoOne date (documented `date` filter)
afterNoDocumented `after` filter, sent as given
beforeNoDocumented `before` filter, sent as given
max_resultsNo
pitch_type_idNoOnly the charge types of this pitch type (looked up first, then filtered by this server)
charge_type_idNoOnly this charge type (filtered by this server)

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover readOnlyHint and openWorldHint, so the description carries the rest and delivers real behavioral facts: results are restricted to future arrival days, and two filters are applied server-side after an internal lookup rather than being pushed to the API. It doesn't mention pagination or rate limits, but the added constraints are substantive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose and returned-field list are front-loaded, and the filter behavior follows in a compact final sentence. It is a touch dense in the enumeration of return fields, but every clause carries information and there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates by listing the returned fields in detail, and it covers the significant future-arrival-days limitation and filter semantics. Only minor gaps remain: no mention of result-size/pagination behavior tied to max_results, and no explicit sibling routing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 83%, so the baseline is 3, but the description adds genuine meaning: it clarifies that `date` is a single-day filter versus the range semantics of after/before, and that charge type and pitch type are alternative filter axes. The only untouched parameter is max_results, which the schema covers by default/min/max.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Prices and stay rules from arrival days') and even names the backing endpoint, then enumerates exactly what is returned (pitch price, extra adult/child/infant prices, min/max stay, CTA/CTD, status, pitches sold/left). This is clearly distinguishable from siblings like list_charge_types or check_availability.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives filter usage (filter by one date or after/before, filter by charge type or pitch type) and a key constraint (only future arrival days are returned), which implies when the tool applies. However it never explicitly routes the agent away from alternatives such as check_availability (availability only) or list_charge_types, leaving the when-not case to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_allocationsList allocation daysA
Read-only

Allocation days: for each date and pitch type, the maximum number of pitches Pitchup may sell (max_allocation) and how many are left to sell. A date with no allocation day has no allocation. Filter by date or after/before, and by pitch type.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNoOne date. `date` is named in the guide's general filtering section; not confirmed for allocation days
afterNoSent as `after`, a filter named in the guide's general filtering section; not confirmed for allocation days, and whether the date itself is included is not documented
beforeNoSent as `before`, a filter named in the guide's general filtering section; not confirmed for allocation days, and whether the date itself is included is not documented
max_resultsNo
pitch_type_idNoOnly this pitch type (filtered by this server)

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds real value beyond that by explaining the return content (max_allocation plus remaining count) and the semantics of a missing allocation day, which matters because there is no output schema. It is silent on pagination/result-cap behavior for max_results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences and a short clause; the definition of an allocation day is front-loaded before the filter hints, and there is no padding. Slightly dense in the first sentence but every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with no output schema, the description supplies the record shape and the filtering options, which is most of what an agent needs. The main omission is behavior of the undocumented max_results cap and any ordering/pagination semantics.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 80%, so the baseline is 3. The description restates the date/after/before and pitch_type filters but adds no format or inclusion/exclusion detail beyond the schema, and it never mentions max_results (default 500, max 3000), the one parameter with no schema description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the resource (allocation days) and precisely defines what a record contains: per date and pitch type, the maximum pitches Pitchup may sell (max_allocation) and how many remain. That is a clear verb+resource+scope, though it never explicitly differentiates itself from siblings such as check_availability or list_pitches.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: 'Filter by date or after/before, and by pitch type' tells the agent it can narrow results, and the note that a date with no allocation day has no allocation clarifies the data model. It stops short of stating when to reach for this tool instead of check_availability, or any when-not condition.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_arrivalsWho arrives on a dateA
Read-only

Guests arriving on one date (bookings with that arrival date), with lead guest name, party size, pitch type and pitch, unit, estimated arrival time and special requests, plus totals. By default only confirmed (Pitchup) and reserved (external) bookings are listed; the rest are counted. The dog total only counts bookings that carry a dog count (the guide lists party.dogs as a prerelease addition) and is null when none does. Structured guest contact details only with include_contact_details; special requests are returned with emails, phone numbers, UK postcodes and UK registrations redacted, but names and street addresses in them are not.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateYesArrival date
campsiteNoCampsite slug, if the account has several
include_all_statusesNoAlso list cancelled, declined, abandoned and other non-staying bookings
include_contact_detailsNoInclude the structured guest email, telephone, address, party member names, vehicle registration and children's ages, and stop redacting emails, phone numbers, UK postcodes and UK registrations in free text

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover only read-only/open-world safety, and the description adds substantial behavior: the default status filter and that excluded bookings are merely counted, contact details gated behind include_contact_details, redaction of emails/phones/postcodes/registrations in free text (with the caveat that names and street addresses are not redacted), and the null-when-no-dog-count rule.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core purpose in the first clause, then layers the return fields, defaults, and privacy caveats. Dense but every sentence carries information; slightly long-winded in the redaction sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with no output schema, the description fully documents what comes back, what the defaults exclude, and the conditional/privacy behavior an agent needs before calling it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, and the description still adds semantic value beyond the schema strings: the confirmed/reserved default, the 'counted not listed' consequence of excluding statuses, and the exact redaction behavior tied to include_contact_details.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Guests arriving on one date, bookings with that arrival date') and enumerates the returned fields, so an agent can distinguish it from list_bookings without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the default filtering behavior ('by default only confirmed and reserved bookings are listed') and points to include_all_statuses implicitly, but never names an alternative tool or states when to pick this over list_bookings or check_availability.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_bookingsList bookingsA
Read-only

Bookings (Pitchup bookings and your Reserved external bookings) with dates, status, lead guest name, party size, pitch, unit, extras, special requests and amounts. Every documented filter is available: creation and modification dates, arrival and departure dates (equals, gt, gte, lt, lte), status, first/last name, campsite, pitch, external_id. Guest emails, phones and addresses only with include_contact_details (in free text, emails, phone numbers, UK postcodes and UK registrations are redacted by default; names and street addresses are not); card details never.

ParametersJSON Schema
NameRequiredDescriptionDefault
afterNoCreated after (documented `after`, which filters on the creation date of the booking; whether the given time itself is included is not documented)
pitchNoPitch ID
arriveNoArrival date equals
beforeNoCreated before (documented `before`; whether the given time itself is included is not documented)
departNoDeparture date equals
statusNoBooking status; sent as its documented numeric key (confirmed = 3, reserved = 7, ...)
campsiteNoCampsite slug
last_nameNoLast name contains
arrive__gtNoArrival date after
arrive__ltNoArrival date before
depart__gtNoDeparture date after
depart__ltNoDeparture date before
first_nameNoFirst name contains
arrive__gteNoArrival date on or after
arrive__lteNoArrival date on or before
depart__gteNoDeparture date on or after
depart__lteNoDeparture date on or before
external_idNoYour own reference for the booking
max_resultsNo
modified_afterNoModified after: new bookings, amendments and cancellations (documented `modified_after`)
modified_beforeNoModified before (documented `modified_before`)
include_contact_detailsNoInclude the structured guest email, telephone, postal address, other party members' names, vehicle registration and children's ages, and stop redacting emails, phone numbers, UK postcodes and UK registrations in free text. Without it, special requests are still returned: campsites can ask guests to write the vehicle registration and party names there, and names and street addresses in free text are not redacted

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true and openWorldHint=true, and the description adds material behavior beyond that: default redaction of emails, phones, UK postcodes and UK registrations in free text, what turning include_contact_details on changes, that names and street addresses are never redacted, and that card details are never returned. It omits pagination/rate-limit behavior (max_results default 200, max 2000 is not surfaced), so not a full 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with what a booking record contains, then filters, then the privacy caveat. Two dense sentences with little waste, though the parenthetical filter list and redaction clause make it long; a slightly tighter structure would read better but nothing is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly enumerates the returned fields an agent needs, covers the 22-parameter filter surface at a high level, and discloses the privacy model. Given 0 required parameters and 95% schema coverage, this is sufficient for correct invocation; only max_results behavior is left implicit in the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 95%, so the schema already carries most parameter meaning and baseline 3 applies. The description adds value by grouping the filter families (creation/modification, arrival/departure with equals/gt/gte/lt/lte, status, names, campsite, pitch, external_id) and by explaining the semantic distinction of include_contact_details, which goes beyond the schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb+resource ('Bookings ... with dates, status, lead guest name, party size, pitch, unit, extras, special requests and amounts') and even clarifies the two data sources (Pitchup bookings and your Reserved external bookings). It doesn't explicitly differentiate itself from siblings like list_arrivals or list_allocations, but the content enumeration is strong enough that an agent knows this is the comprehensive booking-listing tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Every documented filter is available' plus the filter list implies this is the tool to use for filtered booking retrieval, but no alternative tool is named and there is no explicit when-not to use it. The include_contact_details guidance is the only conditional advice present. Usage is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_campsitesList campsitesA
Read-only

The campsites on this Pitchup account: slug, name, state (settingup, bookable...), currency, categories, pitch type IDs and availability. The campsite's own email, phone and address only with include_contact_details.

ParametersJSON Schema
NameRequiredDescriptionDefault
max_resultsNo
include_contact_detailsNoInclude the campsite's email, manager email, phone numbers and postal address

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, covering the safety profile. The description goes beyond them by disclosing the shape of the return payload and the important conditional that contact details appear only with include_contact_details. It still omits pagination/limit behavior, but that is minor given the annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences that front-load the returned-field list and then the conditional contact-details rule. Efficient with no filler, though the field enumeration reads as a packed list.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, enumerating returned fields is genuinely useful and largely compensates. The remaining gap is the undocumented max_results/pagination behavior, which an agent needs to call the tool correctly with more than the default 100 results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50%: include_contact_details is documented in the schema and the description restates its effect, adding little. max_results (default 100, max 500) is documented nowhere, so half the parameters carry no semantic guidance. Baseline 3 reflects that the schema does half the work and the description does not compensate for the gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the resource (the campsites on this Pitchup account) and enumerates the fields returned (slug, name, state, currency, categories, pitch type IDs, availability). It is a specific verb+resource, though it does not explicitly contrast itself with the sibling get_campsite or list other list_* tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The scope 'on this Pitchup account' implies when to reach for this tool (listing all campsites on the account), and the conditional note on include_contact_details guides one option. But there is no explicit when-not or named alternative such as get_campsite for a single record.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_charge_typesList charge typesB
Read-only

Charge types (tariffs such as Standard or Weekly) with their pitch type, active flag and status. Prices for each are read with get_pricing.

ParametersJSON Schema
NameRequiredDescriptionDefault
max_resultsNo
pitch_type_idNoOnly charge types of this pitch type (filtered by this server)

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safe-read profile is covered structurally. The description adds value by naming the fields the records carry (pitch type, active flag, status), which partially compensates for the absent output schema, but says nothing about pagination, result caps, or default limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the resource definition and closing with the cross-tool pointer. No filler, no restatement of the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple list tool with no output schema, the description adequately conveys what comes back, but it omits pagination behavior, the existence of max_results/default of 200, and any distinction from get_charge_type. It is minimally sufficient rather than complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 50%: pitch_type_id carries a description in the schema, but max_results (with its default and maximum) is undocumented there. The description contributes no parameter information at all, so it fails to compensate for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the specific resource ('Charge types') and clarifies it with a concrete synonym and examples ('tariffs such as Standard or Weekly'), so an agent knows exactly what is listed. It also enumerates the returned attributes (pitch type, active flag, status), but it does not explicitly differentiate itself from the sibling get_charge_type or list_pitch_types.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The one routing hint is 'Prices for each are read with get_pricing,' which usefully redirects a related need to a sibling tool. However there is no guidance on when to use list_charge_types versus get_charge_type, nor any mention of prerequisites or filtering conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_extrasList extrasB
Read-only

Extras that can be added to a booking (for example a dog, a cot or an extra car): price, pricing type, pricing period, maximum quantity, compulsory flag and linked charge types. Optionally also the dated prices of extras with variable pricing.

ParametersJSON Schema
NameRequiredDescriptionDefault
max_resultsNo
include_variable_pricesNoAlso list dated prices from GET /rest/api/extraprice/

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so safety and scope are covered. The description adds domain specifics (extras = dog, cot, car; fields returned; variable pricing available on request), but says nothing about pagination behavior despite max_results existing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the resource and its examples, then the field list, then the optional add-on. No filler; only the missing pagination note keeps it from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-required-param list tool with no output schema, the description covers what an 'extra' is and what fields come back, but omits pagination behavior for max_results and any ordering or filtering semantics an agent would need to consume results correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

include_variable_prices is documented in the schema itself (50% coverage). The description only paraphrases it ('Optionally also the dated prices of extras with variable pricing') without adding a format, default, or consequence. Baseline 3 given the schema covers half the parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clear verb-implied resource ('list_extras' with a description that enumerates what an extra is and its fields). It reads as the canonical extras catalog, but nothing explicitly distinguishes it from siblings like list_charge_types or get_pricing, which the description references only obliquely via 'linked charge types'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use or when-not-to-use guidance. The optional variable-prices note implies a use case, but the description never tells the agent when to call list_extras versus get_pricing or list_charge_types.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_pitchesList pitchesA
Read-only

Individual pitches (units) with their pitch type, name, whether Pitchup may book them, priority, your external ID and calendar sync status. Optionally only one pitch type, or the pitch with a given external_id. Calendar feed links (the Pitchup feed carries guests' contact details) only with include_contact_details.

ParametersJSON Schema
NameRequiredDescriptionDefault
external_idNoYour own reference for the pitch; passed to the API as the documented external_id filter
max_resultsNo
pitch_type_idNoOnly pitches of this pitch type (filtered by this server)
include_contact_detailsNoInclude the calendar feed links and unredacted notes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, and the description adds real behavioral context on top: sensitive calendar feed links are gated behind include_contact_details and the Pitchup feed carries guests' contact details. It still doesn't note pagination or the max_results ceiling behavior, so it falls short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences that front-load what the tool returns before the optional filters and the data-sensitivity conditional. The enumerated field list is a little packed, but nothing is wasted or repeated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a four-parameter, output-schema-less read tool, the definition covers the returned fields, the filtering options, and the contact-detail gating. An agent has enough to call it correctly; only pagination/max_results semantics are unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 75%, and the description reinforces the two non-obvious filters: external_id selects a single pitch, pitch_type_id narrows by type, and include_contact_details unlocks feed links. Only max_results is left unexplained, and it is self-evident given its name and bounds.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Individual pitches (units)') and enumerates the returned attributes (pitch type, name, bookability, priority, external ID, sync status), which implicitly separates it from siblings like list_pitch_types and get_pitch_type. It never names those siblings explicitly, so a 5 is not warranted.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It describes two optional filtering modes ('only one pitch type, or the pitch with a given external_id') and the conditional on include_contact_details, which implies usage. It gives no explicit when-to-use/when-not guidance or routing between this and sibling list tools such as list_pitch_types or list_campsites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_pitch_typesList pitch typesB
Read-only

Pitch types (for example an electric grass pitch, a bell tent or a static caravan) with capacity, persons included, pricing method, number of pitches, lead price, facilities and the IDs of their charge types and pitches. Optionally only those of one campsite.

ParametersJSON Schema
NameRequiredDescriptionDefault
campsiteNoOnly pitch types of this campsite (slug). Filtered by this server, on the campsite link of each pitch type.
max_resultsNo

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety/scope profile is covered. The description adds that results can be scoped by campsite and that the payload bundles related IDs, but says nothing about pagination, ordering, or result size despite a max_results parameter existing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core subject and packs field-level detail into a single compact sentence with a parenthetical example. The long field enumeration is dense but each item is informative; only minor trimming is possible.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return-shape burden and does so by naming the fields returned, including linked IDs. Combined with annotations for the safety profile, an agent has enough to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50%: the campsite parameter is well documented in the schema (slug pattern, server-side filtering), and the description corroborates the filter behavior. max_results is undocumented in both places, and the description adds no format or semantics beyond what the schema already states, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States the resource (pitch types) and enumerates what each record contains – capacity, persons included, pricing method, pitch count, lead price, facilities, and related charge-type/pitch IDs – with concrete examples (electric grass pitch, bell tent, static caravan). This is far more than a restatement of the name, though it does not explicitly distinguish itself from get_pitch_type or list_pitches.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The only guidance is 'Optionally only those of one campsite', which describes a filter rather than when to choose this tool over get_pitch_type or list_pitches. No exclusions, prerequisites, or alternative selection criteria are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 14 tool updatesv0.1.0
    • First observedapi_root
    • First observedcheck_availability
    • First observedget_campsite
    • First observedget_charge_type
    • First observedget_pitch_type
    • First observedget_pricing
    • First observedlist_allocations
    • First observedlist_arrivals
    • First observedlist_bookings
    • First observedlist_campsites
    • First observedlist_charge_types
    • First observedlist_extras
    • First observedlist_pitch_types
    • First observedlist_pitches

TDQS

A3.7/5.0

Scored across 14 tools

Disambiguation4/5

Each tool targets a fairly distinct resource (campsites, pitch types, pitches, charge types, pricing, bookings, arrivals, allocations, extras). There is mild overlap between list_allocations and check_availability (both concern allocation) and between list_arrivals and list_bookings (arrivals is a filtered view of bookings), but the detailed descriptions clarify the boundaries well enough.

Naming Consistency4/5

Most tools follow a clean get_/list_ + noun pattern (get_campsite, list_pitches, get_pricing, list_bookings). Minor deviations exist: api_root is a bare noun and check_availability uses a different verb, but the set still reads as one coherent convention.

Tool Count5/5

14 tools is well within the ideal range and each maps to a distinct resource or operation in the booking-management domain. No tool appears redundant or padded.

Completeness4/5

The surface covers the full read lifecycle: account/environment, campsites, pitch types, pitches, charge types, pricing, allocations, availability, bookings, arrivals and extras. It appears intentionally read-only (no create/update/delete), which is likely by API design, though agents cannot mutate bookings or campsites. A direct get_booking for a single booking is also absent, but list_bookings largely compensates.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    It enables MCP clients such as Claude and ChatGPT to read an estate agency's Dezrez Rezi CRM data, including properties and their timelines, people, groups, and offers. It is read-only and applies privacy redactions by default.
    10
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables Claude, ChatGPT and other MCP clients to read an Amiqus ID account—clients, onboarding records and steps, check results, templates, case status counts and webhooks—and, when writes are enabled, create records.
    9
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Lets MCP clients such as Claude and ChatGPT read a rota and time-and-attendance account, exposing venues, groups, shifts, absences and absence types, time entries, venue events and staff names through read-only tools that never return pay data.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables Claude, ChatGPT and other MCP clients to read NewZapp account details, campaign reports, open heatmaps, contact groups and contact counts, and to search contacts with personal data withheld by default; when writes are enabled, it can also create and update contacts.
    MIT