Skip to main content
Octo includes a built-in MS Teams MCP server that lets agents read chats, send messages, and browse teams/channels — all using your personal Microsoft account. No admin approval or Azure AD app registration required.

How It Works

The Teams server runs as a local STDIO process alongside Octo. It uses Microsoft Graph API with user-consent-only scopes and ships a pre-registered public client ID, so authentication is a one-time device code flow — open a URL, enter a code, done.
The server uses the same pre-registered Azure AD application as Softeria ms-365-mcp-server. No tenant admin involvement needed.

Setup

The Teams server is included with Octo. Just add the entry to .mcp.json:
{
  "mcpServers": {
    "msteams": {
      "type": "stdio",
      "command": ".venv/bin/python",
      "args": ["-m", "octo.mcp_servers.teams"]
    }
  }
}
Then reload:
/mcp reload

Authentication

1

Trigger login

Ask Octo to check your Teams messages, or call the login tool directly:
/call msteams login
2

Complete device code flow

The server prints a URL and code to the console:
To sign in, use a web browser to open the page
https://microsoft.com/devicelogin and enter the code ABCD12345
Open the URL, enter the code, and sign in with your Microsoft account.
3

Approve permissions

Microsoft shows a consent screen for these permissions:
PermissionDescription
Read your chat messagesChat.Read
Send chat messagesChatMessage.Send
Read names and descriptions of teamsTeam.ReadBasic.All
Read names and descriptions of channelsChannel.ReadBasic.All
Sign you in and read your profileUser.Read
Click Accept. All permissions are user-consent — no admin approval needed.
4

Done

The token is cached locally. Subsequent calls use silent refresh — no re-auth needed until the refresh token expires (typically 90 days).
The device code flow blocks the tool call until you complete authentication in your browser. If you don’t complete it within 15 minutes, the flow times out.

Available Tools

The server exposes 10 tools:
ToolDescription
loginAuthenticate via device code flow
logoutClear cached tokens
list-chatsList recent chats with message previews and members
list-chat-messagesRead messages from a specific chat
list-chat-membersList members of a chat
find-chatSearch for chats by person name or topic
send-chat-messageSend a message to a chat
reply-to-chat-messageReply to a specific message
list-joined-teamsList Teams you belong to
list-team-channelsList channels in a Team

Parameter Names

All parameters use camelCase to match what LLMs naturally generate:
chatId, messageId, teamId, contentType, limit

Contacts Cache

The server maintains a local contacts cache at ~/.octo/teams_contacts.json. This lets the find-chat tool resolve names instantly without calling the API.

How It Builds

The cache auto-populates when you use list-chats — member names and chat metadata are indexed. After one list-chats call with 50 chats, the cache typically contains 1000+ users from your organization.

How find-chat Uses It

  1. You ask: “check messages from Valentina”
  2. Agent calls find-chat with query: "Valentina"
  3. Server searches the cache by name — instant match
  4. Agent gets the chat ID and calls list-chat-messages
If the cache doesn’t have a match, find-chat automatically fetches the 50 most recent chats, updates the cache, and retries.
The cache persists across server restarts. Run list-chats with a high limit once to seed the cache, then find-chat handles lookups from there.

Token & Cache Storage

All state is stored under ~/.octo/ by default:
FilePurpose
~/.octo/teams_token_cache.jsonMSAL token cache (access + refresh tokens)
~/.octo/teams_contacts.jsonContacts and chat index for fast lookups
File permissions on the token cache are set to 0600 (owner-only read/write).

Overriding Locations

Environment VariableDefaultDescription
TEAMS_TOKEN_CACHE~/.octo/teams_token_cache.jsonPath to the MSAL token cache file
TEAMS_CACHE_DIR~/.octoDirectory for the contacts cache
TEAMS_CLIENT_IDPre-registered public clientOverride with your own Azure AD app
TEAMS_TENANT_IDcommonAzure AD tenant ID
Set these in .mcp.json under env if needed:
"msteams": {
    "type": "stdio",
    "command": ".venv/bin/python",
    "args": ["-m", "octo.mcp_servers.teams"],
    "env": {
        "TEAMS_CLIENT_ID": "your-app-client-id",
        "TEAMS_TENANT_ID": "your-tenant-id"
    }
}

Permissions & Limitations

  • Reading 1:1 and group chat messages
  • Sending messages to any chat you’re a member of
  • Replying to specific messages
  • Listing teams and channels you belong to
  • Browsing chat members
FeatureRequired ScopeWhy
Reading channel messagesChannelMessage.Read.AllAdmin consent required
Posting to channelsChannelMessage.SendAdmin consent required
Reading all user chats (app-level)Chat.Read.AllApplication permission
If your organization’s Azure AD admin has pre-approved these scopes for the Softeria app, channel features may work. But Octo does not request them by default.

Using Your Own Azure AD App

If you prefer to use your own app registration (e.g., to request additional scopes or for compliance):
1

Register an app

Go to Azure Portal > App registrations > New registration.
  • Name: anything (e.g., “Octo Teams”)
  • Supported account types: Accounts in any organizational directory (multi-tenant)
2

Enable public client

Under Authentication > Advanced settings, set Allow public client flows to Yes.
3

Add API permissions

Under API permissions > Add a permission > Microsoft Graph > Delegated:
  • User.Read
  • Chat.Read
  • ChatMessage.Send
  • Team.ReadBasic.All
  • Channel.ReadBasic.All
Add more scopes if needed (e.g., ChannelMessage.Read.All — requires admin consent).
4

Configure Octo

Copy the Application (client) ID and optionally the Directory (tenant) ID:
"msteams": {
    "type": "stdio",
    "command": ".venv/bin/python",
    "args": ["-m", "octo.mcp_servers.teams"],
    "env": {
        "TEAMS_CLIENT_ID": "your-client-id-here",
        "TEAMS_TENANT_ID": "your-tenant-id"
    }
}

Troubleshooting

The refresh token may have expired. Run logout then login again:
/call msteams logout
/call msteams login
Or delete the cache file: rm ~/.octo/teams_token_cache.json
Your organization may block the Chat.Read scope. Check with your Azure AD admin, or try using your own app registration with admin-approved scopes.
The contacts cache may not be populated yet. Run list-chats with a high limit first:
/call msteams list-chats limit=50
Then retry your search.
Verify the Python path is correct and msal is installed:
.venv/bin/python -c "import msal; print('OK')"
.venv/bin/python -m octo.mcp_servers.teams  # should start, Ctrl+C to stop
The device code is printed to stderr. If your MCP client doesn’t show stderr, check the process output manually or look for the login tool’s return value.

What’s Next?