UK legal research MCP server — case law, legislation, parliament, bills, votes, committees, citations, HMRC
Project description
uk-legal-mcp
A Model Context Protocol server for UK legal research. Connects AI assistants to case law, legislation, parliamentary debates, bills, votes, committees, OSCOLA citation parsing, and HMRC tax data through a single endpoint.
24 tools across 8 modules. One connection. Read-only. No API keys required for 23 of 24 tools.
MCP Client (Claude, Cursor, etc.)
|
v
uk-legal-mcp gateway (Streamable HTTP)
+----------------------------------------------------+
| |
| case_law TNA Find Case Law API |
| legislation legislation.gov.uk Atom feed |
| parliament Hansard API + Members API |
| bills Parliamentary Bills API |
| votes Commons + Lords division records |
| committees Select committees + evidence |
| citations OSCOLA regex parser (no network) |
| hmrc HMRC sandbox/prod + GOV.UK search |
| |
+----------------------------------------------------+
Quickstart
Connect to the hosted server
Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"uk-legal": {
"type": "http",
"url": "https://uk-legal-mcp.fly.dev/mcp"
}
}
}
Then try:
- "Search for case law about cycling accidents"
- "Get section 172 of the Companies Act 2006"
- "Parse the citations in: The court applied Donoghue v Stevenson [1932] AC 562 and s.2 Occupiers' Liability Act 1957"
- "What is parliament saying about short selling?"
Run locally
pip install -e .
python -m src.gateway
# Server starts on http://localhost:8000/mcp
Inspect with the MCP Inspector:
npx @modelcontextprotocol/inspector http://localhost:8000/mcp
Tools
Case Law
| Tool | What it does |
|---|---|
case_law_search |
Full-text search of UK judgments. Filter by court, judge, party, date range. |
case_law_grep_judgment |
Find paragraphs in a judgment matching a pattern. Returns {eId, snippet, match} per hit. |
Resource templates (read via resources/read or the read_resource tool generated by ResourcesAsTools):
| URI template | Returns |
|---|---|
judgment://{slug*}/header |
Metadata header (parties, judges, citation). ~1k tokens. |
judgment://{slug*}/index |
Paragraph eId + first-line per row. ~4k tokens. Walk this to discover paragraphs. |
judgment://{slug*}/para/{eId} |
A single paragraph including its sub-paragraphs. 400–1700 tokens. |
Upstream: TNA Find Case Law (Atom/XML). Rate limit: 1,000 req/5 min. Cached 1 hour.
Legislation
| Tool | What it does |
|---|---|
legislation_search |
Search Acts of Parliament and Statutory Instruments on legislation.gov.uk. |
legislation_get_toc |
Table of contents for an Act — parts, chapters, sections, schedules. |
legislation_get_section |
Retrieve a specific section with territorial extent, in-force status, and version date. |
Resource templates (alternative to the tools above for clients that prefer URI-addressed reads):
| URI template | Returns |
|---|---|
legislation://{type}/{year}/{number} |
Full Act/SI as CLML XML. |
legislation://{type}/{year}/{number}/section/{section} |
A specific section as CLML XML. |
legislation://{type}/{year}/{number}/toc |
Flat id: title lines for the table of contents. |
legislation://{type}/{year}/{number}/{date} |
Point-in-time CLML for a YYYY-MM-DD date. |
Upstream: legislation.gov.uk (CLML XML + Atom feed). Cached 24 hours. Uses curl_cffi with Chrome impersonation to defeat CloudFront 437; Companies Act 2006 currently hits an AWS WAF JS challenge intermittently.
Note: Always check the extent field. A section may apply to England and Wales but not Scotland or Northern Ireland.
Parliament
| Tool | What it does |
|---|---|
parliament_search_hansard |
Search Hansard debate contributions by exact phrase. |
parliament_vibe_check |
Assess parliamentary reception of a policy topic. Searches Hansard, then uses LLM sampling to classify sentiment, supporters, opponents, and concerns. |
parliament_find_member |
Look up an MP or Lord by name. Returns member ID for use with member_debates. |
parliament_member_debates |
Retrieve a specific member's Hansard contributions, optionally filtered by topic. |
parliament_member_interests |
Get a member's registered financial interests (donations, shareholdings, etc.). |
parliament_search_petitions |
Search UK Parliament petitions by keyword. |
Upstream: hansard-api.parliament.uk + members-api.parliament.uk + petition.parliament.uk. Not cached (live data).
Bills
| Tool | What it does |
|---|---|
bills_search_bills |
Search current and historical parliamentary bills by keyword, session, or type. |
bills_get_bill |
Get full bill detail — stages, sponsors, publications. |
Upstream: bills-api.parliament.uk. Cached 1 hour.
Votes
| Tool | What it does |
|---|---|
votes_search_divisions |
Search Commons and Lords division records by keyword or date. |
votes_get_division |
Get full division detail — vote counts, how each member voted. |
Upstream: commonsvotes-api.parliament.uk + lordsvotes-api.parliament.uk. Cached 24 hours.
Committees
| Tool | What it does |
|---|---|
committees_search_committees |
Search parliamentary select committees by keyword. |
committees_get_committee |
Get committee detail — membership, sub-committees. |
committees_search_evidence |
Search oral and written evidence submissions to committees. |
Upstream: committees-api.parliament.uk. Cached 1 hour.
Citations
| Tool | What it does |
|---|---|
citations_parse |
Extract all OSCOLA citations from free text. Resolves to canonical URLs. Disambiguates bare court codes via LLM sampling. |
citations_resolve |
Parse and resolve a single citation string to its canonical URL. |
citations_network |
Fetch a judgment from TNA and map every citation within it — cases, legislation, SIs, EU law. |
Self-contained. No external API. Zero network dependency (except citations_network which fetches the judgment XML).
Supported citation formats:
| Format | Example |
|---|---|
| Neutral citation | [2024] UKSC 12 |
| Law report (with or without volume) | [2024] 1 WLR 100, [1932] AC 562 |
| Legislation section | s.47 Companies Act 2006 |
| Statutory Instrument | SI 2018/1234 |
| Retained EU law | Regulation (EU) 2016/679 |
HMRC
| Tool | What it does |
|---|---|
hmrc_get_vat_rate |
VAT rate lookup for any commodity or service. Static table current as of Autumn Statement 2023. |
hmrc_check_mtd_status |
Check Making Tax Digital VAT mandate status for a VRN. Requires HMRC OAuth credentials. |
hmrc_search_guidance |
Search GOV.UK for HMRC guidance documents. |
hmrc_get_vat_rate and hmrc_search_guidance require no credentials. hmrc_check_mtd_status requires HMRC_CLIENT_ID and HMRC_CLIENT_SECRET — register at developer.service.hmrc.gov.uk. Defaults to sandbox; set HMRC_API_BASE=https://api.service.hmrc.gov.uk for production.
Prompts
Four workflow prompts are available for multi-step legal research. Exposed as tools via PromptsAsTools for ChatGPT; accessible natively on protocol-aware clients (Claude, Inspector).
| Prompt | Module | Description |
|---|---|---|
summarise_act |
legislation | Structured summary of a UK Act or SI |
compare_legislation |
legislation | Comparative analysis of two pieces of legislation on a topic |
policy_vibe_check |
parliament | Parliamentary reception assessment for a policy |
member_position_analysis |
parliament | A member's position and voting record on a topic |
Architecture
src/
gateway.py FastMCP gateway — mounts all modules, applies middleware
deps.py Shared httpx clients (lifespan-managed) + error formatting
modules/
case_law/ TNA Find Case Law (Atom/XML parsing)
legislation/ legislation.gov.uk (CLML XML + Atom feed)
parliament/ Hansard API + Members API + Petitions (JSON)
bills/ Parliamentary Bills API (JSON)
votes/ Commons + Lords division records (JSON)
committees/ Select committees + evidence (JSON)
citations/ OSCOLA regex engine (compiled once, lru_cache)
hmrc/ HMRC OAuth + GOV.UK search (JSON)
tests/
test_citations.py 35 unit tests — regex patterns, resolution, disambiguation
Each module is a standalone FastMCP instance mounted into the gateway with a namespace prefix (case_law_, legislation_, etc.). All modules share a single httpx client pool via the gateway's lifespan context.
Middleware stack (gateway level):
| Middleware | Purpose |
|---|---|
ErrorHandlingMiddleware |
Catches unhandled exceptions |
StructuredLoggingMiddleware |
JSON logging with duration and payload size |
DetailedTimingMiddleware |
Per-tool timing logs |
ResponseLimitingMiddleware |
80,000 char cap (LegalDocML XML can exceed 200k) |
Per-module caching: ResponseCachingMiddleware with TTLs — case_law (1hr), legislation (24hr), bills (1hr), votes (24hr), committees (1hr), hmrc (90 days). Parliament and citations are not cached.
Deployment
Fly.io
fly auth login
fly launch --name uk-legal-mcp --region lhr
fly deploy
Optional secrets:
fly secrets set HMRC_CLIENT_ID=your_id HMRC_CLIENT_SECRET=your_secret
# For production HMRC (default is sandbox):
fly secrets set HMRC_API_BASE=https://api.service.hmrc.gov.uk
Docker
docker build -t uk-legal-mcp .
docker run -p 8000:8000 uk-legal-mcp
Testing
pip install -e '.[test]' # or: pip install pytest
pytest tests/test_citations.py -v
All 35 citation tests run offline with no API credentials.
Upstream APIs and Licences
| Source | API | Licence | Auth |
|---|---|---|---|
| TNA Find Case Law | caselaw.nationalarchives.gov.uk |
Open Justice Licence | None |
| legislation.gov.uk | legislation.gov.uk |
OGL v3 | None |
| UK Parliament Hansard | hansard-api.parliament.uk |
Open Parliament Licence | None |
| UK Parliament Members | members-api.parliament.uk |
Open Parliament Licence | None |
| UK Parliament Petitions | petition.parliament.uk |
Open Parliament Licence | None |
| UK Parliament Bills | bills-api.parliament.uk |
Open Parliament Licence | None |
| UK Parliament Votes | commonsvotes-api.parliament.uk |
Open Parliament Licence | None |
| UK Parliament Committees | committees-api.parliament.uk |
Open Parliament Licence | None |
| HMRC | test-api.service.hmrc.gov.uk |
OGL / commercial terms | OAuth 2.0 |
| GOV.UK Search | www.gov.uk/api/search.json |
OGL v3 | None |
Stack
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file uk_legal_mcp-0.4.2.tar.gz.
File metadata
- Download URL: uk_legal_mcp-0.4.2.tar.gz
- Upload date:
- Size: 254.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2fd3153caf1abd21f60eb89feee7a181d155095aa030425a334334553d7180e6
|
|
| MD5 |
758f98ba97102b3a091cb318ef3b7f08
|
|
| BLAKE2b-256 |
dab624f72aa9be836344305b9c7fa5458dca429f4160b5975d26a66f46efb3c5
|
Provenance
The following attestation bundles were made for uk_legal_mcp-0.4.2.tar.gz:
Publisher:
release.yml on paulieb89/uk-legal-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uk_legal_mcp-0.4.2.tar.gz -
Subject digest:
2fd3153caf1abd21f60eb89feee7a181d155095aa030425a334334553d7180e6 - Sigstore transparency entry: 1428881015
- Sigstore integration time:
-
Permalink:
paulieb89/uk-legal-mcp@37b5d2bb38bc5dd10005f589e3ba49092d31536a -
Branch / Tag:
refs/tags/v0.4.2 - Owner: https://github.com/paulieb89
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@37b5d2bb38bc5dd10005f589e3ba49092d31536a -
Trigger Event:
release
-
Statement type:
File details
Details for the file uk_legal_mcp-0.4.2-py3-none-any.whl.
File metadata
- Download URL: uk_legal_mcp-0.4.2-py3-none-any.whl
- Upload date:
- Size: 72.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7e87cb15f48c3a882a3ebb52ac6ba622ffbddcd7cbfb485bd8df1dee7a657f11
|
|
| MD5 |
1c87f88906c59dd1e47df3d464e5f607
|
|
| BLAKE2b-256 |
18310e880ac449acb31b8cb890c422580e63aa804ca0520bf55d1c00432ff2d5
|
Provenance
The following attestation bundles were made for uk_legal_mcp-0.4.2-py3-none-any.whl:
Publisher:
release.yml on paulieb89/uk-legal-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uk_legal_mcp-0.4.2-py3-none-any.whl -
Subject digest:
7e87cb15f48c3a882a3ebb52ac6ba622ffbddcd7cbfb485bd8df1dee7a657f11 - Sigstore transparency entry: 1428881019
- Sigstore integration time:
-
Permalink:
paulieb89/uk-legal-mcp@37b5d2bb38bc5dd10005f589e3ba49092d31536a -
Branch / Tag:
refs/tags/v0.4.2 - Owner: https://github.com/paulieb89
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@37b5d2bb38bc5dd10005f589e3ba49092d31536a -
Trigger Event:
release
-
Statement type: