⤴️

Claude Code キャッチアップ: Slack公式MCPの導入と実践

に公開

1. はじめに

2026年2月17日、Slack公式のMCP Serverが一般提供開始になりました[1]

この記事では、Slack公式MCPの全体像・基本的な使い方・実際に使ってみた際の試行錯誤を共有します。

2. Slack MCPのこれまでとこれから

コミュニティ製Slack MCPサーバー(2024年末〜)

2024年11月にAnthropicがMCP(Model Context Protocol)を発表して以降、コミュニティ主導でSlack向けのMCPサーバーがいくつか登場しました。代表的なものはAnthropicのリファレンス実装である@modelcontextprotocol/server-slack[2]です。

このサーバーを使うには、Slack Appを自分で作成してBot User OAuth Token(xoxb-)を取得し、環境変数として手動設定する必要がありました。非エンジニアが導入するには厳しい状況です。

また、チャンネル履歴の取得やメッセージ投稿は行えるようになりましたが、メッセージの検索機能がありませんでした。特定の期間やユーザーのメッセージを横断的に探すには、チャンネルを1つずつ読み込んでいくしかなかったと思われます。

Slack公式MCP Serverの登場

Slack公式MCP Serverは、2025年10月に限定ベータとして開始[3]されたのち(全然知りませんでした)、2026年2月17日に一般提供開始となりました[4]。同時にReal-time Search(RTS)APIもリリースされています。

コミュニティ製MCPと比較した主な違いは以下の通りです。

観点 コミュニティ製 Slack公式
認証 Slack App作成 + Bot Token手動管理 OAuth連携
検索 なし(チャンネル履歴のみ) あり(RTS APIベース)
レスポンス形式 JSON(生のSlack API応答) LLM向けに最適化された自然言語形式
ツール数 8個[2:1] 12個

Slack公式の発表[3:1]によると、RTS APIは従来のData Access APIから進化したもので、外部サーバーにデータを保存せずにSlackデータを検索・取得できるセキュアな検索インターフェースだそうです。

Claude CodeでのDCR問題(2025年12月〜2026年2月)

Claude Codeでは、Slack MCPプラグインが動作しない問題が2025年12月に報告されていました[5]

原因は、SlackのOAuthがDynamic Client Registration(DCR: クライアントアプリが認証サーバーに自動で登録を行う仕組み)に対応していなかったことです。Claude Codeのプラグインシステムがこれを前提としていたため、認証時にIncompatible auth server: does not support dynamic client registrationというエラーが発生しました。

私は2月6日に/pluginでSlack MCPを発見し意気揚々とインストールしたのですが、見事にこの問題を踏みお預けを食らっていました。ベータ期間中にはどうだったのか、ベータの対象者がこれを回避できていたのかは謎です。。。

このIssueは2026年2月18日に修正済みです。

3. セットアップ

Claude CodeでSlack MCPを使う方法は主に2つあります。

pluginからの導入

Claude Code上で/pluginコマンドからSlack MCPプラグインをインストールできます。claude mcp addコマンドでの手動設定も可能ですが、プラグインならOAuth設定が事前構成されているため手軽です。

導線は/plugin -> Marketplaces -> claude-plugins-official -> Browse plugins -> slackなどです。Anthropic公式のマーケットプレイスなのでデフォルトで入っているかと思われます。念の為マーケットプレイス自体の更新もしておくとよいでしょう(Update marketplace)。

claude.ai Connectors経由

もう1つの方法として、claude.ai側で設定したMCPコネクターがClaude Codeに自動同期される仕組みがあります。GitHub Issueでの報告[6]によると、Claude Code 2.1.x系から導入された機能のようです。

筆者の環境では2026年2月17日、Claude Codeを起動したらSlack MCPが使える状態になっていました。所属組織がClaude Teamプランを導入しており、管理者がIntegrations[7]のSlackコネクターを有効化していたため、自動的に利用可能になったようです。

この方式で接続した場合、ツール名にはmcp__claude_ai_Slack__というプレフィックスが付きます(例: mcp__claude_ai_Slack__slack_search_public)。plugin版はmcp__plugin_slack_slack__プレフィックスです。確認したところ動作に差異はみられませんでした。

現在の/mcpコマンドの見え方は以下のようになっています。mcp addしたもの・コネクター・プラグインから提供されるMCP、という順番で並ぶようですね。

(基本はコネクター経由で利用しているため、プラグインの方は検証時以外disabledにしています)

4. Slack MCP Serverのツール全体像

公式Slack MCP Serverは12個のツールを提供しています[1:1]

