# Microsoft Teams API

**Category:** 💬 Communication  
**Repository:** https://github.com/Maxim-Mazurok/teams-api  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/microsoft-teams-api

## Description
AI-native Microsoft Teams integration — read chats, send messages, search people

## Claude Desktop Quick Installation
Heuristic fallback — verify the package name and runner against the repository README before running it. Uses `npx` (confidence: low):

```json
"mcpServers": {
  "microsoft-teams-api": {
    "command": "npx",
    "args": ["-y","microsoft-teams-api"]
  }
}
```

## Documentation & README

# teams-api

AI-native Microsoft Teams integration — read conversations, send messages, and manage members via the Teams Chat Service REST API.

Designed for autonomous AI agents that need to interact with Teams: read messages, reply to people, monitor conversations, and participate in team workflows.

[<img src="https://img.shields.io/badge/VS_Code-Install_Server-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white" alt="Install in VS Code">](https://insiders.vscode.dev/redirect?url=vscode%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522teams%2522%252C%2522command%2522%253A%2522npx%2522%252C%2522args%2522%253A%255B%2522-y%2522%252C%2522-p%2522%252C%2522teams-api%2540latest%2522%252C%2522teams-api-mcp%2522%255D%252C%2522env%2522%253A%257B%2522TEAMS_LOGIN%2522%253A%2522true%2522%257D%257D)
[<img src="https://img.shields.io/badge/VS_Code_Insiders-Install_Server-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white" alt="Install in VS Code Insiders">](https://insiders.vscode.dev/redirect?url=vscode-insiders%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522teams%2522%252C%2522command%2522%253A%2522npx%2522%252C%2522args%2522%253A%255B%2522-y%2522%252C%2522-p%2522%252C%2522teams-api%2540latest%2522%252C%2522teams-api-mcp%2522%255D%252C%2522env%2522%253A%257B%2522TEAMS_LOGIN%2522%253A%2522true%2522%257D%257D)
[![Install in Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/install-mcp?name=teams&config=%7B%22name%22%3A%22teams%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22-p%22%2C%22teams-api%40latest%22%2C%22teams-api-mcp%22%5D%2C%22env%22%3A%7B%22TEAMS_LOGIN%22%3A%22true%22%7D%7D)
[![npm version](https://img.shields.io/npm/v/teams-api?style=flat-square)](https://www.npmjs.com/package/teams-api)
[![MCP Registry](https://img.shields.io/badge/MCP_Registry-teams--api-green?style=flat-square)](https://registry.modelcontextprotocol.io)

> [!NOTE]
> This project was AI-generated using Claude Opus 4.6 with human guidance and review.

## Getting Started

`teams-api` can be used in three ways:

1. **MCP server** for editors and AI tools — the recommended path for most users.
2. **CLI** for direct terminal use.
3. **Programmatic Node.js library** — advanced, documented near the end.

### Prerequisites

- **[Node.js](https://nodejs.org/)** (v18 or later) — required for `npx`, which all MCP and CLI commands use.

### Install in your editor

The quickest way to get started is to click one of the install badges above, or follow the instructions for your editor below.

#### Editor-specific instructions

<details>
<summary><strong>VS Code / VS Code Insiders</strong></summary>

**Option 1 — One-click install:**

[<img src="https://img.shields.io/badge/VS_Code-Install_Server-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white" alt="Install in VS Code">](https://insiders.vscode.dev/redirect?url=vscode%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522teams%2522%252C%2522command%2522%253A%2522npx%2522%252C%2522args%2522%253A%255B%2522-y%2522%252C%2522-p%2522%252C%2522teams-api%2540latest%2522%252C%2522teams-api-mcp%2522%255D%252C%2522env%2522%253A%257B%2522TEAMS_LOGIN%2522%253A%2522true%2522%257D%257D)
[<img src="https://img.shields.io/badge/VS_Code_Insiders-Install_Server-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white" alt="Install in VS Code Insiders">](https://insiders.vscode.dev/redirect?url=vscode-insiders%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522teams%2522%252C%2522command%2522%253A%2522npx%2522%252C%2522args%2522%253A%255B%2522-y%2522%252C%2522-p%2522%252C%2522teams-api%2540latest%2522%252C%2522teams-api-mcp%2522%255D%252C%2522env%2522%253A%257B%2522TEAMS_LOGIN%2522%253A%2522true%2522%257D%257D)

**Option 2 — CLI:**

macOS / Linux:

```bash
# VS Code
code --add-mcp '{"name":"teams","command":"npx","args":["-y","-p","teams-api@latest","teams-api-mcp"],"env":{"TEAMS_LOGIN":"true"}}'

# VS Code Insiders
code-insiders --add-mcp '{"name":"teams","command":"npx","args":["-y","-p","teams-api@latest","teams-api-mcp"],"env":{"TEAMS_LOGIN":"true"}}'
```

Windows (PowerShell):

```powershell
# VS Code
code --add-mcp '{"name":"teams","command":"npx","args":["-y","-p","teams-api@latest","teams-api-mcp"],"env":{"TEAMS_LOGIN":"true"}}'

# VS Code Insiders
code-insiders --add-mcp '{"name":"teams","command":"npx","args":["-y","-p","teams-api@latest","teams-api-mcp"],"env":{"TEAMS_LOGIN":"true"}}'
```

Windows (CMD):

```cmd
rem VS Code
code --add-mcp "{\"name\":\"teams\",\"command\":\"npx\",\"args\":[\"-y\",\"-p\",\"teams-api@latest\",\"teams-api-mcp\"],\"env\":{\"TEAMS_LOGIN\":\"true\"}}"

rem VS Code Insiders
code-insiders --add-mcp "{\"name\":\"teams\",\"command\":\"npx\",\"args\":[\"-y\",\"-p\",\"teams-api@latest\",\"teams-api-mcp\"],\"env\":{\"TEAMS_LOGIN\":\"true\"}}"
```

**Option 3 — Manual config:**

Add to your VS Code MCP config (`.vscode/mcp.json` or User Settings):

```json
{
  "mcpServers": {
    "teams": {
      "command": "npx",
      "args": ["-y", "-p", "teams-api@latest", "teams-api-mcp"],
      "env": {
        "TEAMS_LOGIN": "true"
      }
    }
  }
}
```

</details>

<details>
<summary><strong>Cursor</strong></summary>

[![Install in Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/install-mcp?name=teams&config=%7B%22name%22%3A%22teams%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22-p%22%2C%22teams-api%40latest%22%2C%22teams-api-mcp%22%5D%2C%22env%22%3A%7B%22TEAMS_LOGIN%22%3A%22true%22%7D%7D)

Or add to `~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "teams": {
      "command": "npx",
      "args": ["-y", "-p", "teams-api@latest", "teams-api-mcp"],
      "env": {
        "TEAMS_LOGIN": "true"
      }
    }
  }
}
```

</details>

<details>
<summary><strong>Claude Desktop</strong></summary>

Add to `claude_desktop_config.json` ([how to find it](https://modelcontextprotocol.io/quickstart/user)):

```json
{
  "mcpServers": {
    "teams": {
      "command": "npx",
      "args": ["-y", "-p", "teams-api@latest", "teams-api-mcp"],
      "env": {
        "TEAMS_LOGIN": "true"
      }
    }
  }
}
```

</details>

<details>
<summary><strong>Claude Code</strong></summary>

```bash
claude mcp add teams -- npx -y -p teams-api@latest teams-api-mcp
```

Then set the environment variable `TEAMS_LOGIN=true` in your shell before starting Claude Code. The server will ask for your email interactively on first use.

</details>

<details>
<summary><strong>Windsurf</strong></summary>

Add to `~/.codeium/windsurf/mcp_config.json`:

```json
{
  "mcpServers": {
    "teams": {
      "command": "npx",
      "args": ["-y", "-p", "teams-api@latest", "teams-api-mcp"],
      "env": {
        "TEAMS_LOGIN": "true"
      }
    }
  }
}
```

</details>

> [!TIP]
> On macOS with a FIDO2 passkey, replace `TEAMS_LOGIN` with `TEAMS_AUTO` for fully unattended auth. See [Authentication](#authentication) for details.

### CLI

You can also use the CLI directly without installing anything:

```bash
npx -y -p teams-api@latest teams-api auth --login
npx -y -p teams-api@latest teams-api list-conversations --login --limit 20
```

If you use the CLI often, a global install is optional:

```bash
npm install -g teams-api
teams-api auth --login
```

### Advanced Topics

Manual token usage, debug-session auth, and programmatic Node.js usage are covered later in this README.

## Platform support

| Feature                | macOS          | Windows / Linux                   |
| ---------------------- | -------------- | --------------------------------- |
| **Interactive login**  | Full support   | Full support                      |
| **Auto-login (FIDO2)** | Full support   | Not supported                     |
| **Debug session**      | Full support   | Full support                      |
| **Direct token**       | Full support   | Full support                      |
| **Token caching**      | macOS Keychain | Windows DPAPI / Linux secret-tool |
| **CLI & MCP server**   | Full support   | Full support                      |
| **Programmatic API**   | Full support   | Full support                      |

> [!NOTE]
> **Windows Defender false positive:** Older versions of this package used inline PowerShell to call the Windows DPAPI — a pattern that Windows Defender flags as ransomware-like behavior. This has been replaced with native Windows Credential Manager storage via [keytar](https://github.com/atom/node-keytar). If you hit issues on an older version, upgrade and re-run `teams-api auth --login`. See [SECURITY.md](./SECURITY.md) for details.

## Authentication

Most users do not need to manage tokens manually.

If you use interactive login, auto-login, or a Chrome debug session, `teams-api` captures the full token bundle automatically from Teams web traffic. That includes the base `skypeToken` plus the extra bearer tokens used for profile resolution and reliable people/chat/channel search.

Those flows also detect the Teams chat region automatically from the intercepted request URLs, so most users do not need to set `--region` or `TEAMS_REGION`.

On macOS, prefer auto-login when you have a platform authenticator / FIDO2 passkey set up. On other platforms, use interactive login.

Direct token usage is the advanced/manual path.

| Method                | Description                                                                  | Automation       | Platform |
| --------------------- | ---------------------------------------------------------------------------- | ---------------- | -------- |
| **Auto-login**        | Playwright launches system Chrome and captures the full token bundle         | Fully unattended | macOS    |
| **Interactive login** | Opens a browser window and captures skype, middle-tier, and Substrate tokens | One-time manual  | All      |
| **Debug session**     | Connects to a running Chrome instance and captures the full token bundle     | Semi-manual      | All      |
| **Direct token**      | Provide a previously captured token or token bundle explicitly               | Manual           | All      |

### Auto-login (macOS only)

Requires macOS with a platform authenticator (e.g. Intune Company Portal) and a FIDO2 passkey enrolled. Fully unattended — no browser window appears.

### Interactive login (recommended for Windows / Linux)

The easiest cross-platform option. A browser window opens, you log in with any method your organization supports (password, MFA, passkey, etc.), and the token is captured automatically:

```bash
teams-api auth --login
```

Optionally pre-fill your email:

```bash
teams-api auth --login --email you@example.com
```

> [!NOTE]
> Interactive login prefers an installed browser (Edge or Chrome) when available, and falls back to Playwright's bundled Chromium.

### Advanced / manual methods

**Debug session** — start Chrome with `--remote-debugging-port=9222`, navigate to Teams and log in, then run:

```bash
teams-api auth --debug-port 9222
```

**Direct token** — advanced/manual only. Extract `x-skypetoken` from browser DevTools (Network tab) and pass it directly:

```bash
teams-api list-conversations --token "<paste-token-here>" --region emea
```

If you want reliable people/chat/channel lookup and profile resolution on the direct-token path, also pass the extra bearer tokens captured from Teams requests:

```bash
teams-api find-people \
  --token "<paste-skype-token-here>" \
  --bearer-token "<paste-api-spaces-skype-bearer-token-here>" \
  --substrate-token "<paste-substrate-bearer-token-here>" \
  --region emea \
  --query "Jane Doe"
```

> [!TIP]
> Skip this section if you are using `--login`, `--auto`, `TEAMS_LOGIN`, or `TEAMS_AUTO`. Those modes capture the full token bundle automatically.

> [!TIP]
> Direct-token mode still needs an explicit region. See [API regions](#api-regions) below.

## CLI

Preferred without install:

```bash
npx -y -p teams-api@latest teams-api <command> [options]
```

Optional global install for frequent use:

```bash
npm install -g teams-api
teams-api <command> [options]
```

The examples below use `teams-api` for readability. If you are not installing globally, replace it with `npx -y -p teams-api@latest teams-api`.

### Auth flags (available on all commands)

| Flag                        | Description                                                                      |
| --------------------------- | -------------------------------------------------------------------------------- |
| `--login`                   | Interactive browser login (all platforms)                                        |
| `--auto`                    | Auto-acquire token via FIDO2 passkey (macOS)                                     |
| `--email <email>`           | Corporate email (required with `--auto`, optional otherwise)                     |
| `--token <token>`           | Use an existing skype token (advanced/manual)                                    |
| `--bearer-token <token>`    | Optional middle-tier bearer token (advanced/manual)                              |
| `--substrate-token <token>` | Optional Substrate bearer token (advanced/manual)                                |
| `--debug-port <port>`       | Chrome debug port (default: 9222)                                                |
| `--region <region>`         | API region override. Auto-detected for login/debug auth; required with `--token` |
| `--format <format>`         | Output format: concise, detailed                                                 |
| `--output <file>`           | Export output to file (default format: concise)                                  |

### Examples

```bash
# Acquire a token (interactive — all platforms)
teams-api auth --login

# Acquire a token (auto — macOS with FIDO2)
teams-api auth --auto --email you@example.com

# List conversations
teams-api list-conversations --login --limit 20 --format detailed

# Find a conversation by topic
teams-api find-conversation --auto --email you@example.com --query "Design Review"

# Find a 1:1 chat by person name
teams-api find-one-on-one --auto --email you@example.com --person-name "Jane Doe"

# Read messages (by topic name, person name, or direct ID)
teams-api get-messages --auto --email you@example.com --chat "Design Review"
teams-api get-messages --auto --email you@example.com --to "Jane Doe" --max-pages 5
teams-api get-messages --auto --email you@example.com --conversation-id "19:abc@thread.v2" --format detailed

# Newest-first order (API returns newest-first; default is oldest-first/chronological)
teams-api get-messages --auto --email you@example.com --chat "General" --order newest-first

# Send a message
teams-api send-message --auto --email you@example.com --to "Jane Doe" --content "Hello!"
teams-api send-message --auto --email you@example.com --chat "Design Review" --content "Status update"

# List members
teams-api get-members --auto --email you@example.com --chat "Design Review"

# Get current user info
teams-api whoami --auto --email you@example.com

# Export messages to a file (default format: concise)
teams-api get-messages --auto --email you@example.com --chat "General" --output exports/general.md

# Export as JSON to a file
teams-api get-messages --auto --email you@example.com --chat "General" --format detailed --output exports/general.json
```

## MCP server

The MCP server exposes Teams operations as tools for AI agents via stdio transport. See [Getting Started](#install-in-your-editor) for editor-specific setup.

### Advanced: direct token configuration

Use this only if you already have tokens from another flow or need to avoid browser-based auth entirely:

```json
{
  "mcpServers": {
    "teams": {
      "command": "npx",
      "args": ["-y", "-p", "teams-api@latest", "teams-api-mcp"],
      "env": {
        "TEAMS_TOKEN": "<paste-skype-token-here>",
        "TEAMS_BEARER_TOKEN": "<optional-api-spaces-skype-bearer-token>",
        "TEAMS_SUBSTRATE_TOKEN": "<optional-substrate-bearer-token>",
        "TEAMS_REGION": "emea"
      }
    }
  }
}
```

> [!TIP]
> If you do use direct tokens, `teams-api auth --login` prints the full token object as JSON. For basic chat operations, `skypeToken` is enough. For reliable people/chat/channel search and profile resolution, also pass `bearerToken` and `substrateToken`.

### Environment variables

| Variable                        | Description                                                                            |
| ------------------------------- | -------------------------------------------------------------------------------------- |
| `TEAMS_TOKEN`                   | Pre-existing skype token                                                               |
| `TEAMS_BEARER_TOKEN`            | Optional middle-tier bearer token                                                      |
| `TEAMS_SUBSTRATE_TOKEN`         | Optional Substrate bearer token                                                        |
| `TEAMS_REGION`                  | API region override. Required with `TEAMS_TOKEN`; optional otherwise                   |
| `TEAMS_EMAIL`                   | Corporate email. Optional — the server prompts the AI agent if needed                  |
| `TEAMS_AUTO`                    | Set to `true` to enable auto-login (macOS + FIDO2)                                     |
| `TEAMS_LOGIN`                   | Set to `true` to enable interactive browser login                                      |
| `TEAMS_DEBUG_PORT`              | Chrome debug port (default: 9222)                                                      |
| `TEAMS_EDIT_REPLY_GUARD`        | Edit reply guard: `allow` (default), `warn`, or `block`. See below                     |
| `TEAMS_AGENT_MARKER`            | Agent marker prefix for sent/edited messages (e.g. `Ⓜ`). See below                    |
| `TEAMS_DELETE_MODE`             | Delete mode: `hard` (default), `soft`, or `block`. See below                           |
| `TEAMS_DELETE_TOMBSTONE`        | Custom tombstone text for soft-delete mode. See below                                  |
| `TEAMS_AUDIT_LOG`               | Audit logging: `off` (default), `stderr`, or `file:<path>`. See below                  |
| `TEAMS_PROTECTED_CONVERSATIONS` | Comma-separated glob patterns of conversations where edit/delete is blocked. See below |

#### Agent marker

When an AI agent sends or edits messages on behalf of a user, it can be hard to tell which messages were composed by the agent and which by the human. The `TEAMS_AGENT_MARKER` environment variable (or `--agent-marker` CLI flag / `agentMarker` MCP parameter) automatically prepends a configurable string to message content:

```jsonc
{
  "env": {
    "TEAMS_AGENT_MARKER": "Ⓜ", // or "🤖", "[Bot]", etc.
  },
}
```

When set, every `send-message` and `edit-message` call prepends the marker followed by a space to the content. For example, with `TEAMS_AGENT_MARKER=Ⓜ`, sending "Hello world" produces "Ⓜ Hello world".

The per-call parameter takes precedence over the environment variable. Pass an empty string to disable the marker for a specific call.

#### Edit reply guard

When editing a message that already has replies, the original context can be lost — replies may no longer make sense. The `TEAMS_EDIT_REPLY_GUARD` environment variable (or `--reply-guard` CLI flag / `replyGuard` MCP parameter) controls this:

| Value   | Behavior                                                                           |
| ------- | ---------------------------------------------------------------------------------- |
| `allow` | Edit proceeds normally (default, backward-compatible)                              |
| `warn`  | Edit proceeds but an annotation is appended: _"⚠️ This message was edited after…"_ |
| `block` | Edit is refused with an error listing the reply count                              |

The per-call parameter takes precedence over the environment variable.

#### Delete mode (soft-delete)

Hard-deleting messages removes content permanently, which can be problematic for auditability and conversation flow in group chats. The `TEAMS_DELETE_MODE` environment variable (or `--delete-mode` CLI flag / `deleteMode` MCP parameter) controls how message deletion is handled:

| Value   | Behavior                                                            |
| ------- | ------------------------------------------------------------------- |
| `hard`  | Permanently delete the message (default, current behavior)          |
| `soft`  | Replace message content with a tombstone marker instead of deleting |
| `block` | Refuse deletion entirely with an error                              |

When using `soft` mode, the message content is replaced with `~~This message was removed by an agent~~` by default. Customize the tombstone text with `TEAMS_DELETE_TOMBSTONE` (or `--delete-tombstone` / `deleteTombstone`):

```jsonc
{
  "env": {
    "TEAMS_DELETE_MODE": "soft",
    "TEAMS_DELETE_TOMBSTONE": "🗑️ [removed by automation]",
  },
}
```

The per-call parameters take precedence over environment variables.

#### Audit logging

State-modifying actions (edit and delete) can emit structured audit events for compliance and traceability. The `TEAMS_AUDIT_LOG` environment variable controls where events are written:

| Value         | Behavior                                                    |
| ------------- | ----------------------------------------------------------- |
| `off`         | No audit logging (default)                                  |
| `stderr`      | Write JSON Lines to stderr                                  |
| `file:<path>` | Append JSON Lines to the specified file (created on demand) |

```jsonc
{
  "env": {
    "TEAMS_AUDIT_LOG": "file:/var/log/teams-audit.jsonl",
  },
}
```

Each event is a single JSON line with the following fields:

| Field               | Description                                                                   |
| ------------------- | ----------------------------------------------------------------------------- |
| `timestamp`         | ISO 8601 timestamp                                                            |
| `action`            | `"edit"`, `"delete"`, or `"soft-delete"`                                      |
| `conversationId`    | Conversation thread ID                                                        |
| `conversationLabel` | Human-readable conversation label (topic or 1:1 partner name)                 |
| `messageId`         | Target message ID                                                             |
| `content`           | New content for edits, tombstone text for soft-delete, `null` for hard delete |

Audit logging is designed to be silent — errors in the audit pipeline never affect tool execution.

#### Protected conversations

Some conversations contain sensitive or compliance-relevant information where accidental edits or deletions could be harmful. The `TEAMS_PROTECTED_CONVERSATIONS` environment variable (or `--protected-conversations` CLI flag / `protectedConversations` MCP parameter) blocks edit and delete actions in matching conversations:

```jsonc
{
  "env": {
    "TEAMS_PROTECTED_CONVERSATIONS": "Incident *,*compliance*,Architecture Decisions",
  },
}
```

Patterns are comma-separated and support `*` as a wildcard (matches any characters). Matching is case-insensitive. When a conversation's name matches any pattern, both `edit-message` and `delete-message` throw an error before making any changes — the message is left untouched.

The per-call parameter takes precedence over the environment variable, so individual tool invocations can override the configured patterns when needed.

### Available tools

All MCP tools accept an optional `format` parameter (`concise` or `detailed`). Default format is `concise`.

| Tool                       | Description                                           |
| -------------------------- | ----------------------------------------------------- |
| `teams_list_conversations` | List available conversations                          |
| `teams_find_conversation`  | Find a conversation by topic or member name           |
| `teams_find_one_on_one`    | Find a 1:1 chat with a person                         |
| `teams_find_people`        | Search the organization directory                     |
| `teams_find_chats`         | Search chats by name or member                        |
| `teams_get_messages`       | Get messages from a conversation                      |
| `teams_send_message`       | Send a message to a conversation                      |
| `teams_get_members`        | List members of a conversation                        |
| `teams_get_transcript`     | Get a meeting transcript from a recorded conversation |
| `teams_download_file`      | Download message files and inline images              |
| `teams_describe_image`     | Describe an inline Teams image with a vision model    |
| `teams_whoami`             | Get the authenticated user's display name             |

Workflow guidance, tips, and important notes are served automatically via the MCP server's `instructions` field — no separate skill file needed. For the same content on the CLI, run `teams-api guide`.

### Image descriptions

`teams_describe_image` reuses the existing Teams AMS image download support and sends the image bytes to an OpenAI-compatible vision endpoint. Configure it with `TEAMS_IMAGE_DESCRIPTION_API_KEY` or `OPENAI_API_KEY`. Optional overrides: `TEAMS_IMAGE_DESCRIPTION_MODEL` and `TEAMS_IMAGE_DESCRIPTION_BASE_URL`.

Examples:

```bash
teams-api describe-image --chat "Project Chat" --message-id 1773736076914 --image-index 0
teams-api describe-image --ams-object-id 0-eaua-d2-877b82634f4e978692f2243d445a6650
```

## API regions

The Teams Chat Service URL varies by region. Login-based and debug-session auth detect it automatically. You only need to set `--region` or `TEAMS_REGION` when you are supplying tokens directly or want to force an override:

| Region | Base URL                                     |
| ------ | -------------------------------------------- |
| `apac` | `https://apac.ng.msg.teams.microsoft.com/v1` |
| `emea` | `https://emea.ng.msg.teams.microsoft.com/v1` |
| `amer` | `https://amer.ng.msg.teams.microsoft.com/v1` |

## Known limitations

- **File attachments are not supported from remote AI hosts** (e.g. Claude.ai). The MCP server runs locally on your machine, so `--file` / `--image` paths must exist on your local filesystem. Cloud-hosted AI clients run in isolated containers and cannot access local paths. Use a local MCP client (Claude Desktop, Cursor, VS Code) or the CLI for file attachments.
- Token lifetime is ~24 hours. After expiry, you must re-acquire.
- The Teams Chat Service REST API is undocumented and may change without notice.
- Auto-login requires macOS, system Chrome, a platform authenticator, and a FIDO2 passkey. On other platforms, use interactive login (`--login`) instead.
- The members API returns empty display names for 1:1 chat participants. Use `findOneOnOneConversation()` to resolve names from message history.
- Reaction actor identities come from the `emotions` field in message payloads. Parsing handles both JSON-string and array formats.

## Programmatic API

This is the advanced integration path. Most users should start with MCP or CLI instead.

Install the package in your project:

```bash
npm install teams-api
```

Example:

```typescript
import { TeamsClient } from "teams-api";

// Interactive login — opens a browser, you log in manually (all platforms)
const client = await TeamsClient.fromInteractiveLogin();

// Or auto-login via platform authenticator (macOS + FIDO2 passkey)
const autoClient = await TeamsClient.fromAutoLogin({
  email: "you@example.com",
});

// Advanced/manual: create a client from previously captured tokens
const manualClient = TeamsClient.fromToken("skype-token-here", "emea");

const conversations = await client.listConversations();
const messages = await client.getMessages(conversations[0].id, {
  maxPages: 5,
  onProgress: (count) => console.log(`Fetched ${count} messages`),
});

await client.sendMessage(conversations[0].id, "Hello from the API!");

const oneOnOne = await client.findOneOnOneConversation("Jane Doe");
const members = await client.getMembers(conversations[0].id);
```

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, architecture, and implementation notes.

## License

MIT

