npm package: @piyapat/msteam-mcp-server
Description: MCP Server for sending notifications and analyzing channel messages in Microsoft Teams via Power Automate Workflow and Office365 MCP
Latest version: 1.2.0

# MS Teams MCP Server

An MCP (Model Context Protocol) server for **sending notifications** and **analyzing channel messages** in Microsoft Teams.

- **Send** → via Power Automate Workflow (Adaptive Cards)
- **Read & Analyze** → works together with **Office365 MCP** (`chat_message_search`) — no Graph API credentials required

## Installation

```bash
npm install
npm run build
```

## Configuration

Only one environment variable is required:

| Variable | Required | Description |
|----------|----------|-------------|
| `TEAMS_WORKFLOW_URL` | ✅ | Power Automate Workflow HTTP trigger URL |

> **Note:** Reading and analyzing channel messages does **not** require Graph API credentials. Messages are fetched by the Office365 MCP (`chat_message_search`) and passed to this server's tools for formatting/analysis.

## MCP Client Setup

### Claude Desktop / Cursor / VS Code

Add to your `claude_desktop_config.json` (or equivalent MCP config):

**Using npx (after publishing to npm):**
```json
{
  "mcpServers": {
    "msteam": {
      "command": "npx",
      "args": ["-y", "@piyapat/msteam-mcp-server"],
      "env": {
        "TEAMS_WORKFLOW_URL": "https://prod-xx.westus.logic.azure.com/..."
      }
    }
  }
}
```

**Using local build:**
```json
{
  "mcpServers": {
    "msteam": {
      "command": "node",
      "args": ["path/to/msteam-mcp-server/dist/index.js"],
      "env": {
        "TEAMS_WORKFLOW_URL": "https://prod-xx.westus.logic.azure.com/..."
      }
    }
  }
}
```

## Creating a Workflow URL in Microsoft Teams

> Microsoft has deprecated the Incoming Webhook Connector. Use **Power Automate Workflows** instead.

1. Open Microsoft Teams → navigate to the target Channel
2. Click **"..."** (More options) next to the channel → **Workflows**
   - Or click **"+"** in the tab bar → search for **Workflows**
3. Search for the template **"Post to a channel when a webhook request is received"** → **Add**
4. Name the flow → **Next** → select Team and Channel → **Add workflow**
5. Copy the **Workflow URL** (format: `https://prod-xx.westus.logic.azure.com/...`)

## Channel Read & Analyze Flow

This server **does not** call Graph API directly. Instead, it works together with the **Office365 MCP** already connected to Claude:

```
1. Claude calls chat_message_search (Office365 MCP)
         ↓  returns array of message objects
2. Claude calls teams_format_messages or teams_summarize_channel (this server)
         ↓  passes the messages array as input
3. Returns formatted log or structured Thai-language summary
         ↓  (optional)
4. Claude calls teams_send_card_message (this server)
         ↓  posts the summary back to Teams
```

**Example prompt:**
> "ดึงข้อความจาก Teams Channel ช่อง GPF Point Service แล้วสรุปวิเคราะห์ให้หน่อย"

Claude will:
1. Call `chat_message_search` → fetch messages from the channel
2. Call `teams_summarize_channel` with the messages → get structured summary
3. (Optionally) call `teams_send_card_message` → post summary back to Teams

## Tools

### Send Tools

#### `teams_send_simple_message`

Send a plain text message with optional title. Supports Markdown in `message`.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `message` | string | ✅ | Message text (Markdown supported) |
| `title` | string | ❌ | Optional heading |

**Example:**
```json
{
  "message": "Hello! This is a **test** notification.\n\n- Item 1\n- Item 2",
  "title": "System Notice"
}
```

---

#### `teams_send_card_message`

Send a rich Adaptive Card with title, body, color theme, facts, action buttons, and file links.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `title` | string | ✅ | Card title |
| `message` | string | ✅ | Card body (Markdown supported) |
| `color` | string | ❌ | Header theme: `default` `good` `warning` `attention` `accent` `emphasis` |
| `facts` | array | ❌ | Key-value pairs `[{ "title": "...", "value": "..." }]` |
| `actions` | array | ❌ | Buttons `[{ "title": "...", "url": "..." }]` |
| `file_links` | array | ❌ | File links `[{ "name": "...", "url": "..." }]` — shown as 📎 buttons |

**Example:**
```json
{
  "title": "Deployment Successful",
  "message": "Version **2.1.0** has been deployed to Production.",
  "color": "good",
  "facts": [
    { "title": "Environment", "value": "Production" },
    { "title": "Version", "value": "2.1.0" },
    { "title": "Deployed by", "value": "CI/CD Pipeline" }
  ],
  "actions": [
    { "title": "View Logs", "url": "https://logs.example.com" }
  ],
  "file_links": [
    { "name": "Release Notes.pdf", "url": "https://sharepoint.com/sites/..." }
  ]
}
```

---

#### `teams_send_alert`

