paulieb89 avatar

UK Legal Research

paulieb89/uk-legal-mcp

Connects Claude and other MCP clients to UK legal sources without API keys. Exposes tools for searching case law from Find Case Law, reading legislation.gov.uk Acts and SIs with point-in-time sections, querying Hansard debates and divisions, tracking bill stages and committee evidence, and parsing OSCOLA citations into canonical references. Also covers HMRC guidance lookups and optional Making Tax Digital endpoints. Returns primary source text plus citation metadata so you can build verifiable evidence packs instead of relying on memory. Runs over HTTP at uk-legal-mcp.fly.dev/mcp or locally via uvx. Most useful when you need to cite UK statutes, trace parliamentary votes, or pull judgment paragraphs with neutral citations for legal research workflows.

GitHub stars
20
tools
37
transport
STDIO, HTTP
last updated
Sep 4, 2026

Install

From registry metadata
$ npx add-mcp https://uk-legal-mcp.fly.dev/mcp --name uk-legal-mcp

Run in your terminal. add-mcp asks which agents to add it to (Claude Code, Codex, Cursor and more). Add -g to install it for every project.

Review the command, arguments and environment values before installing. MCP servers run with your local permissions.

Other ways

Claude Code

$ claude mcp add --transport http uk-legal-mcp https://uk-legal-mcp.fly.dev/mcp

Run in your terminal. Add --scope user to make it available in every project.

Tools

Verified live · 37 tools

Verified live against the running server on Nov 6, 2026.

judgment_get_headerUSE THIS TOOL WHEN you have a judgment slug and need metadata (parties, judges, neutral citation, court, dates). Call case_law_search FIRST to get the slug. AFTER calling, use judgment_get_index to discover paragraphs, then judgment_get_paragraph to read specific ones. Authori...1 params

USE THIS TOOL WHEN you have a judgment slug and need metadata (parties, judges, neutral citation, court, dates). Call case_law_search FIRST to get the slug. AFTER calling, use judgment_get_index to discover paragraphs, then judgment_get_paragraph to read specific ones. Authori...

Parameters* required
slug*string
Judgment slug, e.g. 'uksc/2024/12' or 'ewca/civ/2023/450'
judgment_get_indexUSE THIS TOOL WHEN you have a judgment slug and want the paragraph navigation index (eId + preview line for every paragraph). Call case_law_search FIRST to get the slug. AFTER calling, pass an eId from the returned list into judgment_get_paragraph to read that paragraph's full...1 params

USE THIS TOOL WHEN you have a judgment slug and want the paragraph navigation index (eId + preview line for every paragraph). Call case_law_search FIRST to get the slug. AFTER calling, pass an eId from the returned list into judgment_get_paragraph to read that paragraph's full...

Parameters* required
slug*string
Judgment slug, e.g. 'uksc/2024/12'
judgment_get_paragraphUSE THIS TOOL WHEN you have a judgment slug + LegalDocML eId and want that paragraph's full text. Call judgment_get_index FIRST to discover available eIds (or use case_law_grep_judgment to locate paragraphs by content). Returns the paragraph XML content (400–1,700 tokens typic...2 params

USE THIS TOOL WHEN you have a judgment slug + LegalDocML eId and want that paragraph's full text. Call judgment_get_index FIRST to discover available eIds (or use case_law_grep_judgment to locate paragraphs by content). Returns the paragraph XML content (400–1,700 tokens typic...

Parameters* required
eId*string
Paragraph eId from judgment_get_index, e.g. 'para_12'. Numeric strings like '12' are accepted and normalized to 'para_12'.
slug*string
Judgment slug, e.g. 'uksc/2024/12'
case_law_searchUSE THIS TOOL WHEN searching UK case law by party names, court, judge, date, or free-text query. Returns paginated judgment summaries: neutral citation, court, dates, slug, stable TNA URI. AFTER calling: pass slug into judgment_get_header / judgment_get_index / judgment_get_pa...8 params

USE THIS TOOL WHEN searching UK case law by party names, court, judge, date, or free-text query. Returns paginated judgment summaries: neutral citation, court, dates, slug, stable TNA URI. AFTER calling: pass slug into judgment_get_header / judgment_get_index / judgment_get_pa...

