Claude Code SkillsでMCPのトークン消費を削減する

Claude Code SkillsでMCPのトークン消費を削減する

2025.11.18

Introduction

先日、Anthropicのサイトで「Code execution with MCP」という記事がpostされました。
この記事はMCPでコードを実行させることでより効率的なエージェントを構築しよう、という内容です。

Claude CodeやAI Agent使用時、MCPサーバーのツールを直接呼び出すだけでは大量のトークンを消費してしまいます。
多数のMCPサーバを使用したり、扱うデータによっては大量のトークンを簡単に消費してしまい、
コストと処理時間が問題になります。

この記事では、Anthropicが提唱するコード実行アプローチとClaude Code Skillsを組み合わせて、
トークン消費を削減する方法を解説します。

About Code execution with MCP

まず、Code execution with MCPで何について述べているか簡単に解説を。

従来の問題点

記事では、従来の方法(MCPツールを直接呼び出す方式)には、以下のような課題があります。
(Claude Codeを使用する前提)

課題1: ツール定義でコンテキスト圧迫

MCPのツールはClaude Code起動時にコンテキストに読み込まれます。
なので、多くのMCP Server(ツール)を使っているならそれだけで
起動直後にコンテキストを消費している状態です。

課題2: 中間データ重複

記事の例を出すと、会議記録(50,000トークン)をGoogle DriveからSalesforceへ転送するという要件で

  1. gdrive.getDocument() → 50,000トークン
  2. Claudeがコンテキストで処理
  3. salesforce.updateRecord() → 50,000トークン再送

という処理で合計100,000トークン消費しています。
同じ内容のデータが重複しており、無駄です。

課題3: 制御フローの非効率性

ループや条件分岐をAIが毎回判断・実行するため、非効率的です。

コード実行(Code execution)アプローチ

記事で提案する解決策は、MCPツールをCode APIとして扱う手法です。
従来方式が
AI → MCPツールを直接呼び出し → MCPサーバー
となるのに対し、
コード実行方式では以下のようになります。

AI → TypeScriptコード生成 → コード実行環境(nodeとか) → MCPサーバー
                              ↓
                     コード内でデータ処理
                              ↓
                     必要な結果だけをAIに返す

実行パターン

記事では以下のような実行パターン例を提示しています。

  1. Progressive Disclosure(段階的開示)

    • ツール定義をファイルツリーで管理
    • 必要なツールだけを読み込む
  2. Context-Efficient Data Processing(効率的データ処理)

    • データのフィルタリング・集計をコード内で実行
    • 10,000行 → 5行に絞り込んでから返す
  3. Privacy-Preserving Data Flow(プライバシー保護)

    • 機密データをトークン化してAIに渡さない
    • コード実行環境内だけで実際の値を扱う

記事では、実測値として削減率98.7%というすごい数値がでています。
これは極端な例かもしれませんが、
トークン削減効果として効果が大きいことがわかります。

従来方式: 150,000トークン
コード実行方式: 2,000トークン
削減率: 98.7%

AI AgentとClaude Code Skills

このコード実行アプローチは、以下の環境で特に有用な可能性があります。

Claude Code Skills:

  • Skillsは自動で段階的開示(必要なツールだけを読み込む)
  • Claude CodeはBashツール経由でts/js実行が可能
  • 複数Skillsの組み合わせが容易

AI Agent全般:

  • ツール数が多い環境で効果大
  • 長時間実行されるタスクでトークン節約

About Claude Code Skill

ここで簡単にClaude Code Skills(以下Skills)についておさらい。
Skillsは、Claudeが必要な時に自動的に読み込む、再利用可能な専門知識のパッケージです。
エージェント(Claude Code)が特定のタスクをより効率的に実行できるように、
指示(instruction)、スクリプト、リソースを用いて
専門知識をClaudeの構成可能なリソースにパッケージ化します。
そうすることでClaudeの機能を拡張し、特定タスクに特化したエージェントに変換します。

