Skip to main content
Glama

mcp-teams

npm CI licence

A safe-by-default Model Context Protocol server for Microsoft Teams, over Microsoft Graph. It lets an agent read and operate Teams — list joined teams, channels and members, read channel messages and threaded replies, read 1:1/group chats and their messages, and (in higher modes) post to channels, reply in threads, send chat messages, and soft-delete a message.

Browser sign-in: on first run it opens your browser to the Microsoft sign-in page, then caches the token and refreshes it silently — the server never sees your password.

Part of the dockndevai MCP server suite — one governance model across all of them.

What it gives an agent

The server starts read-only (see Safe by default); higher-capability tools are only registered when you raise the mode.

Tool

For

Needs mode

whoami

confirm which account is in use

read-only

list_teams

teams the user has joined

read-only

list_channels

channels in a team

read-only

list_team_members

members of a team

read-only

list_channel_messages

recent messages in a channel

read-only

get_channel_message

one channel message + body

read-only

list_message_replies

a channel message's thread

read-only

list_chats

the user's 1:1 / group chats

read-only

list_chat_messages

messages in a chat

read-only

send_channel_message

post to a channel

read-write + TEAMS_ALLOW_SEND

reply_channel_message

reply in a channel thread

read-write + TEAMS_ALLOW_SEND

send_chat_message

send a chat message

read-write + TEAMS_ALLOW_SEND

delete_channel_message

soft-delete your own message

admin + TEAMS_ALLOW_DELETE

Related MCP server: teams-mcp-server

Install

npx -y @dockndevai/mcp-teams

You need an Entra (Azure AD) app registration. For the default browser sign-in, register a public client and add the redirect URI http://localhost (platform: Mobile and desktop applications), then use its Application (client) ID as TEAMS_CLIENT_ID. Grant delegated Team.ReadBasic.All, Channel.ReadBasic.All, ChannelMessage.Read.All (and ChannelMessage.Send / Chat.ReadWrite to post). No client secret is needed for interactive use.

Configure

{
  "mcpServers": {
    "teams": {
      "command": "npx",
      "args": ["-y", "@dockndevai/mcp-teams"],
      "env": {
        "TEAMS_CLIENT_ID": "00000000-0000-0000-0000-000000000000",
        "TEAMS_TENANT_ID": "common",
        "TEAMS_MODE": "read-only"
      }
    }
  }
}

On first use the server opens your browser to sign in and caches the token at ~/.mcp-teams/token.json (0600); later runs refresh silently.

See docs/CLIENTS.md for Claude Code / Cursor / Codex / VS Code / Windsurf snippets, and .env.example for every supported variable.

Authentication

Auth mode is chosen automatically (override with TEAMS_AUTH):

  • interactive (default) — only TEAMS_CLIENT_ID set. Authorization-code + PKCE with a loopback redirect: the browser opens, you approve once, and the access + refresh token are cached on disk. Most Teams messaging APIs are delegated-only, so this is the primary mode. The server never handles your password.

  • client-credentials (app-only) — TEAMS_CLIENT_SECRET present; the server fetches an app token itself. Note that several Teams message APIs are not available to app-only tokens without protected-API approval from Microsoft.

  • token — TEAMS_TOKEN set to a pre-obtained Graph bearer token. You manage its lifetime.

Safe by default

The access model is enforced by src/security.ts — defence in depth on top of the Graph token's own scopes/roles:

  • TEAMS_MODE — read-only (default) → read-write → admin. A tool is registered only if the mode allows its capability. Read-only exposes the 9 read tools; posting needs read-write; deletes need admin.

  • TEAMS_ALLOW_SEND — posting a message is visible to others and can't be silently un-posted, so on top of read-write it also requires this flag.

  • TEAMS_ALLOW_DELETE — deletes require this flag on top of admin mode. Deletes are soft-deletes (recoverable), and only your own messages.

  • TEAMS_TEAM_ALLOWLIST / TEAMS_PROTECTED_TEAMS — confine which teams can be posted to / moderated; mark teams that may be read but never posted to.

  • Interactive confirmation — when the client supports MCP elicitation, posting (send_channel_message / reply_channel_message / send_chat_message) and delete_channel_message pause and ask the human to approve before running. The prompt shows the tool, the exact (secret-redacted) arguments and a fingerprint of them; the team, channel and message length are listed separately so they stay visible when a long message is truncated in the arguments dump (the dump is cut at 1500 characters). delete_channel_message also pins the message's version (team + channel + message id with Graph's etag, lastModifiedDateTime and deletedDateTime) across the prompt and is refused if it changed. A prompt nobody answers is a refusal. Clients that can't elicit fall back to the TEAMS_ALLOW_SEND / TEAMS_ALLOW_DELETE gates.

  • TEAMS_REQUIRE_HUMAN_APPROVAL — when true (default false), these operations are refused if the client cannot elicit, instead of falling back to the TEAMS_ALLOW_* gates alone.

  • TEAMS_DRY_RUN — validate and log writes without executing them.

  • TEAMS_AUDIT_LOG — a JSON audit line per guarded operation, on stderr (default on).

