msteams-channel
A Claude Code channel plugin that connects a Microsoft Teams bot to your session. DMs and mention-gated channels, pairing and allowlists, self-hosted in your own tenant.
Install / Use
claude mcp add gtapps -- npx -y github:gtapps/msteams-channelIf the server publishes to npm under a different name, use that package instead β check the repo README.
MCP Server
Model Context Protocol server
Quality Score
Category
Development & EngineeringSupported Platforms
Tags
Our assessment of msteams-channel
msteams-channel scores 83/100 on our quality scale, 3010th of 4,622 Development & Engineering skills we index.
Its MCP Server is 12 KB long, well organised into 15 sections with 9 code examples: a thorough specification that gives an agent plenty to work with.
It has 3 GitHub stars, so there is little community track record yet; judge it on its content.
Maintenance, license and trust
- The repository was last updated today, so msteams-channel is actively maintained.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 92/100, with 1 caution from licensing, adoption, age or documentation. These come from repository metadata, not a code audit β read the skill file before letting an agent act on it.
msteams-channel compared with similar skills
All 4 of these similar skills score higher than msteams-channel; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| msteams-channel (this skill)by gtapps | 83 | 3 | today | MCP Server |
| taste-skillby Leonxlnx | 100 | 110.1k | today | CLAUDE.md |
| Agent-Reachby Panniantong | 100 | 108.9k | 1d ago | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 78.9k | today | CLAUDE.md |
| ai-job-searchby ai-job-search-dev | 100 | 69.6k | 1d ago | CLAUDE.md |
Frequently asked questions
- How do I install msteams-channel?
- Run
claude mcp add gtapps -- npx -y github:gtapps/msteams-channel. The install tabs above show the steps for each supported agent. - Which AI agents does msteams-channel work with?
- It is written for Claude Code and Claude Desktop, as a MCP Server file. Other agents that read the same format can often use it too.
- Is msteams-channel safe to use?
- It is MIT-licensed and scores 92/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is msteams-channel still maintained?
- The repository was last updated today, so msteams-channel is actively maintained.
Skill content
View source on GitHubClaude Code Microsoft Teams Channel Plugin
A Claude Code channel plugin that connects a Microsoft Teams bot to your Claude Code session.
When the bot receives a message (a DM, or an @-mention in an opted-in channel or group chat), the MCP server forwards it to Claude and provides tools to reply and edit messages. Replies land in the same conversation or channel thread.
This is the Microsoft Teams counterpart to the official Discord and Telegram channels, built on the [Microsoft Agents SDK][sdk]. Pairing, allowlists and the permission relay work the same. There is no hosted relay or bot service: you run the plugin and its HTTPS ingress, and the bot registration stays in your Microsoft tenant.
Prerequisites
Teams pushes messages to a webhook, so it must reach the machine running Claude Code.
- Bun on
PATH: the MCP server runs on Bun. - A public HTTPS endpoint forwarding to
127.0.0.1:3978: a reverse proxy, Cloudflare Tunnel, or Microsoftdevtunnelfor development. - A Microsoft 365 organization you administer and an Azure subscription with the Owner role. See costs.
- Azure CLI: the setup is CLI-first, with a few Microsoft 365 and Teams admin-center steps.
- Permission to edit Claude Code managed settings.
Quick Setup
Registering a Teams bot takes real Azure provisioning, with more steps than Discord or Telegram. SETUP.md is the full runbook, and its agent-assisted setup prompt lets Claude Code drive the process for you.
1. Register the Teams bot.
Follow SETUP.md steps 0β5: Entra app
registration, credentials, Azure Bot, Teams channel. Credentials land in
<state dir>/.env with mode 0600, never in command arguments or logs.
2. Install the plugin.
Run these where Claude Code runs:
claude plugin marketplace add gtapps/msteams-channel
claude plugin install msteams@msteams-channel --scope local
A local checkout works too: replace gtapps/msteams-channel in the first command with
/path/to/msteams-channel. Use local scope, because every session that loads the
plugin starts a webhook listener, and a user-scoped install creates port conflicts.
3. Allow the community channel.
On Claude Code v2.1.220+, community channel plugins must be allowlisted in the
managed-settings file (/etc/claude-code/managed-settings.json on Linux and
WSL, /Library/Application Support/ClaudeCode/managed-settings.json on macOS),
with channels enabled:
{
"channelsEnabled": true,
"allowedChannelPlugins": [
{ "marketplace": "msteams-channel", "plugin": "msteams" }
]
}
allowedChannelPluginsreplaces the default allowlist, so preserve every existing channel entry. Once the file exists,channelsEnabled: trueis required or every channel is silently blocked. Details: SETUP.md step 6.
4. Launch with the channel flag.
claude --channels plugin:msteams@msteams-channel
Do not use --dangerously-load-development-channels: as of Claude Code v2.1.220 it
does not register community channels. The managed-settings route above is required.
5. Pair.
DM the bot on Teams and it replies with a pairing code. In your Claude Code session:
/msteams:access pair <code>
Your next DM reaches the assistant. /msteams:configure shows configuration status if
nothing happens.
6. Lock it down.
Pairing is for capturing IDs. Once you're in, switch to allowlist so strangers don't
get pairing-code replies:
/msteams:access policy allowlist
Access control
See ACCESS.md for DM policies, channel and group-chat opt-in, mention
detection, the permission relay, skill commands, and the access.json schema.
Quick reference: senders are matched on AAD object IDs (pairing captures them;
display names never grant access). Default policy is pairing. Channels and group
chats are opt-in per conversation ID and mention-gated by default. Messages from other
tenants are refused outright.
Adding the bot to a team or group chat installs a Teams app, so it needs an app
package: ./teams-app/build.sh builds one from your bot id. DMs need none of this.
See SETUP.md.
Tools exposed to the assistant
| Tool | Purpose |
| --------------------- | ---------------------------------------------------------------------------------------------------------------- |
| reply | Reply to a DM, channel, group chat or channel thread. Auto-chunks long text; attaches files. |
| edit_message | Replace the text of a message the bot previously sent. Useful for "workingβ¦" β result updates. |
| download_attachment | Download a non-image inbound attachment into the local inbox. |
| react | Returns an explanatory error: Teams reactions need a signed-in user. See docs/REACTIONS.md. |
Proactive sends need no running session:
bun send.ts --list
bun send.ts --conversation <id> --text "Deployment complete"
bun send.ts --conversation <id> --files ./report.pdf
Differences from Discord and Telegram
| Capability | Teams | Discord | Telegram |
| ------------------ | :-------------------------: | :--------: | :--------: |
| Reactions | β why | β
| β
|
| Typing indicator | β | β
| β
|
| Outbound files | β
how | β
| β
|
| Permission prompts | y <code> / n <code> | β
buttons | β
buttons |
| Message history | β | β
recent | β |
Unchecked capabilities are unavailable today, not roadmap commitments.
Attachments
Inbound images are downloaded automatically to <state dir>/inbox/; other file types
are listed in the notification and fetched on demand with download_attachment.
Outbound, Teams has no single "send a file" call, so each file takes one of three
routes. Claude just passes paths to reply; the routing is automatic.
| File | In a DM | In a channel or group chat | |---|---|---| | Image under 4MB | inline, renders in the message | inline, renders in the message | | Anything else (and larger images) | consent card the recipient must Accept | uploaded to SharePoint, posted as a file card |
Limits: 100MB per file, 10 files and 200MB per reply.
Consent cards are asynchronous. In a DM the bot cannot push a file at someone: it
offers one, and the bytes move only when the recipient clicks Accept. The tool result
says offered <name>, and that is the end of it, no completion event follows. The
channel server must be running when they click, because it is what performs the
upload. Unaccepted offers expire after an hour.
Channels and group chats need a SharePoint site (MSTEAMS_SHAREPOINT_SITE_ID, see
SETUP.md). Without it, text,
inline images and DM file sends all keep working, and only those sends fail, with an
explanation. Channel files get an organization-wide link; group-chat files get a link
restricted to the people in that chat, and the send fails rather than widening the
link if that membership cannot be read.
Teams exposes no message history to bots, so Claude only sees messages as they arrive; paste or summarize earlier context.
How it works
Claude Code starts one Bun process that is both the MCP server and the Teams webhook:
Microsoft Teams ββHTTPSββ> your ingress
β
127.0.0.1:3978/api/messages
β
msteams MCP server
β stdio
Claude Code session
The Microsoft SDK authenticates every request before it reaches plugin code. You own the HTTPS edge; the plugin binds localhost by default.
| Variable | Default | Notes |
| ---------------------- | --------------- | --------------------------------------------- |
| MSTEAMS_WEBHOOK_PORT | 3978 | One port per bot. |
| MSTEAMS_WEBHOOK_PATH | /api/messages | Must match the bot's messaging endpoint. |
| MSTEAMS_WEBHOOK_HOST | 127.0.0.1 | Use 0.0.0.0 in Docker and publish the port. |
State directory
~/.claude/channels/msteams/ by default, beside the discord and telegram channels,
holding .env, access.json, conversation references and the queue. Dirs are 0700,
files 0600.
MSTEAMS_STATE_DIR moves it. Export it in the shell that launches claude so the
listener and the operator skills resolve the same directory; when they split, the
skills detect it and refuse to write. See
TROUBLESHOOTING.md.
A project-local state dir holds live credentials, so gitignore it yourself.
One bot registration has one messaging endpoint, so Teams traffic reaches exactly one listener. Running a second project needs its own bot registration end to end; see SETUP.md.
Security
- The Microsoft SDK authenticates requests; the plugin enforces the tenant boundary.
- AAD object IDs grant access; display names never do.
- Every outbound send requires a conversation the inbound gate already accepted and that is still allowed; revocation stops both directions immediately.
- Permission requests go only to allowlisted DMs and use one-shot verdicts. The relay
needs
--permission-mode default; auto mode never asks. - Outbound files add one egress path: uploads go only to Microsoft hosts (allowlisted, HTTPS, refusing redirects, and rejecting any host that resolves to a private address) or to the SharePoint site you configured. The upload URL Teams hands back is treated as a credential: held in memory, never logged, never written to disk.
- Files the channel itself stores (credentials, conversation references, pending snapshots) can never be sent back out; the inbox is the one exception, since that is where inbound downloads land.
Troubleshooting
An unregistered or refused message fails silently in Teams. Start with the
Channel notifications skipped: line in ~/.claude/debug/<session-id>.txt, then
follow TROUBLESHOOTING.md.
Development
bun test # no tenant, no network
bun run typecheck
bun run dev
See CONTRIBUTING.md for the development workflow.
Uninstall
claude plugin uninstall msteams@msteams-channel --scope local
claude plugin marketplace remove msteams-channel
Remove the msteams managed-settings entry, delete yo
Truncated for display β read the full file on GitHub.
Related Skills
taste-skill
110.1kAgent skills that give coding agents taste: art direction, reference images and a browser check instead of generic AI pages
Agent-Reach
108.9kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu β one CLI, zero API fees.
headroom
78.9kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
ai-job-search
69.6kThe job search that runs on your machine. AI job application framework built on Claude Code: evaluate postings, tailor CVs, write cover letters, prep interviews. Fork it and own it.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit β see the Safety scan above for what the skill file itself contains.
