Claude Code + Gemini で コンテキストを効率化

はじめに

Claude Code(Sonnet 4.5)は標準で 200K トークンのコンテキストを持っています。大規模なコードベースの分析や、複数回の Web 検索を行うと、すぐにコンテキストが枯渇してしまいます。

また、Claude の知識カットオフは 2025 年 7 月のため、それ以降の最新フレームワーク情報や技術ドキュメントにアクセスできません。

直面していた課題

Claude Code 単体では、次のような制約がありました。

コンテキスト制限による問題として、200K トークンに近づくと自動圧縮が発生します。Claude Code チームによれば 155K トークン付近で自動圧縮を実行しているという情報もあります。

知識の鮮度については、2025 年 7 月以降の情報にアクセスできません。最新のライブラリやフレームワーク情報を取得するのが難しい状況でした。

Web 検索のコストも課題でした。Claude の WebSearch/WebFetch は便利ですが、コンテキストを大量に消費します。複数回の検索を繰り返すと、あっという間にコンテキストが肥大化してしまいます。

大規模なコードベース全体を一度に分析することもできません。大規模なリファクタリングや分析では、作業領域が不足してしまいます。

解決策

Gemini MCP サーバーを Claude Code に統合することで、Claude のコンテキストを節約しながら Gemini の強み(1M トークン、Google Search)を活用できるようになりました。

Claude Code (200K)     →  タスク管理、コード編集、ユーザー対話
     ↓ MCP 経由
Gemini API (1M)        →  Web 検索、大規模分析、最新情報取得

なぜ Gemini を MCP 化するのか

Gemini 専用のサブエージェントを作ることもできますが、MCP 化して共通ツールとして提供することにしました。こうすることで、すべてのサブエージェントから利用できるようになります。

Claude Code との統合では、シームレスな連携が実現します。Claude がタスクに応じて自動的に Gemini を呼び出してくれます。コンテキストは分離されており、Gemini の処理結果のみが Claude に返されます。統一されたワークフローで、単一のインターフェースで作業が完結します。

Gemini の強みは、1M トークンの大きなコンテキストです。大規模なコードベースやドキュメントを一度に処理できます。Google Search grounding により、リアルタイムの最新情報にアクセスできるのも魅力です。Gemini 2.5 Flash は低レイテンシで応答するため、高速に処理が完了します。

アーキテクチャ

Claude + Gemini アーキテクチャ

処理フローは次のようになります。

  1. Claude がタスクに応じて Gemini を呼び出すか判断
  2. MCP 経由で必要な情報のみを Gemini に送信
  3. Gemini が 1M トークンのコンテキストで分析または検索を実行
  4. 結果を要約して Claude に返す(数百トークン程度)
  5. Claude が結果を元に作業を継続

セットアップ手順

Gemini を MCP サーバーとして Claude Code に統合する実装例を示します。OAuth2 認証を使用した MCP サーバーの参考実装です。

1. プロジェクト構造

gemini-mcp-server/
├── src/
│   ├── index.ts              # MCP サーバー本体
│   ├── codeAssistClient.ts   # Gemini API クライアント
│   ├── oauth.ts              # OAuth2 認証
│   └── types.ts              # 型定義
├── dist/                     # ビルド出力
├── package.json
└── tsconfig.json

2. OAuth2 認証の実装

// src/oauth.ts
import { OAuth2Client } from 'google-auth-library';
import { homedir } from 'node:os';
import { join } from 'node:path';
import * as fs from 'node:fs/promises';

/**
 * Load OAuth credentials from $HOME/.gemini/oauth_creds.json
 */
export async function loadCredentials(): Promise<SavedCredentials> {
  const credsPath = join(homedir(), '.gemini', 'oauth_creds.json');
  const credsText = await fs.readFile(credsPath, 'utf-8');
  return JSON.parse(credsText);
}

/**
 * Setup OAuth2 client with credentials
 */
export async function setupOAuth2Client(): Promise<OAuth2ClientSetup> {
  const savedCreds = await loadCredentials();

  // Gemini CLI のデフォルト OAuth 認証情報を使用
  const oauth2Client = new OAuth2Client(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI);

  const credentials: Credentials = {
    access_token: savedCreds.access_token,
    refresh_token: savedCreds.refresh_token,
    expiry_date: savedCreds.expiry_date,
    token_type: savedCreds.token_type,
    scope: savedCreds.scope,
  };

  oauth2Client.setCredentials(credentials);

  // Set up token refresh handler
  oauth2Client.on('tokens', async (tokens: Credentials) => {
    const updatedCreds = {
      ...savedCreds,
      access_token: tokens.access_token || savedCreds.access_token,
      refresh_token: tokens.refresh_token || savedCreds.refresh_token,
      expiry_date: tokens.expiry_date || savedCreds.expiry_date,
    };
    await saveCredentials(updatedCreds);
  });

  return { credentials, savedCreds };
}

3. Code Assist Client の実装

// src/codeAssistClient.ts
import { OAuth2Client } from 'google-auth-library';
import { getAccessToken, setupOAuth2Client } from './oauth.js';

const CODE_ASSIST_BASE_URL = 'https://cloudcode-pa.googleapis.com/v1internal';

export class CodeAssistClient implements ContentGenerator {
  private oauth2Client: OAuth2Client | null = null;
  private projectId: string | undefined;
  public userTier: UserTierId | undefined;

