Pythonで天気情報MCPサーバーを実装
フック
さて、始める前に小さな例を見てみましょう。来週「アークナイツ」の「錆影新生」コスプレイベントに行く予定なので、土曜日の杭州の天気を知りたいと思い、AIに土曜日の天気を聞きました。するとAIは以下のような返答をしました:

これは困ります。皆さんもよくあると思いますが、AIは「魚の釣り方を教える」ことが多く、時には単に最終結果を知りたいだけのとき、特に些細な日常の質問に対してはそう感じます。
実際、天気予報を実装するプログラムはたくさんあります。では、作成した天気予報プログラムをAIに接続し、実際の天気を教えてもらい、明日のコスプレイベントの服装を決める方法はないでしょうか?
直接関数を書いてfunction callingを使うのは少し面倒です。AIプロバイダーのAPI呼び出しやタスクループの構築、テキストレンダリングなど、多くの技術的な詳細を検討する必要があり、貴重な時間を浪費します。MCPは私たちに救いの道を与えてくれました。今回のチュートリアルでは、簡単なMCPサーバーを作成し、AIに天気予報を知る能力を与える方法を教えます。
はじめに
前回はMCPの基礎を簡単に説明しました。今回は、独自のMCPサーバーの開発を開始し、既存のアプリケーション、サービス、ハードウェアなどをAIに接続します。これにより、AIからエンドユーザーアプリケーションへの最後の1キロメートルを完了します。
「工欲善其事、必先利其器」。よりエレガントで楽しいMCPサーバー開発のために、開発プロセスでプログラムの変更を確認し、直接AIに接続してツールの有効性を検証できる優れたテストツールが必要です。
そこで、私は最近、統合型MCPテスト開発ツール「OpenMCP」をオープンソース化しました。初のMCPサーバー統合開発テストソフトウェアOpenMCPリリース!
OpenMCP QQグループ 782833642
OpenMCPオープンソースリンク:https://github.com/LSTM-Kirigaya/openmcp-client
スターをお願いします 😄
最初のMCPプロジェクト
前置きはこのくらいにして、コーディングを始めましょう 😄
vscodeやtraeを開く前に、基本的なuvツールをインストールします。uvはコミュニティで人気のバージョン管理ツールで、性能の良いcondaと理解してください。
まずuvをインストールします。anacondaを使用している場合は、必ずbase環境に切り替えてからインストールしてください:
pip install uv
インストールが完了したら、uvを実行します:
uv
エラーがなければ成功です。uvは再利用不可能な依存関係のみをローカルにインストールするため、anacondaを使用している方は心配ありません。uvがインストールするライブラリがbaseを汚染することはありません。次に、uvを使用して基本的なpythonプロジェクトを作成します:
mkdir simple-mcp && cd simple-mcp
uv init
uv add mcp "mcp[cli]"
次にvscodeまたはtraeを開き、プラグイン市場でOpenMCPプラグインを探してダウンロードします:

まずMCPの最小プログラムを作成します:
ファイル名:simple_mcp.py
from mcp.server.fastmcp import FastMCP
mcp = FastMCP('錦恢の MCP Server', version="11.45.14")
@mcp.tool(
name='add',
description='2つの数値の実数領域での加算'
)
def add(a: int, b: int) -> int:
return a + b
@mcp.resource(
uri="greeting://{name}",
name='greeting',
description='デモンストレーション用のリソースプロトコル'
)
def get_greeting(name: str) -> str:
# greeting://{name}リソースアクセスプロトコルを処理し、返す
# ここでは簡単のため、直接Helloを返す
return f"Hello, {name}!"
@mcp.prompt(
name='translate',
description='翻訳用のプロンプト'
)
def translate(message: str) -> str:
return f'以下の文章を中国語に翻訳してください:\n\n{message}'
@mcp.tool(
name='weather',
description='指定都市の天気情報を取得'
)
def get_weather(city: str) -> str:
"""天気予報プロトコルをシミュレートし、フォーマットされた文字列を返す"""
return f"Weather in {city}: Sunny, 25°C"
@mcp.resource(
uri="user://{user_id}",
name='user_profile',
description='ユーザー基本情報を取得'
)
def get_user_profile(user_id: str) -> dict:
"""ユーザープロトコルをシミュレートし、辞書データを返す"""
return {
"id": user_id,
"name": "張三",
"role": "developer"
}
@mcp.resource(
uri="book://{isbn}",
name='book_info',
description='ISBNで書籍情報を検索'
)
def get_book_info(isbn: str) -> dict:
"""書籍プロトコルをシミュレートし、構造化データを返す"""
return {
"isbn": isbn,
"title": "Pythonプログラミング:入門から実践まで",
"author": "Eric Matthes"
}
@mcp.prompt(
name='summarize',
description='テキスト要約のプロンプトテンプレート'
)
def summarize(text: str) -> str:
"""要約生成プロンプトを返す"""
return f"以下の内容を一言で要約してください:\n\n{text}"
実行してみます:
uv run mcp run simple_mcp.py
エラーがなく、止まっている場合は、依存関係のインストールに問題がないことを意味します。ctrl cまたはctrl zで終了してください。
これらの関数は単純で意味がないように見えるかもしれませんが、最終的なシステムに到達するためには、簡単な例が必要です。
リンク、スタート!
OpenMCPプラグインをダウンロードした場合、pythonエディタの右上にOpenMCPの紫色のアイコンが表示されます。クリックするとOpenMCPが起動し、現在のMCPをデバッグできます。

