SkillAgentSearch skills...

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-channel

If the server publishes to npm under a different name, use that package instead β€” check the repo README.

About this skill
πŸ”Œ

MCP Server

Model Context Protocol server

Quality Score

83/100

Supported Platforms

Claude Code
Claude Desktop

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.

Substance
30/30
Structure
20/20
Description
15/15
Adoption
3/20
Freshness
15/15

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.

SkillScoreStarsUpdatedFormat
msteams-channel (this skill)by gtapps833todayMCP Server
taste-skillby Leonxlnx100110.1ktodayCLAUDE.md
Agent-Reachby Panniantong100108.9k1d agoCLAUDE.md
headroomby headroomlabs-ai10078.9ktodayCLAUDE.md
ai-job-searchby ai-job-search-dev10069.6k1d agoCLAUDE.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.

Claude Code Microsoft Teams Channel Plugin

CI Version License Downloads

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 Microsoft devtunnel for 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" }
  ]
}

allowedChannelPlugins replaces the default allowlist, so preserve every existing channel entry. Once the file exists, channelsEnabled: true is 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

View on GitHub
GitHub Stars3
CategoryDevelopment
Updated10h ago
Forks1

Languages

TypeScript

Trust signals

92/100

From repository metadata: license, adoption, age and documentation. Not a code audit β€” see the Safety scan above for what the skill file itself contains.

1 low
msteams-channel β€” MCP Server: Install & Safety Check | SkillAgent