使用说明
转录Webhook MCP服务器
一个MCP服务器,用于管理团队会议记录的Microsoft Graph webhook订阅并记录更改通知。用途 应用层 (客户端凭据)身份验证。
伴侣: 转录MCP服务器 (委托OBO认证)——按需转录检索服务器。
建筑
┌─────────────────────────────────────────┐
│ Transcripts Webhook MCP Server │
│ Auth: Application (Client Credentials) │
│ │
│ POST /mcp ─────── MCP Protocol │
│ Tools (8): │
│ • subscribe_to_transcripts │
│ • subscribe_to_recordings │
│ • list_subscriptions │
│ • renew_subscription │
│ • delete_subscription │
│ • get_notification_log │
│ • get_transcript_content │
│ • get_recording_url │
│ │
│ Resources (5): │
│ • webhook://status │
│ • webhook://subscriptions/{id} │
│ • webhook://notifications/{index} │
│ • webhook://transcripts/{u}/{m}/{t} │
│ • webhook://recordings/{u}/{m}/{r} │
│ │
│ POST /notifications ─── Graph Webhook │
│ • Validation handshake │
│ • Notification processing │
│ • Lifecycle event handling │
│ │
│ GET /health ────── Health Check │
└─────────────────┬───────────────────────┘
│
┌───────────┴──────────┐
▼ ▼
┌──────────┐ ┌──────────────┐
│ Graph │ │ Agent / │
│ Webhooks│ │ Copilot │
│ (push) │ │ (pull MCP) │
└──────────┘ └──────────────┘
授权与应用程序授权
| 转录MCP服务器 | 此Webhook服务器 | |
|---|---|---|
| 认证流程 | 委托OBO(用户在场) | 仅应用程序客户端凭据 |
| 身份 | 充当登录用户 | 充当应用程序 |
| 范围 | 仅限用户会议 | 所有用户会议 |
| 用例 | 按需检索 | 事件驱动自动化 |
| 扩展 | 缩放到0(按需) | 始终打开(webhook侦听器) |
工具
| 工具 | 说明 |
|---|---|
subscribe_to_transcripts |
为所有用户的新转录事件创建webhook订阅 |
subscribe_to_recordings |
为所有用户的新录制事件创建webhook订阅 |
list_subscriptions |
列出所有活动的webhook订阅(本地+可选Graph API检查) |
renew_subscription |
在订阅到期之前延长订阅期限(最长约70小时) |
delete_subscription |
删除webhook订阅 |
get_notification_log |
查看最近收到的通知和处理结果 |
get_transcript_content |
使用用户ID、会议ID和转录ID从通知日志中获取特定会议的完整转录(VTT格式) |
get_recording_url |
使用通知日志中的userId、meetingId和recordingId获取特定会议录制的限时下载URL |
资源
MCP资源提供了结构化的、URI可寻址的数据,代理可以直接读取这些数据,从而补充了上述工具。
| 资源 | URI | 描述 |
|---|---|---|
| 服务器状态 | webhook://status |
带有健康状况、活动订阅、通知统计和配置的实时仪表板 |
| 订阅详细信息 | webhook://subscriptions/{subscriptionId} |
特定跟踪订阅的详细信息(到期、通知URL、剩余时间) |
| 通知条目 | webhook://notifications/{index} |
按索引(0=最新)显示的特定通知,包含所有字段,包括成绩单内容 |
| 成绩单内容 | webhook://transcripts/{userId}/{meetingId}/{transcriptId} |
从Microsoft Graph实时获取完整的VTT成绩单 |
| 录制URL | webhook://recordings/{userId}/{meetingId}/{recordingId} |
从Microsoft Graph实时获取的限时下载URL |
注: 资源模板通过以下方式列出
resources/templates/list并支持自动完成通知日志中的变量。
场景和用例
1.自动会议记录
AI代理监控整个组织的所有团队会议。创建成绩单时,它会自动获取内容,生成包含操作项的摘要,并将其发布到Teams频道或SharePoint网站。
Meeting ends → Graph notification → auto-fetch transcript → agent summarises → posts to channel
使用的工具: subscribe_to_transcripts → get_notification_log → get_transcript_content
2.合规与记录保存
合规团队需要对所有记录的会议进行审计跟踪。webhook服务器实时捕获每个记录事件,代理定期检查日志并将记录URL存档到合规系统。
Recording created → Graph notification → agent retrieves download URL → archives to compliance store
使用的工具: subscribe_to_recordings → get_notification_log → get_recording_url
3.实时会议智能仪表板
连接到此MCP服务器的Copilot Studio代理为管理人员提供了一个对话界面,可以提出以下问题:
- “今天有会议记录吗?”
- “给我看上次项目脱口秀的记录”
- “本周收到了多少份成绩单通知?”
使用的工具: get_notification_log → get_transcript_content
4.会议情绪与主题分析
每次会议后,代理都会获取记录并运行情绪分析或主题提取。结果存储在数据库中用于趋势跟踪,例如跟踪团队士气在冲刺周期中的变化。
Transcript notification → fetch VTT content → parse speakers & dialogue → analyse sentiment → store trends
使用的工具: subscribe_to_transcripts → get_transcript_content
5.自动跟进电子邮件
代理人观察新的记录,总结讨论,提取行动项目和所有者,然后起草后续电子邮件给会议参与者。
Transcript created → fetch content → extract action items → draft & send follow-up email
使用的工具: get_notification_log → get_transcript_content
6.多租户监控
MSP或IT团队部署具有应用程序级权限的此服务器,以监控整个租户的会议活动,无需单个用户登录。始终在线的webhook侦听器确保即使在工作时间之外也不会错过任何事件。
主要优势:应用程序身份验证意味着服务器独立于任何用户会话运行。
7.培训和知识库
自动捕获培训课程、入职电话或客户演示的会议记录。代理获取成绩单,清理VTT格式,并将其作为可搜索文档存储在知识库中。
Training meeting ends → transcript notification → fetch content → clean & index → add to knowledge base
使用的工具: subscribe_to_transcripts → get_transcript_content
8.订阅健康监测
代理会定期检查订阅状态,并在订阅到期前自动续订(最大生存期约为70小时)。如果Graph删除了订阅,代理将检测生命周期事件并重新创建。
Agent on schedule → list_subscriptions (with Graph check) → renew if < 12h remaining → alert if missing
使用的工具: list_subscriptions → renew_subscription → subscribe_to_transcripts
先决条件
Azure应用程序注册
创建一个 分开 应用程序注册(或向现有应用程序添加应用程序权限):
- 首选 Azure 门户 → 应用程序注册 → 新注册
- 姓名:
Transcripts Webhook MCP(或类似) - 支持的帐户类型: 仅此组织目录中的帐户
应用程序权限
| 权限 | 类型 | 为什么 |
|---|---|---|
OnlineMeetingTranscript.Read.All |
应用程序 | 接收创建的成绩单通知 |
OnlineMeetingRecording.Read.All |
应用程序 | 接收录制创建的通知 |
OnlineMeetings.Read.All |
应用程序 | 读取任何用户的会议详细信息 |
重要:这些是 应用 权限(未委派)。他们要求 管理员同意.
管理员同意
az ad app permission admin-consent --id <your-app-object-id>
客户端密钥
- 首选 证书和秘密 → 新客户机密
- 复制机密值(您将不会再看到它)
- 设置为
AZURE_CLIENT_SECRET环境变量
环境变量
| 变量 | 必填 | 描述 |
|---|---|---|
AZURE_CLIENT_ID |
是 | 应用程序注册中的应用程序(客户端)ID |
AZURE_CLIENT_SECRET |
是 | 客户端机密值 |
AZURE_TENANT_ID |
是 | 目录(租户)ID |
NOTIFICATION_URL |
推荐 | 用于webhook通知的公共HTTPS URL(例如。 https://your-app.azurecontainerapps.io/notifications) |
PORT |
无 | 服务器端口(默认:8080) |
部署
码头工人
docker build -t transcripts-webhook-mcp .
docker run -p 8080:8080 \
-e AZURE_CLIENT_ID=your-client-id \
-e AZURE_CLIENT_SECRET=your-secret \
-e AZURE_TENANT_ID=your-tenant-id \
-e NOTIFICATION_URL=https://your-app.example.com/notifications \
transcripts-webhook-mcp
Azure容器应用
# Create ACR and build
az acr create -n <acr-name> -g <rg> --sku Basic --admin-enabled
az acr build -r <acr-name> -t transcripts-webhook-mcp:v1 .
# Create always-on container app (min replicas = 1)
az containerapp create \
--name transcripts-webhook-mcp \
--resource-group <rg> \
--image <acr-name>.azurecr.io/transcripts-webhook-mcp:v1 \
--target-port 8080 \
--ingress external \
--min-replicas 1 \
--max-replicas 2 \
--env-vars \
AZURE_CLIENT_ID=<client-id> \
AZURE_CLIENT_SECRET=secretref:client-secret \
AZURE_TENANT_ID=<tenant-id> \
NOTIFICATION_URL=https://<app-fqdn>/notifications
备注:
--min-replicas 1--此服务器必须保持运行才能接收webhook通知。与可以扩展到0的委托MCP服务器不同。
Webhooks的工作原理
1. Agent calls subscribe_to_transcripts
│
▼
2. Server POSTs to Graph /subscriptions
│
▼
3. Graph POSTs to /notifications?validationToken=xxx
│
▼
4. Server echoes validationToken → subscription confirmed
│
▼
5. User creates a meeting transcript in Teams
│
▼
6. Graph POSTs notification to /notifications
{
"subscriptionId": "...",
"changeType": "created",
"resource": "users/{userId}/onlineMeetings/{meetingId}/transcripts/{id}",
"tenantId": "..."
}
│
▼
7. Server logs notification, extracts user/meeting/transcript IDs
8. Server auto-fetches transcript content (VTT) or recording URL
9. Agent can retrieve content on-demand via get_transcript_content / get_recording_url
订阅生命周期
- 最大寿命:约4230分钟(约70.5小时)用于在线会议资源
- 续订:必须致电
renew_subscription到期前 - 生命周期事件:图形发送
reauthorizationRequired,subscriptionRemoved,missed通知
本地开发
npm install
npm run build
npm start
对于本地测试,通知URL必须可公开访问。使用类似隧道的 吸烟 或 Azure开发隧道:
# Using dev tunnels
devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host
# Use the tunnel URL as NOTIFICATION_URL
测试
健康检查
curl http://localhost:8080/health
MCP工具(通过curl)
所有工具均通过调用 POST /mcp 使用具有SSE响应格式的JSON-RPC 2.0。
订阅成绩单
为所有用户创建用于成绩单更改通知的webhook订阅。
# With defaults (uses server's NOTIFICATION_URL, 4200 min expiry)
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"subscribe_to_transcripts","arguments":{}}}'
# With custom options
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"subscribe_to_transcripts","arguments":{"notificationUrl":"https://your-app.example.com/notifications","expirationMinutes":4230,"clientState":"my-secret-state"}}}'
订阅录音
创建一个webhook订阅,用于记录所有用户的更改通知。
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"subscribe_to_recordings","arguments":{}}}'
列出订阅
列出所有活动的webhook订阅。根据Graph API进行可选验证。
# Local state only (fast)
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_subscriptions","arguments":{}}}'
# With Graph API verification (slower but more accurate)
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_subscriptions","arguments":{"includeGraphCheck":true}}}'
续订订阅
延长订阅的到期时间。必须在订阅失效前调用(最大生存期约为70小时)。
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"renew_subscription","arguments":{"subscriptionId":"YOUR-SUBSCRIPTION-ID"}}}'
# With custom expiry
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"renew_subscription","arguments":{"subscriptionId":"YOUR-SUBSCRIPTION-ID","expirationMinutes":4230}}}'
删除订阅
删除webhook订阅,停止所有未来的通知。
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"delete_subscription","arguments":{"subscriptionId":"YOUR-SUBSCRIPTION-ID"}}}'
获取通知日志
查看服务器最近收到的webhook通知。
# Default (last 20 notifications)
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_notification_log","arguments":{}}}'
# Last 5 notifications
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_notification_log","arguments":{"limit":5}}}'
获取成绩单内容
获取特定会议的完整成绩单(VTT格式)。使用通知日志中的userId、meetingId和transcriptId。
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_transcript_content","arguments":{"userId":"USER-ID-FROM-LOG","meetingId":"MEETING-ID-FROM-LOG","transcriptId":"TRANSCRIPT-ID-FROM-LOG"}}}'
获取录制URL
获取特定会议录制的限时下载URL。使用通知日志中的userId、meetingId和recordingId。
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_recording_url","arguments":{"userId":"USER-ID-FROM-LOG","meetingId":"MEETING-ID-FROM-LOG","recordingId":"RECORDING-ID-FROM-LOG"}}}'
MCP资源(通过curl)
列出静态资源:
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"resources/list","params":{}}'
列出资源模板:
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"resources/templates/list","params":{}}'
读取服务器状态:
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"resources/read","params":{"uri":"webhook://status"}}'
阅读特定订阅:
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"resources/read","params":{"uri":"webhook://subscriptions/SUBSCRIPTION-ID"}}'
按索引读取通知(0=最新):
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"resources/read","params":{"uri":"webhook://notifications/0"}}'
阅读成绩单:
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"resources/read","params":{"uri":"webhook://transcripts/USER-ID/MEETING-ID/TRANSCRIPT-ID"}}'
读取录制URL:
curl -s -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"resources/read","params":{"uri":"webhook://recordings/USER-ID/MEETING-ID/RECORDING-ID"}}'
Copilot工作室/代理提示
如果通过Copilot Studio或其他MCP感知代理连接,请使用以下自然语言提示:
| 提示 | 使用的工具 |
|---|---|
| “订阅成绩单通知” | subscribe_to_transcripts |
| “订阅录制通知” | subscribe_to_recordings |
| “显示所有活动的webhook订阅” | list_subscriptions |
| “检查我们的订阅是否仍在Graph中处于活动状态” | list_subscriptions (带图形检查) |
| “续订成绩单订阅” | renew_subscription |
“删除订阅 <id>" |
delete_subscription |
| “检查通知日志中最近的活动” | get_notification_log |
| “显示最近5条通知” | get_notification_log |
| “获取最新通知的完整成绩单” | get_transcript_content |
| 获取用户X、会议Y、记录Z的记录内容 | get_transcript_content |
| “从最新通知中获取录制下载URL” | get_recording_url |
| “总结最近的会议记录” | get_notification_log → get_transcript_content |
小贴士:代理将自动链接工具,例如首先检查通知日志,提取ID,然后获取转录内容。
Webhook验证(模拟Graph握手)
curl -s -X POST "http://localhost:8080/notifications?validationToken=test-token-123"
# Should return: test-token-123
模拟通知
curl -s -X POST http://localhost:8080/notifications \
-H "Content-Type: application/json" \
-d '{
"value": [{
"subscriptionId": "test-sub-id",
"changeType": "created",
"resource": "users/user-123/onlineMeetings/meeting-456/transcripts/transcript-789",
"tenantId": "tenant-abc",
"resourceData": {
"@odata.type": "#microsoft.graph.callTranscript",
"id": "transcript-789"
}
}]
}'
# Should return: 202 Accepted
Microsoft文档
安全注意事项
- 应用程序权限强大 --他们授予对所有用户会议数据的访问权限
- 在可能的情况下,部署网络隔离(ExpressRoute、专用端点)
- 使用
clientState在订阅中验证通知真实性 - 将客户端机密存储在Azure密钥库中,而不是生产环境中的环境变量中
- 监控通知日志中的意外活动
- 此服务器不需要或接受用户承载令牌,它使用自己的应用程序标识
免责声明
此MCP服务器是 独立开源项目 作为社区资源而建立。它是基于官方 Microsoft Graph API的Microsoft学习文档 并遵循公开记录的模式 变更通知 和 在线会议记录/录音.
本项目按“原样”提供,不提供任何明示或暗示的保证。 对于因使用本软件而产生的任何损害、数据丢失、安全事件或其他问题,作者不承担任何责任。您全权负责:
- 在将代码部署到您的环境中之前,请先对其进行审查和理解
- 保护您的Azure应用程序注册凭据和权限
- 遵守贵组织的数据治理和隐私政策
- 在使用访问所有用户会议数据的应用程序级权限时,确保适当的访问控制
这个项目是 不隶属于微软、不受微软认可或不受微软支持Microsoft Graph、Microsoft Teams、Azure和Copilot Studio是微软公司的商标。
使用风险自负。始终首先在非生产环境中进行测试。
许可证
麻省理工学院