コンテンツにスキップ

Slack MCP Agent — 技術選定

v1.3 / 2026-04-20

ADR (Architecture Decision Record) 形式で、MVP の技術選定理由と棄却した代替案を記録する。
将来の選定見直し時に「なぜこの判断をしたか」を追跡可能にする。


ADR-001: Backend 言語 — Python

ステータス: 採用

コンテキスト

  • Anthropic SDK の Python 版が最も機能が充実 (Managed Agents beta 含む)
  • Slack Bolt の Python 版が安定
  • 開発者 (1 名) が Python に精通
  • プロトタイプが既に Python で実装済み

決定

Python 3.12+ を使用する。

代替案と棄却理由

代替案 棄却理由
TypeScript (Node.js) Anthropic SDK の beta 機能 (Managed Agents) が Python 版でのみ先行リリースされている。Slack Bolt も Python 版と同等だが、プロトタイプからの移行コストが発生
Go Anthropic 公式 SDK なし。Slack SDK は存在するが Bolt 相当のフレームワークがない

影響

  • Backend と MCP Server を同一言語で統一できる
  • 型安全性は dataclass + Pydantic v2 で補完

ADR-002: LLM — Anthropic Claude (Messages API + Managed Agents)

ステータス: 採用

コンテキスト

  • 先行プロジェクト caster-division-ai が Anthropic Managed Agents で実装済み
  • L1-L3 は Messages API (1-shot)、L4 は Managed Agents API (エージェントループ)
  • Custom Tool パターンで認証情報を Agent に渡さない設計が可能

決定

  • L1-L3: anthropic.AsyncAnthropic.messages.create (claude-sonnet-4-6)
  • L4: beta.sessions.create/retrieve/events (Managed Agents)

代替案と棄却理由

代替案 棄却理由
OpenAI GPT-4o + Assistants API Custom Tool の pause/resume パターンが Anthropic ほど成熟していない。caster-division-ai の知見が活かせない
LangChain / LangGraph 抽象化レイヤーが厚く、Managed Agents の beta API に追従が遅れる。直接 SDK 利用の方がデバッグ容易
自前 Agent ループ L4 のツール呼出ループ、リトライ、コンテキスト管理を自前実装するコストが大きい。Managed Agents に委譲する方が MVP 速度に寄与

影響

  • Anthropic API の beta 変更に追従が必要
  • Managed Agents の制約 (MCP Server 必須、ngrok 必要) を受け入れる

ADR-003: DB — SQLite (aiosqlite)

ステータス: 採用

コンテキスト

  • MVP はローカル実行、1 人運用
  • Backend (Python) と Web (Next.js) の両方から同一データを参照する必要がある
  • デプロイ・インフラの最小化が優先

決定

SQLite (WAL モード) + aiosqlite (Python 側) + better-sqlite3 (Node.js 側)。

代替案と棄却理由

代替案 棄却理由
PostgreSQL ローカル開発でも別プロセスの起動が必要。1 人運用 MVP にはオーバースペック。Post-MVP で検討
Firestore caster-division-ai で使用中だが、ローカル開発にエミュレータが必要。リアルタイムリスナーは本プロジェクトでは不要
DynamoDB AWS 依存。ローカル開発コスト大
Turso (libSQL) SQLite 互換で将来の分散化に有利だが、MVP では通常 SQLite で十分

トレードオフ

  • 利点: ファイル 1 つで完結、デプロイ不要、Backend/Web で共有容易
  • 欠点: 同時書込に弱い (WAL で軽減)、スケールアウト不可
  • 移行パス: Post-MVP で PostgreSQL or Turso への移行を想定。SQL は標準的な構文で書き、ORM は使わない (移行容易性)

ADR-004: Slack 連携 — Slack Bolt (Socket Mode)

ステータス: 採用

コンテキスト

  • プロトタイプが Socket Mode で実装済み
  • Socket Mode はインバウンド HTTPS 不要 (ngrok は MCP 用のみ)
  • Events API + Interactive Components + Agent Container を統合的に扱えるフレームワークが必要

決定

slack-bolt (Python) + Socket Mode。

代替案と棄却理由

