celmis について
Celmis は、複数リポジトリを扱うチーム向けのセルフホスト可能なコードインテリジェンス基盤です。共有シンボルグラフを使ったコード質問、依存関係監査、PR レビュー、アラートから PR へのワークフローを、アクセス制御と監査のもとで提供します。
主な機能
- 01引用付きの複数リポジトリ横断質問
- 02シンボルグラフを活用した PR レビュー
- 03依存関係監査と CycloneDX SBOM
- 04アラートや検出事項から PR を作成
- 05ワークスペース別ナレッジパック
- 06個人別 MCP トークンと呼び出し監査
活用シーン
- 01複数リポジトリにまたがる呼び出し経路の追跡
- 02下流の呼び出し元を考慮した変更レビュー
- 03SBOM と再計算可能な証拠パックの作成
- 04アラートや依存関係の検出から修正を開始
MCP 対応
Celmis は MCP 経由で 51 個のツールを公開し、エディター向けの簡潔な `/mcp/dev` プロファイルも提供します。MCP 呼び出しは共有コードインデックスを使い、リポジトリのアクセス規則と監査に従います。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
docker run -i --rm ghcr.io/celmis-labs/celmis-api:v0.1.30ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ghcr.io/celmis-labs/celmis-api:v0.1.30Streamable HTTPツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Celmis
監視から届いたアラートを、誰かがレビューできるプルリクエストへ。 セルフホスト可能。1 台のマシンで。ご自身のモデル、サブスクリプション、ネットワークを使います。
ウェブサイト · ドキュメント · クイックスタート · 新着情報 · 成果

運用しているサービスからアラートが届きます。Celmis はそのサービスがどのリポジトリに属し、誰が所有しているかをすでに把握しているため、そこから修正を開始します。お使いのサブスクリプションを使い、お使いのインストール環境内で動作する埋め込みの Claude Code セッションがコードを編集し、ランナーがコミットしてブランチをプッシュし、プルリクエストを作成します。ある検出結果では、最初にアラートが届いたデバイスを問わず、220 秒で完了しました。
すべてが1 つのインデックス上にあるため、この一連の流れが実現します。インデックスは、モデルを使わずに一度だけ構築される、リポジトリのシンボルグラフです。ほかのすべての機能が同じインデックスを参照します。
できること
| ここから修正 | アラートや依存関係の検出結果から埋め込みセッションを開始し、ブランチを作成して、プルリクエストを作成します。人がレビューしてマージします。Celmis がマージすることはありません。ここから修正 · アラート |
| プルリクエストのレビュー | エージェントが差分を読み、グラフがある場合は、変更箇所を呼び出すほかのコードもリポジトリをまたいで確認します。@celmis で対話し、remember で知識を教えると、伝えることがないときは応答を控えます。レビュー |
| コードへの質問 | 複数のリポジトリにまたがる質問に、呼び出しの両側の file:line 引用付きで回答します。コードへの質問 |
| コードベースと MCP | MCP 経由で 51 個のツールを利用できます。エディター向けのコンパクトな /mcp/dev プロファイル、Claude Code プラグイン、そしてチームがすでに口頭で説明しているスキルをまとめた、バージョン管理されたナレッジパックも提供します。MCP · パック |
| エビデンス | 依存関係の監査、CycloneDX SBOM、第三者がマニフェストを再計算できるエビデンスパックを提供します。SBOM とエビデンス |
| 説明責任を果たせるアクセス管理 | リポジトリはデフォルトで非公開です。MCP トークンはユーザーごとに発行され、すべての呼び出しが監査され、シークレットはソースで除外されます。また、リポジトリを別のワークスペースと一定期間共有できます。誰が何を閲覧できるか · 共有 |
インストール
git clone https://github.com/Celmis-labs/Celmis.git celmis && cd celmis
./scripts/init-env.sh # writes .env and fills every secret
docker compose --env-file .env up -d
次に http://localhost を開き、Settings → LLM Setup でモデルプロバイダーのキーを 1 つ貼り付けます。
クリーンなサーバーで、クローンから 6 つのサービスが正常に起動するまで197 秒です。Postgres と Qdrant は同梱されており、必要なメモリは約 4 GB です。詳細はクイックスタートをご覧ください。ライセンスなしのインストールでは最大 5 人まで利用できます。ライセンスをご覧ください。
v3 の新機能
- コメントに値するレビュー。 コメントの重要度を下回る指摘はプルリクエストに届きません。指摘が何もなければ、レビューは承認します。コメントには、問題点、理由、修正方法をリポジトリの言語で記載します(3.1)。
- 対話できるレビュアー。 スレッド内での
@celmisコマンドや質問、rememberルール、チームが却下した内容からの学習、プッシュごとの段階的なレビュー、サマリーでの Jira 受け入れ基準の確認(2.3)。 - ナレッジパック。 ワークスペースごとにバージョン管理されたスキル、API の例、チェックリストを用意し、アプリ内や、
briefとskillsを通じてコーディングアシスタントから閲覧できます。celmis-packで公開できます(3.0)。 - デフォルトでアクセスを遮断。 ルールが設定されていないリポジトリは見えません。MCP トークンは個人に紐づき、すべての呼び出しが監査されます(2.3.7)。3.0.2 ではシークレットの非表示をさらに強化しました。
- ワークスペース間の共有。 調査用に、期間を限定し、パスを非表示にして、閲覧者数に上限を設けて共有できます(3.1)。
- 開発者向け MCP プロファイルと、エディター向けに調整された Claude Code プラグイン(2.3.7)。
すべてのリリースは変更履歴に記載されています。
ログと、その境界
Celmis はサービスを監視しません。それは Grafana など、すでにお使いのツールが担います。 アプリケーションは独自のログを取り込まず、アラートを起点として動作します。リポジトリには、Celmis だけでなくプラットフォーム全体のログを収集するオプションのオブザーバビリティオーバーレイ(Prometheus、Loki、Promtail、Grafana)が含まれています。
docker compose -f docker-compose.yml -f docker-compose.observability.yml up -d
Loki には認証機能がないため、すべてのポートは 127.0.0.1 にバインドし、SSH トンネル経由でアクセスします。GRAFANA_ADMIN_PASSWORD は必須です。
差分のみを扱うツールではできないこと
2 つのリポジトリにまたがる質問をすると、両方を引用して回答します。

