Octofs について
Octofsは、ローカルやSSH/SFTP上のファイルを扱う、コーディングエージェント向けの単体Rust製MCPサーバーです。ファイル編集、シェル実行、作業ディレクトリ管理に加え、行ハッシュで古い内容への誤編集を防ぎます。
主な機能
- 01ファイルの読み取り、一覧表示、検索
- 02ファイルの作成、編集、変更の取り消し
- 03古い書き込みを検査する一括編集
- 04シェル実行と作業ディレクトリ管理
- 05SSH/SFTP経由のファイル操作
- 06STDIOとStreamable HTTPに対応
活用シーン
- 01プロジェクト構成の確認とコード検索
- 02ソースファイルへの複数変更
- 03リモートホスト上のファイル操作
- 04MCPクライアントからのプロジェクトコマンド実行
MCP 対応
MCPクライアントにファイルシステム、編集、シェル、作業ディレクトリのツールを提供します。STDIOとStreamable HTTPに対応しています。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
🐙 Octofs
AI アシスタントにファイルシステムの強力な機能を
Model Context Protocol 経由でファイルシステムツールを公開する、単体で動作する Rust バイナリです。rmcp 3.x、tokio、axum を基盤としています。
インストール · クイックスタート · 機能 · ツールリファレンス · ドキュメント · アーキテクチャ · 変更履歴 · コントリビューション · 初めての方におすすめの課題
MCP レジストリ:io.github.Muvon/octofs
Octofs が選ばれる理由
AI コーディングアシスタント(Cursor、Claude、Windsurf など)は賢いものの、ファイルシステムを見ることができません。Octofs がその隔たりを埋め、AI に次の機能を提供します。
- 目 — ファイルの読み取り、内容の検索、ディレクトリの調査
- 手 — ファイルの作成、編集、一括変更をアトミックに実行
- コンテキスト — コマンドの実行、作業ディレクトリの管理
- 接続性 — 透過的な SSH/SFTP:すべてのファイルツールで
ssh://URL を利用可能
┌─────────────────────────────────────────────────────────────┐
│ You: "Refactor all error handling to use anyhow::Context" │
├─────────────────────────────────────────────────────────────┤
│ AI without Octofs: │
│ • "I can't see your project structure" │
│ • "Please paste the relevant files" │
│ • *Wastes 10 minutes on back-and-forth* │
├─────────────────────────────────────────────────────────────┤
│ AI with Octofs: │
│ • Reads your codebase directly │
│ • Finds all error handling patterns │
│ • Suggests atomic batch edits │
│ • Applies changes with your approval │
└─────────────────────────────────────────────────────────────┘
他との違い
| 機能 | Octofs | 一般的な代替ツール |
|---|---|---|
| 実装 | ランタイム不要のコンパイル済み Rust バイナリ | Python/Node スクリプト |
| コンテンツ検索 | 前後の行を含む組み込み検索 | 文字列の照合のみ |
| 一括操作 | 1 つのファイルに対するアトミックな複数編集 | 1 回に 1 件 |
| 行の指定 | 複合 N:hh ID — 適用時にハッシュを検証し、古い編集は移動先のヒントを示して失敗 | 行番号のみ |
| トランスポート | STDIO + Streamable HTTP | STDIO のみ |
| シェル連携 | フォアグラウンドからバックグラウンドへの自動切り替え | 限定的、またはなし |
| リモートファイル | すべてのファイルツールで透過的な SSH/SFTP | なし |
| 再読み込み | 差分表示 — ファイルを再表示すると、コンテキストエポックを報告するクライアントでは、前回以降に変更されたハンクのみを返します | 毎回ファイル全体 |
| 安全性 | Gitignore 対応、古い書き込みの検出、パス検証 | ファイルシステム全体へのアクセス |
インストール
Cargo(crates.io)
cargo install octofs
Homebrew
brew install muvon/tap/octofs
npm(Rust ツールチェーン不要)
npx -y @muvon/octofs --version
ラッパーは初回実行時に、対応するビルド済みバイナリをダウンロードします。MCP の設定:
{
"mcpServers": {
"octofs": {
"command": "npx",
"args": ["-y", "@muvon/octofs", "mcp"]
}
}
}
ビルド済みバイナリ
お使いのプラットフォーム向けのバイナリを GitHub Releases からダウンロードしてください。
| プラットフォーム | ターゲット |
|---|---|
| Linux(x86_64) | x86_64-unknown-linux-musl |
| Linux(ARM64) | aarch64-unknown-linux-musl |
| Windows(x86_64) | x86_64-pc-windows-msvc |
| Windows(ARM64) | aarch64-pc-windows-msvc |
| macOS(Intel) | x86_64-apple-darwin |
| macOS(Apple Silicon) | aarch64-apple-darwin |
各リリースには、MCP バンドルに対応するクライアント(Claude Desktop など)でワンクリックインストールできる .mcpb バンドルも含まれています。
MCP レジストリ
MCP Registry に io.github.Muvon/octofs として公開されています。
ソースからのビルド
Rust 1.95+ が必要です。
git clone https://github.com/muvon/octofs
cd octofs
cargo build --release
# Binary at ./target/release/octofs
クイックスタート
1. AI アシスタントを設定する
CLI は mcp サブコマンドを使用するため、設定で引数として ["mcp"] を渡す必要があります。
Cursor(~/.cursor/mcp.json):
{
"mcpServers": {
"octofs": {
"command": "octofs",
"args": ["mcp"]
}
}
}
Claude Desktop(macOS の場合は ~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"octofs": {
"command": "octofs",
"args": ["mcp"]
}
}
}
Windsurf(~/.windsurf/mcp.json):
{
"mcpServers": {
"octofs": {
"command": "octofs",
"args": ["mcp"]
}
}
}
Octofs が
PATHにない場合は、バイナリへのフルパス(例:/usr/local/bin/octofsまたは./target/release/octofs)を使用してください。
2. AI アシスタントを再起動する
AI アシスタントが接続すると、MCP サーバーが自動的に起動します。
3. 試してみる
AI アシスタントに次のように依頼してください。
- 「プロジェクトの構造を表示して」
- 「main.rs ファイルを読んで」
- 「コードベース内で
unwrap()が使われている箇所をすべて検索して」 - 「
test.rsという新しいファイルを作成して」
機能
📁 ファイルシステム操作
- ファイルとディレクトリの表示 — 単一ファイルを読み取る(複数の場合は
viewを並列で呼び出します)、glob パターンでディレクトリを一覧表示する、コンテンツを検索する - スマートな切り捨て — コンテキストウィンドウが大きなファイルで圧迫されないよう、適切に切り捨てます
- Gitignore 対応 — ディレクトリの走査時に
.gitignoreパターンを尊重します - 行範囲 — 負のインデックス(
-1= 最終行)を使って特定の行範囲を読み取ります - リモートファイル(SSH/SFTP) — すべてのファイルツールで
ssh://user@host:port/pathURL を使用できます(リモートファイルシステムを参照)
✏️ テキスト編集
- ファイルの作成 — 親ディレクトリを自動的に作成して、新しいファイルを作成します
- 文字列の置換 — 空白文字のあいまい一致によるフォールバック付きで、完全一致する文字列を置換します
- 削除 — ファイルを削除します(undo で復元できます)
- 取り消し — 最後の編集を元に戻します(ファイルごとに最大 10 段階、メモリ内)
- 一括編集 — 1 つのファイルに対する複数の挿入/置換操作をアトミックに実行します
- 古い書き込みの保護 — 編集対象の
N:hhID は適用時にファイルと照合されます。ID が古い場合、誤った行を編集する代わりに、現在の内容と移動先が返されます
🔍 コードインテリジェンス
- コンテンツ検索 — ファイル内の文字列を、前後の行とともに検索します
- 行の抽出 — 特定の行範囲を別のファイルにコピーします
🖥️ シェルとシステム
- コマンド実行 — 出力を取得しながらシェルコマンドを実行します
- バックグラウンドプロセス — 長時間実行されるコマンドは自動的にバックグラウンドで継続し、完了時に通知されます
- 作業ディレクトリ — 操作の作業ディレクトリのコンテキストを設定/取得/リセットします
設定
行識別子
各行は複合 ID N:hh で指定します。これは、1 から始まる行位置と、その内容の 2 文字の 16 進数ハッシュ(FNV-1a)を組み合わせたものです。view は行を N:hh|content として出力します。
1:a3|fn main() {
2:f1| println!("Hello");
3:0e|}
編集ツールはこれらの ID を対象として受け取り、適用前にファイルとハッシュを照合します。ID が古い(表示後にファイルが変更された)場合、対象の前後にある現在の内容と、期待した内容の移動先を返します。そのため、モデルはファイルを再読み込みする代わりに、エラーをもとに対象を指定し直せます。編集結果は新しい ID を含む差分なので、再表示せずに編集を続けられます。削除された行は以前の ID の範囲にまとめられ(-12:a3..15:f1 (4 lines))、末尾の shift: lines after 40:b2 +3 行には、各編集後に元の行番号がどのように移動したかが示されます。これにより、モデルが保持している ID を、呼び出しを失敗させることなく調整できます。
行 ID の形式はこれ 1 つだけで、モード切り替えはありません。位置だけで安全に扱える場合は、通常の行番号も引き続き使用できます。対象となるのは view の範囲指定(負の数は末尾から数えます)と、挿入位置のアンカー 0(ファイルの先頭)/-1(末尾に追加)です。
シェルの誤用の防止
Octofs は、専用の MCP ツールを使うべき cat、grep、find、sed などのコマンドによるシェルの誤用を検出し、使用すべきツールを説明するエラーを返して拒否します。呼び出しは失敗し、何も実行されません。これは意図された動作であり、設定で変更できません。専用ツールは、通常のシェル出力では得られない行 ID、gitignore の認識、リモートホストへの対応をモデルに提供するためです。パイプライン(cargo build 2>&1 | grep error)は引き続き使用できます。ブロックされるのは、これらのプログラムを単独で実行した場合のみです。
範囲外の指定やあいまい一致に関する通知など、その他のガイダンスは呼び出しを失敗させず、成功したレスポンスに ⚠️ ヒントとして追加されます。
トランスポートモード
STDIO(デフォルト)
標準入出力トランスポートです。すべての MCP クライアントで動作します。
octofs mcp
HTTP
リモートアクセスや複数クライアントでの利用に対応する、ストリーミング可能な HTTP トランスポートです。shell を含むすべてのツールに、接続できるユーザーなら誰でもアクセスできるため、アクセスは制限されています。
# Loopback, no token: requests carrying a browser Origin header are rejected
octofs mcp --bind 127.0.0.1:12345
# Any other address requires a bearer token; octofs refuses to start without one
OCTOFS_AUTH_TOKEN="$(openssl rand -hex 32)" octofs mcp --bind 0.0.0.0:12345
クライアントを http://localhost:12345/mcp に接続します。トークンを使用する場合は、Authorization: Bearer <token> を送信します。サーバーはプレーン HTTP を使用するため、トークンがネットワークを通過する場合は、TLS または SSH トンネルの背後に配置してください。--auth-token <TOKEN> も使用できますが、コマンドライン引数は他のローカルユーザーから見える状態になります。
作業ディレクトリ
デフォルトでは、Octofs は現在のディレクトリで動作します。別のルートを指定するには、次のようにします。
{
"mcpServers": {
"octofs": {
"command": "octofs",
"args": ["mcp", "--path", "/path/to/your/project"]
}
}
}
リモートファイルシステム(SSH/SFTP)
すべてのパスパラメーターと --path 自体に、ssh:// または sftp:// の URL を指定できます。
# Remote session root: relative paths resolve on the remote host
octofs mcp --path ssh://[email protected]/var/www/app --ssh-key ~/.ssh/id_ed25519
view path="ssh://[email protected]/etc/nginx/nginx.conf"
- ログインホーム —
ssh://host(パスなし)とssh://host/~/dirは、ssh host/scp host:dirと同様に、ログインユーザーのホームディレクトリを基準に解決されます。ssh://host/dirは絶対パスとして扱われます。 - OpenSSH の設定 — ホストのエイリアスは、ローカルの OpenSSH 設定(
IncludeとMatchを含む)を通じて解決され、HostName、User、Port、単一のProxyJumpが適用されます。URL に明示された値が優先されるため、ssh://dev/pathとssh://[email protected]:2222/pathはどちらも想定どおりに動作します。複数ホップのProxyJumpとProxyCommandによるルーティングは、明確なエラーを返して拒否されます。 - 認証 — ホストの
IdentityAgent(例:1Password)または$SSH_AUTH_SOCKを使用し、続いて鍵ファイルを使用します。鍵ファイルは、指定されている場合は--ssh-key、ホストのIdentityFileエントリー、次に~/.sshのデフォルト(id_ed25519、id_ecdsa)の順に確認されます。パスフレーズで保護された鍵ファイルは直接サポートされていません。代わりにエージェントを使用してください。 - RSA 鍵はサポートされていません — Rust の
rsaクレートには未修正のタイミングサイドチャネル脆弱性(Marvin 攻撃、RUSTSEC-2023-0071)があるため、octofs は RSA を完全に無効にしてビルドされています。代わりに ed25519 鍵(ssh-keygen -t ed25519)を使用してください。ecdsa も使用できます。RSA のみを使用する設定では、鍵の名前を含む明確なエラーが発生します。 - ホスト鍵 — OpenSSH の
accept-newポリシーに従い、~/.ssh/known_hostsと照合して検証されます。未知のホストは初回使用時に記録され、鍵が変更されている場合は接続が拒否されます。 --ssh-timeout SECS— 接続タイムアウト(デフォルトは 30 秒)です。接続はホストごとにプールされ、トランスポートのキープアライブによって維持されます。切断された場合は自動的に再接続されます。shellはローカルで動作します — コマンドは常に Octofs が動作しているマシン上で実行されます。リモートホストにアクセスするのはファイルツール(view、text_editor、batch_edit、extract_lines、workdir)のみです。
MCP ツールのリファレンス
view — ファイルの読み取り、ディレクトリの一覧表示、コンテンツの検索
ファイルの読み取り:(path は単一のパス、start/end は行番号または行 ID です)
{"path": "src/main.rs"} // whole file
{"path": "src/main.rs", "start": 10, "end": 20} // lines 10–20
{"path": "src/main.rs", "start": 42, "end": 42} // single line
{"path": "src/main.rs", "start": 80} // line 80 → end of file
{"path": "src/main.rs", "start": -20} // last 20 lines
{"path": "src/main.rs", "start": "12:a3", "end": "20:f1"} // line ids from prior output
出力では各行が N:hh|content の形式で表示されます。N:hh のプレフィックスは、batch_edit と extract_lines で対象として指定する行 ID です。
複数のファイルを読み取るには、view を複数回呼び出します。これらの呼び出しは並列で実行されます。
すでに返されたコンテンツと行 ID を再利用してください。関連する関数またはブロックは、隣接する範囲をまとめて、1 回の呼び出しで全体を読み取ります。場所が分からない場合は、一致箇所を理解するのに十分な context を指定して content を使い、その後、不足している周辺コードだけを取得します。重複する範囲を再度読み取ったり、編集対象を選ぶためだけに範囲を何度も絞り込んだりしないでください。ファイルが変更された可能性がある場合、出力が途中で切れていた場合、または以前のコンテキストを利用できない場合は、再度読み取ってください。空のファイルを初回または強制的に全体読み取りした場合は、[empty file, 0 lines] が返されます。
差分表示: すでにこのセッションで提供されたファイルを全体表示すると、変更されたハンクのみが返されます。編集結果と同じ .../-/+ 形式で、削除された行は元の ID 範囲にまとめられます。または、[unchanged since you last viewed or edited it: N lines. Pass full: true to re-read.] が返されます。Octofs 自身による編集ではキャッシュが最新に保たれるため、自分で batch_edit した後の再表示は 1 行分のコストで済みます。範囲指定の表示とコンテンツ検索では、指定された内容がそのまま表示されます。full は範囲指定や検索には影響しません。ファイル全体を強制的に読み取るには、start/end を省略し、コンテンツ検索を指定しないでください。出力制限は変更されません。
{"path": "src/main.rs", "full": true} // force the complete file (e.g. after context compaction)
ディレクトリの一覧表示:
{"path": "src/"}
{"path": "src/", "pattern": "*.rs"}
{"path": "src/", "max_depth": 2, "include_hidden": true}
リモートディレクトリ(ssh://host/path、pattern/content なし)をそのまま一覧表示すると、各サブディレクトリの確認に SFTP の往復が必要なため、デフォルトでは max_depth: 1(ルート直下のエントリのみ)になります。さらに深い階層をたどるには、max_depth を明示的に指定してください。pattern または content を使った検索では、rg と同様に常にツリー全体をたどります。
pattern は、ripgrep の -g/--glob と同じ gitignore 形式の glob 文法を使います。/ を含まない場合は、どの階層のファイル名にも一致します。/ を含むパターンは、返される相対パスに一致します。1 つのパス要素内の *、ディレクトリをまたぐ **、?、[abc] のような文字クラス、*.{rs,toml} のような波括弧による選択肢、および先頭の ! による除外をサポートします。1 つの MCP 文字列で順序付きの glob を渡すには | を使います。後の glob が優先されます。
{"path": ".", "pattern": "**/*.{rs,toml}|!target/**"}
{"path": ".", "content": "unsafe", "pattern": "src/**/*.rs|!src/generated/**"}
glob は、Octofs の gitignore 対応トラバーサルで検出されたファイルをフィルタリングします。隠しパスを含めるには include_hidden: true を指定してください。gitignore で除外されたパスは引き続き除外されます。パターンの上限は UTF-8 で 4096 バイト、| で区切られたルールが 64 個、波括弧のネストが 16 階層です。パターンは 1 行で指定し、トラバーサルの前に検証されます。先頭の # または ! を文字として扱うには \# または \! としてエスケープしてください。そうしないと、# は gitignore のコメントとして黙って処理されるのではなく、拒否されます。ripgrep がサポートしていないため、{,rs} のような空の選択肢を含む波括弧は拒否されます。
コンテンツ検索:(デフォルトではリテラル検索です。Rust の正規表現を使うには regex: true を設定します。(?i) は大文字と小文字を区別しない指定です)
{"path": "src", "content": "fn main"}
{"path": "src", "content": "unwrap()", "context": 3}
{"path": "src", "content": "(?i)error", "regex": true}
{"path": "docs|scripts|BENCHMARK.md", "content": "update_benchmark.py", "context": 4}
複数のルートを対象に rg 形式の検索を行う場合、content が設定されていれば、path に | で区切ったリテラルのファイルとディレクトリを指定できます。ルートは正規表現ではありません。rg の位置引数のパスと同様、それぞれが存在している必要があります。実際のパスに | が含まれている場合は、この省略記法よりも実際のパスが優先されます。ルートのリストは 1 行で指定し、重複を含めることはできません。上限は 32 個のルート、UTF-8 で 8192 バイトです。
ディレクトリ一覧では、各ファイルに path<TAB>NL<TAB>~Nt(行数+推定トークン数)の形式で注釈が付き、ファイルを開く前に読み取り量を見積もれます。バイナリファイルは path<TAB>(binary) と表示されます。
text_editor — テキストの作成、編集、置換
ファイルを作成:
{"command": "create", "path": "src/new.rs", "content": "pub fn new() {}"}
文字列を置換:(old_text は完全に一致するものが1つである必要があります)
{
"command": "str_replace",
"path": "src/main.rs",
"old_text": "fn old()",
"new_text": "fn new()"
}
すべての出現箇所を置換(名前変更のような編集):
{
"command": "str_replace",
"path": "src/main.rs",
"old_text": "old_name",
"new_text": "new_name",
"replace_all": true
}
照合は段階的に行われます:完全一致 → エスケープ済みリテラルの復元(二重エスケープされた \n/\t は、結果が一意に一致する場合に解釈)→ インデント調整を伴う空白正規化済みのあいまい照合 → 最も近い候補とその行 ID を示す詳細な診断。CRLF ファイルは LF として照合され、書き込み時には行末コードが維持されます。
ファイルを削除:(undo_edit で復元可能)
{"command": "delete", "path": "src/old.rs"}
最後の編集を元に戻す:
{"command": "undo_edit", "path": "src/main.rs"}
batch_edit — 複数操作の一括編集
1つのファイルに対して、複数の挿入/置換操作をアトミックに実行します。
各操作には start が必要です。replace の場合、これは view の出力からコピーした範囲の先頭行の行 ID です(範囲を指定する場合は end を追加し、1行だけの場合は省略します)。insert の場合、これは挿入位置となる行 ID、または整数 0(ファイルの先頭)/-1(最後の行の後)です。適用前にすべての ID がファイルと照合されます。古い ID が含まれている場合は、モデルが再度表示を取得せずに挿入先を変更できるよう、現在の内容とともに失敗します。結果は、新しい ID を含む差分です。
先頭に挿入:
{
"path": "src/main.rs",
"operations": [
{"operation": "insert", "start": 0, "content": "// Header\n"}
]
}
行を置換:
{
"path": "src/main.rs",
"operations": [
{"operation": "replace", "start": "10:4b", "end": "15:c2", "content": "new code here"}
]
}
extract_lines — ファイル間で行をコピー
{
"from_path": "src/utils.rs",
"from_start": 10,
"from_end": 25,
"append_path": "src/new.rs",
"append_line": -1
}
from_end は省略可能です(省略すると1行だけコピーします)。from_start、from_end、append_line はそれぞれ、行番号または行 ID("12:a3"。ファイルと照合されます)を指定できます。append_line はコピー先での位置を指定します:0 =先頭、-1 =末尾、N =N行目の後。
shell — コマンドを実行
コマンドはフォアグラウンドで開始され、約10秒以内に完了すると、通常どおり出力を返します:
{"command": "cargo test"}
{"command": "cd foo && cargo build"}
その時点でコマンドがまだ実行中の場合、同じプロセスがバックグラウンドで実行を続けます。応答にはその PID と出力リソースへのリンクが含まれ、終了時に完了通知が届きます。background フラグはなく、引き継ぎ中にコマンドが強制終了されたり再起動されたりすることはありません。同じ作業ディレクトリからも、複数の異なるコマンドを同時に実行できます。同じ作業ディレクトリで実行中のコマンドと完全に重複するコマンドは、最初のコマンドが実行中の間は拒否されます。
MCP tasks 拡張機能(io.modelcontextprotocol/tasks、SEP-2663)を宣言するクライアントには、バックグラウンドに移行したコマンドが、ジョブ ID を ID とするタスクとして返されます。クライアントは tasks/get をポーリングし、フォアグラウンド呼び出しで返されるものと同じ結果を受け取ります(コマンドが失敗した場合は、終了コードから始まるエラー結果)。tasks/cancel はコマンドのプロセスグループを停止します。コマンドの実行中、タスクのステータスメッセージには PID と強制終了コマンド(kill -- -<pid>)、経過時間、最新の出力行が表示されます。
その他のクライアントには、ジョブリソースに対する resources/updated として完了通知が届きます(クライアントが subscriptions/listen ストリームを開いている場合)。Claude Code はこれをモデルに表示しないため、2026-07-28 より前の接続では、octofs は Claude Code のチャネルメッセージ(notifications/claude/channel)としても送信します。終了コードと出力末尾によって、セッションが再開されます。Claude Code がチャネルメッセージを受け付けるのは、そのセッションで有効になっているサーバーから、インタラクティブモードで、かつ2026-07-28より前の接続の場合のみです。Claude Code はデフォルトで stdio サーバーとの接続に2026-07-28をネゴシエートするため、tasks 拡張機能を宣言するまでは、次の設定も無効にしてください:
MCP_PROTOCOL_NEGOTIATION=legacy claude --dangerously-load-development-channels server:octofs
この設定がない場合、結果が必要になったらジョブのリソースリンクを読み取ってください。
Windows では、シャットダウン時のクリーンアップで終了するのは直接の子プロセスのみです(Unix のプロセスグループのセマンティクスには対応していません)。プロセスツリーを終了するには
taskkill /PID <pid> /Tを使用してください。
workdir — 作業ディレクトリを管理
現在のディレクトリを取得:
{}
新しいディレクトリを設定:
{"path": "/path/to/project"}
セッションルートに戻す:
{"reset": true}
アーキテクチャ
octofs/
├── src/
│ ├── main.rs # Entry point, STDIO/HTTP server setup, signal handling
│ ├── cli.rs # CLI argument parsing (clap): octofs mcp [OPTIONS]
│ ├── mcp/
│ │ ├── mod.rs # McpToolCall, SessionRoot
│ │ ├── server.rs # OctofsServer (rmcp tool impl), Params structs, SessionWorkdir
│ │ ├── request_ctx.rs # Per-request hint queue + stale-file stamps
│ │ └── fs/ # Filesystem tool implementations
│ │ ├── mod.rs # Re-exports
│ │ ├── core.rs # view, text_editor, batch_edit, extract_lines
│ │ ├── file_ops.rs # view_file_spec, create_file_spec
│ │ ├── text_editing.rs # str_replace, batch_edit, undo, per-file locking
│ │ ├── directory.rs # Directory listing + content search
│ │ ├── search.rs # search_content
│ │ ├── shell.rs # Command execution, background, process cleanup
│ │ ├── workdir.rs # Working directory management
│ │ ├── remote.rs # SSH/SFTP path abstraction, SshHandler, SFTP pool
│ │ └── fs_tests.rs # Integration tests (cfg(test))
│ └── utils/
│ ├── mod.rs # Module re-exports
│ ├── line_hash.rs # Composite line ids (N:hh), FNV-1a hashes, endpoint parsing
│ └── truncation.rs # Token estimation, smart truncation
主な設計上の決定事項:
- rmcp SDK — プロトコル処理には公式の Rust MCP SDK(
rmcp3.x)を使用します - Tokio — 非同期ランタイムです。すべてのファイル I/O には
tokio::fsを使用し、ブロッキング処理を行うstd::fsは使用しません - ファイルロック — ファイルごとの
tokio::sync::Mutexにより、同時書き込みの競合を防ぎます - 元に戻す履歴 — ファイルごとに最大 10 件のスナップショットをメモリ上に保持します(再起動すると失われます)
- パス解決 — 相対パスはセッションの作業ディレクトリを基準に解決します。正規化は行いません(ファイルがまだ存在しない場合があるため)
- 古い書き込みの検出 — 編集対象ごとの
N:hhID を適用時にファイルと照合します。ID が古い場合は、誤った行を編集する代わりに現在の内容を返して失敗します
開発
# Build
cargo build --release
# Run tests
cargo test
# Lint (zero warnings policy)
cargo clippy
# Format
cargo fmt
# Run locally
cargo run -- mcp
テストの実行
# All tests
cargo test
# Specific test
cargo test test_view_file
# With output
cargo test -- --nocapture
コントリビューション
コントリビューションを歓迎します!ガイドラインについては、CONTRIBUTING.md をご覧ください。
簡単なチェックリスト:
- コミット前に
cargo fmtを実行する cargo clippyが警告ゼロで成功することを確認する- 新しい機能のテストを追加する
- 必要に応じてドキュメントを更新する
セキュリティ
セキュリティポリシーと脆弱性の報告については、SECURITY.md をご覧ください。
ライセンス
Apache-2.0 — LICENSE をご覧ください
謝辞
- rmcp — 公式の Rust MCP SDK
- Model Context Protocol — プロトコル仕様
Muvon が 🦀 を使って開発しました
Octofs がより迅速なリリースに役立ったら、GitHub でスターをお願いします!⭐
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。