German Terms-of-Service (AGB) clause checker — detects unfair clauses against BGB §§ 305c/307/308/309 with verifiable § citations
Four tools with clear German legal domain focus. All have descriptions (50-200 chars, good length). Input schemas present with type definitions. However, parameter descriptions are minimal or absent in several tools, and output schemas are documented in docstrings but not formally in JSON Schema. Error handling uses error_envelope() but lacks recovery guidance. Tool naming is clear (verb_noun pattern: check_*, analyze_*). No security issues detected (read-only operations, no secrets). Composition is sound, each tool has one responsibility. Main gaps: parameter-level descriptions missing, output schemas not formally declared, no error classification or recovery hints.
Full-AGB analyzer — splits the input into discrete clauses, runs all three checkers (§ 309, § 308, general red flags) on each one, and returns a consolidated report ranked by severity. This is the tool the Chrome-extension calls. User pastes / highlights the AGB, gets a single structured response.
Check a clause against § 308 BGB — Klauselverbote mit Wertungsmöglichkeit. These 8 clause types can be unwirksam *depending on the specifics*: a delivery-deadline AGB clause is fine at 14 days, suspect at 60. Verdict: "wahrscheinlich unwirksam — kontextabhängig".
Check a single clause against § 309 BGB — Klauselverbote ohne Wertungsmöglichkeit. These are the 13 absolutely-forbidden clause types. A match means the clause is unwirksam, no balancing, no exceptions.
Check a clause against the Verbraucherzentrale-style catalog of typical problematic AGB clauses — § 305c (überraschende Klauseln), § 307 (unangemessene Benachteiligung), § 306 (salvatorisch). These flags catch the *patterns* that show up across many AGB sets: Gerichtsstandsklauseln, Rechtswahl, intransparente Formulierungen, einseitige AGB-Änderungsvorbehalte, vorab-Werbeeinwilligung.
Parameter descriptions missing or minimal. 'clause_text' and 'agb_text' have descriptions, but 'max_clauses' in analyze_agb lacks detail on why 100 is the default or what happens if exceeded.
Output schemas documented in docstrings but not formally declared in JSON Schema. LLMs cannot parse docstring examples reliably. Violations/suspicions/red_flags arrays and their field types should be in explicit schema definitions.
Error handling returns error_envelope() but provides no recovery guidance. When clause_text is empty, the error 'clause_text must be non-empty' does not suggest what the LLM should do next (e.g., 'Ask the user to provide the clause text').
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 68 | <=2025-11-25 | v2 |
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). All four tools are read-only and idempotent, declaring this via annotations helps agents optimize caching and retry logic.
Clause splitting regex in analyze_agb is incomplete (truncated in source). Cannot verify correctness of clause boundary detection, which is critical for accurate analysis.