これは検索結果ではありません。ゲートウェイと決済サービスはコードを共有しない別々のリポジトリですが、回答は両者の呼び出しチェーンをたどり、さらに、Kafka トピック名が両方にハードコードされており、一方を変更するともう一方が気づかれないまま壊れることまで、促されることなく指摘します。
差分だけを構造的に読むレビュアーには、これはできません。もう一方のリポジトリを開いたことがないからです。
9 つの利用例
| PM、デリバリーリード、またはクライアントとして、プロジェクト群の進捗状況や、仕組みの実際の動きを知りたい | 質問してください。どのデバイスからでも、どこからでも、エンジニアの時間を予約したり、成果が段落ひとつだけの会議を開いたりする必要はありません → コードに質問する |
| 新しいエンジニアが、シニアエンジニアなら答えなければならない質問をしている | その質問のたびに、経験豊富な人が、すでに対応に追われているタイミングで作業の流れを中断することになります。代わりにコードベースが、ファイルと行番号を引用して答えます → コードに質問する |
| 2 つのチームがインテグレーションを共有しているものの、互いのリポジトリを読めない | 読み込み、質問する権限を付与し、非公開にしておく必要があるパスへのアクセスを拒否します。回答は得られ、認証情報はソースで拒否されます → 誰が何を見られるか |
| 顧客や監査担当者から SBOM を求められた | ボタンひとつで CycloneDX を生成し、エビデンスパックも作成します。パックのマニフェストは、パックとは別の場所で公開するハッシュを使って、相手自身が再計算できます → 依存関係、SBOM、エビデンスパック |
| 依存関係に脆弱性が見つかった | ここから修正を使うと、組み込みセッションにリポジトリ、パッケージ、検出結果が渡されます。セッションが編集し、ランナーがブランチをプッシュして PR を作成します → ここから修正 |
| プルリクエストのレビューが必要になった | エージェントが差分を読み取ります。依存関係グラフが構築されている場合は、別のリポジトリからの呼び出しも含め、変更対象をほかに何が呼び出しているかも確認します → プルリクエストレビュー |
| 40 個のサービスに同じ作業を行う必要がある | 作業内容を文章で入力してください。Celmis は該当すると判断したリポジトリを表示し、もう一度押すのを待ちます。40 個の中から探し出してボタンを 40 回押す必要はありません → 複数のリポジトリに作業を依頼する |
| 02:00 にアラートが発生したが、デスクにいない | アラートは Celmis に届き、ワークスペースのチャットチャンネルに送信されます。ここから修正を使えば、アラートを受け取った状態でセッションが開きます。ランナーがプルリクエストを作成します → アラートとスマートフォンからの修正 |
| 自分のエージェントやエディターにコードベースを理解させたい | /mcp/ を指定してください。同じインデックス上の 51 個のツールのうち 35 個は読み取り専用で、アクセスルールも共通です。コードの複製を別途作る必要はありません → Claude Code やその他の MCP クライアントを接続する |
最初の 3 つは、コードレビューツールではまったくできないことです。これこそが、Celmis がレビューツールではなくプラットフォームである理由です。インデックスを一度作成すれば、作業のどの側にいる場合でも、そのインデックスを読み取れます。
3 つの数値
| 197 秒 | git clone から 6 つのサービスが正常に稼働するまでの時間。クリーンなサーバーで計測 |
| $0.118 | 同梱モデルを使用した場合の、レビュー済みプルリクエスト 1 件あたりのコスト |
| 50 件中 17 位 | Martian Code Review Bench のオフラインセットで、3 人の審査員すべてを対象にした順位 |
最後の数値は、意図的に厳しい結果をそのまま掲載しています。下記の機能のうち、隔離された単一リポジトリの PR に対するプルリクエストレビューを測定したもので、このセットにはシンボルの利用先となる関連サービスがありません。そのため、この製品の中核となる機能は数値にまったく反映されていません。表、誤検出と評価されたすべての検出結果の監査、そして両方を再現するコマンドは結果にあります。
目次
- できること
- v3 の新機能
- 差分のみを扱うツールではできないこと
- 活用例 9 選
- 3 つの数値
- クイックスタート
- 最初のユーザーと管理者
- リポジトリを接続する
- コードに質問する
- プルリクエストのレビュー
- 依存関係、SBOM、エビデンスパック
- ここから修正する
- アラートとスマートフォンからの修正
- 複数のリポジトリにまたがる作業を依頼する
- 誰が何を見られるか
- 言語と形式
- 決定論的なチェック — モデル不要、誤検知なし
- Claude Code などの MCP クライアントを接続する
- 結果
- 誤検知の監査
- テスト用リポジトリ
- 設定
- 運用
- ローカル開発
- CLI リファレンス
- アーキテクチャ
- トラブルシューティング
- プロジェクト構成
- 来歴と権利
クイックスタート
必要なもの
| Docker | 24 以降、Compose v2 | macOS/Windows では Docker Desktop、Linux ではネイティブエンジン |
| モデル API キー | 次のいずれか | Google Gemini、Anthropic、OpenAI、OpenRouter、Groq、Mistral。評価には無料の Gemini キーで十分です:https://aistudio.google.com/app/apikey |
| RAM | 空き容量約 4 GB | 実際のインデックス作成で測定:5 つのコンテナすべてでピーク時 1.1 GB、アイドル時 565 MB |
Postgres と Qdrant は同梱されているため、外部クラスターを用意する必要はありません。Docker を使う手順では、Python や Node.js のインストールも不要です。
起動する
git clone https://github.com/Celmis-labs/Celmis.git celmis
cd celmis
# Generates .env and fills every secret in the format each one needs.
# Idempotent: run it again after a pull and it fills only the new blanks.
./scripts/init-env.sh
docker compose --env-file .env up -d
# Wait for healthy — first boot pulls three images and applies migrations
docker compose ps
http://localhost を開きます。
ここでは何もビルドされません。3 つのイメージは、CELMIS_REGISTRY で指定されたレジストリから、CELMIS_TAG で指定されたタグのものを、linux/amd64 と
linux/arm64 向けに取得します。Apple Silicon と ARM サーバーのどちらにも、ネイティブイメージが使われます。
実行するマシン上でビルドした場合、api だけで 485 秒、ディスク容量 4.2 GB が必要だと測定されました。そのため、インストール時にコンパイルする必要はなくなりました。
ポートは 3000 ではなく 80 です。リバースプロキシにより、アプリと API を同じオリジンに配置し、API を /backend 配下で提供します。これはデプロイ時の好みの問題ではありません。ブラウザーバンドルは相対パスを使用するため、それが、ビルドした環境だけでなく、あらゆるインストール環境で 1 つの公開イメージを使う唯一の方法です。
Celmis を実行するのではなく、Celmis 自体の開発に取り組む場合は、開発用オーバーレイを追加すると、ローカルビルドが再び使えるようになります。
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build
init-env.sh --check は、何も書き込まずに、まだ空の項目を報告します。
これはキャプチャしたセッションの描画であり、画面録画ではありません。図中の数値は 2026 年 8 月 26 日の実行で得られたもので、Compose の出力はインストールレポート内の logs/03-up.log からの逐語的な引用です。稼働中のスタックの隣では別のスタックを起動できません。docker-compose.yml で container_name が固定されているため、名前が衝突します。そのため、写真ではなく描画を使用しています。
停止する
docker compose down # stop, keep your data
docker compose down -v # stop and DELETE every volume
最初のユーザーと管理者
スタックが正常に動作すれば、/login のサインアップフォームをすぐに利用できます。このアカウントは通常のユーザーです。サインアップしても管理者権限は付与されず、最初に登録した人にも付与されません。
グローバル管理者は環境変数で設定します。.env にある CELMIS_MASTER_EMAIL と CELMIS_MASTER_KEY(パスワードとして使用)でサインインしてください。サーバーを運用する人が管理者になるため、最初にフォームを利用した人が管理者になるよりも、セルフホスト可能なインストールに適した方式です。両方の変数が設定されていない場合、このログイン方法は利用できません。また、この方法が使われるたびに監査ログに記録されます。
通常のアカウントを昇格するには:
docker compose exec api analyzer auth make-admin [email protected]
昇格したアカウント(または OIDC_ADMIN_ROLE によって管理者になったアカウント)はグローバル管理者です。システムの状態、運用、コンプライアンス、すべてのワークスペースを閲覧できます。ただし、スーパー管理者ではありません。スーパー管理者はマスターアカウントのみを指し、以下の権限を付与できる唯一のアカウントです。
ワークスペースのロール
すべてのワークスペースはテナントです。ユーザーはワークスペースごとに異なるロールを持つことができます。たとえば、あるワークスペースでは管理者、ほかの2つでは編集者になれます。
| ロール | そのワークスペースでできること |
|---|---|
viewer | 閲覧 |
member | 閲覧、レビュー課題のステータス変更 |
editor | プロンプトエディター:エージェントのシステムプロンプト、リポジトリごとのレビューポリシー(プロンプトテンプレート、フォルダールール、エージェントごとのプロンプトの上書き)、分析。メンバー、招待、チーム、LLM キー、Git 接続、ライセンスの管理はできません |
admin | editor の権限に加え、メンバーと閲覧者、招待、チーム、LLM キー、Git 接続を管理できます |
owner | admin の権限に加え、ワークスペースを削除できます |
各ロールを付与できる人:
- owner、admin、editor — 付与、変更、削除を行えるのはスーパー管理者のみです。ワークスペース管理者は、オーナーや別の管理者を降格できません。
- member、viewer — スーパー管理者、またはそのワークスペースのオーナー/管理者が付与できます(直接、または招待による付与)。招待で付与できるのは作成者自身が付与できるロールまでで、招待が承諾される際に再確認されます。既存のアカウントを直接追加できるのは、すでにそのアカウントと同じワークスペースを共有している場合に限られます。それ以外のユーザーには、承諾が必要な招待が送られます。
- パスワードリセットリンク — ワークスペース管理者が作成するリンクの対象範囲は、このワークスペースだけでなく、その人が所属するすべてのワークスペースに及びます。マルチテナントモードでは全員が個人用ワークスペースを所有するため、実際にはスーパー管理者だけが作成できます。マスターアカウントのリセットリンクを作成するルートはありません。
- 共有ワークスペースはスーパー管理者が作成します。全員にサインアップ時に個人用ワークスペースが作成され、そのオーナーになります。
スーパー管理者は管理 → ユーザー(/admin/users)で、ワークスペースをまたいでユーザーを管理します。どのページから行われた場合も、メンバーシップの変更はすべて、実行者、対象者、ワークスペース、変更前と変更後のロールとともに監査ログに記録されます。チームへのアクセスなしフィルターには、サインイン方法を問わず、個人用ワークスペースのみを持つアカウントが新しい順に表示されます。
参加する:招待とアクセスリクエスト
アカウントを持たない人への招待。 アカウントのないメールアドレスを招待すると、そのメールアドレスに紐づく一度限りのリンクが作成されます。招待した人はそのリンクを確認できます(Team ページからコピーしてください)。SMTP が設定されている場合は、メールでも送信されます。サインアウトした状態で開くと、/invite/<token> にワークスペース、ロール、招待した人が表示され、サインイン、サインアップ(AUTH_PASSWORD_LOGIN で許可されている場合)、Google、会社の SSO(有効になっている場合)が提示されます。いずれの場合も、リンクに戻って招待を承諾できます。承諾時には、招待した人が引き続きそのロールを付与できるか再確認され、監査記録が残り、リンクは使用済みになります。有効期限切れ、取り消し済み、使用済みのリンクには、その状態が表示されます。メールアドレスに紐づくリンクを別のアカウントで開いた場合は拒否されます。
自動承諾 — 検証済みアドレスのみ。 Google または会社の SSO でサインインし、ID プロバイダーがメールアドレスを検証済みとして示している場合(email_verified)、そのメールアドレス宛ての保留中の招待は、同じ承諾処理を通じてサインイン時に承諾されます(付与ルールを再確認し、監査記録を残し、一度限りで使用します)。パスワードアカウントがアドレスだけで自動承諾されることはありません。 Celmis はサインアップ時に入力されたアドレスを検証しないため、誰でも他人のメールアドレスで登録できます。パスワードアカウントは、送信されたリンクを開いてそこで承諾します。パスワードが設定され、Google/SSO がリンクされたアカウントも同様です。パスワードを設定した人は、引き続きそのパスワードでサインインできるためです。自動承諾で行われるのは、常にメンバーの追加のみです。すでに参加しているワークスペースへの招待は、ロールを変更せずに使用済みとなり、メンバーを削除すると、その人宛ての当該ワークスペースの有効な招待は取り消されます。
アクセスリクエスト。 個人用ワークスペースしか持たないサインイン済みの人には、ダッシュボードと /access-request に「チームのワークスペースへのアクセス権がまだありません — リクエストを送信」と表示されます。コメントは任意で、最大 1000 文字です。一度に保留中にできるリクエストは 1 件です。リクエストはキャンセルでき、拒否された後に新たなリクエストを送信できます。リクエストでワークスペースが指定されることはなく、承認されるまではリクエストした人にワークスペースは表示されません。決定できるのはスーパー管理者のみです。Administration → Access requests(/admin/access-requests)で、1 つ以上の(ワークスペース、ロール)の組み合わせを指定して承認します(すべて一括で適用され、各メンバーシップには via="access_request" の監査記録が残ります)。または、リクエストした人に表示される理由を添えて拒否します。別の方法(Users ページ、承諾済みの招待)でアクセス権が付与されると、保留中のリクエストは承認済みとして処理されます。決定済みのリクエストは履歴として一覧に残ります。リクエストした人は /access-request で決定を確認でき、次回アクセス時にはトースト通知も表示されます。承認されたワークスペースは、サインアウトせずにワークスペース切り替えメニューに表示されます。SMTP が設定されている場合、リクエストした人には決定が、マスターアドレスには新しいリクエストがメールで通知されます。それ以外の通知方法はありません。
POST /api/access-requests {comment?} | リクエストを送信(保留中のリクエストがある場合、またはアカウントにすでにチームアクセス権がある場合は 409) |
GET /api/access-requests/me | 申請資格と最新のリクエストを取得 |
DELETE /api/access-requests/me | 保留中のリクエストをキャンセル |
GET /api/admin/access-requests?status= | スーパー管理者:一覧表示。保留中を先に表示 |
POST /api/admin/access-requests/{id}/approve {grants:[{workspace_id, role}]} | スーパー管理者:1 件以上。重複不可、既存のワークスペースに限り、個人用ワークスペースは不可 |
POST /api/admin/access-requests/{id}/reject {reason} | スーパー管理者:理由必須 |
保留中でなくなったリクエストを決定しようとすると、409 が返されます。
リポジトリを接続する
- Settings → LLM Setup — プロバイダーキーを貼り付けます。データベースに保存される前に
CREDENTIAL_MASTER_KEYで暗号化され、UI では最初と最後の4文字だけが 表示されます。 - Connections — GitHub、GitLab、または Bitbucket のトークンを追加します。自分のアカウントではなく、マシンアカウントを使用してください。個人用トークンでは、自分がアクセスできるすべてのリポジトリにアクセスでき、トークンはバックアップ、ログ、スクリーンショットに残ることになります。
- Repositories → Add — プロバイダーからリポジトリを選ぶか、クローン URL を貼り付けます。インデックス作成はキューに登録され、ジョブは同じページに表示されます。
同じチェックアウトから、インデックス作成によって2つのものが作られます。レビューエージェントが推論に使うシンボルグラフ(定義、呼び出し、インポート)と、Q&A が検索に使う Qdrant の埋め込みです。12万シンボルのリポジトリなら、4コアで約1分かかります。
23の言語がグラフに解析されます。パーサーのない言語のファイルは、黙ってスキップされるのではなく、明示的に通知されます。analyzer graph-stats には、読み込まれたものと読み込まれなかったものが一覧表示されます。
コードについて質問する
チャットで質問すると、指定した数のリポジトリから ファイル:行の引用付きで回答します。回答は生成されると同時にストリーミングされます。
リポジトリをプロジェクトにまとめると、そのグループに対して質問できます。

