Metadata-Version: 2.4
Name: bartram-companies-house
Version: 0.3.3
Summary: UK regulatory data via MCP — Companies House (12 tools), FCA Financial Services Register (19 tools), and Charity Commission (31 tools) with cleaning, normalisation, and deduplication.
Project-URL: Homepage, https://github.com/RobertAlsop/bartram_foundry
Project-URL: Repository, https://github.com/RobertAlsop/bartram_foundry
Author: Bartram Foundry
License-Expression: MIT
License-File: LICENSE
Keywords: agent,charity,charity-commission,companies-house,company-data,fca,financial-regulation,mcp,uk
Classifier: Development Status :: 4 - Beta
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Requires-Dist: mcp>=1.0.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: rapidfuzz>=3.0.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.8.0; extra == 'dev'
Description-Content-Type: text/markdown

# UK Companies House MCP Server

Clean, structured UK company data for AI agents — via the [Model Context Protocol](https://modelcontextprotocol.io/).

<!-- mcp-name: io.github.RobertAlsop/companies-house -->
<!-- mcp-name: io.github.RobertAlsop/fca-register -->
<!-- mcp-name: io.github.RobertAlsop/charity-commission -->

## What this does

This MCP server gives agents access to 12 UK Companies House endpoints — company search, profiles, officers, beneficial ownership, filings, charges, insolvency, officer search, officer appointments, disqualification checks, advanced search, and registered addresses — with data cleaning that the raw API doesn't provide.

Companies House data has known quality issues: officer names appear in multiple formats creating ~614K duplicate records, corporate entities get filed as natural persons in PSC (beneficial ownership) data, and addresses arrive in inconsistent formats. This server fixes those problems before the data reaches your agent.

**What the cleaning layer does:**

- **Officer deduplication** — fuzzy name matching merges records like "SMITH, John David" and "John Smith" when they share the same role and company.
- **PSC entity classification** — flags corporate entities incorrectly filed as natural persons, using identification fields and name pattern detection.
- **Address normalisation** — consistent formatting, postcode standardisation, single-line formatted output across all endpoints.
- **SIC code descriptions** — adds human-readable industry descriptions alongside raw SIC codes.
- **Nature of control interpretation** — converts coded PSC control types into plain English descriptions.
- **Charge status interpretation** — translates charge status codes (outstanding, fully-satisfied, part-satisfied, satisfied).
- **Insolvency case type interpretation** — converts case type codes (CVL, compulsory-liquidation, etc.) to descriptions.
- **Company number normalisation** — agents can send `445790` and the server correctly zero-pads it to `00445790`.
- **Full pagination** — officers, PSCs, filings, charges, and appointments are fetched across all pages automatically.
- **Data quality annotations** — every cleaned record carries `_cleaning` metadata so agents can see what was changed and why.

## Quick start

```bash
# Install
pip install bartram-companies-house

# Set your API key (required)
export COMPANIES_HOUSE_API_KEY="your-key-here"

# Run the MCP server
bartram-companies-house
```

Or with [uvx](https://docs.astral.sh/uv/):

```bash
uvx bartram-companies-house
```

Register for a free API key at [Companies House Developer Hub](https://developer.company-information.service.gov.uk/).

### Configure with Claude Desktop

Add to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "companies-house": {
      "command": "uvx",
      "args": ["bartram-companies-house"],
      "env": {
        "COMPANIES_HOUSE_API_KEY": "your-key-here"
      }
    }
  }
}
```

## Tools

| Tool | Description |
|------|-------------|
| `uk_companies_house_search` | Search for UK companies by name or number |
| `uk_companies_house_profile` | Get company details — address, status, SIC codes with descriptions, key dates |
| `uk_companies_house_officers` | Get officers with name deduplication and entity classification |
| `uk_companies_house_psc` | Get beneficial owners with entity classification and nature of control interpretation |
| `uk_companies_house_filings` | Get filing history with readable descriptions, optional category filter |
| `uk_companies_house_charges` | Get charges (mortgages/security interests) with status interpretation |
| `uk_companies_house_insolvency` | Get insolvency cases with case type interpretation and practitioner details |
| `uk_companies_house_officer_search` | Search for officers by name across all companies |
| `uk_companies_house_officer_appointments` | Get all appointments for an officer across companies |
| `uk_companies_house_disqualified_officer` | Check if an officer is disqualified |
| `uk_companies_house_advanced_search` | Search companies with filters (status, SIC code, location, dates) |
| `uk_companies_house_registered_address` | Get the registered office address |

See [SCHEMA.md](SCHEMA.md) for full parameter and response documentation with examples.

## Example

Ask your agent: *"Who are the directors of Tesco?"*

The agent calls `uk_companies_house_search` with `query: "Tesco"`, gets the company number, then calls `uk_companies_house_officers` with that number. The response includes deduplicated officer records with cleaning metadata:

```json
{
  "data": {
    "items": [
      {
        "name": "MURPHY, Ken",
        "officer_role": "director",
        "appointed_on": "2020-10-01",
        "nationality": "Irish",
        "_cleaning": {
          "deduplicated": true,
          "duplicate_count": 2,
          "original_names": ["MURPHY, Kenneth", "MURPHY, Ken"],
          "note": "Merged 2 records with similar names. Showing most recently appointed."
        }
      }
    ],
    "_cleaning": {
      "original_count": 45,
      "deduplicated_count": 38,
      "duplicates_removed": 7,
      "active_count": 12,
      "resigned_count": 26
    }
  },
  "metadata": {
    "source": "Companies House Public Data API",
    "licence": "Open Government Licence v3",
    "endpoint": "/company/00445790/officers",
    "attribution": "Contains public sector information licensed under the Open Government Licence v3.0. Source: Companies House."
  }
}
```

Every response includes a `metadata` envelope with source attribution, licence information, and retrieval timestamp.

## Data source

All data comes from the [Companies House API](https://developer.company-information.service.gov.uk/) and is published under the [Open Government Licence v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/). Crown copyright.

## Caching

Responses are cached locally in SQLite to reduce API calls and improve latency:

| Endpoint | TTL |
|----------|-----|
| Company search | 5 minutes |
| Company profile | 1 hour |
| Officers | 30 minutes |
| PSC | 30 minutes |
| Filing history | 30 minutes |
| Charges | 30 minutes |
| Insolvency | 30 minutes |
| Officer search | 5 minutes |
| Officer appointments | 30 minutes |
| Disqualified officer | 1 hour |
| Advanced search | 5 minutes |
| Registered address | 1 hour |

Cache is stored in `~/.bartram/cache.db` by default. Set `BARTRAM_DATA_DIR` to change the location.

## Development

```bash
git clone https://github.com/RobertAlsop/bartram_foundry.git
cd bartram_foundry
uv sync --all-extras
uv run pytest
uv run ruff check .
```

## Licence

MIT

---

Built by [Bartram Foundry](https://github.com/RobertAlsop/bartram_foundry) — production-grade MCP tools for UK public data.
