MCP integration
Since v0.4.0. Production stable can lag behind new releases. If the version in its manifest is older than v0.4.0, load a pinned vX.Y.Z path (v0.4.0 or later) instead. Use MCP integration when your application already exposes data or operations through a remote MCP server. The chatbot can call an approved set of tools for the user signed in to your page.
The browser calls your MCP endpoint directly. This flow is for user-scoped operations. Keep backend-only credentials out of it; see Security and CSP.
What to provide to Tiketo
Section titled “What to provide to Tiketo”For each server, provide:
- an absolute HTTPS MCP endpoint that uses Streamable HTTP; URLs must not contain credentials, including query-string credentials;
- the tools to enable, with each tool classified as
readorwrite; - a description and JSON input schema for each enabled tool, or access for Tiketo to create a filtered snapshot;
- the frontend origins that will host the chatbot;
- a test account for integration and agent evaluation.
The allowlist denies all tools by default. Tiketo gives each endpoint a short server key. The chatbot can call only the tools configured for that key. Keep real endpoints and customer configuration out of client-side integration code.
Register browser authentication
Section titled “Register browser authentication”Register each server before or after init. The header provider runs for every MCP request, so your application can refresh credentials when needed. This example supplies the signed-in user’s bearer token:
tiketoChat("mcp", "primary", { headers: async () => ({ Authorization: "Bearer " + await getToken(), }),});
tiketoChat("mcp", "analytics", { headers: async () => await getAnalyticsHeaders(),});
tiketoChat("mcp", "cookie-session", { credentials: "include",});The object can contain authorization, API-key, tenant, or other headers expected by your server. Header mode is the default because many MCP servers advertise bearer_methods_supported: ["header"] in their OAuth protected-resource metadata and accept bearer credentials only in Authorization. For cookies, set credentials: "include"; the header provider is optional. Calling the command again replaces that server’s registration. On logout, remove it with tiketoChat("mcp", "primary", null) and call reset to discard the conversation and all MCP session IDs.
The embed controls protocol and correlation headers. It accepts Authorization and custom headers, but ignores host values for Content-Type, Accept, mcp-session-id, MCP-Protocol-Version, X-Tiketo-Conversation-Id, and X-Tiketo-Request-Id.
Register MCP access in an effect. Remove it when the signed-in session changes or the component unmounts:
import { useEffect } from "react";
export function ChatMcpAuth({ getToken }: { getToken(): Promise<string> }) { useEffect(() => { tiketoChat("mcp", "primary", { headers: async () => ({ Authorization: `Bearer ${await getToken()}` }), }); return () => tiketoChat("mcp", "primary", null); }, [getToken]);
return null;}MCP server CORS
Section titled “MCP server CORS”Allow requests from every frontend origin that uses the client ID. Permit POST and list Authorization, Content-Type, Accept, mcp-session-id, MCP-Protocol-Version, X-Tiketo-Conversation-Id, and X-Tiketo-Request-Id, plus every custom host header. Access-Control-Allow-Headers: * does not cover Authorization under the Fetch standard. Expose mcp-session-id so the browser can keep the server’s session identifier. Your page’s Content Security Policy must also list the MCP origin in connect-src; see Security and CSP.
For bearer header mode, a preflight response can be:
HTTP/1.1 204 No ContentAccess-Control-Allow-Origin: https://app.example.comAccess-Control-Allow-Methods: POST, OPTIONSAccess-Control-Allow-Headers: Authorization, Content-Type, Accept, mcp-session-id, MCP-Protocol-Version, X-Tiketo-Conversation-Id, X-Tiketo-Request-IdAccess-Control-Expose-Headers: mcp-session-idVary: OriginCookie mode requires the exact frontend origin, not *, and the credentials flag:
HTTP/1.1 204 No ContentAccess-Control-Allow-Origin: https://app.example.comAccess-Control-Allow-Credentials: trueAccess-Control-Allow-Methods: POST, OPTIONSAccess-Control-Allow-Headers: Authorization, Content-Type, Accept, mcp-session-id, MCP-Protocol-Version, X-Tiketo-Conversation-Id, X-Tiketo-Request-IdAccess-Control-Expose-Headers: mcp-session-idVary: OriginCheck the deployed preflight from an allowed frontend origin. Add every custom host header to the request and the server allowlist.
curl -X OPTIONS 'https://mcp.example.com/rpc' \ -H 'Origin: https://app.example.com' \ -H 'Access-Control-Request-Method: POST' \ -H 'Access-Control-Request-Headers: Authorization, Content-Type, Accept, mcp-session-id, MCP-Protocol-Version, X-Tiketo-Conversation-Id, X-Tiketo-Request-Id' \ -iProtocol and transport
Section titled “Protocol and transport”The embed supports MCP 2025-06-18 and sends MCP-Protocol-Version: 2025-06-18. It does not negotiate another version from the initialize response. The changelog will announce support for a newer version before it is enabled.
The transport is POST only. The embed never opens a GET SSE stream, so a stateless server needs no GET handler. POST responses may use text/event-stream or application/json.
Every MCP HTTP request includes:
Content-Type: application/json;Accept: application/json, text/event-stream;MCP-Protocol-Version: 2025-06-18;mcp-session-idafter the server establishes a session;X-Tiketo-Conversation-Id, an opaque per-chat-session ID generated by the embed;X-Tiketo-Request-Idontools/callonly; and- the headers returned by the host provider.
The embed rotates X-Tiketo-Conversation-Id on reset or logout. It records the same opaque per-chat-session ID generated by the embed in the launch event as tiketoConversationId, so Tiketo can correlate it with transcripts on request. X-Tiketo-Request-Id matches params._meta["tiketo/requestId"].
Credential and data handling
Section titled “Credential and data handling”Authentication headers are read only when an MCP request is about to be sent. Tiketo Chat does not cache, persist, or log their names or values. It does not include them in completion events. They travel from the browser to your configured MCP endpoint and are not sent to Tiketo’s Worker or the conversation service.
Tool arguments and results are part of the chatbot task. The conversation service processes them, and they can appear in transcripts. Enable only tools whose input and output are suitable for that data path.
Ask Tiketo for the retention, region, and subprocessor documentation that applies to your integration.
Write tools always show an explicit confirmation in the chat before the browser makes a network request. Declining returns cancelled and sends nothing to the MCP server.
Treat tool results as untrusted third-party text. The chatbot can call only allowlisted tools, and every write requires fresh user confirmation in the UI. Tool text cannot authorize or execute a write by itself.
Limits and results
Section titled “Limits and results”The default timeout is 20 seconds per call. It covers authentication header resolution, the network request, response reading, parsing, and retries. The default result limit is 8,000 Unicode characters; Tiketo can change the server default or set a per-tool limit. Only text content items are passed to the chatbot. Other content types become short placeholders, and truncated says whether text was cut. structuredContent is not currently used, so always include a text rendering in content.
Every response also has a byte ceiling. The per-server maxResponseBytes setting defaults to 1 MiB and stops JSON or SSE bodies as soon as they exceed the limit.
Each chatbot tool call gets a new opaque ID in _meta["tiketo/requestId"]. Use it to de-duplicate writes. The embed keeps the same ID if it sends that logical call again:
| Condition | Embed behavior |
|---|---|
401 |
Calls the header provider again and retries once with the same request id; another 401 or a 403 returns not_authenticated. |
403 |
No retry; returns not_authenticated. |
404 with mcp-session-id |
Re-initializes once and retries once with the same request id. The unknown session means the server did not execute that attempt. |
| Timeout or network/CORS failure | Never retried by the embed. |
After timeout or mcp_unavailable, the chatbot is instructed not to repeat a write automatically. It tells the user that the outcome is unknown and asks them to verify it or confirm a retry.
| Error | Meaning |
|---|---|
not_authenticated |
No header/cookie registration exists, the provider failed, or authentication still failed after one retry. |
tool_not_allowed |
The tool is not in that server’s explicit allowlist. No request was sent. |
unknown_server |
The server key is not configured for this client. |
invalid_arguments |
The MCP server returned JSON-RPC error -32602. |
timeout |
The configured call deadline expired. |
tool_error |
The tool returned isError, or JSON-RPC returned another tool error. |
mcp_unavailable |
The endpoint could not be reached, including network and CORS failures. |
cancelled |
The user declined a write-tool confirmation. |
Tool schema synchronization
Section titled “Tool schema synchronization”The chatbot’s schema snapshot is generated from the configured allowlist. Tiketo refreshes it in a pull request after your team announces a tool schema change. If a server changes an input schema without notice, the chatbot can send outdated arguments. The server should return JSON-RPC -32602, which becomes invalid_arguments.
Adding or removing a tool requires a client configuration change, a schema snapshot change, and a deploy. It does not require a new embed version because the generic mcpCall@1 browser contract stays the same.
Client checklist
Section titled “Client checklist”- The endpoint is absolute HTTPS and implements Streamable HTTP with protocol version
2025-06-18. - The enabled tool list and read/write classifications are agreed with Tiketo.
- The MCP server validates the logged-in user’s authorization and tenant scope for every call.
- CORS allows each frontend origin and every header the provider can return, and exposes
mcp-session-id. - The
curl -X OPTIONSpreflight check succeeds for each frontend origin and auth mode. - The bearer token or other credential is available through an async host function and is never hard-coded.
- Write-tool confirmation, timeout behavior, result limits, token refresh, and logout removal/reset have been tested.
- Tiketo has a non-production test account for evaluation.