📚
[Cline] Memory Bank を一括読み込みする MCP を作ってみた
TL;DR
- Cline の Memory Bank は複数ファイルの読み込みが必要で、毎チャット5回程度のチャットのラリーが発生する
- MCP で簡単なツールを作り、一回のやり取りで前ファイルの読み込みが可能になった。
- MCP は一種の Custom Instructions のようにも使える
課題
Cline で Memory Bank という、Cline にプロジェクトの知識を外部化して持たせるプラクティスがあるが、これをやっていると毎回チャットの初めにファイルの読み込みためのラリーが発生してしまいます。
これは Cline が使える read_file
というツールが単一のファイル読み込みで、かつ、Cline は一回のチャットのラリーで一つのツールを一回しか使えないからです。
解決策
そこで今回は MCP で Memory Bank の一括読み込み用のツールを作ることで、このやりとりが一回で済むように作ってみました。
このスクリーンショットのように、チャットの一番初めに MCP を使って一括で Memory Bank のファイルを読み込んでくれるようになりました。
コード例
複雑なことはやっていませんがコード例を載せておきます。Deno で fastmcp を使って書いてます。
#!/usr/bin/env deno run --allow-read
import * as fs from "node:fs/promises";
import * as path from "node:path";
import { FastMCP } from "npm:fastmcp@1.20.5";
import { z } from "npm:zod@3.24.2";
// MCPサーバー設定
const server = new FastMCP({
name: "Memory Bank Loader",
version: "1.0.0",
});
// ツール定義
server.addTool({
name: "get_memory_bank",
description:
"指定されたメモリーバンク用のディレクトリ(絶対パス指定)のファイルをすべて読み込み、一つの文字列として返す",
parameters: z.object({
directory: z.string().optional(), // ディレクトリのみのパラメータ
}),
execute: async (params) => {
try {
// パラメータで指定されたディレクトリか、デフォルト値を使用
const memoryBankDir = params.directory;
if (!memoryBankDir) {
throw new Error("ディレクトリが指定されていません");
}
const contents: string[] = [];
// ディレクトリ内のファイル一覧を取得
const files = await fs.readdir(memoryBankDir);
// ファイルリストを保持する配列
const fileList = [];
// ファイルの内容を読み込む
for (const filename of files) {
try {
const filePath = path.join(memoryBankDir, filename);
// ファイルの情報を取得
const stat = await fs.stat(filePath);
// ディレクトリの場合はスキップ
if (stat.isDirectory()) {
continue;
}
// ファイルリストに追加
fileList.push(filename);
const content = await fs.readFile(filePath, "utf-8");
contents.push(`# ${filePath}\n\n${content}\n\n---\n\n`);
} catch (fileError) {
console.error(`Error reading file ${filename}:`, fileError);
contents.push(
`# ${filename}\n\n**ファイルの読み込みに失敗しました**\n\n---\n\n`,
);
}
}
return JSON.stringify({
contents: contents.join(""),
files: fileList,
});
} catch (error) {
console.error("Error in get_memory_bank:", error);
return JSON.stringify({
error: "メモリーバンクファイルの読み込みに失敗しました",
message: error instanceof Error ? error.message : String(error),
});
}
},
});
// サーバー起動
server.start({
transportType: "stdio",
});
console.info("Memory Bank Loader MCP サーバーが起動しました");
まとめ
Cline などの AI 開発エージェントは、 read_file
などの汎用的なツールを持っていますが、ある程度作業のフローが固定化した時に Memory Bank の読み込みのように非効率になる場合があります。
今回追加した Memory Bank Loader は実質 read_file
を一括で読んでいるだけに過ぎませんが、Cline に「Memory Bank Loader とい MCP が存在する」と伝えることで、効率的に作業してもらえるようになりました。実質 MCP を作業フローの Custom Instructions として活用したような気がしてます。こういう手法もアリかも
Discussion