Skillsの基本

Skillsは以下のような機能をもっています。

  • 自動検出: タスクに関連するSkillを自動で識別
  • 段階的読み込み: 必要最小限の情報だけをロード
  • 組み合わせ可能: 複数のSkillsを同時に使用
  • 実行可能なコード: 任意のスクリプトを含められる

スラッシュコマンドはユーザー呼び出しですが、SkillsはClaudeが自律的に呼び出します。

Skillsを定義するにはSKILL.mdファイルを含むディレクトリを作成するだけでOK。

個人用Skills(全プロジェクトで利用)は以下のように作成します。
※ Skillsの詳細な作成方法はここを参照

~/.claude/skills/your-skill-name/
├── SKILL.md (必須)
└── (その他サポートファイル)

プロジェクト用Skills以下の構造。

.claude/skills/your-skill-name/
├── SKILL.md (必須)
└── (その他サポートファイル)

SKILL.md(大文字)はSkillsに必須のファイルで、Skills内容を
YAMLフロントマターとMarkdown形式のコンテンツで構成されています。

---
name: skill-name
description: |
  What the skill does and when to use it.
  Includes trigger phrases and use cases.
---

# Skill Documentation

## Instructions
Step-by-step guide...

## Examples
Concrete usage examples...

nameはスキル名を表します。
descriptionはそのスキルが何をするか、いつ使用するかの簡潔(最大 1024 文字)な説明です。
詳しくはこちらのベストプラクティスを確認してください。

Skillsの主なユースケースは以下です。

  • プロジェクト固有の知識 - コーディング規約、アーキテクチャ
  • 頻出タスクの自動化 - テスト実行、デプロイ手順
  • ドメイン知識の共有 - 業界特有のルール、ベストプラクティス

本記事ではMCPサーバのwrapperとしてSkillsを使用します。

About mcp-bookmark

以前この記事で紹介したのですが、
これはChromeブックマークをローカルDBにインデックス化し、全文検索できるMCPサーバーです。
※動作するのはmacのみ

今回はSkillsでこのMCPサーバをつかってトークンを計測してみます。

このMCPサーバはブックマークしていればChrome Extension経由でPDFでもインデックス化できるので、
いくつかの技術系PDF(機械学習やAWSなどのPDF)をインデックス化して試してみます。

mcp-bookmarkが提供するツールは以下。

// 全文検索
search_bookmarks_fulltext({ query, limit })

// コンテンツ全取得
get_bookmark_content({ url })

// PDF特定ページ取得
get_bookmark_content_range({ url, start_page, end_page })

// インデックス進捗確認
get_indexing_status()

mcp-bookmarkのセットアップ

Claude Codeでmcp-bookmarkを使えるようにします。
git clone してinstallスクリプト実行して指示どうりにすると
chrome extensionとMCPサーバがインストールできます。

% git clone https://github.com/nakamura-shuta/mcp-bookmark.git
% cd mcp-bookmark
% ./install.sh

PDFをインデックス化するには、ChromeでPDF(ローカルでもWEBでもOK)を開いてブックマークします。
その後、インストールしたExtensionをつかってローカルDBにインデックス化します。
最後に、Claude Codeを使うリポジトリに.mcp.jsonを作成したら準備OKです。

{
  "mcpServers": {
    "mcp-bookmark": {
      "command": "<mcp-bookmarkをインストールしたパス>",
      "args": [],
      "env": {
        "RUST_LOG": "info",
        "INDEX_NAME": "<インデックス名>"
      }
    }
  }
}

claude codeを起動し、mcp-bookmarkが有効なことを確認できたらOK。

> /mcp

 Manage MCP servers                                                       │
│                                                                         │
│   1. mcp-bookmark                            ✔ connected · Enter        │

なお、インデックス名は以下のように確認可能です。

% /path/your/mcp-bookmark --list-indexes

Available indexes:
==================

  your_pdf_index) [2.3MB]

