Teams MCP - Subscription Management — Unique AI Documentation
Teams MCP - Subscription Management
A Microsoft Graph webhook subscription must be active for meeting transcripts to be ingested automatically. The server manages the full lifecycle — creation, renewal, expiry detection, and removal — and exposes it through three tools: start_kb_integration, stop_kb_integration, and verify_kb_integration_status.
Transcripts only
This subscription covers meeting-transcript ingestion into the Unique knowledge base. Chat and channel messages are read live through Microsoft Graph and are never subscribed to or ingested. The ingest_meeting tool does not require a subscription — it pulls a single meeting's transcript on demand.
Subscription Creation
Unlike a background-only connector, ingestion is opt-in per user: a subscription is created when the user calls start_kb_integration (it is not created automatically on connect).
start_kb_integrationinvokesSubscriptionCreateService.subscribe()- The service creates a Graph subscription for the resource
users/{providerUserId}/onlineMeetings/getAllTranscriptswithchangeType: created - The subscription is registered with
notificationUrl(transcript notifications) andlifecycleNotificationUrl(lifecycle events), authenticated with aclientStatewebhook secret - The subscription record is stored in the
subscriptionstable (internalType: 'transcript') with the Graph subscription id and its expiration time
The expiration time is set to the next occurrence of the configured off-peak UTC hour, giving a predictable renewal window.
Subscription Renewal
Subscriptions are renewed via Microsoft Graph lifecycle notifications:
- Microsoft sends a
reauthorizationRequiredlifecycle notification before the subscription expires (the exact timing varies; Microsoft does not guarantee a fixed window, but notifications arrive at least ~15 minutes before expiry) - The lifecycle webhook controller enqueues the event, and
SubscriptionReauthorizeService.reauthorize()PATCHes/subscriptions/{id}with a newexpirationDateTime - The new expiration is again the next configured UTC expiration hour, and the
subscriptionsrecord is updated to match
The database is the source of truth: a reauthorizationRequired notification for a subscription id that is not in the subscriptions table is ignored.
Subscription Status
The verify_kb_integration_status tool reports one of four statuses:
| Status | Meaning | Action |
|---|---|---|
active |
Subscription valid, more than 15 minutes until expiry | None required |
expiring_soon |
15 minutes or less until expiry | Renewal is automatic; no action needed |
expired |
Subscription has lapsed | Call start_kb_integration |
not_configured |
No subscription exists | Call start_kb_integration |
start_kb_integration
Safe to call at any time — it is idempotent and inspects the existing subscription before acting:
- No subscription exists: creates a new subscription (
created) - Valid subscription, more than 15 minutes until expiry: returns
already_active, no changes made - Valid subscription, expiring within 15 minutes: returns
expiring_soon, no changes made — automatic renewal is either in progress or imminent - Expired subscription: deletes the lapsed record and creates a fresh subscription (
created)
stop_kb_integration
Removes the transcript-ingestion subscription:
- Deletes the
subscriptionsrecord, then issuesDELETE /subscriptions/{id}to Microsoft Graph - Returns
removedwhen a record was deleted, ornot_foundwhen nothing was active
Removal stops future automatic ingestion. Previously ingested transcripts remain in the Unique knowledge base — stop_kb_integration does not delete content. To resume automatic ingestion, call start_kb_integration again.
Subscription Failure Handling
Microsoft Graph sends lifecycle notifications when a subscription's state changes. The server handles the two it acts on automatically; all other lifecycle events are discarded.
| Condition | What Happens | User Action Required? |
|---|---|---|
reauthorizationRequired lifecycle event |
Server automatically PATCHes the subscription with a new expiration time | No |
subscriptionRemoved lifecycle event |
Server deletes the local subscriptions record — automatic ingestion stops |
Yes — user must call start_kb_integration to re-subscribe |
Other lifecycle events (e.g. missed) |
Discarded and logged; no recovery action is taken | No |
| Subscription expired (missed renewal) | verify_kb_integration_status reports expired; no notifications are received |
Yes — user must call start_kb_integration |
| No subscription exists | verify_kb_integration_status reports not_configured |
Yes — user must call start_kb_integration |
No automatic gap recovery
Teams MCP does not run a catch-up pass for transcripts missed while a subscription was lapsed or after a missed lifecycle event. To ingest a specific meeting whose transcript was not captured, use ingest_meeting with the meeting's join URL.
Configuration
| Variable | Default | Description |
|---|---|---|
MICROSOFT_SUBSCRIPTION_EXPIRATION_TIME_HOURS_UTC |
3 |
Hour of day (UTC, 0–23) at which scheduled subscription expirations are set. |
MICROSOFT_WEBHOOK_SECRET |
(required) | Secret sent as the subscription clientState and validated on every incoming notification. |
SELF_URL / MICROSOFT_PUBLIC_WEBHOOK_URL |
SELF_URL |
Public URL Microsoft Graph posts notifications to. |