Contract review where AI agents propose redlines and humans dispose. Built on WebMCP.
Redline demonstrates solid tool design with clear naming, comprehensive descriptions, and well-structured schemas. All 9 tools follow verb_noun conventions (get_, list_, flag_, annotate_, propose_, compare_). Descriptions are detailed (100-250 chars typical) and explain WHEN to use each tool. Input schemas are complete with proper types and enums. However, output schemas are not formally documented, responses are JSON but structure is inferred from code. Error handling is minimal; tools return plain strings on failure rather than structured error objects with recovery guidance. Parameter descriptions are strong but could be more explicit about constraints (e.g., maxLength on text fields is in schema but not always in description text). Tool composition is excellent: read tools support discovery, write tools create proposals (not direct mutations), and the invariant that agents cannot accept proposals is enforced structurally.
Attach a plain-English note to a clause explaining what it actually means in practice. Use it for dense legal language the reviewer needs translated. This is a note for the human — it does not change the contract.
Compare a clause against the market-standard playbook for this kind of agreement and get back the standard position plus how this contract deviates from it. Omit clauseId to compare the whole contract.
Attach a risk flag to a clause so it is marked in the document for the reviewer. Explain the concrete consequence for the party in get_review_context — what this could cost them and in what circumstances — not merely that the clause is unusual. Raise one flag per distinct risk.
Get the full text of specific clauses, or of the whole contract. Pass clauseIds for particular clauses; omit it to read everything. Always read a clause before proposing an edit to it — proposals written against text you have not read are usually wrong.
Get the contract's structure and review state: title, counterparty, which side of the deal you are reviewing for, the current phase, the ordered clause index with ids and headings, and counts of open redlines and risk flags. Call this first — every other tool needs clause ids from here.
Output schemas not formally documented. Tools return JSON but structure is inferred from code (e.g., get_document returns title, counterparty, phase, clauses array). LLMs cannot reliably parse undocumented output structures, risking field extraction errors and downstream tool call failures.
Error handling returns plain strings instead of structured error objects. When a clause ID is invalid, get_clauses returns 'Error: no clause with id...' as a string. LLMs cannot distinguish errors from success responses, cannot classify them as retryable/fatal, and cannot extract recovery guidance.
propose_redline has a required 'proposedText' parameter but the description does not state that it is required for replace/insert operations. The schema shows it required unconditionally, but the description says 'Required for replace and insert', this mismatch could cause LLM confusion about when the parameter is mandatory.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 67 | 2026-07-28+ | v2 |
Get who this review is for and what they care about: their role in the deal, their stated priorities, and their hard dealbreakers. Read this before flagging risks or drafting language — a clause that is dangerous for a contractor may be perfectly fine for a client, and proposals that ignore the dealbreakers get rejected.
List risk flags already raised on this contract, with severity, category, and who raised them. Check this before flagging so you add to the analysis instead of repeating it.
List redlines with their current status (pending, accepted, rejected, or withdrawn), who wrote each one, and any reason a human gave when rejecting. Use this to check the outcome of your own proposals, avoid duplicating a change someone already proposed, and learn what this reviewer tends to reject.
Propose a change to the contract: replace a clause's text, delete a clause, or insert a new one. Every proposal requires a rationale — the reviewer needs to understand why you are proposing this change. Proposals are pending until a human accepts or rejects them in the UI; the contract is unchanged until acceptance.
No pagination support on list_proposals and list_flags. If a contract has hundreds of proposals or flags, these tools return all results, risking context window exhaustion. No limit parameter, no offset/cursor, no total count in response.
Tool composition: propose_redline requires a 'rationale' parameter (max 400 chars) but does not reference get_review_context or list_flags in its description. LLMs may propose changes without checking dealbreakers or existing flags, leading to rejected proposals. Description should guide: 'Read get_review_context and list_flags before proposing to avoid dealbreaker violations.'