🛺

FastMCPでMCPサーバーをTypescriptで簡単に作る

に公開

TypeScriptでMCPサーバーを構築するためのフレームワーク「FastMCP」

MCPというプロトコル、最近よく聞くようになったけど実際どうやって使うのか分からない人も多いはず。今回はTypeScriptでMCPサーバーを簡単に構築できるフレームワーク「FastMCP」を紹介。

https://github.com/punkpeye/fastmcp

MCPってそもそも何?

Model Context Protocol(MCP)は、LLMや各種AIツールとIDE(Cursor、Windsurf等)を連携させるためのプロトコル。これを使うと、AIに外部知識を与えたり、特定の機能を実行させたりすることが可能になる。

MCP対応IDEで使うには、.cursor/mcp.json(Cursorの場合)や~/.codeium/windsurf/mcp_config.json(Windsurfの場合)にサーバー設定を追加する。基本的な設定例はこんな感じ:

{
  "mcpServers": {
    "my-mcp-server": {
      "command": "pnpm",
      "args": [
        "dlx",
        "tsx",
        "/プロジェクトへのパス/src/index.ts"
      ]
    }
  }
}

これでIDEがMCPサーバーを自動的に起動し、AIアシスタントが外部知識やツールにアクセスできるようになる。

重要なのは、この設定によってIDE(CursorやWindsurf)が実際にローカルマシン上でコマンドを実行するということ。つまり、LLMアシスタントがこの設定を通じて指定されたプログラムを起動し、それを通じてファイルシステムへのアクセスやAPIコール、データ処理などを行えるようになる。これにより、AIアシスタントの能力を大幅に拡張できる。

上の例だと、IDEは pnpm dlx tsx /プロジェクトのパス/src/index.ts というコマンドをローカルマシン上で実行する。このコマンドはtsxを通じてTypeScriptファイルを直接実行し、MCPサーバーを立ち上げる。起動したサーバーはIDEと通信を開始し、AIアシスタントはサーバーが提供するツールやリソースを利用できるようになる。
(セキュリティの観点からも重要な点で、自分で作成したコードだけを実行するよう設定のが望ましい)

FastMCPの特徴

FastMCPはTypeScript製のフレームワーク。以下のような機能を備えている:

  • シンプルなツール、リソース、プロンプト定義
  • 認証機能
  • セッション管理
  • 画像コンテンツ対応
  • ログ記録とエラー処理
  • SSE(Server-Sent Events)サポート
  • CORSのデフォルト有効化
  • 進捗通知
  • 型付きサーバーイベント
  • 引数の自動補完
  • テスト用CLI

インストールと基本的な使い方

pnpm add fastmcp

基本的な使い方も単純。以下は2つの数値を足し算するサーバーの例:

import { FastMCP } from "fastmcp";
import { z } from "zod";

const server = new FastMCP({
  name: "My Server",
  version: "1.0.0",
});

server.addTool({
  name: "add",
  description: "Add two numbers",
  parameters: z.object({
    a: z.number(),
    b: z.number(),
  }),
  execute: async (args) => {
    return String(args.a + args.b);
  },
});

server.start({
  transportType: "stdio",
});

これだけでMCPサーバーの完成。zodを使った型定義が美しい。

SSE対応のサーバー構築

FastMCPはServer-Sent Events(SSE)もサポートしており、ウェブブラウザとリアルタイム通信ができる:

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

これでhttp://localhost:8080/sseでSSE接続を受け付けるサーバーが起動する。クライアント側では以下のように接続できる:

import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";

const transport = new SSEClientTransport({
  url: "http://localhost:8080/sse"
});

const client = new Client({
  name: "example-client",
  version: "1.0.0",
  transport
});

進捗報告機能も備えており、長時間実行されるツールで便利:

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

リソース機能

ファイル内容や画像などをクライアントに提供できるリソース機能も便利:

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

動的にリソースを生成するテンプレート機能も:

server.addResourceTemplate({
  uriTemplate: "file:///logs/{name}.log",
  name: "ログファイル",
  mimeType: "text/plain",
  arguments: [
    {
      name: "name",
      description: "ログ名",
      required: true,
    },
  ],
  async load({ name }) {
    return {
      text: `${name}のログ内容例`,
    };
  },
});

プロンプト機能

再利用可能なプロンプトテンプレートを定義できる機能も魅力的:

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

簡単なサーバーの建て方

FastMCPでシンプルなMCPサーバーを構築する手順は以下の通り:

  1. プロジェクトディレクトリを作成:
mkdir my-mcp-server
cd my-mcp-server
  1. 必要なパッケージをインストール:
pnpm init
pnpm add fastmcp zod
pnpm add -D typescript ts-node
  1. src/index.tsファイルを作成:
import { FastMCP } from "fastmcp";
import { z } from "zod";

// サーバーインスタンスを作成
const server = new FastMCP({
  name: "マイMCPサーバー",
  version: "1.0.0",
});

// 天気情報ツールを追加
server.addTool({
  name: "getWeather",
  description: "指定した都市の天気情報を取得",
  parameters: z.object({
    city: z.string().describe("都市名"),
  }),
  execute: async ({ city }) => {
    // 実際はAPI呼び出しなど
    return `${city}の天気は晴れです。気温は25度です。`;
  },
});

// プロジェクト情報リソースを追加
server.addResource({
  uri: "file:///project/info",
  name: "プロジェクト情報",
  mimeType: "text/plain",
  async load() {
    return {
      text: "これはマイMCPサーバーのプロジェクト情報です。"
    };
  },
});

// サーバーを起動(標準入出力)
server.start({
  transportType: "stdio",
});

// 以下のようにSSEサーバーとして起動することも可能
// server.start({
//   transportType: "sse",
//   sse: {
//     endpoint: "/mcp",
//     port: 3000,
//   },
// });
  1. サーバーを起動:
pnpm dlx ts-node src/index.ts
  1. または、FastMCPのCLIでテスト:
pnpm dlx fastmcp dev src/index.ts

これでMCPサーバーが起動し、CursorやWindsurfなどのIDEから利用できるようになる。

テストと動作確認

サーバーの動作確認は付属のCLIツールで簡単に:

pnpm dlx fastmcp dev サーバーファイル.ts

ウェブUIでの確認も可能:

pnpm dlx fastmcp inspect サーバーファイル.ts

CursorやWindsurfとの連携

Cursor等のIDEと連携するには、.cursor/mcp.jsonを次のように設定:

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

終わりに

FastMCPを使えば、TypeScriptでサクッとMCPサーバーが構築できる。AIと連携したカスタムツールやナレッジベースを作りたい人には最適なフレームワーク。今後もLLMとのインタラクションがさらに進化していく中で、重要度が増していくプロトコルになりそうです!

Discussion