代替案 棄却理由
HTTP Mode (Events API) 開発環境で ngrok が必要になる (MCP Server と合わせて 2 つ)。Socket Mode の方がローカル開発が楽
slack-sdk のみ (Bolt なし) Event ルーティング、ack タイムアウト処理、ミドルウェアを自前実装する必要がある
Slack API 直接 (requests) SDK の型安全性・retry 処理を自前で再実装する意味がない

影響

  • Socket Mode ではアプリ配信先が制限される (Slack App Directory 非公開)
  • Post-MVP で HTTP Mode への切替を検討

ADR-005: Web フレームワーク — Next.js (App Router)

ステータス: 採用

コンテキスト

  • 管理画面は MVP 4 画面(パイプライン一覧/詳細、設定、外部連携)。監査ログとログイン画面は Post-MVP
  • 主に読み取り表示 (Server Components に適合)
  • 設定変更・外部連携は Server Actions で処理

決定

Next.js 16+ (App Router, Server Components 主体)。現行は next@16.2.4

代替案と棄却理由

代替案 棄却理由
Remix Server Components のストリーミング対応が Next.js に劣る。コミュニティ・エコシステムが小さい
SvelteKit 開発者の習熟度が低い。shadcn/ui 相当のコンポーネントライブラリが少ない
Streamlit Python 完結だが、カスタム UI の自由度が低い。shadcn/ui 相当のデザインシステムが使えない
Flask/FastAPI + React SPA Backend が 2 プロセスになる (Slack Bolt + Web API)。Next.js は SSR + SQLite 直接参照でプロセス増を避けられる
Gradio ML デモ向き。管理画面の CRUD には不向き

影響

  • TypeScript でのフロントエンド実装が必要 (Backend は Python)
  • SQLite を Node.js から読むため better-sqlite3 を使用

ADR-006: UI コンポーネント — Tailwind CSS v4 + shadcn/ui

ステータス: 採用

コンテキスト

  • DESIGN.md でデザイントークン・コンポーネント規約を定義済み
  • AI による実装を前提に、コードベースに直接存在するコンポーネントが望ましい
  • ダークモード対応が必要

決定

Tailwind CSS v4 + shadcn/ui (Radix UI ベース)。

代替案と棄却理由

代替案 棄却理由
MUI (Material UI) バンドルサイズ大。テーマカスタマイズの学習コスト。Server Components との相性が悪い
Chakra UI v3 で RSC 対応が進んでいるが、shadcn/ui の方がソースコードが手元にあり AI がカスタマイズしやすい
Ant Design 企業向け UI だが日本語ロケール・ダークモード対応にカスタムが必要
CSS Modules コンポーネントライブラリなし。全て自前実装が必要

影響

  • npx shadcn@latest add でコンポーネントをプロジェクトにコピーする運用
  • コンポーネントは components/ui/ に配置され、直接編集可能

ADR-007: パッケージ管理 — uv (Python) + pnpm (Node.js)

ステータス: 採用

コンテキスト

  • Python 側: Backend + MCP Servers で依存管理が必要
  • Node.js 側: Web フロントエンドの依存管理
  • 開発速度と再現性を重視

決定

  • Python: uv (高速な pip 互換 + venv 管理 + pyproject.toml)
  • Node.js: pnpm (高速・ディスク効率の良い node_modules)

代替案と棄却理由

代替案 棄却理由
Poetry (Python) uv の方が 10-100 倍高速。lock ファイル形式は uv が標準化の方向
pip + venv (Python) lock ファイルが標準でない。依存解決が遅い
npm (Node.js) pnpm の方がディスク効率が良く、phantom dependency を防げる
yarn (Node.js) pnpm と比較して大きな優位性なし。Plug'n'Play モードはツール互換性に課題

ADR-008: ID 生成 — ULID

ステータス: 採用

コンテキスト

  • 全テーブルの PK に使用
  • 時系列ソートが可能な分散 ID が望ましい
  • SQLite は TEXT 型で PK を管理

決定

ULID (Universally Unique Lexicographically Sortable Identifier)。ulid-py ライブラリ使用。

代替案と棄却理由

