Skip to content

tyamori/mcp-quickstart-test

Repository files navigation

MCP (Model Context Protocol) サーバー実装ガイド

このリポジトリは、Model Context Protocol (MCP) を利用したカスタムサーバーの実装例です。エコーツールとYahoo!ニュース取得機能を提供します。

概要

MCPは、AIモデルが外部環境とやり取りするためのプロトコルです。このプロジェクトでは、以下の機能を実装しています:

  • エコーメッセージ送信と時刻表示
  • Yahoo!ニュースの自動取得

セットアップ方法

前提条件

  • Python 3.8以上
  • pipまたはpipenv

インストール手順

  1. リポジトリをクローンする:
git clone [リポジトリURL]
cd [リポジトリ名]
  1. 依存パッケージのインストール:
pip install mcp-python-sdk playwright
  1. Playwrightブラウザのインストール:
playwright install chromium
  1. MCPクライアント設定ファイルの生成:
python generate_config.py

ファイル構造

.
├── server.py         # メインMCPサーバー
├── echo_tools.py     # エコー関連機能
├── news_tools.py     # ニュース取得機能
├── generate_config.py # MCPクライアント設定生成スクリプト
├── .gitignore        # Git無視リスト
├── pyproject.toml    # Pythonプロジェクト設定
├── README.md         # このファイル
└── mcp_client_config.json # (生成されるファイル、Git管理外)

実行方法

MCPサーバーを起動するには:

python server.py

Cursorクライアントとの連携

  1. Cursorアプリを起動する
  2. コマンドパレットを開く(Cmd+Shift+P)
  3. MCP: Settingsを選択
  4. mcp_client_config.json の内容をコピー&ペーストするか、設定ファイルへのパスを指定します。 (注意: generate_config.py が生成したファイルの内容を使用してください)

使用可能なツール

エコーツール

メッセージをエコーバックしたり、現在時刻を表示したりします。

例:

  • 「こんにちは」→「こんにちは」を返す
  • 「時刻」または「time」→現在時刻を返す

Yahoo!ニュース取得ツール

Yahoo! Japanから最新のニュース記事を取得します。

デコレータとその仕組み

MCPサーバーはPythonのデコレータを活用して、関数をMCPの各種機能として登録します。

デコレータの基本概念

デコレータはPythonの強力な機能で、既存の関数やクラスを変更せずに拡張できます。シンプルに言えば、デコレータは関数を引数として受け取り、処理を追加して新しい関数を返す「関数のラッパー」です。

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("関数が呼ばれる前の処理")
        result = func(*args, **kwargs)
        print("関数が呼ばれた後の処理")
        return result
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

# この呼び出しは以下と同等:
# say_hello = my_decorator(say_hello)
say_hello()  # 装飾された関数を実行

MCPにおけるデコレータの役割

MCPサーバーでは、主に3種類のデコレータを使用します:

  1. @mcp.tool() - AIモデルが呼び出せるツールを定義
  2. @mcp.resource() - 動的なリソースへのアクセスを提供
  3. @mcp.prompt() - プロンプトテンプレートを定義

これらのデコレータは、関数をMCPサーバーに登録し、クライアント(AIモデル)からアクセス可能にします。

@mcp.tool() デコレータ

@mcp.tool() デコレータは、関数をAIモデルが利用可能なツールとして登録します。

@mcp.tool()
def echo_tool(message: str) -> str:
    """Echo a message or return current time if 'time' is included."""
    # 関数の実装
    return result

内部動作の流れ

  1. デコレータが関数を変換し、MCP内部レジストリに登録
  2. AIモデルがツールのリストを要求するとき、登録されたツールが返される
  3. AIモデルがツールを呼び出すとき、MCPサーバーは登録された関数を実行
  4. 関数の戻り値がAIモデルに返される

引数タイプの処理

MCPは関数のシグネチャ(型ヒントと引数名)を解析して、AIモデルに適切な引数情報を提供します:

@mcp.tool()
def search_tool(query: str, max_results: int = 10) -> list:
    """検索を実行するツール"""
    # queryとmax_resultsを使用した処理
    return results

この例では、AIモデルに「query(必須)」と「max_results(オプション、デフォルト値10)」の2つの引数が必要であることが伝わります。

@mcp.resource() デコレータ

@mcp.resource() デコレータは、動的なリソースへのアクセスを提供します。

@mcp.resource("user://{user_id}")
def get_user(user_id: str) -> dict:
    """特定のユーザー情報を取得"""
    # user_idを使用してユーザー情報を取得
    return user_info

URLパターンマッチング

resourceデコレータは、URLパターンを使用して動的なリソースにアクセスできます。{param}形式のプレースホルダーがURLパスにマッピングされます。

@mcp.prompt() デコレータ

@mcp.prompt() デコレータは、再利用可能なプロンプトテンプレートを定義します。

@mcp.prompt()
def translate_prompt(text: str, target_language: str) -> str:
    """翻訳プロンプトを生成"""
    return f"以下のテキストを{target_language}に翻訳してください:\n\n{text}"

デコレータの高度な使い方

パラメータ付きデコレータ

デコレータには追加のパラメータを渡すことができます:

@mcp.tool(name="custom_search", description="カスタム検索を実行")
def search_function(query: str) -> list:
    # 実装
    return results

非同期ツールの登録

非同期関数も同様にツールとして登録できます:

