Tools and Context
Gives Tambo access to data and capabilities through tools, MCP servers, and context.
Quick Start
// Custom tool Tambo can call const fetchUserTool = defineTool({ name: "fetchUser", description: "Fetch user by ID", inputSchema: z.object({ userId: z.string() }), tool: async ({ userId }) => fetchUser(userId), });
<TamboProvider tools={[fetchUserTool]}> <App /> </TamboProvider>;
Custom Tools
Register JavaScript functions Tambo can call:
import { defineTool, TamboProvider } from "@tambo-ai/react"; import { z } from "zod";
const fetchUserTool = defineTool({ name: "fetchUser", description: "Fetch a user by ID", inputSchema: z.object({ userId: z.string().describe("The user ID to fetch"), }), outputSchema: z.object({ name: z.string(), email: z.string(), }), tool: async ({ userId }) => { const user = await fetchUser(userId); return user; }, });
<TamboProvider tools={[fetchUserTool]} components={components}> <App /> </TamboProvider>;
Tool Key Points
-
inputSchema: Zod object for parameters, use .describe() on fields
-
outputSchema: Zod schema for return value (optional)
-
tool: Function receives single object with input params
-
transformToContent: Enable rich content responses (images, formatted text)
MCP Servers
Connect to external MCP servers for tools, resources, prompts:
Feature Server-side Client-side
Performance Fast (direct) Slower (browser proxies)
Auth OAuth + API keys Browser session only
Local servers No Yes (localhost)
Config Tambo dashboard React code
Server-Side Setup
-
Go to project dashboard
-
Click "Add MCP Server"
-
Enter URL and server type (StreamableHTTP or SSE)
-
Complete OAuth if required
Client-Side Setup
npm install @modelcontextprotocol/sdk@^1.24.0 zod@^4.0.0 zod-to-json-schema@^3.25.0
import { TamboProvider } from "@tambo-ai/react"; import { MCPTransport } from "@tambo-ai/react/mcp";
<TamboProvider mcpServers={[ { url: "http://localhost:8123/", serverKey: "local", transport: MCPTransport.HTTP, }, ]}
<App /> </TamboProvider>;
Context Helpers
Provide dynamic context on every message:
<TamboProvider contextHelpers={{ currentPage: () => ({ url: window.location.href }), currentTime: () => ({ time: new Date().toISOString() }), selectedItems: () => selectedItems.map((i) => i.name), }}
<App /> </TamboProvider>
Dynamic Context Helpers
Add/remove helpers at runtime:
const { addContextHelper, removeContextHelper } = useTamboContextHelpers();
useEffect(() => { addContextHelper("project", () => ({ projectId, projectName })); return () => removeContextHelper("project"); }, [projectId, projectName, addContextHelper, removeContextHelper]);
Context Attachments
One-time context for the next message (cleared after sending):
const { addContextAttachment, attachments, removeContextAttachment } = useTamboContextAttachment();
function handleSelectFile(file) { addContextAttachment({ context: file.content, displayName: file.name, type: "file", }); }
Local Resources
Register @ mentionable resources users can reference in messages:
Static Resources
import { TamboProvider, ListResourceItem } from "@tambo-ai/react";
const resources: ListResourceItem[] = [ { uri: "docs://api", name: "API Reference", mimeType: "text/plain" }, { uri: "docs://faq", name: "FAQ", mimeType: "text/plain" }, ];
const getResource = async (uri: string) => { const content = await fetchDoc(uri); return { contents: [{ uri, mimeType: "text/plain", text: content }] }; };
<TamboProvider resources={resources} getResource={getResource}> <App /> </TamboProvider>;
Dynamic Resources
const listResources = async (search?: string) => {
const docs = await fetchDocs();
return docs
.filter((d) => !search || d.name.includes(search))
.map((d) => ({
uri: docs://${d.id},
name: d.title,
mimeType: "text/plain",
}));
};
const getResource = async (uri: string) => { const doc = await fetchDocument(uri); return { contents: [{ uri, mimeType: "text/plain", text: doc.content }] }; };
// Both listResources and getResource must be provided together <TamboProvider listResources={listResources} getResource={getResource}> <App /> </TamboProvider>;
Programmatic Registration
const { registerResource, registerResources } = useTamboRegistry();
// Single resource registerResource({ uri: "user://file.txt", name: "File", mimeType: "text/plain", });
// Batch registration
registerResources(
docs.map((d) => ({
uri: docs://${d.id},
name: d.title,
mimeType: "text/plain",
})),
);
Context Types Summary
Type When Called Use Case
Context Helpers Every message Ambient state (current page, time)
Context Attachments Next message only User-selected files, selections
Resources When @ mentioned Documentation, searchable data