結論: 1機能あたりの開発時間が73%短縮しました
「ドキュメントを調べて、コードを書いて、テストを通す」——この一連の流れをClaude Codeに丸ごと任せたら、1機能あたりの開発時間が半日(約4時間)から約1時間に短縮しました。
鍵は、MCPサーバーの組み合わせです。
- Context7 MCP → ライブラリの最新ドキュメントをリアルタイム取得
- Claude Code → ドキュメントに基づいた正確な実装
- Playwright MCP → E2Eテストの自動生成・実行・結果フィードバック
この3つを連携させると、Claude Codeが「調査→実装→テスト→修正」のループを自律的に回し続けるワークフローが完成します。本記事では、環境構築からNext.jsフォーム機能の実演、Before/After比較まで、すべて具体的に解説します。
課題: ドキュメント参照→実装→テストの往復で1機能に半日
従来の開発フローを振り返ると、開発者の時間は次のように分散していました。
| 作業 | 所要時間(目安) | 内容 |
|---|---|---|
| ドキュメント調査 | 60〜90分 | 公式ドキュメント・GitHub Issue・Stack Overflowを巡回 |
| 実装 | 60〜90分 | コーディング+型エラー修正 |
| E2Eテスト作成 | 40〜60分 | テストコード手書き+セレクタ調整 |
| テスト実行・修正ループ | 30〜60分 | 失敗→原因調査→修正を繰り返し |
合計: 約3.5〜5時間(≒半日)
特に辛いのが「ドキュメントのバージョン違い」による手戻りです。LLMに聞いても古いAPIを返されることがあり、結局公式ドキュメントを自分で確認する——このコンテキストスイッチが生産性を著しく落としていました。
解決策の全体アーキテクチャ
3ツールの連携は、以下のシーケンスで動作します。
ポイントは、開発者が最初に指示を出した後、Claude Codeが自律的にループを回すことです。ドキュメント参照もテスト実行もMCPサーバー経由で行うため、人間が介在する必要がありません。
環境構築ステップバイステップ
前提条件
- Node.js 18以上
- Claude Code CLI がインストール済み(
claudeコマンドが使える状態) - 対象プロジェクト(本記事ではNext.js 15を使用)
Step 1: MCPサーバーの設定(mcp.json)
プロジェクトルートに .mcp.json を作成します。
{
"mcpServers": {
"context7": {
"command": "npx",
"args": ["-y", "@upstash/context7-mcp@latest"]
},
"playwright": {
"command": "npx",
"args": ["-y", "@anthropic-ai/mcp-playwright@latest"]
}
}
}
補足:
npx -yを使うことで、グローバルインストールなしにMCPサーバーを起動できます。チーム開発でも.mcp.jsonをリポジトリにコミットすれば全員同じ環境になります。
Step 2: MCPサーバーの動作確認
Claude Codeを起動し、MCPサーバーが認識されているか確認します。
claude
起動後、/mcp コマンドで接続状態を確認できます。
> /mcp
MCP Servers:
✓ context7 (connected) - 2 tools available
✓ playwright (connected) - 12 tools available
両方 connected になっていればOKです。
Step 3: CLAUDE.mdへの連携指示
プロジェクトルートの CLAUDE.md に、3ツール連携の指示を記述します。これがワークフロー自動化の肝です。
## 開発ワークフロー
### ライブラリ利用時のルール
- 新しいライブラリのAPIを使う場合、必ずContext7 MCPで最新ドキュメントを参照してから実装すること
- `resolve_library_id` → `get_library_docs` の順で呼び出すこと
- ドキュメントに記載のないAPIは使わないこと
### 実装後のテストルール
- UIコンポーネントの実装後、Playwright MCPでブラウザを操作してE2Eテストを実行すること
- テスト手順:
1. dev serverが起動していることを確認(`http://localhost:3000`)
2. `browser_navigate` で対象ページにアクセス
3. `browser_snapshot` でページ構造を確認
4. ユーザー操作を `browser_click` / `browser_type` で再現
5. 期待する表示が出るかスナップショットで検証
- テスト失敗時は原因を分析し、コードを修正して再テストすること(最大3回まで)
### テストコードの生成
- E2Eテストが成功したら、その操作手順をPlaywrightテストコード(.spec.ts)として出力すること
実演: Next.jsのフォーム機能を題材にライブ実行
お題
「Next.js 15のServer Actionsを使って、名前・メールアドレスの入力フォームを作成してください。バリデーションエラーはフォーム内にインラインで表示し、送信成功時は完了メッセージを表示してください。」
Claude Codeの動き(実際のログを要約)
Phase 1: ドキュメント調査(Context7 MCP)
Claude: Context7でNext.jsのServer Actionsについて調べます。
→ resolve_library_id("next.js")
← ライブラリID: "/vercel/next.js"
→ get_library_docs(id: "/vercel/next.js", topic: "server actions forms useActionState")
← Server Actionsのドキュメント取得完了(useActionState, formData, revalidatePath等)
ここでuseActionState(React 19で追加)の正しいAPIシグネチャを取得。Claude Code単体だと旧APIの useFormState を使ってしまうケースがありましたが、Context7経由で最新情報を参照できます。
Phase 2: 実装(Claude Code)
取得したドキュメントに基づいて、以下のファイルを生成:
-
app/form/page.tsx— フォームUIコンポーネント -
app/form/actions.ts— Server Actionとバリデーションロジック
Phase 3: E2Eテスト(Playwright MCP)
Claude: Playwright MCPでフォームの動作確認をします。
→ browser_navigate("http://localhost:3000/form")
← ページスナップショット取得
→ browser_click(element: "送信ボタン")
← スナップショット: "名前を入力してください" エラー表示確認 ✓
→ browser_type(element: "名前フィールド", text: "テスト太郎")
→ browser_type(element: "メールフィールド", text: "invalid-email")
→ browser_click(element: "送信ボタン")
← スナップショット: "有効なメールアドレスを入力してください" エラー表示確認 ✓
→ browser_type(element: "メールフィールド", text: "test@example.com", clear: true)
→ browser_click(element: "送信ボタン")
← スナップショット: "送信完了しました" 表示確認 ✓
Phase 4: テストコード生成
E2Eテストの成功を確認後、tests/form.spec.ts を自動生成:
import { test, expect } from '@playwright/test';
test.describe('お問い合わせフォーム', () => {
test('空送信でバリデーションエラーが表示される', async ({ page }) => {
await page.goto('/form');
await page.getByRole('button', { name: '送信' }).click();
await expect(page.getByText('名前を入力してください')).toBeVisible();
});
test('不正なメールアドレスでエラーが表示される', async ({ page }) => {
await page.goto('/form');
await page.getByLabel('名前').fill('テスト太郎');
await page.getByLabel('メールアドレス').fill('invalid-email');
await page.getByRole('button', { name: '送信' }).click();
await expect(page.getByText('有効なメールアドレスを入力してください')).toBeVisible();
});
test('正常送信で完了メッセージが表示される', async ({ page }) => {
await page.goto('/form');
await page.getByLabel('名前').fill('テスト太郎');
await page.getByLabel('メールアドレス').fill('test@example.com');
await page.getByRole('button', { name: '送信' }).click();
await expect(page.getByText('送信完了しました')).toBeVisible();
});
});
指示を出してから完了まで、約12分。人間の操作は最初のプロンプト入力のみでした。
Before/After比較
作業時間
| 工程 | Before(手動) | After(3ツール連携) | 削減率 |
|---|---|---|---|
| ドキュメント調査 | 70分 | 2分(Context7) | 97% |
| 実装 | 80分 | 5分 | 94% |
| E2Eテスト作成 | 50分 | 3分 | 94% |
| テスト実行・修正 | 40分 | 2分 | 95% |
| 合計 | 240分 | 12分 | 95% |
注: 上記は「バリデーション付きフォーム」という比較的定型的な機能での計測です。複雑なビジネスロジックを含む機能では削減率は下がります。私の5機能での平均は73%の時間短縮でした。
コード品質
| 指標 | Before | After |
|---|---|---|
| APIバージョン不整合 | 3回/週 | 0回/週 |
| テストカバレッジ(E2E) | 主要パスのみ | 正常系+異常系3パターン |
| 型エラー残存 | 時々あり | ほぼなし |
ハマりポイント3選と対処法
1. Context7のドキュメント取得が空で返ってくる
症状: get_library_docs の結果が空、または期待した内容が含まれない。
原因: topic パラメータが抽象的すぎる、またはライブラリIDの解決が不正確。
対処法:
<!-- CLAUDE.md に追記 -->
### Context7の使い方
- topicは具体的なAPI名やキーワードを含めること(例: "useActionState server actions form validation")
- 取得結果が不十分な場合、topicを変えて再取得すること
- resolve_library_idで候補が複数出た場合、GitHub stars数が最も多いものを選択すること
2. Playwright MCPのスナップショットでアクセシビリティツリーが取得できない
症状: browser_snapshot の結果にフォーム要素が表示されない。
原因: ページの読み込み完了前にスナップショットを取得している、またはクライアントサイドレンダリングが完了していない。
対処法:
<!-- CLAUDE.md に追記 -->
### Playwright MCPのルール
- browser_navigate後、必ずbrowser_snapshotでページが完全に読み込まれたことを確認すること
- SPAの場合、動的コンテンツの描画を待つためbrowser_wait_for_navigationやbrowser_snapshotの再取得を行うこと
- 要素が見つからない場合は2秒待ってからスナップショットを再取得すること
3. MCPサーバー間のコンテキスト共有の罠
症状: Context7で取得したAPIの使い方と、Playwrightでのテスト結果が噛み合わない。Claude Codeが混乱して無限修正ループに入る。
原因: MCPサーバー同士は直接コンテキストを共有しません。Context7の取得結果をClaude Codeが正しく解釈・保持できていないケースがあります。
対処法:
<!-- CLAUDE.md に追記 -->
### 修正ループの制御
- テストが3回連続で失敗した場合、ループを中断して開発者に状況を報告すること
- テスト失敗時は、まずContext7で該当APIのドキュメントを再取得してから修正すること
- テストコードの修正ではなく、実装コードの修正を優先すること
まとめ
- MCPサーバーは「単体」ではなく「組み合わせ」で真価を発揮する — Context7(知識)× Playwright(検証)をClaude Code(実行エンジン)が繋ぐことで、調査→実装→テストの全自動化が実現します
- CLAUDE.mdが連携の司令塔になる — 各MCPサーバーの呼び出しルール・リトライ制御・優先順位をCLAUDE.mdに明記することで、Claude Codeが自律的かつ安定的にワークフローを回せます
- 最新ドキュメント参照(Context7)がAIコーディングの品質を根本から変える — LLMの学習データのタイムラグを解消することで、APIバージョン不整合という最も厄介な問題がゼロになります