overseer-nvim-mcp について
overseer-nvim-mcpは、Neovim内で動くコーディングエージェント向けのMCPサーバーです。overseer.nvimのタスクリストを共有し、長時間実行するコマンドを管理できます。
主な機能
- 01タスクとテンプレートの一覧表示
- 02長時間実行コマンドの起動
- 03出力の確認とパターン待機
- 04タスクの再起動・停止・削除
- 05ユーザー起動タスクの保護
活用シーン
- 01エージェントが起動した開発サーバーをNeovimの一覧で管理
- 02テストやファイル監視の出力をポーリングせず確認
- 03MCPクライアントからエージェント所有タスクを停止・再起動
MCP 対応
stdio経由で、overseer.nvimのタスク管理用MCPツールを7種類提供します。Neovimの`$NVIM` RPCソケットを使うため、クライアントはNeovimのターミナルバッファ内で実行する必要があります。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
overseer-nvim-mcp
コーディングエージェントに、あなたと同じように overseer.nvimのタスクを操作する機能(一覧表示、出力の追跡、実行、再起動、停止、破棄)を提供する MCPサーバーです。

理由
エージェントのシェルツールと overseer のタスクリストは、別々の実行環境です。エージェントが自身のシェルで起動した開発サーバーはタスクリストに表示されず、そこから停止できません。また、セッションが終了するとプロセスツリーが孤立します。あなたが起動したタスクは、適切に終了処理されます。このギャップを埋め、エージェントの長時間実行コマンドを実際の overseer タスクとして扱えるようにします。
要件
- overseer.nvimを導入した Neovim
(
v2.1.0でテスト済み) - Node >= 22
- Neovim のターミナルバッファ内で実行する MCP クライアント
インストール
サーバーは stdio を使用し、MCP クライアントによって起動されます。コマンドは常に同じです。
npx -y overseer-nvim-mcp
クライアントはNeovim のターミナルバッファ内で実行する必要があります。継承する$NVIMソケットはそこから取得されます。MCP サーバーは起動時に接続するため、ツールは次のセッション開始時に表示されます。ツールが表示されない場合、通常は$NVIMがサーバーの環境に渡っていません。サーバーは$NVIMがなければ何も登録せず、クライアントによってはサーバーに渡す環境変数を削除します。
Claude Code
claude mcp add overseer -- npx -y overseer-nvim-mcp
Codex CLI
codex mcp add overseer -- npx -y overseer-nvim-mcp
次に、生成された~/.codex/config.tomlのブロックに1行追加します。
[mcp_servers.overseer]
command = "npx"
args = ["-y", "overseer-nvim-mcp"]
env_vars = ["NVIM"]
env_varsの行は必須です。Codex が stdio サーバーに渡す環境変数は固定の許可リスト(HOME、PATH、TERMなど)に限られており、$NVIMは含まれていません。この行がないと、サーバーはツールを登録しません。
Codex は自動的にこのサーバーを使うこともありません。詳しくはエージェントに実際に使わせるをご覧ください。
Antigravity CLI
~/.gemini/config/mcp_config.jsonに設定します。
{
"mcpServers": {
"overseer": {
"command": "npx",
"args": ["-y", "overseer-nvim-mcp"]
}
}
}
ユーザー全体の設定ファイルを使用してください。CLI の非対話型の print モード(agy -p)が MCP サーバーを読み込むのはこのファイルのみで、他の場所からは読み込みません。ワークスペースレベルの.agents/mcp_config.jsonは、このモードでは通知なしに無視されます。
Antigravity も自動的にこのサーバーを使うことはありません。詳しくはエージェントに実際に使わせるをご覧ください。
Gemini CLI
gemini mcp add overseer npx -y overseer-nvim-mcp
または、settings.jsonに設定します。
{
"mcpServers": {
"overseer": {
"command": "npx",
"args": ["-y", "overseer-nvim-mcp"]
}
}
}
opencode
opencode.jsonに設定します。
{
"mcp": {
"overseer": {
"type": "local",
"command": ["npx", "-y", "overseer-nvim-mcp"]
}
}
}
mcphub.nvim (codecompanion.nvim, avante.nvim)
mcphub のサーバー設定に記述します。
{
"mcpServers": {
"overseer": {
"command": "npx",
"args": ["-y", "overseer-nvim-mcp"],
"env": { "NVIM": "${NVIM}" }
}
}
}
envブロックは必須です。mcp-hub は自身の環境変数を起動するサーバーに渡さないため、これがないとサーバーに$NVIMが渡らず、ツールが登録されません。サーバーは、ハブを起動した Neovim インスタンスを操作します。Neovim の外部から起動したハブには転送できる$NVIMがないため、mcp-hub ではこのサーバーが切断状態となり、Variable 'NVIM' not foundと表示されます。
LazyVim には overseer.nvim extra が付属しています。
:LazyExtras で有効にし(editor.overseer を選択)、Neovim を再起動してから、
上記のとおりサーバーを MCP クライアントに追加します。それ以外に必要な作業はありません。サーバーは、すでに設定されている overseer を使用します。
ツール
| ツール | 目的 |
|---|---|
overseer_list_tasks | id、name、status、exit_code、cmd、cwd、実行時間、origin を含むタスク |
overseer_list_templates | ディレクトリ内のテンプレート(npm、go-task、make、just、VS Code)と、provider、desc、params |
overseer_tail | タスクの出力とステータス。パターンが現れるまで待機できます |
overseer_run | 長時間実行するコマンドを開始します。生の cmd 配列、または params を指定した template を使用します |
overseer_restart | id または名前の部分一致でタスクを再起動します |
overseer_stop | 実行中のタスクを停止します |
overseer_dispose | タスクを停止し、一覧から削除します |
最後の3つは force を受け取り、force なしでは、自分が開始した実行中のタスクを拒否します。
タスクは数値の id または大文字と小文字を区別しない名前の部分一致で指定できるため、エージェントは id を追跡せずに "dev" と指定できます。
仕組み
トランスポートには $NVIM を使用します。これは Neovim がターミナルバッファーで起動する各プロセスに公開する RPC ソケットです。MCP クライアントはこれを継承し、このサーバーもクライアントの子プロセスとして、同じものを継承します。
それ以外の動作もすべて、これに基づいています。
$NVIMが設定されている場合、サーバーは msgpack-RPC 経由で overseer に対してnvim_exec_luaを実行する7つのツールを登録します。$NVIMが設定されていない場合、サーバーは何も登録せず、処理を行いません。Neovim の外部で実行しても、エラーではなく何もしません。
ソケットの検出は行いません。cwd のハッシュ化も、lsof も、
pgrep もありません。こうした方法は構造的に破綻しています(cwd ハッシュ方式では、クラッシュしたインスタンスの古いソケットと稼働中のソケットを見分けられず、稼働中のソケットを削除してしまいます。また macOS の pgrep は、呼び出し元自身の祖先プロセスを除外します。まさに対象となる Neovim インスタンスがこれに当たります)。$NVIM を使えば、こうした問題を設計上回避できます。
すべてのユーザー入力(タスク名、コマンド、作業ディレクトリ)は msgpack の引数として渡され、Lua では ... として受け取られます。Lua ソースへの文字列埋め込みは一切行われないため、タスク名がコード実行につながることはありません。
タスクリストを共有しつつ、自分のタスクには干渉しません
現在、タスクリストを書き込むプロセスは2つありますが、それを確認できるのは片方だけです。これによる問題を防ぐ仕組みが2つあります。
- 複数のタスクに一致する部分文字列はエラーとなり、候補を一覧表示して数値の id を指定するよう求めます。モノレポでは
"dev"が十数個の名前に一致することがあり、最初のものを黙って選ぶと、誤ったタスクを停止してしまいます。 - タスクには開始者のタグが付けられます。
overseer_list_tasksはoriginとしてagentまたはuserを報告します。また、overseer_stop、overseer_restart、overseer_disposeは、forceを指定しない限り、自分が開始した実行中のタスクを拒否します。終了済みのタスクには制限がありません。終了した行を削除しても問題はないためです。
この非対称性は意図的なものです。誤って拒否されても、余分に1回呼び出すだけで済みます。誤って停止すると開発サーバーが停止し、保持していた状態が失われます。そもそも、そのタスクをエージェントに接続する理由もありません。
overseer_run は、自動終了しないコマンド向けです。開発サーバー、ファイルウォッチャー、--watch を指定したテスト実行などが該当します。自動終了する短いコマンドは、出力をインバンドで確認できるエージェント標準のシェルツールを使ってください。2秒で終わるビルドを開始してからポーリングするのは、かえって非効率です。
テンプレート一覧が空でも正常です
overseer_list_templates は、overseer のプロバイダーが検出した内容をそのまま返します。
ほとんどのリポジトリでは実行可能なものが何も宣言されておらず、空の一覧が返されます。これは正当な応答であり、エラーではありません。このため、一般的なケースではテンプレートのみの設計では使いものにならないので、overseer_run は主な実行方法として生の cmd を受け取ります。
このサーバーには、特定のプロバイダーに関する知識はありません。一部のタスクランナーが公開するヘルプ専用の項目も含め、結果のフィルタリングや書き換えは行いません。そうすると、そのプロバイダーのことをまったく知らないリポジトリでも同じように動作しなければならないサーバーに、あるプロバイダー固有の慣習を組み込むことになるためです。
各項目に含まれるもの:
{
"name": "just fixture-just-generate",
"provider": "just",
"desc": "Generate output for a language",
"params": [{ "name": "lang", "type": "string", "required": true }],
"running_task_id": 128
}
- プロバイダーが説明を提供しない場合、
descは明示的なnullです。 npm と make は説明を提供しませんが、go-task と just は通常提供します。明示的な null は、どこかでフィールドが削除されたのかと推測する必要はなく、読み取るものがないことを示します。 - 説明のある項目が先に並びます。 これは特定のプロバイダーに関するものではなく、情報量の違いを反映しているだけです。Taskfile と package.json の両方があるリポジトリでは、そうしないと説明のある項目が、名前だけの npm スクリプトの数十項目の下に埋もれてしまいます。
paramsはテンプレートが受け取る引数です。requiredは、その引数がないとoverseer_runが呼び出しを拒否するものを示します。引数はparamsとして渡してください。必須の引数がない場合は、エディターでプロンプトが開くのではなく、必要な引数の名前を示すエラーが返されます。running_task_idは、同じ名前のタスクがすでに実行中の場合に表示されます。名前で照合するため、見落とすこともあります(パラメーター付きで呼び出されたテンプレートは、解決後のコマンド名をタスク名にするためです)。ただし、これがある場合は、すでに実行中の開発サーバーに加えて、もう一つ起動しないための目印になります。filterは名前と desc に対して部分文字列で照合します。使う価値があります。3 種類のランナーを使うモノレポでは、80 件を大幅に超える項目が返されることがあります。
エージェントに実際に使わせる
一部のクライアントでは、これは自動的に行われます。サーバーは初期化結果で MCP の instructions を返し、それらを表示するクライアントはエージェントのシステムプロンプトに追加します。そこなら、50 個のツールの説明に埋もれず、エージェントが実際に参照できます。そこでは、実行期間の境界(ここでは長時間実行、シェルでは短いコマンド)を示し、コマンドを再構成する前にテンプレートを確認すること、ポーリングの代わりに wait_for を使うこと、自分のタスクだけをクリーンアップすることをエージェントに伝えます。
$NVIM が設定されていない場合、サーバーは同じ理由でこれらの指示を提供しません。ツールを登録しないのと同様、ツールを受け取らないセッションに使い方を伝えるべきではないためです。
指示がモデルに届くかどうかがすべてであり、クライアントによって異なります。
- Claude Code は指示を注入します。Copilot CLI は、指示を許可したサーバーに対して注入します(スクリプト実行では
--allow-all-mcp-server-instructionsを指定します)。 - Codex CLI はモデルにツール定義を表示しますが、指示は表示しません。促されるまでサーバーを利用しない問題は、既知の未解決の問題です。「開発サーバーを起動して」と頼むと、サーバーに接続され、動作している状態で、自分のシェル上で
npm run devを実行します。 - Antigravity CLI は何も注入しません。指示とすべてのツールスキーマを
~/.gemini/antigravity-cli/mcp/overseer/配下のファイルに書き込みますが、モデルがその場所を参照するよう指示されるまで読み込みません。同じプロンプトでも、同じ結果になります。自分のシェルを使います。
この 2 つのクライアントでは、プロンプトで overseer を指定する(「overseer で開発サーバーを起動して」はどちらでも機能します)か、クライアントが実際に読み取るコンテキストファイルで一度指定してください。AGENTS.md(Codex)または GEMINI.md(Antigravity)に 1 行追加すると、同じプロンプトでも overseer を全面的に使うようになります。まずテンプレートを確認し、タスク名で実行してから、出力を追跡します。
以下の Markdown は、その一度だけ追加する指示であり、すべてのクライアントでプロジェクトのコンテキストファイル(CLAUDE.md、AGENTS.md、GEMINI.md など、使用しているクライアントが読み込むファイル)に記載します。クライアントはプロジェクトの指示を常に再読み込みするため、サーバーが送信できる内容よりも優先されます。
## Long-running commands
Start dev servers, file watchers and `--watch` test runs with `overseer_run`,
not the shell. They then appear in my task list, I can stop them myself, and
their process trees get torn down properly instead of being orphaned.
Short commands that exit on their own stay on the shell: their output is
in-band there, which is what you want.
Check `overseer_list_templates` first. If the repo declares one that matches, run
it by name rather than reconstructing the command.
これでも不十分な場合は、PreToolUse フックで動作を確実にできます。このフックは、明確なケースでシェルの使用をブロックし、代わりに何をすべきかエージェントに伝えます。まずは対象を絞り、実際に遭遇したパターンを追加してください。誤った対象に反応するフックは、フックがない場合よりも厄介です。
#!/usr/bin/env bash
# ~/.claude/hooks/prefer-overseer.sh: exit 2 blocks the call and shows stderr
# to the agent. Receives the tool call as JSON on stdin.
cmd=$(jq -r '.tool_input.command // ""')
case "$cmd" in
*"vitest run"*) ;; # one-shot, stays on the shell
*" --watch"*|*"vitest"*|*"npm run dev"*|*"pnpm dev"*|*"yarn dev"*)
echo "This looks long-running. Use overseer_run so it lands in the task list and can be stopped." >&2
exit 2
;;
esac
exit 0
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{ "type": "command", "command": "~/.claude/hooks/prefer-overseer.sh" }]
}
]
}
}
繰り返し待たずに待機する
エージェントが手作業でタスクを進めると、推測を繰り返すことになります。起動し、出力を追い、何も得られず、もう一度出力を追い、やはり何も得られません。待機する方法がないため、推測するたびに往復処理が発生し、その様子を見続けることになります。
overseer_tail は、代わりに wait_for 正規表現を受け取ります。一致する行が現れたとき、タスクが終了したとき、または timeout_ms に達したときに返り、どのケースだったかを示します。そのため、タイムアウトを成功と誤解することはありません。
overseer_tail { task: 48, wait_for: "ready - listening" }
status=RUNNING total=5 from=1 waited=matched
compiling... 0
compiling... 1
compiling... 2
ready - listening on http://localhost:3000
GET /route-4 200
total はカーソルです。これを since として渡すと、毎回同じ画面分を読み直すのではなく、新しい出力だけを取得できます。
overseer_tail { task: 48, since: 5 }
status=RUNNING total=9 from=6
GET /route-5 200
GET /route-6 200
GET /route-7 200
GET /route-8 200
from は、ブロックが実際に始まる位置を示すインデックスです。これが since + 1 より大きい場合、呼び出しの間に出力がスクロールされているため、続きではなく欠落部分を見ていることになります。
overseer_run も、短時間だけ待機します。settle_ms(デフォルトは 1500、無効にするには 0)まで待機し、タスクが出力を生成するか終了した時点で返します。起動直後に終了したコマンドは、正常な開発サーバーと同じ単なる ID を返すのではなく、ここで失敗を報告します。
待機処理は Node で実行されます。 このサーバーはエディター内で動作し、vim.wait は入力を処理しないため、Lua で 15 秒待機するとセッションが 15 秒間フリーズします。ローカルソケット経由でポーリングすれば Neovim の応答性が保たれ、往復処理を目にすることもありません。
スラッシュコマンドとアタッチ可能なリソース
ツールはエージェントが呼び出すものです。サーバーは、あなたが操作するものも2つ公開します。
プロンプトはスラッシュコマンド(Claude Codeでは/mcp__overseer__...)として表示されます。
サーバーは呼び出しごとにプロンプトを生成するため、一般的な回答を繰り返すのではなく、現在のエディターの状態を確認します。
-
**
directory_local_task**は、npm スクリプト、Makefile、Taskfileのないプロジェクト向けに、.nvim.lua内でoverseer独自のregister_templateを使ってタスクを定義します。exrcが実際に有効になっているか、また.nvim.luaが すでに存在するかを確認し、正しく設定されていても動作していないように見える原因となる2点も含めます。 Neovimを再起動するまで表示されないことと、ファイルに対して:trustを求められることです。 -
**
diagnose**は、overseerに期待したタスクが表示されない理由を説明します。 Overseerは、各プロバイダーが何も提供しなかった理由を記録しますが、その理由は通常、表示されません。- `npm`: 11/11 available - `make`: 0/0 available - No Makefile found - `mise`: 0/0 available - Command "mise" not found
これにより、「読み取るものがない」と「そのランナーがインストールされていない」を区別できます。 空のリストでは、この違いを判断できません。
リソースは呼び出すのではなく、アタッチして使います。
overseer://tasks:タスク一覧全体をJSON形式で表示しますoverseer://task/{id}/output:ステータス行付きで、1つのタスクの出力を表示します
サーバーは、実際のIDを使ったタスクごとのURIを列挙し、補完にも対応しています。そのためクライアントは、 タスクを自分で探さなくても、存在するタスクを提示できます。
注意事項
- RPC経由で開始したタスクの出力は、overseerパネルを開くまで、ターミナルバッファーではなく
ストラテジーの保留中バッファーに保存されます。
overseer_tailは両方を読み取り、 ANSIカラーコードとキャリッジリターンを取り除き、PTYの空白の余白を削除します。 そのため、空の画面の下部ではなく、整ったログ行を取得できます。 exit_codeはタスクの実行中には存在せず、終了後に存在します。これにより、エージェントは 正常終了とクラッシュを区別できます。
貢献
CONTRIBUTING.mdを参照してください。リリースはrelease-pleaseで自動化されているため、 コミットは Conventional Commitsに従う必要があります。
ライセンス
MIT © Miguel Angelo Sepulveda
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。