|
1 | 1 | # OneDrive Transcript Processing Agent |
2 | 2 |
|
3 | | -A Humr agent that polls OneDrive for Teams meeting recordings, downloads VTT transcripts, converts them into structured meeting notes, and posts results to Slack. |
| 3 | +A Humr agent that polls Microsoft Graph for new Teams meeting transcripts, converts them into structured markdown meeting notes, and posts the results to a Slack channel. |
4 | 4 |
|
5 | | -## Setup |
| 5 | +## How It Works |
6 | 6 |
|
7 | | -### 1. Configure Microsoft Graph Access |
| 7 | +On a cron schedule (default: every 30 minutes), the agent: |
8 | 8 |
|
9 | | -The agent accesses OneDrive via a Microsoft Graph MCP server (e.g., `microsoft-mcp`). Configure the MCP server in the agent schedule's `mcpServers` field. |
| 9 | +1. Reads `state/processed.json` to skip transcripts it has already handled. |
| 10 | +2. Lists the connected user's calendar events with Teams online meetings (`/me/events` with `isOnlineMeeting=true`). |
| 11 | +3. For each meeting, resolves the `onlineMeeting` resource by its `joinUrl`, then lists transcripts. |
| 12 | +4. Downloads each new transcript as VTT. |
| 13 | +5. Parses the VTT into structured JSON (speakers, segments, duration). |
| 14 | +6. Generates structured markdown meeting notes (subject, attendees, summary, key topics, action items, detailed notes). |
| 15 | +7. Posts the notes to the configured Slack channel. |
| 16 | +8. Records the processed transcript ID in `state/processed.json` (capped at 20 entries). |
10 | 17 |
|
11 | | -You will need a Microsoft Entra (Azure AD) app registration: |
| 18 | +Authentication to Microsoft Graph goes through OneCLI's MITM proxy — the agent uses `MICROSOFT_GRAPH_TOKEN=humr:sentinel` and the proxy swaps in a real OAuth bearer token transparently. |
12 | 19 |
|
13 | | -1. Go to [Azure Portal](https://portal.azure.com/) > **App registrations** > **New registration** |
14 | | -2. Set a redirect URI matching your OneCLI callback (e.g., `http://localhost:4444/api/apps/microsoft-graph/callback`) |
15 | | -3. Under **API permissions**, add Microsoft Graph delegated permissions: |
16 | | - - `Files.Read` (read OneDrive files) |
17 | | - - `Files.Read.All` (read all files the user can access) |
18 | | -4. Under **Certificates & secrets**, create a client secret |
19 | | -5. Note the **Application (client) ID** and **Client Secret** |
| 20 | +### Scope and limits |
20 | 21 |
|
21 | | -### 2. Configure OneCLI |
| 22 | +- ✅ **Scheduled Teams meetings** (those that appear on the user's calendar) are fully supported. |
| 23 | +- ❌ **MeetNow / ad-hoc channel meetings** are not supported. They have no calendar entry, and the bulk `getAllTranscripts` API requires application permissions + a Teams Application Access Policy (heavy admin overhead). For transcripts to be processed, the meeting must be scheduled via the calendar (not started with "Meet now"). |
22 | 24 |
|
23 | | -1. Open OneCLI at http://localhost:4444 |
24 | | -2. Add a **Microsoft Graph** connector with your Client ID and Client Secret |
25 | | -3. Complete the Microsoft OAuth consent flow |
26 | | -4. Grant the onedrive-transcript agent access to this credential |
| 25 | +## Setup |
27 | 26 |
|
28 | | -### 3. Configure Slack |
| 27 | +### 1. Register an Azure app |
29 | 28 |
|
30 | | -The agent posts meeting notes to Slack via an MCP server. Configure a Slack MCP server in the schedule's `mcpServers` field with a bot token that has `chat:write` permission for the target channel. |
| 29 | +1. Go to [Azure Portal > App registrations](https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade) > **New registration**. |
| 30 | +2. **Supported account types**: single-tenant. |
| 31 | +3. **Redirect URI**: `http://localhost:4444/api/apps/microsoft-graph/callback` (for local dev). Production: `http://<your-onecli-host>/api/apps/microsoft-graph/callback`. |
| 32 | +4. Under **API permissions**, add Microsoft Graph **Delegated** permissions: |
| 33 | + - `Calendars.Read` — list calendar events to find scheduled Teams meetings |
| 34 | + - `OnlineMeetings.Read` — resolve a meeting ID from its Teams join URL |
| 35 | + - `OnlineMeetingTranscript.Read.All` — list and download VTT transcripts (admin consent required by Microsoft policy, but the scope only grants per-user access) |
| 36 | + - `User.Read` — sign in |
| 37 | + - `offline_access` — refresh tokens |
| 38 | +5. Click **Grant admin consent for {tenant}**. |
| 39 | +6. Under **Certificates & secrets**, create a client secret. Copy the **Application (client) ID**, **Client Secret**, and **Tenant ID**. |
31 | 40 |
|
32 | | -### 4. Create a Schedule |
| 41 | +### 2. Connect Microsoft Graph in OneCLI |
33 | 42 |
|
34 | | -Create an agent schedule using the **onedrive-transcript** template with: |
| 43 | +1. Open OneCLI at http://localhost:4444 → **Apps** → **Microsoft Graph**. |
| 44 | +2. Enter Client ID, Client Secret, Tenant ID. Click **Save**. |
| 45 | +3. Click **Connect** to start the OAuth flow. Sign in as the user whose meeting transcripts you want to process. Approve the requested scopes. |
35 | 46 |
|
36 | | -- **Cron**: `*/30 * * * *` (every 30 minutes) |
37 | | -- **Session mode**: `continuous` (maintains context across runs) |
38 | | -- **Task prompt**: "Check OneDrive for new Teams meeting transcripts, process any new VTT files, and post meeting notes to Slack." |
39 | | -- **MCP servers**: Configure `microsoft-mcp` and `slack-mcp` with appropriate credentials |
| 47 | +### 3. Grant the connection to the agent |
40 | 48 |
|
41 | | -## How It Works |
| 49 | +1. Open the Humr UI at http://humr.localhost:4444. |
| 50 | +2. Add a new agent from the **onedrive-transcript** template. |
| 51 | +3. Open **Configure** → **Connections** → check **Microsoft Graph**. Save. |
| 52 | + |
| 53 | +### 4. Configure Slack |
42 | 54 |
|
43 | | -1. The agent runs on a cron schedule (default: every 30 minutes) |
44 | | -2. Each run, it reads `state/processed.json` to skip already-processed files |
45 | | -3. Lists the OneDrive recordings folder via the Microsoft Graph MCP server |
46 | | -4. For each new `.vtt` file: |
47 | | - - Downloads the transcript |
48 | | - - Parses it using the bundled `parse-vtt.py` script (via `uv`) |
49 | | - - Generates structured meeting notes with summary, attendees, action items |
50 | | - - Posts the notes to Slack |
51 | | -5. Updates `state/processed.json` with newly processed file IDs (capped at 5 entries) |
| 55 | +The agent posts via a Slack MCP server configured in the schedule's `mcpServers` field. You'll need a Slack app with `chat:write` permission and a bot token. Reference: [Slack MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/slack) (or any other Slack MCP server). |
52 | 56 |
|
53 | | -## Bundled Components |
| 57 | +### 5. Create a schedule |
54 | 58 |
|
55 | | -- **`scripts/parse-vtt.py`** — Python VTT parser that extracts speakers, timestamps, and merges consecutive same-speaker blocks into segments |
56 | | -- **`/process-transcript` skill** — Claude Code skill that orchestrates VTT parsing and meeting notes generation |
| 59 | +In the Humr UI, create a schedule on the agent with: |
| 60 | + |
| 61 | +- **Cron**: `*/30 * * * *` (every 30 minutes) |
| 62 | +- **Session mode**: `continuous` — the agent maintains context across runs |
| 63 | +- **Task prompt**: e.g. |
| 64 | + ``` |
| 65 | + Check for new Teams meeting transcripts since the last run, process them |
| 66 | + into meeting notes, and post each set of notes to the #meetings channel |
| 67 | + in Slack. |
| 68 | + ``` |
| 69 | +- **MCP servers**: configure the Slack MCP server with the bot token |
| 70 | + |
| 71 | +## Workspace contents |
| 72 | + |
| 73 | +``` |
| 74 | +/home/agent/work/ |
| 75 | +├── CLAUDE.md # Agent operating manual |
| 76 | +├── scripts/ |
| 77 | +│ ├── fetch-new-transcripts.py # List events, resolve meetings, download new VTTs |
| 78 | +│ ├── parse-vtt.py # VTT → structured JSON |
| 79 | +│ └── mark-processed.py # Append entry to state/processed.json |
| 80 | +└── state/ |
| 81 | + └── processed.json # Last 20 processed transcripts (managed by scripts) |
| 82 | +``` |
| 83 | + |
| 84 | +The workspace is persisted on the `/home/agent` PVC, so `state/processed.json` survives pod restarts. |
| 85 | + |
| 86 | +## Architecture |
| 87 | + |
| 88 | +The agent uses the Microsoft Graph REST API directly (no MCP server), with the OneCLI gateway handling token injection and refresh. The `microsoft-graph` provider in OneCLI is configured with tenant-aware token URL refresh — see `apps/web/src/lib/apps/microsoft-graph.ts` and `apps/gateway/src/apps.rs` in the OneCLI repo. |
| 89 | + |
| 90 | +## Future considerations |
| 91 | + |
| 92 | +- **Box upload**: post-processing to a Box folder (separate from Slack). Out of scope for this initial version. |
| 93 | +- **Application permissions**: required for processing MeetNow / channel meetings. Would need a Teams Application Access Policy configured by the tenant admin (PowerShell). Not implemented today; delegated auth covers scheduled meetings only. |
0 commit comments