agent-teams について
agent-teams は、AI エージェントや人がコマンドラインから Microsoft Teams を操作するための TypeScript CLI です。チームやアカウントの切り替えに加え、デバイスコード認証とローカルでのトークン抽出に対応します。
主な機能
- 01メッセージの送信と検索
- 02チャットとチャネルの管理
- 03チームとアカウントの切り替え
- 04ファイルのアップロードとダウンロード
- 05ログインとトークン抽出
活用シーン
- 01AI エージェントからのメッセージ送信
- 02チャネルやチャット履歴の確認
- 03複数の Teams チームでの操作
- 04Teams ファイルの共有や取得
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ agent-messenger/ agent-messenger --skill agent-teamsインストール後、Claude Code で/agent-teamsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/authentication.mdcommon-patterns.mdtemplates/monitor-channel.shpost-message.shteam-summary.sh詳細
エージェントチーム
AI エージェントと人間が、シンプルなコマンドインターフェースを通じて Microsoft Teams を操作できる TypeScript CLI ツールです。Teams デスクトップアプリからのシームレスなトークン抽出(ブラウザーへのフォールバックあり)と、複数チームのサポートを備えています。
クイックスタート
# Get team snapshot (credentials are extracted automatically)
agent-teams snapshot
# Send a message
agent-teams message send <team-id> <channel-id> "Hello from AI agent!"
# List channels
agent-teams channel list <team-id>
認証
同等の方法が2つあります。用途に合う方を選んでください。
agent-teams auth login(職場/学校アカウントまたは個人の Microsoft アカウント) — デバイスコードを使ったサインインです。表示された URL を開き、コードを入力して、ブラウザーで承認します。デスクトップアプリもブラウザーからの抽出も不要です。Microsoft のメールアドレスを尋ねられます(または--email <email>を渡します)。職場用か個人用かを自動検出して、対応するフローを開始します。--account-type work|personalを渡すと、アカウントの種類を指定して検出を省略できます。message searchに必要な AAD リフレッシュトークンを保存するのはauth loginだけです。agent-teams auth extract— Teams デスクトップアプリから設定不要でトークンを抽出し、失敗した場合は Chromium ブラウザーにフォールバックします。すでにローカルで Teams にサインインしている場合に最適です。Skype トークンのみを取得します。メッセージの送信には十分ですが、message searchには使えません(詳しくは以下を参照)。
認証情報が保存されていない場合、どのコマンドでも初回使用時に自動で抽出されるため、auth extract はバックグラウンドでサイレントに実行されることがあります。
Teams のトークンは有効期間が短く(抽出の場合は60~90分、デバイスコードの場合は数時間)、デバイスコードを使うアカウント(auth login)はサイレントに更新されます。保存されたリフレッシュトークンを使って、CLI が期限切れのトークンを再発行するため、再ログインは不要です。抽出を使うアカウントは、Teams デスクトップアプリまたは対応ブラウザーにサインインしたままであれば、自動的に再抽出されます。失敗した場合は auth extract を再実行するか、auth login に切り替えてください。
非対話型の auth login(エージェント/CI)
TTY がない場合、auth login は2つの呼び出しに分かれます。
# 1. Start — returns verification_uri, user_code, and device_code as JSON.
# Pass --email to auto-detect the account type (no prompt without a TTY),
# or --account-type work|personal to force it.
agent-teams auth login --email <email>
# 2. After the user approves in a browser, finish with the device_code
agent-teams auth login --device-code <device_code>
どちらの呼び出しでも、--client-id <id> を指定すると AAD クライアント ID を上書きできます(または AGENT_TEAMS_CLIENT_ID を設定してください)。--account-type <work|personal> はアカウントを選択します(既定値は work)。この値は2回の呼び出しで維持されるため、個人アカウントで非対話型のサインインを行う場合は、両方の呼び出しに指定してください。
複数チームのサポート
# List all available teams
agent-teams team list
# Switch to a different team
agent-teams team switch <team-id>
# Show current team
agent-teams team current
# Check auth status (includes token expiry info)
agent-teams auth status
複数アカウントのサポート(職場用/個人用)
# Switch between work and personal accounts
agent-teams auth switch-account work
agent-teams auth switch-account personal
# Use a specific account for one command (without switching)
agent-teams snapshot --account work
メモリー
エージェントは、セッションをまたいで保持されるメモリーとして ~/.config/agent-messenger/MEMORY.md ファイルを管理します。これはエージェントが管理するもので、CLI がこのファイルを読み書きすることはありません。Read ツールと Write ツールを使って、メモリーファイルを管理してください。
メモリーの読み込み
すべてのタスクの開始時に、Read ツールを使って ~/.config/agent-messenger/MEMORY.md を読み込み、これまでに確認したチーム ID、チャネル ID、ユーザー ID、設定を読み込んでください。
- ファイルがまだ存在しない場合は、そのまま続行してください。保存する有用な情報が初めて見つかったときに作成します。
- ファイルを読み込めない場合(権限がない、ディレクトリがないなど)は、メモリーなしで続行してください。エラーにする必要はありません。
メモリーの書き込み
有用な情報を見つけたら、Write ツールを使って ~/.config/agent-messenger/MEMORY.md を更新してください。書き込むタイミングの例は次のとおりです。
- チーム ID と名前を確認した後(
team list、snapshotなど) - 役に立つチャネル ID と名前を確認した後(
channel list、snapshotなど) - ユーザー ID と名前を確認した後(
user list、user meなど) - ユーザーから別名や設定を伝えられた後(「これをスタンドアップ用チャネルと呼んで」「メインのチームは X」など)
- チャネルの構成(標準チャネルかプライベートチャネルか)を確認した後
書き込む際は、ファイルの全内容を含めてください。Write ツールはファイル全体を上書きします。
保存する情報
- チーム ID と名前
- チャネル ID、名前、チームの情報
- ユーザー ID と表示名
- ユーザーが付けた別名(「スタンドアップ用チャネル」、「メインチーム」など)
- アカウントの設定(職場用か個人用か)
- やり取りの中でユーザーが示した設定
保存してはいけない情報
トークン、認証情報、機密データは決して保存しないでください。メッセージの内容全体は保存せず、ID とチャネルの情報だけを保存してください。ファイルのアップロード内容も保存しないでください。
古くなったデータの扱い
記憶している ID を使用したときにエラー(チャネルが見つからない、チームが見つからないなど)が返された場合は、MEMORY.md から削除してください。記憶したデータをむやみに信用せず、何かおかしいと感じたら確認してください。古くなっている可能性のある記憶済み ID を使うより、一覧を再取得してください。
形式/例
# Agent Messenger Memory
## Teams
- `team-id-1` — Acme Corp (default, work account)
- `team-id-2` — Side Project (personal account)
## Channels (Acme Corp)
- `channel-id-1` — General
- `channel-id-2` — Engineering
- `channel-id-3` — Standups
## Users (Acme Corp)
- `user-id-1` — Alice (engineering lead)
- `user-id-2` — Bob (backend)
## Aliases
- "standup" → `channel-id-3` (Standups in Acme Corp)
- "main team" → `team-id-1` (Acme Corp)
## Notes
- User prefers work account by default
- Main team is "Acme Corp"
記憶を利用すると、
channel listとteam listの呼び出しを繰り返さずに済みます。以前のセッションで ID が分かっている場合は、そのまま使用してください。
コマンド
認証コマンド
# Sign in via device code (personal Microsoft accounts).
agent-teams auth login
agent-teams auth login --device-code <code> # finish a non-interactive login
# Extract token from Teams desktop app or browser (usually automatic)
agent-teams auth extract
agent-teams auth extract --debug
agent-teams auth extract --browser-profile ~/browser-data
agent-teams auth extract --browser-profile ~/work-profile --browser-profile ~/personal-profile
# --browser-profile accepts repeatable or comma-separated Chromium profile/user-data dirs
# Check auth status (includes token expiry info)
agent-teams auth status
# Logout from Microsoft Teams
agent-teams auth logout
# Switch between work and personal accounts
agent-teams auth switch-account <account-type>
agent-teams auth switch-account work
agent-teams auth switch-account personal
Whoami コマンド
# Show current authenticated user
agent-teams whoami
agent-teams whoami --pretty
出力には、認証済みユーザーの識別情報が含まれます。
メッセージコマンド
# Send a message
agent-teams message send <team-id> <channel-id> <content>
agent-teams message send <team-id> 19:[email protected] "Hello world"
# Send a rich-text message written in markdown
agent-teams message send <team-id> <channel-id> "## Deploy done
- service A
- service B" --format markdown
# List messages
agent-teams message list <team-id> <channel-id>
agent-teams message list <team-id> 19:[email protected] --limit 50
# Get a single message by ID
agent-teams message get <team-id> <channel-id> <message-id>
# Delete a message
agent-teams message delete <team-id> <channel-id> <message-id> --force
# Search messages across Teams (requires `auth login` — see Authentication)
agent-teams message search <query>
agent-teams message search "deploy" --limit 10 --from 0
message search を使うには、auth login アカウントが必要です。このコマンドは、auth extract(Cookie ベース)では取得できない AAD トークンを使って、Microsoft の Substrate 検索 API に問い合わせます。Cookie のみのアカウントでは、auth login を実行するよう明示するエラーが表示されます。--limit は正の整数(デフォルトは 20)です。--from はページネーションに使用する 0 以上のオフセット(デフォルトは 0)です。
チャネルコマンド
# List channels in a team
agent-teams channel list <team-id>
# Get channel info
agent-teams channel info <team-id> <channel-id>
agent-teams channel info <team-id> 19:[email protected]
# Get channel history (alias for message list)
agent-teams channel history <team-id> <channel-id> --limit 100
チャットコマンド
チームやチャネルがなく、1 対 1、グループ、自分とのチャットスレッドのみを利用できる個人用 Microsoft アカウント(@outlook.com/@live.com)向けです。職場アカウントでも、1 対 1 チャットやグループチャットにこれらのコマンドを使用できます。
# List 1:1, group, and self chats
agent-teams chat list
# Get chat message history
agent-teams chat history <chat-id> --limit 100
# Get a single chat message
agent-teams chat get <chat-id> <message-id>
# Send a message to a chat
agent-teams chat send <chat-id> "Hello"
agent-teams chat send <chat-id> "**Important**: see the [board](https://example.com)" --format markdown
# Edit one of your own chat messages
agent-teams chat edit <chat-id> <message-id> "Updated text"
agent-teams chat edit <chat-id> <message-id> "Fixed \`bug\`" --format markdown
チャット ID は、19:[email protected](1 対 1)または 19:[email protected](グループ)のような形式です。chat list で取得してください。48:notes チャット(type: self)は、個人用の「自分宛て」メモスレッドです。
chat edit は自分のメッセージにのみ使用でき、チャットに限られます。Teams のチャネルメッセージは、この API では編集できません。
メッセージの内容(テキスト、HTML、ファイル)
chat history、chat get、message list/get/replies、channel history のメッセージには、次の内容が含まれます。
content— プレーンテキスト(段落は改行、リンクはtext (url)の形式です。&、 、—などの数値文字参照と一般的な名前付き文字参照はデコードされますが、あまり使われない名前付き文字参照はそのまま表示されます)html— リッチテキストメッセージに限り、元の HTML が含まれます。画像がテキスト内のどこに配置されているかを確認する際に使用してくださいfiles— メッセージ内のダウンロード可能な URL がすべて含まれます。インライン画像が順番に並び、その後に添付ファイルが続きます
files の各エントリは、agent-teams file download <url> [output-path] でダウンロードしてください。
メッセージの書式設定
message send、chat send、chat edit では、--format <text|markdown|html> を指定できます(デフォルトは text です)。
text モードでは、コンテンツは HTML エスケープされるため、<、>、& はそのまま送信されます。
markdown モードでは、送信前にコンテンツが HTML に変換されます。次の構文がサポートされています。
| 構文 | 表示形式 |
|---|---|
# Heading から #### Heading まで | 見出し |
##### Heading、###### Heading | サポート対象外 — 本文テキストと区別できません |
**bold**、_italic_、***bold italic*** | 強調 |
`inline code` | インラインコード |
| 3 つのバッククォートによるフェンス | シンタックスハイライトなしのフェンス付きコードブロック |
- item | 箇条書き |
1. item | 番号付きリスト |
> quote | 引用 |
[label](https://example.com) | リンク |
--- | 水平線 |
見出しレベル 5 と 6 は使用できません。Teams クライアントでは <h5> と <h6> が本文と同じサイズで表示されるため、周囲のテキストと区別できません。#### までにしてください。フェンス付きコードブロックは等幅フォントのブロックとして表示されますが、シンタックスハイライトは行われません。言語タグ(```ts)は指定できますが、無視されます。どちらの動作も実際のアカウントで確認済みです。
リンクに使用できるのは、http:、https:、mailto:、ルート相対(/)、アンカー(#)の URL に限られます。それ以外はプレーンテキストとして表示されます。
html モードでは、コンテンツはそのまま送信されるのではなく、許可リストに基づいてタグがフィルタリングされます。Markdown では表現できない Teams 固有のマークアップ(主に @メンション)が必要な場合に使用します。
agent-teams message send <team-id> <channel-id> "Hey <at id=\"29:abc\">John</at>, build is ready" --format html
許可されているタグは、at、a、b、i、u、s、strong、em、code、pre、br、p、ul、ol、li、blockquote、h1~h6、hr です。<at> で保持される属性は id のみです。<a> で保持される属性は href のみで、かつ Markdown モードと同じ URL 許可リストに一致する場合に限られます。それ以外のタグでは、属性はすべて削除されます。リストにないもの(<script>、<img>、on* イベント属性、不正なタグや認識できないタグ)は、そのまま渡されず、エスケープまたは削除されます。
許可リストにより影響範囲は限定されますが、このモードが任意の入力に対して安全になるわけではありません。自分で作成したコンテンツのみを渡してください。信頼できない入力には text モードを使用してください。
チームコマンド
# List all teams
agent-teams team list
# Get team info
agent-teams team info <team-id>
# Switch active team
agent-teams team switch <team-id>
# Show current team
agent-teams team current
# Remove a team from config
agent-teams team remove <team-id>
ユーザーコマンド
# List team members
agent-teams user list <team-id>
# Get user info
agent-teams user info <user-id>
# Get current user
agent-teams user me
リアクションコマンド
# Add reaction (use emoji name)
agent-teams reaction add <team-id> <channel-id> <message-id> <emoji>
agent-teams reaction add <team-id> 19:[email protected] 1234567890 like
# Remove reaction
agent-teams reaction remove <team-id> <channel-id> <message-id> <emoji>
ファイルコマンド
# Upload file
agent-teams file upload <team-id> <channel-id> <path>
agent-teams file upload <team-id> 19:[email protected] ./report.pdf
# List files in channel
agent-teams file list <team-id> <channel-id>
# Get file info
agent-teams file info <team-id> <channel-id> <file-id>
# Download a file (to a path or directory; defaults to the current dir)
agent-teams file download <team-id> <channel-id> <file-id>
agent-teams file download <team-id> <channel-id> <file-id> ./report.pdf
agent-teams file download <team-id> <channel-id> <file-id> ./downloads/ --pretty
# Download a URL from a message's `files` (inline image or attachment)
agent-teams file download <url> ./downloads/
URL ダウンロードの出力:{ "name", "size", "content_type", "path" }。レスポンスにファイル名がない場合、インライン画像の名前には Teams オブジェクト ID(例:0-skr-d1-....jpg)が使用されます。
file download の出力:{ "id", "name", "size", "content_type", "path" }。path はファイルの書き込み先です。インライン画像の添付ファイルは抽出した Skype トークンを使ってダウンロードされ、サインイン済みのすべてのアカウントで利用できます。SharePoint/OneDrive のドキュメントは Microsoft Graph 経由でダウンロードされるため、auth login 済みのアカウントが必要です(Cookie のみを使う auth extract のアカウントでは、auth login の実行を促す明確なエラーが表示されます)。
スナップショットコマンド
AI エージェント向けにチームの概要を取得します(デフォルトは簡易表示)。
# Brief snapshot (default) — fast, minimal API calls
agent-teams snapshot
# Full snapshot — includes messages and members (slow, large output)
agent-teams snapshot --full
# Filtered full snapshots
agent-teams snapshot --full --channels-only
agent-teams snapshot --full --users-only
# Limit messages per channel (only with --full)
agent-teams snapshot --full --limit 10
デフォルトでは、次の情報を含む簡易版 JSON が返されます。
- チームのメタデータ(id、name)
- チャネル(id、name)
- 次のコマンドのヒント
--full を指定すると、次の情報を含む包括的な JSON が返されます。
- チームのメタデータ(id、name)
- チャネル(id、name、type、description)
- 最近のメッセージ(id、content、author、timestamp)
- メンバー(id、displayName、email)
出力形式
JSON(デフォルト)
すべてのコマンドは、AI での利用を想定して、デフォルトで JSON を出力します。
{
"id": "19:[email protected]",
"content": "Hello world",
"author": "John Doe",
"timestamp": "2024-01-15T10:30:00.000Z"
}
整形済み(人間が読みやすい形式)
整形して出力するには、--pretty フラグを使用します。
agent-teams channel list --pretty
Discord/Slack との主な違い
| 機能 | Teams | Discord | Slack |
|---|---|---|---|
| サーバーの用語 | Team | Guild | Workspace |
| チャネル識別子 | UUID 形式(19:[email protected]) | Snowflake ID | チャネル名または ID |
| トークンの保存場所 | Cookies SQLite | LevelDB | LevelDB |
| トークンの有効期限 | 60-90 minutes | ほとんどの場合、期限切れになりません | ほとんどの場合、期限切れになりません |
| メンション | <at id="user-id">Name</at>(--format html が必要) | <@user_id> | <@USER_ID> |
重要:Teams は UUID 形式のチャネル ID(19:[email protected] など)を使用します。チャネル名を直接使用することはできません。まず channel list を使用して ID を確認してください。
よく使われるパターン
一般的な AI エージェントのワークフローについては、references/common-patterns.md を参照してください。
テンプレート
実行可能なサンプルについては、templates/ ディレクトリを参照してください。
post-message.sh- エラー処理を含むメッセージの送信monitor-channel.sh- 新しいメッセージのチャネル監視(トークンの更新機能付き)team-summary.sh- チームの概要を生成
エラー処理
すべてのコマンドは一貫した形式のエラーを返します。
{
"error": "Not authenticated. Run \"auth extract\" first."
}
よくあるエラー:
Not authenticated:有効なトークンがありません(自動抽出に失敗しました。トラブルシューティングを参照してください)Token expired:トークンの期限が切れ、自動更新に失敗しました。トラブルシューティングを参照してくださいNo current team set:まずteam switch <id>を実行してください。個人アカウントにはチームがありません。代わりにchat list/chat history/chat sendを使用してくださいMessage not found:メッセージ ID が無効ですChannel not found:チャネル ID が無効です401 Unauthorized:トークンの期限が切れ、自動更新に失敗しました。トラブルシューティングを参照してください
設定
認証情報は ~/.config/agent-messenger/teams-credentials.json に保存されます(権限は 0600)。形式とセキュリティの詳細については、references/authentication.md を参照してください。
SDK:プログラムからの使用
TeamsClient は、スクリプトや自動化を構築するための TypeScript SDK として利用できます。
セットアップ
import { TeamsClient } from 'agent-messenger/teams'
const client = await new TeamsClient().login()
または、認証情報を手動で管理する場合:
import { TeamsClient, TeamsCredentialManager } from 'agent-messenger/teams'
const manager = new TeamsCredentialManager()
const creds = await manager.getTokenWithExpiry()
if (!creds) {
throw new Error('Teams token not found. Run auth extract first.')
}
const client = await new TeamsClient().login({ token: creds.token, tokenExpiresAt: creds.tokenExpiresAt })
使用例
// List teams
const teams = await client.listTeams()
// List channels in a team
const channels = await client.listChannels(teams[0].id)
// Send a message
const msg = await client.sendMessage(teams[0].id, channels[0].id, 'Hello from SDK!')
// React to it
await client.addReaction(teams[0].id, channels[0].id, msg.id, 'like')
// Upload a file
await client.uploadFile(teams[0].id, channels[0].id, './report.pdf')
リアルタイムイベント
内部の trouter WebSocket を介して、Teams のチャットメッセージをリアルタイムでストリーミングできます。ユーザーとして接続するため、ボットやパブリックエンドポイントは必要ありません。Teams デスクトップアプリにログインしている必要があります。
import { TeamsClient, TeamsListener } from 'agent-messenger/teams'
const client = await new TeamsClient().login()
const listener = new TeamsListener(client)
listener.on('message', async (message) => {
console.log(`New message in ${message.chatId}: ${message.content}`)
// Channel messages carry team/channel context and parsed @mentions.
if (message.conversationType === 'channel') {
for (const mention of message.mentions) {
console.log(`Mentioned: ${mention.displayName} (${mention.mri})`)
}
await client.sendMessage(message.teamId!, message.channelId!, 'On it 👍')
}
})
await listener.start()
各 message は TeamsRealtimeMessage です。
| フィールド | 型 | 備考 |
|---|---|---|
id | string | メッセージ ID |
chatId | string | 会話 ID(変更なし) |
conversationType | 'chat' | 'channel' | チームのチャネルメッセージの場合は 'channel' |
teamId | string? | チャネルメッセージの場合に設定されます(sendMessage と組み合わせて使用) |
channelId | string? | チャネルメッセージの場合に設定されます(sendMessage と組み合わせて使用) |
content | string | プレーンテキスト(段落区切りは保持され、エンティティはデコードされます) |
html | string? | 元の HTML。リッチテキストメッセージの場合のみ |
files | string[]? | ダウンロード可能な URL:インライン画像が先、次に添付ファイル |
mentions | TeamsMention[] | 常に存在します。@mentions がない場合は空です。各要素は { id, mri?, displayName } です |
author | { id, displayName } | 送信者(変更なし) |
messageType | string | 例:Text、RichText/Html |
timestamp | string | ISO タイムスタンプ |
API リファレンス全文
メソッドシグネチャ、型、スキーマ、サンプルの詳細については、Teams SDK ドキュメントを参照してください。
制限事項
- リアルタイムイベントは SDK 専用です(
TeamsListener)。CLI にはwatchコマンドがありません - 音声/動画チャンネルには対応していません
- チーム管理(チャンネルの作成/削除、ロール)には対応していません
- 個人アカウントではチャットのみ利用できます(チーム/チャンネルは利用できません)。
chatコマンドを使用してください - 会議には対応していません
- Webhook には対応していません
- プレーンテキストメッセージのみ対応しています(v1 ではアダプティブカードは利用できません)
- ユーザートークンのみ対応しています(アプリトークンは利用できません)
- トークンの有効期間は短いです。デバイスコード(
auth login)を使うアカウントでは、保存済みのリフレッシュトークンからバックグラウンドで更新されます。抽出したアカウントでは自動更新されますが、Teams デスクトップアプリまたはブラウザーでログイン状態を維持する必要があります
トラブルシューティング
agent-teams: command not found
agent-teams は npm パッケージ名ではありません。 npm パッケージ名は agent-messenger です。
パッケージがグローバルにインストールされている場合は、agent-teams を直接使用してください。
agent-teams team list
パッケージがインストールされていない場合は、既定で npx -y を使用してください。どのパッケージランナーを使うか、ユーザーに尋ねてはいけません。そのまま実行してください。
npx -y agent-messenger teams team list
bunx agent-messenger teams team list
pnpm dlx agent-messenger teams team list
ユーザーが希望するパッケージランナー(例:
bunx、pnpm dlx)をすでに把握している場合は、代わりにそれを使用してください。
npx agent-teams、bunx agent-teams、pnpm dlx agent-teams は絶対に実行しないでください。agent-teams は npm パッケージ名ではないため、失敗するか、誤ったパッケージがインストールされます。
認証情報の抽出、トークンの有効期限切れ、権限など、その他のトラブルシューティングについては、references/authentication.md を参照してください。