FastMCP

MIT License
6,371

Integrations

  • Enables generation of media content using Flux's AI image generation capabilities

  • Provides tools for generating Git commit messages based on code changes

  • Built as a TypeScript framework for constructing MCP servers with client session management

FastMCP

FastMCP is a TypeScript framework for building MCP servers with client session management.

[!NOTE]

For a Python implementation, see FastMCP Python .

Key Features

FastMCP offers the following features:

How to install

npm install fastmcp

Quickstart

[!NOTE]

There are many real-world use cases for FastMCP. Check out our case studies .

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", });

Now you have a working MCP server!

You can test it in the terminal with:

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

Server-Sent Events (SSE) is a mechanism by which a server can send real-time updates to a client over an HTTPS connection. In the context of MCP, SSE is primarily used to enable remote MCP communication, allowing an MCP hosted on a remote machine to be accessed and updates relayed over the network.

You can also run the server with SSE support:

server.start({ transportType: "sse", sse: { endpoint: "/sse", port: 8080, }, });

This will start a server, listening for SSE connections at http://localhost:8080/sse .

Then you can connect to the server using 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);

Basic Concepts

tool

In MCP tools , servers expose executable functions that clients and LLMs can call to perform actions.

FastMCP uses the Standard Schema specification for defining tool parameters, which allows you to use your favorite schema validation library that implements the specification, such as Zod, ArkType, or Valibot.

Zod example:

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 example:

import { type } from "arktype"; server.addTool({ name: "fetch-arktype", description: "URLのコンテンツを取得します(ArkTypeを使用)", parameters: type({ url: "string", }), execute: async (args) => { return await fetchWebpageContent(args.url); }, });

Example of Valibot:

Valibot requires a peer dependency: @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); }, });

Returning a String

execute can return a string:

server.addTool({ name: "download", description: "ファイルをダウンロードします", parameters: z.object({ url: z.string(), }), execute: async (args) => { return "こんにちは、世界!"; }, });

This is equivalent to:

server.addTool({ name: "download", description: "ファイルをダウンロードします", parameters: z.object({ url: z.string(), }), execute: async (args) => { return { content: [ { type: "text", text: "こんにちは、世界!", }, ], }; }, });

Returning a List

If you want to return a list of messages, you can return an object with content property:

server.addTool({ name: "download", description: "ファイルをダウンロードします", parameters: z.object({ url: z.string(), }), execute: async (args) => { return { content: [ { type: "text", text: "1つ目のメッセージ" }, { type: "text", text: "2つ目のメッセージ" }, ], }; }, });

Returning the images

To create an image content object, use 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(...) // ], // }; }, });

The imageContent function accepts the following options:

  • url : URL of the image
  • path : Path to the image file
  • buffer : Image data as a buffer

Exactly one of url , path or buffer must be specified.

The above example is equivalent to:

server.addTool({ name: "download", description: "ファイルをダウンロードします", parameters: z.object({ url: z.string(), }), execute: async (args) => { return { content: [ { type: "image", data: "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=", mimeType: "image/png", }, ], }; }, });

Logging

Tools can log messages to the client using the context object's 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 object has the following methods:

  • debug(message: string, data?: SerializableValue)
  • error(message: string, data?: SerializableValue)
  • info(message: string, data?: SerializableValue)
  • warn(message: string, data?: SerializableValue)

error

Errors that should be displayed to the user should be thrown as UserError instances:

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 "完了"; }, });

Progress Notifications

A tool can report its progress by calling reportProgress on the context object:

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 "完了"; }, });

resource

Resources represent any kind of data that an MCP server wants to provide to its clients. This includes:

  • File Contents
  • Screenshots and images
  • Log files
  • And many more

Each resource is identified by a unique URI and can contain text or binary data.

server.addResource({ uri: "file:///logs/app.log", name: "アプリケーションログ", mimeType: "text/plain", async load() { return { text: await readLogFile(), }; }, });

[!NOTE]

load can return multiple resources, this can be used for example to return a list of files in a directory when the directory is loaded.

async load() { return [ { text: "1つ目のファイルの内容", }, { text: "2つ目のファイルの内容", }, ]; }

