# Anthropic公式のMCPによるコード実行をserena MCPで試してみたけど無理だった件

  ## TL;DR

- Anthropic の MCP コード実行手法(トークン 98.7%削減)を Serena MCP で試したがうまくいかなかった
- ツール数 5 個以下、シンプルな型定義の MCP でないと効果が出ない。Google Drive のようなシンプルな MCP で検証すべき。

## はじめに

Anthropic の記事「[Code execution with MCP: building more efficient AI agents](https://www.anthropic.com/engineering/code-execution-with-mcp)」を読みました。

https://www.anthropic.com/engineering/code-execution-with-mcp

Claude Code で MCP を登録すると、登録されている MCP のすべての Tools が Context に反映され、初期状態で Context 量を圧迫する問題があります。この記事では、MCP ツールを TypeScript コードとして実行することでトークン消費を 98.7%削減できること(150,000 トークン → 2,000 トークン)、中間データを LLM コンテキストに含めず最終結果のみを返すアプローチが紹介されていました。

この内容が気になったので、Serena MCP のツール(`listDir`, `findFile`, `getSymbolsOverview` など)を TypeScript コードから呼び出せる Claude Code Skill を実装しました。

https://github.com/Suntory-N-Water/mcp-code-execution

必要なツールのみをオンデマンドでインポートし、コード内でデータを処理してから最終結果のみを LLM に返すことで、トークン消費を削減できると考えました。

## 検証の目的

実装した Skill を使って、既存の Serena MCP(直接ツール呼び出し)とコード実行方式のコンテキスト消費量を実測値として比較することが目的です。仮説として、同じ Serena MCP ツールを使用しても、コード実行方式のほうがコンテキスト消費量が少なくなる想定です。

検証対象は本プロジェクト用に用意した簡易的なスクレイピング機能を持つ `test-parser` プロジェクトの parser ディレクトリ(TypeScript ファイル 10 個未満)を選定しました。
小規模で検証に適しており、Serena MCP と同様の水準でシンボル解析できるか試験できること、実測値の比較に十分な複雑さがあることから、検証対象として適切だと判断しました。

## 検証内容

`test-parser` プロジェクトの parser ディレクトリに対して、以下の 3 つのタスクを順次実行する計画を立てました。

1. ディレクトリ構造の取得(`listDir`)
2. TypeScript ファイルの一覧化(`findFile`)
3. シンボル情報の抽出(`getSymbolsOverview`)

### 検証ゴール

- Serena MCP 直接呼び出しと比較して、コンテキスト消費量の削減率を確認する
- 中間データが LLM コンテキストに含まれないことを確認する
- 最終結果のみが返されることを確認する

### 前提条件

`test-parser` プロジェクト内に `.claude/skills/mcp-code-execution` を配置すれば、Serena がプロジェクトルートを認識し、相対パス指定で parser 配下のファイルを解析できると想定していました。

## 実装方針

Claude Code 公式ドキュメントによると、`.claude/skills/` に配置されたプロジェクトスキルは、そのプロジェクトのコンテキストで実行されます。そのため、プロジェクトスキルとして配置すれば、Serena は親プロジェクトをルートディレクトリとして認識すると考えました。

`test-parser` プロジェクト内に `.claude/skills/mcp-code-execution` を配置し、検証スクリプト `src/analyze-parser.ts` を作成しました。3 つのタスクを順次実行する予定でしたが、まず最初のタスク(ディレクトリ構造の取得)を実装して動作を確認することにしました。

```
test-parser/                                 ← 期待するプロジェクトルート
├── .claude/
│   └── skills/
│       └── mcp-code-execution/              ← Skillを配置
│           ├── src/
│           │   └── analyze-parser.ts        ← 検証スクリプト
│           ├── servers/serena/              ← 生成されたツール
│           └── SKILL.md
└── parser/                                  ← 解析対象
    └── src/
        ├── file1.ts
        ├── file2.ts
        └── ...
```

検証スクリプトでは、相対パス `'parser'` を指定して `listDir` を呼び出しました。期待動作としては、`/Users/.../test-parser/parser` が解釈されるはずです。成功すれば、タスク 2(`findFile`)、タスク 3(`getSymbolsOverview`)を実装する予定でした。

```typescript
import { listDir } from '../servers/serena/index.js';
import { closeClient } from './client.js';

async function main() {
  try {
    const result = await listDir({
      relative_path: 'parser',
      recursive: true,
    });
    console.log('Parser directory contents:', result);
  } catch (error) {
    if (error instanceof Error) {
      console.error('Error:', error.message);
    }
  } finally {
    await closeClient();
  }
}

main();
```

セットアップ後にスクリプトを実行したところ、以下のエラーが発生しました。

## プロジェクトルートの誤認識

タスク 1(ディレクトリ構造の取得)の実行時にエラーが発生しました。

```
Error: Directory not found: parser
```

このため、タスク 2(TypeScript ファイルの一覧化)とタスク 3(シンボル情報の抽出)は実行できませんでした。Serena のログ出力を確認したところ、以下のように記録されています。

```
INFO serena.agent:load_project_from_path_or_name:443 -
Found registered project 'mcp-code-execution' at path
/Users/user/dev/test-parser/.claude/skills/mcp-code-execution
```

Serena は**Skillディレクトリ自身**をプロジェクトルートとして認識していました。
つまり、期待していたのは `/Users/user/dev/test-parser` をプロジェクトルートとして認識し、相対パス `'parser'` を `/Users/user/dev/test-parser/parser` と解釈することです。
ですが、実際には `/Users/user/dev/test-parser/.claude/skills/mcp-code-execution` をプロジェクトルートとして認識し、相対パス `'parser'` を `/Users/user/dev/test-parser/.claude/skills/mcp-code-execution/parser` と解釈していました。当然、この場所には parser ディレクトリは存在しません。

```
test-parser/
├── .claude/
│   └── skills/
│       └── mcp-code-execution/      ← Serenaが認識したルート
│           └── parser/              ← ここを探してしまう(存在しない)
└── parser/                          ← 本当はここを探したい
```

この問題は MCP サーバーの起動元を動的に設定することで解決できました。例えば Serena MCP はプロジェクトのカレントディレクトリでサーバーを起動し、その後はそのプロジェクトを対象に調査を行います。`~/.claude/skills/` で登録した時は相対パスでプロジェクトのルートを特定できないため、環境変数に実行パスのフルパスを設定することで解決できます。

```ts
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
import { fileURLToPath } from 'node:url';
import { dirname, resolve } from 'node:path';

let globalClient: Client | null = null;

const projectRoot = (() => {
  // 環境変数が設定されていれば優先
  if (process.env.SERENA_PROJECT_ROOT) {
    return process.env.SERENA_PROJECT_ROOT;
  }

  // このファイルの場所を特定
  const __filename = fileURLToPath(import.meta.url);
  const __dirname = dirname(__filename);

  // Project Skillかどうかを判定
  // Project Skill: /path/to/project/.claude/skills/mcp-code-execution/src/client.ts
  // Personal Skill: ~/.claude/skills/mcp-code-execution/src/client.ts
  const isProjectSkill = __dirname.includes('/.claude/skills/');

  if (isProjectSkill) {
    // Project Skillの場合は ../../../.. で解決
    // src → mcp-code-execution → skills → .claude → project root
    return resolve(__dirname, '../../../..');
  }

  // Personal Skillで環境変数未設定はエラー
  throw new Error(
    '環境変数 SERENA_PROJECT_ROOT が設定されていません。\n' +
      'Personal Skill (~/.claude/skills/) を使用する場合は必須です。\n\n' +
      '設定方法:\n' +
      '1. 環境変数で指定: export SERENA_PROJECT_ROOT=/path/to/your/project\n' +
      '2. .env ファイルで指定: echo "SERENA_PROJECT_ROOT=/path/to/your/project" > .env',
  );
})();

/**
 * Serena MCP サーバへの接続を初期化。
 */
export async function initClient(): Promise<Client> {
  if (globalClient) {
    return globalClient;
  }

  // Serena MCP サーバの起動設定
  const transport = new StdioClientTransport({
    command: 'uvx',
    args: [
      '--from',
      'git+https://github.com/oraios/serena',
      'serena',
      'start-mcp-server',
      '--context',
      'ide-assistant',
      '--project',
      projectRoot,
      '--enable-web-dashboard=false',
    ],
  });

  globalClient = new Client(
    {
      name: 'mcp-code-executor',
      version: '0.1.0',
    },
    {
      capabilities: {},
    },
  );

  await globalClient.connect(transport);

  return globalClient;
}
```


## Claude Codeの型定義認識の課題

今回の検証では、SKILL.md と TOOLS.md を用意しました。Claude Code の公式ドキュメントに従って、SKILLS 自体の役割と、関連ファイルを分離しています。(詳細は付録 A、付録 B を参照)

検証用として一部の Tools では明確に型定義も行っていました。

```ts
import { callMCPTool } from '../../src/client.js';
import type { SymbolKind, SymbolLocation } from './types.js';

type FindSymbolInput = {
  name_path: string;
  depth?: number;
  relative_path?: string;
  include_body?: boolean;
  include_kinds?: SymbolKind[];
  exclude_kinds?: SymbolKind[];
  substring_matching?: boolean;
  max_answer_chars?: number;
};

/**
 * findSymbolツールの戻り値に含まれるシンボル情報
 */
export type FindSymbolResultItem = {
  name_path: string;
  kind: SymbolKind;
  body_location: SymbolLocation;
  relative_path: string;
};

/**
 * findSymbolツールの戻り値型
 */
export type FindSymbolResult = FindSymbolResultItem[];

export async function findSymbol(
  input: FindSymbolInput,
): Promise<FindSymbolResult> {
  return await callMCPTool('find_symbol', input);
}
```

### 型定義の誤認識

`findSymbol` ツールでファイルのパスを指定するプロパティは `name_path` で定義されています。型定義も同様に行っていましたが、毎回 `name` として設定してしまいます。

```ts
// findSymbolでシンボルの実装を取得
const symbolDetail = await findSymbol({
  name: 'functionName', // 型エラー
  relative_path: file,
  include_body: true
});
```

SKILL.md に型定義を参照することを明記していますが、それでも解決しなかったので、毎回型エラーが起きる→修正する→動くといった形で往復が発生しており効率が悪いです。このあたりは他の SKILLS でも同様に発生する問題なのだろう。

### 存在しないプロパティの捏造

型定義しているにもかかわらず、独自の `as` アサーションを作成していました。当然のごとく動作しません。`isExported` プロパティはファイルのどこにも存在しないので、本当にどこから出てきたのか不明です。

```ts
// ファイル内のシンボル一覧を取得
const symbols = await getSymbolsOverview({
  relative_path: file
}) as Array<{
  name: string;
  kind: number;
  isExported: boolean;
  startLine: number;
  endLine: number;
}>;

// 本来は以下の型定義が正しいのに何故かアサーションしてくる
// export type SymbolInfo = {
//   name_path: string;
//   kind: SymbolKind;
//   body_location: SymbolLocation;
//   relative_path: string;
// };
// export type GetSymbolsOverviewResult = SymbolInfo[];
```

## 問題の原因

### ツール数の多さと型定義の複雑さ

Serena MCP は 20 個のツールを持ち、それぞれに複雑な型定義があります。TOOLS.md で仕様を説明し、型定義ファイルも用意していましたが、Claude Code は以下のミスを繰り返しました。

- プロパティ名の誤り(`name` → 正しくは `name_path`)
- 独自の型アサーション(`isExported` プロパティの捏造)

型定義を提供しても、Claude Code がそれを正確に参照する保証はありませんでした。結果として、エラー修正の往復が発生し、トークン消費が増加しました。「ソースコード生成後に型チェックを実行すること」と明記することも可能ですが、コード生成→型チェック→エラーという流れになると、トークン消費量が多くなるため根本的な解決にはなりません。

### Serena独自の設計思想

ファイル内容を取得する方法が一般的な `readFile` ではなく、`searchForPattern` や `findSymbol` という Serena 独自の設計になっています。これはトークン効率を重視した設計ですが、Claude Code は一般的な API を前提にコードを生成するため、ミスマッチが発生しました。Serena MCP は「ファイル全体を読み込まない」という設計方針を採用しています。この設計は、LLM が直接ツールを呼び出すなら有効ですが、LLM がコードを生成するなら認知的な負荷が高くなる可能性があります。

## 考察

### シンプルなMCPでは成功率が上がる可能性

Context7 MCP は 2 つのツールのみで、型定義もシンプルです(`resolve-library-id` と `get-library-docs`)。ツール数が少なく、パラメータもシンプルなため、EXAMPLES.md に掲載するソースコードの例を明確に書くことができます。結果として、Claude Code が型エラーを起こす可能性が低くなると考えられます。

### 検証できなかったこと

当初の目的は、Serena MCP 直接呼び出しと比較してコンテキスト消費量の削減率を確認し、中間データが LLM コンテキストに含まれず、最終結果のみが返されることを確認することでした。しかし、実用に足りるものではなかったため、検証を中止しました。この状態で「トークン削減効果」を計測しても、Skill の問題なのか、Serena MCP の複雑さの問題なのかが切り分けられません。型定義がシンプルな MCP で再検証する必要があると感じました。

### 改善案

今後別で実施するとしたら以下の手順で実施します。

1 つ目はシンプルな MCP での再検証を行います。Context7 MCP のような、ツール数が少なく(2-3 個程度)、パラメータがシンプルで(必須 1-2 個、オプション 1-2 個)、返却値の型が明確な MCP で検証します。これにより、Skill 自体の有効性を切り分けて評価できます。

2 つ目はテンプレートスクリプトを事前に配置します。`src/template.ts` を用意し、Claude Code の操作がスムーズになるかを検証します。

3 つ目は EXAMPLES.md のコードをより具体的に書きます。Serena MCP ではツールが多く Claude Code が実際に出力するコードにもばらつきがありました。実際に動作するソースコードを複数パターン EXAMPLES.md に掲載し、Claude Code が参照しやすくすることで型エラーが減るか検証します。

## おわりに

Claude Code 自体に TODO を作成させ、確認が終わってからコード生成→ツール実行する方法が考えられますが、それでは既存のツール呼び出しほうが速くストレスもありません。理想は対象のファイルを 1 回で全部 Tool 読み込みし最小のコンテキスト量で関連ファイルの分析を行うことでしたが、何回も実行する前提の MCP にこのアプローチは適切ではなかっただろう。

MCP サーバーのコード実行をするためには、以下の条件を満たした MCP が適切だだ。

- ツール数が 5 個以下
- 型定義がプリミティブ型中心(string, number, boolean)
- パラメータが必須 1-2 個・オプション 0-2 個
- 返却値が配列やオブジェクトではなく単一の値
- 設計思想が一般的な API の命名規則に沿っている

対象にした Serena MCP はこれらの条件を満たしていませんでした。記事にある通り、Google Drive のように返却されるものがはっきりしている MCP で実施することを推奨します。

---

## 付録A、SKILL.md

````md SKILL.md
---
name: mcp-code-execution
description: MCP ツールを TypeScript コードとして実行し、トークン消費を最大 98.7% 削減します。Serena MCP ツール呼び出しが必要な場合、大規模データセット処理、コードベース全体への操作、バッチ処理、プライバシーに配慮したデータ処理が必要な場合に使用してください。
allowed-tools: Read, Write, Bash, Glob, Grep
---

## MCP コード実行

## 概要

MCP ツールを TypeScript コードとして実行し、トークン消費を劇的に削減します。必要なツールのみをインポートし、コード内でデータを処理してから、最終結果のみを返します。

**トークン削減**: マルチツールワークフローで最大 **98.7%**(150,000 トークン → 2,000 トークン)

## いつこのスキルを使うか

以下の条件のいずれかに該当する場合、このスキルを使用してください：

### 使用すべき場合
- ✓ **Serena MCP ツール**を連続使用する必要がある
- ✓ **100個以上のファイル**を処理する
- ✓ **大規模データのフィルタリング**(結果を絞り込んでから報告)
- ✓ **バッチ操作**(複数ファイルへのループ処理)
- ✓ **プライバシー保護**(機密データを LLM コンテキストに入れない)

### 使用すべきでない場合
- ✗ 1-2個のツールを1回だけ使う単純なタスク
- ✗ どのツールが必要かまだ分からない探索的作業
- ✗ 中間結果を確認する必要がある対話的デバッグ

## セットアップ

### プロジェクトルートの設定

このスキルの配置場所により、プロジェクトルートの設定方法が異なります。

#### Project Skills(`.claude/skills/` に配置)の場合

**プロジェクトルートは自動検出されます**。環境変数の設定は不要です。

```bash
## プロジェクト内のスキル
## .claude/skills/mcp-code-execution から自動的に ../../../../ でプロジェクトルートを検出
bun run src/your-script.ts
```

#### Personal Skills(`~/.claude/skills/` に配置)の場合

**環境変数 `SERENA_PROJECT_ROOT` が必須**です。未設定の場合、エラーが発生します。

**方法1: 環境変数で指定**
```bash
export SERENA_PROJECT_ROOT=/path/to/your/project
bun run src/your-script.ts
```

**方法2: .env ファイルで管理**(推奨)
```env
SERENA_PROJECT_ROOT=/path/to/your/project
```

プロジェクトルートに `.env` ファイルを配置すれば、Bun が自動的に読み込みます。

**異なるプロジェクトでの使用例**:
```bash
## test-parser プロジェクト
SERENA_PROJECT_ROOT=/Users/user/dev/test-parser bun run src/analyze-parser.ts

## testA プロジェクト
SERENA_PROJECT_ROOT=/Users/user/dev/testA bun run src/analyze-testA.ts
```

## ワークフロー(Claude が従うべき手順)

### ステップ1: タスクの評価

ユーザーのタスクが上記の「使用すべき場合」に該当するか判断してください。該当する場合のみ、このスキルを使用してください。

### ステップ2: ツール仕様の確認(必須・スキップ不可)

このステップを省略すると100%失敗します。以下のファイルを必ずReadツールで読んでください：

**チェックリスト:**
- [ ] TOOLS.mdを読んだ(Readツール使用)
- [ ] 使用する各ツールの型定義ファイル `servers/serena/[ツール名].ts` を読んだ(Readツール使用)
- [ ] パラメータ名が型定義と完全に一致している
- [ ] 戻り値の型が型定義と完全に一致している
- [ ] 型アサーション(`as`)を使用していない(型定義から自動推論される)

上記すべてにチェックが入るまでステップ3に進まないでください。

### ステップ3: TypeScript スクリプトの生成

`src/` ディレクトリに適切な名前の TypeScript ファイルを作成してください：

```typescript
import { /* 必要なツールのみ */ } from '../servers/serena/index.js';
import { closeClient } from './client.js';

async function main() {
  try {
    // ここにロジックを実装
    // - 必要なツールのみインポート
    // - コード内でデータをフィルタリング
    // - 最終結果のみ console.log()

  } catch (error) {
    if (error instanceof Error) {
      console.error('エラー:', error.message);
    }
  } finally {
    await closeClient();  // 必須
  }
}

main();
```

**重要**:
- 必要なツールのみをインポート(全20ツールではなく)
- **TOOLS.mdで確認した正確な型定義を使用**
- データ処理はコード内で実施(filter、map、reduce)
- 最終結果のみを `console.log()` で出力
- 必ず `await closeClient()` を呼び出す

### ステップ4: スクリプトの実行

```bash
bun run src/your-script.ts
```

### ステップ5: 結果の報告

スクリプトの出力から最終結果のみをユーザーに報告してください。中間データや処理の詳細は報告しないでください(プライバシー保護のため)。

**エラーが発生した場合**:
- 型エラー: TOOLS.mdと型定義を再確認
- 実行時エラー: パラメータの形式とツールの存在を確認

## 利用可能なツール

全20の Serena MCP ツールが利用可能です。詳細は [TOOLS.md](TOOLS.md) を参照してください。

**主要なツール**:
- `listDir`, `findFile`, `searchForPattern` - ファイル操作
- `getSymbolsOverview`, `findSymbol` - コード解析
- `replaceSymbolBody`, `renameSymbol` - コード編集

インポート例：
```typescript
import { listDir, findFile, getSymbolsOverview } from '../servers/serena/index.js';
```

## 基本的な使用例

### 例: エクスポートされたクラスを持つファイルを検索

```typescript
import { listDir, getSymbolsOverview } from '../servers/serena/index.js';
import { closeClient } from './client.js';

async function main() {
  try {
    const result = await listDir({ relative_path: 'src', recursive: true });
    const tsFiles = result.files.filter(f => f.endsWith('.ts'));

    const filesWithClasses = [];
    for (const file of tsFiles) {
      const symbols = await getSymbolsOverview({ relative_path: file });
      if (symbols.some(s => s.kind === 5)) {  // kind 5 = クラス
        filesWithClasses.push(file);
      }
    }

    console.log(`クラスを含むファイル: ${filesWithClasses.join(', ')}`);
  } catch (error) {
    if (error instanceof Error) {
      console.error('エラー:', error.message);
    }
  } finally {
    await closeClient();
  }
}

main();
```

**効果**: 1000ファイルの処理でも、最終結果のみが LLM に到達(トークン削減: 99%以上)

さらに詳しい例は [EXAMPLES.md](EXAMPLES.md) を参照してください。

## 必須事項

### 1. closeClient() を必ず呼び出す

```typescript
finally {
  await closeClient();  // スクリプトの最後に必ず
}
```

### 2. .js 拡張子を使用

```typescript
import { listDir } from '../servers/serena/index.js';  // ✓ 正しい
import { listDir } from '../servers/serena/index';     // ✗ 間違い
```

### 3. エラーハンドリング

```typescript
try {
  // ツール呼び出し
} catch (error) {
  console.error('エラー:', error.message);
} finally {
  await closeClient();
}
```

## 主な利点

| 利点 | 説明 |
|------|------|
| **トークン削減** | 最大 98.7% のトークン削減 |
| **オンデマンドロード** | 必要なツールのみインポート |
| **データフィルタリング** | LLM が見る前に処理 |
| **プライバシー保護** | 機密データがコード内に留まる |

## さらに詳しい情報

- **全ツールリスト**: [TOOLS.md](TOOLS.md)
- **詳細な使用例**: [EXAMPLES.md](EXAMPLES.md)
- **技術詳細**: [REFERENCE.md](REFERENCE.md)

## 参考

このスキルは Anthropic の推奨アプローチに基づいています:
[Code execution with MCP: building more efficient AI agents](https://www.anthropic.com/engineering/code-execution-with-mcp)
````

## 付録B、TOOLS.md

````md TOOLS.md
## 利用可能なツール

自動生成された TypeScript ラッパーを通じて、全 20 の Serena MCP ツールが利用可能です。

すべてのツールは `servers/serena/index.ts` からインポートできます：

```typescript
import { listDir, findFile, getSymbolsOverview } from '../servers/serena/index.js';
```

## ファイル操作

### `listDir(input)`
ファイルとディレクトリの一覧を取得します。

**入力例:**
```typescript
await listDir({
  relative_path: 'src',
  recursive: true
});
```

### `findFile(input)`
パターン/マスクでファイルを検索します。

**入力例:**
```typescript
await findFile({
  file_mask: '*.ts',
  relative_path: 'src'
});
```

### `searchForPattern(input)`
ファイル内の正規表現パターンを検索します。

**入力例:**
```typescript
await searchForPattern({
  substring_pattern: 'export.*function',
  relative_path: 'src/index.ts'
});
```

## シンボル操作

### `getSymbolsOverview(input)`
ファイル内のトップレベルシンボルを取得します。

**用途:** ファイルの構造を理解する、エクスポートされた関数/クラスを検索

**入力例:**
```typescript
await getSymbolsOverview({
  relative_path: 'src/index.ts'
});
```

### `findSymbol(input)`
シンボルを検索して本体を含む詳細を読み取ります。

**用途:** 特定の関数やクラスの実装を取得

**入力例:**
```typescript
await findSymbol({
  name_path: 'myFunction',
  relative_path: 'src/utils.ts'
});
```

### `findReferencingSymbols(input)`
シンボルへのすべての参照を検索します。

**用途:** リファクタリング前に影響範囲を確認

**入力例:**
```typescript
await findReferencingSymbols({
  name_path: 'oldName',
  relative_path: 'src/main.ts'
});
```

## コード編集

### `replaceSymbolBody(input)`
シンボルの実装を置換します。

**用途:** 関数やメソッドの本体を書き換え

**入力例:**
```typescript
await replaceSymbolBody({
  name_path: 'myFunction',
  relative_path: 'src/utils.ts',
  body: 'return "new implementation";'
});
```

### `insertAfterSymbol(input)`
シンボルの後にコードを挿入します。

**用途:** 新しいメソッドや関数を既存コードの後に追加

**入力例:**
```typescript
await insertAfterSymbol({
  name_path: 'existingFunction',
  relative_path: 'src/utils.ts',
  body: 'function newFunction() { ... }'
});
```

### `insertBeforeSymbol(input)`
シンボルの前にコードを挿入します。

**用途:** インポート文の追加、前置き関数の追加

**入力例:**
```typescript
await insertBeforeSymbol({
  name_path: 'mainFunction',
  relative_path: 'src/index.ts',
  body: 'import { helper } from "./helper";'
});
```

### `renameSymbol(input)`
コードベース全体でシンボルの名前を変更します。

**用途:** リファクタリング、変数・関数名の統一

**入力例:**
```typescript
await renameSymbol({
  name_path: 'oldName',
  relative_path: 'src/main.ts',
  new_name: 'newName'
});
```

## メモリ操作

### `writeMemory(input)`
後で使う情報を保存します。

**用途:** セッション間で情報を保持、学習内容の蓄積

**入力例:**
```typescript
await writeMemory({
  memory_file_name: 'project-structure',
  content: '{ "src": "source files", "tests": "test files" }'
});
```

### `readMemory(input)`
以前保存した情報を取得します。

**入力例:**
```typescript
await readMemory({
  memory_file_name: 'project-structure'
});
```

### `listMemories(input)`
保存されたすべてのメモリを一覧します。

**用途:** 保存された情報の確認

**入力例:**
```typescript
await listMemories({});
```

### `deleteMemory(input)`
メモリを削除します。

**入力例:**
```typescript
await deleteMemory({
  memory_file_name: 'obsolete-key'
});
```

## メタツール

### `initialInstructions(input)`
Serena の使用方法を取得します。

**用途:** Serena MCP の基本的な使い方を確認

### `checkOnboardingPerformed(input)`
オンボーディング状態を確認します。

### `onboarding(input)`
Serena オンボーディングを実行します。

### `thinkAboutCollectedInformation(input)`
収集したデータを振り返ります。

**用途:** タスク完了前の情報整理

### `thinkAboutTaskAdherence(input)`
タスクの整合性を確認します。

**用途:** 元のタスク要件との一致を検証

### `thinkAboutWhetherYouAreDone(input)`
完了チェックを行います。

**用途:** タスク完了の判断

## 型定義

すべてのツールには MCP スキーマから自動生成された TypeScript 型があります。

詳細な型定義は `servers/serena/*.ts` ファイルを確認してください。

**例:**
```typescript
type ListDirInput = {
  relative_path: string;
  recursive: boolean;
  skip_ignored_files?: boolean;
  max_answer_chars?: number;
};
```

## 重要な注意事項

- インポートには `.js` 拡張子を使用: `from '../servers/serena/index.js'`
- スクリプトの最後に必ず `await closeClient()` を呼び出してください

````
    