はじめに
Claude DesktopでModel Context Protocol (MCP)を使うと、ローカルファイルの操作ができて便利ですよね。公式のfilesystem serverを使っていたのですが、いくつか不満点がありました。
特に大きなファイルを読むときのトークン消費が激しくて...そこで、より実用的なMCPサーバーを作って公開しました。
公式filesystem serverの課題
1. トークン爆発問題 💥
こんな経験ありませんか?
私: このプロジェクトの依存関係を確認して
Claude: package.jsonとpackage-lock.jsonを確認しますね。
[package.jsonを読む]
[package-lock.jsonを読む]
// 結果: 333KBのpackage-lock.json全体が返ってきて...
Claude: package.jsonの内容は...
package-lock.jsonの内容は以下の通りです:
{
"name": "my-project",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "my-project",
[... 延々と333KB分のJSON ...]
}
}
[... まだまだ続く ...]
}
私: ちょっと待っ(会話のコンテキストが満杯になり強制終了)
実際のトークン消費:
- package.json (3KB) → 約750トークン ✅
- package-lock.json (333KB) → 約85,000トークン 💀
- 合計: 約85,750トークン(コンテキストウィンドウの大部分を消費)
特に困るのは、AIが「念のため関連ファイルも確認しますね」と親切心で大きなファイルを読んでしまうケース。ログファイルやビルド成果物を読まれた日には...
2. 検索機能が限定的 🔍
// TODOコメントを探したい
> search("TODO") // → 単純な文字列検索のみ
// 正規表現使いたい
> search("/TODO|FIXME/") // → 使えない😢
開発中は正規表現でコードを検索したいことが多いんですよね。
Smart Filesystem MCPで解決したこと
📊 スマートなファイル読み取り
20KB以下のファイル → そのまま返す(普通の動作)
// 設定ファイルなど小さなファイル
await read_file({ path: "/path/to/config.json" })
// ✅ 通常通り内容が返る
20KBを超えるファイル → 自動的にプレビューモード
// 333KBのpackage-lock.json
await read_file({ path: "/path/to/package-lock.json" })
// 🎯 返ってくる内容:
{
"success": false,
"error": {
"code": "size_exceeded",
"message": "ファイルサイズが制限を超えています",
"file_info": {
"size": 341504,
"size_display": "333.50 KB",
"estimated_tokens": 85376
},
"preview": {
"first_lines": "最初の50行のプレビュー...",
"content_summary": "package-lock.json with 2500+ dependencies"
},
"alternatives": {
"force_read_available": false, // 256KBを超えているため不可
"suggestions": [
"ファイルが256KBを超えているため、read_file_forceでも読み取れません",
"特定の依存関係を検索するには search_content を使用"
]
}
}
}
256KB以下のファイルならread_file_forceで読み取れます:
// 100KBのログファイル
await read_file_force({
path: "/path/to/app.log",
acknowledge_risk: true
})
// ✅ 256KB以下なので全文取得可能
🔍 強力な正規表現検索
// テストファイルを探す
await search_content({
file_pattern: ".*\\.test\\.ts$",
directory: "/path/to/src"
})
// TODOコメントを検索(正規表現)
await search_content({
content_pattern: "TODO|FIXME|HACK",
directory: "/path/to/project",
extensions: [".js", ".ts"],
max_matches_per_file: 10
})
// 複合検索も可能
await search_content({
file_pattern: "config", // ファイル名に"config"を含む
content_pattern: "database.*url", // かつ database...url パターンを含む
case_sensitive: true
})
🛡️ 安全性も考慮
- サンドボックス化: 指定したディレクトリのみアクセス可能
-
パストラバーサル防止:
../などの攻撃を防ぐ - 削除のドライラン: 誤削除を防ぐプレビュー機能
インストールと設定
1. インストール不要!npxで即使える
# グローバルインストール不要
npx @zio3/smart-fs-mcp
2. Claude Desktop設定
設定ファイルの場所:
-
macOS:
~/Library/Application Support/Claude/claude_desktop_config.json -
Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"smart-fs-mcp": {
"command": "npx",
"args": [
"@zio3/smart-fs-mcp",
"/path/to/project1",
"/path/to/project2"
]
}
}
}
実際の使用例
例1: コードレビュー
私: このプロジェクトのTODOコメントを全部リストアップして
Claude: search_contentを使って検索しますね。
[検索実行]
以下のTODOコメントが見つかりました:
src/api/server.ts (3件):
- Line 45: "TODO: Add rate limiting"
- Line 89: "TODO: Implement caching"
- Line 156: "TODO: Add authentication"
src/core/file-handler.ts (2件):
- Line 23: "TODO: Support streaming for large files"
- Line 67: "TODO: Add progress callback"
例2: ログファイルの調査
私: error.logの最近のエラーを確認して
Claude: ファイルサイズを確認します...
ファイルが127KBあるため、プレビューを表示します:
[最初の50行]
2024-01-15 10:23:45 ERROR: Connection timeout
2024-01-15 10:24:12 ERROR: Database connection failed
2024-01-15 10:24:13 ERROR: Retry attempt 1/3
...
ファイル全体には約500件のエラーログがあるようです。
特定のエラーを検索したい場合は、search_contentで絞り込めます。
例3: ファイルの編集
// シンプルな置換
await edit_file({
path: "/path/to/config.js",
edits: [{
type: "literal",
old_text: "const PORT = 3000",
new_text: "const PORT = 8080"
}]
})
// 正規表現での一括置換
await edit_file({
path: "/path/to/utils.js",
edits: [{
type: "regex",
pattern: "console\\.log",
replacement: "logger.debug",
flags: "g"
}],
dry_run: true // まずはプレビュー
})
実装で工夫した点
1. シンプルファースト設計
- デフォルトで「うまくいく」ように
- 必要な時だけ複雑さが現れる
- ほとんどの操作が1コマンドで完了
2. 統一エラーハンドリング
// すべてのエラーが統一された形式
{
"success": false,
"error": {
"code": "file_not_found",
"message": "ファイルが見つかりません",
"details": { "path": "/path/to/file" },
"suggestions": ["パスを確認してください"]
}
}
3. LLMファーストな開発アプローチ
このツール最大の特徴は、LLM自身と対話しながら開発したことです。
私: read_fileでサイズ超過エラーが出た時のレスポンス、使いやすい?
Claude: 現在のエラーメッセージだと次のアクションが分かりにくいですね。
以下のような改善案はどうでしょう:
1. プレビューを含める(最初の数行を見せる)
2. ファイルの種類を推定して表示
3. 代替手段を具体的に提示(force_readの存在を明示)
私: なるほど!じゃあこんな感じで実装してみる
[実装]
Claude: [新しいAPIを試して]
いいですね!ただ、estimated_tokensも表示してもらえると、
force_readするかどうかの判断材料になります。
私: 確かに!修正した
LLMとの開発ループで得られた改善点:
- エラーメッセージの改善: 「次に何をすべきか」を明確に
- プレビュー機能: 「とりあえず最初だけ見たい」ニーズに対応
- トークン数表示: 判断材料として重要
- 段階的な情報開示: 必要な情報だけを必要な時に
実際、このツールの「20KBでプレビュー、256KB上限」という仕様も、LLMとの対話で決まりました:
Claude: 1MBまで読めるようにすると、うっかり大きなファイルを
読んでしまった時のダメージが大きいです。
私: じゃあどのくらいが適切?
Claude: 256KB(約64kトークン)くらいが実用的な上限では?
それ以上はどうせコンテキストに入りきらないし、
部分的に読むなら search_content の方が効率的です。
LLM自身が使うツールだからこそ、LLMの意見を聞きながら作る。
これが一番の工夫点でした。
パフォーマンス比較
| ファイルサイズ | 公式版 | Smart FS MCP |
|---|---|---|
| 10KB | 全文返却 | 全文返却 |
| 100KB | 全文返却(25kトークン消費) | プレビュー表示 + force_read可(256KB上限) |
| 1MB | 全文返却(250kトークン消費) | プレビュー表示のみ(256KB制限で読取不可) |
今後の展望
- ストリーミング対応(巨大ファイルの部分読み取り)
- ファイル監視機能
- より高度なコード解析
- 他のMCPクライアントでのテスト
まとめ
Claude Desktopでファイル操作をする際の「かゆいところに手が届く」ツールを目指しました。
- 🎯 トークン消費を抑制 - 大きなファイルは自動的にプレビュー
- 🔍 正規表現検索 - 開発作業が効率的に
- 🛡️ 安全性重視 - サンドボックス化とドライラン機能
- 📦 簡単導入 - npxで即使える
ぜひ試してみてください!
リンク
- GitHub: https://github.com/zio3/smart-fs-mcp
- npm: https://www.npmjs.com/package/@zio3/smart-fs-mcp
- 公式MCP仕様: https://modelcontextprotocol.io
フィードバックや機能要望はGitHub Issuesまでお願いします!