You can also return binary content with load :

async load() { return { blob: 'base64でエンコードされたデータ' }; }

Resource Templates

You can also define resource templates:

server.addResourceTemplate({ uriTemplate: "file:///logs/{name}.log", name: "アプリケーションログ", mimeType: "text/plain", arguments: [ { name: "name", description: "ログの名前", required: true, }, ], async load({ name }) { return { text: `${name}のサンプルログ内容`, }; }, });

Auto-completion of resource template arguments

To enable auto-completion of resource template arguments, we provide a complete function:

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}のサンプルログ内容`, }; }, });

prompt

Prompts allows servers to define reusable prompt templates and workflows that clients can easily present to users and LLMs, providing a powerful way to standardize and share common LLM interactions.

server.addPrompt({ name: "git-commit", description: "Gitコミットメッセージを生成します", arguments: [ { name: "changes", description: "Gitの差分または変更の説明", required: true, }, ], load: async (args) => { return `これらの変更に対する簡潔かつ説明的なコミットメッセージを生成してください:\n\n${args.changes}`; }, });

Prompt Argument Auto-Completion

The prompt can provide auto-completion of arguments:

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: [], }; }, }, ], });

Auto-completion of prompt arguments using enum

If you provide an enum array for arguments, the server will automatically provide argument completion.

server.addPrompt({ name: "countryPoem", description: "国についての詩を書きます", load: async ({ name }) => { return `こんにちは、${name}さん!`; }, arguments: [ { name: "name", description: "国の名前", required: true, enum: ["日本", "フランス", "イタリア"], }, ], });

certification

FastMCP allows you to authenticate clients using a custom function:

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, } }, });

You can now access the authenticated session data in your tools:

server.addTool({ name: "sayHello", execute: async (args, { session }) => { return `こんにちは、${session.id}さん!`; }, });

session

session object is an instance of FastMCPSession and describes an active client session.

server.sessions;

To allow one-to-one communication between client and server, a new server instance is allocated for each client connection.

Typed Server Events

You can listen to events emitted by the server using the on method:

server.on("connect", (event) => { console.log("クライアント接続:", event.session); }); server.on("disconnect", (event) => { console.log("クライアント切断:", event.session); });

FastMCPSession

FastMCPSession represents a client session and provides methods for interacting with the client.

See the Session example for how to obtain FastMCPSession instance.

requestSampling

requestSampling makes a sampling request and returns the response.

await session.requestSampling({ messages: [ { role: "user", content: { type: "text", text: "現在のディレクトリにはどのファイルがありますか?", }, }, ], systemPrompt: "あなたは役立つファイルシステムアシスタントです。", includeContext: "thisServer", maxTokens: 100, });

clientCapabilities

clientCapabilities property contains the client capabilities.

session.clientCapabilities;

loggingLevel

loggingLevel property describes the logging level set by the client.

session.loggingLevel;

roots

roots property contains the routes set by the client.

session.roots;

server

server property contains the instance of the MCP server associated with the session.

session.server;

Typed Session Events

You can listen to events emitted by the session using on method:

session.on("rootsChanged", (event) => { console.log("ルート変更:", event.roots); }); session.on("error", (event) => { console.error("エラー:", event.error); });

Running the Server

Test with MCP-CLI

The fastest way to test and debug your server is to use fastmcp dev :

npx fastmcp dev server.js npx fastmcp dev server.ts

This will run a server for testing and debugging your MCP server in the terminal using mcp-cli .

Inspect with MCP Inspector

Another option is to inspect your server in the WebUI using the official MCP Inspector :

npx fastmcp inspect server.ts

FAQ

How to use with Claude Desktop?

Follow the guide https://modelcontextprotocol.io/quickstart/user and add the following configuration:

{ "mcpServers": { "my-mcp-server": { "command": "npx", "args": [ "tsx", "/プロジェクトへのパス/src/index.ts" ], "env": { "環境変数名": "値" } } } }

Case Study

[!NOTE]

If you have developed a server using FastMCP, please submit a PR and introduce it as a case study!

Acknowledgements

ID: cgkg5xtk38