回答では実際のコードが引用され、質問者が閲覧を許可されているコードだけが使われます。そのため、リポジトリを所有するチームの外部の人にも安心して質問を任せられます。誰が何を見られるかをご覧ください。
プルリクエストのレビュー
エージェントが差分を読み、GitHub、GitLab、または Bitbucket に指摘を投稿します。このインターフェースのスクリーンショットでその様子を見せるのではなく、レビューは投稿先にそのまま残されています。実際のプロジェクトにある50件のプルリクエストに、コメントも対象行に紐づいたままです。これらはTest repositoriesに一覧表示されており、下記の監査で誤りと判定された指摘を含め、出力は編集されていません。
グラフが構築されている場合、レビューには差分からは分からない情報も含まれます。別のリポジトリからの呼び出しも含め、変更対象のシンボルをほかに誰が呼び出しているかが分かります。グラフが構築されていない場合でもレビューは実行されます。ただし、より限定的な問いに答えるだけです。ベンチマークで測定されたのはこのケースです。
レビュアーとのやり取りと、学習する内容
最初のレビュー後も、レビュアーはプルリクエスト内で作業します。
- コメントコマンド。
@celmis help、start-review、review --force、remember: <rule>、および同じスレッドで回答される自由形式の質問 (PR コマンド)。 - 差分レビューと頻度。 新しいプッシュは、最後にレビューしたコミットからレビューされます。リポジトリでは、プッシュが集中した後に自動レビューを一時停止したり、キーワードでタイトルをスキップしたり、概要を説明に記載したりできます (レビュー設定)。
- チームのメモリーと学習。 チームが明示したルールや、チームが却下した指摘は、シャドーモードで効果を事前に判断したうえで、その後のレビューに反映されます (メモリーと学習)。
- 課題のバックログ。 指摘はプッシュ後やマージ後も追跡され、コードから不具合が解消されたことが確認されると、自動的に解決されます (課題のバックログ)。
- Jira タスクのコンテキスト。 ビジネスロジックエージェントは、プルリクエストで指定されたタスクに照らして変更を確認し、受け入れ基準のチェックリストを表示します (Jira)。
- 生産性指標。 オーナーと管理者向けに、プルリクエストの履歴からサイクルタイムと4つの DORA 指標を算出します (生産性)。
- 誰が何を見られるか。 ロールとアクセス権。これらの機能はいずれも、MCP と同じルールに従い、閲覧権限のある人に対してのみリポジトリを読み取ります (MCP のアクセス権)。チャットの応答と Jira のチェックでは、質問者が開けないコードを引用することはありません。
- リポジトリを別のワークスペースと共有する。 調査のために、期間を定めて、開発者トークンにそのリポジトリが記載されている少数の人と共有できます。オーナーが許可しない限り、パスは非表示になり、質問は無効になります (共有)。
- コーディングアシスタント向けのコンパクトな MCP プロファイル。
/mcp/devは、エディター向けに調整された読み取り専用ツールを11個提供します。「このサービスでは認証をどのように行っていますか」と尋ねるhowto、ワークスペース独自のナレッジパック向けのbriefとskills、さらに Claude Code プラグインを利用できます (開発者プロファイル、 howto)。
ベンチマークで誤りと判定された指摘はすべて、ソースで確認し、判定結果とともに公開しました。79件中33件は、ゴールドセットに含まれていない実際の不具合であることが判明しました。その調査内容は、各指摘のコードとパーマリンクを含めて 誤検知の監査にまとめています。どの指摘についても、異論があればご確認ください。
依存関係、SBOM、エビデンスパック
依存関係の監査は決定論的です。ツールがインストールされている場合はネイティブの監査ツールを使い、それ以外ではどこでも OSV を使います。モデルは関与しません。キーを設定している場合、言語モデルはサマリーを作成しますが、何が脆弱かを判断することはありません。