カテゴリ ツール名 概要
検索 slack_search_public publicチャンネルのメッセージ・ファイル検索
検索 slack_search_public_and_private 全チャンネル(public, private, DM含む)の検索
検索 slack_search_channels チャンネル名・説明でチャンネルを検索
検索 slack_search_users 名前・メール等でユーザーを検索
読み取り slack_read_channel チャンネルのメッセージ履歴を取得
読み取り slack_read_thread スレッドの親メッセージ+全返信を取得
読み取り slack_read_canvas Canvasの内容をMarkdownで取得
読み取り slack_read_user_profile ユーザーの詳細プロフィールを取得
書き込み slack_send_message メッセージ送信(スレッド返信も可)
書き込み slack_send_message_draft メッセージの下書き作成
書き込み slack_schedule_message 指定時刻にメッセージを予約送信
書き込み slack_create_canvas Canvasドキュメントを新規作成

5. 検索ツールの基本的な使い方

前章で紹介した12個のツールのうち、今回は「特定ユーザーの1週間分の投稿を一括取得する」という、これまでのサードパーティMCPでは難しかったユースケースを試してみます。これができると週報作成などが自動化できますね。

主軸: slack_search_public_and_private

from:<@UID> + 日付フィルタで特定ユーザーの期間内投稿を一括取得できます。slack_search_publicではprivateチャンネルやDMが対象外になるため、網羅性の観点からslack_search_public_and_privateを選びました。

slack_read_channelで全チャンネルを1つずつ読む方式も考えましたが、対象チャンネル数だけAPIコールが必要になるため非現実的です。

補助: slack_read_thread

検索結果にはスレッドの一部しか含まれないため、重要な議論を含むスレッドはslack_read_threadで全文を取得して補完します。

検索クエリの構文

slack_search_public_and_privatequeryパラメータには、Slackの検索構文がそのまま使えます。

from:<@U084XXXXXXX> after:2026-02-09 before:2026-02-14

主なフィルタ演算子は以下の通りです。

演算子 用途
from:<@UID> 特定ユーザーの投稿 from:<@U084XXXXXXX>
after:YYYY-MM-DD 指定日以降 after:2026-02-09
before:YYYY-MM-DD 指定日より前 before:2026-02-14
in:<#channel> 特定チャンネル内 in:<#general>
on:YYYY-MM-DD 特定の日 on:2026-02-10
is:thread スレッド内のメッセージ is:thread

response_format

レスポンスの形式はdetailedconciseの2種類から選べます。
(以下全てのレスポンス内容はダミーです)

detailedの例:

