Skip to main content

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:

MethodPathPurpose
POST/mcpSend JSON-RPC requests / receive responses.
GET/mcpOpen a server-initiated SSE stream. Not used — returns 405.
DELETE/mcpTerminate the current session.
GET/mcp/healthUnauthenticated 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

MethodDescription
initializeNegotiate the protocol version and start a session.
notifications/initialized (also initialized)Lifecycle notification sent by the client after initialize. No response.
tools/listList the available tools and their input schemas.
tools/callInvoke a tool by name with arguments.
pingLiveness check within a session; returns {}.
Account selection

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 initialize POST, the server creates a session and returns its id in the Mcp-Session-Id response header.
  • The client must echo Mcp-Session-Id on every subsequent request. A missing or expired session id is rejected with Session not found or expired (-32001, HTTP 404).
  • 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:

CodeMeaningNotes
-32700Parse errorMalformed JSON.
-32600Invalid requestMissing jsonrpc or method.
-32601Method not foundUnknown method or unknown tool name.
-32602Invalid paramsBad arguments — unknown resource, attribute, operator, or field. The message lists valid options.
-32603Internal errorUnexpected server-side failure.
-32000UnauthorizedMissing / invalid / expired token. HTTP 401.
-32001Session not found or expiredMissing or stale Mcp-Session-Id. HTTP 404.
-32029Rate limit exceededOver 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"