Claude Media
Claude CodeでTeams Botを作る — Teams SDKの雛形とローカル検証

Claude CodeでTeams Botを作る — Teams SDKの雛形とローカル検証

Claude CodeでMicrosoft Teams Botを作る手順。Teams SDKの雛形生成、CLAUDE.mdへの構成規約、Agents Playgroundでの認証なしローカル検証、Teams実機で試す前の確認点までを扱う。

Claude CodeでTeams Botを作るときの分担

Teams Botは、雛形の生成、メッセージハンドラーの実装、ローカルでの疎通確認までをClaude Codeに任せやすい題材です。一方でMicrosoft 365側の登録や実機のTeamsでの動作確認は、人の手が要ります。

この記事では、MicrosoftのTeams SDKクイックスタートに沿って、echoテンプレートから始めてローカルで応答を確認するまでを扱います。あわせて、Teams Botの構成ルールをClaude CodeのCLAUDE.mdに書いておき、Claude Codeが毎回同じ前提で実装する形にします。

Teams Botの構成要素と作る前の選択

Teams Botは、ユーザーのメッセージを受けて、ルールまたはAIで判断し、応答や処理を返すアプリです。Microsoft Learnの概要ページは、Botの要素として次の5つを挙げています。

  • アクティビティハンドラー: ユーザー操作から生じるイベントを処理する部品
  • イベント: メッセージ送信やボタン操作などで発火するもの
  • 会話: ユーザーとBotのやり取り。履歴や状態を含む
  • Botロジック: どう応答するかを決める判断部分
  • Botのスコープ: 個人チャット、グループチャット、チャネルの3つ

Botの種類は、AIを使うカスタムエンジンエージェント、会話型Bot、通知Bot、ワークフローBot、コマンドBotに分かれます。作りたいものがどれかを先に決めると、Claude Codeへの指示が具体的になります。

開発の道具立ては、同じ概要ページによるとBot Framework SDKまたはTeams SDKに、Microsoft 365 Agents Toolkit(旧Teams Toolkit)を組み合わせる形です。Teams SDKはJavaScriptとC#で一般提供され、Pythonは開発者プレビューとされています。旧称のTeams AIライブラリv1は非推奨です。

手順1: CLAUDE.mdにTeams Botの構成規約を書く

コードを書かせる前に、プロジェクトの前提をCLAUDE.mdに置きます。CLAUDE.mdは毎回のセッション開始時にコンテキストへ読み込まれる指示ファイルです。Claude Codeのドキュメントは、1ファイル200行未満を目安に、確認できる具体的な書き方を勧めています。

Teams Bot向けの断片は、たとえば次のような形です(構成規約の一例で、Microsoftの雛形そのものではありません)。

# Teams Bot 規約
 
- SDK: Teams SDK(TypeScript)。TeamsFxとBot Frameworkの旧式ボイラープレートは新規に使わない
- 受信エンドポイントは `/api/messages`、ポートは 3978
- Botの応答ロジックは `src/handlers/` に置き、`src/index.ts` は起動と登録だけにする
- 認証: `skipAuth` はローカル検証専用。`src/index.ts` の本番用ビルドで有効にしない
- 資格情報(Bot ID・シークレット)は `.env` のみ。コミットしない
- 変更後は `npm run dev` で起動し、Agents Playgroundで応答を確認してから完了とする

数字や設定値は、公式のクイックスタートに出てくる値(ポート3978、/api/messages、npm run dev)に合わせています。曖昧な指示より、検証できる指示のほうが従われやすいとClaude Codeのドキュメントにあります。「ハンドラーは src/handlers/ に置く」のような具体的な指示が、その例です。

規約が増えたら、ファイル種別ごとに .claude/rules/ へ分けます。paths フロントマターで対象を絞ると、該当ファイルを触るときだけ読み込まれます。

---
paths:
  - "appPackage/**"
  - "manifest*.json"
---
 
# Teamsアプリマニフェストの規約
 
- マニフェストはJSON。アイコンと一緒にzipのアプリパッケージにまとめる
- `bots` のスコープは、対象に合わせて personal / team / groupChat のうち必要なものだけを指定する
- マニフェストを変えたら、変更内容と再アップロードが必要な点をコミットメッセージに書く

Teamsのマニフェストは、アプリの機能と設定を記述するJSONで、アイコンなどとともにzip形式のアプリパッケージになります。bots.scopes の値の追加履歴はマニフェストのスキーマ参照にあるので、値を書かせる前に最新のスキーマを確認するよう、規約に一行足しておくと安全です。

手順2: Teams Developer CLIで雛形を作る