See SECURITY.md.

Developing

npm install
npm run build
# introspect the tool list without signing in (uses a fake token, no network):
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | TEAMS_TOKEN=x node dist/index.js
npm test

Licence

MIT

Available Tools

9 tools
get_channel_messageGet channel messageA
Read-onlyIdempotent

Fetch a single channel message by id, with its full body and metadata.

Inputs: team_id (required), channel_id (required), message_id (required).

list_channel_messagesList channel messagesA
Read-onlyIdempotent

List the top-level messages in a channel, most recent first. Returns compact summaries (id, from, created, body, webUrl). Use list_message_replies for a message's thread.

Inputs: team_id (required), channel_id (required), top.

list_channelsList channelsA
Read-onlyIdempotent

List the channels in a team, with their ids, display names, and membership type (standard/private/shared).

Inputs: team_id (required).

list_chat_messagesList chat messagesA
Read-onlyIdempotent

List the messages in a 1:1 or group chat, most recent first. Returns compact summaries.

Inputs: chat_id (required), top.

list_chatsList chatsA
Read-onlyIdempotent

List the signed-in user's 1:1 and group chats (id, topic, type, last updated). Use a chat id with list_chat_messages.

Inputs: top.

list_message_repliesList message repliesA
Read-onlyIdempotent

List the replies in a channel message's thread, most recent first.

Inputs: team_id (required), channel_id (required), message_id (required), top.

list_team_membersList team membersA
Read-onlyIdempotent

List the members of a team (display name, email, roles).

Inputs: team_id (required).

list_teamsList joined teamsA
Read-onlyIdempotent

List the teams the signed-in user is a member of, with their ids, display names, and descriptions. Start here to get a team id for list_channels.

Inputs: no named parameters.

whoamiWho am IA
Read-onlyIdempotent

Return the signed-in user's identity (display name, user principal name, id). Use this to confirm which account the server is operating as before reading or posting.

Inputs: no named parameters.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.1/5.0

    Scored across 9 tools

    Disambiguation5/5

    Each tool targets a distinct Teams entity and action: identity, teams, channels, members, channel messages, replies, and chats. The potentially similar message tools are clearly separated by scope (channel vs. chat vs. reply) and by singular vs. plural retrieval.

    Naming Consistency4/5

    The naming is overwhelmingly consistent with a list_* / get_* verb-noun pattern. The main deviation is whoami, which is a common standard command, and the distinction between list and get is semantically clear.

    Tool Count5/5

    Nine tools is well-scoped for a read-only Microsoft Teams server. Every tool earns its place by covering a distinct read operation without unnecessary redundancy or bloat.

    Completeness4/5

    Core read workflows are covered well: identity, teams, channels, members, channel messages with replies, and chats. The main gaps are the lack of a full get_chat_message equivalent, no search capability, and no write actions, but these are workable for a listing-focused server.

    Maintenance

    ActivityNo data
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI assistants to interact with Microsoft Teams, users, and organizational data via Microsoft Graph APIs, including sending messages, managing chats and channels, and searching messages.
      MIT
    • A
      license
      Not graded
      quality
      A
      maintenance
      Enables AI assistants to access Microsoft Teams, chats, users, files, and organizational data via Microsoft Graph APIs, including messaging, search, attachment handling, and user management.
      12 npm
      MIT