---
name: teams-message
description: Send Microsoft Teams messages to people, chats, or channels.
metadata:
  activation:
    keywords: [teams message, teams chat, teams channel, send message to, 发消息给, 发消息, 发teams]
    patterns:
      - "(?i)\\b(send|post|write|reply|tell|forward)\\b.{0,48}\\bteams\\b"
      - "(?i)\\bteams\\s+(message|msg|chat|channel)\\b"
      - "(?i)\\b(message|msg|chat)\\b.{0,32}\\b(on|in|to|via)\\s+teams\\b"
      - "(?i)(teams上(发|写|说|回|聊)|发到teams)"
      - "(?i)(发消息给|发.*teams.*消息|给.{0,10}发.{0,5}teams)"
      - "(?i)(给.{1,32}发(个|条)?消息|发(个|条)消息给)"
      - "(?i)\\b(send|post)\\s+(a\\s+)?(message|msg)\\s+to\\b"
  requires:
    tools: [MCP_teams]
---

# Teams Message

## Routing

| Intent | Signal | Action |
|---|---|---|
| Message someone else | Has recipient (name, team, channel, email, link) | MCP_teams (this skill) |
| Note to self | 发给我自己, save to Teams, 记一下 | `MCP_teams_PostMessage(chatId="48:notes", ...)` |
| Notify (current user) in Teams | 通知我, notify me, Teams 上提醒我 | `notify(channel='cloud')` — NOT MCP_teams |
| Scheduled reminder via Teams | Teams上N分钟后提醒我, at 4:50 remind me on Teams | `cron(message=..., notify_channels=['cloud'])` — NOT this skill |
| Ambiguous | - | Check conversation context. If unclear, investigate and ask with choices. |

## Resolve target

### Self chat

Fixed chatId: `48:notes` (Teams "Myself" chat, always valid).

### From a Teams link

Extract id directly from URL:
- Chat: `https://teams.../l/chat/19:...@.../conversations` → chatId
- Channel: `https://teams.../l/channel/19:...@.../...?groupId=...` → channelId + teamId (from `groupId`)

Verify with `MCP_teams_GetChat` or `MCP_teams_GetChannel`.

### From UPN/email (person only)

`MCP_teams_CreateChat(chatType="oneOnOne", members_upns=[myUPN, targetUPN])` → chatId. UPN must be email or guid.

### From name or topic

`MCP_teams_SearchTeamsMessages(message="my chat with <name or topic>")` → `chatIds` array. Filter by id format:

| chatId format | Type |
|---|---|
| `19:{guid}_{guid}@unq.gbl.spaces` | 1:1 chat |
| `19:{hex}@thread.v2` | Group chat |
| `19:meeting_*@thread.v2` | Meeting chat |

Verify: `MCP_teams_GetChat` (topic, chatType) + `MCP_teams_ListChatMembers` (displayName, email).

- Exact match (one result, name/topic matches): use directly.
- Multiple or ambiguous: show target + draft together for one confirmation.

### From team/channel name

1. `MCP_teams_ListTeams` → teamId.
2. `MCP_teams_ListChannels` → channelId. No channel specified: prefer `General`, then match team name, then ask.

## Send

- Chat/self/group: `MCP_teams_PostMessage(chatId=..., content=..., contentType="html")`
- Channel: `MCP_teams_PostChannelMessage(teamId=..., channelId=..., content=..., contentType="html")`

If MCP_teams tools are not visible, run `tools(name='MCP_teams')` first to connect and enable them.

## Content

Prefer `html`. Max 32KB per message. Use `text` only when explicitly requested.

HTML limitations: no `<style>`, `<script>`, `<iframe>`. Supported: `<b>`, `<i>`, `<a>`, `<ul>`, `<ol>`, `<li>`, `<table>`, `<br>`, `<p>`, `<pre>`, `<code>`. 
`markdown` contentType does NOT render — convert to HTML.

## Message prefix

Prepend `[🤖]` by default (AI-generated indicator). Skip if user has disabled or declined.

`html`: `<b>[🤖]</b> message...` | `text`: `[🤖] message...`

## Safety

- **Cross-org**: confirm before sending to external orgs.
- **Inactive**: `MCP_teams_ListChatMessages` or `MCP_teams_ListChannelMessages` (top=1), check `createdDateTime`. If older than 7 days, confirm.
- **Ambiguous target**: investigate with read-only APIs first, then confirm target + draft in one shot.
