Claude Code上級編|MCP・Hooks・Skills・サブエージェント実践ガイド

Claude Codeの基本コマンドを覚えたら、次はMCPサーバー・Hooks・Skills・サブエージェントといった拡張機能を使いこなす段階です。

この記事では、Claude Codeを「開発環境そのもの」に組み込むための上級テクニックを、実装コード付きで解説します。


MCPサーバー — 外部ツールとの接続

MCP(Model Context Protocol)は、Claude Codeを外部のツール・API・データベースに接続する標準プロトコルです。stdio・SSE・HTTPの3つの接続方式をサポートしています。

設定ファイルの配置

場所スコープ用途
.claude/.mcp.jsonプロジェクトチーム共有(Git管理)
~/.claude/.mcp.jsonユーザー全体個人ツール(全プロジェクト共通)

stdio方式 — ローカルプロセス連携

最も一般的な接続方式です。Claude Codeがサーバープロセスを起動し、stdin/stdoutでJSON-RPCメッセージをやり取りします。

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "${GH_PAT}"
      }
    },
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
    }
  }
}

envフィールドでは${変数名}構文でシェルの環境変数を参照できます。APIキーをハードコードせずに管理できます。

SSE方式 — リモートサーバー連携

Server-Sent Eventsによる持続的なHTTP接続です。リモートのMCPサーバーに接続する場合に使います。

{
  "mcpServers": {
    "remote-analytics": {
      "type": "sse",
      "url": "https://mcp.example.com/api/sse",
      "headers": {
        "Authorization": "Bearer ${MCP_TOKEN}"
      }
    }
  }
}

カスタムMCPサーバーの自作(TypeScript)

TypeScript SDKを使えば、独自のMCPサーバーを簡単に構築できます。

import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";

const server = new Server({
  name: "my-custom-server",
  version: "1.0.0",
});

server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: "analyze-bundle",
      description: "バンドルサイズを分析して改善点を提示",
      inputSchema: {
        type: "object" as const,
        properties: {
          entryPoint: { type: "string", description: "エントリーポイントのパス" },
        },
        required: ["entryPoint"],
      },
    },
  ],
}));

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === "analyze-bundle") {
    const entry = request.params.arguments.entryPoint;
    return {
      content: [{ type: "text", text: `分析結果: ${entry}` }],
    };
  }
  throw new Error(`Unknown tool: ${request.params.name}`);
});

const transport = new StdioServerTransport();
await server.connect(transport);

MCPサーバーの管理コマンド

コマンド説明
claude mcp list接続中のMCPサーバー一覧と状態を表示
claude mcp add サーバー名レジストリからMCPサーバーを追加
/mcp対話中にMCPサーバーを管理
claude --debug-file /tmp/debug.logMCP接続のデバッグログを出力

Hooks — ライフサイクルの自動化

Hooksは、Claude Codeの特定イベントに応じてシェルコマンドやHTTPリクエストを自動実行する機能です。.claude/settings.jsonに設定します。

フックイベント一覧

イベントタイミング用途
PreToolUseツール実行前危険なコマンドのブロック
PostToolUseツール実行後自動フォーマット・リント
SessionStartセッション開始時環境変数の読み込み
StopClaude応答完了時タスク完了チェック
NotificationClaude入力待ち時デスクトップ通知
PostCompactコンテキスト圧縮後コンテキストの再注入
UserPromptSubmitユーザー入力送信時入力のバリデーション

フックの4つのタイプ

1. command — シェルコマンド実行(最も一般的)

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "bash -c 'jq -r \".tool_input.file_path\" | xargs npx prettier --write'"
          }
        ]
      }
    ]
  }
}

2. http — リモートエンドポイントにPOST

{
  "hooks": {
    "PostToolUse": [
      {
        "hooks": [
          {
            "type": "http",
            "url": "https://audit.example.com/hooks/tool-use",
            "headers": {
              "Authorization": "Bearer ${AUDIT_TOKEN}"
            }
          }
        ]
      }
    ]
  }
}

3. prompt — LLMによる判定(1ターン)

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "prompt",
            "prompt": "すべてのタスクが完了しているか確認し、JSON形式で回答してください。"
          }
        ]
      }
    ]
  }
}

