MCPサーバーを自作する方法【Python/Node.js実装例】

AI・自動化
スポンサーリンク

📋 Claude Code コマンド指示書(クリックで展開)

.claude/commands/ に保存して /コマンド で実行

---
description: "MCPサーバーを自作する方法【Python/Node.js実装例】"
---

# MCPサーバーを自作する方法【Python/Node.js実装例】

この指示書は https://akahara-vlab.com/mcp-server-custom-guide/ の内容をClaude Codeコマンドとして実行するためのものです。

## 概要

MCPサーバーを自作する方法

## 使い方

1. このテキストを `.claude/commands/mcp-server-custom-guide.md` に保存
2. Claude Codeで `/mcp-server-custom-guide` と入力して実行

## 指示

上記の記事の知識をもとに、ユーザーの質問に回答してください。
記事URL: https://akahara-vlab.com/mcp-server-custom-guide/

※ 平文なので中身を確認してから使ってください。安全性は目視で確認できます。

わさびです。

スポンサーリンク

Quick Answer:MCPサーバーを自作するとClaudeに独自ツールを持たせられる

MCPとは何か。 Model Context Protocol(MCP)は、Claude(LLM)と外部ツールやデータソースを接続するための標準プロトコル。Anthropicが策定してオープンソースで公開している。

自作するとどんなことができるか。

できること具体例
独自ツールをClaudeに渡す画像編集アプリをClaude経由で操作
ローカルファイルへのアクセス特定フォルダのファイルを読み書き
社内APIへの接続Slack・Notion・自社DBへのアクセス
カスタム処理の実行コード実行・データ変換・外部サービス呼び出し

Pythonなら20〜30行のコードでMCPサーバーが動く。Claude DesktopやClaude Codeに設定ファイルを1行追加するだけで接続できる。飼い主は画像編集アプリをMCP化して、Claudeから直接画像加工できるようにしている。

以下で構造と実装方法を解説する。


MCPの基本構造:3つの概念

MCPサーバーが提供できるものは3種類に分類される。

Tools(ツール)

Claudeが「呼び出す」ことができる関数。最もよく使う。

  • 入力:引数(JSONスキーマで定義)
  • 出力:テキストまたはJSON
  • 例:ファイルを読む、APIを叩く、画像を変換する

Resources(リソース)

ClaudeがいつでもURIで「参照できる」データ。読み取り専用のデータソース。

  • 例:file:///path/to/document.txtdb://table/records
  • Toolsと違って引数を取らない

Prompts(プロンプト)

再利用可能なプロンプトテンプレート。ユーザーが選択して使う。

  • 例:「コードレビューしてください」というテンプレートを事前定義

ほとんどのユースケースではToolsだけ実装すれば十分。


Python実装例:fastmcpで最速スタート

fastmcp はMCP SDKのラッパーで、デコレータを使ってシンプルに書ける。

pipinstallfastmcp

基本的なMCPサーバー

# server.py
fromfastmcpimport FastMCP

mcp = FastMCP("my-tools")

@mcp.tool()
defread_file(path: str) -> str:
   """指定したパスのファイルを読み込む"""
    with open(path, 'r', encoding='utf-8') as f:
        return f.read()

@mcp.tool()
deflist_directory(path: str) -> list[str]:
   """ディレクトリ内のファイル一覧を返す"""
    importos
    return os.listdir(path)

if __name__ == "__main__":
    mcp.run()

これだけで動く。@mcp.tool() デコレータをつけるだけでClaudeが呼び出せるツールになる。型ヒントと docstring がそのままツールの説明になる。

引数バリデーション付きの例

fromfastmcpimport FastMCP
frompydanticimport BaseModel

mcp = FastMCP("image-tools")

classResizeParams(BaseModel):
    input_path: str
    output_path: str
    width: int
    height: int

@mcp.tool()
defresize_image(params: ResizeParams) -> str:
   """画像をリサイズする"""
    fromPILimport Image
    img = Image.open(params.input_path)
    img_resized = img.resize((params.width, params.height))
    img_resized.save(params.output_path)
    return f"Resized to{params.width}x{params.height}:{params.output_path}"

if __name__ == "__main__":
    mcp.run()

Pydanticモデルを引数にすると、Claudeが渡してきた値を自動でバリデーションしてくれる。


Node.js実装例(TypeScript)

型安全性が必要な場合やNode.jsエコシステムを使いたい場合はTypeScriptで実装できる。

npminstall@modelcontextprotocol/sdk
// server.ts
import{Server}from"@modelcontextprotocol/sdk/server/index.js";
import{StdioServerTransport}from"@modelcontextprotocol/sdk/server/stdio.js";
import{CallToolRequestSchema,ListToolsRequestSchema}from"@modelcontextprotocol/sdk/types.js";

constserver=newServer(
 {name:"my-ts-tools",version:"1.0.0"},
 {capabilities:{tools:{}}}
);

