unsplash-mcp-server について
名前とは異なり、この README は Unsplash 連携の説明ではなく、MCP サーバー構築の一般的なガイドです。プロトコル設計、トランスポート、サーバー機能、実装、セキュリティを扱います。
主な機能
- 01MCP の構造とメッセージのライフサイクル
- 02Stdio と SSE のトランスポート例
- 03ツール、リソース、プロンプト
- 04TypeScript SDK によるサーバー構築手順
- 05セキュリティとエラー処理の指針
活用シーン
- 01MCP サーバーとクライアントの役割を学ぶ
- 02Stdio と SSE の例を比較する
- 03基本的な TypeScript MCP サーバーを構築する
- 04トランスポートとセキュリティの注意点を確認する
MCP 対応
README は MCP サーバーの設計と実装を説明し、サーバーが MCP クライアントにツール、リソース、プロンプトを公開する方法を扱います。Unsplash 固有の機能は記載されていません。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
unsplash-mcp-server
モデルコンテキストプロトコル(MCP)サーバー開発ガイド:LLM 向けの強力なツールを構築する
目次
1. MCP サーバーの紹介
モデルコンテキストプロトコル(MCP)とは?
モデルコンテキストプロトコル(MCP)は、大規模言語モデル(LLM)アプリケーション(クライアント)と外部サービス(サーバー)間のやり取りを促進する、標準化された通信プロトコルです。これらのサーバーは、コンテキスト情報、ツール、リソースを提供します。MCP は関心事を明確に分離し、LLM アプリケーションがデータの取得、外部 API へのアクセス、特殊な計算などのタスクを、それぞれを担うサーバーに委任できるようにします。
MCP エコシステムにおけるサーバーの役割
サーバーは MCP エコシステムの中核であり、LLM アプリケーションと外部の世界をつなぐ仲介役を務めます。サーバーは次のようなさまざまな機能を提供できます。
- リアルタイムデータの提供: データベース、API、その他のソースから情報を取得します。
- 特化したツールの公開: 画像処理、コード実行、データ分析などの機能を提供します。
- プロンプトの管理と共有: 事前定義されたプロンプトやプロンプトテンプレートを保存し、提供します。
- 外部システムとの接続: 他のアプリケーション、サービス、プラットフォームと統合します。
MCP サーバーを実装するメリット
MCP サーバーを実装すると、次のようなさまざまなメリットがあります。
- 拡張性: LLM アプリケーションのコアコードを変更せずに、新しい機能を簡単に追加できます。
- モジュール性: 特化した機能を独立した再利用可能なコンポーネントとして開発、保守できます。
- 相互運用性: 異なる LLM アプリケーション間で、同じコンテキストソースやツールを共有できます。
- スケーラビリティ: ワークロードを分散し、複雑なタスクを効率的に処理できます。
- イノベーション: LLM の力を活用し、独自の機能や統合の開発に集中できます。
サーバーとクライアント:関係を理解する
MCP アーキテクチャでは、次のようになっています。
- クライアントは通常、LLM アプリケーション(Claude Desktop、VS Code、またはカスタムアプリケーション)であり、サーバーに接続してサービスをリクエストします。
- サーバーはクライアントのリクエストを処理して応答を返す独立したプロセスであり、ツール、リソース、プロンプトなどの機能を公開します。
1 つのクライアントは複数のサーバーに接続でき、1 つのサーバーは複数のクライアントをサポートできます。この多対多の関係により、柔軟で強力な統合が可能になります。
2. コアサーバーアーキテクチャ
MCP サーバーの主要コンポーネント
MCP サーバーは、複数の主要コンポーネントが連携して動作するシステムです。
- プロトコル層: この層は、メッセージのフレーミング、リクエストとレスポンスの関連付け、通知の処理など、高レベルの通信パターンを処理します。
Protocol、Client、Serverなどのクラスが含まれます。 - トランスポート層: この層は、クライアントとサーバー間の実際の通信を管理します。MCP は、Stdio や HTTP(Server-Sent Events(SSE))など、複数のトランスポートメカニズムをサポートしています。すべてのトランスポートは、メッセージ交換に JSON-RPC 2.0 を使用します。
- 機能(Capabilities): サーバーができることを定義します。機能には、ツール(実行可能な関数)、リソース(データソース)、プロンプト(LLM 向けに事前定義されたテキスト入力)が含まれます。
プロトコルの基本原則
MCP はクライアント・サーバーアーキテクチャに基づいて構築されています。LLM アプリケーション(ホスト)が接続を開始します。クライアントはホストアプリケーション内でサーバーとの 1 対 1 の接続を維持します。サーバーはクライアントにコンテキスト、ツール、プロンプトを提供します。
サーバーのライフサイクル:接続、交換、終了
MCP 接続のライフサイクルは、次の 3 つの主な段階で構成されます。
-
初期化:
- クライアントは、プロトコルのバージョンと機能を含む
initializeリクエストを送信します。 - サーバーは、自身のプロトコルバージョンと機能を応答として返します。
- クライアントは
initialized通知を送信して確認します。 - その後、通常のメッセージ交換が開始されます。
- クライアントは、プロトコルのバージョンと機能を含む
-
メッセージ交換: 初期化後、クライアントとサーバーは次のようなパターンでメッセージを交換します。
- リクエスト・レスポンス: 一方がリクエストを送信し、もう一方がレスポンスを返します。
- 通知: 一方がメッセージを送信します(レスポンスはありません)。
-
終了: 接続はいくつかの方法で終了できます。
close()メソッドによる正常終了。- トランスポート接続の終了。
- エラーの発生による終了。
メッセージ形式とトランスポート
MCP はメッセージ形式として JSON-RPC 2.0 を使用します。主なメッセージタイプは 3 つあります。
- リクエスト(Requests): レスポンスを期待するメッセージで、
methodと省略可能なparamsを含みます。
{
"jsonrpc": "2.0",
"id": "1",
"method": "method_name",
"params": { "key": "value" }
}
- レスポンス(Responses): リクエストへの応答で、
result(成功時)またはerror(失敗時)を含みます。
{
"jsonrpc": "2.0",
"id": "1",
"result": { "key": "value" }
}
- 通知(Notifications): レスポンスを期待しない一方向メッセージです。
methodと省略可能なparamsを含みます。
{
"jsonrpc": "2.0",
"method": "method_name",
"params": { "key": "value" }
}
전송 방식
MCP는 여러 전송 메커니즘을 지원합니다. 기본적으로 두 가지 전송이 제공됩니다:
- 표준 입력/출력 (stdio): 이 전송은 표준 입력과 출력을 사용하며, 로컬 통합 및 명령줄 도구에 적합합니다.
서버 예시:
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = new McpServer({
name: "example-server",
version: "1.0.0"
}, { capabilities: {} });
const transport = new StdioServerTransport();
await server.connect(transport);
클라이언트 예시:
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
const client = new Client({
name: "example-client",
version: "1.0.0"
}, { capabilities: {} });
const transport = new StdioClientTransport({
command: "./server", // 서버 실행 파일 경로
args: ["--option", "value"] // 선택적 인수
});
await client.connect(transport);
- 서버-전송 이벤트(SSE): 이 전송은 HTTP POST 요청을 클라이언트-서버 통신에 사용하고, 서버-클라이언트 스트리밍을 위해 Server-Sent Events를 사용합니다.
서버 예시:
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
import express, { Response } from 'express';
const server = new McpServer({
name: "example-server",
version: "1.0.0"
}, { capabilities: {} });
const app = express();
app.use(express.json());
app.get("/sse", async (req, res) => {
const transport = new SSEServerTransport("/messages", res as Response);
await server.connect(transport);
app.locals.transport = transport;
});
app.post("/messages", async (req, res) => {
const transport = app.locals.transport;
await transport.handlePostMessage(req, res);
});
app.listen(3000, () => {
console.log('Server listening on port 3000');
});
클라이언트 예시:
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
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:3000/sse")
);
await client.connect(transport);
커스텀 전송
MCP는 커스텀 전송 구현을 지원합니다. 커스텀 전송은 Transport 인터페이스를 구현해야 합니다.
interface Transport {
start(): Promise<void>;
send(message: JSONRPCMessage): Promise<void>;
close(): Promise<void>;
onclose?: () => void;
onerror?: (error: Error) => void;
onmessage?: (message: JSONRPCMessage) => void;
}
오류 처리
전송 구현은 연결 오류, 메시지 파싱 오류, 프로토콜 오류, 네트워크 시간 초과 및 리소스 정리를 처리해야 합니다. 예시:
class ExampleTransport implements Transport {
onclose?: () => void;
onerror?: (error: Error) => void;
onmessage?: (message: JSONRPCMessage) => void;
async start() {
try {
// 연결 로직
} catch (error) {
this.onerror?.(new Error(`Failed to connect: ${error}`));
throw error;
}
}
async send(message: JSONRPCMessage) {
try {
// 전송 로직
} catch (error) {
this.onerror?.(new Error(`Failed to send message: ${error}`));
throw error;
}
}
async close(): Promise<void> {
// 종료 로직
}
}
3. 첫 번째 MCP 서버 구축하기
이 섹션은 TypeScript SDK를 사용하여 기본 MCP 서버를 만드는 과정을 안내합니다.
개발 환경 설정
- Node.js와 npm 설치: Node.js(버전 18 이상)와 npm(Node Package Manager)을 시스템에 설치하십시오.
- 프로젝트 디렉토리 생성:
mkdir my-mcp-server
cd my-mcp-server
- Node.js 프로젝트 초기화:
npm init -y
- MCP TypeScript SDK 설치:
npm install @modelcontextprotocol/sdk
- TypeScript 및 기타 의존성 설치:
npm install typescript zod
tsconfig.json파일 생성:
{
"compilerOptions": {
"target": "ES2020",
"module": "NodeNext",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"outDir": "./build"
},
"include": ["src/**/*"]
}
src디렉토리 및index.ts파일 생성:
mkdir src
touch src/index.ts
SDK 선택
@modelcontextprotocol/sdk는 TypeScript로 MCP 서버를 구축하는 데 편리한 방법을 제공합니다. 프로토콜 세부 사항을 처리하므로 서버의 기능 구현에 집중할 수 있습니다.
서버 인터페이스 구현
간단한 입력을 반환하는 서버를 만들겠습니다. src/index.ts 파일에 다음 내용을 작성합니다:
#!/usr/bin/env node
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
// MCP 서버 인스턴스 생성
const server = new McpServer({
name: 'EchoServer',
version: '1.0.0',
});
// 입력을 그대로 되돌려주는 도구 추가
server.tool(
'echo',
{ message: z.string() }, // 입력 스키마 정의
async ({ message }) => ({
content: [{ type: 'text', text: `Echo: ${message}` }],
})
);
// 전송 방식 생성 (이번 예시에서는 stdio 사용)
const transport = new StdioServerTransport();
// 서버와 전송 연결
await server.connect(transport);
연결 및 인증 처리
이 간단한 예에서는 StdioServerTransport를 사용하여 연결을 자동으로 처리합니다. 더 복잡한 시나리오에서는 다른 전송 메커니즘을 사용할 때 커스텀 연결 처리 및 인증을 구현해야 할 수 있습니다.
클라이언트 요청 처리
server.tool() 메서드는 서버가 처리할 "echo"라는 도구를 정의합니다. 두 번째 인수는 { message: z.string() }로 zod 라이브러리를 사용하여 도구의 예상 입력 스키마를 정의합니다. 세 번째 인수는 비동기 함수로 입력을 받아 결과를 반환합니다. McpServer는 자동으로 클라이언트의 요청을 적절한 도구로 라우팅합니다.
이 서버를 실행하려면:
- TypeScript 코드 컴파일:
npx tsc
- 컴파일된 JavaScript 실행:
node build/index.js
package.json의 scripts 섹션에 다음을 추가하십시오:
"scripts": {
"build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
"start": "node build/index.js"
}
이제 npm run build와 npm start를 실행할 수 있습니다. ./build/index.js를 실행하고 JSON-RPC 2.0 메시지를 입력하여 테스트할 수 있습니다.
echo 도구로 유효한 JSON-RPC 2.0 메시지 예시:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": { "name": "echo", "arguments": { "message": "Hello, world!" } }
}
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。