MCP
Connect your agents to any MCP-compatible server — GitHub, Slack, Notion, databases, and hundreds more. Theazo acts as an MCP client, discovering tools from external servers and making them available to agents alongside built-in and custom tools.
Connecting to MCP servers
Register MCP server connections at the platform level with theazo.mcp.connect(). Theazo establishes the connection, discovers available tools, and makes them ready to attach to agents.
SSE / Streamable HTTP transport
For remote MCP servers accessible over the network. Theazo maintains a persistent connection and proxies tool calls through it.
import { Theazo } from class="cb-str">'theazo'
const theazo = new Theazo({ apiKey: class="cb-str">'th_live_...' })
// Connect to GitHub's MCP server via SSE
const github = await theazo.mcp.connect({
name: class="cb-str">'GitHub',
transport: class="cb-str">'sse',
url: class="cb-str">'https://mcp-github.example.com/sse'thub.example.com/sse',
headers: {
class="cb-str">'Authorization': class="cb-str">'Bearer ghp_...',
},
toolFilter: [class="cb-str">'create_issue', class="cb-str">'list_repos', class="cb-str">'create_pr'],
requiresApproval: [class="cb-str">'create_pr'],
})
// → { id: 'mcp_abc', name: 'GitHub', status: 'connected', toolCount: 3 }
// Connect via Streamable HTTP
const slack = await theazo.mcp.connect({
name: class="cb-str">'Slack',
transport: class="cb-str">'streamable-http',
url: class="cb-str">'https://mcp-slack.example.com/mcp'lack.example.com/mcp',
headers: { class="cb-str">'Authorization': class="cb-str">'Bearer xoxb-...' },
})stdio transport
For MCP servers that run as local processes. Theazo spawns the process inside each agent's sandbox — the server runs co-located with the agent.
const sqlite = await theazo.mcp.connect({
name: class="cb-str">'SQLite',
transport: class="cb-str">'stdio',
command: class="cb-str">'npx',
args: [class="cb-str">'-y', class="cb-str">'@modelcontextprotocol/server-sqlite', class="cb-str">'/data/db.sqlite'],
})
// stdio servers are spawned per-agent inside the sandboxFiltering tools
Use toolFilter to limit which tools are exposed from a server. Use requiresApproval to gate specific tools through human review.
await theazo.mcp.connect({
name: class="cb-str">'Salesforce',
transport: class="cb-str">'sse',
url: class="cb-str">'https://mcp-salesforce.example.com/sse'orce.example.com/sse',
headers: { class="cb-str">'Authorization': class="cb-str">'Bearer sf_...' },
toolFilter: [class="cb-str">'query_records', class="cb-str">'create_record', class="cb-str">'update_record'],
requiresApproval: [class="cb-str">'update_record'],
})toolFilter to limit exposure — agents with more than 50 tools may see degraded model performance.Per-user credentials
When your end users each have their own accounts on an external service (Notion, Salesforce, etc.), set credentials: 'per_user'. Each user provides their own auth token, and Theazo injects the correct credentials per session.
// Register the connection as per-user
const notion = await theazo.mcp.connect({
name: class="cb-str">'Notion',
transport: class="cb-str">'sse',
url: class="cb-str">'https://mcp-notion.example.com/sse'tion.example.com/sse',
credentials: class="cb-str">'per_user',
})
// Store credentials for each user (encrypted at rest)
await theazo.mcp.setUserCredentials(notion.id, class="cb-str">'user_123', {
headers: { class="cb-str">'Authorization': class="cb-str">'Bearer ntn_user123_token...' },
})
await theazo.mcp.setUserCredentials(notion.id, class="cb-str">'user_456', {
headers: { class="cb-str">'Authorization': class="cb-str">'Bearer ntn_user456_token...' },
})
// Remove a user's credentials
await theazo.mcp.deleteUserCredentials(notion.id, class="cb-str">'user_123')per_user connection, those tools are silently excluded from the agent's tool list — not an error, just unavailable.Attaching MCP servers to agents
Pass the mcp field when creating an agent. MCP tools appear alongside built-in and custom tools — the agent doesn't know the difference.
const session = await theazo.sessions.forUser(class="cb-str">'user_123')
// Attach specific MCP servers (by name or ID)
const agent = await session.agents.create({
compute: class="cb-str">'python',
tools: [class="cb-str">'web_search', class="cb-str">'write_file'], class="cb-cmt">// built-in tools
mcp: [class="cb-str">'GitHub', class="cb-str">'Slack'], class="cb-cmt">// MCP servers
})
// Agent now has: web_search, write_file, create_issue,
// list_repos, create_pr, send_message, list_channels, ...
// Attach ALL connected MCP servers
const agent2 = await session.agents.create({
compute: class="cb-str">'python',
mcp: class="cb-str">'*',
})
// One-shot with MCP
const result = await session.run(class="cb-str">'DevOps Agent', class="cb-str">'create an issue for the login bug', {
mcp: [class="cb-str">'GitHub'],
})
// Agent definitions with MCP (reusable templates)
await theazo.agents.define({
name: class="cb-str">'DevOps Agent',
compute: class="cb-str">'python',
tools: [class="cb-str">'web_search', class="cb-str">'http_request'],
mcp: [class="cb-str">'GitHub', class="cb-str">'Slack'],
instructions: class="cb-str">'You are a DevOps assistant...',
})Managing connections
List and inspect
// List all connections
const connections = await theazo.mcp.list()
// → [{ id: 'mcp_abc', name: 'GitHub', status: 'connected', toolCount: 3 }, ...]
// Get a specific connection
const conn = await theazo.mcp.get(class="cb-str">'mcp_abc')
// Discover tools from a connected server
const tools = await theazo.mcp.tools(class="cb-str">'mcp_abc')
// → [{ name: 'create_issue', description: '...', inputSchema: {...} }, ...]Refresh tool discovery
MCP servers can change their tool list over time. Theazo periodically refreshes (every 5 minutes), but you can trigger a manual refresh.
const refreshed = await theazo.mcp.refresh(class="cb-str">'mcp_abc')
// → MCPTool[] — updated list reflecting any schema changesUpdate credentials and filters
// Rotate credentials
await theazo.mcp.update(class="cb-str">'mcp_abc', {
headers: { class="cb-str">'Authorization': class="cb-str">'Bearer ghp_new_token...' },
})
// Change tool filter (remove access to create_pr)
await theazo.mcp.update(class="cb-str">'mcp_abc', {
toolFilter: [class="cb-str">'create_issue', class="cb-str">'list_repos'],
})
// Change approval requirements
await theazo.mcp.update(class="cb-str">'mcp_abc', {
requiresApproval: [class="cb-str">'create_issue', class="cb-str">'create_pr'],
})Health checks
const health = await theazo.mcp.health(class="cb-str">'mcp_abc')
// → { status: 'connected', latencyMs: 45, lastPingAt: '2026-05-08T...' }
// If the server is down:
// → { status: 'error', latencyMs: 0, lastPingAt: '...', error: 'Connection timeout' }Disconnect
await theazo.mcp.disconnect(class="cb-str">'mcp_abc')
// Connection removed. Agents with this server will lose those tools.Behavior and edge cases
Server goes down
Status becomes 'error'. Tool calls return mcp_tool_unavailable. Theazo retries with backoff (5s, 15s, 60s, 5m). Fires mcp.connection_lost webhook.
Schema change
On periodic refresh or manual refresh(), new tools become available automatically. Removed tools return mcp_tool_unavailable mid-run.
Tool name collision
If two servers expose the same tool name, Theazo prefixes with server name: github_create_issue vs gitlab_create_issue. Warning logged at connection time.
stdio crash
Theazo restarts the process once. If it crashes again, marks tools unavailable for that agent only. Other agents are unaffected.
Rate limiting (429)
Theazo queues tool calls with backoff. The error is surfaced to the agent so it can adjust behavior.
Exposing Theazo as an MCP server
Theazo can also expose its own tool registry as an MCP server. External frameworks (LangChain, CrewAI, custom agents) can connect to Theazo's MCP endpoint to consume your built-in and custom tools without using the SDK.
// Get Theazo's MCP server URL
const url = theazo.mcp.serverUrl()
// → 'https://mcp.theazo.com/v1/th_live_abc...'
// Any MCP client can connect to this URL
// Configure which tools are exposed
await theazo.mcp.serverConfig({
expose: [class="cb-str">'web_search', class="cb-str">'http_request', class="cb-str">'update_crm'],
class="cb-cmt">// expose: '*' — all tools (default)
auth: class="cb-str">'api_key', class="cb-cmt">// MCP clients must include your Theazo API key
})
// Get current config
const config = await theazo.mcp.getServerConfig()
// → { expose: [...], auth: 'api_key', url: 'https://mcp.theazo.com/v1/...' }API reference
Client (connecting to servers)
theazo.mcp.connect(opts)Promise<MCPConnection>Connect to an external MCP server. Supports SSE, Streamable HTTP, and stdio transports.theazo.mcp.list()Promise<MCPConnection[]>List all MCP server connections for this platform.theazo.mcp.get(id)Promise<MCPConnection>Get a connection by ID.theazo.mcp.tools(id)Promise<MCPTool[]>List discovered tools from a connected server.theazo.mcp.refresh(id)Promise<MCPTool[]>Re-discover tools (re-runs tools/list on the server).theazo.mcp.update(id, opts)Promise<MCPConnection>Update connection credentials, tool filters, or approval requirements.theazo.mcp.health(id)Promise<MCPHealth>Health check. Returns status, latency, and last ping time.theazo.mcp.disconnect(id)Promise<void>Disconnect and remove a connection.Per-user credentials
theazo.mcp.setUserCredentials(id, userId, opts)Promise<void>Set per-user auth headers for a per_user connection. Encrypted at rest.theazo.mcp.deleteUserCredentials(id, userId)Promise<void>Remove per-user credentials.Server (exposing Theazo)
theazo.mcp.serverUrl()stringGet Theazo's MCP server URL for external frameworks to connect to.theazo.mcp.serverConfig(config)Promise<void>Configure which tools are exposed and auth requirements.theazo.mcp.getServerConfig()Promise<MCPServerConfigResponse>Get current MCP server configuration and URL.