Skip to main content
Glama

FastMCP

FastMCP 是一个 TypeScript 框架,用于构建具有客户端会话管理的MCP服务器。

[!笔记]

对于 Python 实现,请参阅FastMCP Python 。

主要特点

FastMCP 提供以下功能:

Related MCP server: MCP Base Server

如何安装

npm install 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 :图片的 URL

  • path :图像文件的路径

  • 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的一个实例,描述一个活动的客户端会话。

server.sessions;

为了允许客户端和服务器之间的一对一通信,每个客户端连接都会分配一个新的服务器实例。

类型化服务器事件

您可以使用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属性描述客户端设置的日志记录级别。

session.loggingLevel;

roots

roots属性包含客户端设置的路线。

session.roots;

server

server属性包含与会话关联的 MCP 服务器的实例。

session.server;

类型化会话事件

您可以使用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并作为案例研究介绍!

致谢

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A TypeScript-based template for rapidly developing MCP servers with modular tool architecture, built-in validation using Zod schemas, and comprehensive error handling.
    8 npm
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides a starting template for building MCP servers with TypeScript, including examples of tools and resources to accelerate development.
    -