代替案 棄却理由
UUID v4 ランダムのためソート不可。インデックス性能で ULID に劣る
UUID v7 時系列ソート可能だが、Python のネイティブサポートが限定的
AUTO INCREMENT 分散環境で衝突。Post-MVP のマルチテナント・マイグレーション時に問題
nanoid 時系列ソート不可

ADR-009: MCP Server フレームワーク — FastMCP

ステータス: 採用

コンテキスト

  • Managed Agents がツール実行に MCP プロトコルを使用
  • MCP Server は HTTP (streamable-http) で公開
  • プロトタイプで FastMCP を採用済み

決定

FastMCP (mcp.server.fastmcp.FastMCP) + streamable-http トランスポート。

代替案と棄却理由

代替案 棄却理由
mcp-server (低レベル SDK) FastMCP の方がデコレータベースで記述量が少ない
自前 HTTP サーバー MCP プロトコルのハンドシェイク・ストリーミングを自前実装する意味がない

ADR-010: freee API 統合 — Custom Tool Executor (Backend 内直接呼出)

ステータス: 採用

コンテキスト

  • freee OAuth トークンは HR 個人情報へのアクセス権を持つ
  • caster-division-ai の Custom Tool パターンを踏襲
  • 認証情報を Anthropic Cloud や MCP Server に渡したくない

決定

freee API の呼出は Backend プロセス内の Custom Tool Executor で行う。Managed Agent の custom_tool_use イベントを Backend がポーリングで検知し、Backend 内で freee API を呼出、結果を tool_result として返送する。

代替案と棄却理由

代替案 棄却理由
MCP Server 経由 (hr-freee) OAuth トークンが MCP Server プロセスに存在する。ngrok 経由で Anthropic Cloud からアクセスされるため、トークンが外部経路を通るリスクがある
freee SDK 直接 (Agent 内) 認証情報が Agent のコンテキストに入る。セキュリティポリシー違反

トレードオフ

  • 利点: 認証情報が Backend 内で完結。監査ログ統合。Policy Engine 対応可能
  • 欠点: L4 のポーリングループ内で custom_tool_use イベントをハンドリングするコードが必要。MCP Server パターンより実装が複雑

備考

MVP 初期は MCP Server (hr-freee) 経由で動作確認し、Custom Tool Executor への移行はセキュリティ要件確認後に実施する可能性あり。


ADR-011: テスト — pytest + Playwright

ステータス: 採用

コンテキスト

  • Backend は Python、Web は TypeScript
  • TDD ベースの開発プロセス
  • パイプライン各層の契約テストが重要

決定

  • Python (Backend / MCP): pytest + pytest-asyncio
  • Web: Vitest (ユニット) + Playwright (E2E)
  • モック: unittest.mock (Python) + MSW (Web)

代替案と棄却理由

代替案 棄却理由
unittest (Python) pytest の方がフィクスチャ・パラメタライズが強力
Jest (Web) Vitest の方が Vite/Next.js との親和性が高く、ESM 対応が良い
Cypress (E2E) Playwright の方がマルチブラウザ対応が優れ、CI での安定性が高い

ADR-012: 開発トンネル — ngrok

ステータス: 採用

コンテキスト

  • Anthropic Cloud の Managed Agent が MCP Server にアクセスするため、localhost のポートを外部公開する必要がある
  • Slack は Socket Mode のため ngrok 不要

決定

ngrok で MCP Server のポート (8001, 8002) を公開。

代替案と棄却理由

代替案 棄却理由
Cloudflare Tunnel 無料枠の制約。ngrok の方がセットアップが簡単
localtunnel 安定性に課題。商用利用での SLA なし
tailscale funnel Tailscale ネットワークのセットアップが必要

影響

  • ngrok の URL は変動するため、Agent 定義の再作成が必要 (固定ドメインは有料)
  • setup-managed-agent.py で Agent 定義時に ngrok URL を指定

ADR-013: E2E 動作確認 — アクションシミュレーション + Playwright

ステータス: 採用

コンテキスト

  • AI エージェントが自律的に動作確認を行う仕組みが必要
  • Slack の承認/却下ボタン操作を自動化する方法として、Slack Web UI の Playwright 自動化と、Backend ハンドラの直接呼出しの 2 つの選択肢がある
  • 管理画面(Next.js)のブラウザ検証には Playwright が適している