Parameters* required
courtvalue
Filter by court slug. Values: 'uksc', 'ukpc', 'ewca/civ', 'ewca/crim', 'ewhc/kb', 'ewhc/ch', 'ewhc/comm', 'ewhc/fam', 'ewhc/pat', 'ewhc/ipec', 'ewhc/admin', 'ewhc/tcc', 'ewhc/costs', 'ewfc', 'ewcop...
from_datevalue
Earliest judgment date (YYYY-MM-DD). NOTE: the TNA atom.xml endpoint currently appears to ignore this filter — the same results come back regardless. Do not rely on it to narrow output; sort+slice...
judgevalue
Filter by judge surname. Case-insensitive substring match against the indexed form. Use the surname alone ('Reed', 'Sumption') or with the bare title ('Lord Reed'). Honorific suffixes silently zero...
limitinteger
Maximum results to return (1–50). TNA returns up to 50 per request; this slices client-side. Default 10 for a tight shortlist. Set higher for breadth (e.g. 50 to scan the full result set).default: 10
pageinteger
Result page number (1-indexed)default: 1
partyvalue
Filter by party name
query*string
Full-text search query, e.g. 'negligence duty of care'
to_datevalue
Latest judgment date (YYYY-MM-DD). Same caveat as `from_date` — currently silently ignored by upstream. Filtering happens client-side at best.
case_law_grep_judgmentUSE THIS TOOL WHEN you have a judgment slug and want to find paragraphs whose text matches a pattern. Returns a list of `{eId, snippet, match}` hits — small per-paragraph snippets centred on the match. AFTER calling, read full paragraphs via judgment_get_paragraph(slug, eId) o...4 params

USE THIS TOOL WHEN you have a judgment slug and want to find paragraphs whose text matches a pattern. Returns a list of `{eId, snippet, match}` hits — small per-paragraph snippets centred on the match. AFTER calling, read full paragraphs via judgment_get_paragraph(slug, eId) o...

Parameters* required
case_insensitiveboolean
Default true. Set false for case-sensitive matching.default: true
max_hitsinteger
Cap on number of hits returned.default: 25
pattern*string
Regex pattern (or plain substring) to search within paragraph text. If the pattern doesn't compile as regex, falls back to literal substring match.
slug*string
TNA judgment slug, e.g. 'uksc/2024/12' or 'ewca/civ/2023/450'.
legislation_searchUSE THIS TOOL WHEN searching UK Acts and Statutory Instruments by title, phrase, or full-text. Returns ranked results: title, type, year, number, legislation.gov.uk URL, and next_steps hints (toc URI, section template). AFTER calling, chain to legislation_get_toc then legislat...5 params

USE THIS TOOL WHEN searching UK Acts and Statutory Instruments by title, phrase, or full-text. Returns ranked results: title, type, year, number, legislation.gov.uk URL, and next_steps hints (toc URI, section template). AFTER calling, chain to legislation_get_toc then legislat...

