FastMCP
FastMCP는 클라이언트 세션 관리가 가능한 MCP 서버를 구축하기 위한 TypeScript 프레임워크입니다.
[!NOTE]
Python 구현 버전은 FastMCP Python 을 참조하십시오.
주요 기능
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
: 이미지 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
인스턴스로 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
의 인스턴스이며 활성 클라이언트 세션을 설명합니다.
클라이언트와 서버 간의 일대일 통신을 가능하게 하기 위해 각 클라이언트 연결에 대해 새 서버 인스턴스를 할당합니다.
유형이 지정된 서버 이벤트
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
속성은 클라이언트가 설정한 로깅 수준을 설명합니다.
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
FAQ
Claude Desktop에서 사용하는 방법?
가이드 https://modelcontextprotocol.io/quickstart/user 에 따라 다음 설정을 추가하십시오.
{
"mcpServers": {
"my-mcp-server": {
"command": "npx",
"args": [
"tsx",
"/プロジェクトへのパス/src/index.ts"
],
"env": {
"環境変数名": "値"
}
}
}
}
사례 소개
[!NOTE]
FastMCP를 사용하여 서버를 개발한 경우 꼭 PR 제출 하여 사례로 소개해 주세요!
감사의 말