Skip to content

MCP servers

Tavora agents can call tools exposed by any Model Context Protocol (MCP) server you declare on the agent. Inside an execute_js block the agent writes code like:

var list = require('tasklist-example').create_task_list({ name: 'Europe trip' });
var added = 0;
var cities = ['Berlin', 'Munich', 'Hamburg', 'Cologne'];
for (var i = 0; i < cities.length; i++) {
require('tasklist-example').add_task({
list_id: list.content.id,
title: 'Visit ' + cities[i]
});
added++;
}
return added + ' tasks added';

One execute_js turn can make as many MCP calls as the plan needs.

MCP servers are part of the agent’s source — they live alongside the persona and skills under tavora/agents/<id>/agent.jsonc and ship with the agent through tavora deploy. There is no per-server CRUD endpoint anymore; the SDK doesn’t expose createMCPServer etc.

tavora/agents/trip-planner/agent.jsonc
{
"id": "trip-planner",
"name": "Trip planner",
"persona": "persona.md",
"model": "gemini-2.5-flash",
"mcp": [
{
"name": "tasklist-example",
"url": "https://example.com/mcp",
"transport": "streamable_http",
"auth": {
"type": "bearer",
"tokenRef": "TASKLIST_BEARER"
}
}
]
}
FieldNotes
nameThe module name the agent uses in require('<name>'). Unique per agent.
urlThe MCP server URL.
transportstreamable_http (recommended) or sse.
auth.typebearer or header.
auth.tokenRef / auth.valueRefName of a secret in the app’s vault. Resolved server-side at run time — never sent over the wire from your shell.

tavora dev and tavora deploy carry the mcp block through:

Terminal window
# Watch + sync drafts as you save
tavora dev
# Snapshot the current draft as the next published version
tavora deploy

On every sync, the platform validates the mcp block (URL reachable, auth refs resolve against the app’s vault, schema parses). Validation issues come back with file:line markers so editors (VS Code, Cursor) surface them inline.

Every MCP tool is exposed as a JavaScript method on a module named for the mcp[].name field:

// 'tasklist-example' is the server's name in agent.jsonc.
var mod = require('tasklist-example');
var list = mod.create_task_list({ name: 'Europe' });
mod.add_task({ list_id: list.content.id, title: 'Visit Berlin' });

Calls emit skill_call events in the run trace.

Your MCP server must:

  • Speak MCP over the declared transport (streamable_http or sse).
  • Validate the auth header on every incoming request — the platform attaches the bearer/header per the auth block.
  • Be reachable from the Tavora platform’s network.

See examples/tasklist/internal/web/mcp.go in tavora-sdk-go for a reference bearer-gate middleware.

  • tavora dev --verbose — surfaces MCP validation issues inline as you save agent.jsonc.
  • tavora run <agent> "<msg>" — runs the local draft and writes a trace to tavora/.runs/; every skill_call event lands in the trace markdown.
  • The session detail view at /sessions/:id shows the same trace for SDK-triggered runs.

examples/tasklist in tavora-sdk-go is a full end-to-end MCP server: it exposes six tools over streamable_http with bearer auth, and ships a web UI that shows the agent, the chat turns, and the resulting SQLite tasks. Start there when building your own — the step-by-step walkthrough lives in Build the tasklist agent.