🚀

MCPサーバーのコンテキスト負荷をClaude Agent経由で削減した話

に公開

はじめに

Claude Codeには MCP (Model Context Protocol) という、外部ツールと連携するための仕組みがあります。Backlog用のMCPサーバー(backlog-mcp-server)も公開されており、プロジェクト管理や課題追跡をClaude Codeから行えます。

しかし、MCPサーバーを直接統合すると、全てのツール定義がコンテキストに読み込まれ、大量のトークンを消費するという問題があります。Anthropicの公式記事でも、この課題が言及されています。

今回、この問題を解決するエージェント経由の動的接続パターンを実装し、コンテキスト消費を大幅に削減しました。

問題: MCPサーバーのコンテキスト占領

Backlog MCPサーバーは、以下の7つのツールセットで約47個のツールを提供します:
(2025/11月時点)

  • Space管理 (3ツール): スペース情報、ユーザー一覧取得
  • Project管理 (5ツール): プロジェクト一覧、詳細取得
  • Issue管理 (18ツール): 課題の作成、更新、検索、コメント追加
  • Wiki管理 (4ツール): Wiki作成、更新、一覧取得
  • Git連携 (10ツール): リポジトリ操作、コミット管理
  • 通知管理 (4ツール): 通知一覧、既読管理
  • ドキュメント管理 (3ツール): ドキュメント作成、取得

MCPサーバーを通常の方法で統合すると、これら全てのツール定義がセッション開始時にコンテキストに読み込まれ、トークンを常時消費します。実際の作業では一部のツールしか使わないのに、全ツールの定義を保持し続けるのは非効率です。

解決策: エージェントベースの動的接続パターン

この問題を解決するため、以下のアーキテクチャを実装しました:

1. 軽量なエージェント定義のみをコンテキストに配置

通常のMCP統合では、全ツール定義がコンテキストに読み込まれますが、今回はエージェント定義ファイルのみをコンテキストに配置します。

# Backlog Agent

このエージェントは、Backlogの操作を自然言語で実行できます。

## 使い方

プロジェクト一覧を取得する場合:
- @agent-backlog:backlog プロジェクト一覧を取得して
- 内部的に `backlog-connector.mjs` を呼び出してMCPサーバーに接続

2. 必要な時だけMCPサーバーに接続

Node.jsスクリプト(backlog-connector.mjs)を使って、実行時に動的にMCPサーバーを起動・接続します:

import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';

async connect() {
  this.transport = new StdioClientTransport({
    command: 'npx',
    args: ['backlog-mcp-server'],
    env: {
      BACKLOG_DOMAIN: process.env.BACKLOG_DOMAIN,
      BACKLOG_API_KEY: process.env.BACKLOG_API_KEY,
    },
  });

  this.client = new Client({ name: 'claude-backlog-agent' });
  await this.client.connect(this.transport);
}

async callTool(toolName, args) {
  await this.connect();
  const result = await this.client.callTool({ name: toolName, arguments: args });
  await this.disconnect();
  return result;
}

3. 実行フロー

  1. ユーザーが自然言語でリクエスト: 「プロジェクト一覧を取得して」
  2. Claudeがエージェント定義を参照し、backlog-connector.mjsを実行
  3. スクリプトがMCPサーバーをnpxで起動して接続
  4. 必要なツールのみを呼び出し
  5. 結果を返して接続を切断

結果: コンテキスト消費を劇的に削減

統合方式 コンテキスト消費 説明
通常のMCP統合 約23,600トークン 47ツール全ての定義を常時保持
エージェントベース 約500トークン エージェント定義のみ、ツール定義は不要

約98%のコンテキスト削減を達成し、他の作業に使えるトークンが大幅に増えました。

トレードオフ: 実行速度

このアプローチには性能上のトレードオフがあります:

  • 通常のMCP統合: MCPサーバーが常時起動しているため、即座にツールを呼び出せる
  • 動的接続方式: 毎回npxでMCPサーバーを起動するため、実行に数秒かかる

頻繁にBacklog操作を行う場合は待ち時間が気になるかもしれませんが、コンテキスト効率を優先する場合には有効な選択肢です。

プラグイン形式での提供

このプロジェクトはClaude Codeプラグインとして提供しています。その理由は:

  1. 他のMCPサーバーにも同じパターンを適用しやすい

    • 同じ「動的接続」パターンで、Slack、GitHub、JiraなどのMCPサーバーも統合可能
    • プラグイン構造がテンプレートとして機能
  2. 配布と導入が簡単

    • GitHubリポジトリを指定するだけでインストール可能
    • 設定は~/.claude/settings.jsonに追加するだけ
{
  "enabledPlugins": {
    "backlog@claude-backlog-agent": true
  },
  "env": {
    "BACKLOG_DOMAIN": "yourspace.backlog.com",
    "BACKLOG_API_KEY": "your_api_key_here"
  }
}

※ 環境変数の読み込み方法がこの方法しかわからないかったので、もっといい方法あれば教えてほしいです

免責事項

このプラグインは実験・テスト目的で作成したものです。動作確認は行っていますが、定期的なメンテナンスや更新の予定はありません。本番環境での使用は自己責任でお願いします。

まとめ

MCPサーバーの「コンテキスト占領」問題に対して、以下のアプローチで解決しました:

  • エージェント定義のみをコンテキストに配置
  • 動的にMCPサーバーに接続 (必要な時だけ起動)
  • 98%のコンテキスト削減 (23,600 → 500トークン)
  • ⚠️ トレードオフ: 実行速度は遅くなる (起動に数秒)
  • 🔌 プラグイン形式: 他のMCPサーバーにも適用可能なパターン

このパターンは、コンテキスト効率を重視する場合に有効です。頻繁にツールを使う場合は通常のMCP統合が適していますが、時々使う程度であれば、コンテキストを節約できるこのアプローチが役立ちます。

リポジトリ

実装の詳細やソースコードは以下で公開しています:

https://github.com/ryotsukuda333/claude-backlog-agent

同様のパターンで他のMCPサーバーを統合したい場合は、参考にしてください。

おわりに

プラグインの導入は初めてだったので、苦戦しました。
インストールは成功するけど、エージェントとして認識されないことが多く
/plugin コマンドでみると、5番の選択肢が増えており。そこにエラー内容が記載されていたためでした。エラー内容をすべて取り除けばちゃんと認識されたので、今後の開発のデバッグ作業の際に利用します。

実際に社内などで活用する際にはプライベートリポジトリとし
マーケットプレイスにはださず、直接リポジトリを指定して入れるのがいいと思います。

Discussion