実際にインデックス化された情報を取得してみます。

> mcp-bookmarkのツールをつかって、AWSの機械学習に関連するサービスはどん
なものがあるか教えて下さい。

⏺ mcp-bookmarkを使って、インデックス化されたPDFからAWSの機械学習関連サ
  ービスを検索します。

⏺ mcp-bookmark - search_bookmarks_fulltext (MCP)(query: "AWS 機械学習
                                                サービス SageMaker", limit:
                                                 20){                                                                 
      "indexing_complete": true,
      "indexing_status": "✅ Chrome Extension index loaded: 8
    documents
    … +90 lines (ctrl+o to expand)
・
・
・
⏺ インデックス化されたPDFから、AWSの機械学習関連サービスの情報を抽出で
  きました。目次から主要なサービスを整理してお伝えします。

  AWSの機械学習関連サービス

  1. Amazon SageMaker (統合機械学習プラットフォーム)

  Amazon SageMakerは、機械学習のフルライフサイクルをカバーする包括的な
  サービスです:

  データ準備・処理
  - SageMaker Processing Job: データ前処理・特徴量エンジニアリング
  - SageMaker Ground Truth: 訓練データのラベル付け
  - SageMaker Data Wrangler: データ変換とGUI操作
  - SageMaker Feature Store: 特徴量の共有・管理
  - SageMaker Clarify: バイアス検出とドリフト検出

<省略>

  7. その他の機械学習関連サービス

  量子コンピューティング
  - Amazon Braket: 量子コンピュータプログラミング環境

  データベース統合
  - Amazon Neptune: グラフデータベース(機械学習統合)
  - Amazon Aurora: リレーショナルDB(SageMakerモデル呼び出し可能)

  インフラ・デプロイ
  - AWS Lambda: サーバーレスモデルデプロイ
  - AWS IoT: IoTデバイスとの統合

  開発者ツール
  - CodeGuru Reviewer: AI自動コードレビュー
  - CodeGuru Profiler: パフォーマンス向上
  - DevOps Guru: アプリケーション可用性向上

  ---
  まとめ

  AWSの機械学習スタックは、「AI Servicesとして使う」
  (Rekognition、Comprehendなど)から 「SageMakerでフルカスタマイズ」
  まで、幅広いレベルをカバーしています。

  選択の指針:
  - 簡単に始めたい → Amazon AI Services
  - カスタマイズが必要 → Amazon SageMaker
  - データパイプライン構築 → Glue、Athena、Redshift
  - MLOps実践 → SageMaker Pipelines

  このように、AWSには30以上の機械学習関連サービスが用意されており、デー
  タ取り込みからモデルデプロイまでエンドツーエンドでカバーできます。

インデックス化された情報が検索できてます。
では、このあとmcp-bookmarkを使うSkillsを定義して計測してみます。

Environment

  • MacBook Pro (14-inch, M3, 2023)
  • OS : MacOS 15.7.1
  • Claude Code : 2.0.25
  • Node : v20.11.0
  • mcp-bookmark: v0.5.2

About Control Flow Efficiency

Code execution with MCPでは、コード実行アプローチによる
コンテキスト効率の高いフロー(Context efficient tool results)について解説してます。
コード実行アプローチは「制御フローをコード内に移し、結果のみをClaudeに返す」ことでコンテキストの効率化を実現します。

MCPを直接呼び出す方式の問題点

通常のやり方だと、ClaudeとMCPツールの往復で制御フローが実行されていました。
ローカルにインデックスされた複数PDF内容から結果を比較する例を考えてみます。
(mcp-bookmarkを使用した場合)

流れは以下。

Claude: PDFを検索する
  ↓
MCP Tool: 検索結果を返却
  ↓
Claude: 1冊目のPDFを取得する
  ↓
MCP Tool: 約20,000文字返却 (~5,000トークン)
※ PDF 50ページ分の内容
  ↓
Claude: 内容を分析・キーワードカウント・関連度判定して、2冊目のPDFを取得して
  ↓
MCP Tool: 約20,000文字返却 (~5,000トークン)
  ↓
Claude: 内容を分析・キーワードカウント・関連度判定して、3冊目を...
  ↓
<中略>
  ↓
Claude: 全ての結果を比較・フィルタリング(関連度が低いものを除外)
  ↓
Claude: 比較表を作成
  ↓
Claude: 推奨PDFを決定

往復回数: 6回以上(search 1回 + PDF取得 search結果の回数分 + 分析・判定)
総トークン: ~80,000トークン(search結果が4回と仮定。各PDF内容がcontextに蓄積)
処理時間: 30-60秒

この処理方法の場合、ClaudeとMCP toolが何度も往復し、そのたびに時間を消費します。
また、各PDFの全文が全てClaudeのcontextに蓄積され、
分析・フィルタリング・比較表作成の全てをClaudeが実行することで余計にトークンを消費してしまいます。

制御フローのコード内で完結させる

制御フローをTypeScript/JavaScriptコード内に移すことで、
Claudeには「最終結果のみ」返します。

Claude: TypeScriptコードを実行
  ↓
TypeScript実行環境(1セッションで完結):
  ├─ MCPツール: search_bookmarks_fulltext(1回目)
  ├─ ループ処理開始
  │   ├─ MCPツール: get_bookmark_content_range (PDF1) ← 2回目
  │   ├─ コード内で分析・条件判定
  │   <中略>
  │   ├─ コード内で分析・条件判定
  │   └─ MCPツール: get_bookmark_content_range (PDF4) ← 5回目
  ├─ 比較表を生成(コード内)
  └─ 最終結果のみ返す
  ↓
Claude ← 比較表のみ受け取る(500トークン)

MCPツール呼び出しは5回(search 1回 + PDF取得 4回)です。
しかし、Claude ↔ 実行環境の往復は1回のみとなっています。
また、中間結果(各PDF全文、計80,000文字)はClaudeに送られず、
TypeScript内で処理され、不必要な情報は破棄されます。

このアプローチにより、MCPツール呼び出しは複数回発生するが、
Claude ↔ 実行環境の往復は1回に抑えられ、中間結果がClaudeのcontextを圧迫しない
ようになります。

コード実行の共通基盤

コード実行アプローチを実施するにあたり、MCPサーバーへアクセスできるような処理を用意します。

MCPクライアント(_shared/mcp-client.ts)

TypeScript内からMCPサーバーに接続するための共通コード例です。
※本記事では説明をシンプルにするため、mcp-bookmark専用の実装にしてます

//_shared/mcp-bookmark-client.ts
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';

let cachedClient: Client | null = null;

async function getClient(): Promise<Client> {
  if (cachedClient) {
    return cachedClient;
  }

  // .mcp.jsonから設定を読み込む
  const config = loadConfig('mcp-bookmark');

  const transport = new StdioClientTransport({
    command: config.command,
    args: config.args,
    env: config.env
  });

  const client = new Client({
    name: 'skill-mcp-client',
    version: '0.1.0'
  });

  await client.connect(transport);
  cachedClient = client;
  return client;
}

export async function callMCPTool<T>(toolName: string, input: any): Promise<T> {
  const client = await getClient();
  const result = await client.callTool({
    name: toolName,
    arguments: input
  });

  return extractPayload(result) as T;
}

export async function closeConnection() {
  if (cachedClient) {
    await cachedClient.close();
    cachedClient = null;
  }
}

callMCPTool<T>() は呼び出したいMCPツールの名前とパラメータを指定し、
mcpライブラリのcallToolをつかってMCPツールを実行します。
以下のように使用します。

// PDF検索
const searchResult = await callMCPTool('search_bookmarks_fulltext', {
  query: 'concurrency async parallel',
  limit: 50
});

普通にMCPサーバを実行する場合、MCPツールを呼び出すたびにClaudeにもどって実行する必要があります。
しかし、callMCPTool関数を自分で定義することにより、
TypeScript内から直接MCPツールを呼び出せます。

// TypeScript内で完結
const searchResult = await callMCPTool('search_bookmarks_fulltext', {...});

for (const pdf of searchResult.results) {
  const content = await callMCPTool('get_bookmark_content_range', {...});

  // コード内で分析など実施
  if (shouldSkip(content)) continue;

  // 必要なものだけ保存
  results.push(analyze(content));
}

// Claudeには最終結果のみ返す
return results;

その他関数は以下。

  • getClient():mcp-bookmarkサーバーへの接続を確立し、キャッシュして再利用
  • closeConnection():処理完了後にMCP接続をクリーンアップ
  • loadConfig('mcp-bookmark'):.mcp.jsonから設定をload

共通の型定義とユーティリティ

必要な型やヘルパーを定義します。

//_shared/types.ts

export interface CompareOptions {
  //PDF比較オプション(略)
}

export interface AnalysisResult {
  //分析結果(略)
}

export interface PdfInfo {
  // PDF情報(略)
}

こちらは取得したPDF内容を分析したり出力するための関数です。

// キーワード分析(コンテンツ内でキーワードを検索・カウント、関連ページを抽出など)
export function analyzeContent(content: string, keywords: string[]): AnalysisResult {
}

// Markdown形式の比較表を生成
export function generateComparisonTable(results: PdfInfo[]): string {
}

// 推奨PDF決定
export function identifyBestPdf(results: PdfInfo[]): string {
}

本記事ではmcp-bookmark専用の実装をしましたが、
複数のMCPサーバーを使用したい場合は、サーバーごとに別client.tsを作成するか、
サーバー名を動的に指定する汎用的な実装を用意するような対応が必要です。

以降は、これらのコードを前提としてそれぞれの方法を説明します。

実現方法:3つのアプローチ

「制御フローのコード内完結処理」は、以下の方法で実現できます。

方法1: 動的に生成

ClaudeがタスクごとにTypeScriptコードを生成し、実行する方式です。

  • Claudeがタスク依頼を受け、TypeScriptコードを動的に生成
  • Write toolで一時ファイルに保存(例: ./tmp/compare-pdfs.ts
  • 柔軟性が高く、一度限りの処理や試行に良い

フローは以下です。

User: "AWSのサービスにおける並行性を比較して"
  ↓
Claude: タスクを理解→TypeScriptコードを生成
  ↓ Write tool
./tmp/compare-pdfs.ts に保存
  ↓ Bash tool: npx tsx ./hoge/compare-pdfs.ts
TypeScript実行環境(1セッションで完結):
  ├─ MCPツール: search_bookmarks_fulltext
  ├─ ループでMCPツール: get_bookmark_content_range
  ├─ コード内で分析・フィルタリング
  └─ 比較表を生成
  ↓
Claude ← 比較表のみ受け取る(500トークンくらい)

総トークン: 700-1000トークンくらい?(コード生成トークン + 結果500

毎回動的にコードを生成させる方法は柔軟性が高く、
毎回異なる要求に対応できます。
また、ユーザーは自然言語で依頼するだけなので学習コストもありません。
しかし、毎回コード生成のトークンが必要だったり、作成したコードを再利用するかどうかは
Claude Codeに委ねられます。

方法2: Skillsを定義する

PDFの比較処理をSkillsとして定義する方式です。

  • SKILL.mdでSkillの説明と使用方法を定義する
  • index.tsで実装を事前作成(.claude/skills/control-flow/
  • Progressive Disclosure: 必要なときだけSKILL.mdを読み込み(150トークンくらい?)
  • 最初にコード生成しておけば、再実行可能
  • チーム内で共有・改善しやすい

フローは以下です。

<前提:Skillsの定義をしておく>

User: "AWSのサービスにおける並行性を比較して"
  ↓
Claude: control-flow Skillをload
  ├─ SKILL.mdを読み込み(150トークン)
  ↓ Bash tool: npx tsx .claude/skills/control-flow/index.ts
TypeScript実行環境(1セッションで完結):
  ├─ MCPツール: search_bookmarks_fulltext
  ├─ ループでMCPツール: get_bookmark_content_range
  ├─ コード内で分析・フィルタリング
  └─ 比較表を生成
  ↓
Claude ← 比較表のみ受け取る

総トークン: 650トークンくらい?(Skill読み込み + 結果)

Skillによる処理はここで言っている、Progressive Disclosureと一致します。

構成配下です。.claude/skillsに必要なファイル群を定義しておきます。
index.tsに必要な処理(MCPの接続処理、PDFからの情報取得、集計など)
をすべて記述しておきます。

.claude/skills/
  control-flow/
    SKILL.md          ← 最初に読まれる
    index.ts          ← 必要なときだけ読まれる
  _shared/
    mcp-client.ts     ← 呼び出し時のみ

Skillsでは、必要な機能だけを段階的に読み込めるので、
対象のMCPがSkill経由のみでよいなら、最初から有効化しておく必要はありません。
これだけでも多少トークンの節約になります。

ただ、要件に応じてあらかじめ実装しておく必要があるので、
事前に仕様を決めておく必要があります。

方法3: Skill + 動的生成wrapper

Skillをベースに、タスク固有のロジックだけを動的生成する方式です。

方法2の、Skillをベースとして
タスク固有のカスタマイズを要件ごとにClaudeに生成させます。(フィルタリング条件など)
柔軟性は方法2より高くなります。

import { comparePdfs } from './.claude/skills/control-flow/index.ts';

// ↓のようなロジックだけ必要に応じて生成
const customWeighting = (pdf) => {
  if (pdf.title.includes('Rust')) return pdf.mentions * 1.5;
  return pdf.mentions;
};

const result = await comparePdfs({
  query: 'concurrency',
  keywords: ['並行', 'async'],
  customScoring: customWeighting  // 動的ロジック注入
});

Try: impliments Skill

では、方法2のSkillを定義し、
インデックス化された複数のPDFを比較してみます。

ここでは、インデックス化されている技術書から「並行性・非同期処理」の概念を抽出し、
クラウドアーキテクチャと言語実装という抽象度の違いを比較表にまとめます。

Skill実装

以下のSkillで実行されるコードでは、
複数PDFの取得処理と分析・条件分岐を実行して
最終的に必要なデータだけを返しています。

// .claude/skills/control-flow/index.ts
import { callMCPTool, closeConnection } from '../_shared/mcp-client.ts';

export async function comparePdfs(options: {
  query: string;
  keywords: string[];
  maxPdfs?: number;
  minMentions?: number;
}) {
  const { query, keywords, maxPdfs = 3, minMentions = 5 } = options;

  try {
    // Step 1: 検索
    const searchResponse = await callMCPTool('search_bookmarks_fulltext', {
      query,
      limit: 50
    });

    const pdfs = searchResponse.results
      .filter(r => r.url.endsWith('.pdf'))
      .slice(0, maxPdfs);

    // Step 2: ループ処理
    const results = [];
    for (const pdf of pdfs) {
      const content = await callMCPTool('get_bookmark_content_range', {
        url: pdf.url,
        start_page: 1,
        end_page: 50
      });

      // Step 3: 分析
      const analysis = analyzeContent(content.content, keywords);

      // Step 4: 条件分岐
      if (analysis.totalMentions < minMentions) {
        continue;  // 関連度が低いものはスキップ
      }

      results.push({
        pdf: pdf.title,
        mentions: analysis.totalMentions,
        pages: analysis.relevantPages.length,
        topics: analysis.topicsCovered
      });
    }

    // Step 5: 比較表生成
    const table = generateComparisonTable(results);

    // Step 6: 最終結果のみ返す
    return {
      processed: pdfs.length,
      relevant: results.length,
      comparisonTable: table,
      recommendation: identifyBestPdf(results),
      processingTime: `${((Date.now() - startTime) / 1000).toFixed(1)}s`
    };
  } finally {
    await closeConnection();
  }
}

SKILL.md:

mcp-bookmarkを使った複数PDF情報を比較するための
SKILL.mdは以下です。

---
name: control-flow
description: |
ループと条件分岐を完全にコード内で実行し、複数のPDFを処理。
Claude-Toolの処理回数を削減。
複数のPDFを比較、結果を集約、比較表を作成する際に使用。
技術書間の概念比較(例:各技術における並行処理)、APIドキュメントにおける最適実装の発見に最適。
制御フロー最適化を備えたAnthropicの文脈効率型データ処理パターンに基づく。
---

# Control Flow Efficiency Skill

## Instructions

1. Import from `./index.ts`:
   ---typescript
   import { comparePdfs } from './index.ts';
   ---

2. Call with parameters:
   ---typescript
   const result = await comparePdfs({
     query: 'concurrency async parallel',
     keywords: ['並行', '非同期', 'async', 'スレッド'],
     maxPdfs: 4,
     minMentions: 3
   });
   ---

3. Display results:
   ---typescript
   console.log(result.comparisonTable);
   console.log(result.tokensSaved);
   ---

## Examples

### Example: Compare concurrency concepts across AWS and Rust
---typescript
const result = await comparePdfs({
  query: 'concurrency async parallel thread',
  keywords: ['並行', '非同期', 'async', 'Lambda', 'スレッド', 'アトミック'],
  maxPdfs: 4,
  minMentions: 3
});
---

実行結果

Claude Codeで以下のように指示してSkillを実行してみます。

AWSとRustの技術書から「並行性・非同期処理」について比較してください。
キーワード: 並行、非同期、async、Lambda、スレッド、アトミック

実行ログ:**

🔁 Control Flow Efficiency
Comparing up to 4 PDFs for keywords: 並行, 非同期, async, Lambda, スレッド, アトミック

📚 Processing 4 PDFs...

  Processing: AWS書籍...
    ✅ Found 8 mentions (Step Functions, Lambda並列実行)
  Processing: Rustの並行処理に関する書籍...
    ✅ Found 25 mentions (スレッド, Mutex, アトミック操作)
  Processing: eBPFの書籍...
    ⏭️  Skipped (only 2 mentions, need 3)
  Processing: Linuxカーネルの書籍...
    ✅ Found 6 mentions (スケジューラ, 並行処理)

=== COMPARISON COMPLETE ===
Processed: 4 PDFs
Relevant: 3 PDFs

| PDF | Mentions | Pages | 抽象度レイヤー | 主なトピック |
|-----|----------|-------|--------------|------------|
| Rust書籍 | 25 | 15 | 言語実装 | スレッド, Mutex, アトミック操作, メモリオーダリング |
| Linuxカーネル書籍 | 6 | 8 | OS/カーネル | CPUスケジューラ, プリエンプション, 並行処理 |
| AWS書籍 | 8 | 5 | クラウド | Step Functions並列実行, Lambda同時実行制御 |

📌 クラウドレイヤー(AWS)とコード実装レイヤー(Rust)で並行性の扱い方が明確に異なる
⚡ Processing time: 0.3s

実際に処理を実行すると、以下のように動作しました。

  • MCPツール呼び出し: 5回(search 1回 + PDF取得 4回)
  • Claude ↔ 実行環境の往復: 1回のみ
  • 中間結果はTypeScript内で処理・破棄されるので、Claudeには送信されない

Verification Results

次に、MCP直接実行とSkillのトークン効率を比較してみます。

検証用Skill

検証にはkeyword-count Skillを使用しました。
mcp-bookmarkを使ってPDFからキーワードをカウントし、結果のみを返すだけのSkillです。

// .claude/skills/keyword-count/index.ts
import { callMCPTool, closeConnection } from '../_shared/mcp-client.ts';

export async function countKeyword(options: {
  url: string;
  keyword: string;
  startPage: number;
  endPage: number;
}) {
  const result = await callMCPTool('get_bookmark_content_range', {
    url: options.url,
    start_page: options.startPage,
    end_page: options.endPage,
  });

  const content = result.content;
  const matches = content.match(new RegExp(options.keyword, 'gi')) || [];

  return {
    keyword: options.keyword,
    count: matches.length,
    totalChars: content.length,
    totalBytes: Buffer.byteLength(content, 'utf8'),
  };
}

同一条件での検索

以下の条件でMCP直接実行とSkill版(countKeyword)を比較しました。

  • 対象PDF: AWS関連書籍(約600ページ)
  • ページ範囲: 1-20
  • 検索キーワード: "lambda"
項目 MCP直接実行 Skill版 差分
取得文字数 18,212 18,212 なし
"lambda"出現回数 1回 1回 なし
コンテンツ - - 一致

Skill版で書籍全体を処理。

項目
処理ページ数 571ページ
取得文字数 476,958文字
取得バイト数 578,034バイト
"lambda"出現回数 134回
出現ページ数 47ページ

※MCP直接実行ではClaudeのコンテキス制限を超過してリトライすることもあった

トークン効率の比較

方式 トークン消費
MCP直接実行 約8,500トークン
Skill版 約450トークン

※ccusage・/contextコマンドを使って実施前後で確認

PDF全文がClaudeのコンテキストに蓄積されずに処理できたので、
トークン効率と処理速度が向上しました。

モデルが直接MCPツールを叩かず、コード越しにMCPを使って制御フローをコード内完結させるので、
大幅なトークン削減が可能になります。
MCPツール呼び出しは複数回発生しても、Claudeと実行環境間のやりとりは1回です。
(中間結果はClaudeに送られず、TypeScript内で処理・破棄)
MCPではトークン制限で失敗していた処理(約600ページ分の書籍全体を処理)も可能でした。

検証まとめ

コード実行アプローチは、要件に応じて実現手法を使わけましょう。

方法1(完全動的生成)

まだ試行錯誤段階だったり、1回限りの特殊な処理であれば
オンデマンドでコードを生成させてその場限りの処理をさせるのが低コストです。

方法2(再利用可能なSkill)

同じパターンを頻繁に使う場合やチーム内で共有したい、
少しでもトークンを節約したいのであればSkillを定義するのが良いと思います。
このケースは実行したい仕様が明確であればあるほど効果が高いと思います。

その他の方法

基本的なパターンは決まってるけど、タスクごとにカスタマイズが必要で実行頻度もある程度ありそう、
というケースなら、Skillとしてある程度定義しておき、
カスタマイズが必要な部分だけ動的に生成させるようなパターンになりそうです。

※例えば、PDF比較という目的はあるが重み付けやフィルタリングルールはタスクごとに変えたいなど

大量のデータ処理や頻繁に実行するタスクはコード実行方式にして、
逆にデータ量が少ない、ワンタイムのみのシンプルなタスクは直接実行方式にするのがよいでしょう。

Summary

本記事では、Anthropicの「Code execution with MCP」を参考に、
Claude Code Skillsと組み合わせて、
トークン消費を削減する方法を解説しました。

MCPツールを直接呼び出すのではなく、TypeScriptコード内からMCPを呼び出し、
制御フローをコード内で完結させることで、Claudeには最終結果のみを返します。
その結果、トークンと処理時間の向上が確認できました。

大量データ処理や繰り返し実行するタスクにはコード実行方式を、
シンプルなワンタイム処理には直接実行方式を使い分けることで、
コストと処理時間を最適化できます。

References

この記事をシェアする

FacebookHatena blogX

関連記事