決定

  • Slack ボタン操作: scripts/simulate-action.pybackend/src/slack/actions.py の async ハンドラを直接呼出し。Slack Web UI の自動化は行わない
  • Slack メッセージ送受信: Cursor の Slack MCP ツール (slack_send_message, slack_read_thread) を使用
  • 管理画面検証: tests/e2e/ の Playwright (Chromium のみ) で事前定義スペック + 統合ユーティリティスクリプト
  • ログ監視: Cursor ターミナルファイルの直接読み取り

代替案と棄却理由

代替案 棄却理由
Playwright で Slack Web UI を自動化 DOM 構造が頻繁に変更される。Slack ログイン認証の管理が複雑。脆弱なテストになる
Backend に HTTP エンドポイントを追加 Socket Mode のアーキテクチャに HTTP サーバーを追加する必要があり、本番コードへの影響が大きい
pytest の既存 E2E テストのみ モック前提のため、実際の Slack カード更新や管理画面との整合性は検証できない

トレードオフ

  • 利点: 安定した自動化。実際の DB と Slack API を使用するため擬似 E2E として高い信頼性。管理画面は本物のブラウザで検証
  • 欠点: Slack のボタン UI 自体のレンダリングは検証しない。DB 同時アクセスのタイミング制御が必要(WAL モード前提)

決定サマリー

# 領域 決定 代替案 (主要)
001 Backend 言語 Python 3.12+ TypeScript
002 LLM Anthropic Claude (Messages + Managed Agents) OpenAI, LangChain
003 DB SQLite (aiosqlite + better-sqlite3) PostgreSQL, Firestore
004 Slack slack-bolt (Socket Mode) HTTP Mode
005 Web Next.js 16+ (App Router) Remix, Streamlit
006 UI Tailwind CSS v4 + shadcn/ui MUI, Chakra UI
007 パッケージ管理 uv + pnpm Poetry + npm
008 ID ULID UUID v4/v7
009 MCP FastMCP (streamable-http) 低レベル SDK
010 freee 統合 Custom Tool Executor MCP Server 経由
011 テスト pytest + Vitest + Playwright unittest + Jest + Cypress
012 トンネル ngrok Cloudflare Tunnel
013 E2E 動作確認 アクションシミュレーション + Playwright Slack UI Playwright, HTTP エンドポイント
014 ホスティング Railway (単一コンテナ + nginx) Cloud Run, ECS, Fly.io

ADR-014: Railway 単一コンテナデプロイ

ステータス: 採用

コンテキスト

  • チームメンバーが管理画面を触れるようにデプロイが必要
  • main マージでの自動デプロイ (CD) を確立したい
  • Backend + MCP Server + Web の 3 プロセスが SQLite ファイルを共有する

決定

Railway に単一コンテナとしてデプロイする。nginx リバースプロキシで / (Web) と /mcp/ (MCP Server) をルーティング。Backend は Socket Mode のためインバウンドポート不要。

代替案

棄却理由
Cloud Run SQLite ファイル共有が困難 (サービス分割が必要)
ECS セットアップが重い (VPC, ALB, ECR 等)
Fly.io Volume サポートはあるが Railway の方が GitHub 連携と環境変数管理が優秀
サービス分割 (Backend / Web / MCP 別コンテナ) SQLite 共有が不可能。PostgreSQL 移行が前提になりコストが増大

トレードオフ

  • 利点: GitHub 連携 CD、Volume で SQLite 永続化、環境変数 UI、Free トライアルで検証可能
  • 欠点: 単一コンテナのため個別スケール不可、プロセス管理がシェルスクリプトで簡素
  • 移行パス: PostgreSQL 移行時にサービス分割し、Cloud Run / ECS に移行

変更履歴

日付 バージョン 変更内容
2026-04-18 v1.0 初版: ADR-001 〜 ADR-012
2026-04-20 v1.1 ADR-013 追加: E2E 動作確認アプローチ
2026-04-20 v1.2 ADR-014 追加: Railway 単一コンテナデプロイ (issue #31)
2026-04-20 v1.3 実装整合: Next.js を 16+ に更新、管理画面 MVP 4 画面 + Post-MVP(監査ログ UI・ログイン画面)を明記