Skip to main content
Glama
Parker-Fawcett

rebuild-dossier

rebuild-dossier

DOI

既存のアプリから、信頼できる再構築仕様(ロックされた CLAUDE.md.claude/ 設定、ミューテーションテスト済みのテストスイート)をリバースエンジニアリングするMCPサーバーです。これにより、あらゆるコーディングエージェントが推測ではなく、その仕様に基づいてクリーンに再構築できるようになります。

アプリ自体を再構築するわけではありません。 仕様、契約、テストを生成し、コーディングエージェントがそれを消費して別途再構築を行います。この境界線は意図的なものです — 詳細は「なぜ」を参照してください。

ステータス: v0。 コアループは動作し、実際の複雑なリポジトリ1つに対してエンドツーエンドで検証済みです。2つのモデル階層で独立したフレッシュエージェントのハンドオフを2回実施しました。正直な結果(何が壊れたかを含む)は docs/v0-findings.md をお読みください。

なぜ

先行研究(AgentModernize, arXiv:2605.17535)によると、再構築パイプラインは検証済みのフィードバックループがない場合、行動等価性が0%、粗いフィードバックループがある場合でも9〜19% に留まります。このツールの背後にある仮説は、テストを実行する前にインターフェース契約をロックし、バッチ再生成ではなく厳格な1テストずつのリトライループを用いることで、有意に改善できるというものです。

このようなパイプラインで最もリスクが高いのは、バグを意図的なものとして静かに検証してしまうことです。4つの証拠源が、誰も理由を説明しないまま、同じ誤りに静かに同意することがあります。そのため、このツールにおける唯一の絶対ルールは次の通りです:曖昧さを自動解決するには、シグナルの一致、誰かが実際に決定したという積極的なシグナル(明示されたコメント、バグを認めるTODO、または直接の人間の回答)の両方が必要です。 静かな一致だけ — コードと観測された動作が単に一致し、誰も理由を説明していない場合 — は、見かけ上の信頼度がどれだけ高くても、常に質問となり、自動解決にはなりません。

Related MCP server: reforge-mcp

仕組み

通常のClaude Code(またはMCP互換の任意のクライアント)セッション内から実行する6つのMCPツール:

ツール

機能

ingest_repo(path)

静的解析のみで、LLM呼び出しなし:ルート、package.json、ビルド設定(AST経由、実行はしない)、既存テスト、構造的スメル検出器(例:サーバー側検証のないクライアント側のみの資格情報チェック)を処理します。これにより、誰もコメントしていなくても実際の曖昧さが浮き彫りになります。

crawl_site(url)

到達可能なルートをヘッドレスPlaywrightでクロールし、進行状況通知を送信するため、長時間のクロールが応答なしとして強制終了されません。

flag_known_bug(description)

自由テキストで、そのまま保存されます。一致するものに対しては常に自動解決を上書きします — システム内で最も安価で最も権威のあるシグナルです。

get_case_queue() / resolve_case(id, decision)

曖昧さのキュー。クライアントがサポートする場合はMCPエリシテーションを介して未解決の質問を提示します。resolve_case はスクリプト化されたフォールバックとして常に利用可能です。

generate_spec()