クイックスタートの前提は、Node.js v20以上(C#はv10以上の.NET、Pythonはv3.12以上)です。まずTeams Developer CLIを入れます。クイックスタートは、このCLIをプレビュー段階と説明しています。

npm install -g @microsoft/teams.cli
teams --version
teams project new typescript quote-agent --template echo

echoテンプレートは、受け取ったメッセージをそのまま返すだけの基本的なエージェントです。仕組みの学習にちょうどよい最小構成で、ここからClaude Codeに拡張させます。

cd quote-agent
npm install
claude

claude を起動したら、手順1のCLAUDE.mdを置いた状態で、たとえば「echoの応答を、/quote というコマンドにだけ反応するハンドラーに分けて。ハンドラーは src/handlers/ に置く」と頼みます。既存のメッセージ処理は、公式のコード例では次のように登録されています。

app.on('message', async ({ send, activity }) => {
  await send(`You said: ${activity.text}`);
});

この登録の形を保ったまま、ハンドラー関数だけを別ファイルに切り出す指示にすると、差分が小さく、レビューしやすくなります。

手順3: 起動してローカルで応答を確認する

雛形を起動します。

npm run dev

公式のTypeScript例では、HTTPサーバーがポート3978で待ち受けます。ここで注意したいのが認証です。資格情報を設定していない状態だと、受信リクエストがすべて拒否される旨の警告が出ます。

ローカルで試すには、Microsoft 365 Agents Playgroundを使います。Teamsにサイドロードせずにエージェントを試せるツールです。Playgroundは認証なしでリクエストを送るため、ローカル専用で skipAuth を有効にします。

// src/index.ts(ローカル検証のみ)
const app = new App({ skipAuth: true });

クイックスタートは、skipAuth は受信リクエストの認証を無効にするので、本番では絶対に使わないよう警告しています。手順1の規約に「本番ビルドで有効にしない」と書いたのは、このためです。環境変数で切り替える形にしておけば、Claude Codeが本番設定を書き換える事故も防ぎやすくなります。

別のターミナルでPlaygroundを起動します。

npm install -g @microsoft/m365agentsplayground
agentsplayground -e http://localhost:3978/api/messages -c emulator

Playgroundは http://localhost:56150 で開き、送ったメッセージへの応答が画面に表示されます。この確認まではClaude Codeにサーバー起動とログの読み取りをさせられます。Playgroundの操作は自分で行い、結果をClaude Codeへ伝えて次の修正に進めるのが現実的な分担です。

手順4: Teams実機で試す前に確認すること

Playgroundで応答を確認できたら、実際のTeamsで試す段階です。ここからは環境側の設定が絡むので、Claude Codeに任せる範囲を絞ります。

Agents Toolkitのローカルデバッグ手順は、dev tunnelでローカルのポートを公開する流れです。

devtunnel user login
devtunnel host -p 3978 --protocol http --allow-anonymous

別のターミナルで、env/.env.local の BOT_DOMAIN と BOT_ENDPOINT をトンネルのURLに更新し、次を実行します。

atk provision --env local
atk deploy --env local
atk preview --env local

BOT_ENDPOINT に入るのはトンネルのURLです(例: https://sample-id-3978.devtunnels.ms/。ドキュメント中の例示値です)。この手順でAgents Toolkitが、アプリの登録とTeamsへのアップロードを自動で行います。

実機で確認する前のチェックリストは次のとおりです。

確認項目内容Claude Codeに任せられるか
skipAuth の残存内容本番設定に入っていないかClaude Codeに任せられるか◎ grepで検索できる
.env のコミット内容資格情報が追跡対象になっていないかClaude Codeに任せられるか◎ git status で確認できる
メッセージサイズ内容1メッセージは約100KB上限、80KB以内が目安Claude Codeに任せられるか○ 長文応答の分割を実装できる
@メンション内容チャネル・グループではメンションされたときだけ受ける処理が必要Claude Codeに任せられるか○ フィルターを実装できる
M365アカウント・テナント内容サインインとテスト用テナントの準備Claude Codeに任せられるか✕ 自分の手で行う

メッセージサイズとメンションの扱いは、Teamsの会話の基本を扱うページに記載があります。チャネルやグループでは、メンションされたメッセージだけを処理する条件分岐を入れるのが基本です。RSC(リソース固有の同意)を使うと、メンションなしでもメッセージを受けられます。

Claude Codeへの指示と検証のサイクル

雛形以降の実装は、次の順で回すと手戻りが減ります。

  1. 追加したい応答を1つ決め、ハンドラーの追加を頼む
  2. npm run dev で起動し、エラーが出ていないかClaude Codeにログを読ませる
  3. Playgroundで応答を確認し、結果(表示された文言や、出ていない場合はその旨)を伝える
  4. 期待と違う場合は、その差分をそのまま貼って修正を頼む

「このルールだけは必ず守らせたい」ものは、CLAUDE.mdではなくhookに置きます。Claude Codeのドキュメントも、CLAUDE.mdはコンテキストであって強制設定ではなく、特定の操作を確実に止めたいならPreToolUseフックを使うよう案内しています。skipAuth を本番ファイルに書かせない、といった禁止事項はこちらが向いています。

よくあるつまずき

起動しても応答が返ってこない

資格情報がなく skipAuth も有効でないときは、すべてのリクエストが拒否されます。起動時のログに「No credentials configured」の警告が出ていないかを確認します。

Playgroundは動くのにTeamsでは反応しない

Playgroundは認証なしのテスト用です。実機のTeamsでは、アプリの登録・マニフェスト・公開エンドポイントが揃っている必要があります。dev tunnelを起動し忘れたり、BOT_ENDPOINT を古いURLのままにしたりするのが原因になりがちです。

Claude Codeが旧式の手順で実装する

TeamsFxやTeams AIライブラリv1を前提にした古い手順が出てきたら、CLAUDE.mdの規約(手順1)を見直します。新規にTeamsFxを使わない旨と、使うSDKを明記しておきます。

CLAUDE.mdが長くなりすぎた

200行を超えると、コンテキストを圧迫し、従われにくくなります。マニフェストやテストなど、ファイル種別が限られる規約は .claude/rules/ に分けます。

まとめ

Teams Botの開発は、雛形の生成と応答ロジックの実装をClaude Codeに任せ、登録とテナント設定は自分で行う分担が扱いやすい構成です。CLAUDE.mdにSDK・エンドポイント・認証の規約を書き、Playgroundで応答を確認してからdev tunnelでTeams実機に進めれば、手戻りが減ります。

同じ「Claude Codeでチャット系Botを作る」型の記事として、HTTPのInteractionsを受けるDiscord Bot、Webhook受信からSDK応答まで進めるLINE Botがあります。拡張機能の雛形から公開まで進める例はVS Code拡張の自作にあります。

この記事を共有:XはてブLinkedIn