osnova について
Osnovaはリポジトリを決定的なシンボル・コールグラフに索引化し、コーディングエージェント向けに提供します。MCPサーバーとCLIで正確なファイル・行の根拠を示し、未解決の呼び出しは確定した関係と区別します。
主な機能
- 01tree-sitterによる20言語の索引化
- 02シンボルとコールグラフの検索
- 03正確なファイル・行の根拠
- 04リポジトリマップと変更影響の分析
- 05CLIとMCPサーバーからの利用
活用シーン
- 01関数を編集する前に呼び出し元を追跡
- 02タスクに関係するテストやシンボルを検索
- 03コード変更が影響する依存先を確認
- 04CIで索引化されたコード関係を検証
MCP 対応
リポジトリ検索、シンボル、コールグラフ、影響分析、テストの各クエリをMCPツールとして提供します。応答には索引世代が含まれ、不完全な結果や省略項目も示されます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
10掲載時のツール一覧 · 3 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| in | string | いいえ | ファイルまたはディレクトリのパスに限定します(リポジトリ相対) |
| full | boolean | いいえ | 8 行の抜粋ではなく、定義全体をインライン表示します |
| lean | boolean | いいえ | デフォルトは true:ソースを含めず、file:line、種類、定義範囲、シグネチャを保持します。false にするとソースをインライン表示し、明示的に true を指定すると full より優先されます |
| limit | number | いいえ | ヒット数の上限(デフォルト 8) |
| question | string | はい | 自然言語またはキーワードによるクエリ |
詳細
Osnova
AI コーディングエージェント向けの決定論的なコードマップです。 Osnova は tree-sitter でリポジトリをインデックス化し、シンボルと呼び出しグラフを作成して、あらゆる MCP クライアントまたはコマンドラインから利用できるようにします。同じ入力なら、バイト単位で同じ出力になります。埋め込みもテレメトリーもなく、osnova update-check を入力しない限り、ネットワーク接続も行いません。20 言語に対応し、そのうち 7 言語(TypeScript、JavaScript、Python、Go、Rust、Java、C#)には高度なアダプターを用意しています。
Osnova はスラヴ語で「基礎」や「土台」を意味します。コードを編集する前にエージェントがしっかりと立てる足場を与えること、それが Osnova の役割です。
Node.js 22.13 以降が必要です。リポジトリを任意の MCP クライアントに提供します。
npx -y @getdomovoi/osnova mcp --workspace /path/to/repo
npm install -g @getdomovoi/osnova の実行後、エージェントの種類ごとにコマンドを 1 つ実行します。claude は Claude Code(MCP エントリー、セッション、プロンプトと停止時のフック、スキル)を設定します。agents は AGENTS.md を読み取るインストール済みのすべてのハーネス(Codex、OpenCode、Kilo、Pi、Cursor)を、それぞれのフック、プラグインまたは拡張機能とともに設定し、さらに ~/.agents/skills/ に共有スキルを 1 つ設定します。どちらのコマンドも変更内容を事前に表示し、--apply を指定すると変更を書き込み、変更する各ファイルをバックアップします。
osnova setup claude --apply
osnova setup agents --apply
または、MCP エントリーを手動で追加します。グローバルインストールがない場合は、osnova を npx -y @getdomovoi/osnova に置き換えてください。
{ "mcpServers": { "osnova": { "command": "osnova", "args": ["mcp"] } } }
得られるもの
このリポジトリでの osnova warp src/api.ts#refreshWorkspace の結果を 12 行に絞ったものです(最初の 2 行で再現できなくなると test/docs-readme-warp.test.ts が失敗します)。
function src/api.ts#refreshWorkspace: 83 indexed edges
reach: d1 callers 83 in 14 files (3 dirs); d2 +16 in 2 files; unresolved same-name 10; tests 18
d1 calls src/cli/cli.ts#ensureIndex:78 [import-binding]
d1 calls src/cli/hook.ts#runHook:191,203,225,240 [import-binding]
d1 calls src/mcp/server.ts#createOsnovaMcpServer.refresh:297 [import-binding]
d1 calls test/verification-fastpath.test.ts#<module>:37,47,48,51,53,57,58,64,68,74,78,85,110,114,132,145,154,166,171,197 [re-export-binding]
via src/index.ts:65 refreshWorkspace -> src/api.ts (export refreshWorkspace)
This does not prove absence of callers or that deletion is safe.
unresolved evidence (10); not confirmed relationships
candidates for refreshWorkspace (2, unverified): src/api.ts#refreshWorkspace, test/mcp-watch.test.ts#refreshWorkspace
d1 calls refreshWorkspace test/artifact-format9.test.ts:78,85,104,120,140 [binding-blocked]
d1 calls refreshWorkspace scripts/perf.mjs:485,486,491 [import-target-unresolved]
確定した各行には、呼び出し元、その行番号、呼び出しをこの定義に結び付けた根拠が記載されます。根拠には、インポートのバインディング、同一ファイル内の定義、ホップ数を含む再エクスポートの連鎖、特定されたレシーバーがあります。インデックスが定義に結び付けられなかった呼び出しは、未解決の根拠として分けて一覧表示し、見つかった同名候補と探索を打ち切った理由も示します。そのため、名前が一致しただけのものを呼び出し元と取り違えることはありません。reach 行にはスコアではなく正確な件数が表示されます。また、一覧が予算を超える場合は、capped: 行と omitted: フッターに省略された件数が表示されます。
グラフのうち、どの程度が正確か
インデックスが名前を示せる根拠によって呼び出し箇所を1つの定義に結び付けた場合、その呼び出し箇所は解決済みとみなされます。それ以外は、理由とともに未解決のままです。以下は、benchmarks/corpora/ 内の固定チェックアウトにおける割合で、benchmarks/results/resolution-coverage-2026-09-21b.json に記録されています。最後の列では、リポジトリ外のパッケージを経由する呼び出しと、組み込み関数への呼び出しを除外しています。これらはローカルでは解決できません。リファレンスには各列の定義が記載されています。
| Corpus | Languages | Call sites | Resolved | Share | Excluding externals |
|---|---|---|---|---|---|
| click | all | 6593 | 2903 | 44.0% | 62.4% |
| cobra | all | 4374 | 1980 | 45.3% | 88.9% |
| gson | all | 23382 | 8473 | 36.2% | 56.7% |
| humanizer | all | 30517 | 7798 | 25.6% | 51.3% |
| pyright | all | 58578 | 30070 | 51.3% | 74.5% |
| ripgrep | all | 13387 | 6121 | 45.7% | 71.6% |
| zod | all | 53417 | 21630 | 40.5% | 73.2% |
言語ごとの行はリファレンスにあります。osnova coverage を実行すると、自分のリポジトリについても同じ数値が言語別、理由別に表示されます。
解決済みであることと、正しいことは同じではありません。そのため、呼び出しエッジも各言語の型チェッカーまたはコンパイラーを基準に評価しています。固定した6つのチェックアウトにあるすべての呼び出し箇所を、呼び出し先の宣言について型チェッカーに確認させ、宣言を含む定義を osnova エッジが示している場合は true、示していない場合は false としました。0.12.0 での測定結果です。
| Corpus | Checker | Decided edges | False | False-edge rate | In-repo sites covered |
|---|---|---|---|---|---|
| click | pyright 1.1.414 | 2883 | 0 | 0% | 90.4% |
| zod | TypeScript 5.9.3 | 21593 | 4 | 0.02% | 78.2% |
| cobra | go/types, Go 1.27.1 | 1980 | 0 | 0% | 87.5% |
| ripgrep | rust-analyzer 1.98.1 | 6066 | 29 | 0.48% | 85.8% |
| humanizer | Roslyn 5.9.0 | 7363 | 3 | 0.04% | 62.2% |
| gson | javac 27 | 8133 | 4 | 0.05% | 72.3% |
Java と C# では、オーバーロードはインデックス内で1つのシンボルを共有します。そのため、記述された引数の数が、その型、その partial 部分、および宣言された基底クラスにある宣言のうち、ちょうど1つに合致する場合に限り、呼び出しエッジはバインド先のオーバーロードを示します。複数または0個の宣言に合致する場合、エッジはメソッドを保持しますが、宣言は示しません。この場合、オラクルはそのエッジをどちらの割合にも含めません(gson では2526エッジ、humanizer では602エッジ)。0.11.0 では、すべての呼び出しについて最後に宣言されたオーバーロードを示し、呼び出し箇所を呼び出し式の先頭行に記録していました。また、C# ファイルでは、プライマリコンストラクターまたは raw string の後の部分が失われていました。その測定では、gson で誤ったエッジが2045個(24.75%)、humanizer で617個(8.25%)、ripgrep で112個(2.06%)でした。ripgrep に残る29個のうち、11個は #[cfg] の各分岐で1回ずつ宣言された関数、6個は親と同じ名前の関数を持つテストモジュール、5個は別の場所にある関数と同名のローカルクロージャーまたはパラメーターへの呼び出しです。呼び出し先に合致する宣言が1つある呼び出しは、基底型がインデックス外にあって、コンパイラーが見えない基底クラスのオーバーロードをバインドする可能性がある場合も、そのエッジを保持します。この制限を設けているのは、そのようなエッジを取り下げると、誤ったエッジが1つ減る一方で、humanizer の再現率が10ポイント低下したためです。すべての誤ったエッジの原因は、手法とその限界とともにbenchmarks/results/type-checker-oracle-2026-09-30.jsonに分類されています。これらの数値を生成するスクリプトはbenchmarks/oracle/にあります。
Grep とグラフの比較
テキスト検索を実行するのではなく、呼び出しグラフを保持する理由は速度ではありません。人が最初に入力する正規表現は、見た目以上に間違っていることが多く、それに誰も気づかないからです。6 つの言語で 9 組の呼び出し箇所を行ごとに検証しました。各セルには、見つかった箇所数(適合率/再現率)が示されています。手法には、それぞれが見落とした内容を記載しています。
| コーパス | 対象 | 検証済み箇所 | テキスト検索 | 解決済みグラフ |
|---|---|---|---|---|
| click | Context.invoke 深さ 2 | 13 | 12 (0.92 / 0.85) | 12 (1.00 / 0.92) |
| pyright | getChildNodes 深さ 2 | 28 | 5 (0.80 / 0.14) | 28 (1.00 / 1.00) |
| cobra | Command.Root 深さ 1 | 30 | 30 (1.00 / 1.00) | 30 (1.00 / 1.00) |
| cobra | Command.PersistentFlags 深さ 1 | 12 | 13 (0.92 / 1.00) | 12 (1.00 / 1.00) |
| humanizer | Configurator.GetFormatter 深さ 1 | 18 | 19 (0.74 / 0.78) | 18 (1.00 / 1.00) |
| ripgrep | Searcher.line_terminator 深さ 1 | 12 | 32 (0.38 / 1.00) | 12 (1.00 / 1.00) |
| ripgrep | LineTerminator.as_byte 深さ 1 | 26 | 26 (1.00 / 1.00) | 26 (1.00 / 1.00) |
| gson | JsonReader.beginObject 深さ 1 | 10 | 29 (0.34 / 1.00) | 10 (1.00 / 1.00) |
| gson | TypeToken.getRawType 深さ 1 | 27 | 43 (0.63 / 1.00) | 27 (1.00 / 1.00) |
グラフが対象の呼び出しではない箇所を返したことは一度もありません。記録は benchmarks/results/grep-vs-graph-2026-09-21.json にあります。
10 個のツール
名前は土台のイメージにちなんでいます。CLI では接頭辞を付けずに同じ名前を使います。osnova ground と osnova_ground は同じクエリです。
| ツール | 意味 | 機能 |
|---|---|---|
osnova_ground | 立つための地面 | キーワード検索:正確な file:line を含む、順位付けされた定義 |
osnova_thread | 布をたどる糸 | テキスト検索:シンボルごとにまとめた正規表現またはリテラルの一致 |
osnova_outline | ある部分の輪郭 | 1 つのファイルのシグネチャと行範囲 |
osnova_warp | 織り目を支える糸 | 呼び出しグラフ:直接または推移的な呼び出し元と呼び出し先 |
osnova_groundwork | すべてを支える基礎 | リポジトリマップ:ディレクトリのクラスター、ハブ、ホットスポット |
osnova_footing | 構築の土台 | タスクコンテキスト:質問に関連する定義、関係、テスト候補 |
osnova_settle | 変更後に地面が落ち着く様子 | 変更影響:差分が触れるシンボルと、インデックスに登録された依存先 |
osnova_plumb | まっすぐ垂らした下げ振り | 主張の検証:列挙された呼び出し箇所のうち、インデックスが確認したものと、抜け落ちた依存先 |
osnova_tests | 支えを確かめるために引く布 | テスト:シンボルを参照するテストファイル、または 1 つのテストファイルが到達するシンボル |
osnova_unreferenced | 端でほつれた糸 | インデックスに登録された呼び出し元がない定義と、それぞれの手掛かり。証明ではなく候補です |
すべての MCP レスポンスはインデックスの生成情報から始まり、インデックスが部分的な場合はその旨を示し、予算によって除外された項目数を数えます。予算と、どの CLI サブコマンドが生成情報を含むかについては、リファレンスを参照してください。
フックとクライアント
1 つのグローバルインストールで、すべてのリポジトリとクライアントに対応します。各クライアントのグローバル設定に 1 つエントリーを追加するだけで、プロジェクトごとの設定は不要で、リポジトリ内に何も書き込みません。osnova setup claude と osnova setup agents は差分を表示し、--apply を指定するまで何も書き込みません。agents は設定フォルダーがないハーネスをスキップし、--only codex,pi で対象を絞り込めます。また、編集したスキルファイルやプラグインファイルは保持され、その旨が報告されます。--uninstall はどちらのファミリーも同じ方法で元に戻し、まず変更内容を表示します。次の表は、クライアントごとの設定方法を 1 つずつ示しています。各フックが表示する内容、何も表示しない場合、試験で測定した内容については、リファレンスを参照してください。
| クライアント | 設定方法 | 追加される内容 |
|---|---|---|
| Claude Code | osnova setup --apply --client claude-code --hooks | MCP エントリーに加え、セッション、プロンプト、停止時のフックを追加します。--skill でスキルを、--nudge でオプトイン方式の grep ナッジを追加します |
| Claude Code(プラグインとして) | /plugin marketplace add getdomovoi/osnova then /plugin install osnova@osnova | 同じ MCP エントリー、フック、スキルを npx -y @getdomovoi/osnova@<version> 経由で実行します。プラグインのリリースに固定され、グローバルインストールは不要です。更新はマーケットプレイスに従います |
| Codex | osnova setup --apply --client codex --hooks | MCP エントリーに加え、同じ 3 つのフックを追加します。/hooks で信頼する設定にしないと、Codex はフックを通知なくスキップします。手順についてはCodex での Osnovaを参照してください |
| Cursor | osnova setup --apply --client cursor --hooks | MCP エントリーに加え、フォローアップメッセージとして停止時のフックを追加します |
| OpenCode | osnova setup --apply --client opencode --plugin | MCP エントリーに加え、各メッセージに開始地点を追加するプラグインを追加します。ツールのガイダンスは MCP の指示から提供されます |
| Kilo | osnova setup --apply --client kilo --plugin | MCP エントリーに加え、同じプラグインを追加します |
| Pi | osnova setup --apply --client pi --plugin | pi-mcp-adapter 経由で MCP エントリーを追加し、同じ処理を行う拡張機能を追加します |
CI での利用
このアクションは、プルリクエストのベースに対して osnova settle --base-ref を実行し、プルリクエストで変更されたシンボルに依存する、インデックスに登録されたすべての項目を一覧表示します。このレポートはインデックス化された構造上の証拠のみを示すため、依存する項目が見つからなくても、その変更に依存するものがない証明にはなりません。
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: getdomovoi/[email protected]
with:
depth: "2"
入力とローカルでの実行方法については、リファレンスを参照してください。
osnova が行わないこと
- 型推論と動的ディスパッチは行いません。エッジは構文に基づきます。直接呼び出し、インポート、名前参照、宣言された継承関係(記述されたスーパークラス名またはインターフェース名)、フレームワークのルート(レシーバーが列挙されたフレームワークのインポートに結び付く登録で、動詞とリテラルのパスがその箇所に記述されているもの)を対象とし、TypeScript、JavaScript、Python では字句的なバインディングとレシーバーのヒントを使用します。解決はヒューリスティックであり、その旨を明示します。
- ルートテーブルは作成しません。
routesエッジは、1 つの登録箇所を 1 つのハンドラーに結び付けます。マウント、ブループリント、コントローラーのプレフィックスはそれぞれ別のエッジに記録され、完全なパスとして結合されることはありません。計算されたパスはパスを記録せず、インラインクロージャーやラップされたハンドラーはターゲットなしでルートを記録します。Express、NestJS、Flask、FastAPI は解析しますが、gin、axum、Django、Spring、ASP.NET、Rails、ファイルベースのルーターには対応していません。 - この境界には、測定可能な代償があります。2 つの固定コーパスで型チェッカーと比較したところ、osnova が解決できない呼び出しの多くは、レシーバーの型がコードに記述されていない呼び出しです。zod で見逃した 6359 箇所のうち 2945 箇所、click で見逃した 307 箇所のうち 164 箇所は、型注釈のない単純な名前です。また、zod ではさらに 1478 箇所が呼び出し結果またはプロパティチェーンです。レシーバーの宣言に型が記述されている見逃し箇所は、zod で 349 箇所、click で 10 箇所にすぎず、そのうち 349 箇所中 248 箇所は、単一のライブラリーイディオムです。これらをすべて解決しても、再現率は zod で 76.9% から 78.2% に、click で 90.4% から 90.7% に上がるだけです。つまり、この境界による損失は 10 ポイントではなく、およそ 1 ポイントです。全件調査の結果は
benchmarks/results/receiver-boundary-census-2026-09-21.jsonにあります。 - セマンティック検索は行いません。
osnova_groundは定義に対するフィールド型の語彙ランキングです。高速で、決定論的かつ説明可能ですが、言い換えには一致しません。 - 安全性の証明は行いません。呼び出し元のリストが空でも、インデックスに呼び出し元が見つからなかったという意味であり、呼び出し元が存在しないことを意味するわけではありません。
- コストに関する主張は行いません。これまでのエージェント試験では、小規模なタスクにおいて、グラフの有無による正確性の同等性が示されています。この 2 つを分離して比較するベンチマークは進行中です。
誠実さを保つ仕組み
- すべてのクエリで、未コミットの編集内容も含めて、まず作業ツリーからインデックスを更新し、その世代を報告します。
- 出力を切り詰める場合は、切り詰めた量を必ず示します。ランキングリストでは、除外した候補の数を必ず示します。部分的なインデックスである場合は、すべての応答でその旨を示します。
- すべての検索結果には
file:line形式の範囲、ソースハッシュ、インデックスの世代が含まれるため、エージェントが引用する内容を確認できます。 benchmarks/results/内のベンチマーク結果はすべて、コーパスのフィンガープリントとともに固定され、却下された実験も採用された実験と並べて記録されています。- キャッシュは解析の前に構造コアの SHA-256 を検証し、読み込み時にはソーステキストごとにハッシュを照合します。キャッシュの外部には何も書き込みません。
CLI
各ツールはサブコマンドです。osnova build <root>、osnova warp <symbol>、osnova settle --base-ref <ref> に加え、coverage、check、doctor、setup、mcp があります。全コマンドの一覧はリファレンスを参照してください。
ライブラリー
import { buildIndex, ask, callersDetailed, renderMapCard } from "@getdomovoi/osnova"。構造化 API は省略数を含む完全な結果を返します。テキストの予算が適用されるのは CLI と MCP の表示のみです。すべてのエクスポートはリファレンスを参照してください。
コントリビューション
バグ報告、言語アダプター、ベンチマークコーパス、エージェント試験を歓迎します。変更が通過すべきゲート(lint、typecheck、tests、build、perf budgets、package smoke)については、CONTRIBUTING.mdをお読みください。
pnpm install
pnpm lint && pnpm typecheck && pnpm test && pnpm build && pnpm perf
決定性は中核となる不変条件です。インクリメンタル更新の結果がフルリビルドと 1 バイトでも異なる変更は、バグです。
ライセンス
Apache-2.0
プライバシー:PRIVACY.md。セキュリティポリシーと報告:SECURITY.md。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。
