legal-contract-mcp
An MCP (Model Context Protocol) server that gives an LLM client (Claude, Claude Code, Claude Desktop, etc.) tools to do a first-pass review of contracts: load a .txt/.docx/.pdf, detect standard clause types, flag heuristic risk issues, generate a summary, and diff two contracts against each other.
This is not legal advice — it's a rules-based first pass meant to speed up human review, built to demonstrate a real, non-trivial MCP server (as opposed to a toy "add two numbers" example).
Why this exists
Most MCP server examples are thin wrappers around an API call. This one does actual work locally:
- Parses real document formats (txt/docx/pdf)
- Detects 12 standard clause types via a maintained pattern library, not a single regex
- Runs 8 explainable risk heuristics (e.g. indemnification without a liability cap, auto-renewal without a clear notice period, non-competes with no defined scope) — every flag cites the exact clause text it's based on
- Falls back gracefully to an extractive summary if no
ANTHROPIC_API_KEYis set, and upgrades to an LLM-generated summary if one is
Tools exposed
| Tool | Description |
|---|---|
load_contract(path) |
Load a .txt/.docx/.pdf file, returns a doc_id |
list_documents() |
List contracts loaded in this session |
extract_clauses(doc_id) |
Detected clause types with snippets |
missing_clauses(doc_id) |
Standard clause types NOT found — gap check |
flag_risks(doc_id) |
Heuristic risk flags with severity + evidence |
summarize_contract(doc_id) |
Plain-English summary (LLM or extractive fallback) |
compare_contracts(doc_id_a, doc_id_b) |
Diff clause types and risk flags between two contracts |
search_clause_library(query) |
Look up a clause type's definition by keyword |
Setup
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ".[dev]"
Optional — enable LLM-powered summaries:
export ANTHROPIC_API_KEY=sk-ant-...
Run it
Inspector (interactive dev UI):
mcp dev src/legal_contract_mcp/server.py
As a stdio server (for Claude Desktop / Claude Code config):
{
"mcpServers": {
"legal-contract-mcp": {
"command": "python",
"args": ["-m", "legal_contract_mcp.server"],
"cwd": "/absolute/path/to/legal-contract-mcp",
"env": { "ANTHROPIC_API_KEY": "sk-ant-..." }
}
}
}
Then in a chat with the connected client:
Load the contract at tests/sample_contracts/weak_nda.txt and flag its risks.
Test
pytest # unit tests for clause detection + risk rules
python scripts/smoke_test.py # spins up the real MCP server over stdio and calls every tool
Includes two sample contracts (tests/sample_contracts/weak_nda.txt and solid_msa.txt) chosen so the risk engine's output differs meaningfully between a weak and a well-drafted agreement — tests assert on that difference, not just "does it run."
Project structure
src/legal_contract_mcp/
parsing.py # txt/docx/pdf -> plain text, in-memory doc store
clause_library.py # 12 clause types: definitions + detection patterns
clauses.py # runs the library against a document
risk_rules.py # 8 heuristic risk rules, each with cited evidence
llm.py # optional Claude-powered summary, extractive fallback
server.py # FastMCP tool definitions
tests/
sample_contracts/ # weak NDA vs. solid MSA fixtures
test_clauses_and_risks.py
Extending it
- Add a clause type: add an entry to
CLAUSE_LIBRARYinclause_library.pywith a definition and one or more regex patterns. - Add a risk rule: add a function block to
evaluate_risks()inrisk_rules.py— return aRiskFlagwithrule,severity,message, andevidence. - Swap the in-memory store in
parsing.pyfor a database if you want documents to persist across server restarts.
Disclaimer
This tool provides automated, heuristic pattern-matching only. It is not a substitute for review by a licensed attorney and should not be relied on as legal advice.