Parameters* required
fulltextboolean
Default false → searches Act/SI titles only (best for finding a named Act, e.g. 'Housing Act 1988' returns ukpga/1988/50 first). Set true to search the full text of every Act/SI for the query (retu...default: false
limitinteger
Maximum results to return (1–50). Passed to the upstream results-count param.default: 20
query*string
Search query, e.g. 'Housing Act 1988' or 'data protection personal data'
typevalue
Filter by type: 'ukpga' (Acts), 'uksi' (SIs), 'asp' (Scottish Acts), 'nia' (NI Acts). Exact-match — omit if you don't already know whether you're looking for an Act vs an SI.
yearvalue
Filter by year of enactment (exact-match — a single integer, not a range). Omit unless you already know the Act's year. Speculating a year (e.g. 'this is recent so it must be 2026') and getting it...
legislation_get_sectionUSE THIS TOOL WHEN you have a known Act / SI and want the parsed text of a specific section, regulation, or article, with extent and in-force metadata. Returns the provision's own text and heading, never a neighbouring Part/Chapter. Also returns extent, in-force/prospective da...5 params

USE THIS TOOL WHEN you have a known Act / SI and want the parsed text of a specific section, regulation, or article, with extent and in-force metadata. Returns the provision's own text and heading, never a neighbouring Part/Chapter. Also returns extent, in-force/prospective da...

Parameters* required
max_charsinteger
Maximum characters of section content to return. Default 10,000 (~2,500 tokens) covers almost every section. Raise to 50,000+ only for unusually long Finance Act definition sections. Check content_...default: 10000
number*integer
Chapter or SI number
section*string
Provision number, e.g. '47' or '12A' — works for Act sections, SI regulations, and SI articles alike. Use the numeric part only — not 'section-47'/'regulation-47'/'article-47'. Schedules are not cu...
type*string
Legislation type code: 'ukpga' (Acts), 'uksi' (SIs), 'asp' (Scottish Acts), 'nia' (NI Acts). Use the value from legislation_search results.
year*integer
Year of enactment
legislation_get_tocUSE THIS TOOL WHEN you have a known Act / SI and want the structural table of contents (parts, chapters, individual sections/regulations/articles). Returns XML ids and titles in document order, including Parts, chapters, crossheadings, and provisions; a rare untitled provision...5 params

USE THIS TOOL WHEN you have a known Act / SI and want the structural table of contents (parts, chapters, individual sections/regulations/articles). Returns XML ids and titles in document order, including Parts, chapters, crossheadings, and provisions; a rare untitled provision...

Parameters* required
limitinteger
Maximum items to return in this call (default 200, max 1000). Raise only when you need a larger slice in one response. Check has_more and total_items to know if further pages exist.default: 200
number*integer
Chapter or SI number
offsetinteger
Number of items to skip from the flattened TOC. Use with limit to page through very large statutes like the Companies Act 2006 (1300+ items).default: 0
type*string
Legislation type code: 'ukpga' (Acts), 'uksi' (SIs), 'asp' (Scottish Acts), 'nia' (NI Acts). Use the value from legislation_search results.
year*integer
Year of enactment
parliament_search_hansardUSE THIS TOOL WHEN searching Hansard by topic, bill title, or text phrase. Returns source-backed contributions with citation-grade metadata: member_id, attributed_to, column_ref, debate_id, debate_ext_id, contribution_ext_id, and public URL. The independent corpus envelope is...9 params

USE THIS TOOL WHEN searching Hansard by topic, bill title, or text phrase. Returns source-backed contributions with citation-grade metadata: member_id, attributed_to, column_ref, debate_id, debate_ext_id, contribution_ext_id, and public URL. The independent corpus envelope is...

Parameters* required
contribution_typestring
Which Hansard section to paginate. 'Spoken' = chamber + Westminster Hall debates (the default; what a lawyer usually means). 'Written' = written answers and statements. 'Corrections' = published co...one of Spoken · Written · Correctionsdefault: Spoken
from_datevalue
Start date (YYYY-MM-DD)
housestring
Restrict to one House. Default 'both' returns Commons + Lords contributions.one of Commons · Lords · bothdefault: both
limitinteger
Max contributions per call (1–100). Default 20. Paginate further with offset; total corpus size is in total_corpus on the response.default: 20
member_idvalue
Filter to contributions by a single member. Pass the integer Members API ID (resolve a name via parliament_find_member). The prior `member` field accepted a name string but Hansard's /search.json s...
offsetinteger
Skip this many contributions before the page. Default 0. Re-call with offset=offset+returned to paginate; has_more flags whether more remain.default: 0
query*string
Phrase to find in Hansard contribution text bodies. Hansard searches the words members actually said in their speeches — NOT debate titles, topic metadata, or written headlines. Pass tokens that wo...
text_modestring
'preview' returns the upstream ~250-char snippet (fast, low context cost). 'full' returns ContributionTextFull (still capped at 3000 chars). For full contribution text without the cap, read the res...one of preview · fulldefault: preview
to_datevalue
End date (YYYY-MM-DD)
parliament_policy_position_summaryUSE THIS TOOL WHEN you want debate-level corpus signals on a topic — by_house, by_year, by_section breakdowns — without reading every contribution. Aggregates Hansard debate-level signals on a topic. Pure counts — no LLM, no editorial labels. Sweeps /search/Debates.json with p...5 params

USE THIS TOOL WHEN you want debate-level corpus signals on a topic — by_house, by_year, by_section breakdowns — without reading every contribution. Aggregates Hansard debate-level signals on a topic. Pure counts — no LLM, no editorial labels. Sweeps /search/Debates.json with p...

Parameters* required
from_datevalue
Start date (YYYY-MM-DD)
housestring
Restrict to one House. Default 'both'.one of Commons · Lords · bothdefault: both
max_debates_scannedinteger
Hard cap on debates sampled from /search/Debates.json to compute facets. Default 200 issues ≤4 upstream calls (take=50 each). Raise to 2000 (≤40 calls) for an exhaustive sweep on a heavily-debated...default: 200
to_datevalue
End date (YYYY-MM-DD)
topic*string
Phrase to find in Hansard contribution text bodies for the facet aggregation. Same semantics as parliament_search_hansard.query: tokens that appear in members' actual speeches, not bill titles or t...
parliament_find_memberUSE THIS TOOL WHEN you have a member's name and need their integer member_id. Returns all members matching the name query, each with the integer `id`, party, constituency, house, and current-sitting status. Disambiguates common-name matches (e.g. "Lord Smith" returns multiple...1 params

USE THIS TOOL WHEN you have a member's name and need their integer member_id. Returns all members matching the name query, each with the integer `id`, party, constituency, house, and current-sitting status. Disambiguates common-name matches (e.g. "Lord Smith" returns multiple...

Parameters* required
name*string
Name or partial name, e.g. 'Starmer', 'Baroness Hale'
parliament_member_debatesUSE THIS TOOL WHEN you have a member_id and want contributions where THAT member used a specific topic phrase verbatim (text-body search). CALL parliament_find_member(name) FIRST to obtain the integer member_id. This is a name-based text-body search — it matches contributions...4 params

USE THIS TOOL WHEN you have a member_id and want contributions where THAT member used a specific topic phrase verbatim (text-body search). CALL parliament_find_member(name) FIRST to obtain the integer member_id. This is a name-based text-body search — it matches contributions...

Parameters* required
limitinteger
Maximum contributions to return. Default 20.default: 20
member_id*integer
Parliament Members API integer ID. Obtain from parliament_find_member.
offsetinteger
Number of contributions to skip before this page. Default 0. Re-call with offset=offset+returned while has_more is true.default: 0
topicvalue
Optional phrase to find in THIS member's contribution text bodies. Hansard searches the words the member actually said, NOT the topic or title of the debate. Pass tokens this member would have spok...
parliament_member_interestsUSE THIS TOOL WHEN you have a member_id and need their registered financial interests (donations, directorships, land, gifts). CALL parliament_find_member(name) FIRST to obtain the integer member_id. Returns ONE PAGE of interests (default 20, caller controls via limit). For pr...5 params

USE THIS TOOL WHEN you have a member_id and need their registered financial interests (donations, directorships, land, gifts). CALL parliament_find_member(name) FIRST to obtain the integer member_id. Returns ONE PAGE of interests (default 20, caller controls via limit). For pr...

Parameters* required
categoryvalue
Filter by interest category. Common categories: 'donations' (donations and support), 'gifts_uk' (gifts/hospitality from UK), 'employment' (employment and earnings), 'land' (land and property), 'sha...
limitinteger
Max interests per call. Hard-capped at 20 by the upstream interests-api.parliament.uk (verified live 2026-05-29: Take=100 still returns 20). For prolific members, paginate via offset; total size is...default: 20
max_description_charsinteger
Per-entry cap on the free-text description field. Default 500 prevents context blow-up on members with lengthy donation or directorship narratives. Raise to 2000+ only for forensic provenance work.default: 500
member_id*integer
Parliament Members API integer ID. Get from parliament_find_member.
offsetinteger
Number of interests to skip before this page. Default 0 for the first page. To paginate prolific members (100+ interests), re-call with offset=offset+returned while the previous response had has_mo...default: 0
parliament_search_petitionsUSE THIS TOOL WHEN searching UK Parliament petitions by keyword or topic. Returns petition title, state, signature count, and dates for government response or parliamentary debate if applicable. Filter by state (open, closed, debated, etc.) to narrow to live or historical peti...4 params

USE THIS TOOL WHEN searching UK Parliament petitions by keyword or topic. Returns petition title, state, signature count, and dates for government response or parliamentary debate if applicable. Filter by state (open, closed, debated, etc.) to narrow to live or historical peti...

Parameters* required
limitinteger
Maximum petitions to return. Default 20.default: 20
offsetinteger
Number of petitions to skip before this page. Default 0. Re-call with offset=offset+returned while has_more is true.default: 0
query*string
Search term for petition titles, e.g. 'ban trophy hunting' or 'NHS funding'.
statestring
Filter by petition state.one of open · closed · alldefault: all
parliament_get_debate_divisionsUSE THIS TOOL WHEN you have a debate_ext_id and want the divisions (formal votes) held within it. Most debates contain no divisions — Business of the House sittings, statements, urgent questions, debates without a vote. A populated list typically appears around bill stages, mo...1 params

USE THIS TOOL WHEN you have a debate_ext_id and want the divisions (formal votes) held within it. Most debates contain no divisions — Business of the House sittings, statements, urgent questions, debates without a vote. A populated list typically appears around bill stages, mo...

Parameters* required
debate_ext_id*string
Debate GUID (DebateSectionExtId). Chain from parliament_search_hansard contribution.debate_ext_id, top_debates[].debate_ext_id, or parliament_policy_position_summary top_debates[].debate_ext_id.
parliament_get_debate_contributionsUSE THIS TOOL WHEN you have a debate_ext_id and want verbatim contributions, optionally filtered to one member. Canonical path for "everything a member said in this debate" regardless of vocabulary — text-search tools (parliament_member_debates, parliament_search_hansard) filt...2 params

USE THIS TOOL WHEN you have a debate_ext_id and want verbatim contributions, optionally filtered to one member. Canonical path for "everything a member said in this debate" regardless of vocabulary — text-search tools (parliament_member_debates, parliament_search_hansard) filt...

Parameters* required
debate_ext_id*string
Debate GUID (DebateSectionExtId). Chain from parliament_search_hansard top_debates[].debate_ext_id, parliament_lookup_by_column matches[].debate_ext_id, or any tool that surfaces a debate identifier.
member_idvalue
Optional integer Members API ID. When given, only that member's contributions in this debate are returned — regardless of which words they used. Resolves via parliament_find_member. When omitted, e...
parliament_lookup_by_columnUSE THIS TOOL WHEN you have an OSCOLA-style Hansard citation (column + volume + house) and need the debate. Example input: 'HL Deb 14 Oct 2025, vol 849, col 200'. AFTER calling, read the contribution at the cited column via read_resource(uri="hansard://debate/{debate_ext_id}/h...3 params

USE THIS TOOL WHEN you have an OSCOLA-style Hansard citation (column + volume + house) and need the debate. Example input: 'HL Deb 14 Oct 2025, vol 849, col 200'. AFTER calling, read the contribution at the cited column via read_resource(uri="hansard://debate/{debate_ext_id}/h...

Parameters* required
column_number*string
Hansard column number from an OSCOLA footnote, e.g. '200' for 'HL Deb 14 Oct 2025, vol 849, col 200'. String (not integer) to accommodate column suffixes like '1162W' for written answers.
housestring
Restrict to one House. Default 'both' searches across both Houses.one of Commons · Lords · bothdefault: both
volume_number*integer
Hansard volume number (the 'vol 849' part of an OSCOLA citation). Required — the endpoint only resolves citations when given the volume; sitting date is NOT a substitute (verified live 2026-05-29).
bills_search_billsUSE THIS TOOL WHEN searching UK parliamentary bills by keyword, session, house, or legislative stage. Returns a paginated page of bill summaries (title, originating and current house, current stage, whether it became an Act). AFTER calling, pass a bill_id into bills_get_bill f...6 params

USE THIS TOOL WHEN searching UK parliamentary bills by keyword, session, house, or legislative stage. Returns a paginated page of bill summaries (title, originating and current house, current stage, whether it became an Act). AFTER calling, pass a bill_id into bills_get_bill f...

Parameters* required
housevalue
Filter by originating house: the House the bill was introduced in, wherever it sits now. Omit (or 'All') for all houses.
limitinteger
Maximum bills to return in this call. Default 20 keeps responses focused; raise up to 100 for bulk exports.default: 20
offsetinteger
Number of results to skip before this page. Default 0 for the first page. Re-call with offset=offset+returned while has_more is true to paginate.default: 0
query*string
Search term for bill titles and descriptions, e.g. 'online safety' or 'financial services'.
sessionvalue
Numeric parliamentary session ID (e.g. 40 = 2024-25, 39 = 2023-24). NOT a year string like '2025'. If you only know the year, omit this and filter the results instead. Omit to search all sessions.
stagevalue
Filter by current legislative stage.
bills_get_billUSE THIS TOOL WHEN you have a bill_id (from bills_search_bills) and want the full detail. Returns sponsors, current stage, long title, summary, and Royal Assent date if enacted. Summary text is capped per max_summary_chars — check summary_truncated in the response. AFTER calli...2 params

USE THIS TOOL WHEN you have a bill_id (from bills_search_bills) and want the full detail. Returns sponsors, current stage, long title, summary, and Royal Assent date if enacted. Summary text is capped per max_summary_chars — check summary_truncated in the response. AFTER calli...

Parameters* required
bill_id*integer
Bill ID from bills_search_bills results.
max_summary_charsinteger
Maximum characters of the bill summary text to return. Default 5,000 (~1,250 tokens) covers most bills. Raise for substantive government bills (Finance Act, Levelling-up) whose summary runs longer....default: 5000
votes_search_divisionsUSE THIS TOOL WHEN searching Commons or Lords formal votes by topic, date, or member. Returns one page of division summaries (title, date, vote counts, pass/fail) plus `total`, the source's count of all matching divisions. While `has_more` is true, re-call with offset=offset+r...7 params

USE THIS TOOL WHEN searching Commons or Lords formal votes by topic, date, or member. Returns one page of division summaries (title, date, vote counts, pass/fail) plus `total`, the source's count of all matching divisions. While `has_more` is true, re-call with offset=offset+r...

Parameters* required
from_datevalue
Start date (YYYY-MM-DD).
housestring
Which house to search.one of Commons · Lordsdefault: Commons
limitinteger
Maximum divisions to return. Default 25. The Lords API honours up to 100; the Commons API returns at most 25 per call, so page by `returned`, not `limit`.default: 25
member_idvalue
Filter to divisions where this member voted. Get the member ID from parliament_find_member.
offsetinteger
Number of divisions to skip before this page. Default 0. Re-call with offset=offset+returned while has_more is true.default: 0
queryvalue
Search term for division titles, e.g. 'Rwanda' or 'Online Safety Bill'. Omit to browse recent divisions.
to_datevalue
End date (YYYY-MM-DD).
votes_get_divisionUSE THIS TOOL WHEN you have a division_id + house and want the full member-by-member voting record. Voter lists are truncated to 100 per side to fit response limits; total voter counts are always accurate regardless of truncation. Chain from votes_search_divisions or parliamen...2 params

USE THIS TOOL WHEN you have a division_id + house and want the full member-by-member voting record. Voter lists are truncated to 100 per side to fit response limits; total voter counts are always accurate regardless of truncation. Chain from votes_search_divisions or parliamen...

Parameters* required
division_id*integer
Division ID from votes_search_divisions results.
housestring
Which house this division belongs to.one of Commons · Lordsdefault: Commons
committees_search_committeesUSE THIS TOOL WHEN searching or listing UK parliamentary select committees by name, house, or active status. Returns committee summaries (name, house, active status, ID). AFTER calling, pass committee_id into committees_get_committee for current membership, or into committees_...4 params

USE THIS TOOL WHEN searching or listing UK parliamentary select committees by name, house, or active status. Returns committee summaries (name, house, active status, ID). AFTER calling, pass committee_id into committees_get_committee for current membership, or into committees_...

Parameters* required
active_onlyboolean
If true, only return currently active committees.default: true
housevalue
Filter by house.
limitinteger
Maximum committees to return. Default 100 comfortably covers all currently-active UK select committees. Raise only for historical sweeps.default: 100
queryvalue
Search term for committee names, e.g. 'defence' or 'treasury'. Searched by the upstream API before `limit` is applied. Omit to list all committees.
committees_get_committeeUSE THIS TOOL WHEN you have a committee_id and want the metadata + current membership. Fetches committee detail and member list in parallel. AFTER calling, pass committee_id into committees_search_evidence to see what evidence has been submitted to this committee on what topics.1 params

USE THIS TOOL WHEN you have a committee_id and want the metadata + current membership. Fetches committee detail and member list in parallel. AFTER calling, pass committee_id into committees_search_evidence to see what evidence has been submitted to this committee on what topics.

Parameters* required
committee_id*integer
Committee ID from committees_search_committees results.
committees_search_businessesUSE THIS TOOL WHEN identifying a committee inquiry or business before evidence retrieval. Returns official business IDs, titles, types, dates, and report/status metadata. AFTER calling, use an exact ID as committee_business_id in committees_search_evidence. Source: UK Parliame...3 params

USE THIS TOOL WHEN identifying a committee inquiry or business before evidence retrieval. Returns official business IDs, titles, types, dates, and report/status metadata. AFTER calling, use an exact ID as committee_business_id in committees_search_evidence. Source: UK Parliame...

Parameters* required
committee_id*integer
Committee ID from committees_search_committees results.
limitinteger
Maximum inquiry/business records to return (1–100).default: 50
queryvalue
Optional official inquiry/business title search term. Returns source-supplied IDs; do not infer an ID from a title.
committees_search_evidenceUSE THIS TOOL WHEN retrieving committee evidence, especially for an identified inquiry. Returns ONE PAGE of evidence (default 20) plus `total`, the source's count of matching items. evidence_type='both' lists all oral evidence first, then all written evidence, each newest-publ...8 params

USE THIS TOOL WHEN retrieving committee evidence, especially for an identified inquiry. Returns ONE PAGE of evidence (default 20) plus `total`, the source's count of matching items. evidence_type='both' lists all oral evidence first, then all written evidence, each newest-publ...

Parameters* required
committee_business_idvalue
Exact official inquiry/business ID from committees_search_businesses. Applies the source filter before pagination; do not infer this from a title.
committee_id*integer
Committee ID from committees_search_committees results.
evidence_typestring
Type of evidence to search.one of oral · written · bothdefault: both
limitinteger
Maximum evidence items to return. Default 20. For evidence_type='both' a page may hold only oral, only written, or the last oral items followed by the first written items.default: 20
max_title_charsinteger
Per-item cap on the free-text title field. Default 300 prevents context blow-up from verbose inquiry titles. Raise to 1000+ only when you need the full title text.default: 300
offsetinteger
Number of evidence items to skip before this page. Default 0. Re-call with offset=offset+returned while has_more is true. For evidence_type='both' this is a position in the combined sequence (all o...default: 0
published_fromvalue
Optional inclusive source publication-date lower bound (YYYY-MM-DD). Applied upstream before pagination.
published_tovalue
Optional inclusive source publication-date upper bound (YYYY-MM-DD). Applied upstream before pagination.
citations_parseUSE THIS TOOL WHEN you have free text (a memo, an email, a clause) and want every OSCOLA-style citation it contains extracted and classified. Identifies: neutral citations ([2024] UKSC 12), law reports ([2024] 1 WLR 100), legislation sections (s.47 Companies Act 2006), SIs (SI...2 params

USE THIS TOOL WHEN you have free text (a memo, an email, a clause) and want every OSCOLA-style citation it contains extracted and classified. Identifies: neutral citations ([2024] UKSC 12), law reports ([2024] 1 WLR 100), legislation sections (s.47 Companies Act 2006), SIs (SI...

Parameters* required
disambiguateboolean
Default False — pure-regex parsing, no model in the loop. If True, ambiguous citations (e.g. bare EWHC without a division) are sent to the connected client's own LLM, via MCP sampling, to resolve t...default: false
text*string
Free text containing OSCOLA citations to extract. Supported: neutral citations ([2024] UKSC 12), law reports ([2024] 1 WLR 100), legislation sections (s.47 Companies Act 2006), SIs (SI 2018/1234),...
citations_resolveUSE THIS TOOL BEFORE constructing an OSCOLA citation string from known fields, OR to confirm a citation points at a real document. Parses + resolves a single citation (neutral citation, SI, legislation section, retained EU law) and returns parsed fields plus resolved_url. For...1 params

USE THIS TOOL BEFORE constructing an OSCOLA citation string from known fields, OR to confirm a citation points at a real document. Parses + resolves a single citation (neutral citation, SI, legislation section, retained EU law) and returns parsed fields plus resolved_url. For...

Parameters* required
citation*string
A single OSCOLA citation to parse and resolve. E.g. '[2024] UKSC 12', 'SI 2018/1234', 's.47 Companies Act 2006'
citations_networkUSE THIS TOOL WHEN you have a judgment slug and want to map every citation it makes — cases cited, legislation referenced, SIs, retained EU law. Fetches the judgment XML from TNA and parses all OSCOLA citations within. Returns citations grouped by type, deduplicated and sorted...1 params

USE THIS TOOL WHEN you have a judgment slug and want to map every citation it makes — cases cited, legislation referenced, SIs, retained EU law. Fetches the judgment XML from TNA and parses all OSCOLA citations within. Returns citations grouped by type, deduplicated and sorted...

Parameters* required
case_uri*string
TNA judgment URI slug, e.g. 'uksc/2024/12' or 'ewca/civ/2023/450'. Use the 'uri' field from case_law_search results — not the full URL. Do not include the 'https://caselaw.nationalarchives.gov.uk/'...
citations_format_oscolaUSE THIS TOOL AFTER citations_resolve to produce the correctly formatted OSCOLA citation string. Pass the parsed fields returned by citations_resolve directly into this tool. Formats per OSCOLA 4th edition rules for each citation type. Refuses (status: upstream_validation) if...14 params

USE THIS TOOL AFTER citations_resolve to produce the correctly formatted OSCOLA citation string. Pass the parsed fields returned by citations_resolve directly into this tool. Formats per OSCOLA 4th edition rules for each citation type. Refuses (status: upstream_validation) if...

Parameters* required
citation_type*string
'type' field from citations_resolve result.one of neutral · law_report · legislation · si · eu_retained
confidence*number
'confidence' from citations_resolve. Refuses to format if 0.0 — that means TNA confirmed the document does not exist. Pass only the value citations_resolve returned; do not guess.
courtvalue
'court' from citations_resolve, e.g. 'UKSC', 'EWCA CIV', 'EWHC (KB)'.
legislation_titlevalue
'legislation_title' from citations_resolve, e.g. 'Companies Act 2006'.
numbervalue
'number' from citations_resolve (judgment number within the year).
pagevalue
'page' from citations_resolve (starting page in the law report).
rawvalue
'raw' from citations_resolve. Used as-is for EU retained law — the original text preserves the Regulation/Directive distinction.
report_seriesvalue
'report_series' from citations_resolve, e.g. 'WLR', 'AC', 'QB'.
resolved_urlvalue
'resolved_url' from citations_resolve. Must be non-null for neutral citations.
sectionvalue
'section' from citations_resolve, e.g. '47', '12', '20A'.
si_numbervalue
'si_number' from citations_resolve.
si_yearvalue
'si_year' from citations_resolve.
volumevalue
'volume' from citations_resolve (law report volume, if any).
yearvalue
'year' from citations_resolve.
hmrc_get_vat_rateUSE THIS TOOL WHEN you know the UK VAT category name for a good or service and want its VAT treatment. Exact named-category lookup, not a free-text VAT classifier or tax advice. The query must equal a category name, ignoring only case, spacing, hyphens and apostrophe style. Ex...1 params

USE THIS TOOL WHEN you know the UK VAT category name for a good or service and want its VAT treatment. Exact named-category lookup, not a free-text VAT classifier or tax advice. The query must equal a category name, ignoring only case, spacing, hyphens and apostrophe style. Ex...

Parameters* required
commodity_code*string
Commodity code or plain-English description. E.g. 'food', 'domestic fuel', 'software', 'financial services', 'new build residential'
hmrc_check_mtd_statusUSE THIS TOOL WHEN you have a 9-digit VAT Registration Number and need that business's Making Tax Digital VAT mandate status. Returns whether the business is mandated for MTD, effective date, and trading name. Connects to the HMRC sandbox by default. Set HMRC_API_BASE to 'http...1 params

USE THIS TOOL WHEN you have a 9-digit VAT Registration Number and need that business's Making Tax Digital VAT mandate status. Returns whether the business is mandated for MTD, effective date, and trading name. Connects to the HMRC sandbox by default. Set HMRC_API_BASE to 'http...

Parameters* required
vrn*string
VAT Registration Number: 9 digits, e.g. '123456789'. GB prefix accepted and stripped automatically.
hmrc_search_guidanceUSE THIS TOOL WHEN discovering HMRC GOV.UK guidance on a topic. Returns official-search titles, URLs, descriptions, and published dates; descriptions do not establish the contents of a cited page. AFTER calling, use hmrc_get_manual_page when a result is an HMRC internal-manual...2 params

USE THIS TOOL WHEN discovering HMRC GOV.UK guidance on a topic. Returns official-search titles, URLs, descriptions, and published dates; descriptions do not establish the contents of a cited page. AFTER calling, use hmrc_get_manual_page when a result is an HMRC internal-manual...

Parameters* required
limitinteger
Maximum guidance results to return (1–25). Passed to the GOV.UK search count param.default: 10
query*string
Search query for HMRC guidance, e.g. 'VAT digital services', 'R&D tax relief SME'
hmrc_get_manual_pageUSE THIS TOOL WHEN a cited HMRC internal-manual page must be read. Returns bounded source-order text, canonical URL, manual reference, source metadata, and retrieval provenance. AFTER calling, cite or analyse only returned text; if retrieval fails, do not infer the page's cont...4 params

USE THIS TOOL WHEN a cited HMRC internal-manual page must be read. Returns bounded source-order text, canonical URL, manual reference, source metadata, and retrieval provenance. AFTER calling, cite or analyse only returned text; if retrieval fails, do not infer the page's cont...

Parameters* required
manual_familyvalue
GOV.UK manual-family slug, e.g. 'employment-income-manual'. Required with reference when manual_url is omitted.
manual_urlvalue
Canonical HTTPS GOV.UK HMRC internal-manual page URL. Provide this OR manual_family plus reference.
max_charsinteger
Maximum main-text characters to return (500–20000). Truncation is explicitly reported.default: 8000
referencevalue
Manual page reference, e.g. 'EIM00500'. Required with manual_family when manual_url is omitted.
list_promptsList all available prompts. Returns JSON with prompt metadata including name, description, and optional arguments.

List all available prompts. Returns JSON with prompt metadata including name, description, and optional arguments.

No parameters. Call it with no arguments.

get_promptGet a prompt by name with optional arguments. Returns the rendered prompt as JSON with a messages array. Arguments should be provided as a dict mapping argument names to values.2 params

Get a prompt by name with optional arguments. Returns the rendered prompt as JSON with a messages array. Arguments should be provided as a dict mapping argument names to values.

Parameters* required
argumentsvalue
Optional arguments for the prompt
name*string
The name of the prompt to get
list_resourcesList all available resources and resource templates. Returns JSON with resource metadata. Static resources have a 'uri' field, while templates have a 'uri_template' field with placeholders like {name}.

List all available resources and resource templates. Returns JSON with resource metadata. Static resources have a 'uri' field, while templates have a 'uri_template' field with placeholders like {name}.

No parameters. Call it with no arguments.

read_resourceRead a registered server resource URI, not an ordinary web URL. USE WHEN you have a judgment://, legislation://, hansard://, or server:// URI returned by this server. Do not use for https:// URLs; use the source-specific tool instead (for a canonical GOV.UK HMRC internal-manua...1 params

Read a registered server resource URI, not an ordinary web URL. USE WHEN you have a judgment://, legislation://, hansard://, or server:// URI returned by this server. Do not use for https:// URLs; use the source-specific tool instead (for a canonical GOV.UK HMRC internal-manua...

Parameters* required
uri*string
A server resource URI such as judgment://..., legislation://..., hansard://..., or server://about

Sponsors

Readme

Details

Repository
github.com/paulieb89/uk-legal-mcp
Website
bouch.dev/products/uk-legal-mcp
Package
uk-legal-mcp
Transport
STDIO, HTTP
Registry
MCP registry, active
Resources
1
Prompts
4
Tools verified
Nov 6, 2026

More from paulieb89