Send a structured alert with severity level. Ideal for monitoring, CI/CD, and system events.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `severity` | string | ✅ | `info` `success` `warning` `error` |
| `title` | string | ✅ | Alert title |
| `message` | string | ✅ | Alert details (Markdown supported) |
| `source` | string | ❌ | Source system or service name |
| `timestamp` | string | ❌ | ISO 8601 timestamp (defaults to now) |
| `actions` | array | ❌ | Buttons `[{ "title": "...", "url": "..." }]` |

**Example:**
```json
{
  "severity": "error",
  "title": "Database Connection Failed",
  "message": "Unable to connect to PostgreSQL on `prod-db-01`.",
  "source": "API Server",
  "timestamp": "2026-03-17T10:30:00Z",
  "actions": [
    { "title": "View Dashboard", "url": "https://grafana.example.com" }
  ]
}
```

---

#### `teams_send_rich_message`

Send a message with precise inline formatting using **RichTextBlock/TextRun** — the most granular text control available in Teams Adaptive Cards. Supports mixed formatting within a single line.

> **Note:** HTML tags are NOT supported in Teams Adaptive Cards. Use TextRun properties instead.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `title` | string | ❌ | Optional heading (plain text) |
| `paragraphs` | array | ✅ | Array of paragraphs; each paragraph is an array of TextRun objects |
| `file_links` | array | ❌ | File links `[{ "name": "...", "url": "..." }]` — shown as 📎 buttons |
| `actions` | array | ❌ | Action buttons `[{ "title": "...", "url": "..." }]` |

**TextRun properties:**

| Property | Type | Description |
|----------|------|-------------|
| `text` | string | ✅ Text content |
| `bold` | boolean | Bold |
| `italic` | boolean | Italic |
| `strikethrough` | boolean | Strikethrough |
| `highlight` | boolean | Highlighted background |
| `monospace` | boolean | Monospace / code font |
| `color` | string | `default` `dark` `light` `accent` `good` `warning` `attention` |
| `url` | string | Turn this run into a hyperlink |

**Example:**
```json
{
  "title": "Release v3.0.0",
  "paragraphs": [
    [
      { "text": "Status: " },
      { "text": "DEPLOYED", "bold": true, "color": "good" }
    ],
    [
      { "text": "Commit: " },
      { "text": "abc1234", "monospace": true },
      { "text": "  →  " },
      { "text": "View Changelog", "url": "https://github.com/org/repo/releases" }
    ],
    [
      { "text": "Note: " },
      { "text": "Service restart required after deploy.", "italic": true, "color": "warning" }
    ]
  ],
  "file_links": [
    { "name": "Release Notes.docx", "url": "https://sharepoint.com/sites/..." }
  ],
  "actions": [
    { "title": "View Pipeline", "url": "https://ci.example.com/builds/123" }
  ]
}
```

---

### Channel Read & Analyze Tools

> These tools require messages to be fetched first by **Office365 MCP** (`chat_message_search`).
> Pass the returned message array directly as the `messages` parameter.

#### `teams_format_messages`

Format raw channel messages into a readable chronological log.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `messages` | array | ✅ | Message objects from `chat_message_search` |
| `channel_name` | string | ❌ | Channel name for display |

Returns formatted text: `[timestamp] sender: content`

---

#### `teams_summarize_channel`

Analyze channel messages and return a structured **Thai-language summary** identifying participants, action items, issues, and decisions.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `messages` | array | ✅ | Message objects from `chat_message_search` |
| `channel_name` | string | ❌ | Channel name for display |
| `focus` | string | ❌ | Guide the analysis (e.g. `"action items"`, `"unresolved issues"`, `"decisions"`) |

**Example output:**
```
## สรุปวิเคราะห์ Teams Channel: GPF Point Service

**ช่วงเวลา:** 24/3/2569 09:00 → 24/3/2569 17:30
**จำนวนข้อความ:** 15 ข้อความ
**ผู้เข้าร่วม (3 คน):** Somchai K., Niran P., Wanida T.

### ประเด็นที่พบ
- ⚠️ มีการกล่าวถึง ปัญหา/ข้อผิดพลาด ในการสนทนา
- 📋 มีการกล่าวถึง Action Items / งานที่ต้องทำ

### ข้อความล่าสุด (5 ข้อความ)
- **Somchai K.:** ปัญหาการเชื่อมต่อฐานข้อมูลได้รับการแก้ไขแล้ว…
```

## Known Limitations

| Feature | Supported | Alternative |
|---------|-----------|-------------|
| Binary file attachments | ❌ | Use `file_links` with SharePoint/OneDrive URLs |
| HTML tags in cards | ❌ | Use Markdown (TextBlock) or TextRun properties |
| Markdown in TextBlock | ✅ | `**bold**`, `_italic_`, `[link](url)`, `- list` |
| Bold / Italic / Color / Monospace inline | ✅ | Use `teams_send_rich_message` with TextRun |
| Inline hyperlinks | ✅ | TextRun `url` field |
| Channel read without Graph API credentials | ✅ | Via Office365 MCP + `teams_format_messages` / `teams_summarize_channel` |

## License

MIT