監査ごとに2つのファイルが生成され、どちらにも LLM のキーは必要ありません。
-
SBOM — すべての依存関係、そのバージョン、パッケージ URL、およびそれらに対して確認されている脆弱性を記載した CycloneDX インベントリです。「SBOM を送ってください」と言うときに指しているのがこのファイルです。
-
エビデンスパック — 監査記録一式です。すべての SBOM、すべての検出結果、過去の実行履歴、および各ファイルの sha256 が含まれます。これらのハッシュはアーカイブの内部整合性を証明しますが、それだけでは、そのアーカイブがここから出たものだとは証明できません。マニフェストにはマニフェスト自身のハッシュが記録されず、誰でもファイルを編集してそのエントリーを書き換えられるからです。エクスポートでは、マニフェスト自体の sha256 が
X-Celmis-Manifest-SHA256に返されます。エビデンスパックを公開しない場所でこれを公開すれば、第三者は、ファイルと一緒に渡されていない値と照合して、私たちを信頼することなく検証できます。後から中身を変更できるフォルダーには、何の証明力もありません。エビデンスにするのはマニフェストです。この最後の文は、以前は誰も実行に移せない主張でした。パックを検証するには、このリポジトリをクローンし、Python 3.13 の下で40個の依存関係をインストールする必要がありました。つまり、作成者の出力を検証するために、作成者のツールチェーン一式が必要だったのです。検証機能は、依存関係もネットワーク呼び出しもない独立したパッケージになりました。
pip install celmis celmis verify evidence-pack.zipCelmis を一度も実行したことのないマシンでも、Python 3.9 以降であればオフラインで使えます。マニフェストに記載されたすべての sha256 を再計算し、記載されているが存在しないファイル、ハッシュが一致しないファイル、記載されていないが存在するファイルを報告します。問題がなければ終了コード 0、問題が見つかれば 1 です。これは検証ツールのみです。プラットフォーム自体は docker compose で動作する6つのサービスから成り、pip ではインストールできません。引数なしで実行すると、パッケージがそのことを示します。
これらに加えて、コードから生成される技術文書もあります。モジュールの PRD、機能文書、統合ガイドが含まれます。これらはお手元に残り、サブスクリプションが終了した後も使い続けられます。
これが今必要な理由。 2026年9月11日から、EU サイバーレジリエンス法により、製造業者は積極的に悪用されている脆弱性を24時間以内に ENISA へ報告することが義務付けられます。正式な SBOM 義務化は2027年12月に始まりますが、まずコンポーネント単位の可視性がなければ、24時間以内の報告には対応できません。影響を受けるものを報告するには、何が含まれているかを把握する必要があります。
Celmis はコンプライアンスへの準拠を主張しません。今後も主張しません。 提出に必要な成果物を作成します。提出内容が適切かどうかは弁護士の判断です。それ以外をほのめかすツールは、誤った安心感を売ることになります。
監査ページがもう一つ、はっきりと示すことがあります。誰も気づかない、見落とされがちな問題です。スキャンされていないエコシステムは、クリーンなエコシステムとまったく同じように、脆弱性ゼロと報告されます。 検出結果の横にカバレッジが表示されます。各結果をどの監査ツールが生成したのか、さらに重要な点として、何が未検査で、その理由は何かがわかります。
ここから修正する
何かを見つけるのは、改善サイクルの半分にすぎません。組み込みの Claude Code セッションがインストール環境内で実行され、チェックアウトを編集します。その後、ランナーがコミットし、ブランチをプッシュして、プルリクエストを作成します。
サブスクリプションを使い、自分のマシンで実行
私たちから購入するキーはなく、モデルもバンドルされていません。Cursor と同じように、ご自身の Claude サブスクリプションに接続します。お使いのノートパソコンで claude setup-token を一度実行し、トークンを設定画面に貼り付けてください。トークンは認証情報ストアに暗号化して保存され、後で実行するセッションで使用されます。
スロットは 2 つあり、次の順に解決されます。
| 個人用 | ご自身のサブスクリプション。他の人には表示されません |
| ワークスペース | 管理者がワークスペースと共有する 1 つのサブスクリプション — 明示的なオプトインが必要です |
ワークスペース用スロットは、誰かが有効にするまでオフになっています。保存する前に、その理由をインターフェースで説明します。1 人のサブスクリプションを複数人で共有すると、Anthropic の一般消費者向け利用規約に違反する可能性があります。 これはサブスクリプションの所有者が判断することであり、製品側でひそかに進めることはありません。
また、セッションは誰かのクラウド上で実行されるわけではありません。ご自身のインストール環境で、セッションごとに分離されたワークスペース内で実行されます。これによって得られるのは「クラウドへのアクセス」ではありません。コードが置かれたマシンを自分で管理でき、オフィスのノートパソコンからでも、電車の中でスマートフォンからでもアクセスできるということです。自分が運用するサービスにアクセスするのと同じ理由です。自分のものであり、稼働しているからです。
これが、アラートと、スマートフォンからの修正のすべてです。アラートが届き、それを読んだ場所から修正を始められます。
依存関係の監査で脆弱性が見つかると、ここから修正ボタンが表示されます。空のチャットを開くのではなく、リポジトリ、パッケージ、両方のバージョン、作業範囲をすでに記述したうえで、セッションに渡します。

実際に検出された問題を使った一連の流れを、最初から最後まで見てみましょう。既知の脆弱性がある lodash 4.17.11 のケースです。セッションを開始してからプルリクエストが開くまで、5 回のやりとりで220 秒です。
Read package.json
→ "Only package.json has lodash; no requirements.txt/pyproject/go.mod exist here."
Edit package.json: "lodash": "4.17.11" → "4.18.0"
mcp__exec__run: cat package.json | grep -A2 lodash; ls
→ "Confirmed no other manifest files exist, so no other changes were needed."
GitHub でプッシュされたブランチと、作成されたプルリクエストです。

その差分に含まれていないものに注目してください。すぐ上と下の行には axios 0.21.1、minimist 1.2.0、node-fetch 2.6.0 があります。どれも古く、同じ監査で指摘されていますが、すべてそのままです。タスクではマニフェストだけを対象としており、エージェントがついでにさらに 3 つも整理していたら、レビューしやすくなるどころか、かえって悪い結果になっていたでしょう。
これはスクリーンショットではなく、実際に開かれたプルリクエストです。
celmis-demo-gateway#6
— ブランチは celmis-agent/b8960e01、コミットは 1 つ、変更は +1/-1 です。

