Treering について
Treeringはコードベースの構造をローカルでマップ化し、スナップショットを保存して依存関係の変化を示します。SCIPインデックスを読み込み、LLMを使わずに、Web画面・コマンドライン・MCPツールから調べられます。
主な機能
- 01モジュール・名前空間・型の関係を可視化
- 02スナップショット間の依存変化を比較
- 03型のメンバー、呼び出し元、呼び出し先を表示
- 04インデックスの差分更新と定期監視
- 05コマンドラインとWeb画面で構造を探索
活用シーン
- 01型の呼び出し元や依存関係を特定
- 02スナップショット間で追加・削除された依存を比較
- 03型の呼び出し元が増える過程を追跡
- 04エージェントからインポート済みプロジェクトのシンボルや変更を検索
MCP 対応
`treering mcp`を実行するとstdioのMCPサーバーが起動し、プロジェクト一覧、シンボル検索、呼び出し元やサブグラフの照会、変更確認、スナップショット一覧のツールを提供します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Treering
英語 | 한국어
Treeringはコードベースのマップを作成し、コミットごとにそのコピーを保存するため、構造がどのように変化したかを確認できます。たとえば、先週どの型が互いに依存し始めたか、あるクラスの呼び出し元が増え始めたのはいつか、といったことが分かります。すべてお使いのマシン上で動作し、ネットワーク経由でデータを送信することはありません。LLMを使用しないため、同じコードからは常に同じグラフが生成されます。

ボックスをクリックすると中に入ります。開いた部分が、その中にあるものを囲んで表示します。その後、外に戻ると、同じシートがチップとして表示されます。

