Skip to main content

MCP Tools

The platform integrates with the Model Context Protocol (MCP) to give conversations access to external tools, resources, and prompts. MCP servers are registered on the platform and their capabilities are exposed to the LLM during generation.

Where tools come from

Three different things can put a tool in front of the model, and they differ in who runs the tool when it is called.

SourceWho executes itYou provide
Platform MCP serversThe platformNothing — they are already there
Client-side toolsYour appThe tool definitions, and the results
Third-party apps via PipedreamPipedreamAn account connection

Platform MCP servers

The platform ships its own MCP servers and exposes them to conversations automatically — covering things like semantic memory, notifications, location enrichment, holiday calendars, and nutrition lookup. You do not register or host anything.

Call mcp-list-available-servers to see what is live for your tenant rather than assuming a fixed set; which servers a given conversation sees also depends on its own MCP configuration and any active agent profile.

Client-side tools

For anything that has to run on your side — reading device state, navigating your UI, touching a system only your backend can reach — declare it as a client tool in the generation config's clientTools. The model sees it like any other tool, but the platform does not execute it: the call comes back to you, you run it, and you post the result with submit-client-tool-results. See Client-Side Tools below.

This is the extension point. You do not need to stand up an MCP server to give the model your own capabilities.

Third-party apps via Pipedream

Your users can connect their own SaaS accounts — GitHub, Google Calendar, Slack, and thousands more — and the apps they connect become MCP servers named pipedream:{appSlug}. Add one to a thread's conversation_settings.mcp_servers and the model gets that app's tools, called as that user, without you building an integration per app or ever holding their credentials.

See the Third-Party Integrations guide for the connect flow and the Third-Party Integrations API reference for the endpoints.

Running Pipedream actions directly, and deploying event triggers, are not on the public API yet — the conversational path above is what ships today.

How It Works

MCP tool execution flow — client sends a message, the LLM requests a tool call, MCP service invokes the MCP server, and the tool result flows back to the LLM before the final assistant message is returned

  1. When a message is sent, the platform includes available tool definitions in the LLM request
  2. If the LLM decides a tool is needed, it returns a tool call request
  3. The platform executes the tool via the MCP service (or asks for approval)
  4. The tool result is fed back to the LLM
  5. The LLM produces its final response incorporating the tool output

Discovering Available Tools

List MCP Servers

See which MCP servers are available on the platform:

curl -X POST https://api.travila.ai/api/v1/llm/mcp-list-available-servers \
-H "X-API-Key: sk_your_key_here" \
-H "X-On-Behalf-Of: user_123" \
-H "Content-Type: application/json" \
-d '{}'

Get Server Info

Get details about a specific MCP server, including its capabilities:

curl -X POST https://api.travila.ai/api/v1/llm/mcp-get-server-info \
-H "X-API-Key: sk_your_key_here" \
-H "X-On-Behalf-Of: user_123" \
-H "Content-Type: application/json" \
-d '{
"serverId": "memory-server"
}'

Reload Server Configuration

Not exposed on the public API

mcp-reload-config has no route on api.travila.ai and returns 404. It is an operational call rather than an application one, and may stay internal — documented here so the behaviour is known, not so you build against it.

Re-reads the MCP server configuration, reconnects to the configured servers, and refreshes tool discovery. Use it when a server was added or its credentials changed and you do not want to wait for the next natural refresh — a newly added server will not appear in mcp-list-tools until something reloads.

curl -X POST https://api.travila.ai/api/v1/llm/mcp-reload-config \
-H "X-API-Key: sk_your_key_here" \
-H "X-On-Behalf-Of: user_123" \
-H "Content-Type: application/json" \
-d '{}'

Response:

{
"success": true,
"message": "reloaded 4 servers",
"loadedServers": ["memory-server", "notification-server", "github"],
"failedServers": ["internal-crm"]
}

A server that fails to connect lands in failedServers and the call still reports success: true — the reload worked, that one server did not. Check the array, not just the flag. Tools from a failed server simply do not appear in discovery.

configPath is an optional override for the configuration source; omit it to reload whatever the deployment is already pointed at.

List Tools

List all tools available from a specific MCP server:

curl -X POST https://api.travila.ai/api/v1/llm/mcp-list-tools \
-H "X-API-Key: sk_your_key_here" \
-H "X-On-Behalf-Of: user_123" \
-H "Content-Type: application/json" \
-d '{
"servers": ["memory-server"]
}'

Returns the tool name, description, and JSON Schema for the input parameters. Omit servers to list tools across every server registered for the conversation.

Calling Tools Directly

You can call MCP tools directly outside of a conversation:

curl -X POST https://api.travila.ai/api/v1/llm/mcp-call-tool \
-H "X-API-Key: sk_your_key_here" \
-H "X-On-Behalf-Of: user_123" \
-H "Content-Type: application/json" \
-d '{
"toolCall": {
"serverId": "memory-server",
"name": "search_memories",
"argumentsJson": "{\"query\": \"user preferences\"}"
},
"requestId": "req_abc123"
}'