ケースキューが空の場合にのみ呼び出し可能。CLAUDE.md.claude/rules/.claude/settings.json(規律を機械的に強制するフック — 下記参照)、spec/contracts/*.mdtests/visible/ + tests/held-out/kickoff-prompt.txt を、元のリポジトリではなくクリーンな兄弟ディレクトリ <repo>-rebuild/ に書き込みます。テストを確定する前に実際のミューテーションチェックを実行します:元のコードを意図的に壊し、生成された各テストが実際にそれを検出することを確認し、検出しないものは格下げします。

文章だけでなく機械的に強制されるルール

2つのモデル階層での比較実行により、弱いモデルは CLAUDE.md を読み、「現在失敗しているものだけを構築し、バッチ再生成はしない」と理解しても、それを静かに違反することが判明しました — なぜなら、それをチェックするものが何もないからです。このツールの2つのルールは、まさにその理由から、散文ではなく実際のフックによって強制されています:

  • spec/ はロックされています。 PreToolUse フックが spec/ 配下の編集をブロックします。

  • テストのない契約は予定より早く構築されません。 generate_specspec/untested-contracts.json(カバーテストのないすべてのルート/契約)を書き出し、2つ目の PreToolUse フックがそのリスト上のものへの書き込みをブロックします — spec/ 編集ブロックと同じ強制形状で、以前は助言のみだったギャップを埋めます。

PostToolUse フックは、編集のたびに可視テストスイートを実行します。

クイックスタート

git clone https://github.com/businessfawcett-cloud/rebuild-dossier.git
cd rebuild-dossier
npm install
npx playwright install chromium   # needed for crawl_site

Claude Code(またはMCP互換の任意のクライアント)でMCPサーバーとして追加し、セッション内で:

ingest_repo({ path: "/path/to/some-app" })
get_case_queue({ repoPath: "/path/to/some-app", interactive: true })
# ...resolve whatever the queue surfaces...
generate_spec({ repoPath: "/path/to/some-app" })

これにより、クリーンな some-app-rebuild/ 兄弟ディレクトリが作成されます。cd で移動し、新しい Claude Code セッション(他にスコープ内のものは何もない状態)を開始し、その kickoff-prompt.txt の内容を貼り付けます。

操作ガイド

完全なライフサイクルを順に説明します — 各ステップの実際の動作(呼び出しシグネチャだけでなく)。

1. リポジトリを取り込む

ingest_repo({ path: "/absolute/path/to/some-app" })

静的解析のみ — LLM呼び出しなし、実行もなし。package.json、ルートファイル(現在はExpressとNext.js App Router — スコープ を参照)、ビルド設定(Tailwind/Vite/Next、AST経由、実行はしない)、既存テストを解析し、コメント/TODOシグナルと構造的スメル(例:サーバー側検証のないハードコードされたクライアント側資格情報チェック — 誰もコメントしない類のもの。だからこそ、コメントの存在に頼るのではなく、独自の検出器が必要なのです)をスキャンします。すべては <repo>/.dossier/ に保存されます — このツール自身のスクラッチ状態で、元のリポジトリ内にあり、共有やアップロードは一切行われません。要約が返されます:

{
  "routes": 8,
  "existingTests": 0,
  "signals": 3,
  "buildConfig": ["tailwind", "next"],
  "openCases": 3,
  "savedTo": "/absolute/path/to/some-app/.dossier/evidence.json"
}

ここでの openCases はすでに調整を反映しています — 自動解決されなかったコメント/TODOシグナルと構造的スメルは、自動的にケースキューのエントリになります。

routes0 で返ってきた場合は、アプリにルートがないと決めつける前に monorepoHint フィールドを確認してください — ingest_repo はモノレポのルートラッパーではなく、実際のアプリディレクトリを指す必要があります(apps/*/packages/* が隣にある package.json、Turborepo/Nx/ワークスペースレイアウトで一般的。workspaces フィールドを実際に宣言していないものも含む)。ヒントには apps//packages/ 配下で見つかった実際の候補ディレクトリがリストされるため、実際のアプリを自分で探す必要はありません — 代わりにそのうちの1つを指して ingest_repo を再実行してください。

クライアントがMCPエリシテーションをサポートしている場合は、手動での再実行を完全にスキップできます:interactive: true を渡すと、候補を持つモノレポルートが検出されたとき、ingest_repo はどれが実際のアプリかを尋ね、直接取り込みます — 決して静かに推測しません。これは get_case_queue のインタラクティブモードが、あなたなしで何かを解決するのではなく常に尋ねるのと同じです。拒否する、クライアントがサポートしていない、または実際の候補のいずれでもない回答は、すべて上記のプレーンなヒントにフォールバックします(変更なし)。

2.(任意)ライブサイトをクロール

crawl_site({ url: "http://localhost:3000", repoPath: "/absolute/path/to/some-app" })

アプリが実際にどこかで実行されている場合にのみ有用です。到達可能なルートをヘッドレスPlaywrightでクロールし、定期的に進行状況通知を発行します — 長時間のクロールはほとんどのMCPクライアントで自動的にバックグラウンド化され、通知がないと応答なしとして強制終了されるリスクがあります。

3.(任意ですが、ステップ4の前に行ってください)既知のバグをフラグする

flag_known_bug({
  repoPath: "/absolute/path/to/some-app",
  description: "The login gate secret check runs entirely client-side and is bypassable"
})

システム全体で最も安価で最も権威のあるシグナル — 直接の人間の声明は常に推論よりも優先されます。一致するものに対しては自動解決を上書きします。他のすべてのシグナルが静かにその動作が意図的であると同意している場合でも。キューを解決する前に行ってください。なぜなら、それがキューに表示される内容を変えるからです(また、他の証拠がゼロでも単独でケースを生み出すことができます — それがなぜ重要なのかは docs/v0-findings.md を参照)。

マッチングは、各オープンケースのファイルパスとクレームテキストに対するプレーンなトークン重複であり、ファジーやセマンティックではありません — そのため、コードベースに類似した名前のコンポーネントが複数ある場合、1つのバグ説明が意図したよりも多くのオープンケースにマッチ(および自動解決)する可能性があります。検証済みの例では、「ログインゲート」に関する1つのバグが、Madelineのほぼ重複したゲートコンポーネント3つすべてにマッチし、個別にレビューされる前に1回の呼び出しで閉じられました。resolve_case は現在のステータスに関係なくケースの決定を上書きするため、意図したものではない場合は、広く巻き込んだケースに直接呼び出してください — 触れたすべてのケースが実際に同じ決定であると想定しないでください。

4. ケースキューを解決する

get_case_queue({ repoPath: "/absolute/path/to/some-app", interactive: true })

interactive: true は、MCPエリシテーションを介して各オープンケースを処理します — クライアントがサポートする場合、証拠を並べて表示する実際のインタラクティブプロンプトです。サポートしていない場合(またはスクリプト化している場合)は、代わりにケースを1つずつ解決します:

resolve_case({ repoPath: "/absolute/path/to/some-app", id: "case:...", decision: "intentional", note: "..." })

このステップにショートカットはありません。 generate_spec は、ケースがまだ開いている間は実行を拒否します。設計によるものです — 再構築エージェントに注意事項付きの部分的な仕様や進行中の仕様を渡すことはありません。フェーズ1〜2は、そもそも spec/ を生成するものです。

5. 仕様を生成する

generate_spec({ repoPath: "/absolute/path/to/some-app" })

キューが空になって初めて呼び出し可能です。CLAUDE.md.claude/(ルール、フック、spec-auditor サブエージェント、verify-against-spec スキル — すべてこのプロジェクトの実際の契約とテストから導出されたもので、ボイラープレートではありません)、spec/(契約、ロックされた決定、test-dependencies.jsonuntested-contracts.json)、および tests/ を、クリーンな兄弟ディレクトリ some-app-rebuild/ に書き出します — 元のリポジトリには決して書き込みません。さらに2つの .claude/ アーティファクトは、それだけの価値がある場合にのみ生成されます: test-verifier サブエージェントは、保持されたテストがガード対象として存在する場合のみ、parallel-test-fix ワークフローは、生成されたテストが(共有ルートファイルによって)並行して修正する価値のある2つ以上の独立したクラスタに分割される場合のみです。同じルートをカバーするいくつかのテストを持つ小さなアプリ — 上記の検証済みの例のように — はどちらも取得しません。それはバグではなく、ジェネレーターが再構築エージェントに実際に関係のないツールを渡すことを拒否しているのです。このステップはまた、実際のミューテーションチェックを実行します: スクラッチコピー内で元のコードを意図的に壊し(比較を反転、null チェックを削除、ループ境界をオフバイワン)、生成された各テストが実際にそれを検出することを確認します — 検出しないものは、信頼できるかのように出荷される代わりに tests/weak/ に移動されます。次のものが返されます:

{
  "outputDir": "/absolute/path/to/some-app-rebuild",
  "mutationsChecked": 8,
  "weakTests": [],
  "unrunnableTests": []
}

weakTestsunrunnableTests はどちらも tests/visible/ ではなく同じ tests/weak/ ディレクトリに置かれますが、その理由は区別する価値があります: weak テストは正常に実行されたが、ミューテーションが壊したものを決して検出しなかったものです。unrunnable テストは、元のミューテーションされていないコードに対しても決してパスしなかったものです(壊れたインポート、欠落した環境変数、ベアリポジトリにはないインフラストラクチャ)— この区別が存在する前は、unrunnable テストは、テスト対象のコードがミューテーションされたかどうかに関係なく同じように「失敗」するため、100%有効なテストと見分けがつきませんでした。どちらもエラーではありません — 特定のテストが tests/visible/ に置かれる資格を得なかったことと、その理由をツールが正直に伝えているのです。

生成されたすべてのテストが mutationsChecked: 0tests/weak/ に置かれた場合、構造的に何かが間違っていると想定する前に warning フィールドを確認してください — はるかに一般的な原因は、ターゲットリポジトリで npm install が実行されていないため、ミューテーションチェックのスクラッチコピーにターゲット自身の実際の依存関係(next@prisma/client、アプリが実際に必要とするもの)がなく、生成されたすべてのテストがそれらをインポートすることさえ失敗するというものです。generate_spec はこれを直接チェックして明示的に伝えるため、混乱を招く全-unrunnable 結果をデバッグする必要はありません。

任意: ビジョン支援によるページコンテンツ分類

Next.js ターゲットの場合、ページルートは上記の API ルートテストに加えて、実際の Playwright キャプチャテスト(スクリーンショットと DOM テキストアサーション)を取得します。キャプチャされたテキストが完全一致アサーション(static)を取得するか、緩い形状チェック(dynamic)を取得するかは、デフォルトでは小さな正規表現分類器によって決定されます — ほとんどの場合信頼できますが、実際のアプリで両方向に間違えることが確認されています(ハードコードされたドロップダウンの凡例がライブデータとして読まれる、ライブのカンマ区切りデータベースカウントが固定として読まれる)。

generate_spec を呼び出す前に 両方GROQ_API_KEYREBUILD_DOSSIER_ENABLE_VISION_CLASSIFICATION=1 を設定すると、キャプチャされた各ページのスクリーンショットと(シークレットが削除された)ソースコードが代わりに Groq ビジョンモデルに送信されます。このモデルは、値が実際にどこから来ているか(ソース内のリテラル配列 vs. fetch/useState 呼び出し)を見ることができ、レンダリングされた文字列の見た目からのみ推測するのではありません。両方の変数が意図的に一緒に必要です: 無関係なツールから残った環境の GROQ_API_KEY が、このターゲットリポジトリのコードをサイレントに第三者に送信し始めてはなりません。どちらの変数も設定されていない場合(デフォルト)、generate_spec がすでに行うこと以外の動作変更はゼロ、ネットワーク呼び出しもゼロです。

これは無料ではなく実際の追加コストです: キャプチャされたページごとに1回の Groq API 呼び出しに加え、ページ間の意図的な ~20秒のペーシング遅延(Groq の無料ティアは1分あたりのトークン予算が厳しく、リクエストを連続して送信するとすぐに使い果たします)— generate_spec 自身のレスポンスが、その実行の正確な追加時間を明記します。何らかの理由でこの方法で分類できないページ(レート制限、ネットワーク問題、無効なレスポンス)は、そのページのみ正規表現分類器にフォールバックし、pageVisionFallbacks で報告されます — サイレントなギャップや失敗した実行は決してありません。Groq の無料ティア(クレジットカード不要、console.groq.com)でこれを試すのに十分です。

6. 引き渡す

cd /absolute/path/to/some-app-rebuild
claude   # or oh-my-pi, opencode — any coding agent, a genuinely fresh session

kickoff-prompt.txt の内容をそのまま貼り付けます。そのセッションのコンテキストには他に何も入れるべきではありません — ディレクトリは意図的に完全に自己完結しているため(仕組み を参照)、再構築エージェントが読むもの、ドリフトするもの、クリーンに構築する代わりにその場で編集するものは他にありません。docs/v0-findings.md を読んで、実際のアプリに対してこれを行ったときに実際に何が起こるか、正確にどこで詰まったかを含めて確認してください。

他のツールからの接続(oh-my-pi、opencode など)

これを実行する2つの方法があり、どちらも完全にローカルです — ホスト型/共有インスタンスはなく、必要もありません:

stdio(デフォルト) — 各ツールがサーバーの独自のコピーをローカルサブプロセスとして起動します。これはすべての MCP クライアント(Claude Code、oh-my-piopencode)がローカル MCP サーバーを追加する標準的な方法です — このリポジトリのディレクトリから npx tsx src/index.ts(またはビルド済みの node dist/index.js)をポイントします。追加のセットアップ、認証、このセクションの該当事項はありません。

HTTP(任意) — 複数のツール/セッションがそれぞれ独自のものを起動する代わりに接続する、localhost 上の1つの永続サーバー。oh-my-pi と opencode(または複数の Claude Code セッション)が1つの実行中インスタンスを共有したい場合に便利です。依然として完全にローカルです — MCP_ALLOWED_HOSTS には、実際に接続するホスト名(localhost)のみを含めればよく、実際のドメインは不要です。意図的に自分のマシンを超えて公開することを選択しない限り。

npm run build
PORT=8080 \
MCP_AUTH_TOKEN=$(openssl rand -hex 32) \
MCP_ALLOWED_HOSTS=localhost,127.0.0.1 \
REBUILD_DOSSIER_ALLOWED_PATHS=/absolute/path/to/your/projects \
npm run start:http:prod

3つの環境変数はすべて必須です — サーバーは意図的に、それらなしでは起動を拒否します: MCP_AUTH_TOKEN はすべての /mcp リクエストをゲートし(ベアラー認証)、MCP_ALLOWED_HOSTS は DNS リバインディングを防ぎ、REBUILD_DOSSIER_ALLOWED_PATHS(カンマ区切りの絶対ディレクトリ)は ingest_repo/generate_spec などが触れることを許可される唯一のパスです — 実際に再構築したいリポジトリを保持する親ディレクトリに設定してください。

oh-my-pi.omp/mcp.json または ~/.omp/agent/mcp.json):

{
  "mcpServers": {
    "rebuild-dossier": {
      "type": "http",
      "url": "http://localhost:8080/mcp",
      "headers": { "Authorization": "Bearer ${REBUILD_DOSSIER_TOKEN}" }
    }
  }
}

opencodeopencode.json):

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "rebuild-dossier": {
      "type": "remote",
      "url": "http://localhost:8080/mcp",
      "enabled": true,
      "oauth": false,
      "headers": { "Authorization": "Bearer {env:REBUILD_DOSSIER_TOKEN}" }
    }
  }
}

oauth: false は、401 時の opencode の自動 OAuth ディスカバリーを無効にします — このサーバーは上記の静的ベアラートークンのみをサポートし、実際の OAuth フローはサポートしません。参照された環境変数(両方の例で REBUILD_DOSSIER_TOKEN)を上記の MCP_AUTH_TOKEN と同じ値に設定します。

開発

npm test        # full suite
npm run typecheck

小さく、単一目的の関数。全体を通して TDD(テストは、それらがカバーする実装の前に書かれます。調整ロジック自体のテストも含みます — これはテストを生成するツールなので、それ自身の正確性はどの機能と同じくらい重要です)。

現在のスコープ、そして意図的にまだ構築されていないもの

v0 は機能完全であることではなく、コアループを証明することをスコープとしています。意図的に延期され、サイレントにスキップされるのではなく実際のバックログとして追跡されています:

  • API 形状の曖昧さ(検証ルール、エラーレスポンス形状)に関する調整は、依然として実際にはテストされていません — これまでに検証された唯一の異なる形状の実アプリ(catchandtrade)は、たまたま調整するコメント/TODO シグナルがゼロだったため、この特定の質問にはどちらの方向にもまだ答えがありません。docs/v0-findings.md を参照してください。

  • ビデオ/スクリーンレコーディングの取り込みと、ビデオ LLM によるフラグ付きウィンドウレビュー。

  • 証拠ソースとしての元の CLAUDE.md / 自動メモリ。

  • ヘッドレスクローラーが到達できない認証ゲート付き/マルチアカウントフロー用のライブ Chrome MCP キャプチャ。

  • アセットマニフェスト抽出(バイナリファイルのバイト単位のコピー + ハッシュマニフェスト、ロックされた契約ティア)— 実際の設計は存在しますが、まだ構築されていません。

  • ハンドラー全体を no-op にするミューテーター(現在の3つ — 比較反転、null チェック削除、オフバイワン — は「このブランチは実行されなかった」ミュータントを生成できません)。

完全で正直な書き起こしについては docs/v0-findings.md を参照してください: 検証中に発見され修正された実際のバグ、モデルティア間の比較、そしてまだ未解決のもの。

ライセンス

MIT

Available Tools

6 tools
crawl_siteCrawl siteB

Playwright headless crawl of reachable routes. Emits periodic progress notifications.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesBase URL to crawl
maxPagesNoOptional cap on how many reachable pages to visit. Unset means no limit.
repoPathYesRepo path whose .dossier/ this crawl evidence should be saved under

Output Schema

ParametersJSON Schema
NameRequiredDescription
savedToYes
openCasesYes
routesVisitedYes
routesWithConsoleErrorsYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, idempotency, and destructive hints. The description adds some behavioral detail by noting it runs headless and emits periodic progress notifications, but it does not clarify what side effects the crawl may produce beyond visiting pages, even though readOnlyHint is false and repoPath suggests saving evidence. No contradiction with annotations was found.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences with no filler, and the core action is front-loaded. It is concise and readable, though it could have used the extra space to provide more usage context.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the schema fully documents all parameters and an output schema exists, the core technical details are covered. However, the description alone does not address when to use the tool, what side effects the crawl might have, or how it relates to the sibling tools. It is adequate but has clear gaps for an agent deciding whether to invoke it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already explains url, maxPages, and repoPath. The description does add a small hint that the crawl follows reachable routes from the base URL, but it does not materially improve on the parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the action ('crawl'), the resource ('site'), and the method ('Playwright headless'), and specifies the scope as 'reachable routes.' This distinguishes it from the sibling tools, which perform different operations like ingesting, flagging, or resolving.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to choose this tool over alternatives, no prerequisites, and no exclusions. The intended context is only implied by the word 'crawl,' not explicitly stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

flag_known_bugFlag known bugA

Record a known bug. Always overrides auto-resolve for any case it matches, regardless of other evidence.

ParametersJSON Schema
NameRequiredDescriptionDefault
repoPathYesRepo path whose .dossier/ this known bug belongs to
descriptionYesFree-text description of a known bug, stored verbatim

Output Schema

ParametersJSON Schema
NameRequiredDescription
bugYes
openCasesYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only indicate that this is a non-read-only, non-idempotent mutation. The description adds the crucial non-obvious behavior that a flagged known bug always wins over auto-resolve regardless of evidence. This is valuable context that annotations cannot communicate. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no filler. The primary action is front-loaded, followed immediately by the single most important behavioral rule. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter write tool, the description covers the action and the essential override behavior, and the schema documents the parameters. An output schema exists, so return-value details are not needed. The only small gap is that when-to-use guidance is implied rather than explicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and both parameters (repoPath and description) are already well documented in the schema. The main description adds no additional parameter semantics, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Record a known bug') and immediately supplies the core differentiator: it overrides auto-resolve. This distinguishes it from sibling resolution/auto-resolve tools without needing to inspect the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence gives a clear behavioral context: use this when a known bug should supersede any auto-resolve conclusion, even when other evidence points elsewhere. It does not explicitly list when not to use it or name sibling tools, but the precedence rule strongly implies the intended usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

generate_specGenerate specA
Destructive

Write CLAUDE.md, .claude/, spec/, tests/, and kickoff-prompt.txt to -rebuild/. Only callable once the case queue is empty. Optional: if the target is a Next.js app with page routes, set GROQ_API_KEY and REBUILD_DOSSIER_ENABLE_VISION_CLASSIFICATION=1 before calling this tool to enable vision-assisted page-content classification (sends each captured page's screenshot and source code to Groq to judge static vs. dynamic content more accurately than plain regex matching) — ask the user for a Groq API key if they want more reliable generated page tests and this isn't already configured. Off by default; nothing changes if unset. Optional: pass authStorageStatePath to reach auth-gated pages during capture — see that field's own description for how to produce it.

ParametersJSON Schema
NameRequiredDescriptionDefault
repoPathYesRepo path that was ingested; output is written to a sibling <repoPath>-rebuild/ directory
authStorageStatePathNoOptional path to a Playwright storageState JSON file (cookies/localStorage from an already-authenticated session against the target app) — load it once with `npx playwright open <url> --save-storage=state.json` after logging in by hand, or any equivalent one-time export. When set, page capture uses it to reach auth-gated pages instead of only ever seeing a login screen; this tool never logs in itself or handles credentials. The file is copied into the rebuild output (tests/fixtures/auth-storage-state.json, gitignored) so generated page tests can reach the same pages when run standalone.

Output Schema

ParametersJSON Schema
NameRequiredDescription
warningNo
outputDirYes
weakTestsYes
skippedPagesYes
capturedPagesYes
pageCaptureNoteNo
unrunnableTestsYes
mutationsCheckedYes
pageVisionFallbacksNo
pageVisionFallbackNoteNo
visionClassificationNoteNo
visionClassificationEnabledYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With annotations already marking this as destructive and non-read-only, the description adds substantial behavioral context: the tool is only callable with an empty case queue, the vision mode is off by default and changes nothing when unset, the tool never logs in or handles credentials itself, and the auth state file is copied into build output and gitignored. These details meaningfully extend beyond the annotation hints and help an agent predict side effects and prerequisites.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core action, then moves from precondition to optional enhancements in a logical order. Every sentence carries operational weight: the initial write target, the queue precondition, the vision-mode toggle and tradeoff, and the auth-state option. Although it is longer than a one-liner, the length is justified by the conditional behavior it must convey.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description, annotations, and rich schema collectively cover prerequisites, optional configurations, credential handling, side-effect locations, and output scope. Since an output schema exists, the description does not need to detail return values. There is no obvious gap an agent would need to guess about in order to call this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the input schema already fully documents repoPath and authStorageStatePath. The tool description adds only a cross-reference to authStorageStatePath and an optional storage-state usage note, but does not go beyond what the schema fields themselves say. With high schema coverage, baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: it writes CLAUDE.md, .claude/, spec/, tests/, and kickoff-prompt.txt to a <repo>-rebuild/ directory. This clearly distinguishes it from sibling tools like ingest_repo or crawl_site, which perform other pipeline stages. The title alone would be vague, but the description removes all ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states an explicit precondition: 'Only callable once the case queue is empty,' which tells the agent when it may and may not be invoked. It also provides conditional guidance for two optional modes: when to set the vision-classification env vars, when to ask the user for a Groq key, and when to pass authStorageStatePath. This is direct, operational usage guidance rather than left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_case_queueGet case queueB
Destructive

Return unresolved ambiguity cases from reconciliation.

ParametersJSON Schema
NameRequiredDescriptionDefault
repoPathYesRepo path whose .dossier/ case queue to read
interactiveNoWhen true, walk open cases via MCP elicitation instead of just listing them

Output Schema

ParametersJSON Schema
NameRequiredDescription
openYes
casesYes

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate destructiveHint=true and readOnlyHint=false, but the description's 'Return...' reads as a safe read operation and adds no context about side effects, what may be destroyed, or why the tool is marked destructive. This mismatch makes the safety profile confusing and under-disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is one short sentence with no filler. It front-loads the core purpose, and every word contributes to understanding what the tool returns.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The schema covers parameters and an output schema exists, so return structure is not the description's burden. However, the description is too thin to fully explain the disruptive destructive hint, the reconciliation context, or when an agent should prefer resolve_case, leaving the overall guidance minimally viable but gapped.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so repoPath and interactive are already documented in the schema. The description adds no extra parameter meaning beyond the schema and does not address the interactive behavior or its consequences.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Return unresolved ambiguity cases from reconciliation' uses a specific verb and resource, making the tool's main output clear. It is distinguishable from siblings like resolve_case, but it does not explicitly call out that distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description only implies when to use the tool: when unresolved ambiguity cases from reconciliation need to be retrieved. It gives no guidance about alternatives such as resolve_case, nor any exclusions, leaving the agent to infer selection criteria from the name and schema.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ingest_repoIngest repoA
Idempotent

Parse package.json, tailwind/vite config, route files, and existing tests via static analysis. No LLM call.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesAbsolute path to the repo to ingest
interactiveNoWhen true and 0 routes are found at a monorepo-shaped path, ask via elicitation which candidate directory is the real app, then ingest that instead

Output Schema

ParametersJSON Schema
NameRequiredDescription
routesYes
savedToYes
signalsYes
openCasesYes
buildConfigYes
monorepoHintNo
existingTestsYes
resolvedMonorepoChoiceNo

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide idempotentHint=true and destructiveHint=false. The description adds meaningful behavioral context with 'static analysis' and 'No LLM call', signaling deterministic, non-LLM execution beyond what annotations state.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no filler. The first states the operation and scope, and the second adds a key behavioral constraint. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is low complexity, has full schema coverage, an output schema, and annotations covering idempotency and destructiveness. The description supplies the remaining essential facts: what files are parsed and that no LLM call is made.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both path and interactive are already well documented in the input schema. The description does not add parameter-specific meaning, which is acceptable given the schema already carries the burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb, 'Parse', and names concrete resources: package.json, tailwind/vite config, route files, and existing tests. An agent can tell what the tool operates on, though it does not explicitly contrast itself with siblings like generate_spec or crawl_site.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The static-analysis phrasing and 'No LLM call' imply this is a deterministic, lower-cost ingestion step, but the description does not explicitly say when to use this tool versus alternatives. Sibling names provide context, yet no direct routing or exclusion guidance is given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resolve_caseResolve caseA
DestructiveIdempotent

Resolve one open case with a human decision. Always available, no elicitation capability required.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe case id to resolve, as returned by get_case_queue (e.g. "case:...")
noteNoOptional free-text note explaining the decision
decisionYesFree-text decision, e.g. "intentional" or "bug" — stored verbatim, not a fixed enum
repoPathYesRepo path whose .dossier/ this case belongs to

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
statusYes
signalsYes
conflictNo
topicKeyYes
humanDecisionNo
autoResolutionNo
relatedCaseIdsNo
matchedKnownBugsYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry the safety profile (destructiveHint=true, idempotentHint=true), and the description adds the useful operational trait that the tool is always available and requires no elicitation capability. It does not, however, disclose what resolution actually changes (e.g., case status or removal from the queue), leaving the side effect only implied by the destructive hint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences, front-loaded with the primary purpose and followed by a concise availability note. Every word earns its place; there is no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool benefits from rich annotations, 100% parameter documentation, and an output schema, so the description need not explain return values. Still, it omits the practical effect of resolving a case (e.g., the case disappearing from get_case_queue) and provides no guidance about when to prefer this over the closely related sibling flag_known_bug, leaving a small but real completeness gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema description coverage, the baseline is 3. The description adds the key semantic that the decision must be a human decision, which is not stated in the schema's decision property text and helps prevent an agent from fabricating a decision on its own. This one meaningful addition justifies a score above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'resolve one open case' with the key qualifier 'with a human decision.' It is not a tautology and clearly outlines the core action, but it does not explicitly contrast with sibling tools like flag_known_bug or get_case_queue, so it falls short of full differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'Always available, no elicitation capability required' gives some operational context about when the tool can be invoked, implying it is the standard path for resolving a case. However, it never names alternatives or conditions when another sibling should be used instead, so guidance is mostly implicit rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 6 tool updatesv0.2.6-paper
    • Changedcrawl_site2 fields changed
      • addedInput schema / properties / maxPages / description
        Added value: +"Optional cap on how many reachable pages to visit. Unset means no limit."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "additionalProperties": false,
        +  "properties": {
        +    "openCases": {
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "routesVisited": {
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "routesWithConsoleErrors": {
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "savedTo": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "routesVisited",
        +    "routesWithConsoleErrors",
        +    "openCases",
        +    "savedTo"
        +  ],
        +  "type": "object"
        +}
    • Changedflag_known_bug1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "additionalProperties": false,
        +  "properties": {
        +    "bug": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "description": {
        +          "type": "string"
        +        },
        +        "flaggedAt": {
        +          "type": "string"
        +        },
        +        "id": {
        +          "type": "string"
        +        },
        +        "matchHints": {
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        }
        +      },
        +      "required": [
        +        "id",
        +        "description",
        +        "matchHints",
        +        "flaggedAt"
        +      ],
        +      "type": "object"
        +    },
        +    "openCases": {
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "bug",
        +    "openCases"
        +  ],
        +  "type": "object"
        +}
    • Changedgenerate_spec1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "additionalProperties": false,
        +  "properties": {
        +    "capturedPages": {
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "mutationsChecked": {
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "outputDir": {
        +      "type": "string"
        +    },
        +    "pageCaptureNote": {
        +      "type": "string"
        +    },
        +    "pageVisionFallbackNote": {
        +      "type": "string"
        +    },
        +    "pageVisionFallbacks": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "reason": {
        +            "type": "string"
        +          },
        +          "routeFile": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "routeFile",
        +          "reason"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "skippedPages": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "reason": {
        +            "type": "string"
        +          },
        +          "routeFile": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "routeFile",
        +          "reason"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "unrunnableTests": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "visionClassificationEnabled": {
        +      "type": "boolean"
        +    },
        +    "visionClassificationNote": {
        +      "type": "string"
        +    },
        +    "warning": {
        +      "type": "string"
        +    },
        +    "weakTests": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "outputDir",
        +    "mutationsChecked",
        +    "weakTests",
        +    "unrunnableTests",
        +    "capturedPages",
        +    "skippedPages",
        +    "visionClassificationEnabled"
        +  ],
        +  "type": "object"
        +}
    • Changedget_case_queue1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "additionalProperties": false,
        +  "properties": {
        +    "cases": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "autoResolution": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "decision": {
        +                "enum": [
        +                  "intentional",
        +                  "bug"
        +                ],
        +                "type": "string"
        +              },
        +              "reason": {
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "decision",
        +              "reason"
        +            ],
        +            "type": "object"
        +          },
        +          "conflict": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "detail": {
        +                "type": "string"
        +              },
        +              "kind": {
        +                "enum": [
        +                  "known_bug_vs_intentional_evidence",
        +                  "signal_disagreement"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "kind",
        +              "detail"
        +            ],
        +            "type": "object"
        +          },
        +          "humanDecision": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "decidedAt": {
        +                "type": "string"
        +              },
        +              "decision": {
        +                "type": "string"
        +              },
        +              "note": {
        +                "type": "string"
        +              },
        +              "via": {
        +                "enum": [
        +                  "elicitation",
        +                  "resolve_case_tool"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "decision",
        +              "decidedAt",
        +              "via"
        +            ],
        +            "type": "object"
        +          },
        +          "id": {
        +            "type": "string"
        +          },
        +          "matchedKnownBugs": {
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "relatedCaseIds": {
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "signals": {
        +            "items": {
        +              "additionalProperties": false,
        +              "properties": {
        +                "affirmativeIntent": {
        +                  "additionalProperties": false,
        +                  "properties": {
        +                    "confidence": {
        +                      "maximum": 1,
        +                      "minimum": 0,
        +                      "type": "number"
        +                    },
        +                    "kind": {
        +                      "enum": [
        +                        "comment",
        +                        "docstring",
        +                        "todo",
        +                        "fixme"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    "locator": {
        +                      "additionalProperties": false,
        +                      "properties": {
        +                        "endLine": {
        +                          "maximum": 9007199254740991,
        +                          "minimum": -9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "file": {
        +                          "type": "string"
        +                        },
        +                        "startLine": {
        +                          "maximum": 9007199254740991,
        +                          "minimum": -9007199254740991,
        +                          "type": "integer"
        +                        }
        +                      },
        +                      "required": [
        +                        "file",
        +                        "startLine",
        +                        "endLine"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    "text": {
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "kind",
        +                    "text",
        +                    "locator",
        +                    "confidence"
        +                  ],
        +                  "type": "object"
        +                },
        +                "claim": {
        +                  "type": "string"
        +                },
        +                "detectedAt": {
        +                  "type": "string"
        +                },
        +                "evidenceText": {
        +                  "type": "string"
        +                },
        +                "id": {
        +                  "type": "string"
        +                },
        +                "locator": {
        +                  "anyOf": [
        +                    {
        +                      "additionalProperties": false,
        +                      "properties": {
        +                        "endLine": {
        +                          "maximum": 9007199254740991,
        +                          "minimum": -9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "file": {
        +                          "type": "string"
        +                        },
        +                        "startLine": {
        +                          "maximum": 9007199254740991,
        +                          "minimum": -9007199254740991,
        +                          "type": "integer"
        +                        }
        +                      },
        +                      "required": [
        +                        "file",
        +                        "startLine",
        +                        "endLine"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "additionalProperties": false,
        +                      "properties": {
        +                        "method": {
        +                          "type": "string"
        +                        },
        +                        "path": {
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "path"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ]
        +                },
        +                "source": {
        +                  "enum": [
        +                    "ingest",
        +                    "crawl",
        +                    "known_bug"
        +                  ],
        +                  "type": "string"
        +                },
        +                "topicKey": {
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "source",
        +                "locator",
        +                "topicKey",
        +                "claim",
        +                "evidenceText",
        +                "detectedAt"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "status": {
        +            "enum": [
        +              "auto_resolved",
        +              "open",
        +              "resolved_by_human"
        +            ],
        +            "type": "string"
        +          },
        +          "topicKey": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "topicKey",
        +          "signals",
        +          "matchedKnownBugs",
        +          "status"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "open": {
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "open",
        +    "cases"
        +  ],
        +  "type": "object"
        +}
    • Changedingest_repo1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "additionalProperties": false,
        +  "properties": {
        +    "buildConfig": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "existingTests": {
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "monorepoHint": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "candidates": {
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "message": {
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "message",
        +        "candidates"
        +      ],
        +      "type": "object"
        +    },
        +    "openCases": {
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "resolvedMonorepoChoice": {
        +      "type": "string"
        +    },
        +    "routes": {
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "savedTo": {
        +      "type": "string"
        +    },
        +    "signals": {
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "routes",
        +    "existingTests",
        +    "signals",
        +    "buildConfig",
        +    "openCases",
        +    "savedTo"
        +  ],
        +  "type": "object"
        +}
    • Changedresolve_case4 fields changed
      • addedInput schema / properties / decision / description
        Added value: +"Free-text decision, e.g. \"intentional\" or \"bug\" — stored verbatim, not a fixed enum"
      • addedInput schema / properties / id / description
        Added value: +"The case id to resolve, as returned by get_case_queue (e.g. \"case:...\")"
      • addedInput schema / properties / note / description
        Added value: +"Optional free-text note explaining the decision"
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "https://json-schema.org/draft/2020-12/schema",
        +  "additionalProperties": false,
        +  "properties": {
        +    "autoResolution": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "decision": {
        +          "enum": [
        +            "intentional",
        +            "bug"
        +          ],
        +          "type": "string"
        +        },
        +        "reason": {
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "decision",
        +        "reason"
        +      ],
        +      "type": "object"
        +    },
        +    "conflict": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "detail": {
        +          "type": "string"
        +        },
        +        "kind": {
        +          "enum": [
        +            "known_bug_vs_intentional_evidence",
        +            "signal_disagreement"
        +          ],
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "kind",
        +        "detail"
        +      ],
        +      "type": "object"
        +    },
        +    "humanDecision": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "decidedAt": {
        +          "type": "string"
        +        },
        +        "decision": {
        +          "type": "string"
        +        },
        +        "note": {
        +          "type": "string"
        +        },
        +        "via": {
        +          "enum": [
        +            "elicitation",
        +            "resolve_case_tool"
        +          ],
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "decision",
        +        "decidedAt",
        +        "via"
        +      ],
        +      "type": "object"
        +    },
        +    "id": {
        +      "type": "string"
        +    },
        +    "matchedKnownBugs": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "relatedCaseIds": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "signals": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "affirmativeIntent": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "confidence": {
        +                "maximum": 1,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "kind": {
        +                "enum": [
        +                  "comment",
        +                  "docstring",
        +                  "todo",
        +                  "fixme"
        +                ],
        +                "type": "string"
        +              },
        +              "locator": {
        +                "additionalProperties": false,
        +                "properties": {
        +                  "endLine": {
        +                    "maximum": 9007199254740991,
        +                    "minimum": -9007199254740991,
        +                    "type": "integer"
        +                  },
        +                  "file": {
        +                    "type": "string"
        +                  },
        +                  "startLine": {
        +                    "maximum": 9007199254740991,
        +                    "minimum": -9007199254740991,
        +                    "type": "integer"
        +                  }
        +                },
        +                "required": [
        +                  "file",
        +                  "startLine",
        +                  "endLine"
        +                ],
        +                "type": "object"
        +              },
        +              "text": {
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "kind",
        +              "text",
        +              "locator",
        +              "confidence"
        +            ],
        +            "type": "object"
        +          },
        +          "claim": {
        +            "type": "string"
        +          },
        +          "detectedAt": {
        +            "type": "string"
        +          },
        +          "evidenceText": {
        +            "type": "string"
        +          },
        +          "id": {
        +            "type": "string"
        +          },
        +          "locator": {
        +            "anyOf": [
        +              {
        +                "additionalProperties": false,
        +                "properties": {
        +                  "endLine": {
        +                    "maximum": 9007199254740991,
        +                    "minimum": -9007199254740991,
        +                    "type": "integer"
        +                  },
        +                  "file": {
        +                    "type": "string"
        +                  },
        +                  "startLine": {
        +                    "maximum": 9007199254740991,
        +                    "minimum": -9007199254740991,
        +                    "type": "integer"
        +                  }
        +                },
        +                "required": [
        +                  "file",
        +                  "startLine",
        +                  "endLine"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "additionalProperties": false,
        +                "properties": {
        +                  "method": {
        +                    "type": "string"
        +                  },
        +                  "path": {
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "path"
        +                ],
        +                "type": "object"
        +              }
        +            ]
        +          },
        +          "source": {
        +            "enum": [
        +              "ingest",
        +              "crawl",
        +              "known_bug"
        +            ],
        +            "type": "string"
        +          },
        +          "topicKey": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "source",
        +          "locator",
        +          "topicKey",
        +          "claim",
        +          "evidenceText",
        +          "detectedAt"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "status": {
        +      "enum": [
        +        "auto_resolved",
        +        "open",
        +        "resolved_by_human"
        +      ],
        +      "type": "string"
        +    },
        +    "topicKey": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "topicKey",
        +    "signals",
        +    "matchedKnownBugs",
        +    "status"
        +  ],
        +  "type": "object"
        +}
  2. 1 tool updatev0.2.2-paper
    • Changedgenerate_spec1 field changed
      • addedInput schema / properties / authStorageStatePath
        Added value: +{
        +  "description": "Optional path to a Playwright storageState JSON file (cookies/localStorage from an already-authenticated session against the target app) — load it once with `npx playwright open <url> --save-storage=state.json` after logging in by hand, or any equivalent one-time export. When set, page capture uses it to reach auth-gated pages instead of only ever seeing a login screen; this tool never logs in itself or handles credentials. The file is copied into the rebuild output (tests/fixtures/auth-storage-state.json, gitignored) so generated page tests can reach the same pages when run standalone.",
        +  "type": "string"
        +}
  3. 6 tool updatesv0.2.0
    • First observedcrawl_site
    • First observedflag_known_bug
    • First observedgenerate_spec
    • First observedget_case_queue
    • First observedingest_repo
    • First observedresolve_case

TDQS

A4/5.0
Disambiguation5/5

Each tool has a clearly distinct role in the pipeline: static repo ingestion, dynamic site crawling, recording a known bug override, listing unresolved cases, resolving a case, and generating the final dossier. There is no functional overlap or ambiguity between tool boundaries.

Naming Consistency5/5

All six tool names follow the same snake_case verb_noun convention, such as ingest_repo, crawl_site, get_case_queue, and generate_spec. The verb choices are specific and the object naming is consistent, making the set predictable and easy to navigate.

Tool Count5/5

Six tools is a well-scoped size for this workflow, covering ingestion, crawling, bug flagging, case management, and final generation without redundancy. Each tool maps to a necessary step in the rebuild-dossier process and fits comfortably within the ideal range.

Completeness4/5

The main workflow is well covered: static analysis, dynamic crawling, human-in-the-loop case resolution, and final spec generation are all present. A minor gap is that there is no tool to list or remove previously flagged known bugs, but this does not prevent completing the core pipeline.

Maintenance

ActivityActive
ResponsivenessWithin a week

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    MCP server that spawns autonomous Claude Code agents in GitHub repos, enabling task delegation with persistent state, multi-step workflows, and job monitoring.
    47
    94
    2
    Apache 2.0
  • F
    license
    A
    quality
    D
    maintenance
    A safe, local MCP server that lets Claude drive a controlled software-development loop (inspect, read, plan, patch, apply, check, analyze, fix, summarize) on a project, using deterministic tools and real diffs/test runs.
    10
    1
    -

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Parker-Fawcett/rebuild-dossier'

If you have feedback or need assistance with the MCP directory API, please join our Discord server