Skip to main content
Glama
applemk2-git

sample-mcp-server

by applemk2-git
README.md
# MCP Server with FastAPI_MCP

> **はじめに**  
> 私の本業はネットワークエンジニアです。プログラミングは趣味として取り組んでおり、「動けばそれで良し」という精神で開発しています。  
> そのため、コードの品質や設計に稚拙な部分があるかもしれませんが、ご理解いただけますと幸いです。
>
> FastAPI_MCPのおかげで簡単にmcpサーバが作れますが、mcpを知っていてもmcpサーバをどう作ればいいのかわからない、という人が私の会社の周りには多いのでサンプルで作ってみました。

MCP Server with FastAPI は、fast apiをベースにmcpサーバを作成するアプリケーションです。  
**実行している処理内容はあくまでサンプルで書いているだけのため、エンドポイント内のロジックは利用者側で修正してください。**

## **注意事項**
このアプリは サンプル処理として天気情報を応答します。
天気情報取得には、Open-Meteo.com の API を利用しています。  
Open-Meteo のデータは CC BY 4.0 ライセンスで提供されており、非商用目的での利用が許可されています。  
このプログラムをそのまま商用利用する人はいないと思いますが、もし行う場合は Open-Meteo の利用規約をご確認ください。

## プロジェクトの概要

このアプリケーションは、以下の主要な機能を提供します:

- **MCP統合**: FastApiMCPを使用してMCPサーバーとして機能し、外部クライアントから天気取得ツールを利用可能
- **天気予報API**: 日本の県庁所在地等の主要都市の現在天気(気温・天気コード・天候説明)を取得
- **FastAPIベース**: 高速で信頼性の高いREST APIフレームワークを使用
- **Open-Meteo連携**: 信頼性の高い気象データプロバイダーを使用

## 必要な環境・依存関係

### システム要件
- Python 3.13以上
- uv (Pythonパッケージマネージャー)

### 依存関係
- `fastapi>=0.118.0`: Web APIフレームワーク
- `fastapi-mcp>=0.4.0`: MCP連携ライブラリ
- `uvicorn>=0.37.0`: ASGIサーバー
- `httpx>=0.27.0`: 非同期HTTPクライアント

## インストール・実行方法

### 1. リポジトリのクローン
```bash
git clone https://github.com/applemk2-git/mcp-server-with-fastapi_mcp.git
cd mcp-server-with-fastapi_mcp
```

### 2. 依存関係のインストール
```bash
uv sync
```

### 3. アプリケーションの実行
```bash
uv run main.py
```

アプリケーションが起動したら、サーバーが `http://localhost:9999` で実行されます。
このプログラムではmcpのマウントパスを `/weather/mcp` としているためmcpへのアクセスは`http://localhost:9999/weather/mcp` となります。

### 4. MCPクライアントからの利用
このMCPサーバーを利用するには、MCPクライアントで設定を以下のように追加します:

```json
{
  "weather-server": {
    "transport": "streamable-http",
    "url": "http://localhost:9999/weather/mcp"
  }
}
```

#### Streamlit MCP Agentを使った利用例
mcpクライアント機能を持ったエージェントアプリケーションならなんでも良いですが  
[streamlit-mcp-agent](https://github.com/applemk2-git/streamlit-mcp-agent)を使用した例を以下に示します。  

#### **MCP設定画面**:  
![MCP設定画面](sample_images/mcp_settings.png)

#### **ツール実行中の様子**:
![ツール実行中](sample_images/getweather.png)

#### **実行結果**:
![実行結果](sample_images/result.png)


このようにmcpサーバ経由で情報取得ができています。

## エンドポイント内処理を自身の個別ロジックに置き換える際のポイント
- `@app.post` デコレータの `operation_id`, `summary`, `description` は業務内容に合わせて必ず変更してください。`operation_id`がAIエージェントが認識するツール名、`summary`, `description`はAIエージェントがツールの処理内容を認識するために利用するのでしっかり書きましょう。適当に書くとAIエージェントがツールを使ってくれません。
```
  @app.post(
      "/weather",
      operation_id="get_weather",
      response_model=WeatherResponse,
      summary="現在の天気を応答するエンドポイント",
      description="指定された日本の都市の現在の天気を取得します。",
      tags=["mcp"],
  )
```
- `tags` 今回のサンプルでは`mcp`というタグを使っています。今回mcpインスタンス作成時に、include_tags=["mcp"]としており、このタグが含まれるエンドポイントロジックのみがmcpサーバに適用されます。そのため、このタグが含まれないエンドポイントはmcp経由で利用できません。タグ名などは適宜修正してください。
```
  mcp = FastApiMCP(
      app,
      name="sample-mcp-server",
      description="日本の都市の現在天気を提供するサンプルMCPサーバーです。",
      include_tags=["mcp"],
  )
```
- Inputクラスは各フィールドに `Field` で description と example を記載してください。この二つの説明をもとにAIエージェントは引数に何を設定するかを考えます。ここが適当だと正しく引数が渡されません。
- Outputクラスも各フィールドに `Field` で description と example を記載してください。これはツールの返り値をAIエージェントが理解するのに使われます。しっかり書きましょう。
- 今回のサンプルでは/weather/mcpでmcpサーバを公開しています。パスは利用環境に合わせて直してください。
```
  mcp.mount_http(mount_path="/weather/mcp")
```


## 使用例
繰り返しですが、以下はこのサンプルロジックをそのまま動かす場合の使用方法の説明になります。  
実際はこの天気予報部分を自身の業務ロジックに置き換えて使用します。

### 天気取得ツールの使用
このMCPサーバーは以下のツールを提供します:

- **get_weather**: 指定された日本の都市の現在天気を取得

#### パラメータ
- `city`: 日本の県庁所在地の都市名(例: 東京、横浜、大阪、長野)。「市」の字は付けないでください。

#### 返却値
- `temperature`: 現在の気温 (°C)
- `weather_code`: 天気コード(Open-Meteo標準)
- `condition`: 天気の説明(日本語)

### サンプルリクエスト
```
都市: 東京
応答: 温度=18.5°C, 天候=晴れ
```

### 対応都市
以下の日本の主要都市に対応しています:
札幌、青森、盛岡、仙台、秋田、山形、福島、水戸、宇都宮、前橋、さいたま、千葉、東京、横浜、新潟、富山、金沢、福井、甲府、長野、岐阜、静岡、名古屋、津、大津、京都、大阪、神戸、奈良、和歌山、鳥取、松江、岡山、広島、山口、徳島、高松、松山、高知、福岡、佐賀、長崎、熊本、大分、宮崎、鹿児島、那覿

## 機能詳細

### APIエンドポイント
- `POST /weather`: 天気取得エンドポイント(MCPツール提供)
- `GET /docs`: FastAPI自動生成ドキュメント

### データソース
- **Open-Meteo API**: 気象データをリアルタイムで取得
- **サポート都市**: 日本の都道府県庁所在地等、47都市の緯度経度情報を内部マップで保持

### エラーハンドリング
- サポート外都市指定時の適切なエラーレスポンス
- Open-Meteo API 接続失敗時のエラーハンドリング
- HTTPステータスコードによる適切なエラー返却

### カスタマイズ
- `CITY_COORDS` マップの拡張による対応都市の追加可能
- `WEATHER_CONDITIONS` マップの変更による天候説明のカスタマイズ

## ライセンス

このプロジェクトはApache License 2.0の下でライセンスされています。詳細は[LICENSE](LICENSE)ファイルをご参照ください。

## 注意事項

- 外部API (Open-Meteo) に依存しているため、常に最新の気象データを取得可能
- API使用制限やオープンデータ提供元の利用規約に従ってください
- 実運用の際は適切なエラーハンドリングとロギングの実装を推奨します

## 開発環境について

このプロジェクトでは `uv` をパッケージマネージャーとして採用しています。詳しくは [uvのドキュメント](https://pypi.org/project/uv/) を参照してください。

`main.py` を直接実行することで開発サーバーが起動します。ホットリロードは無効にしてありますので、必要に応じてuvicorn設定を変更してください。</content>