# UK Due Diligence (remote · uk-due-diligence-mcp.fly.dev)

UK due diligence — Companies House, Charity Commission, Land Registry, Gazette, HMRC VAT

- Trust score: 68/100 (medium)
- Change this week: +3
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- remote · `uk-due-diligence-mcp.fly.dev`: 68/100 (this document), [markdown](https://verifymcp.io/servers/paulieb89-uk-due-diligence-mcp/uk-due-diligence-mcp.md), [page](https://verifymcp.io/servers/paulieb89-uk-due-diligence-mcp/uk-due-diligence-mcp)
- pypi · `uk-due-diligence-mcp`: 24/100, [markdown](https://verifymcp.io/servers/paulieb89-uk-due-diligence-mcp/uk-due-diligence-mcp-2.md), [page](https://verifymcp.io/servers/paulieb89-uk-due-diligence-mcp/uk-due-diligence-mcp-2)

## Channel facts

- Endpoint: `https://uk-due-diligence-mcp.fly.dev/mcp`
- Transports: `streamable-http`
- Auth: `none`
- Version: `1.0.3`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-03.

- **Endpoint Security**: 57/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation not fully verified: no authorisation is required to call this server, and 2 tool(s) never declared a destructiveHint. The MCP spec treats an absent hint as destructive by default, so we cannot call this surface safe.
  - HTTPS is enforced; there's no plaintext access path.
  - HSTS check failed: the Strict-Transport-Security header is absent.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 80/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 2372 tokens (~139/item across 17 items; 17 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add --transport http paulieb89-uk-due-diligence-mcp https://uk-due-diligence-mcp.fly.dev/mcp
```

### Codex

```toml
[mcp_servers.paulieb89-uk-due-diligence-mcp]
url = "https://uk-due-diligence-mcp.fly.dev/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "paulieb89-uk-due-diligence-mcp": {
      "type": "remote",
      "url": "https://uk-due-diligence-mcp.fly.dev/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add paulieb89-uk-due-diligence-mcp --url https://uk-due-diligence-mcp.fly.dev/mcp --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  paulieb89-uk-due-diligence-mcp:
    url: "https://uk-due-diligence-mcp.fly.dev/mcp"
```

### Other

```json
{
  "mcpServers": {
    "paulieb89-uk-due-diligence-mcp": {
      "type": "http",
      "url": "https://uk-due-diligence-mcp.fly.dev/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-03 (score 68, +1)

No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-08-01 (score 67, +1)

No change was recorded against any check on this day. Stability & Change Management went from 17 to 20. That category is still filling its 30-day observation window: 5 days of observed history at the previous scan, 6 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-31 (score 66, −1)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 67, +1)

No change was recorded against any check on this day. Stability & Change Management went from 10 to 13. That category is still filling its 30-day observation window: 3 days of observed history at the previous scan, 4 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-29 (score 66, 0)

- [security] The server rewrote its instructions, which are the text every model session reads
- [security] Tool “vat_validate” rewrote its description, which is the text the model reads
- [cosmetic] “gazette_insolvency” added an optional parameter “query”
- [cosmetic] “disqualified_search” added an optional parameter “name”
- [cosmetic] “gazette_insolvency” added an optional parameter “name”
- [cosmetic] “vat_validate” reworded the description of “vat_number”
- [cosmetic] “disqualified_search” reworded the description of “query”
- [cosmetic] “gazette_insolvency” reworded the description of “entity_name”
- [cosmetic] “gazette_insolvency” made “entity_name” optional
- [cosmetic] “disqualified_search” made “query” optional

### 2026-07-28 (score 66, +1)

No change was recorded against any check on this day. Stability & Change Management went from 3 to 7. That category is still filling its 30-day observation window: 1 days of observed history at the previous scan, 2 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-27 (score 65, 0)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-26 (score 65)

First indexed and scored.

## MCP tools (17)

### `company_search` (~181 tokens)

Search Companies House

Search the Companies House register by company name or keyword.

Returns a paginated list of matching companies with name, number,
status, SIC codes, incorporation date, and registered address.
Use company_profile for the full record once you have the company
number. Re-call with start_index=start_index+items_per_page to
fetch the next page.

Input parameters:

- `company_status`: Filter by company status (e.g. 'active', 'dissolved'). Omit to search all.
- `company_type`: Filter by company type (e.g. 'ltd', 'llp'). Omit to search all.
- `items_per_page` (integer): Number of results to return (max 100). Default 20.
- `query` (string, required): Company name or keyword to search for
- `start_index` (integer): Pagination offset. Default 0.

Output parameters:

- `has_more` (boolean): True if more results exist beyond this page. Re-call with start_index=start_index+items_per_page to fetch the next page.
- `items` (array): Matching companies. Use the `company_number` field to call company_profile, company_officers, or company_psc for full detail.
- `items_per_page` (integer): Page size requested from the API for this call.
- `query` (string): The query string that was searched.
- `returned` (integer): Number of items actually returned on this page.
- `start_index` (integer): Number of results skipped before this page (upstream start_index).
- `total_results` (integer): Total matching companies in Companies House (server-side).

### `company_profile` (~87 tokens)

Get Company Profile

Fetch the full Companies House profile for a company number.

Returns status, registered address, SIC codes, filing compliance
(overdue accounts and confirmation statement flags), and whether
the company has outstanding charges. Use company_search first to
find the company number.

Input parameters:

- `company_number` (string, required): Companies House company number (8 digits, e.g. '03782379'). Returned by company_search.

Output parameters:

- `accounts` (object): Accounts filing status and due dates.
- `company_name`: Registered company name.
- `company_number` (string): Companies House company number.
- `company_status`: Current status (active, dissolved, in liquidation, etc.).
- `company_type`: Companies House company type code.
- `confirmation_statement` (object): Confirmation statement filing status and next due date.
- `date_of_creation`: Incorporation date (ISO YYYY-MM-DD).
- `has_charges` (boolean): True if the company has outstanding registered charges (secured debt), derived from the /charges endpoint. A due diligence signal.
- `registered_office_address` (object): Registered office address as returned by Companies House.
- `sic_codes` (array): Standard Industrial Classification codes.

### `company_officers` (~135 tokens)

Get Company Officers

Fetch active officers for a Companies House company number.

Returns directors, secretaries, and other active officers with
appointment dates, nationality, and country of residence.
Resigned officers are excluded. Pagination is handled internally —
do NOT pass items_per_page or start_index; this tool takes only
company_number.

Input parameters:

- `company_number` (string, required): Companies House company number (8 digits, e.g. '03782379'). Returned by company_search.
- `items_per_page`: Ignored — pagination is handled internally. Only accepted to avoid call failures.
- `start_index`: Ignored — all officers are returned in one call.

Output parameters:

- `company_number` (string): Companies House company number.
- `high_appointment_count_flag`: Number of active officers with 10+ total appointments, or null if appointment counts were not fetched. Non-zero values are a nominee/phoenix director risk signal.
- `include_resigned` (boolean): Whether resigned officers were included in this result.
- `officers` (array): Officer records.
- `total` (integer): Total officers returned (filtered by include_resigned).

### `company_psc` (~99 tokens)

Get Persons with Significant Control

Fetch Persons with Significant Control (beneficial ownership) for a company.

Returns PSC entries with natures of control, nationality, and
country of residence. Flags overseas corporate PSC entries as a
beneficial ownership risk signal. Returns an explanatory note for
widely-held PLCs with no registrable PSC.

Input parameters:

- `company_number` (string, required): Companies House company number (8 digits, e.g. '03782379'). Returned by company_search.

Output parameters:

- `company_number` (string): Companies House company number.
- `note`: Explanatory note when total=0. Typical for widely-held listed PLCs where no single person or entity holds 25%+ of shares or voting rights.
- `overseas_corporate_psc_flag` (integer): Number of corporate PSCs registered outside the UK. Non-zero values indicate an offshore beneficial ownership chain.
- `psc` (array): Persons with Significant Control records.
- `total` (integer): Total PSC entries returned for this company.

### `charity_search` (~138 tokens)

Search Charity Commission Register

Search the Charity Commission register of England and Wales by name or keyword.

Returns matching charities with registration number, status, and
registration date. Use charity_profile for full details once you
have the charity number. The upstream `searchCharityName` endpoint
returns the full list in one shot — pagination is applied
client-side via offset/limit.

Input parameters:

- `limit` (integer): Max items to return in this page. Default 20; raise to 100 for bulk views.
- `offset` (integer): Number of items to skip before this page. Default 0.
- `query` (string, required): Charity name or keyword to search for

Output parameters:

- `charities` (array): Matching charity records.
- `has_more` (boolean): True if more items may exist beyond this page. Re-call with offset=offset+returned to continue.
- `limit` (integer): Max items requested for this page.
- `offset` (integer): Number of items skipped before this page (client-side).
- `query` (string): Search term applied.
- `returned` (integer): Items actually returned on this page.
- `total` (integer): Total matches returned by upstream.

### `charity_profile` (~79 tokens)

Get Charity Profile

Fetch the full Charity Commission profile for a charity number.

Returns trustees, latest income/expenditure, insolvency flags,
governing document type, classifications, and countries of operation.
Use charity_search first to find the charity number.

Input parameters:

- `charity_number` (string, required): Charity Commission registration number (e.g. '1234567'). Returned by charity_search.

Output parameters:

- `address`: Registered address of the charity (joined address lines).
- `charity_co_reg_number`: Companies House number for charities also registered as companies (Charitable Incorporated Organisations, etc.).
- `charity_name`: Registered charity name.
- `charity_number` (string): Charity registration number.
- `charity_type`: Charity type.
- `countries_of_operation` (array): Countries the charity operates in (capped at 10 upstream).
- `date_of_registration`: Date of first registration.
- `in_administration` (boolean): True if the charity is in administration.
- `insolvent` (boolean): True if the charity is flagged as insolvent.
- `latest_expenditure`: Latest filed annual expenditure in GBP.
- `latest_income`: Latest filed annual income in GBP.
- `reg_status`: Registration status code ('R', 'RM').
- `reg_status_label`: Human-readable registration status.
- `trustee_names` (array): Trustees on record. Truncated to 30 entries.
- `trustee_names_total` (integer): Total trustees upstream before truncation.
- `trustee_names_truncated` (boolean): True if the trustee list was truncated.
- `who_what_where` (array): Who/What/Where classification entries. The list may be truncated truncated to 50 entries.
- `who_what_where_total` (integer): Total classification entries upstream before truncation.
- `who_what_where_truncated` (boolean): True if the classification list was truncated.

### `disqualified_search` (~171 tokens)

Search Disqualified Directors

Check whether a named individual is banned from acting as a UK company director.

Use this tool when asked to check disqualified, banned, or barred directors.
Query must be an individual's name (e.g. "Richard Howson") — NOT a company
name, which always returns zero results.

Returns names, dates of birth, disqualification period snippets, and
officer IDs that can be used with disqualified_profile for full details.

Input parameters:

- `items_per_page` (integer): Results per page (max 100). Default 20.
- `name`: Alias for query — the person's name.
- `query`: Person's name to search for, e.g. query='Richard Howson'. NOT a company name.
- `start_index` (integer): Pagination offset (0-based). Default 0.

Output parameters:

- `has_more` (boolean): True if more items may exist beyond this page. Re-call with start_index=start_index+items_per_page to continue.
- `items` (array): Matching disqualified officer records.
- `items_per_page` (integer): Page size requested.
- `query` (string): Search query applied.
- `returned` (integer): Items actually returned on this page.
- `start_index` (integer): Pagination offset for this page.
- `total_results` (integer): Total matching records upstream at Companies House.

### `disqualified_profile` (~74 tokens)

Get Disqualified Director Profile

Fetch the full disqualification record for a director by officer ID.

Returns all disqualification orders: reason, Act/section cited,
disqualification period, and associated company names. Use
disqualified_search first to find the officer ID.

Input parameters:

- `officer_id` (string, required): Companies House officer ID. Returned by disqualified_search.

Output parameters:

- `date_of_birth`: Date of birth on record.
- `disqualifications` (array): All disqualification orders attached to this officer.
- `forename`: Given name, if split upstream.
- `name`: Officer name.
- `nationality`: Declared nationality.
- `officer_id` (string): Companies House officer ID looked up.
- `officer_kind` (string): Which CH endpoint returned the record: 'natural' (individual) or 'corporate' (legal entity).
- `surname`: Family name, if split upstream.

### `land_title_search` (~118 tokens)

Search Price Paid Transactions by Postcode

Search HM Land Registry Price Paid Index by postcode or address.

Returns up to 10 recent sale transactions for the postcode: price,
date, address, property type, and tenure (Freehold/Leasehold).
Covers England and Wales only. Postcode gives the most reliable
results — a full address is also accepted and the postcode is
extracted automatically.

Input parameters:

- `address_or_postcode` (string, required): UK property address or postcode. Postcode is most reliable: e.g. 'NG1 1AB'. Full address also accepted.

Output parameters:

- `postcode` (string): Normalised UK postcode extracted from the input.
- `total` (integer): Number of Price Paid transactions returned. Capped at 10 by the upstream SPARQL query.
- `transactions` (array): Recent Price Paid transactions for the postcode, sorted newest first.

### `gazette_notice` (~86 tokens)

Get Gazette Notice Full Text

Fetch the full legal wording of a Gazette notice by numeric notice ID.

Returns the complete JSON-LD linked-data record for the notice: parties,
legal basis, court, and full text. Use gazette_insolvency first to find
notice_numeric_id values.

Input parameters:

- `notice_id` (string, required): Numeric Gazette notice ID. Returned as notice_numeric_id by gazette_insolvency.

### `gazette_insolvency` (~297 tokens)

Search Gazette Corporate Insolvency Notices

Search The Gazette's insolvency notice index by entity name.

Searches the Gazette's insolvency endpoint which covers corporate
notice codes: winding-up orders (2443), administration orders (2448),
liquidator appointments (2452), striking-off notices (2460), and more.
Results are sorted by severity — winding-up orders and administration
orders appear first.

Each result includes a notice_numeric_id. Read the full legal wording
via the notice://{notice_numeric_id} resource.

The Gazette is the official UK public record. A notice here means
the event has been formally published and is legally effective.

Input parameters:

- `end_date`: Filter notices up to this date (YYYY-MM-DD)
- `entity_name`: Deprecated alias for name.
- `max_notices` (integer): Cap on notices returned, applied after severity/date sort. Default 20. The Gazette insolvency feed returns up to 100 results per search — raise to 100 to see the full set.
- `name`: Company or individual name to search for in Gazette insolvency notices
- `notice_type`: Filter by notice code (e.g. '2441' winding-up petition, '2443' winding-up order, '2448' administration order, '2460' striking-off). Omit to search all.
- `query`: Alias for name.
- `start_date`: Filter notices from this date (YYYY-MM-DD)

Output parameters:

- `end_date`: Upper bound of the date range filter, if any.
- `entity_name` (string): Entity name that was searched.
- `max_notices_cap` (integer): The max_notices cap applied. Upstream may have more matching notices.
- `notice_type_filter`: Notice code filter applied, or null if all codes searched.
- `notices` (array): Matching notices, sorted by severity (desc) then date (desc).
- `start_date`: Lower bound of the date range filter, if any.
- `total_notices` (integer): Total notices returned after deduplication, sorting, and cap.

### `vat_validate` (~150 tokens)

Validate UK VAT Number (HMRC)

Validate a UK (GB) VAT number against the HMRC register. UK numbers only.

Returns the trading name and address as registered with HMRC for VAT
purposes. The VAT-registered trading address often differs from the
Companies House registered address — that discrepancy is a due
diligence signal worth noting.

Non-UK (EU) VAT numbers cannot be validated here — use the EU VIES
service for other member states.

Input parameters:

- `vat_number` (string, required): UK (GB) VAT registration number — this tool validates UK numbers only. Accepts: 'GB123456789', '123456789', 'GB 123 456 789'. GB prefix and spaces normalised automatically.

Output parameters:

- `consultation_number`: HMRC consultation reference number for this lookup.
- `registered_address`: VAT-registered trading address. May differ from the Companies House registered office address.
- `trading_name`: Trading name registered with HMRC for VAT. Compare with the Companies House name — discrepancies are a due diligence signal.
- `valid` (boolean): True if HMRC confirmed the VAT number is currently registered. False means HMRC returned 404 (not registered / deregistered).
- `vat_number` (string): Canonical VAT number in 'GB<9 digits>' format.

### `sanctions_screen` (~262 tokens)

Screen a Name Against Sanctions Lists

Screen a name against the UK (OFSI), US (OFAC), EU and UN consolidated sanctions lists.

Returns every list entry whose primary name or alias matches, with the
regime, source reference and listing date. Use it to check whether a
counterparty — or its officers / persons with significant control —
appears on a sanctions list.

MATCHING is deterministic: normalised exact + alias match (case-, accent-
and punctuation-insensitive). A company/entity legal name matches reliably;
PERSON names with transliteration variants may not (e.g. 'Mohammed' vs
'Muhamad'). An empty result is therefore NOT a guarantee of clearance, and a
hit on a common name may be a false positive to disambiguate. This is a
screening aid, not a compliance determination.

\`lists_screened` reports which of OFSI/OFAC/EU/UN were actually loaded — if
any is missing the result is partial. `as_at` is when the lists were last
refreshed on this server.

Input parameters:

- `entity_type`: Optional filter: 'person' or 'entity'. Omit to screen both.
- `name` (string, required): Person or company/entity name to screen against the consolidated sanctions lists.

Output parameters:

- `as_at`: When this server last refreshed the loaded lists (ISO timestamp). Provenance for the screen — the lists update on designation.
- `entity_type_filter`: entity_type filter applied to the screen ('person'/'entity'), or null.
- `hits` (array): Matching list entries. An empty list means no exact/alias match on the screened lists — NOT a guarantee of clearance (see the tool description on matching limits).
- `lists_screened` (array): Which consolidated lists were loaded and actually screened for this call. A list absent here failed to load and was NOT screened — treat the result as partial if any of OFSI/OFAC/EU/UN is missing.
- `match_count` (integer): Number of list entries that matched the query.
- `normalized_query` (string): The normalised form used for matching (upper-cased, accent- and punctuation-stripped, whitespace-collapsed).
- `query` (string): The name that was screened.

### `search` (~82 tokens)

Search UK Due Diligence Registers

Search across all UK due diligence registers simultaneously.

Searches Companies House, Charity Commission, disqualified directors,
and Gazette insolvency notices in parallel. Returns a list of result
IDs — use fetch with each ID to retrieve the full record.

Input parameters:

- `query` (string, required): Company name, charity name, director name, or keyword to search for across all UK due diligence registers

### `fetch` (~113 tokens)

Fetch Full Record from UK Due Diligence Register

Fetch the full record for an ID returned by search.

Routes by prefix to the appropriate register:
\- company:{number} → Companies House full profile
\- charity:{number} → Charity Commission full profile
\- disqualification:{officer_id} → Disqualified director full record
\- notice:{notice_id} → Gazette notice full legal text

Input parameters:

- `id` (string, required): Prefixed record ID returned by search. Format: company:{number}, charity:{number}, disqualification:{officer_id}, or notice:{notice_id}

### `list_prompts` (~28 tokens)

List all available prompts.

Returns JSON with prompt metadata including name, description,
and optional arguments.

Output parameters:

- `result` (string)

### `get_prompt` (~66 tokens)

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.

Input parameters:

- `arguments`: Optional arguments for the prompt
- `name` (string, required): The name of the prompt to get

Output parameters:

- `result` (string)

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/paulieb89-uk-due-diligence-mcp/uk-due-diligence-mcp#diagnostics

## Score history

- 2026-08-03: 68
- 2026-08-02: 67
- 2026-08-01: 67
- 2026-07-31: 66
- 2026-07-30: 67
- 2026-07-29: 66
- 2026-07-28: 66
- 2026-07-27: 65
- 2026-07-26: 65

## Links

- Remote endpoint: https://uk-due-diligence-mcp.fly.dev/mcp
- Repository: https://github.com/paulieb89/uk-due-diligence-mcp
- Website: https://bouch.dev/
- Changelog RSS feed: https://verifymcp.io/servers/paulieb89-uk-due-diligence-mcp/uk-due-diligence-mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/paulieb89-uk-due-diligence-mcp/uk-due-diligence-mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/paulieb89-uk-due-diligence-mcp/uk-due-diligence-mcp
