How to Integrate TREK with MCP (Model Context Protocol): A Complete Developer Guide
TREK exposes a built-in MCP server at /mcp that enables AI assistants to securely query and manipulate travel data through a JSON-RPC API, requiring only the MCP add-on to be enabled and a valid OAuth 2.1, static, or JWT token for authentication.
Integrating TREK with the Model Context Protocol (MCP) allows Claude, Cursor, and other AI assistants to interact with your travel data using a standardized JSON-RPC interface. According to the mauriceboe/TREK source code, the integration centers on a single HTTP endpoint that handles authentication, session management, and tool registration. This guide walks through the architectural flow, authentication requirements, and implementation details needed to connect your AI client to a TREK instance.
Enable the MCP Add-On
Before any client can connect, the MCP feature must be activated in the database. In server/src/mcp/index.ts (lines 18-22), the handler checks isAddonEnabled(ADDON_IDS.MCP) and returns a 403 Forbidden if the add-on is disabled.
Enable the add-on by inserting the record into your SQLite database:
INSERT INTO addons (id, enabled) VALUES ('mcp', 1);
Once enabled, the /mcp endpoint becomes active and accepts POST requests carrying JSON-RPC 2.0 payloads.
Authenticate Incoming Requests
The verifyToken function in server/src/mcp/index.ts (lines 71-102) supports three credential types, returning a payload of {user, scopes, clientId, isStaticToken} that drives permission enforcement:
- OAuth 2.1 access tokens (prefix
trekoa_): Validated viagetUserByAccessTokeninserver/src/services/oauthService.ts. The audience must match the MCP URL, and the resulting scopes control which tools the client can invoke. - Legacy static tokens (prefix
trek_): Verified withverifyMcpTokeninserver/src/services/authService.ts. These grant full access but trigger a deprecation notice that the server automatically appends to the model’s response. - Short-lived JWTs: Used by the TREK web UI, verified via
verifyJwtToken.
Client implementations should obtain an OAuth token from TREK Settings → MCP → OAuth Clients, then include it in the Authorization: Bearer header.
Handle Sessions and Rate Limits
TREK enforces a multi-layered gatekeeping system after authentication.
Rate Limiting
An in-memory rateLimitMap tracks requests per user and client. The isRateLimited utility (lines 11-21 of server/src/mcp/index.ts) reads the MCP_RATE_LIMIT environment variable, defaulting to 300 requests per minute. Exceeding this returns a rate-limit error before the request reaches the business logic.
Session Creation and Resumption
The server distinguishes between new and existing sessions via the Mcp-Session-Id header:
- New Session: For requests without a session ID, the server checks
MCP_MAX_SESSION_PER_USER(default 20) against the in-memorysessionsregistry inserver/src/mcp/sessionManager.ts. If under the limit, it instantiates anMcpServerfrom@modelcontextprotocol/sdk/server/mcp, configures capabilities (tools, resources, prompts) withlistChanged: true, and attaches base instructions describing TREK’s data model. TheStreamableHTTPServerTransportgenerates a UUID, stores the session, and returns it in theMcp-Session-Idresponse header. - Resuming: Requests bearing an existing
Mcp-Session-Idvalidate ownership and client-id, update the activity timestamp, and forward the payload to the existing transport.
A sweep interval periodically removes stale sessions after a one-hour TTL and cleans expired rate-limit entries.
Expose Travel Data via Tools and Resources
Each session registers a curated catalog scoped to the authenticated user. In server/src/mcp/resources.ts and the server/src/mcp/tools/ directory, the server calls registerResources and registerTools to expose:
- Tools: Domain-specific operations like
list_trips,search_place,create_accommodation, andbudget/*grouped by functionality (vacations, packing, etc.). - Resources: Read-only snapshots of travel data.
The scopes array from the OAuth token determines which tools are available, enforcing fine-grained permissions at runtime.
Audit and Monitor Usage
Every tool invocation passes through writeAudit (implemented near lines 4-16 of server/src/mcp/index.ts), logging the user ID, tool name, client ID (or "native" for static tokens), and source IP to logToolCallAudit. This creates an immutable trail of AI interactions for security review.
Graceful Shutdown and Invalidation
When the MCP add-on state changes, invalidateMcpSessions() forces all clients to reconnect, ensuring they receive an updated tool catalog. The closeMcpSessions() function (bottom of server/src/mcp/index.ts) stops the sweep timer and terminates all transports cleanly during server shutdown.
Code Examples
Initialize a Connection with OAuth
Use this Node.js pattern to establish an MCP session:
import fetch from 'node-fetch';
const token = 'trekoa_abc123…'; // From TREK Settings → MCP → OAuth Clients
const response = await fetch('https://your-trek.example.com/mcp', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Accept': 'application/json, text/event-stream',
'Content-Type': 'application/json',
},
body: JSON.stringify({
jsonrpc: '2.0',
method: 'initialize',
id: 1,
params: {
protocolVersion: '2024-11-05',
capabilities: {},
clientInfo: { name: 'my-assistant', version: '1.0' },
},
}),
});
const json = await response.json();
console.log('MCP Session ID:', response.headers.get('Mcp-Session-Id'));
Reuse an Existing Session
Subsequent calls reuse the session ID to maintain context:
const sessionId = 'c1d2e3f4-…';
await fetch('https://your-trek.example.com/mcp', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Mcp-Session-Id': sessionId,
'Content-Type': 'application/json',
},
body: JSON.stringify({
jsonrpc: '2.0',
method: 'tools/call',
id: 2,
params: { name: 'list_trips', args: {} },
}),
});
Handle Static Token Deprecation
When authenticating with a legacy trek_ token, the server prepends STATIC_TOKEN_DEPRECATION_NOTICE to the response result. Your client should surface this warning to the user before displaying tool results, as these tokens are scheduled for removal.
Summary
- Enable first: The MCP add-on must be active in the database (
isAddonEnabled) or the endpoint returns 403. - Token flexibility: Support OAuth 2.1 (
trekoa_), legacy static (trek_), and JWT tokens viaverifyToken. - Session aware: Use
Mcp-Session-Idheaders to persist state, respecting the default limit of 20 sessions per user. - Rate guarded: Default 300 req/min limit controlled by
MCP_RATE_LIMIT. - Scoped access: OAuth scopes filter available tools during
registerToolsexecution. - Fully audited: Every
tools/callis logged with user ID and client context.
Frequently Asked Questions
What authentication method should I use for production integrations?
OAuth 2.1 access tokens are the recommended method for production. According to the mauriceboe/TREK source code, these tokens provide scoped access via the scopes array and are validated against the MCP URL audience. Legacy static tokens (trek_ prefix) function but trigger a deprecation notice, while JWTs are intended primarily for the native web UI.
How do I handle rate limiting when making consecutive tool calls?
The server enforces a default limit of 300 requests per minute per user via the MCP_RATE_LIMIT environment variable. If you receive a rate-limit error, implement exponential backoff in your client. The rateLimitMap tracks both user and client IDs, so distributing requests across multiple clients for the same user does not bypass the limit.
Why does my client receive a 403 error when calling /mcp?
A 403 response indicates the MCP add-on is disabled. In server/src/mcp/index.ts (lines 18-22), the handler explicitly checks isAddonEnabled(ADDON_IDS.MCP) and rejects the request if the value is false. Run the SQL INSERT INTO addons (id, enabled) VALUES ('mcp', 1) to enable the endpoint.
How are tool permissions determined for OAuth-authenticated clients?
Permissions are derived from the scopes field returned by getUserByAccessToken in server/src/services/oauthService.ts. During session initialization in server/src/mcp/index.ts, these scopes are passed to registerTools, which filters the available tool catalog to only those matching the granted scopes. This ensures AI assistants cannot access travel data outside their OAuth permission grant.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →