关于 tools-and-context
这是一项 Tambo 技能,通过自定义工具、MCP 服务和上下文提供应用数据与能力,涵盖服务端和客户端的 MCP 配置、动态上下文、附件及可提及资源。
主要功能
- 01通过 Schema 注册 JavaScript 工具
- 02在服务端或客户端连接 MCP 服务
- 03动态添加和移除上下文助手
- 04为消息附加一次性上下文
- 05注册静态和动态资源
适用场景
- 01向 Tambo 提供应用函数
- 02连接外部 MCP 工具和资源
- 03将页面状态或所选文件作为上下文
- 04通过提及引用文档
MCP 相关
介绍如何从控制面板或 React 客户端将 MCP 服务连接到 Tambo,并使用 StreamableHTTP 或 SSE。MCP 服务可提供工具、资源和提示词。
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ tambo-ai/ tambo --skill tools-and-context安装后在 Claude Code 中输入/tools-and-context确认已加载。
详细介绍
工具和上下文
通过工具、MCP 服务和上下文,为 Tambo 提供数据和能力。
快速入门
// 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>;
自定义工具
注册 Tambo 可调用的 JavaScript 函数:
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>;
工具要点
- inputSchema:用于参数的 Zod 对象,请在字段上使用
.describe() - outputSchema:用于返回值的 Zod 架构(可选)
- tool:接收包含输入参数的单个对象的函数
- transformToContent:启用丰富内容响应(图像、格式化文本)
MCP 服务
连接到外部 MCP 服务以使用工具、资源和提示词:
| 功能 | 服务端 | 客户端 |
|---|---|---|
| 性能 | 快速(直接) | 较慢(浏览器代理) |
| 身份验证 | OAuth + API 密钥 | 仅限浏览器会话 |
| 本地服务 | 否 | 是(localhost) |
| 配置 | Tambo 控制面板 | React 代码 |
服务端设置
- 前往项目控制面板
- 点击“Add MCP Server”
- 输入 URL 和服务类型(StreamableHTTP 或 SSE)
- 根据需要完成 OAuth
客户端设置
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>;
上下文助手
在每条消息中提供动态上下文:
<TamboProvider
contextHelpers={{
currentPage: () => ({ url: window.location.href }),
currentTime: () => ({ time: new Date().toISOString() }),
selectedItems: () => selectedItems.map((i) => i.name),
}}
>
<App />
</TamboProvider>
动态上下文助手
在运行时添加或移除助手:
const { addContextHelper, removeContextHelper } = useTamboContextHelpers();
useEffect(() => {
addContextHelper("project", () => ({ projectId, projectName }));
return () => removeContextHelper("project");
}, [projectId, projectName, addContextHelper, removeContextHelper]);
上下文附件
仅为下一条消息提供一次性上下文(发送后清除):
const { addContextAttachment, attachments, removeContextAttachment } =
useTamboContextAttachment();
function handleSelectFile(file) {
addContextAttachment({
context: file.content,
displayName: file.name,
type: "file",
});
}
本地资源
注册用户可通过 @ 提及并在消息中引用的资源:
静态资源
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>;
动态资源
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>;
以编程方式注册
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",
})),
);
上下文类型概要
| 类型 | 调用时机 | 使用场景 |
|---|---|---|
| 上下文助手 | 每条消息 | 环境状态(当前页面、时间) |
| 上下文附件 | 仅下一条消息 | 用户选择的文件、选区 |
| 资源 | 被 @ 提及时 | 文档、可搜索数据 |
评论
支持 Markdown