Teams MCP
A Model Context Protocol server that provides AI assistants with access to Microsoft Teams, enabling interaction with teams, channels, chats, and organizational data through Microsoft Graph APIs.
README Documentation
Teams MCP
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.
📦 Installation
To use this MCP server in Cursor/Claude/VS Code, add the following configuration:
{
"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_messagesend_chat_messagereply_to_channel_messageupdate_channel_messageupdate_chat_message
Format Options
You can specify the format parameter to control the message formatting:
text(default): Plain textmarkdown: 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
{
"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"
}
{
"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](https://github.com/floriscornel/teams-mcp/blob/main/url) - Lists: Bulleted (
- item) and numbered (1. item) - Code: Inline
`code`and blockscode - Headings:
# H1through###### 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_messagesget_channel_messagesget_channel_message_repliessearch_messagesget_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 consumptionraw: Returns the original HTML from the Microsoft Graph API
What Gets Converted
| HTML Element | Markdown Output |
|---|---|
<at id="0">Name</at> (Teams mention) | @Name (multi-word names merged using mentions metadata) |
<strong>text</strong> | **text** |
<em>text</em> | *text* |
<code>text</code> | `text` |
<a href="url">text</a> | [text](https://github.com/floriscornel/teams-mcp/blob/main/url) |
<ul><li>item</li></ul> | - item |
<table>...</table> | GFM Markdown table |
<attachment id="..."> | {attachment:id} |
<systemEventMessage/> | (removed) |
<hr> | --- |
, &, etc. | Decoded to plain characters |
Attachment Metadata
Messages that contain file attachments or inline images include an attachments array in the response with metadata for each attachment (id, name, contentType, contentUrl, thumbnailUrl). The inline {attachment:id} markers in the markdown content correlate with entries in this array, allowing consumers to identify and download attachments via download_message_hosted_content or download_chat_hosted_content.
Example Usage
{
"chatId": "19:meeting_...",
"limit": 10,
"contentFormat": "markdown"
}
To get the original HTML (previous default behavior):
{
"chatId": "19:meeting_...",
"limit": 10,
"contentFormat": "raw"
}
📦 Installation
# 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 profileUser.ReadBasic.All- Read basic user infoTeam.ReadBasic.All- Read team informationChannel.ReadBasic.All- Read channel informationChannelMessage.Read.All- Read channel messagesChannelMessage.Send- Send channel messages and repliesChannelMessage.ReadWrite- Edit and delete channel messagesChat.Read- Read chat messages (included via read-only scopes)Chat.ReadWrite- Create and manage chats, send/edit/delete chat messages (supersedesChat.Read)TeamMember.Read.All- Read team membersFiles.ReadWrite.All- Required for file uploads to channels and chats
Read-only mode (TEAMS_MCP_READ_ONLY=true) — only these scopes are requested:
User.ReadUser.ReadBasic.AllTeam.ReadBasic.AllChannel.ReadBasic.AllChannelMessage.Read.AllTeamMember.Read.AllChat.Read
🛠️ Usage
Starting the Server
# 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:
npx @floriscornel/teams-mcp@latest authenticate --read-only
MCP server configuration (read-only):
{
"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:
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 statusget_current_user- Get authenticated user information
User Operations
search_users- Search for users by name or emailget_user- Get detailed user information by ID or email
Teams Operations
list_teams- List user's joined teamslist_channels- List channels in a specific teamget_channel_messages- Retrieve messages from a team channel with pagination and filteringget_channel_message_replies- Get replies to a specific channel messagesend_channel_message- Send a message to a team channelreply_to_channel_message- Reply to an existing channel messageupdate_channel_message- Edit a previously sent channel messagedelete_channel_message- Soft delete a channel message (supports replies)list_team_members- List members of a specific teamsearch_users_for_mentions- Search for team members to @mention in messagessend_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 filteringsend_chat_message- Send a message to a chatcreate_chat- Create a new 1:1 or group chatupdate_chat_message- Edit a previously sent chat messagedelete_chat_message- Soft delete a chat messagesend_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 channel messagesdownload_chat_hosted_content- Download hosted content (images, files) from chat messages
Search Operations
search_messages- Search across all Teams messages using KQL syntaxget_my_mentions- Find messages mentioning the current user
📋 Examples
Authentication
First, authenticate with Microsoft Graph:
# 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:
npx @floriscornel/teams-mcp@latest check
Logout if needed:
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.
{
"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
- Fork the repository
- Create a feature branch
- Make your changes
- Run linting and formatting
- 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