MS Graph MCP Server
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MS Graph MCP ServerSend a Teams message to the #general channel about the deployment."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MS Graph MCP Server for Cloud Run
Microsoft Graph API(Outlook メール、Teams チャット、ユーザー情報)を
MCP (Model Context Protocol) ツールとして提供する Python サーバーです。
Google Cloud Run 上にデプロイし、AI アシスタント(Claude Desktop、Cursor 等)から
Streamable HTTP 経由で呼び出すことで、自然言語によるメール操作・Teams 連携を実現します。
目的
本プロジェクトは、組織内の Microsoft 365 サービスを AI エージェントから安全に操作するためのブリッジとして機能します。
Outlook メール操作の自動化 — 下書き作成、送信、受信トレイ確認を AI アシスタントから実行
Teams メッセージ送信 — 1:1 チャット、グループチャット、チャネルへのメッセージ送信
ユーザー情報取得 — 部署・地域情報に基づくアクセス制御やリージョナルコンプライアンス(EU GDPR、中国 AI 規制等)の判定支援
セキュアなクラウドデプロイ — GCP Secret Manager によるシークレット管理、Cloud Run の内部通信制限
Related MCP server: M365 MCP Server
仕様
システムアーキテクチャ
┌──────────────────────┐ Streamable HTTP ┌──────────────────────────┐
│ │ POST /mcp │ │
│ MCP Client │─────────────────────────▶ │ FastAPI + FastMCP │
│ (Claude Desktop, │ │ (Cloud Run) │
│ Cursor, etc.) │◀─────────────────────────│ │
│ │ JSON Response │ │
└──────────────────────┘ └────────┬────────┬────────┘
│ │
MSAL Token │ │ Graph API
Request │ │ Calls
▼ ▼
┌────────────┐ ┌────────────────┐
│ Microsoft │ │ Microsoft │
│ Entra ID │ │ Graph API │
└────────────┘ └────────────────┘技術スタック
カテゴリ | 技術 |
言語 | Python 3.11+ |
Web フレームワーク | FastAPI + uvicorn |
MCP SDK |
|
認証 | MSAL (Client Credentials Flow) |
HTTP クライアント | httpx (非同期) |
シークレット管理 | GCP Secret Manager |
デプロイ先 | Google Cloud Run |
MCP ツール一覧
カテゴリ | ツール名 | 説明 |
Outlook メール |
| ユーザーのメールボックスに下書きメールを作成 |
Outlook メール |
| 作成済みの下書きメールを送信 |
Outlook メール |
| 受信トレイの最新メッセージ一覧を取得 |
Teams チャット |
| 1:1/グループチャット/チャネルにメッセージを送信 |
ユーザー情報 |
| 部署・役職・国/地域などのプロフィール情報を取得 |
必要な Microsoft Graph API 権限
以下は アプリケーション権限(管理者の同意が必要)です:
権限 | 用途 |
| メールの下書き作成・受信トレイ読取 |
| メールの送信 |
| Teams チャットへのメッセージ送信 |
| ユーザープロフィール情報の取得 |
プロジェクト構成と Python モジュールの役割分担
MS-Graph-MCP-Server_for_Cloud_Run/
├── app/
│ ├── __init__.py # パッケージ初期化
│ ├── main.py # ① エントリーポイント(FastAPI + MCP マウント)
│ ├── graph_client.py # ② Microsoft Graph API クライアント
│ └── mcp_tools.py # ③ MCP ツール定義(①と②の橋渡し)
├── requirements.txt # Python 依存パッケージ
├── Dockerfile # マルチステージ Docker ビルド
├── deploy.sh # GCP Cloud Run デプロイスクリプト
├── Gemini.md # プロジェクト仕様書
└── README.md # 本ドキュメント① app/main.py — エントリーポイント
役割: アプリケーション全体の起動と HTTP エンドポイントの定義
FastMCPサーバーをstateless_http=Trueで初期化(Cloud Run のステートレススケーリング対応)mcp.streamable_http_app()を FastAPI の/mcpパスにマウントlifespanコンテキストマネージャーでセッションマネージャーのライフサイクルと Graph クライアントのクリーンアップを管理GET /healthヘルスチェックエンドポイントを提供(Cloud Run の Readiness/Liveness プローブ用)mcp_tools.pyのregister_tools()を呼び出してツールを登録
リクエスト → FastAPI (main.py) → /mcp → FastMCP → ツール実行 → レスポンス② app/graph_client.py — Microsoft Graph API クライアント
役割: Microsoft Graph API との認証・通信を一手に担当
MSGraphClientクラス: MSAL のConfidentialClientApplicationを使用した Client Credentials Flow による認証トークン管理:
acquire_token_silent→acquire_token_for_clientの順でキャッシュ優先のトークン取得HTTP ヘルパー:
_get()/_post()メソッドで認証ヘッダー付きの非同期リクエストを実行シークレット解決: 環境変数 → GCP Secret Manager のフォールバック方式
ビジネスロジック: Outlook メール操作、Teams メッセージ送信、ユーザー情報取得の各メソッドを提供
mcp_tools.py → MSGraphClient → MSAL (トークン取得) → httpx (Graph API 呼び出し)③ app/mcp_tools.py — MCP ツール定義
役割: main.py と graph_client.py の橋渡し。MCP プロトコルのインターフェース層
register_tools(mcp)関数で全5ツールを@mcp.tool()デコレータにより FastMCP に登録各ツールは
MSGraphClientのメソッドを呼び出し、結果を構造化 JSON 文字列に整形して返却遅延初期化:
MSGraphClientはツール初回呼び出し時にインスタンス化(起動時のシークレット取得失敗を回避)エラーハンドリング: 全ツールで例外をキャッチし、エラー情報を JSON で返却(MCP クライアント側でのクラッシュを防止)
shutdown_client()でアプリケーション終了時の HTTP クライアントクリーンアップを提供
MCP Client → FastMCP → mcp_tools.py (ツール定義) → graph_client.py (API 呼出) → Graph APIモジュール間の依存関係
main.py ──imports──▶ mcp_tools.py ──imports──▶ graph_client.py
│ │ │
│ FastMCP 初期化 │ ツール登録 │ MSAL 認証
│ FastAPI マウント │ エラーハンドリング │ Graph API 通信
│ lifespan 管理 │ レスポンス整形 │ シークレット取得
▼ ▼ ▼
HTTP 層 インターフェース層 インフラ/通信層他のアプリケーションとの連携方法
MCP クライアントからの接続
本サーバーは MCP 準拠の Streamable HTTP エンドポイントを提供します。
MCP 対応クライアントであれば、以下の URL を設定するだけで接続可能です。
https://<YOUR_CLOUD_RUN_URL>/mcpClaude Desktop との連携
claude_desktop_config.json に以下を追加します:
{
"mcpServers": {
"ms-graph": {
"url": "https://<YOUR_CLOUD_RUN_URL>/mcp",
"transport": "streamable-http"
}
}
}Cursor との連携
Cursor の MCP 設定画面で以下を入力します:
Name:
ms-graphType:
streamable-httpURL:
https://<YOUR_CLOUD_RUN_URL>/mcp
独自アプリケーションからの連携(Python)
MCP Python SDK を使用してプログラムから接続できます:
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async def main():
async with streamablehttp_client("https://<YOUR_CLOUD_RUN_URL>/mcp") as (
read_stream, write_stream, _
):
async with ClientSession(read_stream, write_stream) as session:
await session.initialize()
# ツール一覧の取得
tools = await session.list_tools()
print(tools)
# メール下書き作成の例
result = await session.call_tool(
"create_email_draft",
arguments={
"user_email": "user@example.com",
"subject": "テスト件名",
"body_html": "<p>テスト本文</p>",
"to_recipients": ["recipient@example.com"],
},
)
print(result)認証が必要な場合(Cloud Run IAM)
Cloud Run が --no-allow-unauthenticated で設定されている場合、
クライアント側で ID トークンを取得してリクエストヘッダーに付与する必要があります:
# gcloud CLI で ID トークンを取得
TOKEN=$(gcloud auth print-identity-token)
curl -H "Authorization: Bearer ${TOKEN}" https://<YOUR_CLOUD_RUN_URL>/health開発環境
前提条件
Python 3.11 以上
Azure AD にアプリ登録済み(Client Credentials 用)
(任意) Docker Desktop(ローカルでのコンテナビルド確認用)
セットアップ
# リポジトリをクローン
git clone <repository-url>
cd MS-Graph-MCP-Server_for_Cloud_Run
# 仮想環境を作成・有効化
python3 -m venv .venv
source .venv/bin/activate
# 依存パッケージをインストール
pip install -r requirements.txt環境変数の設定(ローカル開発)
export TENANT_ID="your-azure-tenant-id"
export CLIENT_ID="your-azure-client-id"
export CLIENT_SECRET="your-azure-client-secret"ローカル起動
# uvicorn で起動
uvicorn app.main:app --host 0.0.0.0 --port 8080 --reload
# ヘルスチェック
curl http://localhost:8080/health
# → {"status":"healthy","service":"ms-graph-mcp-server"}MCP Inspector でのデバッグ
# MCP Inspector を使ってツール一覧・動作確認
mcp dev app/main.py実行環境(本番)
Google Cloud Run
設定項目 | 値 |
プラットフォーム | managed |
Ingress |
|
認証 |
|
メモリ | 512 Mi |
CPU | 1 |
タイムアウト | 300 秒 |
最小インスタンス | 0 |
最大インスタンス | 10 |
シークレット管理
シークレット名 | 説明 |
| Azure AD テナント ID |
| Azure AD アプリケーション (クライアント) ID |
| Azure AD クライアントシークレット |
シークレットは Cloud Run のデプロイ時に --set-secrets オプションで環境変数としてマウントされます。
デプロイ手順
# 1. 環境変数を設定
export GCP_PROJECT_ID="your-gcp-project-id"
export GCP_REGION="asia-northeast1" # 任意(デフォルト: asia-northeast1)
# 2. シークレットの値を登録(初回のみ)
echo -n "YOUR_TENANT_ID" | gcloud secrets versions add TENANT_ID --data-file=- --project=${GCP_PROJECT_ID}
echo -n "YOUR_CLIENT_ID" | gcloud secrets versions add CLIENT_ID --data-file=- --project=${GCP_PROJECT_ID}
echo -n "YOUR_CLIENT_SECRET" | gcloud secrets versions add CLIENT_SECRET --data-file=- --project=${GCP_PROJECT_ID}
# 3. デプロイ実行
chmod +x deploy.sh
./deploy.shエンドポイント
パス | メソッド | 説明 |
| POST | MCP Streamable HTTP エンドポイント |
| GET | ヘルスチェック |
メンテナンス方法
ログの確認
Cloud Run のログは Google Cloud Console または gcloud CLI で確認できます:
# 直近のログを確認
gcloud run services logs read ms-graph-mcp-server \
--region=asia-northeast1 \
--project=${GCP_PROJECT_ID} \
--limit=100
# リアルタイムでログを追跡
gcloud run services logs tail ms-graph-mcp-server \
--region=asia-northeast1 \
--project=${GCP_PROJECT_ID}シークレットのローテーション
Azure AD のクライアントシークレットを更新した場合:
# 1. Secret Manager に新しい値を追加
echo -n "NEW_CLIENT_SECRET" | gcloud secrets versions add CLIENT_SECRET \
--data-file=- --project=${GCP_PROJECT_ID}
# 2. Cloud Run サービスを再デプロイ(最新のシークレットバージョンを取得)
gcloud run services update ms-graph-mcp-server \
--region=asia-northeast1 \
--project=${GCP_PROJECT_ID} \
--set-secrets="TENANT_ID=TENANT_ID:latest,CLIENT_ID=CLIENT_ID:latest,CLIENT_SECRET=CLIENT_SECRET:latest"新しい MCP ツールの追加
app/graph_client.pyに新しい Graph API 操作メソッドを追加app/mcp_tools.pyのregister_tools()関数内に@mcp.tool()デコレータ付きの新しいツール関数を追加必要に応じて Azure AD のアプリ権限を追加・管理者承認
依存パッケージの更新
# 仮想環境内で最新バージョンを確認
pip list --outdated
# requirements.txt を更新後、再デプロイ
./deploy.shトラブルシューティング
症状 | 考えられる原因 | 対処 |
| Client ID/Secret/Tenant ID が不正 | Secret Manager の値を確認 |
| API 権限が不足 | Azure AD でアプリ権限を追加・管理者承認 |
| IAM 認証トークンが無効 |
|
ヘルスチェック失敗 | コンテナ起動エラー |
|
タイムアウト | Graph API の応答遅延 | Cloud Run のタイムアウト値を延長 |
ライセンス
本プロジェクトは社内利用を想定しています。ライセンスについては組織のポリシーに従ってください。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityAmaintenanceA production-ready MCP server that provides secure, delegated access to Microsoft 365 services including Email, SharePoint, OneDrive, and Calendar. It enables AI models to search messages, browse files, manage calendar events, and parse document contents using OAuth 2.1 authentication.Last updatedMIT
- Alicense-qualityCmaintenanceA secure remote MCP server that integrates Microsoft 365 services with AI assistants, enabling email, calendar, Teams, and contact operations via the Microsoft Graph API.Last updated2MIT
- Flicense-qualityDmaintenanceAn MCP server that exposes 17 Google Workspace APIs (e.g., Gmail, Drive, Calendar) as auto-generated tools for AI assistants, enabling natural language control of Google services.Last updated
Related MCP Connectors
Hosted Google Calendar MCP server for AI agents. No self-hosting or Google Cloud setup.
Phone, SMS & email for AI agents — one remote MCP endpoint, OAuth login, zero install.
MCP Hub: AI service discovery, per-user OAuth, and multi-service workflow orchestration
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/MT-Git01/MS-Graph-MCP-Server_for_Cloud_Run'
If you have feedback or need assistance with the MCP directory API, please join our Discord server