Get Persons with Significant Control
company_pscIdentify beneficial ownership risks by fetching Persons with Significant Control for a UK company. Returns PSC entries with natures of control, nationality, and country of residence, flagging overseas corporate PSC as a risk signal.
Instructions
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 Schema
| Name | Required | Description | Default |
|---|---|---|---|
| company_number | Yes | Companies House company number (8 digits, e.g. '03782379'). Returned by company_search. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| company_number | Yes | Companies House company number. | |
| total | Yes | Total PSC entries returned for this company. | |
| overseas_corporate_psc_flag | No | Number of corporate PSCs registered outside the UK. Non-zero values indicate an offshore beneficial ownership chain. | |
| psc | No | Persons with Significant Control records. | |
| note | No | Explanatory note when total=0. Typical for widely-held listed PLCs where no single person or entity holds 25%+ of shares or voting rights. |
Implementation Reference
- companies_house.py:349-359 (handler)The company_psc tool handler function. It is a FastMCP tool decorated with @mcp.tool(name='company_psc') that accepts a company number and returns a CompanyPSCResult. It normalizes the company number and delegates to _fetch_company_psc.
async def company_psc( company_number: Annotated[str, Field(description="Companies House company number (8 digits, e.g. '03782379'). Returned by company_search.", min_length=1, max_length=10)], ) -> CompanyPSCResult: """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. """ return await _fetch_company_psc(_normalise_company_number(company_number)) - companies_house.py:155-203 (helper)The _fetch_company_psc helper function that calls the Companies House API endpoint /company/{number}/persons-with-significant-control, parses PSC entries, computes the overseas corporate PSC flag, and returns a CompanyPSCResult.
async def _fetch_company_psc(company_number: str) -> CompanyPSCResult: async with companies_house_client() as client: resp = await _request_with_retry( client, "GET", f"/company/{company_number}/persons-with-significant-control", ) data = resp.json() raw_items = data.get("items", []) or [] total = int(data.get("total_results", len(raw_items)) or 0) psc_entries: list[CompanyPSCEntry] = [] overseas_flag = 0 for raw in raw_items: natures = _truncate_natures(list(raw.get("natures_of_control") or []), 300) entry = CompanyPSCEntry( kind=raw.get("kind"), name=raw.get("name"), notified_on=raw.get("notified_on"), ceased_on=raw.get("ceased_on"), nationality=raw.get("nationality"), country_of_residence=raw.get("country_of_residence"), natures_of_control=natures, identification=raw.get("identification") or {}, address=raw.get("address") or {}, ) psc_entries.append(entry) if entry.kind in ( "corporate-entity-person-with-significant-control", "legal-person-person-with-significant-control", ): place = (entry.identification.get("place_registered") or "").upper() if place not in UK_JURISDICTIONS: overseas_flag += 1 note = None if total == 0: note = ( "No registrable PSC. Typical for widely-held listed PLCs where " "no single person or entity holds 25%+ of shares or voting rights." ) return CompanyPSCResult( company_number=company_number, total=total, overseas_corporate_psc_flag=overseas_flag, psc=psc_entries, note=note, ) - models.py:241-286 (schema)CompanyPSCEntry model - a single Person with Significant Control record (kind, name, notified_on, ceased_on, nationality, country_of_residence, natures_of_control, identification, address).
class CompanyPSCEntry(BaseModel): """A single Person with Significant Control record.""" model_config = BASE_CFG kind: str | None = Field( None, description=( "Upstream 'kind' (e.g. 'individual-person-with-significant-control', " "'corporate-entity-person-with-significant-control')." ), ) name: str | None = Field(None, description="PSC name (individual or entity).") notified_on: str | None = Field( None, description="Date notified as a PSC (ISO YYYY-MM-DD)." ) ceased_on: str | None = Field( None, description="Date PSC status ceased, if applicable.", ) nationality: str | None = Field( None, description="Declared nationality for individual PSCs." ) country_of_residence: str | None = Field( None, description="Declared country of residence for individual PSCs.", ) natures_of_control: list[str] = Field( default_factory=list, description=( "List of 'nature of control' descriptors (e.g. " "'ownership-of-shares-75-to-100-percent'). Individual entries may " "be truncated to 300 characters each." ), ) identification: dict[str, Any] = Field( default_factory=dict, description=( "Identification block for corporate PSCs: place_registered, " "registration_number, country_registered, legal_authority, etc." ), ) address: dict[str, Any] = Field( default_factory=dict, description="PSC correspondence address.", ) - models.py:289-315 (schema)CompanyPSCResult model - the return type for company_psc, containing company_number, total, overseas_corporate_psc_flag, psc list, and an optional note.
class CompanyPSCResult(BaseModel): """List of Persons with Significant Control for a company.""" model_config = BASE_CFG company_number: str = Field(..., description="Companies House company number.") total: int = Field( ..., description="Total PSC entries returned for this company." ) overseas_corporate_psc_flag: int = Field( 0, description=( "Number of corporate PSCs registered outside the UK. Non-zero " "values indicate an offshore beneficial ownership chain." ), ) psc: list[CompanyPSCEntry] = Field( default_factory=list, description="Persons with Significant Control records.", ) note: str | None = Field( None, description=( "Explanatory note when total=0. Typical for widely-held listed PLCs " "where no single person or entity holds 25%+ of shares or voting rights." ), ) - companies_house.py:336-359 (registration)Registration of the company_psc tool via @mcp.tool(name='company_psc', ...) decorator within the register_tools(mcp) function. Registration happens at runtime in server.py line 158: companies_house.register_tools(mcp).
# ------------------------------------------------------------------ # # 4. company_psc # ------------------------------------------------------------------ # @mcp.tool( name="company_psc", annotations={ "title": "Get Persons with Significant Control", "readOnlyHint": True, "destructiveHint": False, "idempotentHint": True, "openWorldHint": True, }, ) async def company_psc( company_number: Annotated[str, Field(description="Companies House company number (8 digits, e.g. '03782379'). Returned by company_search.", min_length=1, max_length=10)], ) -> CompanyPSCResult: """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. """ return await _fetch_company_psc(_normalise_company_number(company_number))