The call is described by a single toolCall object. argumentsJson is a JSON-encoded string, not a nested object. requestId is yours to choose and comes back on the response for correlation.

Tool Approval Flow

Some tools require explicit user approval before execution. When the LLM requests a tool call that needs approval:

  1. The generation run pauses
  2. The tool call is added to the pending approvals list
  3. The client polls for or is notified of pending approvals
  4. The client submits approvals (approve or deny)
  5. Generation resumes with the approved tool results

Check Pending Approvals

curl -X POST https://api.travila.ai/api/v1/llm/list-pending-approvals \
-H "X-API-Key: sk_your_key_here" \
-H "X-On-Behalf-Of: user_123" \
-H "Content-Type: application/json" \
-d '{
"conversationKey": "conv_abc"
}'

Submit Approvals

curl -X POST https://api.travila.ai/api/v1/llm/submit-tool-approvals \
-H "X-API-Key: sk_your_key_here" \
-H "X-On-Behalf-Of: user_123" \
-H "Content-Type: application/json" \
-d '{
"conversationKey": "conv_abc",
"approvals": [
{
"toolCallId": "call_abc123",
"approved": true
}
]
}'

Set approved to false to deny the tool call. The LLM will be informed that the tool was denied and will adjust its response accordingly.

Client-Side Tools

Some tools are designed to execute on your side (displaying a UI component, navigating to a page, reaching a system only you can reach). The model calls them like any other tool; the platform just hands the call back to you instead of running it.

Declaring them

Put the definitions in clientTools on the generation config — either as the thread default, or per turn via overrideGenerationConfig:

{
"conversationKey": "conv_abc",
"defaultGenerationConfig": {
"clientTools": [
{
"name": "navigate_to",
"serverId": "client",
"description": "Navigate the app to a given screen",
"parametersJsonSchema": {
"type": "object",
"properties": {
"screen": { "type": "string", "description": "Screen identifier" }
},
"required": ["screen"]
}
}
]
}
}

parametersJsonSchema is a plain JSON Schema object — it is what the model reads to work out how to call your tool, so describe the fields properly. It is not a validation contract: the platform never checks the model's arguments against it, so treat what arrives as untrusted. serverId is required on every tool definition; "client" is the conventional value for tools you execute — client tools are matched by name, not by server.

The round trip

  1. The tool call is delivered to the client
  2. The client executes the action locally
  3. The client submits the result back to the platform
curl -X POST https://api.travila.ai/api/v1/llm/submit-client-tool-results \
-H "X-API-Key: sk_your_key_here" \
-H "X-On-Behalf-Of: user_123" \
-H "Content-Type: application/json" \
-d '{
"conversationKey": "conv_abc",
"results": [
{
"toolCallId": "call_xyz789",
"toolName": "navigate_to",
"resultJson": { "navigated_to": "/settings" }
}
]
}'

toolName is required alongside toolCallId — the pair is matched against the calls the run is actually waiting on, and a submission that doesn't match one is rejected with 400. resultJson is a JSON object, not a JSON string.

An empty (or omitted) resultJson records the call as failed — which is how you report that your side couldn't complete the action. Either way, submit something: the run waits 5 minutes by default — tool_policy.client_tool_timeout_ms changes that, and there is no unbounded setting — and fails the tool call if nothing arrives.

Resources

MCP servers can also expose resources — structured data that the LLM can reference.

List Resources

curl -X POST https://api.travila.ai/api/v1/llm/mcp-list-resources \
-H "X-API-Key: sk_your_key_here" \
-H "X-On-Behalf-Of: user_123" \
-H "Content-Type: application/json" \
-d '{
"serverId": "memory-server"
}'

Read a Resource

curl -X POST https://api.travila.ai/api/v1/llm/mcp-read-resource \
-H "X-API-Key: sk_your_key_here" \
-H "X-On-Behalf-Of: user_123" \
-H "Content-Type: application/json" \
-d '{
"serverId": "memory-server",
"uri": "memory://user/preferences"
}'

Prompts

MCP servers can expose reusable prompt templates.

List Prompts

curl -X POST https://api.travila.ai/api/v1/llm/mcp-list-prompts \
-H "X-API-Key: sk_your_key_here" \
-H "X-On-Behalf-Of: user_123" \
-H "Content-Type: application/json" \
-d '{
"serverId": "memory-server"
}'

Get a Prompt

curl -X POST https://api.travila.ai/api/v1/llm/mcp-get-prompt \
-H "X-API-Key: sk_your_key_here" \
-H "X-On-Behalf-Of: user_123" \
-H "Content-Type: application/json" \
-d '{
"serverId": "memory-server",
"name": "summarize_history"
}'