Skip to main content
Glama

FastMCP

FastMCP는 클라이언트 세션 관리가 가능한 MCP 서버를 구축하기 위한 TypeScript 프레임워크입니다.

[!NOTE]

Python 구현 버전은 FastMCP Python 을 참조하십시오.

주요 기능

FastMCP는 다음 기능을 제공합니다.

Related MCP server: MCP Base Server

설치 방법

npm install fastmcp

빠른 시작

[!NOTE]

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

Server-Sent Events (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는 도구 매개변수를 정의하기 위해 Standard Schema 사양을 사용합니다. 이를 통해 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 인스턴스로 throw해야 합니다.

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

[!NOTE]

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

프롬프트

프롬프트 는 서버가 재사용 가능한 프롬프트 템플릿과 워크플로를 정의하여 클라이언트가 사용자나 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 은 클라이언트 세션을 나타내며 클라이언트와 상호 작용하는 방법을 제공합니다.

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

FAQ

Claude Desktop에서 사용하는 방법?

가이드 https://modelcontextprotocol.io/quickstart/user 에 따라 다음 설정을 추가하십시오.

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

사례 소개

[!NOTE]

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.
    -