  async initialize(): Promise<void> {
    const oauth2Client = new OAuth2Client();
    const setup = await setupOAuth2Client();
    oauth2Client.setCredentials(setup.credentials);
    this.oauth2Client = oauth2Client;

    // Load Code Assist configuration
    const accessToken = await getAccessToken(oauth2Client);
    const loadData = await this.loadCodeAssist(accessToken);
    this.projectId = loadData.cloudaicompanionProject;
    this.userTier = loadData.currentTier?.id as UserTierId;
  }

  async generateContent(
    request: GenerateContentParameters,
    userPromptId: string
  ): Promise<GenerateContentResponse> {
    const accessToken = await this.getAccessToken();

    const requestBody = {
      model: request.model,
      project: this.projectId,
      user_prompt_id: userPromptId,
      request: {
        contents: request.contents,
        tools: request.config?.tools,
        generationConfig: request.config,
      },
    };

    const response = await fetch(`${CODE_ASSIST_BASE_URL}:generateContent`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${accessToken}`,
      },
      body: JSON.stringify(requestBody),
    });

    const data = await response.json();
    return data.response;
  }
}

4. MCP サーバーの実装

// src/index.ts
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { createCodeAssistClient } from './codeAssistClient.js';
import { randomUUID } from 'node:crypto';

let client: ContentGenerator | null = null;

const server = new Server(
  { name: 'gemini-cli-mcp', version: '0.4.0' },
  { capabilities: { tools: {} } }
);

// ツールの実行
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;

  switch (name) {
    case 'gemini_query': {
      const { prompt, model = 'gemini-2.5-flash' } = args;
      const response = await client.generateContent(
        { model, contents: prompt },
        randomUUID()
      );
      return { content: [{ type: 'text', text: response.text || '' }] };
    }

    case 'gemini_search': {
      const { query, model = 'gemini-2.5-flash' } = args;
      const enhancedPrompt = `Search the web and provide the latest information about: ${query}`;
      const response = await client.generateContent(
        {
          model,
          contents: enhancedPrompt,
          config: {
            tools: [{ googleSearch: {} }],
          },
        },
        randomUUID()
      );
      return { content: [{ type: 'text', text: response.text || '' }] };
    }
  }
});

// サーバー起動
async function main() {
  client = await createCodeAssistClient();
  const transport = new StdioServerTransport();
  await server.connect(transport);
}

main();

5. ビルドとセットアップ

# 依存関係のインストール
npm install @modelcontextprotocol/sdk google-auth-library @google/genai

# TypeScript のビルド
npm run build

6. 初回認証

MCP サーバーを起動する前に、gemini コマンドで OAuth2 認証を完了しておく必要があります。

# Gemini CLI で認証(初回のみ)
gemini auth

# ブラウザが開いて Google アカウントでの認証を求められます
# 認証が完了すると ~/.gemini/oauth_creds.json に認証情報が保存されます

7. Claude Code への追加

# MCP サーバーを追加
claude mcp add gemini-cli-mcp -- node /path/to/your/gemini-mcp-server/dist/index.js

または、~/.claude/mcp.json に手動で追加できます。

{
  "mcpServers": {
    "gemini-cli-mcp": {
      "command": "node",
      "args": ["/path/to/your/gemini-mcp-server/dist/index.js"]
    }
  }
}

8. MCP サーバーの確認

設定が正しく追加されたことを確認します。

claude mcp list

9. Claude Code を再起動

設定を反映するため、Claude Code を再起動します。

10. 動作確認

Claude Code で以下のように質問してみます。

「SwiftUI の 2025 年の最新機能を調べて」

Claude が自動的に mcp__gemini-cli-mcp__gemini_search を呼び出し、最新情報を取得します。

利用可能なツール

実際に使えるツールは以下の通りです。

gemini_search は、Google Search grounding で最新情報を検索します。検索クエリを query パラメーターに指定し、model には gemini-2.5-flash(高速)または gemini-2.5-pro(高品質)を選択できます。

gemini_query は、一般的な質問や分析に使用します。プロンプトを prompt パラメーターに指定し、同様に model を選択できます。

gemini_analyze_file は、画像、PDF、ドキュメントを分析します。分析の指示を prompt、ファイルパスを filePath、モデルは gemini-2.5-pro(推奨)または gemini-2.5-flash を指定します。

gemini_analyze_codebase は、複数のディレクトリを横断してコードベースを分析します。分析の指示を prompt、ディレクトリパスの配列を directories に指定します。モデルは gemini-2.5-pro(推奨)または gemini-2.5-flash を選べます。

Gemini をどう使うか

最新情報の取得では、Claude の知識カットオフ(2025 年 7 月)以降の情報が必要な場合に、Google Search grounding を活用して最新のフレームワーク情報や技術ドキュメントを取得できます。

大規模なコードベース分析では、1M トークンのコンテキストを活用して、Claude のコンテキストを消費せずに大規模なコードベースを分析できます。ただし、MCP 経由では数 KB〜数百 KB 程度の処理が現実的です。

マルチモーダル処理では、画像や PDF ドキュメントの分析が必要な場合に、Gemini の multimodal 機能を活用できます。

まとめ

Gemini を MCP サーバーとして Claude Code に統合することで、Claude のコンテキストを節約しながら、Gemini の 1M トークンと Google Search grounding を活用できます。OAuth2 認証により、ブラウザベースの簡単なセットアップで、最新情報へのアクセスと大規模なコードベース分析が可能になります。

参考リンク