@mcp.tool()
async def fetch_data(url: str) -> dict:
    """外部APIからデータを取得"""
    # 非同期リクエスト処理
    return data

Pydanticモデルを使用した引数定義

複雑な引数構造はPydanticモデルで定義できます:

from pydantic import BaseModel, Field

class SearchParameters(BaseModel):
    query: str = Field(description="検索クエリ")
    filters: dict = Field(default={}, description="検索フィルター")
    limit: int = Field(default=10, ge=1, le=100, description="結果の最大数")

@mcp.tool()
def advanced_search(params: SearchParameters) -> list:
    """高度な検索機能を提供"""
    # paramsを使用した処理
    return results

デコレータの仕組み

MCPデコレータの内部では以下のことが行われています:

  1. 関数のメタデータ(引数、戻り値の型、docstring)を解析
  2. 関数をMCPの内部レジストリに登録
  3. JSON Schema形式で引数情報を生成
  4. クライアントからのリクエストをハンドリングするラッパー関数を生成

これにより、AIモデルは利用可能なツールを発見し、それらの使い方を理解し、適切に呼び出すことができます。

LLMとdocstringの関係

LLM(大規模言語モデル)は自然言語の理解に優れているため、厳密な型システムよりもdocstringの説明を読み取って解釈する能力が高いという特徴があります。例えば:

@mcp.tool()
def echo_tool_wrapper(message: str) -> str:
    """Echo a message or return current time if 'time' or '時刻' is included."""
    return echo_tool(message)

上記の例では、関数の型シグネチャ(message: str -> str)からは「特定のキーワードで特殊な挙動をする」という情報は得られませんが、docstringには「'time'や'時刻'が含まれると現在時刻を返す」という情報が含まれています。

LLMはこのdocstringを読み取り、以下の情報を総合的に理解します:

  • 関数名: echo_tool_wrapper
  • 引数の型: message: str
  • 戻り値の型: str
  • 説明: "Echo a message or return current time if 'time' or '時刻' is included."

単純な条件(特定の文字列を含むかどうか)については、docstringの説明だけで十分にLLMに伝わります。より複雑なパターンや多数のオプションがある場合は、詳細な型定義(Pydanticモデルなど)が役立つことがありますが、シンプルなケースではdocstringで十分と言えるでしょう。

このようにMCPでは、LLMの自然言語理解能力を活かして、シンプルなインターフェースでも高度な機能を提供できます。

カスタムツール実装方法

基本構造

  1. ツールロジックを実装したファイルを作成
  2. 必要に応じてPydanticモデルでツール引数を定義
  3. 機能を実装する関数を作成
  4. server.pyでラッパー関数を定義し、@mcp.tool()デコレータを付加

ツール引数の定義

from pydantic import BaseModel, Field

class ToolArguments(BaseModel):
    arg1: str = Field(title="引数1")
    arg2: int = Field(title="引数2")

実装例

新しいツールを追加するには:

  1. 新しいファイル(例:my_tools.py)を作成:
async def my_custom_tool(param1: str, param2: int) -> str:
    # ツールのロジックを実装
    return f"結果: {param1}, {param2}"
  1. server.pyに追加:
from my_tools import my_custom_tool

@mcp.tool()
async def my_custom_tool_wrapper(param1: str, param2: int) -> str:
    """ツールの説明をここに書く"""
    return await my_custom_tool(param1, param2)

実装上の注意点

1. 非同期処理

Webスクレイピングなど時間がかかる処理は非同期(async/await)で実装し、MCPサーバーのパフォーマンスを維持しましょう。

@mcp.tool()
async def async_tool() -> str:
    # 非同期処理
    return result

2. エラーハンドリング

ツール実行中の例外を適切に処理し、クラッシュを防ぎましょう:

try:
    # 処理
except Exception as e:
    return f"エラーが発生しました: {str(e)}"

3. ツール説明の充実

ツールデコレータ内のdocstringは、AIがツールを理解するために重要です。詳細かつ明確な説明を書きましょう。

4. ブラウザ自動化における注意点

PlaywrightでWebスクレイピングを行う場合:

  • セレクタは変更される可能性があるため、複数の検索方法を実装する
  • headless=Falseでデバッグする
  • ページ読み込み待機を適切に設定する

5. 型ヒントの活用

すべての関数に適切な型ヒントを付け、MCPサーバーが正しく引数の型を認識できるようにしましょう。

トラブルシューティング

サーバーが起動しない場合

  • Pythonパスが正しく設定されているか確認
  • 必要なライブラリがすべてインストールされているか確認

Playwrightエラー

playwright install

を実行して、ブラウザが正しくインストールされているか確認してください。

非同期ループエラー

「This event loop is already running」エラーが発生する場合、非同期APIを正しく使用しているか確認してください。

CORSエラー

別オリジンからAPIを呼び出す場合、必要に応じてCORS設定を追加してください。

参考資料

学んだことのまとめ

  • MCPを使用することで、AIモデルに外部ツールを簡単に統合できる
  • コードを適切にモジュール化することで保守性が向上する
  • Playwrightを使用したWebスクレイピングは強力だが、HTMLの変更に対応する柔軟性が必要
  • 非同期処理を適切に実装することで、パフォーマンスが向上する
  • 型ヒントを活用することで、AIモデルがツールの使い方を理解しやすくなる

About

MCPの理解と検証用

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages