SaaS_A MCP Server
# SaaS_A MCP Server
SaaS_A(弊社のIoT観測データ監視SaaS)の管理用REST API の**参照専用** MCP サーバーです。
テナント、ユーザー、現場(グループ)、地点(端末)、フォーマット(機種)の構成情報と、
受信データ履歴の CSV エクスポートを Claude Code / Cursor / Claude Desktop から直接調査できます。
すべてのツールは GET リクエストのみを使用しており、**登録・更新・削除などの書き込み操作は一切できない安全設計**です。
---
## ステータス: 実装済み(2026-08-20)
| 項目 | 状況 |
|------|------|
| 設計書 | 完了 → [Documents/DESIGN.md](Documents/DESIGN.md) |
| 引き継ぎ資料 | 完了 → [Documents/HANDOVER.md](Documents/HANDOVER.md) |
| `src/` の実装(9ツール・認証層・整形・CSVエクスポート) | 完了 |
| `tests/`(ユニット134件・検証環境への統合テスト15件) | 完了・全パス |
| 社内Gitサーバーへの登録 | 完了(`http://192.0.2.10/git/saas-a-mcp`) |
| MCP専用APIユーザーの発行 | **未発行**(検証用ユーザーを共用中。[HANDOVER.md](Documents/HANDOVER.md) 未決事項 #1) |
| 本番環境対応 | **待ち**(本番はBearer認証未対応。リリース時期未確定) |
経緯・設計判断は [Documents/DESIGN.md](Documents/DESIGN.md)、残る未決事項は [Documents/HANDOVER.md](Documents/HANDOVER.md) の4章を参照してください。
---
## 前提条件
- **`uv` がインストール済みであること**
- **SaaS_A の API 専用ユーザー**(`user_cd` / パスワード)が発行済みであること
- 現時点で接続できるのは**検証環境のみ**です(本番環境は旧実装のため Bearer 認証に未対応)
### uv のインストール
| OS | インストール方法 |
|----|----------------|
| Windows | `powershell -c "irm https://astral.sh/uv/install.ps1 | iex"` |
| WSL / Linux | `curl -LsSf https://astral.sh/uv/install.sh | sh` |
> **注意**: Windows では `winget install astral-sh.uv` ではなく公式スクリプトを使用してください。winget 版は PATH の反映に問題が生じることがあります。
## インストール
`uv` が Python と依存パッケージを自動管理するため、手動インストールは不要です。
依存パッケージ:
| パッケージ | バージョン | 用途 |
|-----------|-----------|------|
| mcp | >= 1.26.0, < 2 | MCP SDK (FastMCP) |
| httpx | >= 0.27.0 | HTTP クライアント |
## 設定方法
### 環境変数
| 環境変数 | 必須 | 説明 | 例 |
|---------|------|------|-----|
| `SAAS_A_BASE_URL` | ○ | API のベース URL(末尾スラッシュなし) | `https://verify.example-iot.net` |
| `SAAS_A_USER` | ○ | API 専用ユーザーの `user_cd` | — |
| `SAAS_A_PASS` | ○ | API 専用ユーザーのパスワード | — |
> **既定値はありません。** 認証情報を含むため、3 つすべてを MCP 設定の `env` セクションで指定する必要があります。
> キー名のテンプレートは [.env.example](.env.example) を参照してください。
> **重要: API 専用ユーザーを使ってください。**
> SaaS_A は **1 ユーザーにつき有効なアクセストークンを 1 つしか保持しません。**
> 同じユーザーで別のシステムや別の担当者が認証すると、互いのトークンを失効させ合い、どちらも安定して動作しません。
> このサーバー専用のユーザーを発行して使用してください。詳細は [DESIGN.md の 6.4 節](Documents/DESIGN.md) を参照。
### Claude Code(WSL)での設定
社内 Git サーバーから直接取得します。`.claude.json` の `mcpServers` に追加:
```json
{
"mcpServers": {
"saas-a": {
"command": "uvx",
"args": [
"--from",
"git+http://192.0.2.10/git/saas-a-mcp@develope",
"saas-a-server"
],
"env": {
"SAAS_A_BASE_URL": "https://verify.example-iot.net",
"SAAS_A_USER": "<APIユーザーのuser_cd>",
"SAAS_A_PASS": "<APIユーザーのパスワード>"
}
}
}
}
```
`claude mcp add` コマンドでも設定できます:
```bash
claude mcp add saas-a \
-s user \
-e SAAS_A_BASE_URL=https://verify.example-iot.net \
-e SAAS_A_USER=<APIユーザーのuser_cd> \
-e SAAS_A_PASS=<APIユーザーのパスワード> \
-- uvx --from "git+http://192.0.2.10/git/saas-a-mcp@develope" saas-a-server
```
### Cursor での設定
`~/.cursor/mcp.json`(グローバル)またはプロジェクトルートの `.cursor/mcp.json` に追加:
```json
{
"mcpServers": {
"saas-a": {
"command": "uvx",
"args": [
"--from",
"git+http://192.0.2.10/git/saas-a-mcp@develope",
"saas-a-server"
],
"env": {
"SAAS_A_BASE_URL": "https://verify.example-iot.net",
"SAAS_A_USER": "<APIユーザーのuser_cd>",
"SAAS_A_PASS": "<APIユーザーのパスワード>"
}
}
}
}
```
> Cursor は MSIX アプリではないため、Git URL 方式が直接動作します。
### Claude Desktop / Cowork(Windows)での設定
Windows では MSIX アプリの制約により `uvx` の Git URL 方式が動作しないため、事前にツールをインストールします。
**初回セットアップ**(PowerShell で一度だけ実行):
```powershell
uv tool install "git+http://192.0.2.10/git/saas-a-mcp@develope"
```
**MCP 設定**(`claude_desktop_config.json` に追加):
```json
{
"mcpServers": {
"saas-a": {
"command": "saas-a-server",
"env": {
"SAAS_A_BASE_URL": "https://verify.example-iot.net",
"SAAS_A_USER": "<APIユーザーのuser_cd>",
"SAAS_A_PASS": "<APIユーザーのパスワード>"
}
}
}
}
```
**更新時**:
```powershell
uv tool upgrade saas-a-mcp
```
#### 開発者向け(ローカルパス方式)
リポジトリをクローンして開発中の場合は、ローカルパスを指定することもできます:
```json
{
"command": "uvx",
"args": ["--from", "/path/to/saas-a-mcp", "saas-a-server"]
}
```
> **注意**: この方式はパスに依存するため、フォルダを移動すると動作しなくなります。
## ツール一覧(9 ツール・すべて参照専用)
権限レベルは、その操作を実行するために **API 専用ユーザーに必要なユーザーレベル**です。
(1: システム管理者、2: テナント管理者、3: 現場管理者、4: ユーザー管理者、5: 一般ユーザー)
### テナント系(2 ツール)
| ツール名 | 必要権限 | 説明 |
|---------|---------|------|
| `list_tenants` | 制限なし | テナント一覧を取得。**他のツールに渡す `tenant_id` はここで取得します**(最初に呼ぶツール) |
| `list_tenant_dashboards` | 1, 2 | テナント用ダッシュボード一覧を取得 |
### ユーザー系(1 ツール)
| ツール名 | 必要権限 | 説明 |
|---------|---------|------|
| `list_users` | 制限なし | 指定テナントのユーザー一覧を取得(ユーザーCD・名称・権限レベル・タイムゾーン) |
### 現場系(2 ツール)
| ツール名 | 必要権限 | 説明 |
|---------|---------|------|
| `list_groups` | 制限なし | 現場(グループ)一覧を取得。所属ユーザー・通知先は既定で件数のみ(`include_members` / `include_destinations` で全量取得) |
| `list_group_dashboards` | 1, 2, 3 | 現場用ダッシュボード一覧を取得 |
### 地点系(2 ツール)
| ツール名 | 必要権限 | 説明 |
|---------|---------|------|
| `list_devices` | 制限なし | 地点(端末)一覧を取得。現場CDで絞り込み可。フォーマット詳細・通知先は既定で件数のみ(`include_format_detail` / `include_alerts` で全量取得) |
| `list_device_dashboards` | 1, 2 | 地点用ダッシュボード一覧を取得 |
### フォーマット系(1 ツール)
| ツール名 | 必要権限 | 説明 |
|---------|---------|------|
| `list_formats` | **1 のみ** | フォーマット(機種)一覧を取得。システム管理者権限が必要です |
### エクスポート系(1 ツール)
| ツール名 | 必要権限 | 説明 |
|---------|---------|------|
| `export_observation_data` | 1, 2, 3 | 受信データ履歴を CSV でエクスポート。期間・現場・地点を指定。既定では要約を返し、`save_path` 指定でファイル保存 |
## 操作例
Claude Code や Cursor で自然言語で指示するだけで、適切なツールが呼び出されます。
### 例 1: テナント一覧から調査を始める
```
SaaS_A のテナントを一覧して
```
`list_tenants()` が呼ばれます。以降のツールに必要な `tenant_id` はここで確認できます。
### 例 2: 現場ごとの地点数を調べる
```
運用テストテナントの現場ごとの地点数を教えて
```
`list_tenants()` → `list_groups(tenant_id=...)` の順で呼ばれ、各現場の `device_count` が返ります。
### 例 3: 特定現場の地点を絞り込む
```
テナントXの現場CD group001 に属する地点を一覧して
```
`list_devices(tenant_id=..., group_cds=["group001"])` が呼ばれます。
### 例 4: 観測データをCSVで取得する
```
テナントXの全地点の 2026-08-01 〜 2026-08-07 の観測データを生値でCSVに出して
```
`export_observation_data(tenant_id=..., start_date="2026-08-01", end_date="2026-08-07", group_cd="all", device_cd="all", output_type="raw_data")` が呼ばれます。
CSV 本文はコンテキストを圧迫するため、既定では行数・カラム・先頭 20 行のプレビューとファイル保存先が返ります。
## トラブルシューティング
| エラー | 原因 | 対処法 |
|-------|------|-------|
| **401 Unauthorized** が繰り返される | 同じ API ユーザーが他のシステム・他の担当者に使われている(1ユーザー1トークン制約) | このサーバー専用の API ユーザーを発行して使用してください |
| **401 Authentication failed**(初回認証時) | `SAAS_A_USER` / `SAAS_A_PASS` が誤っている | 環境変数の値を確認してください |
| **403 Forbidden**(`Common.forbidden`) | API ユーザーの権限レベル不足、またはテナント参照権限なし | ツール一覧の「必要権限」を確認してください。`list_formats` はシステム管理者専用です |
| **400 `Error.Common.LimitOver`** | エクスポート件数が上限を超過 | `start_date` / `end_date` の期間を短くするか、`group_cd` / `device_cd` で対象を絞ってください |
| **`Error.Common.NoRecords`** | 指定条件に該当するデータが 0 件(エラーではありません) | 期間・現場CD・地点CDを見直してください |
| **接続できない / タイムアウト** | 接続先 URL の誤り、またはネットワーク | `SAAS_A_BASE_URL` を確認してください。本番 URL(`saas-a.example.jp`)は現時点では使用できません |
| **`uvx` が見つからない** | `uv` 未インストール | 前提条件のインストール手順を参照してください |
| **キャッシュが古い** | uvx のキャッシュ | `uv cache prune` を実行してから再起動してください |
| **Git operation failed**(Claude Desktop / Cowork) | MSIX アプリの git 制約 | `uv tool install` 方式を使用してください(Windows 設定手順を参照) |
## 制限事項
- **参照のみ**: すべてのツールは GET リクエストのみです。テナント・ユーザー・現場・地点の登録/更新/削除、通知先の追加・変更はできません
- **検証環境のみ**: 最終仕様の API が稼働しているのは検証環境(`verify.example-iot.net`)だけです。本番環境(`saas-a.example.jp`)は旧実装のため Bearer 認証に未対応で、リリース時期は未確定です
- **API 専用ユーザーが必要**: 1 ユーザー 1 トークンの制約により、他用途との共用はできません
- **子現場の詳細は取得不可**: `list_groups` が返す `children` は「子現場の有無」を示すだけで、子現場自体の情報を取得する API は提供されていません
- **受入検証中の API**: 対象 API は社内Redmine の受入検証チケットで受入検証中であり、仕様が変更される可能性があります
- **エクスポートCSVは UTF-8 で保存**: API の元データは cp932 ですが、保存時に UTF-8 へ変換します。Excel で開くときは「データ」→「テキストまたは CSV から」で文字コードに UTF-8 を指定してください(そのまま開くと文字化けします)
- **一時ディレクトリのCSVは自動削除されません**: `save_path` を省略すると OS の一時ディレクトリに保存されます。不要になったファイルは手動で削除してください
## ドキュメント
| ドキュメント | 内容 |
|-------------|------|
| [Documents/DESIGN.md](Documents/DESIGN.md) | 設計書。スコープ、技術選定、ツール設計、認証・トークン管理、エラー処理、セキュリティ |
| [Documents/HANDOVER.md](Documents/HANDOVER.md) | 引き継ぎ資料。前提知識、実装手順、テスト方針、未決事項 |
## 参照実装
本サーバーは社内の既存 MCP サーバー **`mail-backend-mcp`**(`http://192.0.2.10/git/mail-backend-mcp`)と
同一の構成・配布形式で実装します。実装時はそちらのコードを写経ベースにしてください。
## ライセンス
社内利用限定
TDQS
Scored across 9 tools
Each tool targets a distinct resource: users, tenants, groups, devices, formats, three dashboard scopes, and observation data export. There is no overlap or ambiguity between any of the nine tools.
All tools follow a consistent verb_noun pattern: eight are list_<resource> and the sole exception is export_observation_data, which still uses the same verb_noun structure. No mixed conventions.
Nine tools is well within the ideal 3-15 range. Each tool covers a distinct aspect of the SaaS domain, so none feel redundant or unnecessary.
The tool set provides comprehensive read/list operations for all core entities (tenants, users, devices, groups, formats, dashboards) plus a data export function. It lacks single-item detail retrieval and any create/update/delete operations, but this appears to be an intentional read-only server design.