Companies-House-MCP-Server
MCP server exposing the full UK Companies House Public Data API, enabling natural language queries for company profiles, search, officers, filing history, charges, insolvency, and persons with significant control, as well as downloading and reading PDF documents.
README
companies-house-mcp
MCP server exposing the full UK Companies House Public Data API (~34 tools covering company profiles, search, officers, filing history, charges, insolvency, and persons with significant control).
Setup
python3 -m venv .venv
source .venv/bin/activate # .venv\Scripts\activate on Windows
pip install "mcp>=1.27,<2" httpx pymupdf
Get a free API key at https://developer.company-information.service.gov.uk/signin (register an application in the Developer Hub, then copy the API key).
Export it as an environment variable — never hardcode it in the script:
export COMPANIES_HOUSE_API_KEY="your-key-here"
Test it standalone
python test_client.py
Lists all tools, then calls get_company_profile and search_companies
against Wanderist Ltd (company number 15246704) as a live example.
Tool groups
- Profile:
get_company_profile,get_registered_office_address - Search:
search_all,search_companies,search_companies_alphabetically,search_dissolved_companies,advanced_company_search,search_officers,search_disqualified_officers - Officers:
get_company_officers,get_officer_appointment,get_officer_appointments,get_natural_officer_disqualifications,get_corporate_officer_disqualifications - Filing history & documents:
get_filing_history,get_filing_history_item,get_document_metadata,download_document,read_document_pages - Charges/insolvency/misc:
get_charges,get_charge,get_insolvency,get_exemptions,get_registers,get_uk_establishments - Persons with significant control (PSC):
list_psc,list_psc_statements,get_psc_individual,get_psc_corporate_entity,get_psc_legal_person, and beneficial-owner / super-secure / statement / notification variants
Downloading a filing document (e.g. a set of accounts)
Companies House splits this across two APIs: the main Public Data API gives you filing metadata, and a separate Document API serves the actual file bytes. The flow:
get_filing_history(company_number, category="accounts")— list filings, note thetransaction_idof the one you want.get_filing_history_item(company_number, transaction_id)— get the full filing record. Itslinks.document_metadatafield is a URL; the last path segment is thedocument_id.get_document_metadata(document_id)— (optional) check available formats and file size before downloading.download_document(document_id, format="pdf")— downloads the file to./downloads/{document_id}.pdf(or a path you specify) and returns the local path, content type, and size.
Supported format values: "pdf", "xhtml", "json" (structured iXBRL data,
where available — not all filings have it).
Letting the AI read a document directly (not just download it)
Use read_document_pages(document_id) instead of download_document when you
want the model itself to see the document's contents in this conversation —
e.g. reading figures out of a set of accounts.
It renders each PDF page to a PNG image and returns those as image content
blocks, rather than a raw PDF blob. This is deliberate: MCP clients (including
Claude Desktop / claude.ai) reliably display image content to the model, but
several currently reject raw non-image binary blobs (application/pdf
EmbeddedResources) even though the protocol technically supports them. Images
work everywhere; PDF blobs don't, yet.
Pages are capped at max_pages per call (default 10) to avoid overwhelming
context on long filings — check get_document_metadata first for the total
page count, and pass a higher start_page to continue reading further pages.
Requires pymupdf (included in the setup command above).
About the 1MB tool result limit
Claude Desktop and some other MCP clients enforce a hard 1MB limit on the entire tool result, and base64 encoding adds ~33% overhead on top of raw image bytes — so a page that looks small as a PNG can still push the result over budget once encoded, especially across multiple pages in one call.
To handle this reliably, read_document_pages:
- Defaults to 1 page per call (call again with a higher
start_pagefor more) - Automatically retries at lower DPI (150 → 75 → 50 → 36) if a page doesn't fit a conservative internal budget, and tells you in its response text if it had to step down resolution
- Splits the byte budget evenly if you do request multiple pages at once via
max_pages
If you still hit a size error, try explicitly passing a lower dpi (e.g. 50)
or max_pages=1.
Notes
- Company numbers are auto zero-padded to 8 characters (e.g.
"123456"->"00123456"), matching Companies House's own convention. - Rate limit is 600 requests / 5 minutes, shared across all endpoints — the server surfaces a clear error if you hit it.
get_filing_history_itemreturns a link to document metadata; usedownload_documentto actually fetch the PDF/XHTML/JSON content.
Automated testing
Fast deterministic pytest suite (all mocked HTTP, no network, no API key):
pip install pytest pytest-asyncio respx
pytest tests/ -v
Nineteen tests covering: URL construction, company-number padding, HTTP error handling (401/404/429/missing-key), search-param serialisation, document rendering size-budget compliance, and tool-registration contract. Runs in under a second — safe to put in CI.
Evaluations
Different from unit tests: these grade whether an LLM can use the server to actually complete real tasks end-to-end. Requires both API keys.
pip install anthropic
export ANTHROPIC_API_KEY="sk-ant-..."
export COMPANIES_HOUSE_API_KEY="..."
python evals/eval_runner.py
evals/eval_runner.py spawns the server, hands its tool schemas to Claude
via the Anthropic API, runs an agentic loop (Claude picks tool → we execute
via MCP → feed result back → repeat), then grades each task:
- Verifiable tasks — checks the answer contains required substrings and
that expected tools were actually called (e.g. "must include the
director's surname", "must have called
get_officer_appointments"). - Judged tasks — sends the open-ended answer to a second Claude call acting as an LLM-as-judge, scoring against a written rubric.
Tasks live in evals/tasks.json. Add more to expand coverage. Prints a
per-task PASS/FAIL and aggregate at the end. This is the pattern you'd
extend into a real eval harness — add more tasks, track scores over time,
compare across model versions or server iterations.
Use with Claude Desktop
{
"mcpServers": {
"companies-house": {
"command": "/absolute/path/to/.venv/bin/python",
"args": ["/absolute/path/to/server.py"],
"env": {
"COMPANIES_HOUSE_API_KEY": "your-key-here"
}
}
}
}
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。