# Teams MCP
[](https://www.npmjs.com/package/@floriscornel/teams-mcp)
[](https://www.npmjs.com/package/@floriscornel/teams-mcp)
[](https://app.codecov.io/gh/floriscornel/teams-mcp)
[](https://opensource.org/licenses/MIT)
[](https://github.com/floriscornel/teams-mcp/stargazers)
A Model Context Protocol (MCP) server that provides seamless integration with Microsoft Graph APIs, enabling AI assistants to interact with Microsoft Teams, users, and organizational data.
<a href="https://glama.ai/mcp/servers/@floriscornel/teams-mcp">
<img width="380" height="200" src="https://glama.ai/mcp/servers/@floriscornel/teams-mcp/badge" alt="Teams MCP server" />
</a>
## π¦ Installation
To use this MCP server in Cursor/Claude/VS Code, add the following configuration:
```json
{
"mcpServers": {
"teams-mcp": {
"command": "npx",
"args": ["-y", "@floriscornel/teams-mcp@latest"]
}
}
}
```
## π Features
### π Authentication
- OAuth 2.0 authentication flow with Microsoft Graph
- Secure token management and refresh
- Authentication status checking
### π₯ User Management
- Get current user information
- Search users by name or email
- Retrieve detailed user profiles
- Access organizational directory data
### π’ Microsoft Teams Integration
- **Teams Management**
- List user's joined teams
- Access team details and metadata
- **Channel Operations**
- List channels within teams
- Retrieve channel messages
- Send messages to team channels
- Support for message importance levels (normal, high, urgent)
- **Team Members**
- List team members and their roles
- Access member information
### π¬ Chat & Messaging
- **1:1 and Group Chats**
- List user's chats
- Create new 1:1 or group conversations
- Retrieve chat message history with filtering and pagination
- Send messages to existing chats
- Edit previously sent chat messages
- Soft delete chat messages
### βοΈ Message Management
- **Edit & Delete**
- Update (edit) sent messages in chats and channels
- Soft delete messages in chats and channels (marks as deleted without permanent removal)
- Only message senders can update/delete their own messages
- Support for Markdown formatting, mentions, and importance levels on edits
### π Media & Attachments
- **Hosted Content**
- Download hosted content (images, files) from chat and channel messages
- Access inline images and attachments shared in conversations
- **File Upload**
- Upload and send any file type (PDF, DOCX, XLSX, ZIP, images, etc.) to channels and chats
- Large file support (>4 MB) via resumable upload sessions
- Optional message text, custom filename, formatting, and importance levels
### π Advanced Search & Discovery
- **Message Search**
- Search across all Teams channels and chats using Microsoft Search API
- Support for KQL (Keyword Query Language) syntax
- Filter by sender, mentions, attachments, importance, and date ranges
- Get recent messages with advanced filtering options
- Find messages mentioning specific users
## Rich Message Formatting Support
The following tools now support rich message formatting in Teams channels and chats:
- `send_channel_message`
- `send_chat_message`
- `reply_to_channel_message`
- `update_channel_message`
- `update_chat_message`
### Format Options
You can specify the `format` parameter to control the message formatting:
- `text` (default): Plain text
- `markdown`: Markdown formatting (bold, italic, lists, links, code, etc.) - converted to sanitized HTML
When `format` is set to `markdown`, the message content is converted to HTML using a secure markdown parser and sanitized to remove potentially dangerous content before being sent to Teams.
If `format` is not specified, the message will be sent as plain text.
### Example Usage
```json
{
"teamId": "...",
"channelId": "...",
"message": "**Bold text** and _italic text_\n\n- List item 1\n- List item 2\n\n[Link](https://example.com)",
"format": "markdown"
}
```
```json
{
"chatId": "...",
"message": "Simple plain text message",
"format": "text"
}
```
### Security Features
- **HTML Sanitization**: All markdown content is converted to HTML and sanitized to remove potentially dangerous elements (scripts, event handlers, etc.)
- **Allowed Tags**: Only safe HTML tags are permitted (p, strong, em, a, ul, ol, li, h1-h6, code, pre, etc.)
- **Safe Attributes**: Only safe attributes are allowed (href, target, src, alt, title, width, height)
- **XSS Prevention**: Content is automatically sanitized to prevent cross-site scripting attacks
### Supported Markdown Features
- **Text formatting**: Bold (`**text**`), italic (`_text_`), strikethrough (`~~text~~`)
- **Links**: `[text](url)`
- **Lists**: Bulleted (`- item`) and numbered (`1. item`)
- **Code**: Inline `` `code` `` and blocks ``` ```code``` ```
- **Headings**: `# H1` through `###### H6`
- **Line breaks**: Automatic conversion of newlines to `<br>` tags
- **Blockquotes**: `> quoted text`
- **Tables**: GitHub-flavored markdown tables
## LLM-Friendly Content Format
Messages retrieved from the Microsoft Graph API are returned as raw HTML containing Teams-specific tags. To make this content more consumable by AI assistants, the following tools support automatic HTML-to-Markdown conversion:
- `get_chat_messages`
- `get_channel_messages`
- `get_channel_message_replies`
- `search_messages`
- `get_my_mentions`
### Content Format Options
Use the `contentFormat` parameter to control how message content is returned:
- `markdown` (default): Converts Teams HTML to clean Markdown, optimized for LLM consumption
- `raw`: Returns the original HTML from the Microsoft Graph API
### What Gets Converted
| HTML Element | Markdown Output |
| -------------------------------------- | --------------------------- |
| `<at id="0">Name</at>` (Teams mention) | `@Name` |
| `<strong>text</strong>` | `**text**` |
| `<em>text</em>` | `*text*` |
| `<code>text</code>` | `` `text` `` |
| `<a href="url">text</a>` | `[text](url)` |
| `<ul><li>item</li></ul>` | `- item` |
| `<table>...</table>` | GFM Markdown table |
| `<attachment id="...">` | *(removed)* |
| `<systemEventMessage/>` | *(removed)* |
| `<hr>` | `---` |
| ` `, `&`, etc. | Decoded to plain characters |
### Example Usage
```json
{
"chatId": "19:meeting_...",
"limit": 10,
"contentFormat": "markdown"
}
```
To get the original HTML (previous default behavior):
```json
{
"chatId": "19:meeting_...",
"limit": 10,
"contentFormat": "raw"
}
```
## π¦ Installation
```bash
# Install dependencies
npm install
# Build the project
npm run build
# Set up authentication
npm run auth
```
## π§ Configuration
### Prerequisites
- Node.js 18+
- Microsoft 365 account with appropriate permissions
- Azure App Registration with Microsoft Graph permissions
### Required Microsoft Graph Permissions
**Full mode (default):**
- `User.Read` - Read user profile
- `User.ReadBasic.All` - Read basic user info
- `Team.ReadBasic.All` - Read team information
- `Channel.ReadBasic.All` - Read channel information
- `ChannelMessage.Read.All` - Read channel messages
- `ChannelMessage.Send` - Send channel messages and replies
- `ChannelMessage.ReadWrite` - Edit and delete channel messages
- `Chat.Read` - Read chat messages (included via read-only scopes)
- `Chat.ReadWrite` - Create and manage chats, send/edit/delete chat messages (supersedes `Chat.Read`)
- `TeamMember.Read.All` - Read team members
- `Files.ReadWrite.All` - Required for file uploads to channels and chats
**Read-only mode** (`TEAMS_MCP_READ_ONLY=true`) β only these scopes are requested:
- `User.Read`
- `User.ReadBasic.All`
- `Team.ReadBasic.All`
- `Channel.ReadBasic.All`
- `ChannelMessage.Read.All`
- `TeamMember.Read.All`
- `Chat.Read`
## π οΈ Usage
### Starting the Server
```bash
# Development mode with hot reload
npm run dev
# Production mode
npm run build && node dist/index.js
# Start in read-only mode (disables all write tools)
TEAMS_MCP_READ_ONLY=true node dist/index.js
```
### Read-Only Mode
The server supports a read-only mode that disables all write operations (sending messages, creating chats, uploading files, editing/deleting messages) and requests only read-permission scopes from Microsoft Graph.
**Enable read-only mode** using either:
- Environment variable: `TEAMS_MCP_READ_ONLY=true`
- CLI flag: `--read-only`
**Authenticate with reduced scopes:**
```bash
npx @floriscornel/teams-mcp@latest authenticate --read-only
```
**MCP server configuration (read-only):**
```json
{
"mcpServers": {
"teams-mcp": {
"command": "npx",
"args": ["-y", "@floriscornel/teams-mcp@latest"],
"env": {
"TEAMS_MCP_READ_ONLY": "true"
}
}
}
}
```
**Switching modes:** When switching from read-only to full mode, the server detects the scope mismatch and warns you to re-authenticate:
```bash
npx @floriscornel/teams-mcp@latest authenticate
```
**Read-only tools (15):**
`auth_status`, `get_current_user`, `search_users`, `get_user`, `list_teams`, `list_channels`, `get_channel_messages`, `get_channel_message_replies`, `list_team_members`, `search_users_for_mentions`, `download_message_hosted_content`, `list_chats`, `get_chat_messages`, `search_messages`, `get_my_mentions`
**Write tools disabled in read-only mode (10):**
`send_channel_message`, `reply_to_channel_message`, `update_channel_message`, `delete_channel_message`, `send_file_to_channel`, `send_chat_message`, `create_chat`, `update_chat_message`, `delete_chat_message`, `send_file_to_chat`
### Available MCP Tools
#### Authentication
- `auth_status` - Check current authentication status
- `get_current_user` - Get authenticated user information
#### User Operations
- `search_users` - Search for users by name or email
- `get_user` - Get detailed user information by ID or email
#### Teams Operations
- `list_teams` - List user's joined teams
- `list_channels` - List channels in a specific team
- `get_channel_messages` - Retrieve messages from a team channel with pagination and filtering
- `get_channel_message_replies` - Get replies to a specific channel message
- `send_channel_message` - Send a message to a team channel
- `reply_to_channel_message` - Reply to an existing channel message
- `update_channel_message` - Edit a previously sent channel message
- `delete_channel_message` - Soft delete a channel message (supports replies)
- `list_team_members` - List members of a specific team
- `search_users_for_mentions` - Search for team members to @mention in messages
- `send_file_to_channel` - Upload a local file and send it as a message to a channel
#### Chat Operations
- `list_chats` - List user's chats (1:1 and group)
- `get_chat_messages` - Retrieve messages from a specific chat with pagination and filtering
- `send_chat_message` - Send a message to a chat
- `create_chat` - Create a new 1:1 or group chat
- `update_chat_message` - Edit a previously sent chat message
- `delete_chat_message` - Soft delete a chat message
- `send_file_to_chat` - Upload a local file and send it as a message to a chat
#### Media Operations
- `download_message_hosted_content` - Download hosted content (images, files) from messages
#### Search Operations
- `search_messages` - Search across all Teams messages using KQL syntax
- `get_my_mentions` - Find messages mentioning the current user
## π Examples
### Authentication
First, authenticate with Microsoft Graph:
```bash
# Full access (default)
npx @floriscornel/teams-mcp@latest authenticate
# Read-only (reduced permission scopes)
npx @floriscornel/teams-mcp@latest authenticate --read-only
```
Check your authentication status:
```bash
npx @floriscornel/teams-mcp@latest check
```
Logout if needed:
```bash
npx @floriscornel/teams-mcp@latest logout
```
### Integrating with Cursor/Claude
This MCP server is designed to work with AI assistants like Claude/Cursor/VS Code through the Model Context Protocol.
```json
{
"mcpServers": {
"teams-mcp": {
"command": "npx",
"args": ["-y", "@floriscornel/teams-mcp@latest"]
}
}
}
```
## π Security
- All authentication is handled through Microsoft's OAuth 2.0 flow
- **Refresh token support**: Access tokens are automatically renewed using cached refresh tokens, so you don't need to re-authenticate every hour
- Token cache is stored locally at `~/.teams-mcp-token-cache.json`
- No sensitive data is logged or exposed
- Follows Microsoft Graph API security best practices
## π License
MIT License - see LICENSE file for details
## π€ Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Run linting and formatting
5. Submit a pull request
## π Support
For issues and questions:
- Check the existing GitHub issues
- Review Microsoft Graph API documentation
- Ensure proper authentication and permissions are configured