0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MCP SDKを使ってシンプルなMCPサーバーを作ってみよう

Posted at

はじめに

こんにちは、わんこです。

今回はシンプルな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) 公式が出している概念図
mcp-diagram.png
引用: https://modelcontextprotocol.io/introduction

MCPサーバーを作る

それでは、一通りの概念を学んだところでMCPサーバーを作っていきましょう。
MCPサーバーをゼロからフルスクラッチで作ってもよいのですが、MCPの公式が便利なSDKを複数言語で用意してくれていますので、今回はその中のMCP TypeScript SDKを使っていきたいと思います。

SDKリンク: https://github.com/modelcontextprotocol/typescript-sdk

では今回作ろうと思うのはこちらです。
mcp-network-structure.png

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の設定画面にて「構成を編集」を押すと該当ファイルを探すことができます。
claude-desktop-setting.png

ファイルを見つけたら、以下のように書き込みます。
※ 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サーバーが認識されます。

new-mcp-server.png

動作確認

すべての準備が整ったのでClaude DesktopからClaude(LLM)を通して、bee-jokes MCPサーバーを叩いてみましょう。

mcp-calling-test.png

Claudeがlang: enのパラメータでMCPサーバーに問い合わせることで「What's a programmers favorite bug? A feature.」というジョークを含んだレスポンスが返ってきています。
そしてClaudeはその内容を認識し、日本語に翻訳してから解説付きでユーザーへ返答しています。

通常Claudeが返してくるジョークはこんな感じなので、ジョークの質が良くなっているように思います。

claude-normal-joke.png

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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?