rebuild-dossier
rebuild-dossier
Ein MCP-Server, der aus einer bestehenden App eine vertrauenswürdige Rebuild-Spezifikation ableitet – eine gesperrte CLAUDE.md, .claude/-Konfiguration und eine mutationstestete Testsuite –, sodass jeder Coding-Agent die App sauber anhand dieser Spezifikation neu aufbauen kann, statt zu raten.
Es baut die App nicht neu auf. Es erzeugt die Spezifikation, Verträge und Tests, die ein Coding-Agent konsumiert, um das separat zu tun. Diese Grenze ist bewusst gewählt – siehe Warum unten.
Status: v0. Die Kernschleife funktioniert und wurde Ende-zu-Ende gegen ein reales, unordentliches Repository validiert, einschließlich zwei unabhängiger Fresh-Agent-Übergaben auf zwei Modellstufen. Lies docs/v0-findings.md für das ehrliche Ergebnis, einschließlich dessen, was kaputtging.
Warum
Frühere Forschung (AgentModernize, arXiv:2605.17535) ergab, dass eine Rebuild-Pipeline mit 0% Verhaltensequivalenz ohne verifizierte Feedback-Schleife abschneidet und nur 9–19% mit einer groben. Die Wette hinter diesem Tool: Schnittstellenverträge vor dem Ausführen von Tests zu sperren, plus eine strikte Ein-Test-nach-dem-anderen-Wiederholungsschleife statt Batch-Regenerierung, schneidet deutlich besser ab.
Der riskanteste Teil einer solchen Pipeline ist, einen Fehler stillschweigend als beabsichtigt zu validieren – vier Evidenzquellen können sich leise auf denselben Fehler einigen, ohne dass jemals jemand gesagt hat, warum. Daher ist die einzige nicht verhandelbare Regel in diesem Tool: Die automatische Auflösung einer Mehrdeutigkeit erfordert sowohl Signalübereinstimmung als auch ein bestätigendes Signal, dass jemand tatsächlich entschieden hat (ein ausdrücklicher Kommentar, ein TODO, das einen Fehler zugibt, oder eine direkte menschliche Antwort). Stille Übereinstimmung allein – Code und beobachtetes Verhalten stimmen einfach überein, ohne dass jemals jemand gesagt hat, warum – wird immer zu einer Frage, nie zu einer automatischen Auflösung, egal wie hoch die scheinbare Konfidenz ist.
Related MCP server: reforge-mcp
So funktioniert es
Sechs MCP-Tools, ausgeführt in einer normalen Claude Code (oder einer beliebigen MCP-kompatiblen) Sitzung:
Tool | Was es tut |
| Nur statische Analyse, kein LLM-Aufruf: Routen, |
| Headless-Playwright-Crawl erreichbarer Routen, mit Fortschrittsmeldungen, damit lange Crawls nicht als nicht reagierend abgebrochen werden. |
| Freitext, wörtlich gespeichert. Überschreibt immer die automatische Auflösung für alles, was er abdeckt – das billigste und autoritativste Signal im System. |
| Die Mehrdeutigkeits-Warteschlange. Stellt offene Fragen über MCP-Elicitation dar, wenn der Client dies unterstützt; |
| Nur aufrufbar, wenn die Fall-Warteschlange leer ist. Schreibt |
Regeln, die mechanisch durchgesetzt werden, nicht nur niedergeschrieben
Ein Vergleichslauf über zwei Modellstufen ergab, dass ein schwächeres Modell bereitwillig CLAUDE.md liest, versteht, „nur das bauen, was gerade fehlschlägt, nicht batch-regenerieren", und es dann trotzdem stillschweigend verletzt – weil nichts es überprüft hat. Zwei Regeln in diesem Tool werden jetzt aus genau diesem Grund durch echte Hooks durchgesetzt, nicht durch Prosa:
spec/ist gesperrt. EinPreToolUse-Hook blockiert jede Bearbeitung unterspec/.Verträge ohne Tests werden nicht vorzeitig gebaut.
generate_specschreibtspec/untested-contracts.json(jede Route/jeder Vertrag ohne abdeckenden Test), und ein zweiterPreToolUse-Hook blockiert Schreibvorgänge auf alles auf dieser Liste – dieselbe Durchsetzungsform wie derspec/-Bearbeitungsblock, wodurch eine Lücke geschlossen wird, die früher nur beratend war.
Ein PostToolUse-Hook führt nach jeder Bearbeitung die sichtbare Testsuite aus.
Schnellstart
git clone https://github.com/businessfawcett-cloud/rebuild-dossier.git
cd rebuild-dossier
npm install
npx playwright install chromium # needed for crawl_siteFüge es als MCP-Server in Claude Code (oder einem beliebigen MCP-kompatiblen Client) hinzu, dann in einer Sitzung:
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" })Dies schreibt ein sauberes some-app-rebuild/-Schwesterverzeichnis. Wechsle hinein, starte eine frische Claude-Code-Sitzung (nichts anderes sollte im Umfang sein) und füge den Inhalt seiner kickoff-prompt.txt ein.
Bedienungsanleitung
Der vollständige Lebenszyklus in Reihenfolge – das tatsächliche Verhalten jedes Schritts, nicht nur die Aufrufsignatur.
1. Repository erfassen
ingest_repo({ path: "/absolute/path/to/some-app" })Nur statische Analyse – kein LLM-Aufruf, nichts wird ausgeführt. Analysiert package.json, Routendateien (Express und Next.js App Router heute – siehe Umfang), Build-Konfiguration (Tailwind/Vite/Next, über AST, nie ausgeführt), vorhandene Tests und scannt nach Kommentar-/TODO-Signalen sowie strukturellen Gerüchen (z. B. eine hartcodierte clientseitige Anmeldeüberprüfung ohne serverseitige Verifikation – die Art von Ding, auf das niemand jemals kommentiert, was genau der Grund ist, warum es einen eigenen Detektor braucht, anstatt sich darauf zu verlassen, dass Kommentare existieren). Alles landet in <repo>/.dossier/ – der eigene Scratch-Zustand dieses Tools, im ursprünglichen Repository, niemals geteilt oder irgendwo hochgeladen. Du erhältst eine Zusammenfassung:
{
"routes": 8,
"existingTests": 0,
"signals": 3,
"buildConfig": ["tailwind", "next"],
"openCases": 3,
"savedTo": "/absolute/path/to/some-app/.dossier/evidence.json"
}openCases spiegelt hier bereits die Abgleichung wider – Kommentar-/TODO-Signale und strukturelle Gerüche, die sich nicht automatisch auflösten, werden automatisch zu Einträgen in der Fall-Warteschlange.
Wenn routes 0 zurückgibt, prüfe auf ein monorepoHint-Feld, bevor du annimmst, dass die App keine hat – ingest_repo muss auf das tatsächliche App-Verzeichnis zeigen, nicht auf den Root-Wrapper eines Monorepos (eine package.json mit apps/*/packages/* daneben, üblich bei Turborepo/Nx/Workspace-Layouts, einschließlich solcher, die nie tatsächlich ein workspaces-Feld deklarieren). Der Hinweis listet echte Kandidatenverzeichnisse unter apps//packages/ auf, damit du nicht selbst nach der echten App suchen musst – führe ingest_repo stattdessen erneut aus, auf eines davon gerichtet.
Wenn dein Client MCP-Elicitation unterstützt, kannst du die manuelle Wiederholung ganz überspringen: Übergib interactive: true, und wenn eine Monorepo-Wurzel mit Kandidaten erkannt wird, fragt ingest_repo, welche die echte App ist, und erfasst sie direkt – es rät niemals stillschweigend selbst, genauso wie der interaktive Modus von get_case_queue immer fragt, anstatt etwas ohne dich aufzulösen. Ablehnung, ein nicht unterstützter Client oder eine Antwort, die keiner der echten Kandidaten ist, fallen alle auf den einfachen Hinweis oben zurück, unverändert.
2. (Optional) Die Live-Website crawlen
crawl_site({ url: "http://localhost:3000", repoPath: "/absolute/path/to/some-app" })Nur nützlich, wenn die App tatsächlich irgendwo läuft. Headless-Playwright-Crawl erreichbarer Routen, der regelmäßig Fortschrittsmeldungen ausgibt – lange Crawls werden von den meisten MCP-Clients automatisch in den Hintergrund verschoben, und ein stiller mehrminütiger Aufruf riskiert, ohne sie als nicht reagierend abgebrochen zu werden.
3. (Optional, aber tue dies vor Schritt 4) Markiere alles, von dem du bereits weißt, dass es kaputt ist
flag_known_bug({
repoPath: "/absolute/path/to/some-app",
description: "The login gate secret check runs entirely client-side and is bypassable"
})Das billigste und autoritativste Signal im gesamten System – eine direkte menschliche Aussage hat immer Vorrang vor Inferenz. Es überschreibt die automatische Auflösung für alles, was es abdeckt, selbst wenn jedes andere Signal stillschweigend zustimmt, dass das Verhalten beabsichtigt aussieht. Tue dies vor dem Auflösen der Warteschlange, da es ändert, was dort erscheint (und kann einen Fall ganz allein auslösen, ohne andere Evidenz – siehe docs/v0-findings.md für den Grund, warum das wichtig ist).
Der Abgleich ist einfache Token-Überlappung mit dem Dateipfad und dem Anspruchstext jedes offenen Falls, nicht unscharf oder semantisch – daher kann eine Fehlerbeschreibung mehr offene Fälle abdecken (und automatisch auflösen) als beabsichtigt, wenn deine Codebasis mehrere ähnlich benannte Komponenten hat. Im validierten Beispiel hat ein Fehler über „das Login-Gate" alle drei nahezu duplizierten Gate-Komponenten von Madeline in einem einzigen Aufruf abgedeckt und geschlossen, bevor eine davon einzeln überprüft wurde. resolve_case überschreibt die Entscheidung eines Falls unabhängig von seinem aktuellen Status. Wenn das also nicht gemeint war, rufe es direkt für diejenigen auf, die es zu breit erfasst hat – nimm nicht an, dass jeder Fall, den es berührt hat, tatsächlich dieselbe Entscheidung war.
4. Die Fall-Warteschlange auflösen
get_case_queue({ repoPath: "/absolute/path/to/some-app", interactive: true })interactive: true geht jeden offenen Fall über MCP-Elicitation durch – eine echte interaktive Eingabeaufforderung in deinem Client, die die Evidenz nebeneinander zeigt, wenn dein Client dies unterstützt. Wenn nicht (oder du dies scriptest), löse Fälle stattdessen einzeln auf:
resolve_case({ repoPath: "/absolute/path/to/some-app", id: "case:...", decision: "intentional", note: "..." })Dieser Schritt hat keine Abkürzung. generate_spec weigert sich, zu laufen, solange noch ein Fall offen ist, by design – es gibt keine partielle oder in Arbeit befindliche Spezifikation, die man einem Rebuild-Agenten mit Einschränkungen übergeben könnte; Phasen 1–2 sind buchstäblich das, was spec/ überhaupt erst erzeugt.
5. Die Spezifikation generieren
generate_spec({ repoPath: "/absolute/path/to/some-app" })Nur aufrufbar, sobald die Warteschlange leer ist. Schreibt CLAUDE.md, .claude/ (Regeln, Hooks, ein spec-auditor-Subagent und eine verify-against-spec-Fähigkeit – alles abgeleitet aus den tatsächlichen Verträgen und Tests dieses Projekts, nicht aus Boilerplate), spec/ (Verträge, gesperrte Entscheidungen, test-dependencies.json, untested-contracts.json) und tests/ in ein sauberes Schwesterverzeichnis some-app-rebuild/ – niemals in das ursprüngliche Repository. Zwei weitere .claude/-Artefakte werden nur generiert, wenn sie sich lohnen: ein test-verifier-Subagent, nur wenn es zurückgehaltene Tests zu bewachen gibt; ein parallel-test-fix-Workflow, nur wenn die generierten Tests in zwei oder mehr unabhängige Cluster (nach gemeinsamen Routendateien) aufgeteilt werden, die sich gleichzeitig zu beheben lohnen. Eine kleine App mit ein paar Tests, die dieselben Routen abdecken – wie das oben validierte Beispiel – bekommt keines davon; das ist kein Fehler, sondern der Generator weigert sich, einem Rebuild-Agenten Werkzeuge zu geben, mit denen er nichts wirklich zu tun hat. Dieser Schritt führt auch eine echte Mutationsprüfung durch: Er bricht absichtlich den ursprünglichen Code (dreht einen Vergleich um, lässt eine Nullprüfung weg, macht einen Off-by-one-Fehler bei einer Schleifengrenze) in einer Scratch-Kopie und bestätigt, dass jeder generierte Test ihn tatsächlich erkennt – alles, was das nicht tut, wird nach tests/weak/ verschoben, anstatt als vertrauenswürdig ausgeliefert zu werden. Du erhältst zurück:
{
"outputDir": "/absolute/path/to/some-app-rebuild",
"mutationsChecked": 8,
"weakTests": [],
"unrunnableTests": []
}Sowohl weakTests als auch unrunnableTests landen im selben Verzeichnis tests/weak/ statt in tests/visible/, aber aus unterschiedlichen Gründen, die man auseinanderhalten sollte: Ein schwacher Test lief einwandfrei und hat nur nie etwas erkannt, das eine Mutation kaputt gemacht hat; ein nicht ausführbarer Test bestand nie, selbst gegen den ursprünglichen, nicht mutierten Code (ein kaputter Import, eine fehlende Umgebungsvariable, Infrastruktur, die das nackte Repository nicht hat) – bevor diese Unterscheidung existierte, sah ein nicht ausführbarer Test nicht von einem 100% effektiven zu unterscheiden aus, da er identisch "fehlschlägt", ob der getestete Code mutiert wurde oder nicht. Keines davon ist ein Fehler – es ist das Tool, das dir ehrlich sagt, dass ein bestimmter Test seinen Platz in tests/visible/ nicht verdient hat, und warum.
Wenn jeder generierte Test mit mutationsChecked: 0 in tests/weak/ landet, prüfe auf ein warning-Feld, bevor du annimmst, dass etwas strukturell falsch ist – die weitaus häufigere Ursache ist, dass im Ziel-Repository kein npm install ausgeführt wurde, sodass die Mutationsprüfungs-Scratch-Kopie keine der tatsächlichen Abhängigkeiten des Ziels enthält (next, @prisma/client, was auch immer die App wirklich braucht) und jeder generierte Test sie nicht einmal importieren kann. generate_spec prüft das direkt und sagt es, anstatt dich ein verwirrendes Alles-nicht-ausführbar-Ergebnis debuggen zu lassen.
Optional: Vision-gestützte Seiteninhalts-Klassifizierung
Für ein Next.js-Ziel erhalten Seitenrouten echte Playwright-aufgezeichnete Tests (ein Screenshot plus DOM-Text-Assertions) neben den oben beschriebenen API-Routen-Tests. Ob ein Stück erfasster Text eine Exakt-Übereinstimmungs-Assertion (static) oder eine lockere Formprüfung (dynamic) erhält, entscheidet standardmäßig ein kleiner Regex-Klassifikator – meist zuverlässig, aber nachweislich in der Lage, es bei einer echten App in beide Richtungen falsch zu machen (eine hartcodierte Dropdown-Legende als Live-Daten gelesen; ein Live-Datenbankzähler mit Komma-Formatierung als fest gelesen).
Das Setzen beider Variablen GROQ_API_KEY und REBUILD_DOSSIER_ENABLE_VISION_CLASSIFICATION=1 vor dem Aufruf von generate_spec sendet stattdessen den Screenshot und (geheimnisgeschwärzten) Quellcode jeder erfassten Seite an ein Groq-Vision-Modell, das sehen kann, woher ein Wert tatsächlich kommt – ein wörtliches Array im Quellcode vs. ein fetch/useState-Aufruf – statt nur anhand des gerenderten Strings zu raten. Beide Variablen sind absichtlich zusammen erforderlich: Eine in der Umgebung vorhandene GROQ_API_KEY von einem unabhängigen Tool darf niemals stillschweigend beginnen, den Code dieses Ziel-Repositorys an einen Dritten zu senden. Keine der Variablen gesetzt (der Standard) bedeutet null Verhaltensänderung und null Netzwerkaufrufe über das hinaus, was generate_spec bereits tut.
Das sind echte Zusatzkosten, nicht kostenlos: ein Groq-API-Aufruf pro erfasster Seite, plus eine bewusste ~20s-Verzögerung zwischen den Seiten (Groqs kostenloser Tarif hat ein knappes Token-Budget pro Minute, und das Hintereinanderfeuern von Anfragen erschöpft es schnell) – die eigene Antwort von generate_spec gibt die genaue zusätzliche Zeit für diesen Lauf an. Eine Seite, die aus irgendeinem Grund nicht so klassifiziert werden kann (Ratenlimit, Netzwerkproblem, ungültige Antwort), fällt für diese Seite nur auf den Regex-Klassifikator zurück, gemeldet in pageVisionFallbacks – niemals eine stille Lücke oder ein fehlgeschlagener Lauf. Groqs kostenloser Tarif (keine Kreditkarte erforderlich, unter console.groq.com) reicht aus, um das auszuprobieren.
6. Übergabe
cd /absolute/path/to/some-app-rebuild
claude # or oh-my-pi, opencode — any coding agent, a genuinely fresh sessionFüge den Inhalt von kickoff-prompt.txt wörtlich ein. Nichts anderes sollte im Kontext dieser Sitzung sein – das Verzeichnis ist absichtlich vollständig in sich geschlossen (siehe So funktioniert es), sodass es für einen Rebuild-Agenten nichts anderes zu lesen, zu dem er abdriften oder das er an Ort und Stelle bearbeiten könnte, anstatt sauber zu bauen. Lies docs/v0-findings.md für das, was tatsächlich passiert, wenn du das gegen eine echte App tust, einschließlich genau der Stelle, an der es hängen blieb.
Verbindung von anderen Tools (oh-my-pi, opencode, etc.)
Zwei Möglichkeiten, dies auszuführen, beide vollständig lokal – es gibt keine gehostete/geteilte Instanz, und es ist keine erforderlich:
stdio (Standard) – jedes Tool startet seine eigene Kopie des Servers als lokalen Unterprozess. Das ist die Standardmethode, mit der jeder MCP-Client (Claude Code, oh-my-pi, opencode) einen lokalen MCP-Server hinzufügt – weise ihn auf npx tsx src/index.ts (oder ein gebautes node dist/index.js) aus dem Verzeichnis dieses Repos. Keine zusätzliche Einrichtung, keine Authentifizierung, nichts in diesem Abschnitt gilt.
HTTP (optional) – ein persistenter Server auf localhost, mit dem mehrere Tools/Sitzungen verbunden werden, anstatt dass jedes seine eigene startet. Nützlich, wenn du möchtest, dass oh-my-pi und opencode (oder mehrere Claude-Code-Sitzungen) eine laufende Instanz gemeinsam nutzen. Immer noch vollständig lokal – MCP_ALLOWED_HOSTS muss nur den Hostnamen enthalten, mit dem du dich tatsächlich verbindest (localhost), keine echte Domain, es sei denn, du entscheidest dich bewusst, dies über deine eigene Maschine hinaus zu öffnen.
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:prodAlle drei Umgebungsvariablen sind erforderlich – der Server weigert sich absichtlich, ohne sie zu starten: MCP_AUTH_TOKEN sperrt jede /mcp-Anfrage (Bearer-Auth), MCP_ALLOWED_HOSTS schützt vor DNS-Rebinding, und REBUILD_DOSSIER_ALLOWED_PATHS (kommagetrennte absolute Verzeichnisse) ist der einzige Pfad, den ingest_repo/generate_spec/etc. berühren dürfen – setze es auf das übergeordnete Verzeichnis, das die Repos enthält, die du tatsächlich neu aufbauen möchtest.
oh-my-pi (.omp/mcp.json oder ~/.omp/agent/mcp.json):
{
"mcpServers": {
"rebuild-dossier": {
"type": "http",
"url": "http://localhost:8080/mcp",
"headers": { "Authorization": "Bearer ${REBUILD_DOSSIER_TOKEN}" }
}
}
}opencode (opencode.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 deaktiviert die automatische OAuth-Erkennung von opencode bei einem 401 – dieser Server unterstützt nur das obige statische Bearer-Token, keinen echten OAuth-Flow. Setze die referenzierte Umgebungsvariable (REBUILD_DOSSIER_TOKEN in beiden Beispielen) auf denselben Wert wie MCP_AUTH_TOKEN oben.
Entwicklung
npm test # full suite
npm run typecheckKleine, zweckgebundene Funktionen; durchgängig TDD (Tests werden vor der Implementierung geschrieben, die sie abdecken, einschließlich für die Abgleichslogik selbst – dies ist ein Tool, das Tests generiert, daher ist seine eigene Korrektheit genauso wichtig wie jedes Feature).
Aktueller Umfang und was bewusst noch nicht gebaut ist
v0 ist darauf ausgelegt, die Kernschleife zu beweisen, nicht vollständig zu sein. Bewusst aufgeschoben und als echtes Backlog verfolgt, anstatt stillschweigend übersprungen:
Abgleich bei API-förmiger Mehrdeutigkeit (eine Validierungsregel, eine Fehlerantwortform) ist immer noch wirklich ungetestet – die eine anders geformte echte App, die bisher validiert wurde (catchandtrade), hatte zufällig null Kommentar/TODO-Signale zum Abgleichen, daher hat diese spezifische Frage noch keine Antwort in die eine oder andere Richtung. Siehe docs/v0-findings.md.
Video-/Bildschirmaufnahme-Erfassung und die Video-LLM-Überprüfung markierter Fenster.
Original-CLAUDE.md / Auto-Memory als Beweisquelle.
Live-Chrome-MCP-Erfassung für auth-geschützte/Multi-Konto-Abläufe, die ein Headless-Crawler nicht erreichen kann.
Asset-Manifest-Extraktion (Binärdateien byte-identisch kopiert + ein Hash-Manifest, gesperrte Vertragsstufe) – echtes Design existiert, noch nicht gebaut.
Ein Mutator, der einen Handler vollständig no-op macht (die aktuellen drei – Vergleich umdrehen, Nullprüfung weglassen, Off-by-one – können keinen Mutanten erzeugen, der 'dieser Zweig lief nie' darstellt).
Siehe docs/v0-findings.md für den vollständigen, ehrlichen Bericht: die echten Fehler, die während der Validierung gefunden und behoben wurden, der Vergleich über Modellstufen hinweg und was noch offen ist.
Lizenz
Available Tools
6 toolscrawl_siteCrawl siteB
Playwright headless crawl of reachable routes. Emits periodic progress notifications.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Base URL to crawl | |
| maxPages | No | Optional cap on how many reachable pages to visit. Unset means no limit. | |
| repoPath | Yes | Repo path whose .dossier/ this crawl evidence should be saved under |
Output Schema
| Name | Required | Description |
|---|---|---|
| savedTo | Yes | |
| openCases | Yes | |
| routesVisited | Yes | |
| routesWithConsoleErrors | Yes |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| repoPath | Yes | Repo path whose .dossier/ this known bug belongs to | |
| description | Yes | Free-text description of a known bug, stored verbatim |
Output Schema
| Name | Required | Description |
|---|---|---|
| bug | Yes | |
| openCases | Yes |
TDQS
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.
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.
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.
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.
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.
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 specADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| repoPath | Yes | Repo path that was ingested; output is written to a sibling <repoPath>-rebuild/ directory | |
| authStorageStatePath | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| warning | No | |
| outputDir | Yes | |
| weakTests | Yes | |
| skippedPages | Yes | |
| capturedPages | Yes | |
| pageCaptureNote | No | |
| unrunnableTests | Yes | |
| mutationsChecked | Yes | |
| pageVisionFallbacks | No | |
| pageVisionFallbackNote | No | |
| visionClassificationNote | No | |
| visionClassificationEnabled | Yes |
TDQS
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.
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.
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.
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.
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.
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 queueBDestructive
Return unresolved ambiguity cases from reconciliation.
| Name | Required | Description | Default |
|---|---|---|---|
| repoPath | Yes | Repo path whose .dossier/ case queue to read | |
| interactive | No | When true, walk open cases via MCP elicitation instead of just listing them |
Output Schema
| Name | Required | Description |
|---|---|---|
| open | Yes | |
| cases | Yes |
TDQS
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.
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.
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.
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.
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.
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 repoAIdempotent
Parse package.json, tailwind/vite config, route files, and existing tests via static analysis. No LLM call.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Absolute path to the repo to ingest | |
| interactive | No | When 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
| Name | Required | Description |
|---|---|---|
| routes | Yes | |
| savedTo | Yes | |
| signals | Yes | |
| openCases | Yes | |
| buildConfig | Yes | |
| monorepoHint | No | |
| existingTests | Yes | |
| resolvedMonorepoChoice | No |
TDQS
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.
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.
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.
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.
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.
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 caseADestructiveIdempotent
Resolve one open case with a human decision. Always available, no elicitation capability required.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The case id to resolve, as returned by get_case_queue (e.g. "case:...") | |
| note | No | Optional free-text note explaining the decision | |
| decision | Yes | Free-text decision, e.g. "intentional" or "bug" — stored verbatim, not a fixed enum | |
| repoPath | Yes | Repo path whose .dossier/ this case belongs to |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| status | Yes | |
| signals | Yes | |
| conflict | No | |
| topicKey | Yes | |
| humanDecision | No | |
| autoResolution | No | |
| relatedCaseIds | No | |
| matchedKnownBugs | Yes |
TDQS
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.
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.
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.
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.
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.
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.
6 tool updates
v0.2.6-paper- Changed
crawl_site2 fields changed- added
Input schema / properties / maxPages / descriptionAdded value: +"Optional cap on how many reachable pages to visit. Unset means no limit." - changed
Output 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" +}
- Changed
flag_known_bug1 field changed- changed
Output 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" +}
- Changed
generate_spec1 field changed- changed
Output 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" +}
- Changed
get_case_queue1 field changed- changed
Output 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" +}
- Changed
ingest_repo1 field changed- changed
Output 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" +}
- Changed
resolve_case4 fields changed- added
Input schema / properties / decision / descriptionAdded value: +"Free-text decision, e.g. \"intentional\" or \"bug\" — stored verbatim, not a fixed enum" - added
Input schema / properties / id / descriptionAdded value: +"The case id to resolve, as returned by get_case_queue (e.g. \"case:...\")" - added
Input schema / properties / note / descriptionAdded value: +"Optional free-text note explaining the decision" - changed
Output 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" +}
1 tool update
v0.2.2-paper- Changed
generate_spec1 field changed- added
Input schema / properties / authStorageStatePathAdded 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" +}
6 tool updates
v0.2.0- First observed
crawl_site - First observed
flag_known_bug - First observed
generate_spec - First observed
get_case_queue - First observed
ingest_repo - First observed
resolve_case
TDQS
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.
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.
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.
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
Related MCP Connectors
Augments MCP Server - A comprehensive framework documentation provider for Claude Code
An MCP server that gives your AI access to the source code and docs of all public github repos
MCP server for building and testing AI agents with multi-model experimentation and insights.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceAn MCP server that provides agentic code review powered by OpenAI-compatible models, designed for use with Claude Code.1MIT
- AlicenseBqualityDmaintenanceAn MCP server that connects Claude Code to your codebase for automated code cleanup with scanning, planning, atomic fixes, and rollback safety.102MIT
- AlicenseAqualityBmaintenanceMCP server that spawns autonomous Claude Code agents in GitHub repos, enabling task delegation with persistent state, multi-step workflows, and job monitoring.47942Apache 2.0
- FlicenseAqualityDmaintenanceA 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.101-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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