Content
# teams-mcp
macOS·Windows **Microsoft Teams(New Teams 2)** Read-only MCP Server (Rust).
No Microsoft Graph API, Bot, Token, or Network usage. Only reads data cached locally by Teams app in IndexedDB (local LevelDB), no admin approval or app registration required.
## How it works
- New Teams 2 (process name `MSTeams`, Edge WebView2) caches messages in local IndexedDB.
- Directly parses that LevelDB (`.ldb`/`.log`): **SSTable direct scan** (Chromium `idb_cmp1` comparator bypass) + snappy decompression + **V8 ValueSerializer** decoding.
- Conversation list = `db31/store1` (OneGQL_Conversation), Messages = `db44/store1` (replychain `messageMap`).
- **Read-only**: No write functionality, such as sending or editing messages. Does not manipulate Teams app.
See [`docs/`](docs/) for detailed storage structure and decision-making process (especially `docs/teams-storage-structure.md`, `docs/implementation-plan.md`).
## Scope
- ✅ **Read messages already in local cache** (Teams automatically caches several months' worth, hundreds to 1600 messages per chat).
- ❌ No functionality to collect past conversations not in cache (`docs/scroll-collection/`).
## Structure (Cargo Workspace)
| Crate | Role |
|---|---|
| `teams-core` | LevelDB reader + V8 decoder + Teams schema + query API (transport/MCP independent) |
| `teams-mcp-server` | rmcp `TeamsServer` (tool definition). Transport independent |
| `teams-mcp-stdio` | stdio transport binary |
| `teams-mcp-http` | Streamable HTTP transport binary (localhost bind) |
## Build
```bash
cargo build --release -p teams-mcp-stdio # → target/release/teams-mcp-stdio
cargo build --release -p teams-mcp-http # → target/release/teams-mcp-http
```
## Tools
| Tool | Description |
|---|---|
| `list_chats` | Cached conversation list (conversation name, conversationId, message count, last message) in recent order |
| `read_messages` | Messages in a specific conversation (`chat`=conversationId exact match or conversation name partial match, `limit`, `before_ms`) |
| `search_messages` | Global keyword search in cache (`query`, `limit`) |
## Run · Register
### stdio (Claude Code etc.)
```bash
claude mcp add teams-mcp -s user -- /Users/ljh/workspace/etc/teams-mcp/target/release/teams-mcp-stdio
```
Custom JSON configuration:
```json
{
"mcpServers": {
"teams-mcp": {
"command": "/Users/ljh/workspace/etc/teams-mcp/target/release/teams-mcp-stdio"
}
}
}
```
### HTTP
```bash
# Default 127.0.0.1:8787/mcp, no authentication (localhost only)
target/release/teams-mcp-http
# Change address + Bearer token authentication
TEAMS_MCP_HTTP_ADDR=127.0.0.1:9000 TEAMS_MCP_TOKEN=secret target/release/teams-mcp-http
```
> ⚠️ HTTP exposes sensitive Teams messages over the network. **Default localhost bind**; if external exposure is required, set `TEAMS_MCP_TOKEN`.
## Environment Variables
- `TEAMS_MCP_DB` — IndexedDB leveldb path override. If not set, uses OS-specific standard Teams v2 path:
- macOS: `$HOME/Library/Containers/com.microsoft.teams2/Data/Library/Application Support/Microsoft/MSTeams/EBWebView/WV2Profile_tfw/IndexedDB/https_teams.microsoft.com_0.indexeddb.leveldb`
- Windows: `%LOCALAPPDATA%\Packages\MSTeams_8wekyb3d8bbwe\LocalCache\Microsoft\MSTeams\EBWebView\WV2Profile_tfw\IndexedDB\https_teams.microsoft.com_0.indexeddb.leveldb`
- Linux etc.: No native New Teams 2 client, so only specify with `TEAMS_MCP_DB`.
- `TEAMS_MCP_HTTP_ADDR` — HTTP bind address (default `127.0.0.1:8787`).
- `TEAMS_MCP_TOKEN` — Required for HTTP `Authorization: Bearer <token>`.