Koskamo

Jet Cab AMS MCP

An official MCP server for Jet Cab AMS that allows AI agents to list available chauffeur services, get exact price quotes, and manage bookings including requests, status checks, changes, and cancellations for Amsterdam and Schiphol transfers.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Jet Cab AMS MCP logo, by Jet Cab AMSVendor evidenceStreamable HTTPNo sign-inEndpoint checked 2026-11-01Operated by Jet Cab AMS
MCP endpoint (Streamable HTTP)
https://www.jetcabams.nl/mcp
Vendor documentation

What you can do with it

  • List available routes, tours, cars, and prices
  • Get exact price quotes for fixed routes or custom rides
  • Request bookings for up to 5 rides simultaneously
  • Check booking status, change details, or cancel reservations

Source and maintenance

Vendor evidenceRegistry 1.0.0

Protocol and capabilities

Server
jetcabams 1.0.0
MCP protocol
2025-06-18
Tools
6 advertised
Resources
1 advertised
Resource templates
0 advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {},
  "resources": {},
  "extensions": {
    "io.modelcontextprotocol/ui": {}
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Jet Cab AMS is a private chauffeur service in Amsterdam (Mercedes E-Class, S-Class, V-Class). Prices are per vehicle in EUR including VAT. Flow: list_services to pick a route, tour or car; get_quote for the exact price; show the customer the total, any deposit and the Terms (https://www.jetcabams.nl/terms.html); only after they approve and accept the Terms, call request_booking with the SAME ride fields, the quoteToken and their name, email and phone. Fixed Schiphol rides: the customer confirms the request with the link Jet Cab AMS emails them, then the driver confirms by email; paid in the car. Tours and custom rides return a checkoutUrl for a 25% Mollie prepayment: give that link to the customer; the booking is final only after they pay. Never invent prices, never accept the Terms for the customer, never pay for them. get_quote results show as a card with a Book button in clients that support it. get_booking_status and cancel_booking need the bookingId from request_booking and the customer's email; cancel only at the customer's explicit request.

Tools

6 advertised

list_services — List Jet Cab AMS services and prices
Advertised by the server during the last successful anonymous check.
Advertised read-only

Fixed-fare Schiphol transfers (route ids, per-car prices), private tours (tour ids, durations, per-car prices), vehicles with passenger and luggage limits, and booking rules. No side effects.

list_services input schema
{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
list_services annotations
{
  "title": "List Jet Cab AMS services and prices",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_quote — Get a price for a ride
Advertised by the server during the last successful anonymous check.
Advertised read-only

Exact price and rule check for one ride (no booking, no email, no payment). Returns the total, any online deposit and a quoteToken valid for 15 minutes. Per type: fixed needs routeId, direction and address; custom needs pickup and dropoff; tour needs tourIds and pickup. Fixed fares only apply inside each route's zone: error address_zone means quote a custom ride instead. Does not check driver availability.

get_quote input schema
{
  "type": "object",
  "required": [
    "type",
    "car",
    "date",
    "time",
    "passengers"
  ],
  "properties": {
    "car": {
      "enum": [
        "eclass",
        "sclass",
        "vclass"
      ],
      "type": "string",
      "description": "E-Class max 4, S-Class max 2, V-Class max 7 passengers."
    },
    "date": {
      "type": "string",
      "format": "date",
      "description": "Local date in Europe/Amsterdam."
    },
    "lang": {
      "enum": [
        "en",
        "nl",
        "de",
        "fr",
        "es",
        "pt",
        "ru",
        "ar",
        "zh-CN"
      ],
      "type": "string"
    },
    "time": {
      "type": "string",
      "pattern": "^\\d{2}:\\d{2}$",
      "description": "Local time in Europe/Amsterdam, between 04:00 and 20:00."
    },
    "type": {
      "enum": [
        "fixed",
        "custom",
        "tour"
      ],
      "type": "string"
    },
    "notes": {
      "type": "string",
      "maxLength": 1000
    },
    "flight": {
      "type": "string",
      "maxLength": 24
    },
    "pickup": {
      "type": "string",
      "maxLength": 180,
      "minLength": 4,
      "description": "Required for custom rides and tours: agreed pickup address or hotel, preserved in review and confirmations."
    },
    "address": {
      "type": "string",
      "maxLength": 180,
      "minLength": 4,
      "description": "Fixed routes only: the non-airport pickup/drop-off address. The fare follows the route zone of the address (postcode first, then town name). An address whose Dutch postcode is in no fixed-route zone is refused with error code address_zone; book it as a custom ride."
    },
    "dropoff": {
      "type": "string",
      "maxLength": 180,
      "minLength": 4,
      "description": "Required for custom rides: drop-off address."
    },
    "routeId": {
      "enum": [
        "ams-spl",
        "noord-spl",
        "zaandam-spl",
        "aveen-spl",
        "haarlem-spl",
        "zandvoort-spl",
        "dh-spl",
        "rtm-spl",
        "almere-spl",
        "almere-buiten-spl",
        "utrecht-spl"
      ],
      "type": "string",
      "description": "Fixed routes only; ids from /data/rates.json. The server reprices to the route the address belongs to."
    },
    "tourIds": {
      "type": "array",
      "items": {
        "enum": [
          "amsterdam-city-tour",
          "countryside-tour",
          "keukenhof-tour",
          "aalsmeer-flower-auction",
          "dutch-water-defence-line",
          "giethoorn-day-trip",
          "south-holland-tour",
          "rotterdam-kinderdijk",
          "kroller-muller",
          "efteling-day-trip",
          "bruges-day-trip",
          "roermond-outlet",
          "mall-of-the-netherlands",
          "batavia-stad",
          "style-outlet-amsterdam"
        ],
        "type": "string"
      },
      "maxItems": 5,
      "minItems": 1,
      "description": "Tours only; ids from /data/tours.json.",
      "uniqueItems": true
    },
    "direction": {
      "enum": [
        "to",
        "from"
      ],
      "type": "string",
      "description": "Fixed routes only: to or from Schiphol."
    },
    "meetGreet": {
      "type": "boolean",
      "description": "Optional €25 arrivals-area name card; only for direction=from."
    },
    "driverName": {
      "type": "string",
      "maxLength": 60
    },
    "passengers": {
      "type": "integer",
      "maximum": 7,
      "minimum": 1
    },
    "returnTrip": {
      "type": "object",
      "required": [
        "date",
        "time"
      ],
      "properties": {
        "date": {
          "type": "string",
          "format": "date"
        },
        "time": {
          "type": "string",
          "pattern": "^\\d{2}:\\d{2}$"
        },
        "flight": {
          "type": "string",
          "maxLength": 24
        },
        "meetGreet": {
          "type": "boolean",
          "default": false
        }
      },
      "description": "Fixed rides only. Books the return leg as well: the opposite direction between the same address and Schiphol, with the same vehicle, passengers and luggage. It is priced as a second ride (plus the name-card fee when meetGreet is set on a return that starts at Schiphol). It must be at least one hour after the first ride, between 04:00 and 20:00, and not on a blocked date. Error codes: retour_type, retour, retour_datetime, retour_hours, retour_date_blocked, retour_order. The booking is stored as two linked bookings: the request id and `<id>-ret`."
    },
    "luggageLarge": {
      "type": "integer",
      "default": 0,
      "maximum": 8,
      "minimum": 0,
      "description": "Large check-in suitcases. E-Class and S-Class take at most 2; more needs the V-Class (error code luggage)."
    },
    "luggageSmall": {
      "type": "integer",
      "default": 0,
      "maximum": 8,
      "minimum": 0,
      "description": "Pieces of hand luggage. E-Class and S-Class take at most 2; more needs the V-Class (error code luggage)."
    },
    "ticketService": {
      "type": "boolean",
      "description": "Tours only: attraction ticket purchase assistance, requires 28 days' notice."
    }
  }
}
get_quote annotations
{
  "title": "Get a price for a ride",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
request_booking — Send a booking request
Advertised by the server during the last successful anonymous check.
Open-world

Books the quoted ride. Call ONLY after the customer has seen the quoted total and deposit and has explicitly approved it and accepted the Terms (https://www.jetcabams.nl/terms.html). Send exactly the same ride fields as the get_quote call plus its unchanged quoteToken and the customer's real contact details. Fixed rides: the customer first gets an email with a Confirm link (valid 24 hours); after the click the driver confirms by email, payment in the car. Tours and custom rides: returns checkoutUrl for the 25% Mollie prepayment, which the customer must open and pay. Repeating the identical call does not create a second booking.

request_booking input schema
{
  "type": "object",
  "required": [
    "type",
    "car",
    "date",
    "time",
    "passengers",
    "quoteToken",
    "name",
    "email",
    "phone",
    "acceptedTerms"
  ],
  "properties": {
    "car": {
      "enum": [
        "eclass",
        "sclass",
        "vclass"
      ],
      "type": "string",
      "description": "E-Class max 4, S-Class max 2, V-Class max 7 passengers."
    },
    "date": {
      "type": "string",
      "format": "date",
      "description": "Local date in Europe/Amsterdam."
    },
    "lang": {
      "enum": [
        "en",
        "nl",
        "de",
        "fr",
        "es",
        "pt",
        "ru",
        "ar",
        "zh-CN"
      ],
      "type": "string"
    },
    "name": {
      "type": "string",
      "maxLength": 100,
      "minLength": 2
    },
    "time": {
      "type": "string",
      "pattern": "^\\d{2}:\\d{2}$",
      "description": "Local time in Europe/Amsterdam, between 04:00 and 20:00."
    },
    "type": {
      "enum": [
        "fixed",
        "custom",
        "tour"
      ],
      "type": "string"
    },
    "email": {
      "type": "string",
      "format": "email"
    },
    "notes": {
      "type": "string",
      "maxLength": 1000
    },
    "phone": {
      "type": "string",
      "maxLength": 30,
      "minLength": 7,
      "description": "Customer's phone number, with country code (for example +31 6 1234 5678)."
    },
    "flight": {
      "type": "string",
      "maxLength": 24
    },
    "pickup": {
      "type": "string",
      "maxLength": 180,
      "minLength": 4,
      "description": "Required for custom rides and tours: agreed pickup address or hotel, preserved in review and confirmations."
    },
    "address": {
      "type": "string",
      "maxLength": 180,
      "minLength": 4,
      "description": "Fixed routes only: the non-airport pickup/drop-off address. The fare follows the route zone of the address (postcode first, then town name). An address whose Dutch postcode is in no fixed-route zone is refused with error code address_zone; book it as a custom ride."
    },
    "dropoff": {
      "type": "string",
      "maxLength": 180,
      "minLength": 4,
      "description": "Required for custom rides: drop-off address."
    },
    "routeId": {
      "enum": [
        "ams-spl",
        "noord-spl",
        "zaandam-spl",
        "aveen-spl",
        "haarlem-spl",
        "zandvoort-spl",
        "dh-spl",
        "rtm-spl",
        "almere-spl",
        "almere-buiten-spl",
        "utrecht-spl"
      ],
      "type": "string",
      "description": "Fixed routes only; ids from /data/rates.json. The server reprices to the route the address belongs to."
    },
    "tourIds": {
      "type": "array",
      "items": {
        "enum": [
          "amsterdam-city-tour",
          "countryside-tour",
          "keukenhof-tour",
          "aalsmeer-flower-auction",
          "dutch-water-defence-line",
          "giethoorn-day-trip",
          "south-holland-tour",
          "rotterdam-kinderdijk",
          "kroller-muller",
          "efteling-day-trip",
          "bruges-day-trip",
          "roermond-outlet",
          "mall-of-the-netherlands",
          "batavia-stad",
          "style-outlet-amsterdam"
        ],
        "type": "string"
      },
      "maxItems": 5,
      "minItems": 1,
      "description": "Tours only; ids from /data/tours.json.",
      "uniqueItems": true
    },
    "direction": {
      "enum": [
        "to",
        "from"
      ],
      "type": "string",
      "description": "Fixed routes only: to or from Schiphol."
    },
    "meetGreet": {
      "type": "boolean",
      "description": "Optional €25 arrivals-area name card; only for direction=from."
    },
    "driverName": {
      "type": "string",
      "maxLength": 60
    },
    "passengers": {
      "type": "integer",
      "maximum": 7,
      "minimum": 1
    },
    "quoteToken": {
      "type": "string",
      "maxLength": 2048,
      "minLength": 1,
      "description": "Signed token returned by POST /api/quote. Send unchanged only after the customer approves that quote's total and deposit. It binds the normalized journey, vehicle, passengers, options, fare, rules version and 15-minute expiry. HTTP 409 reviewRequired=true means obtain a new quote and renewed customer approval before retrying. Never supply your own price."
    },
    "returnTrip": {
      "type": "object",
      "required": [
        "date",
        "time"
      ],
      "properties": {
        "date": {
          "type": "string",
          "format": "date"
        },
        "time": {
          "type": "string",
          "pattern": "^\\d{2}:\\d{2}$"
        },
        "flight": {
          "type": "string",
          "maxLength": 24
        },
        "meetGreet": {
          "type": "boolean",
          "default": false
        }
      },
      "description": "Fixed rides only. Books the return leg as well: the opposite direction between the same address and Schiphol, with the same vehicle, passengers and luggage. It is priced as a second ride (plus the name-card fee when meetGreet is set on a return that starts at Schiphol). It must be at least one hour after the first ride, between 04:00 and 20:00, and not on a blocked date. Error codes: retour_type, retour, retour_datetime, retour_hours, retour_date_blocked, retour_order. The booking is stored as two linked bookings: the request id and `<id>-ret`."
    },
    "luggageLarge": {
      "type": "integer",
      "default": 0,
      "maximum": 8,
      "minimum": 0,
      "description": "Large check-in suitcases. E-Class and S-Class take at most 2; more needs the V-Class (error code luggage)."
    },
    "luggageSmall": {
      "type": "integer",
      "default": 0,
      "maximum": 8,
      "minimum": 0,
      "description": "Pieces of hand luggage. E-Class and S-Class take at most 2; more needs the V-Class (error code luggage)."
    },
    "acceptedTerms": {
      "type": "boolean",
      "const": true,
      "description": "Must be an explicit act by the customer after reading the Terms & Conditions. Agents must not set this on a customer's behalf without their consent."
    },
    "ticketService": {
      "type": "boolean",
      "description": "Tours only: attraction ticket purchase assistance, requires 28 days' notice."
    },
    "additionalRides": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "type",
          "car",
          "date",
          "time",
          "passengers",
          "quoteToken"
        ],
        "properties": {
          "car": {
            "enum": [
              "eclass",
              "sclass",
              "vclass"
            ],
            "type": "string",
            "description": "E-Class max 4, S-Class max 2, V-Class max 7 passengers."
          },
          "date": {
            "type": "string",
            "format": "date",
            "description": "Local date in Europe/Amsterdam."
          },
          "lang": {
            "enum": [
              "en",
              "nl",
              "de",
              "fr",
              "es",
              "pt",
              "ru",
              "ar",
              "zh-CN"
            ],
            "type": "string"
          },
          "time": {
            "type": "string",
            "pattern": "^\\d{2}:\\d{2}$",
            "description": "Local time in Europe/Amsterdam, between 04:00 and 20:00."
          },
          "type": {
            "enum": [
              "fixed",
              "custom",
              "tour"
            ],
            "type": "string"
          },
          "notes": {
            "type": "string",
            "maxLength": 1000
          },
          "flight": {
            "type": "string",
            "maxLength": 24
          },
          "pickup": {
            "type": "string",
            "maxLength": 180,
            "minLength": 4,
            "description": "Required for custom rides and tours: agreed pickup address or hotel, preserved in review and confirmations."
          },
          "address": {
            "type": "string",
            "maxLength": 180,
            "minLength": 4,
            "description": "Fixed routes only: the non-airport pickup/drop-off address. The fare follows the route zone of the address (postcode first, then town name). An address whose Dutch postcode is in no fixed-route zone is refused with error code address_zone; book it as a custom ride."
          },
          "dropoff": {
            "type": "string",
            "maxLength": 180,
            "minLength": 4,
            "description": "Required for custom rides: drop-off address."
          },
          "routeId": {
            "enum": [
              "ams-spl",
              "noord-spl",
              "zaandam-spl",
              "aveen-spl",
              "haarlem-spl",
              "zandvoort-spl",
              "dh-spl",
              "rtm-spl",
              "almere-spl",
              "almere-buiten-spl",
              "utrecht-spl"
            ],
            "type": "string",
            "description": "Fixed routes only; ids from /data/rates.json. The server reprices to the route the address belongs to."
          },
          "tourIds": {
            "type": "array",
            "items": {
              "enum": [
                "amsterdam-city-tour",
                "countryside-tour",
                "keukenhof-tour",
                "aalsmeer-flower-auction",
                "dutch-water-defence-line",
                "giethoorn-day-trip",
                "south-holland-tour",
                "rotterdam-kinderdijk",
                "kroller-muller",
                "efteling-day-trip",
                "bruges-day-trip",
                "roermond-outlet",
                "mall-of-the-netherlands",
                "batavia-stad",
                "style-outlet-amsterdam"
              ],
              "type": "string"
            },
            "maxItems": 5,
            "minItems": 1,
            "description": "Tours only; ids from /data/tours.json.",
            "uniqueItems": true
          },
          "direction": {
            "enum": [
              "to",
              "from"
            ],
            "type": "string",
            "description": "Fixed routes only: to or from Schiphol."
          },
          "meetGreet": {
            "type": "boolean",
            "description": "Optional €25 arrivals-area name card; only for direction=from."
          },
          "driverName": {
            "type": "string",
            "maxLength": 60
          },
          "passengers": {
            "type": "integer",
            "maximum": 7,
            "minimum": 1
          },
          "quoteToken": {
            "type": "string",
            "maxLength": 2048,
            "minLength": 1,
            "description": "Signed token returned by POST /api/quote. Send unchanged only after the customer approves that quote's total and deposit. It binds the normalized journey, vehicle, passengers, options, fare, rules version and 15-minute expiry. HTTP 409 reviewRequired=true means obtain a new quote and renewed customer approval before retrying. Never supply your own price."
          },
          "returnTrip": {
            "type": "object",
            "required": [
              "date",
              "time"
            ],
            "properties": {
              "date": {
                "type": "string",
                "format": "date"
              },
              "time": {
                "type": "string",
                "pattern": "^\\d{2}:\\d{2}$"
              },
              "flight": {
                "type": "string",
                "maxLength": 24
              },
              "meetGreet": {
                "type": "boolean",
                "default": false
              }
            },
            "description": "Fixed rides only. Books the return leg as well: the opposite direction between the same address and Schiphol, with the same vehicle, passengers and luggage. It is priced as a second ride (plus the name-card fee when meetGreet is set on a return that starts at Schiphol). It must be at least one hour after the first ride, between 04:00 and 20:00, and not on a blocked date. Error codes: retour_type, retour, retour_datetime, retour_hours, retour_date_blocked, retour_order. The booking is stored as two linked bookings: the request id and `<id>-ret`."
          },
          "luggageLarge": {
            "type": "integer",
            "default": 0,
            "maximum": 8,
            "minimum": 0,
            "description": "Large check-in suitcases. E-Class and S-Class take at most 2; more needs the V-Class (error code luggage)."
          },
          "luggageSmall": {
            "type": "integer",
            "default": 0,
            "maximum": 8,
            "minimum": 0,
            "description": "Pieces of hand luggage. E-Class and S-Class take at most 2; more needs the V-Class (error code luggage)."
          },
          "ticketService": {
            "type": "boolean",
            "description": "Tours only: attraction ticket purchase assistance, requires 28 days' notice."
          }
        }
      },
      "maxItems": 4,
      "description": "Optional: more rides in the same request (up to 5 in total), each with its own ride fields and the quoteToken of its own get_quote call. Tours and custom rides in the request share one 25% prepayment link; fixed rides stay pay-in-car requests."
    }
  }
}
request_booking annotations
{
  "title": "Send a booking request",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
get_booking_status — Check a booking's status
Advertised by the server during the last successful anonymous check.
Advertised read-only

Where a booking request stands: waiting for the customer's email confirmation, waiting for the driver, payment pending (with the payment link), confirmed, completed or cancelled. Needs the bookingId from request_booking and the customer's email.

get_booking_status input schema
{
  "type": "object",
  "required": [
    "bookingId",
    "email"
  ],
  "properties": {
    "email": {
      "type": "string",
      "format": "email",
      "description": "The customer's email address used for the booking (proves it is their booking)."
    },
    "bookingId": {
      "type": "string",
      "pattern": "^[A-Za-z0-9_-]{8,80}$",
      "description": "The bookingId returned by request_booking."
    }
  }
}
get_booking_status annotations
{
  "title": "Check a booking's status",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
change_booking — Change a booking
Advertised by the server during the last successful anonymous check.
Advertised destructive

Changes an existing booking at the customer's request (date, time, address, pickup, drop-off, passengers, luggage, car, flight, notes). First call get_quote with the complete changed ride and get the customer's approval of the new price, then send the same ride fields with that quoteToken plus the bookingId and the customer's email. Requests not yet confirmed by the driver are updated at once (a request still waiting for the email confirmation is re-sent with a new link; an unpaid tour gets a new payment link). Confirmed or paid bookings are passed to Jet Cab AMS as a change request, which they confirm by email. The ride type (transfer, custom ride, tour) cannot change: cancel and book anew instead.

change_booking input schema
{
  "type": "object",
  "required": [
    "bookingId",
    "email",
    "quoteToken",
    "type",
    "car",
    "date",
    "time",
    "passengers"
  ],
  "properties": {
    "car": {
      "enum": [
        "eclass",
        "sclass",
        "vclass"
      ],
      "type": "string",
      "description": "E-Class max 4, S-Class max 2, V-Class max 7 passengers."
    },
    "date": {
      "type": "string",
      "format": "date",
      "description": "Local date in Europe/Amsterdam."
    },
    "lang": {
      "enum": [
        "en",
        "nl",
        "de",
        "fr",
        "es",
        "pt",
        "ru",
        "ar",
        "zh-CN"
      ],
      "type": "string"
    },
    "time": {
      "type": "string",
      "pattern": "^\\d{2}:\\d{2}$",
      "description": "Local time in Europe/Amsterdam, between 04:00 and 20:00."
    },
    "type": {
      "enum": [
        "fixed",
        "custom",
        "tour"
      ],
      "type": "string"
    },
    "email": {
      "type": "string",
      "format": "email",
      "description": "The customer's email address used for the booking (proves it is their booking)."
    },
    "notes": {
      "type": "string",
      "maxLength": 1000
    },
    "flight": {
      "type": "string",
      "maxLength": 24
    },
    "pickup": {
      "type": "string",
      "maxLength": 180,
      "minLength": 4,
      "description": "Required for custom rides and tours: agreed pickup address or hotel, preserved in review and confirmations."
    },
    "address": {
      "type": "string",
      "maxLength": 180,
      "minLength": 4,
      "description": "Fixed routes only: the non-airport pickup/drop-off address. The fare follows the route zone of the address (postcode first, then town name). An address whose Dutch postcode is in no fixed-route zone is refused with error code address_zone; book it as a custom ride."
    },
    "dropoff": {
      "type": "string",
      "maxLength": 180,
      "minLength": 4,
      "description": "Required for custom rides: drop-off address."
    },
    "routeId": {
      "enum": [
        "ams-spl",
        "noord-spl",
        "zaandam-spl",
        "aveen-spl",
        "haarlem-spl",
        "zandvoort-spl",
        "dh-spl",
        "rtm-spl",
        "almere-spl",
        "almere-buiten-spl",
        "utrecht-spl"
      ],
      "type": "string",
      "description": "Fixed routes only; ids from /data/rates.json. The server reprices to the route the address belongs to."
    },
    "tourIds": {
      "type": "array",
      "items": {
        "enum": [
          "amsterdam-city-tour",
          "countryside-tour",
          "keukenhof-tour",
          "aalsmeer-flower-auction",
          "dutch-water-defence-line",
          "giethoorn-day-trip",
          "south-holland-tour",
          "rotterdam-kinderdijk",
          "kroller-muller",
          "efteling-day-trip",
          "bruges-day-trip",
          "roermond-outlet",
          "mall-of-the-netherlands",
          "batavia-stad",
          "style-outlet-amsterdam"
        ],
        "type": "string"
      },
      "maxItems": 5,
      "minItems": 1,
      "description": "Tours only; ids from /data/tours.json.",
      "uniqueItems": true
    },
    "bookingId": {
      "type": "string",
      "pattern": "^[A-Za-z0-9_-]{8,80}$",
      "description": "The bookingId returned by request_booking."
    },
    "direction": {
      "enum": [
        "to",
        "from"
      ],
      "type": "string",
      "description": "Fixed routes only: to or from Schiphol."
    },
    "meetGreet": {
      "type": "boolean",
      "description": "Optional €25 arrivals-area name card; only for direction=from."
    },
    "driverName": {
      "type": "string",
      "maxLength": 60
    },
    "passengers": {
      "type": "integer",
      "maximum": 7,
      "minimum": 1
    },
    "quoteToken": {
      "type": "string",
      "maxLength": 2048,
      "minLength": 1,
      "description": "Signed token returned by POST /api/quote. Send unchanged only after the customer approves that quote's total and deposit. It binds the normalized journey, vehicle, passengers, options, fare, rules version and 15-minute expiry. HTTP 409 reviewRequired=true means obtain a new quote and renewed customer approval before retrying. Never supply your own price."
    },
    "returnTrip": {
      "type": "object",
      "required": [
        "date",
        "time"
      ],
      "properties": {
        "date": {
          "type": "string",
          "format": "date"
        },
        "time": {
          "type": "string",
          "pattern": "^\\d{2}:\\d{2}$"
        },
        "flight": {
          "type": "string",
          "maxLength": 24
        },
        "meetGreet": {
          "type": "boolean",
          "default": false
        }
      },
      "description": "Fixed rides only. Books the return leg as well: the opposite direction between the same address and Schiphol, with the same vehicle, passengers and luggage. It is priced as a second ride (plus the name-card fee when meetGreet is set on a return that starts at Schiphol). It must be at least one hour after the first ride, between 04:00 and 20:00, and not on a blocked date. Error codes: retour_type, retour, retour_datetime, retour_hours, retour_date_blocked, retour_order. The booking is stored as two linked bookings: the request id and `<id>-ret`."
    },
    "luggageLarge": {
      "type": "integer",
      "default": 0,
      "maximum": 8,
      "minimum": 0,
      "description": "Large check-in suitcases. E-Class and S-Class take at most 2; more needs the V-Class (error code luggage)."
    },
    "luggageSmall": {
      "type": "integer",
      "default": 0,
      "maximum": 8,
      "minimum": 0,
      "description": "Pieces of hand luggage. E-Class and S-Class take at most 2; more needs the V-Class (error code luggage)."
    },
    "ticketService": {
      "type": "boolean",
      "description": "Tours only: attraction ticket purchase assistance, requires 28 days' notice."
    }
  }
}
change_booking annotations
{
  "title": "Change a booking",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": true
}
cancel_booking — Cancel a booking
Advertised by the server during the last successful anonymous check.
Advertised destructive

Cancels a booking at the customer's explicit request. Requests not yet confirmed by the driver and unpaid tours are cancelled at once (the customer gets an email). Confirmed or paid bookings are passed to the business as a cancellation request, which it handles under the Terms (free until 24 hours before transfers, 48 hours before tours). Needs the bookingId and the customer's email. Ask the customer to confirm before calling.

cancel_booking input schema
{
  "type": "object",
  "required": [
    "bookingId",
    "email"
  ],
  "properties": {
    "email": {
      "type": "string",
      "format": "email",
      "description": "The customer's email address used for the booking (proves it is their booking)."
    },
    "reason": {
      "type": "string",
      "maxLength": 300,
      "description": "Optional reason from the customer."
    },
    "bookingId": {
      "type": "string",
      "pattern": "^[A-Za-z0-9_-]{8,80}$",
      "description": "The bookingId returned by request_booking."
    }
  }
}
cancel_booking annotations
{
  "title": "Cancel a booking",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": true
}

Prompts

Not advertised

No prompt definitions available.

Resources

1 advertised

quote-card — Jet Cab AMS quote card

Advertised by the server during the last successful anonymous check.

quote-card URI
ui://jetcabams/quote-card-v1.html

MIME type: text/html;profile=mcp-app

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
686 ms
95th percentile latency
686 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 686 ms · metadata changed · 6 tool(s), 1 resource(s), 0 resource template(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http jet-cab-ams-mcp https://www.jetcabams.nl/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add jet-cab-ams-mcp --url https://www.jetcabams.nl/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable jet-cab-ams-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "jet-cab-ams-mcp": {
      "url": "https://www.jetcabams.nl/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "jet-cab-ams-mcp": {
      "type": "streamableHttp",
      "url": "https://www.jetcabams.nl/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start jet-cab-ams-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "jet-cab-ams-mcp": {
      "type": "http",
      "url": "https://www.jetcabams.nl/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http jet-cab-ams-mcp https://www.jetcabams.nl/mcp

Claude Desktop

Merge this into claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\), then restart Claude Desktop.
Claude Desktop configuration
{
  "mcpServers": {
    "jet-cab-ams-mcp": {
      "url": "https://www.jetcabams.nl/mcp"
    }
  }
}

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "jet-cab-ams-mcp": {
      "serverUrl": "https://www.jetcabams.nl/mcp"
    }
  }
}

Let your agent find its tools

Find servers like Jet Cab AMS MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.

Do you run Jet Cab AMS MCP?

Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.

Claim this listing