Channel: #proj-support (ID: C049XXXXXXX)
From: Taro Yamada (ID: U084XXXXXXX)
Time: 2026-02-13 17:02:35 JST
Message_ts: 1770969755.762469
Permalink: [link](https://workspace.enterprise.slack.com/archives/...)
Text:
ページに追記しておきます

Context before:
- From: Hanako Sato (ID: U05GXXXXXXX)
  Message_ts: 1770961502.834039
  問題ないように思います!
- From: Taro Yamada (ID: U084XXXXXXX)
  Message_ts: 1770961581.850919
  これでこの件は解決かな?
  ...(前後10件以上のメッセージ)
Context after:
- From: Jiro Tanaka (ID: U031XXXXXXX)
  Message_ts: 1770971311.009989
  ありがとうございます!

チャンネルID・送信者・正確な日時(JST)・パーマリンク・全文に加え、前後の会話コンテキストも含まれます。

conciseの例:

1. #proj-support - Taro Yamada: ページに追記しておきます
 56121767-06-30

簡潔ですが、日時が56121767-06-30と壊れてしまっています(後述)。

ページネーション

検索結果はcursorベースのページネーションで取得します。limitパラメータで1ページあたりの件数を指定し、レスポンスに含まれるpagination_info.cursorを次回リクエストに渡すことで続きを取得します。cursorが返されなくなったら全件取得完了です。

6. つまづきポイント

6.1 conciseフォーマットについて

現在conciseフォーマットを利用すると、深刻な問題がいくつかあります。

日時が壊れる

先に述べたように、conciseで返される日時は56121767-06-30のような不正な値になることがあります。日別グルーピングなどの処理に使えません。

1. #proj-support - Taro Yamada: ページに追記しておきます
 56121767-06-30

この謎の値についてClaudeくんに聞いたところ、以下のような回答が返ってきました。すごい。。。

特定のメッセージでクラッシュする

特定のメッセージがconciseのレンダリング時にエラーを起こし、そのページ全体のページネーションを巻き込んで失敗します。以下のような構造化メッセージ(箇条書き・ネスト)でクラッシュが確認されました。

このメッセージはdetailedでは正常に取得できます。

Channel: #proj-dev (ID: C03BXXXXXXX)
From: Taro Yamada (ID: U084XXXXXXX)
Time: 2026-02-13 15:07:17 JST
Text:
社内LT大会の企画についてまとめました

開催形式について
以下のどちらかになります
• オフライン開催
    ◦ 会議室の予約が必要です
    ◦ 懇親会も同日開催できます
• オンライン開催
    ◦ 録画を後日共有できるのがメリットです
発表者は現在5名が候補に挙がっています

同じメッセージをconciseで取得するとクラッシュします。

MCP error -32602: Failed to run tool: execution_failed: unexpected_builtin_exception

detailedでは問題なく成功するため、これはconciseのレンダリング処理に起因する問題と思われます。

6.2 before: / after: の挙動

期間を指定するbefore:after:は対称的に見えますが、実際には非対称な挙動をします。これはSlack APIそのものの仕様と考えられます。

  • after:YYYY-MM-DD は当日を含む(その日の00:00:00以降)
  • before:YYYY-MM-DD は当日を含まない(その日の00:00:00より前)

つまり、2月9日〜2月13日のメッセージを取得したい場合、素直に書くと最終日のデータが欠落します。

# 2/13のメッセージが取れない
from:<@UID> after:2026-02-09 before:2026-02-13

# before:に翌日を指定することで2/13まで含まれる
from:<@UID> after:2026-02-09 before:2026-02-14

6.3 detailedのレスポンスサイズ

detailedフォーマットは各メッセージに前後のコンテキスト(10件以上)を付与するため、limit=20ではレスポンスが膨大になります。検証では72,356文字に達し、Claude Codeのインライン処理の上限を超えてファイルに退避されました。

ページネーションで全件取得するなら最終的な取得メッセージ数やコンテキスト消費量はほぼ同じはずですが、ファイル退避が発生するのが何となく嫌なのと、1ページあたりの件数を減らしてエラー発生時の影響範囲を最小化するためにlimit=5に下げることにしました。

6.4 スレッド内容の取得

slack_search_public_and_privateのdetailedフォーマットにはContext before/afterとして前後のメッセージが含まれますが、スレッド内の全メッセージは含まれません。重要な議論がスレッドで行われている場合、検索結果だけでは文脈が不十分になります。

これを補うために、検索結果のパーマリンクに含まれるthread_tsクエリパラメータでスレッド返信を判定し、slack_read_threadで全文を取得します。

# 通常のメッセージのパーマリンク(thread_tsなし)
https://workspace.slack.com/archives/C02XXXXXXXX/p1770861063529189

# スレッド返信のパーマリンク(thread_tsあり)
https://workspace.slack.com/archives/C02XXXXXXXX/p1770969755762469?thread_ts=1770861063.529189&cid=C02XXXXXXXX

# thread_tsの値(= 親メッセージのタイムスタンプ)をslack_read_threadに渡す

7. 安定動作する最終構成

以上の検証を踏まえて、Slack MCPを呼び出す際に採用した設定は以下の通りです。

ツール: slack_search_public_and_private
パラメータ:
  query: "from:<@UID> after:2026-02-09 before:2026-02-14"
  content_types: "messages"
  sort: "timestamp"
  sort_dir: "asc"
  response_format: "detailed"
  limit: 5
  cursor: (2ページ目以降) pagination_info.cursor
設定 理由
response_format detailed conciseの日時壊れ・クラッシュ問題を回避
limit 5 トークン超過を防ぎ、失敗時の影響範囲を最小化
before: 終了日の翌日を指定 当日を含まないSlack APIの仕様に対応
ページネーション cursor-based detailed + limit=5で安定動作
スレッド取得 slack_read_threadを併用 検索結果だけでは得られないスレッド全文を補完
実行方法 逐次実行 ページネーションはcursorの依存関係があるため逐次読み出し

実際のサブエージェントへの依頼プロンプト

最終的に、Claude Codeのスキル機能の中で、以下のプロンプトでサブエージェントにSlack収集を委譲するようにしました。週報作成スキルのうち、Slackからの収集を担当する部分です。

slack_weekly_report.md
## タスク
{START_DATE} から {END_DATE} までのSlack活動をレポートにまとめてください。

## 出力先
{OUTPUT_DIR}/report_slack.md

## 対象ユーザー
- 表示名: @Taro Yamada / 山田 太郎
- User ID: U084XXXXXXX

## 調査方法

### Step 1: メッセージの検索
slack_search_public_and_private を使用して対象期間のメッセージを取得する。

パラメータ:
- query: "from:<@U084XXXXXXX> after:{START_DATE} before:{END_DATE の翌日}"
  - ※ before: は "YYYY-MM-DD 00:00:00 以前" の意味のため、END_DATE 当日を含めるには翌日を指定する
- content_types: "messages"
- sort: "timestamp"
- sort_dir: "asc"
- response_format: "detailed"
- limit: 5

### Step 2: ページネーションで全件取得
レスポンスに pagination_info の cursor が含まれている場合、
同じパラメータに cursor を追加して次ページを取得する。
cursorが返されなくなるまで繰り返す。

### Step 3: スレッドの全文取得
Step 1-2 で取得したメッセージのうち、Permalink に `thread_ts` を含むもの(= スレッド内の返信)を特定する。
同一スレッド(同じ thread_ts)は重複除去し、スレッドごとに slack_read_thread で全文を取得する。

パラメータ:
- channel_id: メッセージの Channel ID
- message_ts: thread_ts の値(親メッセージのタイムスタンプ)
- response_format: "detailed"

これにより、searchのContext(前後数件のみ)では見えないスレッド全体の会話の流れ・結論・他参加者の発言を取得できる。

### Step 4: チャンネル別にグルーピング
取得した全メッセージをチャンネル別に分類し、各チャンネル内で時系列順に整理する。
- スレッドに属するメッセージは read_thread の結果で置き換える(searchのContext は使用しない)
- チャンネル直投稿(スレッドでないもの)はsearchの結果をそのまま使用する

## 出力形式

チャンネルごとにセクションを分けて記載:

## {CHANNEL_NAME}

### {DATE} {TIME}
{メッセージ本文の要約}

### {DATE} {TIME}(スレッド)
{スレッド全体の会話を要約。親メッセージの内容、主要な議論、結論を含める}

---

- 冒頭に対象期間と抽出条件を記載
- 挨拶のみのメッセージ(:ohayo: 等)はまとめて記載し、個別に展開しない
- スレッドは read_thread で取得した全会話を基に要約する
- 末尾に統計サマリー(投稿数、チャンネル別内訳、スレッド参加数)を記載

## 注意事項
- concise フォーマットは特定メッセージでエラーになるため使用しない
- search の limit は 5 を使用する(10以上はレスポンスサイズ超過のリスクあり)
- ページネーションのcursorが失敗した場合は1回リトライし、それでも失敗したら取得済み分で続行する
- read_thread が失敗した場合は search の Context を代替として使用する

実行結果(サンプル)

実際の出力を適当にマスクしたものを掲載しています(日付・時刻・その他の数値はダミーです)。もう少し細かく記載させても良いかもしれませんが、今のところこれで十分だと感じています。

{OUTPUT_DIR}/report_slack.md
# Slack活動レポート

- 対象期間: 2026-02-09(月)〜 2026-02-13(金)
- 対象ユーザー: @Taro Yamada / 山田 太郎(U084XXXXXXX)
- 抽出条件: `from:<@U084XXXXXXX> after:2026-02-09 before:2026-02-14`

---

## #proj-dev

### 2/10 13:17(スレッド)
Aさんのレビューに対するフォローアップ。既知の問題について過去の経緯を共有し、確認が必要な点を指摘。

### 2/10 14:23(スレッド)
仕様確認の結果を共有。複数パターンの同時実行時にルール設定が未整備な点を指摘し、運営に確認する方針を提案。

---

## DM

### 2/9 09:45
Bさんからの問い合わせへの返信。

---

## #proj-support

### 2/12 16:27(スレッド)
Cさんからの不具合報告に対し、修正対応する旨を回答。

---

(他チャンネル省略)

---

# 統計サマリー

| 項目 | 値 |
|------|-----|
| 総投稿数 | 100件(重複除外) |
| 活動日数 | 5日 |
| チャンネル数 | 100 |
| スレッド参加数 | 100件 |

8. まとめ

Slack公式MCPの登場で、これまで手動やBot Token管理が必要だったSlack連携がOAuth認証だけで使えるようになりました。特にメッセージ検索機能の追加は大きいです。

公開されたばかりのサービスなので細かい不具合はありますが、detailedフォーマット + 小さめのlimitという構成で安定して動かせています。当面はこの構成をベースにしておけば困ることはないでしょう。一方コンテキストの消費が凄まじいので、conciseの不具合が解消されることを期待しています。

MCPツールはドキュメントだけでは掴めない挙動が多いため、実際に叩いて試すのが一番の近道です。この記事がその手間を少しでも省く助けになれば幸いです。

参考文献

脚注参照

脚注
  1. Slack MCP Server | Slack Developer Docs ↩︎ ↩︎

  2. modelcontextprotocol/servers-archived - Slack MCP Server ↩︎ ↩︎

  3. Slack Securely Powers Your Third-Party Agents With Your Business Context | Slack ↩︎ ↩︎

  4. Announcing the Slack MCP server and Real-time Search API | Slack Developer Docs ↩︎

  5. [BUG] Slack MCP plugin fails to authenticate: "Incompatible auth server: does not support dynamic client registration" ↩︎

  6. Claude.ai MCP servers auto-injected into Claude Code without opt-in ↩︎

  7. Claude can now connect to your world | Claude ↩︎

GENDA

Discussion