デフォルトではSTDIOモードで起動し、以下のコマンドを実行します:
uv run mcp run <現在開いているpythonファイルの相対パス>
したがって、mcpスキャフォールド(uv add mcp "mcp[cli]"
)がインストールされていることを確認してください。
開いたらまず左下の接続状態を確認し、緑色であることを確認します。これはOpenMCPとMCPサーバーが正常にハンドシェイクしたことを示します。

接続に成功すると、接続の上に現在のMCPサーバーの名前が表示され、カーソルを合わせるとバージョン番号が表示されます。この情報は以下のコードで定義されます:
mcp = FastMCP('錦恢の MCP Server', version="11.45.14")
これはバージョン管理時に非常に便利です。このシステムを活用してください。
接続に失敗した場合は、左側のツールバーの2番目のボタンをクリックして接続コンソールに入り、エラーメッセージを確認するか、手動で接続コマンドを調整します:

OpenMCPの紹介
次に、OpenMCPの基本機能モジュールを簡単に紹介します。最初に画面に何も表示されていない場合は、上のプラス記号をクリックして新しいタブを作成します。このページには以下の4つのボタンが表示されます:

拡大:

最初の3つ、リソース、プロンプト、ツールは、MCP内の対応する項目(Resources、Prompts、Tools)をデバッグするために使用されます。これらの部分の使用法は基本的にMCP公式のInspectorツールと同じです。もちろん、私はこれらを参考にしました。

4番目のボタン「インタラクティブテスト」は、私が開発したMCPクライアントで、基本的にはダイアログウィンドウです。現在のMCPサーバーの機能関数をAIで直接テストできます。

現在はツールのサポートのみを提供しています。プロンプトとリソースについてはまだ考えがまとまっていません(リソースはツールとして扱えると思います)。グループで一緒に議論しましょう:QQグループ 782833642
天気関数のデバッグを開始
ツールデバッグ
最初に示したMCPの例を覚えていますか?OpenMCPを使用して、これらの関数を迅速にデバッグできます。今回の目標は、天気予報MCPを作成することです。天気予報関数がすでに作成されていると仮定し、それをツールとしてカプセル化します:
@mcp.tool(
name='weather',
description='指定都市の天気情報を取得'
)
def get_weather(city: str) -> str:
"""天気予報プロトコルをシミュレートし、フォーマットされた文字列を返す"""
return f"Weather in {city}: Sunny, 25°C"
もちろん、今のところ意味はありません。黒龍江省の都市IDを入力しても25度を返しますが、これは重要ではありません。まず全体のプロセスを理解することが重要です。詳細にこだわるよりも、トップダウンで感覚的な理解を構築する方がユーザーにとって学びやすいです。
この関数をデバッグするには、OpenMCPを開き、新しい「ツール」デバッグプロジェクトを作成します:

左側のリストにweatherツールが表示されます。それを選択し、右側の入力ボックスに何かを入力してEnter(または「実行」をクリック)を押すと、以下の応答が表示されます:

関数が返す文字列が表示され、問題なくリンクが機能していることがわかります。
インタラクティブテスト
プログラミングは得意かもしれませんが、天気予報クローラーを素早く作成する前に、作成したツールをAIダイアログに注入する方法を見てみましょう。AIを使用するには、まずAIモデルと対応するAPIを選択する必要があります。左側のツールバーの3番目のボタンをクリックしてAPIモジュールに入り、使用するAIモデルプロバイダー、モデルを選択し、APIトークンを入力して「保存」をクリックします:

新しいタブを作成し、「インタラクティブテスト」を選択します。これで直接AIと対話できます。まずツールを注入せずにAIが天気予報の質問にどのように応答するかを見てみましょう。下部のツールバーの左から3番目のボタンをクリックしてツール選択インターフェースに入り、「すべてのツールを無効にする」を選択します:

「閉じる」をクリックした後、AIに質問します:
杭州の気温は何度ですか?

AIは記事の冒頭と同じ回答をしました。非常に形式的で、実際には知らないからです。
ここで、「weather」ツールを個別に有効にします:

同じ質問をします:

AIは25度と回答し、追加の推論情報も提供しました。
いくつかの詳細に注目しましょう。まず、AIは直接質問に答えず、weatherツールを呼び出します。呼び出しパラメータは:
{
"city": "杭州"
}
そして、MCPサーバーは以下の応答を返します:
Weather in 杭州: Sunny, 25°C
これに基づいて、AIは最終的な回答を提供します。つまり、このプロセスでは実際に2回AIサービスを呼び出しています。また、2回の呼び出しの入力トークン数が非常に多いことがわかります。これはOpenMCPが関数呼び出しをJSONスキーマ形式でリクエストパラメータに注入するためです。weatherツールのJSONスキーマは以下の図の右側のjsonのようになります:

openaiプロトコルをサポートするAIプロバイダーは、このような情報に対してfunction callingを実行します。そのため、ツールを使用するAIリクエストの入力トークン数は大きくなります。ただし、心配する必要はありません。ほとんどのプロバイダーはKVキャッシュを実装しており、同じプレフィックスの入力に対してキャッシュがあり、キャッシュヒット部分のコストは通常の入力出力トークン価格よりも大幅に低くなります。OpenMCPは各回答の下に、現在のリクエストの