Protocol & transport
Most users never touch this layer — MCP clients handle it. This page documents the raw transport for anyone building a custom client or debugging a connection.
Transport
The server implements the Streamable HTTP transport from the MCP specification, mounted at a single path:
| Method | Path | Purpose |
|---|---|---|
POST | /mcp | Send JSON-RPC requests / receive responses. |
GET | /mcp | Open a server-initiated SSE stream. Not used — returns 405. |
DELETE | /mcp | Terminate the current session. |
GET | /mcp/health | Unauthenticated health probe. |
Requests and responses are JSON-RPC 2.0. If the client's Accept header includes
text/event-stream, the server replies as a single Server-Sent Event (event: message) rather than
plain application/json — handy for strict MCP clients — but it never holds the stream open, since
it emits no server-initiated messages.
Methods
| Method | Description |
|---|---|
initialize | Negotiate the protocol version and start a session. |
notifications/initialized (also initialized) | Lifecycle notification sent by the client after initialize. No response. |
tools/list | List the available tools and their input schemas. |
tools/call | Invoke a tool by name with arguments. |
ping | Liveness check within a session; returns {}. |
For multi-account tokens, each tools/call
must pin an account — via params._meta["bookingsync.com/account-id"], the account_id tool
argument, or the X-BookingSync-Account-ID request header (resolved in that order).
Version negotiation
initialize returns the protocol version the client requested if the server supports it, otherwise
the server's latest. Supported versions, newest first: 2025-06-18, 2025-03-26, 2024-11-05.
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-06-18",
"capabilities": { "tools": { "listChanged": false } },
"serverInfo": { "name": "bookingsync-mcp", "version": "1.0.0" }
}
}
Sessions
- On the first
initializePOST, the server creates a session and returns its id in theMcp-Session-Idresponse header. - The client must echo
Mcp-Session-Idon every subsequent request. A missing or expired session id is rejected withSession not found or expired(-32001, HTTP404). - Sessions use a sliding 1-hour expiry — each successful request resets the clock.
DELETE /mcp(with the session header) ends the session.- A session is still bound to its originating token: if the token is revoked or expires, the session stops working on its next request.
Notifications
A JSON-RPC message without an id is a notification. The server processes it but returns no
body, responding with HTTP 202 Accepted. notifications/initialized is the common example.
Batch requests
A POST body may be a JSON array of requests. The server processes each and returns an array of
responses (notifications produce no entry; an all-notification batch returns 202 Accepted).
Error codes
Errors follow JSON-RPC 2.0, with a few server-specific codes:
| Code | Meaning | Notes |
|---|---|---|
-32700 | Parse error | Malformed JSON. |
-32600 | Invalid request | Missing jsonrpc or method. |
-32601 | Method not found | Unknown method or unknown tool name. |
-32602 | Invalid params | Bad arguments — unknown resource, attribute, operator, or field. The message lists valid options. |
-32603 | Internal error | Unexpected server-side failure. |
-32000 | Unauthorized | Missing / invalid / expired token. HTTP 401. |
-32001 | Session not found or expired | Missing or stale Mcp-Session-Id. HTTP 404. |
-32029 | Rate limit exceeded | Over 1,000 req/hour. HTTP 429, with Retry-After. |
Example error response:
{
"jsonrpc": "2.0",
"id": 7,
"error": {
"code": -32602,
"message": "Unknown filter attribute 'colour'. Valid attributes: id, name, currency, ..."
}
}
A complete session with curl
The example below runs the full handshake and a query. Replace mcp_YOUR_TOKEN.
1. Initialize (note the -i flag to see the Mcp-Session-Id response header):
curl -i -X POST https://www.bookingsync.com/mcp \
-H "Authorization: Bearer mcp_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}'
Capture the Mcp-Session-Id header from the response and reuse it below.
2. Send the initialized notification (no response body; HTTP 202):
curl -X POST https://www.bookingsync.com/mcp \
-H "Authorization: Bearer mcp_YOUR_TOKEN" \
-H "Mcp-Session-Id: THE_SESSION_ID" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"notifications/initialized"}'
3. List the tools:
curl -X POST https://www.bookingsync.com/mcp \
-H "Authorization: Bearer mcp_YOUR_TOKEN" \
-H "Mcp-Session-Id: THE_SESSION_ID" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
4. Call a tool — list bookings for rental 42:
curl -X POST https://www.bookingsync.com/mcp \
-H "Authorization: Bearer mcp_YOUR_TOKEN" \
-H "Mcp-Session-Id: THE_SESSION_ID" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "api_v3_list",
"arguments": { "resource": "bookings", "filter": { "rental_id": 42 }, "limit": 5 }
}
}'
Response (the resource payload is JSON-encoded inside content[0].text):
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{ "type": "text", "text": "{\"bookings\":[{\"id\":123, ...}],\"meta\":{\"total_count\":1,\"limit\":5,\"offset\":0}}" }
]
}
}
5. End the session (optional):
curl -X DELETE https://www.bookingsync.com/mcp \
-H "Authorization: Bearer mcp_YOUR_TOKEN" \
-H "Mcp-Session-Id: THE_SESSION_ID"