MCP Transports
Trove supports two MCP transports. Streamable HTTP is recommended for most clients. WebSocket is available for long-lived desktop apps that benefit from persistent connections.
Streamable HTTP
Section titled “Streamable HTTP”The recommended transport. Each request is a standard HTTP POST carrying a JSON-RPC 2.0 message.
| Property | Value |
|---|---|
| Endpoint | POST https://api.ontrove.sh/mcp |
| Auth | Authorization: Bearer <token> |
| Content-Type | application/json |
| Session TTL | 1 hour (KV-backed) |
Session lifecycle
Section titled “Session lifecycle”- Initialize. POST an
initializerequest. The server returns anMCP-Session-Idheader. - Use. Include the
MCP-Session-Idheader on all subsequent requests. - Terminate. Send
DELETE /mcpwith theMCP-Session-Idheader.
Full handshake example
Section titled “Full handshake example”# Step 1: Initializecurl -X POST https://api.ontrove.sh/mcp \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"my-client","version":"1.0.0"}}}' \ -v
# Response includes MCP-Session-Id header# < MCP-Session-Id: abc123-uuid# < MCP-Protocol-Version: 2025-03-26
# Step 2: List toolscurl -X POST https://api.ontrove.sh/mcp \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -H "MCP-Session-Id: abc123-uuid" \ -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
# Step 3: Call a toolcurl -X POST https://api.ontrove.sh/mcp \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -H "MCP-Session-Id: abc123-uuid" \ -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"trove_search","arguments":{"query":"machine learning"}}}'
# Step 4: Terminatecurl -X DELETE https://api.ontrove.sh/mcp \ -H "MCP-Session-Id: abc123-uuid"Response headers
Section titled “Response headers”| Header | Description |
|---|---|
MCP-Protocol-Version: 2025-03-26 | Always present on every response |
MCP-Session-Id: <uuid> | Returned on the initialize response only |
Content-Type: application/json | All responses are plain JSON (no SSE) |
Notifications
Section titled “Notifications”Requests where the method starts with notifications/ (e.g., notifications/initialized) receive a 202 Accepted response with no body.
Error responses
Section titled “Error responses”| Status | Meaning |
|---|---|
| 400 | Missing MCP-Session-Id header on a non-initialize request |
| 403 | Session belongs to a different user |
| 404 | Session ID is invalid or expired |
WebSocket
Section titled “WebSocket”A persistent connection transport backed by Cloudflare Durable Objects.
| Property | Value |
|---|---|
| Endpoint | GET wss://api.ontrove.sh/mcp?token=<jwt> |
| Upgrade | Upgrade: websocket header required |
| Auth | JWT passed as token query parameter |
| Messages | JSON-RPC 2.0 text frames |
Connection details
Section titled “Connection details”- The token is passed as a query parameter because the browser WebSocket API does not support custom headers.
- Security note. Tokens in query parameters can appear in server logs and proxy logs. Use short-lived tokens for WebSocket connections when possible. The Streamable HTTP transport passes tokens in the
Authorizationheader, which is more secure. - Each user gets a dedicated Durable Object instance, routed by Clerk user ID.
- The server uses the Cloudflare WebSocket Hibernation API, so idle connections cost nothing.
- No
MCP-Session-Idis needed. The WebSocket connection itself is the session.
When to use WebSocket
Section titled “When to use WebSocket”WebSocket fits well for:
- Long-lived desktop applications that want a persistent connection
- Clients that send many requests in quick succession
- Scenarios where connection setup overhead matters
For most use cases, Streamable HTTP is simpler and works well.