その記録の中で、差分よりも重要な点が 2 つあります。エージェントは他にマニフェストがないと決めつけず、サンドボックス内でコマンドを実行して確認しました。また、タスクには「マニフェストのみ。無関係な依存関係には手を付けない」とあり、変更は正確に 1 行だけです。
ランナーが許可すること、許可しないこと
これはプロンプトではなく、ランナーによって決まります。エージェントに何かを許可する前に読んでおく価値があるのは、この部分です。
- 独自のシェルはありません。
Bash、WebFetch、WebSearch、ノートブックの編集は禁止されています。コマンドはサンドボックスコンテナ経由で実行されます。これは独自の uid と読み取り専用のルートファイルシステムを持つ、別のサービスです。 - Git はランナーの役目です。 エージェントがコミットやプッシュを行うことはありません。作業が完了したとき、または Finish & push を押したときに、ランナーがコミットし、ブランチをプッシュして PR を作成します。デフォルトブランチには決してプッシュしません。
- プロバイダーの制限に達しても、一時停止するだけで、作業は失われません。 上記の実行で最初に試したとき、セッションの途中で週間アカウント制限に達しました。セッションは終了せず、
pausedに移行し、14 日間再開可能な状態で作業を保持し、一般的なエラーではなくプロバイダー独自のメッセージを表示しました。2 つ目のキーで作業を完了できました。 - セッションを確認できます。 出力はリプレイ機能付きの SSE でストリーミングされるため、再接続すると最初からではなく、中断したところから再開します。
接続にはセットアップトークンを使い、ユーザーごと、またはワークスペースごとに保持します。保存後に API がトークンを返すことはありません。確認できるのは、トークンが存在するか、まだ機能しているかだけです。
アラートと、スマートフォンからの修正
上記のループは依存関係の検出結果から始まります。また、本番環境から始めることもできます。
任意の監視システムをワークスペースの取り込み URL に設定すると、アラートが Celmis に届きます。
POST /webhook/alerts/{workspace_id}.{secret}
Grafana の統合アラート機能の Webhook はそのまま解析されます。それ以外は {"title", "body", "severity", "repo"} を送信できます。シークレットの値はワークスペースごとに Fernet で暗号化して保存され、定時間比較で照合されます。エンドポイントは設計上、認証なしです。監視システムは OAuth を利用できないためです。また、構造上、テナントに紐付けられています。トークンが書き込めるのは、紐付けられたワークスペースだけです。
これにより、ノート PC がなくても次の流れが実現します。
- アラートが発生します。Celmis に届くと、ワークスペースが連携している任意のチャンネル(Slack、Discord、Google Chat、または通常の Webhook)にすぐ送信されます。わざわざ開くのを覚えておく必要があるページではなく、普段使っている場所に届きます。
- アラートを開きます。
route_incidentはスタックトレースを受け取り、どのリポジトリに属するか、またその所有者が誰かを特定できるため、アラートにはリポジトリの情報が含まれます。 - ここから修正を押します。空のチャットではなく、アラートをすでに含んだ状態でセッションが開きます。
- ランナーがコミットし、ブランチをプッシュしてプルリクエストを作成します。

