Claude MCPサーバーを自作して、AIに社内ツールを使わせる方法

MCP(Model Context Protocol)を使うと、Claudeに「自社のデータベースを検索する」「社内APIを叩く」「ローカルファイルを操作する」といった能力を追加できます。要するに、AIの手足を自分で作れる仕組みです。この記事では、MCPサーバーをゼロから構築して、Claude DesktopやClaude Codeから呼べるようにするまでの手順を解説します。

MCPとは何か——30秒で理解する

MCPはAnthropicが策定したオープンプロトコルで、AIモデルと外部ツール・データソースを接続する標準規格です。

これまでAIに外部ツールを使わせるには、アプリごとに独自の接続コードを書く必要がありました。MCPがあれば、1つのサーバーを書くだけで、Claude Desktop・Claude Code・Cursor・その他MCP対応クライアントすべてから使い回せます。USB-Cみたいなものだと思ってください。1つの規格で何にでもつながる。

最小限のMCPサーバーを作る

Python版のMCP SDKを使って、最もシンプルなサーバーを書いてみます。

# 環境: Python 3.12 / mcp 1.9+
# pip install mcp

from mcp.server.fastmcp import FastMCP

# サーバーを作成
mcp = FastMCP("my-tools")

# ツールを定義(デコレーターで簡単に追加できる)
@mcp.tool()
def get_project_status(project_name: str) -> str:
    # プロジェクトの現在のステータスを取得する
    # 実際にはDB検索やAPI呼び出しをする
    statuses = {
        "backend-api": "開発中(進捗70%)",
        "frontend-v2": "レビュー待ち",
        "infra-migration": "完了",
    }
    return statuses.get(project_name, f"{project_name}は見つかりません")

@mcp.tool()
def search_wiki(query: str, max_results: int = 5) -> str:
    # 社内Wikiをキーワードで検索する
    # 実際にはConfluence APIやNotionを叩く
    return f"「{query}」の検索結果: {max_results}件のドキュメントが見つかりました"

# サーバー起動
if __name__ == "__main__":
    mcp.run(transport="stdio")

たったこれだけ。@mcp.tool()デコレーターで関数を装飾すると、それがAIから呼べるツールになります。関数のdocstringがツールの説明文としてAIに渡されるので、何をするツールなのか分かりやすく書くのがコツです。

Claude Desktopから使えるようにする

サーバーを書いたら、Claude Desktopの設定ファイルに登録します。

// macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
// Windows: %APPDATA%\Claude\claude_desktop_config.json

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

Claude Desktopを再起動すると、チャット画面の右下にツールアイコンが表示されます。これで「backend-apiの進捗を教えて」と聞くだけで、AIがget_project_statusを呼んで結果を返してくれます。

Claude Codeからも使う

Claude Code(CLI版)でも同じMCPサーバーが使えます。

# .claude/settings.json に追加
{
  "mcpServers": {
    "my-tools": {
      "command": "python",
      "args": ["/path/to/my_mcp_server.py"]
    }
  }
}

Claude Codeを起動すると自動でMCPサーバーに接続します。ターミナルでの開発中に「社内Wikiでデプロイ手順を検索して」と頼めば、search_wikiが呼ばれて結果が返ってくる。開発フローから離れずに情報を取得できるのが便利です。

実用的なMCPサーバーの例

データベース検索サーバー

import sqlite3
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("db-tools")

@mcp.tool()
def query_users(department: str) -> str:
    # 指定された部署のメンバー一覧を取得する
    conn = sqlite3.connect("/path/to/company.db")
    cursor = conn.cursor()
    cursor.execute(
        "SELECT name, role FROM users WHERE department = ?",
        (department,)
    )
    rows = cursor.fetchall()
    conn.close()
    if not rows:
        return f"{department}にメンバーが見つかりません"
    return "\n".join(f"- {name}({role})" for name, role in rows)

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

SQLインジェクション対策としてパラメータ化クエリを使っています。MCPサーバーは外部から入力を受けるので、セキュリティは意識して書きましょう。

GitHub連携サーバー

GitHub APIを叩いて、PR一覧の取得、Issue検索、リポジトリ情報の参照ができるサーバーも人気のパターンです。Anthropic公式がリファレンス実装を公開しているので、それをベースにカスタマイズするのが手っ取り早いです。

ハマりやすいポイント

パスの指定ミス

設定ファイルのパスは絶対パスで書いてください。相対パスだとClaude Desktopが見つけられずにサイレントに失敗します。動かないときはまずパスを確認。

docstringが雑だとAIがツールを使ってくれない

AIは関数のdocstringを見て「このツールを使うべきか」を判断します。「データを返す」みたいな漠然とした説明だと、AIが呼ぶタイミングを間違えます。「指定された部署名に基づいて、その部署に所属するメンバーの名前と役職の一覧を返す」くらい具体的に書きましょう。

エラーハンドリング

MCPサーバーがクラッシュすると、AI側にはエラーの詳細が伝わりません。try-exceptで例外をキャッチして、人間が読めるエラーメッセージを返すようにしておきましょう。

よくある質問

いいえ。MCPはオープンプロトコルで、CursorやClineなど他のツールも対応しています。一度書いたMCPサーバーは複数のクライアントから使い回せるのがメリットです。

はい。stdioの代わりにSSEやHTTPトランスポートを使えば、リモートサーバーとして公開できます。チーム全体で同じMCPサーバーを共有するなら、社内ネットワークにHTTPサーバーとして立てるのが現実的です。

できます。REST APIのエンドポイントを呼ぶラッパー関数を書いて@mcp.tool()で装飾するだけ。既存の社内APIがあるなら、薄いMCPラッパーを被せるのが最速の導入パスです。

まとめ

  • MCPはAIと外部ツールを接続するオープンプロトコル。USB-Cのように「1つ書けばどこでも使える」
  • Python数十行でMCPサーバーが作れる。@mcp.tool()デコレーターで関数をツール化するだけ
  • Claude Desktop、Claude Code、Cursorなど複数のクライアントから使い回せる
  • docstringの品質とセキュリティ(SQLインジェクション対策など)が実用化のカギ

参考: MCP公式ドキュメント

K
AWS・Python・生成AIを専門とするソフトウェアエンジニア。AI・クラウド・開発ワークフローの実践ガイドを執筆しています。詳しく見る →