4. agent — サブエージェントによる検証(複数ターン)

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "agent",
            "prompt": "テストスイートを実行して全テストがパスすることを確認してください",
            "timeout": 120
          }
        ]
      }
    ]
  }
}

実践例: 危険コマンドのブロック

#!/bin/bash
# .claude/hooks/block-dangerous.sh
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

DANGEROUS_PATTERNS=(
  "rm -rf"
  "drop table"
  "git push --force"
)

for pattern in "${DANGEROUS_PATTERNS[@]}"; do
  if [[ "$COMMAND" == *"$pattern"* ]]; then
    echo "Blocked: $pattern detected" >&2
    exit 2
  fi
done

exit 0

フックの終了コードで動作が決まります。0は許可、2はブロック(stderrの内容が理由として表示)、それ以外はログ記録のみで続行します。

matcher構文

パターンマッチ対象説明
BashBashツール完全一致
Edit|WriteEditまたはWriteOR(論理和)
mcp__github__.*GitHub MCP全ツール正規表現
""(空文字)すべてのツールワイルドカード

Skills — カスタムスラッシュコマンド

Skillsは再利用可能なプロンプトテンプレートです。.claude/skills/スキル名/SKILL.mdに配置すると、/スキル名で呼び出せます。

SKILL.mdの構成

---
name: component-review
description: Reactコンポーネントの品質レビューを実行
user-invocable: true
allowed-tools: Read Grep
paths:
  - "src/components/**/*.tsx"
---

# コンポーネントレビュー

対象: $ARGUMENTS[0]

以下の観点でレビューしてください:

1. **TypeScript**: any型の使用、Props interfaceの命名
2. **パフォーマンス**: 不要な再レンダリング、メモ化の検討
3. **アクセシビリティ**: aria属性、キーボード操作

フロントマターの主要フィールド

フィールド説明
namestringスキルのコマンド名
descriptionstring自動呼び出しの判定に使用される説明文
allowed-toolsstringスキル実行中に自動許可するツール
pathsarrayスキルが有効になるファイルパターン
contextenumforkで隔離サブエージェントとして実行
effortenum推論の深さ(low / medium / high / max)

動的コンテンツの埋め込み

SKILL.md内でシェルコマンドの出力を動的に展開できます。!`コマンド`構文でスキル読み込み時に実行され、結果がプロンプトに埋め込まれます。

---
name: pr-summary
context: fork
---

## PR情報

- **ブランチ**: !`git rev-parse --abbrev-ref HEAD`
- **最新コミット**: !`git log -1 --oneline`
- **変更ファイル**: !`git diff --name-only origin/main`

上記の変更を要約してください。

サブエージェント — 専門特化したAIアシスタント

サブエージェントは、特定の専門領域に特化した独立エージェントです。親セッションから隔離されたコンテキストで動作し、並列処理にも対応します。

AGENTS.mdの作成

---
name: security-auditor
description: セキュリティ観点のコードレビュー
tools: Read Grep Bash(npm audit *)
model: claude-opus-4-6
effort: high
---

# セキュリティ監査エージェント

以下の観点でコードを監査してください:

1. OWASP Top 10の脆弱性
2. 認証・認可のフロー
3. 入力バリデーション
4. サードパーティ依存関係

深刻度をCRITICAL / HIGH / MEDIUM / LOWで分類し、
修正コード例を提示してください。

組み込みエージェントタイプ

タイプツール用途
ExploreRead, Grep, Glob, WebFetch読み取り専用の調査・分析
Plan分析のみ(ファイル変更不可)実装計画の立案
general-purpose親セッションと同等汎用タスク

CLAUDE.mdの高度な活用

パススコープルール

.claude/rules/ディレクトリにルールファイルを配置し、pathsフロントマターで適用範囲を限定できます。

---
paths:
  - "src/components/**/*.tsx"
  - "src/components/**/*.test.tsx"
---

# フロントエンドルール

- Functional Componentとhooksのみ使用
- Props interfaceは「コンポーネント名Props」で命名
- テストはコンポーネントと同じディレクトリに配置
- any型の使用禁止

@import構文

CLAUDE.mdから外部ファイルを参照して設定をモジュール化できます。

# プロジェクト設定

@README.md
@docs/architecture.md

## コーディング規約
@.prettierrc
@tsconfig.json

推奨ディレクトリ構成