この 4 つの手順に、チェックアウトも、ターミナルも、信頼できるマシンも必要ありません。作業は独自のインストール環境内で行われ、スマートフォンはその画面として機能します。
同じページには、ワークスペースが受け取ったすべてのアラートが表示されます。そのため、誰も対応しなかったアラートも、チャンネル内で失われずに確認できます。
この間に記録される内容。 2 種類の記録があり、それぞれ異なる問いに答えます。
- 監査ログ — サイズに応じてローテーションされる追記専用の JSONL です。時刻、モード、操作、リポジトリで絞り込み、CSV としてエクスポートできます。誰が、どのリポジトリに対して、いつ何をしたかが分かります。デフォルトの保持期間は 90 日で、アクティブファイルは削除されず、アーカイブのみがローテーションされます。
- リソース履歴 — インストール環境自体のサンプルと集計データです。サイジング用の資料として CSV にエクスポートできます。実行コストはいくらかかったかが分かります。
午前 2 時に誰かのスマートフォンからエージェントのセッションがリポジトリを編集することは、後から再構成できなければならない出来事そのものです。実際に再構成できます。
リポジトリを横断した作業を依頼する
上記の各画面で一度に扱えるのは、リポジトリ、プルリクエスト、検出事項のいずれか一つです。ボタンとしては適切ですが、条件によって定義される集合を扱うには適していません。
ドキュメントがないすべてのサービスのドキュメントを生成する。これは一文ですが、インターフェースで行うと、40 件の中から該当するものを探し、ボタンを 40 回押すことになります。acme-ai 配下のうち、過去 30 日間監査されていないすべてのものを監査するには、フィルター、保存した選択、そして一括操作を備えたサブシステムが必要です。あるいは、一文で済ませる必要があります。
そこで、一文を入力するボックスと、その背後に用意された動詞の簡潔なカタログがあります。単一オブジェクトに対する作業は、本来あるべき場所であるボタンから実行します。
最初の押下では何も実行されません。 解釈は推測であり、これらの動詞には費用と時間がかかります。たとえば、ボールトの構築、複数のレビューエージェントの起動、グループ全体の監査などです。そのため、一文に対する回答は作業そのものではなく、この条件に該当するリポジトリの一覧であり、その下に 2 つ目のボタンが表示されます。確認するのは意図ではなく、対象の集合です。
スコープを再確認するのは、依頼時ではなく、確認した時点です。 質問してからボタンを押すまでの数秒間に登録されたリポジトリが、「すべて」を対象とする集合に黙って加わることはありません。作業が行われる場所でチェックを実行するという、製品全体を規定する同じルールが、ここにも適用されます。
自動化された呼び出し元が、上限のない一括処理をキューに追加することは決してありません。 動詞には上限があり、ワークスペースにスコープが限定され、明示的な実行者が必要です。ここでは、暗黙のリクエストコンテキストを参照しません。キューを処理するコネクターにはリクエストがなく、ワークスペースを推測する関数は、あるテナントの自動化が別のテナントのリポジトリにアクセスする経路になるからです。
外部エージェント(MCP 経由)、組み込みエージェント、そしてこの 4 つのサービスを監査して結果を返すチケットコネクターという 3 つの呼び出し元が、同じ動詞を使うようになっています。実装を意図的に共通化しています。別の「監査を開始する」実装を作ることは、実行中の処理、重複排除、強制再起動に関するルールをもう一組作ることになります。そして、誰も保守しないコピーこそが、キューを破損させます。
誰が何を見られるか
アクセスはリポジトリごと、チームごとに解決され、すべての画面に一律に適用されます。Q&A、グラフ、コード検索、生成されたドキュメント、MCP が対象です。
| 設定 | 効果 |
|---|---|
visibility: none | 調査において、そのリポジトリは存在しないものとして扱われます |
visibility: metadata | ドキュメントとアーキテクチャに関する注記のみを表示します |
visibility: code | ソースコードを読み取れます |
deny_globs | code であっても優先されます。認証情報、暗号処理、データベース接続、シークレットの検証が対象です |
allow_globs | 設定した場合は許可リストになります。ただし、deny による除外は引き続き適用されます |
これにより、隣接するチーム間の共有が、単なる約束ではなく実際に機能します。リポジトリを読み込み、他のチームに質問する権限を付与し、読み取られてはならないパスを拒否します。相手チームは回答を得られます。これらのファイルは、すでに含まれていた回答から後で除外されるのではなく、読み取り元で拒否されます。
言語と形式
17 個のグラフモジュールに加え、モジュールがない言語向けに、tree-sitter のタグクエリを使う汎用パスも備えています。
コード — Python、TypeScript、JavaScript、Go、Java、C#、C++、PHP、Vue などに、汎用パスで対応します。
インフラストラクチャ — Dockerfile、docker-compose、Helm、Kubernetes マニフェスト、Terraform、CI ワークフローに対応します。ここはほとんどのコードインテリジェンスツールが対象外とする領域です。関数から、それを実行するサービス定義まで横断して質問に答えられるのは、このためです。
決定論的なチェック — モデル不使用、誤検知なし
以下の各チェックは、ファイルを読み取って判定します。問題があると判断する際に言語モデルは一切関与しないため、調整によってではなく、仕組み上、誤検知率はゼロです。
この違いこそが重要です。誤検知が約20%になると、開発者はツールのコメントをまったく読まなくなります。ひとつの誤検知で数秒の注意を奪われ、千件もあれば、ツールの言うことをすべて読み飛ばすようになったチームができあがります。ここではモデルを説明と優先順位付けに使いますが、検出には決して使いません。
| チェック | 読み取るもの | 検出するもの |
|---|---|---|
install_script | package.json のライフサイクルフック | インストール時にコードを実行する依存関係 |
python_build_hooks | pyproject.toml / setup.py | Python パッケージのビルド時に実行されるコード |
cargo_build_script | Cargo.toml | build.rs を含むクレート |
non_registry | マニフェストとロックファイル | レジストリではなく、Git URL や tarball から取得された依存関係 |
suspect_name | 依存関係の一覧 | タイポスクワッティング — 人気パッケージの名前を1文字変更しただけの名前 |
lock_drift | マニフェストとロックファイル | マニフェストの宣言内容と一致しなくなったロックファイル |
cross_repo_drift | PR の差分、その後に関連リポジトリ | あるリポジトリで変更された定数が、ほかのリポジトリでは更新されずに残っている状態 |
一般的なCVEスキャンは、意図的にこの一覧に含めていません。OSV-Scannerがすでに実施しており、無料で、事実上の標準となっているためです。Celmisはこれを実行し(各エコシステム固有の監査ツールである pip-audit、npm audit、govulncheck、cargo audit も実行します)、機能ではなく入力として扱います。
コンプライアンスについて。 Celmisは監査で求められる成果物を生成します。CycloneDX SBOM、依存関係のインベントリ、タイムスタンプと各検出結果の根拠を含む検出履歴です。ただし、提出書類が十分であるとは主張しません。その判断を正直に下せるツールはありません。監査人が何を受け入れるかは、業種、管轄区域、そして自社の統制によって異なります。成果物を用意し、評価はそれを職務とする人たちに任せてください。
Claude Code とその他の MCP クライアントを接続する
CelmisはインデックスをMCP経由で公開するため、エージェントは、手元にないチェックアウトをgrepする代わりに、シンボルを検索し、APIの公開範囲を読み取り、利用箇所を見つけることができます。
HTTP経由(稼働中のスタックでは /mcp/ で提供されます):
# A token is per person and names the repositories it may read. The
# superadmin issues it (Administration, MCP tokens) or on the server:
docker compose exec api analyzer mcp issue-token \
--user [email protected] --workspace acme --repos 'acme/shop-*' --days 30
トークンが、その人に読み取り権限のないリポジトリに届くことはなく、すべての呼び出しが監査されます。アクセスルールが設定されていないリポジトリは、メンバーもアクセスできません。アクセス、トークン、監査の仕組みについては、MCP access をご覧ください。
// ~/.claude.json (or .mcp.json in a project)
{
"mcpServers": {
"celmis": {
"type": "http",
"url": "http://localhost:8000/mcp/",
"headers": { "Authorization": "Bearer <the token you just minted>" }
}
}
}
外部クライアント向けの単一プロジェクト。 プロジェクトのページでは、スーパー管理者がプロジェクトトークン(cmcp_...、有効期間は1時間から90日、一度だけ表示、取り消し可能)を作成できます。このトークンは、プロジェクトのファイルスコープで絞り込まれた、そのプロジェクトのリポジトリのみを対象とし、search_project と ask_project の2つのツールを通じて利用できます。詳細と claude mcp add コマンドについては、Archives and project tokens をご覧ください。
HTTPを介さないstdio経由:
{
"mcpServers": {
"celmis": {
"command": "docker",
"args": ["compose", "exec", "-T", "api", "analyzer", "mcp", "serve"]
}
}
}
エージェントが質問できること
HTTP マウントでは 51 個のツールが提供されますが、クライアントにすべてが表示されるとは限りません。読み取り専用のツールは 35 個です。書き込みを行う 16 個のツール — add_repo、
start_dep_audit、
cancel_dep_audit、
generate_docs、
set_auto_review、
migrate_consumers、
ack_alert、
retry_job、
cancel_job、
set_budget、
update_review_setting、
propose_review_rules、
generate_review_rules、
review_pr、
index_repo、
update_issue —
は書き込みスコープ(write:repos、write:config、write:reviews)を必要とします。デフォルトのトークンにはこのスコープがないため、読み取りクライアントのツール一覧には表示されず、名前を指定して呼び出しても拒否されます。読み取り専用ツールが答えるのは次の内容です。これらは grep では答えられない質問です。
list_workspace_repos | どのリポジトリが存在し、インデックス化・ドキュメント化されているか、自動レビューが有効か |
search_symbols | プロジェクト全体で、関数やエンドポイントが定義されている場所 |
find_consumers | どのリポジトリがシンボルを呼び出しているか — 一度もクローンしていないリポジトリも含む |
get_api_surface | サービスが実際に公開している HTTP ハンドラー |
get_owner · list_deprecations | ファイルの担当者、廃止予定のものと、まだそれを使用しているユーザー |
route_incident | スタックトレースをもとに、該当するリポジトリと担当者 |
bootstrap_client · start_integration_walk | 他チームのサービスを呼び出すためにクライアントが必要とするもの |
get_dep_audit · list_dep_findings | 最新の監査とその検出結果(深刻度の高い順) |
get_review · get_review_policy | PR の最新レビューと、どのエージェントがどこで実行されるか |
list_reviews · get_review_run | 最新のレビュー実行と、1 回の実行での検出結果(実行 ID、またはリポジトリと PR 番号で指定) |
list_issues | 追跡中のレビュー課題(深刻度の高い順)とステータス別の件数 |
ask_code · search_code | コードに関する文章での回答(1 回のモデル呼び出しで、Q&A として記録);シンボル、使用箇所、担当者、アーキテクチャの検索 |
HTTP マウントでは review_pr(1 つの PR、またはすべてのオープン PR のレビューをキューに追加)、index_repo、update_issue(課題のステータスを設定)でも書き込みを行います。いずれも write:repos が必要です。
| get_review_settings | 適用中のレビュー設定と、各値の取得元 |
| get_spend · get_usage · get_budget | モデル、インターフェース、日別の LLM 支出;レビューの使用状況;月間上限 |
| list_alerts · list_jobs | 受信アラート;ステータス別の件数を含むバックグラウンドジョブ |
| audit_delta · export_sbom | 前回の監査以降の変更;SBOM のダウンロード URL |
| list_members | ロールとチームを含むワークスペースのメンバー |
| howto | リポジトリで特定の処理(db、auth、config、http_client、logging、messaging、cache)を行う方法:コードの抜粋、読み取る環境変数名と設定名、およびその値の取得元(値そのものは含まない);/mcp/ の read:graph と /mcp/dev/ の read:code が必要 |
2 つのトランスポートは、提供するツールが異なります。 stdio 経由の analyzer mcp serve は、グラフ形式の古いツール 13 個(find_symbol、find_callers、query_graph)を提供します。HTTP マウントは読み取り専用ツール 35 個(プロジェクトトークンが必要な 2 つのツール、search_project と ask_project を含む)を提供します。どちらももう一方のサブセットではありません — 必要なツールに応じてトランスポートを選んでください。
各ツールに必要なスコープと失敗時の動作を含む手順ガイドは、.claude/skills/celmis-mcp/SKILL.md にあります。このリポジトリを開くと、Claude Code が自動的に読み込みます。
エージェントが尋ねられること
search_symbols を 1 回呼び出し、コントラクトのシンボルを 1 つ指定すると、2 つのリポジトリから、2 つの言語で結果が返ってきます。どちらのリポジトリもチェックアウトしていないクライアントにです。diff では決して越えられない境界を、これなら当たり前のように越えられます。
以下の表は、stdio サーバーのグラフ形式のツールセットです(analyzer mcp serve、13 個のツール)。/mcp/ の HTTP マウントでは、Streamable HTTP 経由で合計 51 個(読み取り 35 個、書き込み 16 個)のツールを提供し、/api/ と同様に認証されます。トークンからは、スコープで許可されたツールだけが見えます。グラフ検索ツールは次のとおりです。
| ツール | 回答する内容 |
|---|---|
list_repos | インデックス化されているリポジトリと、各インデックスの最新度 |
list_groups | どのリポジトリがグループ化されているか。これにより、リポジトリをまたぐ質問の対象範囲が決まります |
find_symbol | インデックス化されたすべてのリポジトリを対象に、名前が定義されている場所 |
get_symbol | 定義そのものと、そのファイルおよび行の範囲 |
find_callers | これを呼び出しているもの。grep ではうまく答えられず、グラフなら正確に答えられる質問です |
find_callees | これが呼び出すもの。1 ホップ先まで |
cross_repo_edges | リポジトリの境界を越える呼び出し |
query_graph | 上記 7 つのツールでは対応できない質問に使う、読み取り専用の Cypher |
cross_repo_edges は、この製品がそもそもシンボルグラフを備えている理由そのものなので、理解しておく価値があります。diff のみを使うレビュー担当者(上のベンチマーク表にあるすべてのツール。グラフが空の場合のこのツールも含みます)は、関数のシグネチャが変わったことを教えてくれます。しかし、別のリポジトリにあるサービスが古い形式のまま呼び出していることは教えられません。そのリポジトリを開いたことがないからです。リポジトリを一度グループ化すれば、その質問にも答えられるようになります。
> which services outside this repo call PaymentGateway.charge?
ベンチマークの順位が製品の実力を示すどころか、実力を低く見せてしまうのもこのためです。ベンチマークの対象は、単一リポジトリ内で完結するプルリクエストなので、エッジが越える先の別のリポジトリがありません。この機能は実在しますが、ベンチマークでは測れません。これはベンチマークについて述べているのであって、信じ込んでほしいという主張ではありません。MCP クライアントを自分のグループに接続して、確かめてみてください。
結果
Celmis は Martian Code Review Bench の
オフラインセットで実行しました。厳選されたプルリクエスト 50 件と、人間が作成したゴールデンコメント 173 件を対象に、LLM の判定者がゴールドセットと照合して採点しました。e0db376 で gemini-3.6-flash を使い、temperature 0.1、推論トークンなしで測定しています。
| 判定者 | F1 | 適合率 | 再現率 | 順位 |
|---|---|---|---|---|
| claude-opus-4.5 | 47.5% | 52.4% | 43.4% | 17 / 50 |
| claude-sonnet-4.5 | 44.9% | 48.0% | 42.2% | 17 / 50 |
| gpt-5.2 | 42.7% | 46.0% | 39.9% | 17 / 50 |
判定者によって F1 は 4.8 ポイント変動します。順位はまったく変わらず、3 者すべてで 17 位です。
実行全体の費用は $5.88、プルリクエスト 1 件あたり $0.118 で、指摘を 153 件生成しました。PR あたり 3.06 件です(欠陥 114、セキュリティ 27、契約 6、構造 6)。
この比較が公平である理由。 Martian は、ベンチマークのリポジトリにある 49 個のツールについて、同じ 50 件の PR と同じゴールデンコメントを対象に、同じ 3 者の判定者で評価した結果を独自に公開しています。他のツールを再採点することはせず、公開済みの値をそのまま使用し、私たちの結果を追加しています。次のコマンドで表全体を再現できます。
python3 autoloop/offline_table.py anthropic_claude-sonnet-4-5-20250929
オフラインの結果は公開リーダーボードではありません。 Martian は 2 種類のベンチマークを実施しています。公開リーダーボードは オンライン ベンチマークで、開発者が実際に修正した内容に基づき、実際のプルリクエスト 200,000 件を採点します。この表は オフライン ベンチマークで、厳選された PR 50 件をゴールドセットと照合して採点します。測定対象が異なり、数値を相互に置き換えることはできません。「ツール X は Martian で 1 位」といった主張は、通常、オンラインの表、別の指標、または別の判定者を指しています。
この数値に含まれないもの。 ベンチマークセットが、単一リポジトリ内に孤立したプルリクエストで構成されており、シンボルの利用先となる別のサービスが存在しないため、50 件すべてでグラフは空でした(graph_status は null、すべてで drift は空)。この製品がシンボルグラフを使って追跡する、リポジトリをまたいだドリフトは、上記スコアにまったく寄与していません。ここでは測定できず、この表からその性能を主張するものでもありません。実際のコードで動作する様子は、テスト用リポジトリをご覧ください。
偽陽性の監査
ベンチマークの採点には、構造的な限界があります。判定者は私たちのコメントを、人間が作成したゴールデンコメントの有限なリストと照合するため、注釈者が記録していない正しい指摘は、仕組み上誤りとして数えられます。測定対象のコミット時点のソースコードで、私たちの指摘 79 件すべてを確認し、それぞれに判定を付けました。
偽陽性と採点された 79 件のうち、33 件はゴールドセットに含まれていない実際の欠陥で、38 件は本当に誤っており、8 件はコードから判断できませんでした。つまり、この実行の真の適合率は、測定値の 48.0% ではなく 69.7% から 75.0% の範囲になります。ただし、この補正値は上の表の数値と比較できません。他のツールは同じ方法で監査されておらず、その偽陽性にも同程度の実際の欠陥が含まれている可能性が高いためです。他のツールとの比較では、測定値の 48.0% が正直な数値です。全ツールに同じ方法を適用しているからです。
本当に誤っていた 38 件のうち 24 件には、4 つの共通する根本原因があり、どれも「モデルの性能が低い」ことではありません。4 つとも、モデルに何を見せたかに関する問題です。最も多かったのは、同じファイル内で宣言されているものの、エージェントに渡された抜粋の範囲外にあった識別子です。メソッドのパラメーターが 26 行上にあったり、インポートが 3 行目にあったり、attr_reader が 18 行目にあったりしました。
完全なレポートでは、79 件すべてについて、主張、該当コミット時点のコード、判定、根拠、およびパーマリンクを掲載しています。そのため、同じ証拠を見ながら、どの判定にも異議を唱えることができます。
テスト用リポジトリ
上記の実行で行われたレビューはすべて、現在も公開されています。これらは実在するプロジェクトの実際のプルリクエストで、履歴を含めてフォークされ、Celmis が記入したインラインコメントが付いています。
| フォーク | PR |
|---|---|
| celmis-bench/keycloak | 9 |
| celmis-bench/grafana | 10 |
| celmis-bench/discourse-graphite | 10 |
| celmis-bench/cal.diy | 10 |
| celmis-bench/sentry | 6 |
| celmis-bench/sentry-greptile | 4 |
まず確認するなら、こちらがおすすめです。
- keycloak#17 — Keycloak のテストストレージプロバイダーにおける null 参照と、リカバリーコードのインデックスに関する質問
- grafana#16 — Legacy メトリクスに対して記録された Storage エラー。このファイルにある同じ間違いの 3 件中 1 件です
- cal.diy#11 — 非同期コールバックを使った
forEachにより、削除処理が実行完了を待たずに進み、周囲のtryでは何も捕捉されません - sentry#11 — 1 件の Kafka コンシューマー PR に対する 7 件のインラインコメント
ここで読めるのは未編集の出力で、上記の監査で誤りと判定された指摘も含まれています。スコアリング後に削除されたものはありません。
設定
./scripts/init-env.sh は .env.example から .env を作成し、すべてのシークレットを生成します。サンプルでは、各シークレットを意図的に空にしています。以前のバージョンでは、生成コマンドが変数の隣に書かれていましたが、dotenv ファイルにはインラインコメントを記述できません。そのため、これをコピーしたインストール環境では、リポジトリに出力されたマスターパスワードが使われていました。
設定がコンテナに渡されるのは、docker-compose.yml の environment: ブロックを通じてのみです。イメージには .env は含まれません。ここに記載されていない変数は、.env の内容にかかわらず、コードのデフォルト値が使われます。
GET /healthz は、プロセスが実際に解決したレビューのタイムアウト値を返します。これにより、設定が反映されたかどうかを確認できます。
タイムアウト値は .env.example にまとめて記載され、次の不変条件で関連付けられています。
REVIEW_LLM_TIMEOUT_SECONDS × (1 + RETRY_FACTOR) ≤ REVIEW_TIMEOUT_SECONDS
一方を増やす場合は、もう一方もそれに合わせる必要があります。これをテストで検証しています。
| 変数 | デフォルト | |
|---|---|---|
REVIEW_TIMEOUT_SECONDS | 900 | 1 件のレビューに使える実時間です。これを過ぎると後半のステージは停止し、コメントでその旨が伝えられます |
REVIEW_LLM_TIMEOUT_SECONDS | 300 | 1 回のモデル呼び出しのタイムアウトです。推論に時間がかかるモデルでは、約 600 に増やしてください |
REVIEW_LLM_TIMEOUT_RETRY_FACTOR | 2.0 | タイムアウト後の再試行で、待ち時間をどれだけ延ばすかを指定します。1.0 にすると延長されません |
REVIEW_MAX_DIFF_SIZE_BYTES | 500000 | これを超える差分は切り詰められず、拒否されます |
REVIEW_VERIFIER_ENABLED | false | LLM による誤検出の却下機能です |
REVIEW_VERIFIER_MIN_FINDINGS | 1 | 機能が有効な場合に却下機能を起動する、立証済みではない指摘の最小数です |
REVIEW_AGENT_CONCURRENCY | 3 | 1 件のレビューあたり、同時に実行するプロバイダー呼び出し数です |
CELMIS_JOB_LEASE_SECONDS | 600 | ワーカーから応答がない場合に、ジョブを再取得できるまでの上限時間です |
CELMIS_DEPLOYMENT_MODE | single_tenant | multi_tenant にすると、ワークスペースが互いに分離されます |
運用
docker compose logs -f api # follow the API
docker compose exec api analyzer graph-stats <repo> # what parsed, what did not
./scripts/backup.sh # Postgres + volumes
./scripts/restore.sh <archive>
管理 → モニタリングでは、キューの深さ、ワークスペースごとの利用額、エージェントごとのモデル設定を確認できます。使用量とコストでは、利用額を対象ごとに分類して表示するため、ドキュメントの一括ビルドがチャットの利用分として表示されることはありません。
サーバーへのデプロイは、サーバー上で実行する ./scripts/deploy-on-server.sh v0.1.0 です。公開済みのイメージを取得し、Caddy の背後でスタックを起動して、AGPL のフッターリンクが参照するビルド情報を記録します。このために、そのマシンの外部にある認証情報は必要ありません。
docs/ORACLE_CICD.md、または一般的な VM を使う場合は docs/HETZNER.md を参照してください。
ローカル開発
# Postgres and Qdrant from compose, everything else on the host
docker compose up -d postgres qdrant
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
alembic upgrade head
uvicorn src.api.main:app --reload --port 8000
cd web && npm install && npm run dev # http://localhost:3000
pytest -q # the suite
ruff check . # lint, ratcheted at zero
cd web && npx tsc --noEmit
CLI リファレンス
analyzer は pip install -e . でインストールされます。Docker 内では
docker compose exec api analyzer … を使用します。すべてのコマンドで --help を指定できます。
analyzer init | ワークスペースの構成を作成します |
analyzer index <path|url> | リポジトリを解析してグラフにします |
analyzer ask "<question>" | 質問を 1 つ受け付け、出典付きで回答します |
analyzer chat | 対話セッションを開始します |
analyzer review <provider> <repo> <pr> | プルリクエストをレビューします。--post で公開します |
analyzer generate | ドキュメント保管庫を構築します |
analyzer refresh | 変更された内容を再インデックスします |
analyzer graph-stats <repo> | 言語ごとの解析結果を表示します |
analyzer serve | Docker を使わずに API を起動します |
analyzer review-serve | Webhook レシーバーのみを起動します |
グループ化されたサブコマンド:analyzer repo、analyzer group、analyzer auth、
analyzer mcp、analyzer scip。
アーキテクチャ
┌──────────────┐
GitHub / GitLab ──▶│ webhook │──┐
Bitbucket └──────────────┘ │
▼
Browser ──▶ web (Next.js) ──▶ api (FastAPI) ──▶ Postgres jobs, policies, audit
│ Qdrant embeddings
│ sandbox untrusted execution
▼
model provider
(direct, or via a LiteLLM gateway)
- Postgres には、ジョブ、ポリシー、実行履歴、利用額、監査ログが保存されます。
永続的なジョブキューはテーブルとして実装されています。キューからの取得には
SELECT … FOR UPDATE SKIP LOCKEDを使用し、ワーカーはあらかじめ時間を推測するのではなく、 作業中にリースを更新します。 - Qdrant には埋め込みが保存されます。インストールごとに 1 つのコレクションがあり、 フィルターでワークスペースの分離が適用されます。
- sandbox は、テストスイートやビルドなど、信頼されていない処理を専用の UID と 専用ネットワークで実行します。データベースやキーへのアクセスはなく、ルートファイルシステムは 読み取り専用です。
- LiteLLM はオプションです。
LITELLM_PROXY_URLとLITELLM_MASTER_KEYを 両方設定すると、すべての呼び出しがゲートウェイ経由になります。どちらかを空のままにすると、 プロバイダーキーが直接使用されます。
トラブルシューティング
コンテナーが起動しません。 docker compose logs <service> を実行してください。API は起動時に、
利用できないオプション機能とその理由を報告するため、問題が通知されないままになることはありません。
レビュー結果が出ません。 GET /healthz で解決済みのクロックを確認してから、
docker compose logs api | grep agent_ を実行してください。各エージェントは、経過時間、
使用したモデル、失敗コードをログに記録します。
停止ではなく、タイムアウトが発生します。 local_timeout は、プロバイダーが応答する前に
このインストール環境独自の期限を過ぎたことを意味します。REVIEW_LLM_TIMEOUT_SECONDS を
増やしてください。これは意図的にプロバイダーの障害として報告されません。
Q&A に出典が表示されません。 リポジトリがインデックスされていないか、埋め込みなしで
インデックスされている可能性があります。Repositories に各リポジトリの状態が表示されます。
analyzer graph-stats <repo> で解析結果を確認できます。
サンドボックスが常にビジーです。 SANDBOX_SLOTS は同時に実行できるジョブ数であり、
メモリ使用量に影響する設定です。SANDBOX_SLOT_WAIT は、呼び出し元が再試行を促されるまで
キューで待機する時間です。
プロジェクトの構成
src/
api/ FastAPI app, routers, schemas
review/ PR review — agents, orchestrator, providers, policies
indexing/ parsers, symbol graph, embeddings
qa/ retrieval and answer composition
generation/ documentation vault
llm/ provider clients, error taxonomy, cost ledger
sync/ git providers, the durable job queue, workers
sandbox/ the isolated execution server
mcp_server/ the MCP surface
security/ redaction, patterns, log filtering
web/ Next.js UI (App Router, 16 locales)
tests/ 5200+ tests
deploy/ Caddy overlay and the LiteLLM gateway config
docs/ deploy guides and the end-to-end walk-through
bench/ benchmark harness and results
出自と権利
このリポジトリには、約10万行を超える単一のルートコミットがあります。 これは、出自が不明確なコードの一括投入を来歴スキャナーが検出したときに 示される状態であり、曖昧に済ませず説明が必要です。その説明はあります。 PROVENANCE.mdには、ライセンス上の扱いとコードの出自が 記載されています。開発はこのコミットより前に非公開で行われており、 ここにあるものをビルド、監査、フォークするうえで、それらの事実は不要です。
このファイルは事実を記録したものであり、ライセンスではありません。ライセンスは
AGPL-3.0ですが、例外が1つあります。ee/以下のものと、
ファイル名に.ee.を含むファイルには、代わりにLICENSE_EEが
適用されます。LICENSING.mdには境界の詳細が記載されています。
LICENSE自体は、前文を付けていないAGPLの原文です。ライセンス文書の前に
前文があると、そのライセンスとして認識されないためです。
現在、エンタープライズ向け機能は3つあり、シングルサインオン(OIDC /
Keycloak)、レビュー分析、リポジトリの共有機能(共有機能
のその他の部分はAGPL)です。これらはsrc/ee/とweb/ee/にあり、
オフラインライセンスキーで有効化されます(ee/README.mdを
参照)。この境界は最初のタグを付ける前に定められました。後から追加すると、
無条件のAGPLのもとで作業を提供したすべてのコントリビューターに、改めて
許可を求めることになるためです。
ここで公開されているその他のものは、商用機能に見える部分も含めてすべてAGPLです。 監査コンソール、使用量と支出、コンプライアンスチェック、インストール指標も 含まれます。セキュリティ制御がエンタープライズ専用になることはありません。 監査ログはAGPLのもとで開発されており、今後もそうあり続けます。新しいコードの 配置先についてはCONTRIBUTING.mdを参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。