MCP Server Baseline
リモートMCP(Model Context Protocol)サーバーのテンプレートプロジェクトです。中身を入れ替えて、自分だけのMCPサーバーを構築できます。
このリポジトリの目的
- MCPサーバーの動作例: Streamable HTTP Transport で動くMCPサーバーの実装例
- テンプレート: フォークして中身を差し替えるだけで独自のMCPサーバーが作れる
- デプロイ可能: Google Cloud Run にそのままデプロイ可能
サンプル実装: 記事レコメンダー
デモ用に「次に読むべき記事を推薦する」ツールが実装されています。
ユーザー: 「TypeScript入門を読んでるんだけど、次はこの中からどれがいい?
React入門、Python入門、TypeScript応用」
LLM: ツールを呼び出して推薦結果を返すこのロジックは入れ替え可能です。
クイックスタート
# インストール
npm install
# 開発サーバー起動
npm run dev
# テスト実行
npm test
# サンプルクライアントで動作確認(別ターミナルで)
npm run clientサーバーは http://localhost:3000 で起動します。
MCP の仕組み
┌─────────────┐ HTTP ┌─────────────────┐
│ ChatGPT │ ──────────────▶│ MCP Server │
│ Claude │ /mcp │ (このサーバー) │
└─────────────┘ └─────────────────┘
│
┌───────┴───────┐
│ │
ツール登録 リクエスト処理
(index.ts) (recommend.ts)主要コンポーネント
| ファイル | 役割 |
|---|---|
src/index.ts | Express + MCP サーバー設定、ツール登録 |
src/types.ts | Zod スキーマ定義(入力バリデーション) |
src/recommend.ts | ビジネスロジック(入れ替え対象) |
ツール登録の仕組み
// src/index.ts
server.tool(
"recommend_next_article", // ツール名
"ツールの説明文", // LLMが参照する説明
RecommendInputSchema.shape, // Zodスキーマ(自動バリデーション)
async (args) => { // ハンドラー
const result = recommendNextArticle(args);
return { content: [{ type: "text", text: JSON.stringify(result) }] };
}
);カスタマイズ方法
自分のMCPサーバーを作るには、以下の3ファイルを変更します。
1. スキーマ定義 (src/types.ts)
import { z } from "zod";
// 入力スキーマを定義
export const MyInputSchema = z.object({
query: z.string().describe("検索クエリ"),
limit: z.number().optional().default(10),
});
export type MyInput = z.infer;
// 出力の型を定義
export interface MyOutput {
results: string[];
}2. ロジック実装 (src/recommend.ts → リネーム推奨)
import type { MyInput, MyOutput } from "./types.js";
export function myBusinessLogic(input: MyInput): MyOutput {
// あなたのロジックをここに
return { results: ["結果1", "結果2"] };
}3. ツール登録 (src/index.ts)
import { MyInputSchema } from "./types.js";
import { myBusinessLogic } from "./my-logic.js";
server.tool(
"my_tool_name",
"ツールの説明(LLMがこれを見て使い方を判断する)",
MyInputSchema.shape,
async (args) => {
const result = myBusinessLogic(args as MyInput);
return { content: [{ type: "text", text: JSON.stringify(result) }] };
}
);4. テスト更新 (tests/)
新しいロジックに合わせてテストを更新します。
現在のサンプル実装
ツール: recommend_next_article
入力:
{
"reading": "現在読んでいる記事のタイトル",
"candidates": ["候補1", "候補2", "候補3"],
"maxResults": 3
}出力:
{
"picks": [
{ "title": "推薦記事", "reason": "推薦理由", "score": 0.85 }
],
"explanation": "分析の説明"
}アルゴリズム:
- タイトル類似度(Jaccard係数)× 0.7
- 補完性(新しい視点の提供度)× 0.3
プロジェクト構成
.
├── src/
│ ├── index.ts # Express + MCP サーバー設定
│ ├── types.ts # Zod スキーマ定義
│ ├── recommend.ts # ビジネスロジック(入れ替え対象)
│ └── sample_client.ts # テストクライアント
├── tests/
│ └── recommend.test.ts # ユニットテスト
├── Dockerfile # Cloud Run 用
├── package.json
└── tsconfig.jsonCloud Run デプロイ
必要条件
- Google Cloud CLI (
gcloud) - 課金が有効な GCP プロジェクト
デプロイ手順
# 変数設定
PROJECT_ID="your-project-id"
REGION="us-central1"
SERVICE_NAME="my-mcp-server"
# gcloud設定
gcloud config set project $PROJECT_ID
# API有効化
gcloud services enable run.googleapis.com cloudbuild.googleapis.com artifactregistry.googleapis.com
# デプロイ
gcloud run deploy $SERVICE_NAME \
--source . \
--region $REGION \
--allow-unauthenticated \
--set-env-vars NODE_ENV=productionデプロイ後、https://xxx.run.app 形式のURLが発行されます。
動作確認
# ヘルスチェック
curl https:///healthz
# クライアントでテスト
MCP_URL=https:///mcp npm run clientChatGPT から接続
- ChatGPT を開く(Plus/Team/Enterprise が必要)
- 設定 → アプリ → 高度な設定 → 開発者モードオン → アプリを作成する
- 以下のように入力:
- 作成する をクリック
これでチャット内でツールが使用可能になります。
本番環境での注意
デモでは --allow-unauthenticated を使用していますが、本番では認証を追加してください:
# IAM認証を有効化
gcloud run deploy $SERVICE_NAME \
--source . \
--region $REGION \
--no-allow-unauthenticatedその他のオプション:
- API Gateway で API キー認証
- VPC Service Controls で内部アクセス限定
- レート制限ミドルウェアの追加
