FastMCP
FastMCP 是一个 TypeScript 框架,用于构建具有客户端会话管理的MCP服务器。
[!笔记]
对于 Python 实现,请参阅FastMCP Python 。
主要特点
FastMCP 提供以下功能:
如何安装
快速入门
[!笔记]
FastMCP 有许多现实世界的用例。请参阅案例研究。
import { FastMCP } from "fastmcp";
import { z } from "zod"; // または他の検証ライブラリ(Standard Schemaをサポートしているもの)
const server = new FastMCP({
name: "マイサーバー",
version: "1.0.0",
});
server.addTool({
name: "add",
description: "2つの数値を足し算します",
parameters: z.object({
a: z.number(),
b: z.number(),
}),
execute: async (args) => {
return String(args.a + args.b);
},
});
server.start({
transportType: "stdio",
});
现在您有一个可以运行的 MCP 服务器!
您可以在终端中使用以下命令进行测试:
git clone https://github.com/punkpeye/fastmcp.git
cd fastmcp
pnpm install
pnpm build
# CLIを使った足し算サーバーの例をテスト:
npx fastmcp dev src/examples/addition.ts
# MCP Inspectorを使った足し算サーバーの例を検査:
npx fastmcp inspect src/examples/addition.ts
上交所
服务器发送事件(SSE) 是一种服务器通过 HTTPS 连接向客户端发送实时更新的机制。在 MCP 中,SSE 主要用于实现远程 MCP 通信,允许访问托管在远程机器上的 MCP 并通过网络传递更新。
您还可以运行支持 SSE 的服务器:
server.start({
transportType: "sse",
sse: {
endpoint: "/sse",
port: 8080,
},
});
这将启动一个服务器,监听http://localhost:8080/sse
上的 SSE 连接。
然后您可以使用SSEClientTransport
连接到服务器:
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
const client = new Client(
{
name: "example-client",
version: "1.0.0",
},
{
capabilities: {},
},
);
const transport = new SSEClientTransport(new URL(`http://localhost:8080/sse`));
await client.connect(transport);
基本概念
工具
在 MCP工具中,服务器公开客户端和 LLM 可以调用来执行操作的可执行函数。
FastMCP 使用标准模式规范来定义工具参数。这使您可以使用实现规范的最喜欢的模式验证库,例如 Zod、ArkType 或 Valibot。
Zod示例:
import { z } from "zod";
server.addTool({
name: "fetch-zod",
description: "URLのコンテンツを取得します(Zodを使用)",
parameters: z.object({
url: z.string(),
}),
execute: async (args) => {
return await fetchWebpageContent(args.url);
},
});
ArkType示例:
import { type } from "arktype";
server.addTool({
name: "fetch-arktype",
description: "URLのコンテンツを取得します(ArkTypeを使用)",
parameters: type({
url: "string",
}),
execute: async (args) => {
return await fetchWebpageContent(args.url);
},
});
Valibot 的示例:
Valibot 需要对等依赖:@valibot/to-json-schema。
import * as v from "valibot";
server.addTool({
name: "fetch-valibot",
description: "URLのコンテンツを取得します(Valibotを使用)",
parameters: v.object({
url: v.string(),
}),
execute: async (args) => {
return await fetchWebpageContent(args.url);
},
});
返回字符串
execute
可以返回一个字符串:
server.addTool({
name: "download",
description: "ファイルをダウンロードします",
parameters: z.object({
url: z.string(),
}),
execute: async (args) => {
return "こんにちは、世界!";
},
});
这相当于:
server.addTool({
name: "download",
description: "ファイルをダウンロードします",
parameters: z.object({
url: z.string(),
}),
execute: async (args) => {
return {
content: [
{
type: "text",
text: "こんにちは、世界!",
},
],
};
},
});
返回列表
如果要返回消息列表,可以返回具有content
属性的对象:
server.addTool({
name: "download",
description: "ファイルをダウンロードします",
parameters: z.object({
url: z.string(),
}),
execute: async (args) => {
return {
content: [
{ type: "text", text: "1つ目のメッセージ" },
{ type: "text", text: "2つ目のメッセージ" },
],
};
},
});
返回图像
要创建图像内容对象,请使用imageContent
:
import { imageContent } from "fastmcp";
server.addTool({
name: "download",
description: "ファイルをダウンロードします",
parameters: z.object({
url: z.string(),
}),
execute: async (args) => {
return imageContent({
url: "https://example.com/image.png",
});
// または...
// return imageContent({
// path: "/path/to/image.png",
// });
// または...
// return imageContent({
// buffer: Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=", "base64"),
// });
// または...
// return {
// content: [
// await imageContent(...)
// ],
// };
},
});
imageContent
函数接受以下选项:
url
:图片的 URLpath
:图像文件的路径buffer
:图像数据作为缓冲区
必须指定url
、 path
或buffer
中的一个。
上面的例子等价于:
server.addTool({
name: "download",
description: "ファイルをダウンロードします",
parameters: z.object({
url: z.string(),
}),
execute: async (args) => {
return {
content: [
{
type: "image",
data: "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=",
mimeType: "image/png",
},
],
};
},
});
日志记录
工具可以使用上下文对象的log
将消息记录到客户端:
server.addTool({
name: "download",
description: "ファイルをダウンロードします",
parameters: z.object({
url: z.string(),
}),
execute: async (args, { log }) => {
log.info("ファイルをダウンロード中...", {
url: args.url,
});
// ...
log.info("ファイルをダウンロードしました");
return "完了";
},
});
log
对象有以下方法:
debug(message: string, data?: SerializableValue)
error(message: string, data?: SerializableValue)
info(message: string, data?: SerializableValue)
warn(message: string, data?: SerializableValue)
错误
应该向用户显示的错误应该作为UserError
实例抛出:
import { UserError } from "fastmcp";
server.addTool({
name: "download",
description: "ファイルをダウンロードします",
parameters: z.object({
url: z.string(),
}),
execute: async (args) => {
if (args.url.startsWith("https://example.com")) {
throw new UserError("このURLは許可されていません");
}
return "完了";
},
});
进度通知
工具可以通过调用上下文对象上的reportProgress
来报告其进度:
server.addTool({
name: "download",
description: "ファイルをダウンロードします",
parameters: z.object({
url: z.string(),
}),
execute: async (args, { reportProgress }) => {
reportProgress({
progress: 0,
total: 100,
});
// ...
reportProgress({
progress: 100,
total: 100,
});
return "完了";
},
});
资源
资源代表 MCP 服务器想要向其客户端提供的任何类型的数据。其中包括:
每个资源由唯一的 URI 标识,并且可以包含文本或二进制数据。
server.addResource({
uri: "file:///logs/app.log",
name: "アプリケーションログ",
mimeType: "text/plain",
async load() {
return {
text: await readLogFile(),
};
},
});
[!笔记]
load
可以返回多个资源。例如,这可用于在读取目录时返回目录中的文件列表。
async load() {
return [
{
text: "1つ目のファイルの内容",
},
{
text: "2つ目のファイルの内容",
},
];
}
您还可以使用load
返回二进制内容:
async load() {
return {
blob: 'base64でエンコードされたデータ'
};
}
资源模板
您还可以定义资源模板:
server.addResourceTemplate({
uriTemplate: "file:///logs/{name}.log",
name: "アプリケーションログ",
mimeType: "text/plain",
arguments: [
{
name: "name",
description: "ログの名前",
required: true,
},
],
async load({ name }) {
return {
text: `${name}のサンプルログ内容`,
};
},
});
资源模板参数的自动完成
为了实现资源模板参数的自动完成,我们提供了一个complete
函数:
server.addResourceTemplate({
uriTemplate: "file:///logs/{name}.log",
name: "アプリケーションログ",
mimeType: "text/plain",
arguments: [
{
name: "name",
description: "ログの名前",
required: true,
complete: async (value) => {
if (value === "サンプル") {
return {
values: ["サンプルログ"],
};
}
return {
values: [],
};
},
},
],
async load({ name }) {
return {
text: `${name}のサンプルログ内容`,
};
},
});
迅速的
Prompts允许服务器定义可重复使用的提示模板和工作流程,客户端可以轻松地将其呈现给其用户和 LLM。这为标准化和共享常见的 LLM 交互提供了一种强大的方法。
server.addPrompt({
name: "git-commit",
description: "Gitコミットメッセージを生成します",
arguments: [
{
name: "changes",
description: "Gitの差分または変更の説明",
required: true,
},
],
load: async (args) => {
return `これらの変更に対する簡潔かつ説明的なコミットメッセージを生成してください:\n\n${args.changes}`;
},
});
提示参数自动完成
提示可以提供参数的自动完成:
server.addPrompt({
name: "countryPoem",
description: "国についての詩を書きます",
load: async ({ name }) => {
return `こんにちは、${name}さん!`;
},
arguments: [
{
name: "name",
description: "国の名前",
required: true,
complete: async (value) => {
if (value === "日") {
return {
values: ["日本"],
};
}
return {
values: [],
};
},
},
],
});
使用enum
自动完成提示参数
如果您为参数提供enum
数组,服务器将自动提供参数完成。
server.addPrompt({
name: "countryPoem",
description: "国についての詩を書きます",
load: async ({ name }) => {
return `こんにちは、${name}さん!`;
},
arguments: [
{
name: "name",
description: "国の名前",
required: true,
enum: ["日本", "フランス", "イタリア"],
},
],
});
认证
FastMCP 允许您使用自定义函数对客户端authenticate
:
import { AuthError } from "fastmcp";
const server = new FastMCP({
name: "マイサーバー",
version: "1.0.0",
authenticate: ({request}) => {
const apiKey = request.headers["x-api-key"];
if (apiKey !== '123') {
throw new Response(null, {
status: 401,
statusText: "Unauthorized",
});
}
// ここで返すものは`context.session`オブジェクトでアクセスできます
return {
id: 1,
}
},
});
您现在可以在工具中访问经过身份验证的会话数据:
server.addTool({
name: "sayHello",
execute: async (args, { session }) => {
return `こんにちは、${session.id}さん!`;
},
});
会议
session
对象是FastMCPSession
的一个实例,描述一个活动的客户端会话。
为了允许客户端和服务器之间的一对一通信,每个客户端连接都会分配一个新的服务器实例。
类型化服务器事件
您可以使用on
方法监听服务器发出的事件:
server.on("connect", (event) => {
console.log("クライアント接続:", event.session);
});
server.on("disconnect", (event) => {
console.log("クライアント切断:", event.session);
});
FastMCPSession
FastMCPSession
代表一个客户端会话并提供与客户端交互的方法。
请参阅Session示例以了解如何获取FastMCPSession
实例。
requestSampling
requestSampling
发出采样请求并返回响应。
await session.requestSampling({
messages: [
{
role: "user",
content: {
type: "text",
text: "現在のディレクトリにはどのファイルがありますか?",
},
},
],
systemPrompt: "あなたは役立つファイルシステムアシスタントです。",
includeContext: "thisServer",
maxTokens: 100,
});
clientCapabilities
clientCapabilities
属性包含客户端功能。
session.clientCapabilities;
loggingLevel
loggingLevel
属性描述客户端设置的日志记录级别。
roots
roots
属性包含客户端设置的路线。
server
server
属性包含与会话关联的 MCP 服务器的实例。
类型化会话事件
您可以使用on
方法监听会话发出的事件:
session.on("rootsChanged", (event) => {
console.log("ルート変更:", event.roots);
});
session.on("error", (event) => {
console.error("エラー:", event.error);
});
运行服务器
使用 MCP-CLI 进行测试
测试和调试服务器的最快方法是使用fastmcp dev
:
npx fastmcp dev server.js
npx fastmcp dev server.ts
这将运行一个服务器,使用mcp-cli
在终端中测试和调试您的 MCP 服务器。
使用 MCP Inspector 进行检查
另一种选择是使用官方MCP Inspector
在 WebUI 中检查您的服务器:
npx fastmcp inspect server.ts
常问问题
如何与 Claude Desktop 一起使用?
按照指南https://modelcontextprotocol.io/quickstart/user并添加以下配置:
{
"mcpServers": {
"my-mcp-server": {
"command": "npx",
"args": [
"tsx",
"/プロジェクトへのパス/src/index.ts"
],
"env": {
"環境変数名": "値"
}
}
}
}
案例研究
[!笔记]
如果你已经使用 FastMCP 开发了服务器,请提交 PR并作为案例研究介绍!
致谢