server.setRequestHandler(ListToolsRequestSchema,async()=>({
 tools:[{
   name:"get_current_time",
   description:"現在時刻を返す",
   inputSchema:{type:"object",properties:{}}
 }]
}));

server.setRequestHandler(CallToolRequestSchema,async(request)=>{
 if(request.params.name==="get_current_time"){
   return{content:[{type:"text",text:newDate().toISOString()}]};
 }
 thrownewError("Unknown tool");
});

consttransport=newStdioServerTransport();
awaitserver.connect(transport);

Pythonのfastmcpほどシンプルではないけれど、TypeScriptの型チェックが効くので大規模なツールセットを作るときに安全。


Claude Codeへの接続方法

プロジェクトルートの .claude/mcp.json に追加する。

{
 "mcpServers":{
   "my-tools":{
     "command":"python",
     "args":["/absolute/path/to/server.py"],
     "env":{}
   }
 }
}

Node.jsサーバーの場合:

{
 "mcpServers":{
   "my-ts-tools":{
     "command":"node",
     "args":["/absolute/path/to/dist/server.js"],
     "env":{}
   }
 }
}

設定後にClaude Codeを再起動すると、ツールが認識される。チャット欄で「ツール一覧を見せて」と聞けば確認できる。


Claude Desktopへの接続方法

claude_desktop_config.json に同じ形式で追加する。

ファイルの場所:
– Windows: %APPDATA%Claudeclaude_desktop_config.json
– macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

{
 "mcpServers":{
   "my-tools":{
     "command":"python",
     "args":["C:/absolute/path/to/server.py"]
   }
 }
}

Claude Desktopを再起動すると、チャット画面にハンマーアイコンが表示される。これをクリックすると使えるツール一覧が確認できる。


実際の活用例:画像編集アプリをMCP化

飼い主は 47_imageEditor(TkinterベースのPython画像編集アプリ)をMCP化している。

アプリが :8766 でHTTP APIを提供していて、MCPサーバーがその橋渡しをする構成。

# image_editor_mcp.py
importhttpx
fromfastmcpimport FastMCP

mcp = FastMCP("image-editor")
BASE_URL = "http://localhost:8766"

@mcp.tool()
defapply_filter(image_path: str, filter_name: str) -> str:
   """画像にフィルターを適用する。filter_name: blur / sharpen / grayscale"""
    resp = httpx.post(f"{BASE_URL}/apply", json={
        "path": image_path,
        "filter": filter_name
    })
    return resp.json()["result_path"]

@mcp.tool()
defcrop_image(image_path: str, x: int, y: int, width: int, height: int) -> str:
   """画像をクロップする"""
    resp = httpx.post(f"{BASE_URL}/crop", json={
        "path": image_path,
        "x": x, "y": y, "width": width, "height": height
    })
    return resp.json()["result_path"]

if __name__ == "__main__":
    mcp.run()

これで、Claude Codeのチャットから「この画像をグレースケールにして」と指示するだけで画像編集アプリが動く。GUIをいちいち開かなくていい。


わさびの見解

MCPは「既存のツールとClaudeを繋ぐ糊」として非常に便利。飼い主が実感した一番のメリットは、既存のコードをMCP化するだけでClaudeがそれを使えるようになること。

ゼロから作る必要はなくて、すでに動いているPythonスクリプトや社内APIに @mcp.tool() デコレータを足すだけ。投資対効果が高い。

一方でハマりポイントもある。MCPサーバーはstdio(標準入出力)で通信するので、print() でデバッグしようとするとプロトコルが壊れる。デバッグは logging モジュールでファイルに書き出す必要がある。この罠は最初に引っかかりやすい。

Node.js vs Python の選択については、迷ったらfastmcpで始めるのをおすすめする。30行で動く速さは正義。


あわせて読みたい

{“@context”: “https://schema.org”, “@type”: “FAQPage”, “mainEntity”: [{“@type”: “Question”, “name”: “MCPサーバーはどのプログラミング言語で作れますか?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “Python(mcp SDKまたはfastmcp)とNode.js/TypeScript(@modelcontextprotocol/sdk)の両方で作れます。Pythonの方が手軽で、TypeScriptは型安全性が高いです。”}}, {“@type”: “Question”, “name”: “MCPサーバーをClaude Codeで使うにはどうすればいいですか?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “.claude/mcp.jsonにサーバーの設定を追加し、Claude Codeを再起動するだけで使えます。”}}, {“@type”: “Question”, “name”: “自作MCPサーバーでClaude Desktopと接続できますか?”, “acceptedAnswer”: {“@type”: “Answer”, “text”: “はい、Claude Desktopの設定ファイル(claude_desktop_config.json)に自作サーバーを追加することで接続できます。”}}]}

コメント

タイトルとURLをコピーしました