break-clause-analyzer
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@break-clause-analyzerCheck if the break clause conditions are met"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
UK Break Clause Analyzer (MCP)
A self-evaluating MCP server that assesses whether a UK commercial-lease tenant break clause can actually be exercised — and publishes its own measured hallucination rate.
⚖️ Decision-support only — NOT legal advice. Built on a deliberately simplified, non-proprietary ruleset over synthetic data. A qualified solicitor must verify any real decision.
The £2m full stop
In 2012, a tenant served a valid break notice to walk away from a lease — but on the break date they hadn't paid one quarter's rent that had fallen due a few weeks earlier. The break failed. They were bound to the lease (and its rent) for years. No drama, no bad faith — just one unmet condition precedent that everyone missed until it was too late.
Break clauses are unforgiving like that. Whether a tenant can actually leave turns on a short checklist — notice served in time, notice served correctly, no rent arrears, vacant possession given — and getting any one wrong is catastrophic. It is exactly the kind of task you might hand to an LLM... if you could trust it not to confidently invent the answer.
This project is about earning that trust, and measuring it. It is not a clever parser. It is a reliability harness: every claim is grounded to verbatim source text or it isn't made, genuinely-ambiguous cases are routed to a human instead of guessed, and the whole thing ships with an eval that publishes how often it lies.
Related MCP server: contract-risk-analyzer
The edge
Grounded — every asserted condition is backed by a verbatim source span. If the system can't find the text, it returns
NOT_FOUND; it never invents a quote. A deterministic gate slices the span out of the source, so it can't echo hallucinated text.Calibrated — when the lease genuinely doesn't settle a point, the answer is
AMBIGUOUS — human verify, not a coin-flip. Abstaining honestly is a feature.Self-evaluating — a pytest harness scores extraction accuracy, citation faithfulness, hallucination rate, and calibration against 24 labelled cases.
Reasons + verifies — the LLM only proposes; deterministic code disposes (grounds every quote, does the date arithmetic, applies the vacant-possession legal test, aggregates the verdict).
The headline number
See report/report.md for the full eval (all four metrics,
per-model comparison, confusion matrix, caught-hallucination examples).
The committed report is the heuristic baseline (it runs with no API key) — and it already tells the core story: the grounding gate drives ungrounded (fabricated) hallucinations to zero, while a non-reasoning baseline still misgrounds and never abstains on the genuinely-ambiguous cases. That gap is exactly what a calibrated LLM is meant to close:
uv run python scripts/run_eval.py --record # measure claude-haiku-4-5 vs claude-sonnet-4-6How it works
flowchart LR
A["Lease + Background Facts"] --> T["MCP tools"]
T --> L["LLM adapter<br/>extract + reason · temperature 0"]
L -- "proposes verbatim quotes<br/>+ findings" --> G{"Grounding gate<br/>verbatim? else NOT_FOUND"}
G -- "spans sliced from source" --> C["Deterministic core<br/>checklist · UK date math · VP legal test"]
C --> R["Strict-precedence aggregate<br/>fail→INVALID · uncertain→AMBIGUOUS · else VALID"]
R --> O["Assessment<br/>verdict + calibration + human-verify gates"]
subgraph EVAL["Eval (the point)"]
D["24 labelled cases"] --> H["harness"] --> M["4 metrics"] --> P["report.md + SVG"]
endThe trust boundary is structural: the deterministic core/ package physically
cannot import the llm/ package (enforced by a test). "The LLM proposes,
deterministic code disposes" is a property of the codebase, not a discipline.
The four MCP tools (each does one thing)
Tool | What it does |
| Returns the break clause + its verbatim source span |
| The four-condition checklist: each pass / fail / uncertain, with grounded evidence |
| Exact verbatim supporting text for a claim, or |
| Orchestrated verdict + calibration note + mandatory human-verify gates |
Quickstart (clone to running in under 2 minutes)
# 1. Install uv (skip if you have it)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 2. Install deps (uv fetches its own Python 3.12)
uv sync
# 3. Run the test suite — proves the eval apparatus is correct
uv run pytest -q
# 4. Check the dataset (every gold span verbatim, every label coherent)
uv run python scripts/validate_dataset.py
# 5. Regenerate the eval report
uv run python scripts/run_eval.py # heuristic baseline, no key neededNo ANTHROPIC_API_KEY is required for any of the above — the eval falls back to the
heuristic baseline and is fully reproducible. Set the key (and --record) to
measure the real Claude models.
Your Anthropic API key
The key is only needed for live LLM extraction (the eval --record step and the
server's real mode). Everything else runs without one.
Never commit it.
.envis git-ignored and the cassettes redact thex-api-keyheader.For local commands, either export it or use a
.envfile:export ANTHROPIC_API_KEY=sk-ant-… # option 1: shell # or cp .env.example .env && $EDITOR .env # option 2: .env, then: uv run --env-file .env python scripts/run_eval.py --recordFor an MCP client, put it in the server config's
envblock (below).
Run the MCP server
# Inspect it interactively (the official MCP Inspector)
npx @modelcontextprotocol/inspector uv run break-clause-analyzerClaude Desktop — add to claude_desktop_config.json (use the absolute path to
your clone so it runs from the project):
{
"mcpServers": {
"break-clause-analyzer": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/rubo-mcp", "break-clause-analyzer"],
"env": { "ANTHROPIC_API_KEY": "sk-ant-…" }
}
}
}Claude Code — one command:
claude mcp add break-clause-analyzer -e ANTHROPIC_API_KEY=sk-ant-… \
-- uv run --directory /absolute/path/to/rubo-mcp break-clause-analyzerWithout a key the server still runs and responds — it uses the heuristic baseline and says so. Every tool response carries the decision-support disclaimer.
Reproducible evals (cassettes)
temperature=0 is not a determinism guarantee from the API, so reproducibility
comes from recorded cassettes (VCR.py). scripts/run_eval.py --record records one
cassette set per model with the x-api-key header redacted; re-running without
--record replays them with no key in seconds. See
eval/cassettes/README.md.
Layout
src/break_clause_analyzer/
core/ # deterministic trust boundary (no network; cannot import llm/)
grounding.py dates.py checklist.py aggregate.py
llm/ # the only network egress (Anthropic + heuristic fallback)
pipeline.py # propose → gate → dispose orchestration
server.py # FastMCP server: the four tools
data/cases/ # 24 labelled synthetic case files (+ dataset README)
eval/ # harness, metrics, report generator, cassettes
docs/METHODOLOGY.md # pre-registered metric definitions
report/ # generated eval report + SVG
.planning/ # the eval-first roadmap, requirements, and decision logMethodology & honesty
The metric definitions are pre-registered in
docs/METHODOLOGY.md before any model is run, so the
headline number can't be defined after the fact to look good. The hallucination
rate counts misgrounding and overconfidence — not just fabrication — precisely
because a grounding gate makes fabrication trivially zero. The scorer uses no LLM
judge; it is validated against a gold oracle and deliberately-broken systems in
tests/test_harness.py.
Scope (deliberately narrow)
Tenant break clauses only · four conditions precedent · synthetic/public data only · decision-support, not legal advice. Other lease provisions, landlord breaks, real client data, and a production engine are explicitly out of scope.
Built as a reliability-engineering artifact. The eval is the point.
Available Tools
4 toolsassess_validityARead-only
Orchestrated assessment: VALID / INVALID / AMBIGUOUS with per-condition results, the conditions that forced the verdict, a calibration note, and mandatory human-verify gates. Abstains to AMBIGUOUS rather than guess. Decision-support only.
| Name | Required | Description | Default |
|---|---|---|---|
| case_text | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| verdict | Yes | Overall assessment. AMBIGUOUS means 'human verify', not a coin-flip. |
| conditions | Yes | |
| disclaimer | No | |
| calibration | Yes | |
| human_verify | No | |
| decisive_conditions | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, but the description adds valuable behavioral context: it discloses abstention to AMBIGUOUS rather than guessing, mandatory human-verify gates, and decision-support-only intent. These go beyond the annotations and help the agent understand safety and verification requirements.
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 concise and front-loaded, starting with the core purpose and verdict types, then adding key behaviors (abstention, human-verify gates, decision-support). Every sentence contributes value without redundancy or waste.
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 covers the tool's orchestrated nature, output components (per-condition results, conditions forcing verdict, calibration note), abstention behavior, and human-verify requirement. It is largely complete given the schema and output schema exist, though it omits any mention of the input parameter and when to use it, which is partially covered by other dimensions.
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 0%, so the description must compensate for the single parameter (case_text). It does not explicitly explain what case_text should contain, its format, or any requirements. While the parameter name is self-explanatory, the description provides no direct semantic guidance, leaving a gap for low coverage.
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 states the tool's function with a specific verb ('Orchestrated assessment') and resource (the case text), and defines the output verdicts (VALID/INVALID/AMBIGUOUS). It distinguishes itself from siblings (extract_break_clause, check_conditions, find_citation) by being an orchestrated, holistic assessment rather than a targeted extraction or check.
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 implies usage context ('Orchestrated assessment', 'Decision-support only') but does not explicitly state when to use this tool versus alternatives, nor does it provide exclusions or when-not-to-use guidance. The abstention behavior is a partial guideline, but there is no direct comparison to sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_conditionsARead-only
Evaluate the four conditions precedent (notice timing, notice validity, rent/no-arrears, vacant possession) against the document, each pass/fail/uncertain with grounded evidence. Decision-support only.
| Name | Required | Description | Default |
|---|---|---|---|
| case_text | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| conditions | Yes | |
| disclaimer | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds context about the output format ('pass/fail/uncertain with grounded evidence') and decision-support nature. Since annotations already declare readOnlyHint: true, the description does not need to restate safety, but it does not reveal additional behavioral details like authentication or reversibility.
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 sentences, no redundant wording, and the key information is front-loaded. Every phrase earns its place: the conditions, the output nature, and the decision-support scope are all stated efficiently.
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 has only one input parameter and an output schema, so the description does not need to explain return values. It names all four conditions and specifies the pass/fail/uncertain plus evidence format. This is complete for a decision-support tool, though it does not mention edge cases like empty input or handling of ambiguous documents.
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 0%, but the single parameter case_text is self-explanatory as the document text. The description refers to 'the document' providing a light mapping, though it does not explicitly say the parameter represents the document. This is adequate for a simple string parameter.
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 ('Evaluate') and resource ('four conditions precedent') against the document, and names the four conditions (notice timing, notice validity, rent/no-arrears, vacant possession). It clearly distinguishes itself from siblings like extract_break_clause, find_citation, and assess_validity.
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 implies usage when evaluating conditions precedent, and states 'Decision-support only' which hints at its advisory role. However, it does not explicitly mention when to use this tool over alternatives, nor does it provide any exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
extract_break_clauseARead-only
Extract the tenant break clause from a lease document, returning its verbatim text and source span (or found=false). Decision-support only.
| Name | Required | Description | Default |
|---|---|---|---|
| lease_text | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| clause | Yes | Output of extract_break_clause: the clause + its grounded span, or not found. |
| disclaimer | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations (readOnlyHint: true, openWorldHint: false) already declare safe read-only behavior, and the description adds the behavioral detail of returning verbatim text and a source span, or found=false when absent. It also includes 'Decision-support only,' which signals its role as an analytical aid. The description is consistent with the annotations, providing extra context without contradiction.
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 a single, well-structured sentence that packs essential information: extraction action, input reference, output details, and fallback behavior. There is no wasted wording, and each clause adds value. It is appropriately concise and front-loaded.
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 tool's simplicity (one string parameter) and presence of an output schema, the description is sufficient to convey the tool's function and return behavior. It covers the core purpose, the input, and the failure case (found=false), which is important. It does not need to elaborate on output format since the output schema exists, and the description is complete for this level of complexity.
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?
The only parameter, lease_text, is described implicitly through 'lease document,' indicating it should contain the lease text. However, the schema description coverage is 0%, and the description does not elaborate on input format, length, or preconditions. The parameter name itself is fairly self-explanatory, but the description adds minimal meaning beyond that.
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 states the tool's function: extracting the tenant break clause from a lease document, with a specific verb ('Extract') and resource ('tenant break clause'). It also specifies the return format (verbatim text and source span, or found=false), making the purpose unambiguous. While it doesn't explicitly compare to sibling tools, the unique extraction task distinguishes it from check_conditions, find_citation, and assess_validity.
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 implies the tool is for extracting a specific clause but provides no explicit guidance on when to use this tool versus alternatives. 'Decision-support only' is a caveat about usage context, not a comparison with sibling tools. No exclusions or alternative tool references are given, so the usage guidance is limited to what's self-evident.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_citationARead-only
Return the exact verbatim text in the source that supports a claim, or NOT_FOUND. Never invents text. Deterministic. Decision-support only.
| Name | Required | Description | Default |
|---|---|---|---|
| claim | Yes | ||
| source_text | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| citation | Yes | The result of grounding a claim. ``found=False`` is the NOT_FOUND outcome: the system could not locate verbatim support and refuses to invent any. There is no path that substitutes model text for a real span. |
| disclaimer | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as read-only, so the description adds value by disclosing deterministic behavior, the constraint of never inventing text, and the explicit NOT_FOUND return convention. This goes beyond the structured 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?
The description is extremely concise—two sentences front-loaded with the core action and output behavior. Every clause adds value (verbatim, NOT_FOUND, never invents, deterministic, decision-support). No wasted words.
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 tool's simplicity, the description covers the essential return values and constraints. The presence of an output schema (not shown) likely documents return structure; description explains the high-level behavior. Missing edge-case details but acceptable for the tool's scope.
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 0%, but the parameter names (source_text, claim) are self-explanatory. The description refers to 'source' and 'claim' without adding format or constraints beyond what the schema provides, leaving room for more detail but not critical.
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 states the tool's function: returning exact verbatim text from a source that supports a claim, or NOT_FOUND. This is a specific verb-resource combination that distinguishes it from siblings like extract_break_clause or check_conditions.
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 implies usage (when you need supporting evidence for a claim) but does not explicitly state when to prefer this over alternatives or provide exclusions. The phrase 'Decision-support only' hints at appropriate contexts but lacks explicit guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool targets a distinct step in the analysis pipeline: extract the clause, check conditions, find supporting evidence, and produce the final assessment. There is no overlap in purpose.
All tool names follow the verb_noun pattern (extract_break_clause, check_conditions, find_citation, assess_validity), making the naming scheme predictable and uniform.
With 4 tools, the server is well-scoped for a focused break-clause analysis workflow. Each tool serves a necessary, non-redundant role.
The tool set covers the full analysis lifecycle: extraction, condition evaluation, citation retrieval, and final validity assessment. No obvious dead ends or missing operations for the stated purpose.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Lease analysis: flag illegal/risky clauses by jurisdiction (ontario, bc, nyc, texas, general).
Contract review that keeps your contracts: cited answers, Word redlines, key-date alerts.
Verifies legal citations vs primary sources: existence, quote match, proposition support.
Neutral referee for legal-AI output: flags orphan quotes and uncited claims. Not legal advice.
Related MCP Servers
- AlicenseAqualityBmaintenanceProvides comprehensive tools for searching UK case law, legislation, parliamentary Hansard debates, and HMRC tax guidance. It features a specialized OSCOLA citation parser to extract and resolve legal references directly from text.3513MIT
- FlicenseNot gradedqualityDmaintenanceAnalyzes financial contract PDFs to extract clauses, flag risk terms, and compare contract versions, producing structured risk briefs for legal and risk teams.
- AlicenseNot gradedqualityBmaintenanceExact French real-estate legal calculations for AI agents: IRL rent revision, service-charge reconciliation, compliant rent receipts — legal basis included in every answer.MIT
- AlicenseNot gradedqualityCmaintenanceEnables users to paste contracts, leases, terms of service, and other documents to receive a plain-English summary of key risks, deadlines, rights, and negotiation points.MIT
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/Ankur-stockheads/rubo-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server