WebMCP & MCP API
Three read-only yacht-charter tools over remote MCP, plus an authenticated browser-only reservation hold.
document.modelContext · POST /api/mcp · search → details → quote · browser-only hold
On this page
Overview
Browser WebMCP registers tools on document.modelContext. Remote MCP exposes onlysearch_charters, get_charter_details and quote_charter over Streamable HTTP at POST /api/mcp.
Read tools make no business-state changes; request telemetry is still recorded. Browser book_charter explains how to sign in when the current user is not yet eligible; creating a hold requires a signed-in user with a verified e-mail. After an in-tab confirmation, it creates an unpaid PENDING hold and never charges the customer.
browser: document.modelContext
→ WebMCP adapter
├─ three read-only tools
└─ book_charter (verified account only)
→ confirmation dialog
→ PENDING hold
→ hosted checkout
remote: POST /api/mcp
→ MCP adapter
└─ three read-only tools
shared agent-tools core
├─ availability
├─ price engine
└─ request telemetryImplementation notes
- Initial version: four browser tools called dedicated server actions.
- Protocol review: results were reduced to one JSON value, search output was bounded and browser confirmation was added.
- Current version: browser and remote transports share the validated read core. Consequential booking is deliberately browser-only and protected by an authenticated account boundary.
Every core call rechecks the feature flag and requires a positively identified NaCzarter flagship host. Unknown hosts, lookup failures, admin previews and white-label storefronts fail closed.
Quick start
Browser WebMCP
Open naczarter.pl/en in a compatible browser, then check whether the registration API is available.
Checking this browser
Looking for document.modelContext locally.
Local feature detection only. No network request or reservation is made.
typeof document.modelContext?.registerTool === "function"Remote MCP
Configure https://naczarter.pl/api/mcp as a read-only Streamable HTTP endpoint. It exposes three public read tools and no reservation or payment mutation. Every POST must use Content-Type: application/json.
curl -s https://naczarter.pl/api/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-11-25",
"capabilities": {},
"clientInfo": { "name": "docs-example", "version": "1.0" }
}
}'curl -s https://naczarter.pl/api/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2025-11-25' \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}'curl -s https://naczarter.pl/api/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2025-11-25' \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "search_charters",
"arguments": {
"city": "Giżycko",
"minPeople": 6
}
}
}'tools/list is the runtime contract: it returns required fields, enums, limits, annotations and the exact three-tool remote catalogue. Supported protocol revisions are 2025-11-25 and 2025-06-18. The WebMCP manifest is descriptive, not runtime discovery.
Tools
This is a compact summary rendered from the shared AGENT_TOOL_CONTRACT. Use tools/list for the exact remote inputSchema, including required fields, enums and bounds.
Remote MCP exposes the first three read-only tools only. Browser WebMCP exposes all four tools. Calls to book_charter return an authentication hand-off until the signed-in user's account e-mail has been verified.
Scroll the table horizontally to inspect every column.
| Tool | Input and result | Business effect |
|---|---|---|
search_charters | Find a compact set of suitable yachts. Input: City, dates, category, capacity, maximum daily price and page. Up to six yachts with stable slugs, location, capacity, a starting daily price and range availability. | No business-state changes; request telemetry is recorded. |
get_charter_details | Check whether one yacht fits the trip. Input: A yacht slug returned by search_charters. Model, year, berths, dimensions, engine, port, stay limits and licence or skipper options. | No business-state changes; request telemetry is recorded. |
quote_charter | Obtain the source-of-truth price and availability. Input: Yacht slug, exact dates and an optional one-way return. Online charter price, mandatory on-site fees, total, currency and a server-revalidated acceptedQuote snapshot for the yacht, dates, one-way choice and current terms. | No business-state changes; request telemetry is recorded. |
book_charter | Hold the selected dates pending human payment. Input: Yacht, dates, contact details and explicit acceptance of the linked booking terms. The contact e-mail must match the signed-in account's verified e-mail; the in-tab dialog supplies separate human verification. A provisional reservation and hosted checkout URL, or a precise recovery response. | Creates an unpaid temporary hold; it does not make a payment. |
Browser annotations mark discovery tools read-only and book_charter consequential. Catalogue-backed output is marked untrusted where applicable; server validation remains authoritative.
Browser vs remote
Scroll the table horizontally to compare both transports.
| Boundary | Browser | Remote MCP |
|---|---|---|
| Discovery | Runtime page registration | Client-configured endpoint |
| Entry point | document.modelContext | JSON-RPC over POST |
| Tools | Three reads plus book_charter; an ineligible session receives a sign-in hand-off | search_charters, get_charter_details and quote_charter only |
| Result | One JSON-serialisable value | content plus structuredContent |
| Authentication | Reads are public; booking requires a signed-in account with verified e-mail | None; the transport is read-only |
| Consent | NaCzarter in-tab dialog and human verification before a hold | Not applicable; no mutation is exposed |
| Context | Current locale and browser session | Stateless; search uses pl, quote and details use en, result URLs use pl |
| Payment | Customer opens hosted checkout after the hold | Not available through remote MCP |
Browser booking
book_charter is not available over remote MCP. A compatible browser registers it for discovery, but the server creates a hold only when the current user is signed in to a NaCzarter account with a verified e-mail. Otherwise the tool returns a sign-in hand-off and makes no state change.
- 1. Quote. Call
quote_charterfor the selected yacht, dates and one-way option. It returns online charter price, mandatory on-site fees, currency, terms revision and a server-revalidatedacceptedQuotesnapshot. - 2. Identify. The booking contact e-mail must match the verified e-mail of the signed-in account. The server enforces this again when the hold is created.
- 3. Confirm. NaCzarter opens its own in-tab dialog with the fresh quote, customer details, linked terms and a required consent checkbox. A human-verification proof from that dialog is bound to this booking action and checked by the server. Cancelling, expiry or timing out creates no reservation.
- 4. Revalidate. The server checks the authenticated account, matching contact e-mail, quote snapshot, price and availability, locks the yacht row and repeats the overlap check.
- 5. Hold. A successful call creates an unpaid
PENDINGorder that temporarily holds the selected dates. The tool does not charge or receive payment credentials. - 6. Hand off. The customer opens
checkoutUrland pays personally. If checkout startup fails after the hold exists, the tool returns the authenticated customer's account-page URL. Do not create a second hold for the same dates.
Consent and telemetry
Browser cancellation before confirmation prevents the mutation. A late abort is not a rollback and requires state reconciliation. Booking contact data is stored on the reservation but excluded from the tool-call summary; telemetry includes a salted IP hash and user agent, so it is pseudonymous rather than anonymous. Read calls also emit operational telemetry even though they do not change booking or catalogue state.
Errors & limits
Scroll the table horizontally to inspect recovery actions.
| Code | Meaning | Recovery |
|---|---|---|
NOT_ENABLED | Agent tools are disabled for this host or deployment | Use the standard website; do not retry automatically |
INVALID_ARGUMENT | Malformed or out-of-range input | Correct the fields; do not book |
AUTHENTICATION_REQUIRED | No signed-in NaCzarter account | Sign in before requesting a browser hold |
EMAIL_VERIFICATION_REQUIRED | The signed-in account e-mail is not verified | Verify the account e-mail, then reload the page |
CONTACT_EMAIL_MISMATCH | Booking e-mail differs from the verified account e-mail | Use the account's verified e-mail |
AGREEMENT_REQUIRED | Booking terms were not explicitly accepted | Show the linked terms and obtain explicit consent |
PRICE_CHANGED | Live price, fees or currency differ | Request a fresh quote and confirmation |
RATE_LIMITED | A transport or booking limit was reached | Wait before retrying |
CAPTCHA_FAILED | The in-tab human verification failed or expired | Ask the customer to complete the confirmation again |
SERVICE_UNAVAILABLE | Shared booking abuse protection is temporarily unavailable | Nothing was booked; use the yacht page or try again later |
TOO_MANY_PENDING | The customer already has two unpaid agent holds | Pay or cancel one before creating another hold |
HOLD_LIMIT | The yacht and start date reached the unpaid-hold cap | Choose another date or yacht |
AGENT_HOLDS_SATURATED | The global hourly cap for automated holds was reached | Use the yacht page or try again later |
CHECKOUT_FAILED | The hold exists but checkout startup failed | Do not create another hold; send the customer to the returned account-page URL |
- Experimental API: without compatible browser support, the standard website works and tool registration remains inert.
- Date bounds: date ranges may span at most 31 days and every supplied date must be within 730 days of the request date.
- Quote is not a lock: price or availability can change before the booking transaction.
- Temporary hold: an unpaid agent order becomes eligible for
GHOSTEDafter 90 minutes; cleanup timing is not exact. - Remote transport: stateless and read-only,
application/jsonPOST bodies only, no server-initiated SSE stream, no batches, 32 KB body limit, one request per POST and 60 requests per minute per limiter key. - Descriptor:
/.well-known/webmcp.jsonis informative. Browser runtime registration is authoritative.