サンプルプロジェクトのモジュールを模式図で示し、1か月前と比較しています。緑色は新規です。Billingモジュールが新たに決済インターフェースを実装しています。赤い破線は削除されたものです。以前はWebページからデータベースが直接呼び出されていました。
![]() | ![]() |
| マップ。 バブルで示したモジュールと、それらの間の呼び出しです。新しい線は緑色、なくなった線は赤色です。 | 設計図。 1つの階層を段ごとのボックスで示し、それぞれの役割と、ほかの要素がどのように使用するかを表示します。 |
![]() | ![]() |
| モジュールの内部。 開いたモジュールが、その中にあるものを囲んで表示します。配線はシートのポートを通って境界をまたぎます。 | 1つのクラス。 フィールドとメソッド、それらが連携する型、そしてどのメンバーがそれらを結び付けているかを表示します。 |
![]() | |
| チップ。 どこに規模が集中しているかを示します。各領域はコード量に応じた大きさで、ライブラリは端のパッドとして表示されます。 |
これらはすべて、Treeringに付属するサンプルプロジェクト(treering sample)を使ったもので、小規模な架空の店舗です。
Treeringは現在も開発中であり、リリース間でデータベース形式が変更される場合があります。設計メモはtreering-plan.md(韓国語)にあります。
インストール
Windows(PowerShell):
irm https://raw.githubusercontent.com/RedholeTechnologies/Treering/main/install.ps1 | iex
Linux(x86-64):
curl -fsSL https://raw.githubusercontent.com/RedholeTechnologies/Treering/main/install.sh | sh
各スクリプトはReleasesから最新のビルドをダウンロードし、公開されているチェックサムと照合して、treeringをPATHに追加します。Windowsでは、Treeringをスタートメニューにも追加します。どちらも管理者権限は不要で、スクリプトを再度実行するとTreeringが更新されます。スクリプトを実行したくない場合は、Releasesからzipまたはtarballをダウンロードして、任意の場所に展開してください。
次に、treeringを実行するか、スタートメニューから開きます。サーバーが起動し、ブラウザーでhttp://127.0.0.1:7377が開きます。Treeringがすでに実行中の場合は、ブラウザーを開くだけです。
何もインポートせずに試しに見てみるには、最初の画面でOr look around a sample project firstを選択してください。1か月分の履歴がある小規模な架空のオンラインショップ、acme-shopが追加されます。コマンドラインから追加するには、treering sampleを実行してください。
インデクサーのインストール
Treeringはソースコードを直接解析しません。SCIPインデックスを読み込みます。このインデックスは、各言語のインデクサーによって生成されます。使用する言語のインデクサーをインストールしてください。
dotnet tool install --global scip-dotnet # C#
npm install -g @sourcegraph/scip-typescript # TypeScript and JavaScript
npm install -g @sourcegraph/scip-python # Python
リポジトリをインポートする
treering import /path/to/repo
treering serve
import はリポジトリに含まれる言語を調べ、必要なフラグを付けて各インデクサーを実行します。C# の場合、ルートにあるソリューションをインデックス化し、ソリューションがない場合は各プロジェクトをインデックス化します。TypeScript の場合は各階層で最上位にある package.json を、Python の場合は各 pyproject.toml をインデックス化します。グラフはユーザーフォルダーに保存され、リポジトリ内には保存されません。インポートしたプロジェクトは treering projects で確認できます。
treering serve を実行すると、http://127.0.0.1:7377 にマップが表示されます。データベースの引数を指定しない場合、インポート済みのすべてのプロジェクトが表示され、ページ上部のメニューでプロジェクトを切り替えられます。
ページからインポートすることもできます。プロジェクトメニューを開き、Import…、続いて Choose a folder… を選択します。ブラウザーからページにフォルダーの完全なパスを渡すことはできないため、サーバーがシステムのフォルダー選択ダイアログを開きます(Windows ではエクスプローラー、macOS では標準のダイアログ、Linux では zenity または kdialog が使われます)。パスを入力することもできます。フォルダーを選択するとインポートが始まり、ダイアログには各インデクサーの実行状況が表示されます。失敗した場合は、理由と試すべき対処法が示されます。
インポート用およびフォルダー用のエンドポイントが受け付けるのは、ページ自体から送信された JSON リクエストだけです。そのため、ブラウザーで開いている別のサイトからインポートを開始したり、ウィンドウを開いたりすることはできません。
マップを読む
マップでは、モジュール、名前空間、型がノードとして、それらの間の参照がエッジとして表示されます。
- ノードをクリックすると、その中に入ります。入ったノードは、その内容を囲むリングとして画面に残ります。空白部分をクリックするか、リングを右クリックするか、Esc キーを押すと上の階層に戻り、直前に離れたノードがマップ上で示されます。
- 色はコードの所有者を示します。独自の各モジュールには色が付き、ライブラリはグレーで表示されます。サイズはノードの使用頻度を示します。
- Shape メニューでは、同じグラフを Constellation、Orbit、Ring、Layers、Tree の5通りに配置できます。Layers は依存関係を上から下へ積み重ね、循環をまとめて表示します。Tree は、何が何を含んでいるかを一度に1つの枝ごとに表示します。
- サイドパネルには、現在表示している対象、またはクリックした型の情報が表示されます。メンバー、注入する対象と注入される場所、実装するもの、呼び出し元、呼び出す先を確認できます。パネル内の各名前は、そのノードへのリンクになっています。
/またはCtrl+Kを押すと検索できます。検索結果を選ぶと、その項目がある場所に移動します。- At と Compare では、1つのスナップショットのグラフを表示したり、2つのスナップショット間で追加・削除されたエッジを表示したりできます。
- Scope では、すべての項目と Our code を切り替えられます。シンボルの定義がインデックスに含まれている場合、そのシンボルは独自のものと見なされます。そのため、名前から推測することなくライブラリを除外できます。Acme.Shop では、これによりモジュール数が38から4に、型の数が829から401に減ります。
- Theme では Light、Dark、Slate、Skyfall、Obsidian を選択でき、Language では英語と韓国語を切り替えられます。
- システムで視差効果を減らす設定が有効になっている場合、装飾的なアニメーションは停止します。
最新の状態に保つ
treering update /path/to/repo
treering watch /path/to/repo # every 10 minutes
treering watch /path/to/repo 30 # every 30 minutes
update は、ファイルが変更されたプロジェクトのみを再インデックス化します。変更された各ファイルは、最も近いプロジェクト(.csproj、package.json、または pyproject.toml と setup.py)に振り分けられ、その言語のインデクサーで処理されます。そのため、複数の言語を使うリポジトリでは、各部分がそれぞれのツールで更新されます。インデクサーが見つからない場合、Treering はインストールするコマンドを表示します。
watch は一定の間隔で update を実行し、変更があった場合にのみスナップショットを追加するため、作業中に履歴が蓄積されます。最後のスナップショットに記録されたコミットを起点にするため、停止して再開しても情報は失われません。また、コミットだけでなく未コミットの変更も数えます。
通常は、自分で watch を実行する必要はありません。treering serve を実行している間は、インポート済みのすべてのプロジェクトに対して同じ処理が行われます。10分ごとに変更を再インデックス化してスナップショットを追加し、最新のスナップショットを表示している場合は、ページが自動的に新しいスナップショットに切り替わります。再インデックス化してもグラフに変化がなければ、スナップショットは追加されません。--no-watch またはページ上の Settings で無効にし、--watch-minutes N で間隔を変更できます。また、--port N で別のポートを指定できます。
インデックスを直接扱う
インデクサーを自分で実行し、その出力を読み込めます。C# の場合:
scip-dotnet index YourSolution.slnx --allow-global-symbol-definitions --output index.scip
treering load index.scip graph.db
treering serve graph.db
treering callers graph.db OrderRepository
treering map graph.db type --own
scip-dotnet には必ず --allow-global-symbol-definitions を渡してください。これを指定しないと、シンボルにパッケージ名が含まれず、プロジェクトを個別にインデックス化したり、スナップショットを追加したりしたときに、1つのシンボルが複数に分かれてしまいます。あるテストでは、追加されたシンボルが6,784個、削除されたシンボルが6,790個と記録されました。
経時的に比較するには、スナップショットをさらに読み込みます:
treering snap index-new.scip graph.db 1
treering diff graph.db 0 1
treering growth graph.db InvoiceModel
diff は2つのスナップショット間で追加・削除された依存関係を一覧表示し、growth はある型の呼び出し元がいつ増えたかを示します。
エージェントから使用する
treering mcp
これは、インポート済みのプロジェクトを対象に、stdio で Model Context Protocol(MCP)サーバーを実行します。6つのツールがあります:list_projects、find_symbol、callers_of、subgraph、changed_since、snapshots。各ツールには project(list_projects が返す名前または ID)を指定します。空のままにすると、最後にインポートしたプロジェクトが使われます。これらのツールはページと同じクエリを、同じサイズ制限で実行します。結果が大きすぎる場合、レスポンスには省略された内容が示されるため、エージェントは質問を絞り込んで再度問い合わせることができます。treering mcp graph.db は、そのデータベースのみを対象に回答します。
Claude Code に追加するには:
claude mcp add treering -- treering mcp
他のホストでは、コマンドは treering、引数は mcp です。各リリースには、1ステップで MCPB をインストールするホスト向けの MCP バンドル(treering-win-x64.mcpb、treering-linux-x64.mcpb)も含まれており、MCP Registry に io.github.RedholeTechnologies/treering として公開されています。
パフォーマンス
Acme.Shop(4プロジェクト、632個の .cs ファイル)での結果:
| 手順 | 結果 |
|---|---|
| インデックス化(scip-dotnet) | 89s |
| グラフへの読み込み | 2.6s、ピークメモリ 53 MB |
| データベースサイズ | 5.9 MB(8.2 MB の index.scip から) |
| 2つ目のスナップショットのコスト | 27%増(5.9 MB から 7.5 MB) |
| 全体マップのクエリ | モジュール単位で29 ms、名前空間単位で30 ms、全型で48 ms |
| ドリルダウンクエリ | 182 ms(384型、2,933エッジ) |
| 増分更新 | 17s(うちインデックス化に16.6s) |
大規模な C# リポジトリ(11,385個の .cs ファイル)での結果:
| 手順 | 結果 |
|---|---|
| インデックス化 | 3 min 28s、インデックスは34.5 MB |
| シンボルとエッジ | 43,932個、185,266個 |
| スキャン中のメモリ | 41.6 MB(8.2 MB のインデックスの場合と同じ) |
| 読み込み | 11 to 15s、103 MB、データベースは40.3 MB |
| 全体マップのクエリ | 115個のモジュールで26 ms、406個の名前空間で48 ms、全型で210 ms(上限2,000) |
スキャン時のメモリ使用量はインデックスのサイズに応じて増加せず、このサイズでもすべての全体マップ表示が300 ms未満に収まります。これは、インデックスの読み込み時にモジュール、名前空間、型ごとにエッジを一度だけ要約し、クエリのたびに要約しないためです。この変更により、モジュールマップの処理時間は327 msから26 msに短縮されました。
言語
C#、TypeScript、Python はエンドツーエンドで動作します。入力が SCIP なので、言語の追加は主にインデクサーを追加することを意味します。TypeScript のために Treering を変更する必要はなく、モジュールレベルは npm パッケージに、名前空間はそれぞれ独立したフォルダーになりました。コンストラクターインジェクションは .ctor、<constructor>、__init__、<init> から認識されます。update と watch は TypeScript も処理します。ShopWeb では、1 つのパッケージ内の変更された 19 ファイルを 52s で処理しました。
scip-python 0.6.6 は Windows で起動しません。パス区切り文字から正規表現を構築しますが、\ 単体は有効なパターンではないためです。Treering は scip-python の前に小さなスクリプトを読み込み、このパターンをエスケープします。また、scip-python 用の pip を探す際は、まずリポジトリの .venv を調べ、その後 py ランチャーが認識している Python を調べます。pip がない場合は、空のパッケージリストでインデックスを作成します。この場合、サードパーティパッケージの名前だけが失われます。python-sample では、これにより 1,800 個のシンボルと 6,564 個のエッジが 51.6s で生成されました。
言語ごとに固有の癖があります。構造的部分型付けではインデクサーが implements を出力することがほとんどないため、TypeScript では継承エッジがあまり生成されません。また、TypeScript の参照の 14.8% は定義に紐付けられません。C# では 1.4% です。これは、インポートとモジュールレベルのコードがファイル内のどの定義よりも前に現れるためです。
既知の制限事項
SCIP は参照の位置を記録しますが、その参照がどのシンボル内にあるかは記録しません(enclosing_symbol は空です)。Treering は各参照を、その前にある最も近い定義に割り当てます。ファイル内の参照が、そのファイルで定義されている型に属する型レベルでは信頼できます。メソッドレベルでは、ネストされた型、ラムダ、ローカル関数、プロパティアクセサー、フィールド初期化子の周辺で誤った割り当てが生じるため、ページと MCP ツールではこれらのエッジを推定値として示します。
現在一般的な Program.cs のような C# のトップレベルステートメントには、それより前に定義がまったくありません。scip-dotnet は引き続き args をコンパイラー生成の Program.<Main>$ のパラメーターとして書き込むため、Treering はこれらの呼び出しをプロジェクトの Program の下に記録します。これにより、サービスの起動時の登録がマップに表示されます。ステートメントが args を一度も使用しない場合、その呼び出しは除外されます。
更新にかかる時間は約 10 秒を下回りません。そのほとんどをインデクサーが占めます。最小の C# プロジェクトでも scip-dotnet に 16.6s かかり、scip-typescript は ShopWeb の 1 つのパッケージに 50s かかります。比較と読み込みを行う Treering 自身の処理は、0.5 秒未満です。
対象外
Treering には、次のものは含めません。
- SCIP インデクサーが言語解析を行うため、独自の言語パーサー
- グラフを再現可能にする必要があるため、LLM、埋め込み、ベクトル検索
- クラウド同期、アカウント、テレメトリー
- コード編集
ビルド
dotnet test
dotnet publish src/Treering.Cli -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true
これにより、約 52 MB の単一の実行可能ファイルが生成されます。Web ページは実行可能ファイルに埋め込まれているため、実行に必要なものを別途インストールする必要はなく、Node も不要です。IncludeNativeLibrariesForSelfExtract を指定しない場合、e_sqlite3.dll は実行可能ファイルの隣に配置されます。
JSON シリアル化でリフレクションを使用し、MCP SDK がアセンブリをスキャンするため、NativeAOT はまだ動作しません。
「Treering」の由来
年輪は、それ以前の年月を囲むように一年分の成長が刻まれたものです。そのため、幹を切ると歴史全体が一度に見えます。Treering はコードに対して同じことをします。更新ごとに構造のスナップショットを保持し、モジュール、型、それらの依存関係がどのように成長したかを振り返ることができます。この名前は、他のコードマップとの違いを一言で表しています。それは時間です。また、構文木からモジュール、名前空間、型のツリーまで、コードをすでに形作っている木々にも着想を得ています。
ロゴは、切断された丸太の断面です。中心からずれた髄の周りには不均一な年輪があり、樹皮から乾燥による亀裂が入り込んでいます。最も外側の年輪は現在を表し、アクセントカラーで描かれています。
ライセンス
Apache-2.0。公開済みの実行可能ファイルにバンドルされているコンポーネントとそのライセンスは、THIRD-PARTY-NOTICES.md に記載されています。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。




