使用说明
Entra ID保护的MCP服务器
受Microsoft Entra ID(前Azure AD)认证保护的Model Context Protocol(MCP)服务器
具有Microsoft Entra ID访问令牌验证功能的FastMCP服务器。提供认证用户的索赔信息检索、Azure资源管理、Microsoft Graph API集成、基于角色的访问控制(RBAC)等功能。
✨ 主要功能
- 🔐 Microsoft Entra ID认证:JWT令牌签名验证、audience/issuer验证、作用域或角色验证
- 👤 获取用户信息:从访问令牌中提取详细的用户索赔信息
- ☁️ 空气资源整合:通过On-Bahalf-Of(OBO)流获取Azure Virtual Machines一览表
- 📊 Microsoft Graph统合:检索和优化用户简档信息的查询
- 🎭 基于角色的访问控制:基于令牌roles索赔的阶段性信息访问控制
- 🔧 可扩展设计:可轻松添加新MCP工具的模块结构
📑 目次
技术栈
- python: 3.12+
- MCP框架: FastMCP 2.14.5+
- 认证:
python-jose- JWT検证msal–OBO流cryptography- 暗号化処理
- Azure SDK/微软图形SDK:
azure-mgmt-compute- Azure VM 管理msgraph-sdk-Microsoft Graph API客户端
- 包管理: 紫外线
机能概要
🔐 认证机能
- 全面验证Microsoft Entra ID的JWT令牌
- 签名验证(使用JWKS)
aud(audience)和iss(issuer)的验证- 所需作用域(
ENTRA_REQUIRED_SCOPES)或必需角色(ENTRA_REQUIRED_ROLES),模板名称将采用不同的格式 - 验证成功时,将通过哪个scope/role输出到INFO日志
- 基于快速MCP的MCP服务器
- 默认值:
streamable-http通过传输localhost:8000等待 - 灵活的环境变量设置
- 默认值:
🛠️ 交付工具
用户信息
get_user_info:获取已认证用户的索赔信息subject,tenant_id,user_principal_name,email,name,roles,scopes等等
Azure统合
list_azure_vms: Azure Virtual Machines 一覧取得- 在OBO流中更换为Azure资源管理器的标记
- 返回指定预订中的虚拟机信息
Microsoft Graph统合
get_graph_me:获取用户的完整基本信息- 在OBO流中更换为Graph API用令牌
get_graph_me_with_select_query:优化的字段检索$select仅检索查询所需的字段- 优化网络效率和响应速度
基于角色的访问控制(RBAC)
get_company_info:按角色逐步提供企业信息- 无角色:基本发布信息
- 用户角色:详细的发布信息
- 审计角色:包括审计信息
- 管理员角色:包括机密信息的所有信息
get_sensitive_data:管理员角色专用敏感数据- 仅管理员角色所有者可访问
- 权限不足时
AuthenticationError发生
list_available_resources:可访问资源列表- 列出当前用户角色可访问的资源
- 便于权限确认
目录配置
entra-id-protected-mcp-server/
├── .vscode/
│ ├── launch.json # VS Code デバッグ設定
│ └── settings.json # VS Code エディタ設定
├── src/
│ ├── main.py # エントリーポイント
│ ├── auth/ # 認証関連
│ │ ├── __init__.py
│ │ ├── entra_auth_provider.py # Microsoft Entra ID トークン検証
│ │ ├── obo_client.py # On-Behalf-Of フロー実装
│ │ └── claims_helpers.py # クレーム情報抽出ヘルパー
│ ├── common/ # 共通ユーティリティ
│ │ ├── __init__.py
│ │ ├── config.py # 環境変数設定
│ │ ├── logging_config.py # ログ設定管理
│ │ └── utils.py # ヘルパー関数
│ └── tools/ # MCP ツール
│ ├── __init__.py # ツール自動登録
│ ├── userinfo.py # ユーザー情報ツール
│ ├── azure_vm.py # Azure VM 管理ツール
│ ├── graph_user.py # Graph API ツール
│ └── role_based_info.py # RBAC ツール
├── .env.example # 環境変数テンプレート
├── LOGGING_GUIDE.md # ログ設定の詳細ガイド
├── pyproject.toml # プロジェクト設定と依存関係
├── uv.lock # uv のロックファイル
└── README.md # このファイル
主要模块角色
|模块|角色|
|----------|------|
| main.py 初始化和启动快速MCP服务器。读取配置、设置认证提供程序、注册工具
| auth/entra_auth_provider.py |JWT令牌的验证。获取JWKS并执行签名验证、audience/issuer/范围或角色检查
| auth/obo_client.py 使用MSAL实现On-Behalf-Of流。将用户令牌更换为服务令牌
| auth/claims_helpers.py 从访问令牌中提取用户信息角色作用域的辅助函数组
| common/config.py |环境变量的集中管理。提供Microsoft Entra ID设置、日志级别和MCP服务器设置
| common/logging_config.py 用于单独控制3种日志级别(应用程序认证MCP服务器)的设置类
| common/utils.py 范围透视、Graph模型序列化等辅助函数
| tools/__init__.py 自动检测和注册工具。tools/ 动态加载下属的模块
| tools/userinfo.py |用户信息获取工具(get_user_info) |
| tools/azure_vm.py |Azure VM管理工具(list_azure_vms) |
| tools/graph_user.py |Microsoft Graph工具(get_graph_me, get_graph_me_with_select_query) |
| tools/role_based_info.py RBAC工具(get_company_info, get_sensitive_data, list_available_resources) |
必要要件
- python: 3.12 以降
- 微软Entra ID租户
- API应用程序注册
- 可发行访问令牌的环境(SPA/Web应用/CLI等)
- 包管理器: 紫外线 (推奨)
安装,安装
1.Microsoft Entra ID的应用程序登录和作用域/应用程序角色制作
在使用此服务器之前,必须使用Microsoft Entra ID注册应用程序。此服务器包含Microsoft Entra ID v2.0令牌(requestedAccessTokenVersion=2),模板名称将采用不同的格式。
1-1.在Azure门户注册应用程序
- Azure门户→ “微软Entra ID” → “注册应用程序” → 「新规登録」
- 设置任意名称**「登録」** 来修改标记元素的显示属性
- 请记住以下信息(稍后)
.env文件):- 目录(租户)标识 -稍后
ENTRA_TENANT_ID设置为 - 应用程序(客户端)标识 -稍后
ENTRA_APP_CLIENT_ID设置为
- 目录(租户)标识 -稍后
1-2.将访问标记版本设置为v2.0
- 对象应用程序的 “宣言” 打开菜单
requestedAccessTokenVersion的2的明细栏样式中定义的设置
{
"requestedAccessTokenVersion": 2
}
1-3.设置应用程序标识URI
- 公开API 移到
- “设置” 或 设置应用程序标识URI 来修改标记元素的显示属性
- 设置URI(例如:
api://<アプリケーションID>) - 记下此值(稍后)
ENTRA_APP_CLIENT_ID作为.env),模板名称将采用不同的格式
1-4.作用域(access_as_user),模板名称将采用不同的格式
- 「公开API」 → 添加范围
- 输入:
- 作用域名称:
access_as_user - 谁可以同意:
Admins and users - 显示名称/描述:输入适当的说明
- 作用域名称:
- “已启用” 中选择所需的墙类型
- 范围名称
access_as_user(稍后)ENTRA_REQUIRED_SCOPES作为.env),模板名称将采用不同的格式
1-5.应用程序角色(access_as_application),模板名称将采用不同的格式
- 对象应用程序的 “应用程序角色” 的双曲正切值
- “创建应用程序角色” 来修改标记元素的显示属性
- 输入:
- 表示名:
access_as_application - 允许的成员类型: 应用程序
- 値:
access_as_application - 说明:输入适当的说明
- 表示名:
- 有効化 保存为
- 角色值
access_as_application(稍后)ENTRA_REQUIRED_ROLES作为.env),模板名称将采用不同的格式
💡 补足:此角色是在客户端凭据流等中获取的令牌的
roles包含在索赔中。
1-6.创建客户端密码(用于OBO流)
- “证书和密码” → 新客户端密码
- 设置说明和到期日期
- 秘密的 値 复制并记录(稍后)
ENTRA_APP_CLIENT_SECRET作为.env),模板名称将采用不同的格式
⚠️ 重要:仅在创建时显示密码值。你一定要记下来。
1-7.添加API访问权限
在OBO流中访问Azure或Graph API:
- 允许API访问 → 添加权限
- 添加:
- 微软图形:
User.Read(授权访问) - Azure服务管理:
user_impersonation(授权访问)
- 微软图形:
- “管理员同意” (需要管理员权限)
2.Microsoft Entra ID下的应用程序角色注册(可选)
如果要实现基于角色的访问控制(RBAC),请定义其他应用程序角色并将其分配给用户。另外,MCP服务器认证用角色 access_as_application 是按照前一章的步骤完成的假设。如果不需要RBAC功能,则可以跳过此步骤。
2-1.在Azure门户创建应用程序角色
- Azure门户→ “微软Entra ID” → “注册应用程序”
- 选择目标应用程序
- 从左侧菜单 “应用程序角色” 列表框中,此格式对应于条目“无”
- “创建应用程序角色” 来修改标记元素的显示属性
2-2.角色定义示例
创建以下三个角色:
字段:管理员
|----------|-------|---------|------|
| 表示名 |管理员|审核员|用户|
| 値 | Admin | Auditor | User |
| 说明 |管理员权限。可访问所有信息=审计人员权限。可访问审计信息=一般用户权限。可访问基本信息
| 允许的成员类型 | ☑ 两者(用户/组+应用程序)☑ 两者☑ 两者
| 有効化 | ☑ 有効 | ☑ 有効 | ☑ 有効 |
注: 値 字段为访问标记的
roles包含在索赔中。
2-3.将角色分配给用户
- Azure门户→ “微软Entra ID” → 企业应用程序
- 搜索并选择目标应用程序
- 用户和组 → 添加用户或组
- 选择用户或组
- 选择角色 中描述的场景,使用下列步骤创建明细表,以便在概念设计中分析体量的周长
- 分配 来修改标记元素的显示属性
2-4.使用标记检查角色
如果角色被正确分配 roles 包括在索赔中:
{
"aud": "api://your-app-id",
"iss": "https://login.microsoftonline.com/tenant-id/v2.0",
"sub": "user-object-id",
"roles": ["Admin", "User"],
"scp": "access_as_user"
}
令牌是 jwt.ms 啊 jwt.io 中所述修改相应参数的值。
⚠️ 注意事项:
- 要分配角色,请执行以下操作: 租户管理员权限 时褪色为此颜色
- 角色分配后,用户 重新登录 中描述的场景,使用以下步骤创建明细表,以便在概念设计中分析体量的体积
- 现有标记不包含新角色信息
3.克隆存储库
git clone <this-repo-url>
cd entra-id-protected-mcp-server
4.安装依赖包
这个项目 紫外线 中所述修改相应参数的值。
# uv がインストールされていない場合
pip install uv
# プロジェクト依存関係のインストール
uv sync
注:
uv是虚拟环境(.venv),模板名称将采用不同的格式。手动python -m venv而需要与环境混合的每条反射光线,进行环境采样。
5.设置环境变量
.env.example 的 .env 将条目添加到文档注册表。
# Windows (PowerShell)
Copy-Item .env.example .env
# Linux/macOS
cp .env.example .env
.env 设置示例:
# Microsoft Entra ID 認証設定
ENTRA_TENANT_ID=your-tenant-id-here
ENTRA_APP_CLIENT_ID=your-client-or-api-id-here
ENTRA_REQUIRED_SCOPES=access_as_user
ENTRA_REQUIRED_ROLES=access_as_application
ENTRA_APP_CLIENT_SECRET=your-mcp-api-client-secret-here
# ログレベル設定(3 種類を個別制御可能)
# APP_LOG_LEVEL: アプリ・Azure SDK・Microsoft Graph SDK のログレベル
APP_LOG_LEVEL=INFO
# ENTRA_AUTH_LOG_LEVEL: Entra 認証・MSAL のログレベル(未指定なら APP_LOG_LEVEL と同じ)
ENTRA_AUTH_LOG_LEVEL=INFO
# MCP_SERVER_LOG_LEVEL: MCP サーバーのログレベル(未指定なら APP_LOG_LEVEL と同じ)
MCP_SERVER_LOG_LEVEL=INFO
# MCP サーバー設定
MCP_TRANSPORT=streamable-http
MCP_HOST=localhost
MCP_PORT=8000
请设定在上述步骤1中取得的值。
実行方法
从VS Code启动(推荐)
VSCode的launch.json包含MCP服务器启动设置。
- 在VS代码中打开项目
.env创建文件并设置环境变量- 在运行和调试视图中 “运行MCP服务器” 列表框中,此格式对应于条目“无”
- 启动F5或开始调试
从命令行启动
# Windows (PowerShell)
$env:PYTHONPATH = "$PWD/src"
uv run python src/main.py
# Linux/macOS (Bash)
export PYTHONPATH="$PWD/src"
uv run python src/main.py
当服务器启动时,将显示以下日志:
2026-02-15 04:16:19,695 INFO __main__: Logger Configuration: LoggerConfig(app=INFO, auth=INFO, mcp_server=INFO)
2026-02-15 04:16:19,702 INFO __main__: Entra Tenant ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
2026-02-15 04:16:19,702 INFO __main__: Entra Required Scopes: access_as_user
2026-02-15 04:16:19,702 INFO __main__: Entra Required Roles: access_as_application
2026-02-15 04:16:19,836 INFO auth.entra_auth_provider: JWKS fetched: keys=6
[02/15/26 04:16:21] INFO Starting MCP server 'entra-mcp-server' with
transport 'streamable-http' on http://localhost:8000/mcp
在处理实际请求时,还将输出以下成功日志:
INFO auth.entra_auth_provider: Token validation succeeded via scopes: access_as_user
认证流程概述
sequenceDiagram
participant Client as MCP クライアント
participant Server as MCP サーバー
participant Entra as Microsoft Entra ID
participant Azure as Azure/Graph API
Client->>Entra: 1. ユーザー認証
Entra-->>Client: 2. アクセストークン (JWT)
Client->>Server: 3. Bearer トークンで MCP ツール呼び出し
opt JWKSキャッシュなし/期限切れ
Server->>Entra: 3a. JWKS (公開鍵) 取得
Entra-->>Server: 3b. JWKS 返却
end
Server->>Server: 4. JWT 検証 (署名, aud, iss, scopes/roles)
Server->>Entra: 5. OBO フロー (必要な場合)
Entra-->>Server: 6. サービストークン
Server->>Azure: 7. Azure/Graph API 呼び出し
Azure-->>Server: 8. データ返却
Server-->>Client: 9. 結果を返却
详细流程
- 客户端认证:MCP客户端(例如代理/编辑器扩展)从Microsoft Entra ID获取访问令牌
- 标记发送:
Authorization: Bearer <token>以页眉发送到MCP服务器 - 标记验证:
EntraIDAuthProvider验证以下内容- 签名验证(获取Entra的JWKS并在JOSE中验证)
audience的ENTRA_APP_CLIENT_ID符合issuer支持租户的URL- 所需作用域(
ENTRA_REQUIRED_SCOPES)或必需角色(ENTRA_REQUIRED_ROLES)中的任一项 - 验证成功时,在INFO日志中记录匹配的scope/role
- 保存上下文:验证成功时,FastMCP的
AccessToken的明细栏样式中定义的设置 - 工具运行:MCP工具
get_access_token()通过访问索赔 - OBO流程 (如果需要):要访问Azure/Graph API,请将用户令牌更换为服务令牌
- 错误处理:如果标记无效、过期、必需范围/角色不足
AuthenticationError发生
交付工具
👤 get_user_info
从已认证用户的访问令牌中提取并返回代表性索赔。
返回字段示例:
{
"subject": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"client_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"tenant_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"user_principal_name": "user@contoso.com",
"email": "user@contoso.com",
"name": "山田 太郎",
"roles": ["Admin", "User"],
"scopes": ["access_as_user"],
"issued_at": 1707868800,
"expires_at": 1707872400
}
☁️ list_azure_vms
获取指定预订中的“Azure Virtual Machines”列表。
引数:
subscription_id(string):Azure预订ID
动作:
- 在OBO流中将用户令牌更换为Azure资源管理器的令牌
azure-mgmt-compute在SDK中获取虚拟机列表- VMの基本情报(id,name,location,type,tags)を返却
返却例:
[
{
"id": "/subscriptions/.../resourceGroups/rg1/providers/Microsoft.Compute/virtualMachines/vm1",
"name": "vm1",
"location": "eastus",
"type": "Microsoft.Compute/virtualMachines",
"tags": {"environment": "production"}
}
]
📊 get_graph_me
使用Microsoft Graph API获取已认证用户的完整配置文件信息。
动作:
- 在OBO流中更换为Graph API标记(作用域:
https://graph.microsoft.com/.default) msgraph-sdk的/v1.0/me调用端点- 返回用户的所有基本信息字段
返回字段示例:
{
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"displayName": "山田 太郎",
"mail": "yamada@contoso.com",
"userPrincipalName": "yamada@contoso.com",
"jobTitle": "Senior Engineer",
"department": "Engineering",
"officeLocation": "Tokyo Office"
}
📊 get_graph_me_with_select_query
仅指定所需字段以获取用户简档信息(优化版)。
引数:
select(string):逗号分隔的字段列表- 默认值:
"displayName,mail,id,officeLocation,jobTitle"
- 默认值:
优点:
- 减少网络传输量
- 缩短响应时间
- 仅高效获取所需信息
使用例:
# 名前とメールのみ取得
result = await get_graph_me_with_select_query(select="displayName,mail")
# ID、役職、部署のみ取得
result = await get_graph_me_with_select_query(select="id,jobTitle,department")
🎭 get_company_info
根据角色逐步返回企业信息(RBAC实施示例)。
访问级别:
角色|可访问信息| |--------|-----------------| | 无角色 基本公开信息(公司名称、成立年份、联系方式等) | 用户 |详细な公开情报(従业员数范围、株式情报、认证情报など)| | 审计员 审核信息(实际员工数、年销售额、审核报告等) | 管理员 机密信息(未公开项目、详细财务、战略计划、董事报酬等)
返还示例(管理员角色):
{
"access_level": "admin",
"user_roles": ["Admin", "User"],
"company_name": "Contoso Corporation",
"public_info": { ... },
"audit_info": {
"employee_count": 2847,
"annual_revenue_usd": 450000000
},
"confidential_info": {
"unreleased_projects": [...],
"financial_details": {...},
"strategic_plans": {...}
}
}
🔒 get_sensitive_data
获取只有具有管理员角色的用户才能访问的敏感数据。
所需角色: Admin
错误处理:
try:
data = await get_sensitive_data()
except AuthenticationError as e:
# insufficient_role: 'Admin' role required, but user has ['User']
print(f"アクセス拒否: {e}")
📋 list_available_resources
列出当前用户角色可访问的资源和工具。
返却例:
{
"user_info": {
"name": "山田 太郎",
"user_id": "xxx-xxx-xxx",
"roles": ["Admin", "User"]
},
"accessible_resources": [
{
"resource": "公開会社情報",
"description": "会社の基本的な公開情報",
"access_level": "public",
"tools": ["get_company_info"]
},
{
"resource": "機密情報",
"description": "未公開プロジェクト、詳細財務情報",
"access_level": "admin",
"tools": ["get_company_info", "get_sensitive_data"]
}
]
}
调试和测试
在VS代码中执行调试
此存储库包含用于VSCode的调试配置(.vscode/launch.json),模板名称将采用不同的格式。
事前准备
.env创建并设置所需的值uv sync安装依赖关系- 安装VS代码的Python扩展
选择Python解释器
- 打开命令选项板(Ctrl+Shift+P/Cmd+Shift+P)
- “Python:选择解释器” 输入/选择
.venv中选择Python- 例:
Python 3.x.x ('.venv': venv) ./.venv/Scripts/python
- 例:
.venv对话框,您可以在此定义自定义格式settings.json添加:{ "python.venvPath": ".", "python.venvFolders": [".venv"] }
调试启动
- 在VS代码中打开项目
- 在运行和调试视图中 “运行MCP服务器” 列表框中,此格式对应于条目“无”
- F5或 启动调试 启动
您可以设置断点来执行标记验证和工具执行步骤。
在MCP检验器上测试
您可以使用MCP检查器交互式测试工具。
前提条件
- Node.js (推奨: v22.7.5 以降)
- MCP服务器正在启动(
localhost:8000)
1.获取访问令牌
在测试MCP检查器之前,使用Azure CLI获取访问令牌。
# アプリケーション ID URI を指定
$RESOURCE = "api://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# スコープを指定してログイン
az login --scope "$RESOURCE/access_as_user"
# アクセストークンを取得
$token = az account get-access-token --resource $RESOURCE --query accessToken -o tsv
# トークンの内容を確認 (オプション)
Write-Host "Token: $token"
💡 提示之一:要登录来宾用户,请在az login命令中添加--tenant选项,并指定要访问的租户的租户ID
💡 提示2:获取的标记为 jwt.ms 啊 jwt.io 中描述的场景,使用以下步骤创建明细表,以便在概念设计中分析体量的体积。
roles、scp等索赔是否正确包含。
2.MCP检查器的启动和设置
- 在VSCode的执行和调试视图中 “运行MCP检查器” 列表框中,此格式对应于条目“无”
- F5或 启动调试 启动
- 在浏览器中打开MCP检查器
- 设置MCP服务器连接:
- 传输:
HTTP/streamable-http - 统一资源定位符:
http://localhost:8000/mcp - 认证:
Authorization: Bearer <access_token><access_token>粘贴通过上述步骤获取的标记
- 传输:
3.测试工具
您可以在检查器上交互式测试以下工具:
get_user_info:确认令牌的索赔信息list_azure_vms:获取Azure VM列表(需要预订标识)get_graph_me:从Microsoft Graph获取用户简档get_company_info:根据角色获取企业信息list_available_resources:确认可访问的资源
调整日志级别
可以使用环境变量详细控制日志级别:
# 3 種類のログを個別制御
APP_LOG_LEVEL=DEBUG # アプリ・Azure SDK・Microsoft Graph SDK のログレベル
ENTRA_AUTH_LOG_LEVEL=DEBUG # Entra 認証・MSAL のログレベル
MCP_SERVER_LOG_LEVEL=INFO # MCP サーバーのログレベル
记录级别: DEBUG | INFO | WARNING | ERROR | CRITICAL
了解更多信息 LOGGING_GUIDE.md 来修改标记元素的显示属性。
开发指南
添加新的MCP工具
新的工具 tools/ 只要在属下添加模块就会自动注册。
最小配置示例
tools/hello.py:
from fastmcp import FastMCP
def register_tools(mcp: FastMCP) -> None:
"""Hello 系ツールを登録する。"""
@mcp.tool()
async def say_hello(name: str = "world") -> str:
"""挨拶メッセージを返すサンプルツール。
引数:
name: 挨拶する相手の名前
"""
return f"Hello, {name}!"
重新启动服务器时 say_hello 工具将自动可用。
访问认证的用户信息
from auth.claims_helpers import get_user_context, has_role
@mcp.tool()
async def my_tool():
"""認証済みユーザー情報を使用するツール。"""
# ユーザーコンテキストを取得(ヘルパー関数を使用)
roles, user_id, client_id, scopes, claims = get_user_context()
# ロールチェック
is_admin = has_role(roles, "Admin")
return {
"user_id": user_id,
"client_id": client_id,
"roles": roles,
"scopes": scopes,
"is_admin": is_admin
}
使用OBO流
访问Azure或Graph API:
from auth.claims_helpers import get_access_token_and_context
from auth.entra_auth_provider import build_obo_credential
@mcp.tool()
async def my_azure_tool():
"""Azure リソースにアクセスするツール。"""
# アクセストークンとユーザーコンテキストを取得
access_token, roles, user_id, client_id, scopes, claims = (
get_access_token_and_context()
)
# OBO credential を作成
credential = build_obo_credential(
access_token.token,
"https://management.azure.com/.default"
)
# Azure SDK で使用
# from azure.mgmt.compute import ComputeManagementClient
# client = ComputeManagementClient(credential, subscription_id)
错误处理
from starlette.authentication import AuthenticationError
import logging
logger = logging.getLogger(__name__)
@mcp.tool()
async def my_tool():
"""エラーハンドリングの例。"""
try:
# 処理
pass
except AuthenticationError:
logger.error("認証エラー")
raise
except Exception as e:
logger.error(f"予期しないエラー: {e}")
raise RuntimeError(f"tool_error: {str(e)}") from e
范围/角色设置
ENTRA_REQUIRED_SCOPES 和 ENTRA_REQUIRED_ROLES 可以用逗号分隔:
ENTRA_REQUIRED_SCOPES=access_as_user, User.Read, files.read
ENTRA_REQUIRED_ROLES=access_as_application, Admin
如果同时设置,则标记验证 满足所需范围 或 满足所需角色 中选择所需的墙类型。
utils.parse_scopes 将规格化为:
- 前后空格删除
- 小文字化
- 删除空元素
- 重复削除
- 排序
结果:
ENTRA_REQUIRED_SCOPES→["access_as_user", "files.read", "user.read"]ENTRA_REQUIRED_ROLES→["access_as_application", "admin"]
错误和日志
主要错误代码:
|错误代码|说明|发生时间|
|------------|------|--------------|
| jwks_fetch_failed |JWKS获取失败|服务器启动时|
| access_token_expired 标记过期|标记验证时|
| invalid_access_token |非法令牌|令牌验证时|
| invalid_issuer |发行者不一致|令牌验证时|
| invalid_audience |收件人不匹配|令牌验证时|
| missing_required_permissions |必需作用域/角色不足|令牌验证时|
| insufficient_role |角色不足|调用RBAC工具时|
| obo_token_acquisition_failed 在访问OBO流失败时
部署到Azure App Service
也可以将此服务器部署到Azure App Service中,在云环境中运行,作为远程MCP服务器使用。
1.在Azure Portal上创建App Service
1-1.新建应用程序服务
- 登录Azure Portal**“应用服务”** 查找并选择
- 「+ 作成」 → 「Web App」 来修改标记元素的显示属性
- 设置以下项目:
- 预订:选择要使用的预订
- 资源组:选择现有或新建
- 名前:输入应用程序的唯一名称(例如:
entra-mcp-server) - 公开: 代码 列表框中,此格式对应于条目“无”
- 运行时栈: 「Python 3.12」 列表框中,此格式对应于条目“无”
- 操作系统: 「Linux」 列表框中,此格式对应于条目“无”
- 地域:选择任意区域(例如,Japan East)
- 应用服务计划 (例如,基本B1)
- 确认和创建 → 「作成」 来修改标记元素的显示属性
1-2.设置环境变量
创建应用程序服务后,设置环境变量。
- 转到已创建的应用程序服务页面
- 从左侧菜单 「设定」> [环境变数] 列表框中,此格式对应于条目“无”
- 应用程序设置 在工作空间的边缘 「+追加」 来修改标记元素的显示属性
- 添加以下环境变量:
| 名前 | 値 | 说明 |
|---|---|---|
ENTRA_TENANT_ID |
your-tenant-id |Microsoft Entra ID租户ID| |
|
ENTRA_APP_CLIENT_ID |
api://your-client-id 应用程序(客户端)ID或API的URI |
|
ENTRA_REQUIRED_SCOPES |
access_as_user 必需的作用域(逗号分隔) |
|
ENTRA_REQUIRED_ROLES |
access_as_application 必须的应用程序角色(逗号分隔) |
|
ENTRA_APP_CLIENT_SECRET |
your-client-secret 客户机密(用于OBO流) |
|
APP_LOG_LEVEL |
INFO 应用程序日志级别 |
|
ENTRA_AUTH_LOG_LEVEL |
INFO |认证日志级别| |
|
MCP_SERVER_LOG_LEVEL |
INFO |MCP服务器日志级别| |
|
MCP_TRANSPORT |
streamable-http |MCP传输方式| |
|
MCP_HOST |
0.0.0.0 |
重要:在App Service中 0.0.0.0 设置为 |
MCP_PORT |
8000 |MCP服务器端口| |
⚠️ 重要:
MCP_HOST在App Service中必须0.0.0.0中所述修改相应参数的值。localhost中所述修改相应参数的值。
- 「保存」 单击保存设置
1-3.设置启动命令
在App Service中指定启动Python应用程序的命令。
- 「构成」 在工作空间的边缘 「全般设定」 选择选项卡
- 启动命令 在字段中输入:
python main.py
注:在后述的ZIP部署中
src/文件夹的内容/home/site/wwwroot中所述修改相应参数的值。因此main.py啊/home/site/wwwroot/main.py将条目添加到文档注册表。
- 「保存」 来修改标记元素的显示属性
2.使用VSCode的Azure Tools扩展进行ZIP部署
2-1.在VS代码中安装Azure App Service扩展
- 打开VS代码
- 打开扩展视图(Ctrl+Shift+X/Cmd+Shift+X)
- 「Azure应用服务」 搜索并安装
- 「Azure资源」 扩展功能也会自动安装
2-2.登录到Azure
- 在VS代码左侧的活动栏中 “空气”图标 来修改标记元素的显示属性
- “登录Azure…” 来修改标记元素的显示属性
- 因为浏览器打开,所以用Azure账户登录
2-3.准备部署
在部署之前requirements.txt 创建 src/ 放在下面。
💡 提示:
src/仅将文件夹上传到App Service,因此依赖文件也src/中所述修改相应参数的值。
- 在项目根目录中运行以下命令:
# requirements.txt を生成
uv export --format requirements-txt --output-file requirements.txt --no-hashes
# Windows (PowerShell)
Move-Item requirements.txt src/requirements.txt -Force
# Linux/macOS (Bash)
mv requirements.txt src/requirements.txt
- 确认:
src/应用程序代码位于目录中src/requirements.txt存在.env文件是 不包括(环境变量已在App Service的配置中设置)
2-4.执行ZIP部署
- 在VS代码中打开项目
- 在左侧的活动栏中 “空气”图标 来修改标记元素的显示属性
- “资源” 展开节
- 展开预订- “应用服务” 展开
- 创建的应用程序服务(例如:
entra-mcp-server),模板名称将采用不同的格式 - “部署到Web应用程序…” 列表框中,此格式对应于条目“无”
- 选择要部署的文件夹-
src选择文件夹 - 单击功能区上 “部署” 来修改标记元素的显示属性
部署完成后,日志将显示在VS代码输出面板中:
Deploying to "entra-mcp-server"...
Creating zip package...
Uploading package...
Deployment successful.
2-5.部署后确认
- 在Azure Portal上转到App Service页面
- 「概要」 在工作空间的边缘 统一资源定位符 点击进入应用程序
- 单击功能区上的日志流 的双曲正切值
如果已成功启动,则会显示以下日志:
2026-02-15 04:16:19,695 INFO __main__: Logger Configuration: LoggerConfig(app=INFO, auth=INFO, mcp_server=INFO)
2026-02-15 04:16:19,702 INFO __main__: Entra Tenant ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
2026-02-15 04:16:19,702 INFO __main__: Entra Required Scopes: access_as_user
2026-02-15 04:16:19,702 INFO __main__: Entra Required Roles: access_as_application
2026-02-15 04:16:19,836 INFO auth.entra_auth_provider: JWKS fetched: keys=6
[02/15/26 04:16:21] INFO Starting MCP server 'entra-mcp-server' with
transport 'streamable-http' on http://0.0.0.0:8000/mcp
2-6.连接到MCP服务器
要连接到部署的MCP服务器,请使用以下URL:
https://{App Service ドメイン名}/mcp
例:App Service名称为 entra-mcp-server 的情况下
https://entra-mcp-server.azurewebsites.net/mcp
💡 提示:App Service的域名是Azure Portal的 「概要」 中所述修改相应参数的值。