.claude/
├── CLAUDE.md              # メインの指示書
├── CLAUDE.local.md        # 個人設定(.gitignore推奨)
├── settings.json          # フック・パーミッション
├── .mcp.json              # MCPサーバー設定
├── rules/
│   ├── code-style.md      # 全ファイル共通スタイル
│   ├── frontend.md        # フロントエンド専用
│   └── testing.md         # テスト規約
├── skills/
│   ├── review/SKILL.md    # レビュースキル
│   └── deploy/SKILL.md    # デプロイスキル
└── agents/
    └── security/AGENTS.md # セキュリティエージェント

パーミッション設定の実践

settings.jsonの設定例

{
  "permissions": {
    "allow": [
      "Read",
      "Bash(npm test *)",
      "Bash(npm run *)",
      "Bash(git *)",
      "WebFetch(domain:github.com)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(sudo *)",
      "Edit(.env*)"
    ]
  }
}

パーミッションルールの構文

構文マッチ対象
完全一致Bash(npm test)npm testのみ
ワイルドカードBash(npm run *)npm run dev
パスパターンEdit(src/**/*.ts)src配下のTSファイル
ドメイン指定WebFetch(domain:github.com)GitHubへのリクエスト
MCP指定mcp__github__*GitHub MCPの全ツール

評価順は Deny → Ask → Allow で、最初にマッチしたルールが適用されます。


実践: フロントエンド開発環境の構築例

Next.js + TypeScriptプロジェクトを例に、MCP・Hooks・パーミッションを組み合わせた設定を紹介します。

.claude/settings.json:

{
  "permissions": {
    "allow": ["Read", "Bash(pnpm *)", "Bash(git *)", "Bash(npx *)"],
    "deny": ["Bash(rm -rf *)", "Edit(.env*)"]
  },
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "bash -c 'jq -r \".tool_input.file_path\" | xargs npx prettier --write 2>/dev/null || true'"
          }
        ]
      }
    ]
  }
}

CLAUDE.md:

# プロジェクト名

## 技術スタック
- Next.js 15(App Router)
- TypeScript 5.x
- Tailwind CSS 4
- pnpm

## コマンド
- 開発: `pnpm dev`
- ビルド: `pnpm build`
- テスト: `pnpm test`

## 規約
@.claude/rules/code-style.md
@.claude/rules/frontend.md

この設定をプロジェクトにコミットするだけで、チーム全員が同じClaude Code環境で開発できます。


よくある質問

Q. MCPサーバーが接続できない場合のデバッグ方法は?

claude --debug-file /tmp/claude-debug.logで起動し、tail -f /tmp/claude-debug.log | grep -i mcpでMCP関連のログをリアルタイム確認できます。/mcpコマンドでサーバーの接続状態も確認できます。

Q. Hooksで複数のフックが同時に発火した場合の動作は?

同一イベントの複数フックは並列実行されます。PreToolUseの場合、1つでもブロック(exit 2)を返せばツール実行が阻止されます。最も制限的な結果が優先される設計です。

Q. CLAUDE.mdが長すぎるとどうなる?

200行を超えると読み込みコストが増加し、指示の遵守率が下がる傾向があります。テーマ別に.claude/rules/へ分割し、pathsフロントマターでスコープを限定するのがベストプラクティスです。

Q. MCPサーバーを自作する最小構成は?

npm install @modelcontextprotocol/sdkでSDKをインストールし、ListToolsとCallToolの2つのハンドラーを実装するだけです。20行程度のコードで動くMCPサーバーが作れます。

Q. Hooksの設定ファイルはどこに置くべき?

チーム共有のフックは.claude/settings.json(Git管理)、個人用は.claude/settings.local.json(.gitignore推奨)に配置します。ユーザー全体の設定は~/.claude/settings.jsonです。


まとめ

Claude Codeの拡張機能を活用すると、単なるAIアシスタントから「開発環境に統合されたAIパートナー」へと進化します。

  • MCPで外部ツール・API・データベースを接続
  • Hooksでファイル編集後の自動フォーマットや危険コマンドのブロック
  • Skillsでチーム共通のワークフローをコマンド化
  • サブエージェントで専門タスクを隔離実行
  • パーミッションでツールアクセスを細かく制御

まずは.claude/settings.jsonにPostToolUseフックを1つ追加するところから始めてみてください。自動フォーマットだけでも開発体験が大きく変わります。