はじめに
こんにちは、システム開発第1グループの清水です。
普段は主にPHPを利用して、「レコチョク」等の単曲販売サービスを担当しています。
システム開発第1グループではAI活用の取り組みに力を入れており、様々なAIコーディングツールやAIサービスの利用・検証を推進しています。
今回はそういった活動の一環として、シンプルなMCPサーバーを作ってみることに挑戦したので、記事としてまとめたいと思います。
そもそもMCPとは?
MCPについてそれほど詳しくない読者もいるかと思いますので、まずはMCPの概要を説明します。
MCPとはModel Context Protocolの略であり、LLMに対してデータ(コンテキスト)を渡すための標準規格を指します。
開発元のAnthropic社はこれを 「AIアプリケーションのためのUSB-Cポート」と例えており、LLMとコンテキストを提供するサーバーの接続方法と言ってもよいでしょう。
MCPサーバーとは?
MCPという規格を利用して通信を行う際には、3つのコンポーネントが必要です。
1つ目がMCPホスト。これはMCPを利用するアプリケーションのことで、Claude Desktop, Cursor, GitHub Copilotなどが該当します。
2つ目がMCPクライアント。これは通信を担当するシステムです。この後説明するMCPサーバーとの通信を行い、情報のやり取りを担当します。
3つ目がMCPサーバー。これはMCPの規格を使って、特定の機能をMCPホストに対して公開するプログラムです。Web APIのAIアプリケーション版だと思ってもらえば概ね合っていると思います。MCPサーバーのプログラムはLLMの要求に応じて外部ソースなどにアクセスし、必要なデータを渡す機能を提供します。
今回のテーマになっているMCPサーバーは、上記のようにMCPの通信における必須要素の1つとなっています。MCPサーバーは様々なリソースにアクセスする役割を担っていて、MCPによるLLMの能力拡張の中心的な役割を担っているという意味で特に重要と言えるかもしれません。
Model Context Protocol(MCP) 公式が出している概念図
引用: https://modelcontextprotocol.io/introduction
MCPサーバーを作る
それでは、一通りの概念を学んだところでMCPサーバーを作っていきましょう。
MCPサーバーをゼロからフルスクラッチで作ってもよいのですが、MCPの公式が便利なSDKを複数言語で用意してくれていますので、今回はその中のMCP TypeScript SDKを使っていきたいと思います。
SDKリンク: https://github.com/modelcontextprotocol/typescript-sdk
では今回作ろうと思うのはこちらです。
Claude Desktop(LLM)から標準入出力を通してDockerコンテナ上のMCPサーバーを叩き、bee-jokesと呼ばれるジョーク生成ライブラリを利用してMCPサーバーからClaude Desktop(LLM)へジョークを返すことを目指します。
これにより脳が疲れた時に、Claudeから通常よりもキレのあるジョークを言ってもらうことができるようになり、日常生活のストレスを和らげることができます。
ジョーク生成ライブラリ: https://www.npmjs.com/package/bee-jokes
環境構築・サーバー用コードを作成
まずは環境構築です。本プロジェクトではNode.js、TypeScript(npm環境)、Dockerが必要になります。
今回利用したバージョンは以下の通りです。
Node.js v22.17.1 TypeScript v5.8.3 npm v11.4.2 Docker v27.5.1 |
すべてを説明していると文量が多くなるので、これらの導入方法に関しては省略します。
では次に必要なライブラリの導入を行います。
npm install @modelcontextprotocol/sdk zod bee-jokes |
使用するのは上記3つです。ZodはSDKに強く統合されているので導入しましたが必須ではないです。
というわけでこれらを利用してMCPサーバーを起動するためのコードを作成しましょう。
/* index.ts */ import { Joke, Lang } from "bee-jokes"; 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: "bee-jokes", version: "1.0.0", }); // MCPサーバーに"jokes"というツール(LLMが使える機能)を登録 server.registerTool("jokes", { title: "respond jokes", description: "Get a random joke", inputSchema: { lang: z.string() }, }, async ({ lang }) => { const joke = new Joke(); const randomJoke = joke.getRandomJoke(lang as Lang); return { content: [{ type: "text", text: randomJoke?.joke ?? "No joke available" }], }; } ); // 標準入出力でリクエストを待機する(サーバー起動) (async () => { const transport = new StdioServerTransport(); await server.connect(transport); })(); |
このようにしてサーバーを生成、ツールを登録、サーバーを起動という流れでコードを実行することでMCPサーバーを立ち上げることができます。
MCPサーバーをDockerコンテナに載せる
次にTypeScriptのコードをDockerで実行し、コンテナ上でサーバーを起動する準備をします。
最初にDockerfileを作ります。
# Dockerfile # Node.js LTS版を使用 FROM node:22-alpine # 作業ディレクトリを設定 WORKDIR /app # package.jsonとpackage-lock.jsonをコピー COPY package*.json ./ # 依存関係をインストール RUN npm ci # TypeScriptをインストール RUN npm install -g typescript # tsconfig.jsonをコピー COPY tsconfig.json ./ # ソースコード(本体)をコピー COPY index.ts ./ # TypeScriptをコンパイル RUN tsc |
その次にDocker Composeで設定を行います。
# docker-compose.yml version: '3.8' services: bee-jokes-mcp: build: . container_name: bee-jokes-mcp-server restart: unless-stopped # コンテナが終了した場合は再起動 stdin_open: true # コンテナの標準入力を開く tty: true # コンテナが終了しないようにする |
そしてこれらの設定をもとに以下のコマンドを実行すると念願のMCPサーバーが起動します。
docker compose up -d |
MCPホストからの接続設定
それでは最後にMCPホスト(Claude Desktop)からMCPサーバーへの接続設定をしましょう。
Claude DesktopではMCPサーバー接続の設定ファイルとして、
claude_desktop_config.jsonという名前のファイルが用意されています。
MacOS版であれば、Claude Desktopの設定画面にて「構成を編集」を押すと該当ファイルを探すことができます。
ファイルを見つけたら、以下のように書き込みます。
※ dist/index.jsの部分は各々のJavaScriptファイルパスに置き換えてください
{ "mcpServers": { "bee-jokes": { "command": "docker", "args": ["exec", "-i", "bee-jokes-mcp-server", "node", "dist/index.js"] } } } |
ファイルを保存した後に、Claude Desktopを再起動します。すると以下のようにbee-jokesというMCPサーバーが認識されます。
動作確認
すべての準備が整ったのでClaude DesktopからClaude(LLM)を通して、bee-jokes MCPサーバーを叩いてみましょう。
Claudeが
lang: enのパラメータでMCPサーバーに問い合わせることで「What’s a programmers favorite bug? A feature.」というジョークを含んだレスポンスが返ってきています。
そしてClaudeはその内容を認識し、日本語に翻訳してから解説付きでユーザーへ返答しています。
通常Claudeが返してくるジョークはこんな感じなので、ジョークの質が良くなっているように思います。
MCPサーバーを作成することによって、Claude(LLM)のジョーク能力を上げることができました!
まとめ
今回はMCPサーバーを作ってみました。なんだか難しそうと思っていたのですが、必要最低限の機能であれば意外と簡単だとわかりました。
もちろん外部に公開するレベルで作ろうと思ったら大変ですが、個人で使う用のMCPサーバーであればすぐ作れるので、インターネット上で欲しいものが見つからなければどんどん自分で作っていきましょう。
自分だけのオレオレMCPサーバーを作ろう!!
参考
Introduction – Model Context Protocol: https://modelcontextprotocol.io/introduction
modelcontextprotocol/typescript-sdk: https://github.com/modelcontextprotocol/typescript-sdk
bee-jokes – npm: https://www.npmjs.com/package/bee-jokes
この記事を書いた人

-
24卒で株式会社レコチョクに入社。
フロントエンド・バックエンドエンジニアをしています。
三度の飯よりもEDMが好き。
最近書いた記事
2025.07.29MCP SDKを使ってシンプルなMCPサーバーを作ってみよう
2024.12.24設計はメリット・デメリットを分析して考えよう