MCP integration
Since v0.4.0. MCP integration is useful when your application already exposes business data or operations through a remote MCP server. Tiketo Chat can let the agent call an explicitly allowed subset of those tools on behalf of the user who is signed in to your host page.
The call is made by the browser directly to your MCP endpoint. Use this integration for user-scoped operations. Do not use it for service credentials or secrets that must stay on a backend.
What to provide to Tiketo
Section titled “What to provide to Tiketo”For each server, provide:
- an absolute HTTPS MCP endpoint using the Streamable HTTP transport; 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 is default-deny. Tiketo assigns each endpoint a short server key, and the agent can only call tools configured under that key. No real endpoint or customer configuration belongs in 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 HTTP request, so your application can refresh credentials when needed. A typical server accepts the logged-in user’s bearer access 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 may contain bearer authorization, API-key headers, tenant headers, or any other headers your server expects. Header mode is the default recommendation: many MCP servers advertise bearer_methods_supported: ["header"] in their OAuth protected-resource metadata and accept bearer credentials only in Authorization. If a server uses cookies, set credentials: "include"; the header provider is then optional. Calling the command again replaces that server’s registration. Remove it during logout with tiketoChat("mcp", "primary", null) and call reset to discard the chat and all MCP session IDs.
Protocol and correlation headers are controlled by the embed. Values supplied for Authorization or custom headers are accepted, but host values for Content-Type, Accept, mcp-session-id, MCP-Protocol-Version, X-Tiketo-Conversation-Id, and X-Tiketo-Request-Id are ignored.
Register MCP access in an effect and remove it when the authenticated 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”Your MCP server must allow requests from every frontend origin where the configured client ID is used. Allow POST and explicitly allow 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, so list it explicitly. Expose mcp-session-id so the browser can retain the server’s session identifier.
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: OriginFor cookie mode, credentials require the exact frontend origin—never *—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 both the request and the server’s allow-list):
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 speaks MCP 2025-06-18 only and sends MCP-Protocol-Version: 2025-06-18; it does not negotiate another version from the initialize response. Support for a newer version will be announced in the changelog before it is enabled.
The transport is POST only. The embed never opens a GET SSE stream, so a stateless MCP server needs no GET handler. A text/event-stream response to POST is supported, as is 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 and also records it in the chat launch event as tiketoConversationId, so Tiketo can correlate it with transcripts on request. X-Tiketo-Request-Id has the same value as 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 their values, persist them, put them in done events, or log their names or values. They travel only from the browser to your configured MCP endpoint; they are not sent to Tiketo’s Worker or Voiceflow.
Tool arguments and tool results are different: the agent needs them to perform the task, so they are processed by the agent and can appear in conversation transcripts. Do not enable tools whose arguments or output are inappropriate for that data path.
Retention, region, and subprocessor details are available from Tiketo as part of the data and privacy documentation; contact Tiketo for the documentation applicable 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 agent can call only explicitly allowlisted tools, and every write call requires a fresh explicit user confirmation in the UI. Text returned by a tool cannot, by itself, authorize or execute a write.
Limits and results
Section titled “Limits and results”The default timeout is 20 seconds per call and covers authentication header resolution, network requests, response reads, parsing, and retries. The default result limit is 8,000 Unicode characters; Tiketo can configure a different server default or a smaller/larger per-tool limit. Only text content items are passed to the agent. Other content types are represented by short placeholders, and truncated reports whether text was cut. structuredContent is currently not used, so servers should always include a text rendering in content.
Every response also has a streamed byte ceiling. The per-server maxResponseBytes setting defaults to 1 MiB and stops JSON or SSE bodies as soon as they exceed that limit.
Each agent-initiated tool call gets a new opaque id in _meta["tiketo/requestId"]. Servers should use it to de-duplicate writes. The same id is retained if the embed re-sends that logical call:
| 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 for a write tool, the agent is instructed not to repeat that write automatically. It tells the user the outcome is unknown and asks them to verify or explicitly confirm before retrying.
| 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 agent’s schema snapshot is generated by scripts/mcp-snapshot.ts from the configured allowlist. Tiketo refreshes it in a pull request after the integrating team announces a tool schema change. If a server changes an input schema without notice, the agent 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, an agent snapshot change, and a deploy. It does not require a new embed version: 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.