Openregistry

by sophymarine

583 downloads
Not rated
GitHub

Description

# openregistry **Real-time queries. Raw data. Raw documents. Synced directly from official registries — no intermediaries.** openregistry is a free remote MCP server — a platform by [sophymarine](https://sophymarine.com) — that connects AI agents directly to official national…

About

# openregistry **Real-time queries. Raw data. Raw documents. Synced directly from official registries — no intermediaries.** openregistry is a free remote MCP server — a platform by [sophymarine](https://sophymarine.com) — that connects AI agents directly to official national company registries as typed, structured…

Details

Author
sophymarine
Downloads
583
Categories
Other, Security, Finance

- Real-time queries – every tool call is a live proxy to the official registry.
- Raw data – upstream field names preserved; no AI interpretation or aggregation.
- Official sources – data comes directly from statutory registries per jurisdiction.
- Free anonymous tier – no installation, API key, or account needed to start.
- Multi-country search – user-confirmed fan-out across jurisdictions in parallel.
- 14+ typed tools – search, profile, officers, shareholders, UBO, charges, filings, documents, financials, and jurisdiction discovery.

Setting up with Highlight

This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:

  1. Download and install Highlight from highlightai.com/download
  2. Navigate to the plugins tab and select "Add Custom Plugin"
  3. Configure the plugin with the settings below
    Plugin Name Openregistry
    Command (node, npx, python, etc.)

    Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.

  4. Enable "Start Automatically" if you want the plugin to start when Highlight launches

From the repository

Add the server URL https://openregistry.sophymarine.com/mcp to your MCP client’s configuration (e.g., claude_desktop_config.json, ~/.cursor/mcp.json, or Cline settings). Use Streamable HTTP transport per the MCP spec. No API key or account required for anonymous use; sign in via OAuth 2.1 (passwordless email magic link) for higher rate limits.

list_jurisdictions

Per-country reference data dictionary. Two modes — pass EXACTLY ONE of: • `jurisdiction: 'GB'` — full schema for one country: registry name + URL, data license, company ID format with examples, native status values + mapping to the unified active/inactive/dissolved/unknown enum, list of supported tools, list of field names available in `jurisdiction_data` sub-objects (profile/filing/officer/shareholder/psc/charge), free-text quirks notes, and the global_search_excluded flag. • `supports_tool: 'get_officers'` — cross-country matrix for one tool: which jurisdictions implement it (with their registry names) and which don't. Calling with no parameters returns a structured 400 with both shapes documented. For server-level info (codes list, version, rate limits) call `about` instead.

search_companies

Search company registries. Two calling modes — pick EXACTLY ONE per call: 1. `jurisdiction: "GB"` — single country, direct query, no confirmation screen. Use when the user has named a specific country. 2. `jurisdictions: ["GB","NO","FR"]` — multi-country fan-out when you are unsure. On clients that support MCP elicitation the server asks the user to confirm / edit your list before running; on others it returns an error telling you to ask in chat. **Per-tier caps** on how many distinct countries can be in `jurisdictions` (or searched in a 60-second window via repeated single calls): anonymous/free = 3, pro = 10, max = 30, enterprise = unlimited. **Prefer `jurisdiction` (singular) when in doubt; ask the user first.** The confirmation dialog around `jurisdictions` is a safety net, not a way to fan out silently. Follow-up tools (get_company_profile, list_filings, get_officers, etc.) do NOT count against the fan-out cap. Returns candidates with unified top-level fields (jurisdiction, company_id, company_name, status, status_detail, incorporation_date, registered_address) plus a `jurisdiction_data` object carrying the raw upstream fields verbatim. The `status` field is a coarse four-value enum (active / inactive / dissolved / unknown) safe for cross-country comparison; `status_detail` carries the registry's native status string. Per-country caveats (ID format, accepted input shapes, filter options, paid-tier gates, status taxonomy) are available on demand — call `list_jurisdictions({jurisdiction:"<code>"})` for full schema, or `list_jurisdictions({supports_tool:"search_companies"})` for the full country-support matrix. All registries are official government sources.

search_companies_near_point

Search the French registry for companies whose siège social (registered office) lies within a given radius (km) of a latitude/longitude point. Maps to recherche-entreprises' /near_point endpoint. Useful for 'companies within 2km of the Eiffel Tower' style queries. Pricing: free. Returns the same UnifiedSearchCandidate shape as search_companies. Other jurisdictions return 501 — only FR exposes this endpoint.

get_specialised_record

Retrieve a record from one of ARES's specialised source registers — covers sector-specific data the basic profile doesn't include. ── CZ (Czechia ARES) ── Available source codes: • `ros` — Public Registers (Registr osob) summary state • `res` — Statistical Register of Economic Entities (Registr ekonomických subjektů) • `rzp` — Trade Licence Register (Registr živnostenského podnikání) — trade licences a sole trader / company holds • `nrpzs` — National Register of Healthcare Providers (Národní registr poskytovatelů zdravotních služeb) — for hospitals, clinics, pharmacies • `rpsh` — Register of Political Parties and Movements (Registr politických stran a hnutí) • `rcns` — Register of Churches and Religious Societies (Registr církví a náboženských společností) • `szr` — Farmers' Register (Registr zemědělských podnikatelů) • `rs` — Register of Schools (Registr škol) • `ceu` — Central Insolvency Record (Centrální evidence úpadců) Each source returns its own response shape — refer to ARES API docs at https://ares.gov.cz/swagger-ui/ for field details. The full upstream record is returned verbatim under `record`. Use this when the basic get_company_profile or get_officers/get_psc/get_charges don't have the field you need (e.g. trade-licence specialisations for sole traders → rzp, school accreditation details → rs, healthcare facility list → nrpzs). Returns 404 if the IČO doesn't exist in that specific source register. Pricing: free. Other jurisdictions return 501.

search_specialised_records

Fetch raw records from one specific ARES source register in a single call, optionally filtered by a list of IČOs. This is the paired search endpoint for get_specialised_record (which fetches one record at a time). Uses POST /ekonomicke-subjekty-{source}/vyhledat upstream. ── CZ (Czechia ARES) ── Available source codes (same as get_specialised_record, plus 'vr'): • `vr` — Commercial register (Veřejný rejstřík) — the full company record with officers/PSCs/charges • `ros` — Public Registers summary (Registr osob) • `res` — Statistical Register (Registr ekonomických subjektů) • `rzp` — Trade Licence Register (Registr živnostenského podnikání) • `nrpzs` — Healthcare Providers (Národní registr poskytovatelů zdravotních služeb) • `rpsh` — Political Parties (Registr politických stran a hnutí) • `rcns` — Churches and Religious Societies (Registr církví) • `szr` — Farmers (Společný zemědělský registr) • `rs` — Schools (Registr škol) • `ceu` — Insolvency Record (Centrální evidence úpadců) The upstream filter is intentionally narrow — ARES only accepts an optional list of IČOs plus pagination on these per-source endpoints. For rich name/address/legal-form search, use search_companies (which queries the main /ekonomicke-subjekty/vyhledat endpoint). Returns `{ source, pocet_celkem, count, records[] }` with each `records[i]` preserved verbatim from the upstream source — field set varies per source (refer to the ARES API docs at https://ares.gov.cz/swagger-ui/). Pricing: free. Other jurisdictions return 501.

search_addresses

Resolve a free-text or structured Czech address against the RÚIAN (Registr územní identifikace, adres a nemovitostí) register. Returns one or more normalised addresses with full geographic codes (kodAdresnihoMista, kodObce, kodOkresu, kodKraje, PSC). Powered by ARES's POST /standardizovane-adresy/vyhledat. ── Use cases ── • Normalise a messy address string before matching it against other data sources • Resolve an obec/street/house number to its canonical RÚIAN code • Validate whether an address exists in the Czech cadastre ── Standardisation mode ── • `UPLNA_STANDARDIZACE` (default): require full match (street + house number + locality) • `VYHOVUJICI_ADRESY`: accept partial matches (e.g. obec only) At least one of (text, nazev_obce, kod_obce, kod_adresniho_mista) should be supplied. Response contains a `stav_standardizace` field reporting whether the match was UPLNA, CASTECNA_OBEC, or NEUSPESNA (no match). Pricing: free. Other jurisdictions return 501.

list_change_batches

Access the change-batch feed — incremental delta batches listing every company ID that changed in a given source register during a given reporting period. Currently only available for CZ; other jurisdictions return 501. Two modes: 1. **List mode** (omit `batch_id`): returns the N latest batches, optionally filtered by `source`. Page forward via `offset`/`limit` until the returned array is empty — the upstream has no total-count field. 2. **Detail mode** (supply `batch_id` + `source`): returns change records in that batch with typZmeny ∈ {INS, UPD, DEL} and the changed company ID. Response also carries `total_changes` (full batch size) and `pagination: { limit, offset, has_more }`. Client-side sliced — batches can exceed 1000 records. Raw upstream fields come through verbatim under `jurisdiction_data`. Default page size 100, max 1000. Per-country source codes, capabilities and caveats — call `list_jurisdictions({jurisdiction:"<code>"})`.

list_establishments

Return every establishment unit (vestigingseenheid / unité d'établissement) attached to a Belgian enterprise number, as exposed by the official KBO Public Search vestiginglijst.html page. Each unit is a physical location (office / shop / warehouse) operated by the enterprise and has its own 10-digit establishment number starting with the digit 2 (e.g. 2.143.775.125). The unit itself is NOT a legal entity — the enterprise is — but the KBO exposes per-unit name, address, start date, activity codes, contact details, and (where applicable) authorisations and entrepreneurial-skill registrations. Returns an array of `{ establishment_id, establishment_id_digits, status, start_date, name, address }`. Pricing: free. Other jurisdictions return 501.

check_name_availability

Probe the Isle of Man Companies Registry 'Check Name Availability' endpoint (companynameavailability.iom). Returns `{ query, available, warning, similar_names[] }` where `available` is true only when upstream does not emit the 'Name entered already exists' warning AND the similar-names table is empty. Each similar_names row carries the exact name, company number, registry type, status, and (when upstream linked it) the opaque Id of the existing company. Pricing: free; no login required. Other jurisdictions return 501.

list_actos_inscritos

Scans BORME Section I (Empresarios — Actos inscritos) and Section B (Otros actos) province PDFs across a date range, returns every acto paragraph whose header line exactly matches the given denominación. Use this to recover current/historical directors, resignations, constitución details, sole-shareholder declarations, capital changes, dissolution, extinción — all statutory registered acts, which are NOT exposed by the per-company /buscar/anborme.php search (that indexes only Section II Anuncios y avisos legales). Each hit includes the verbatim acto_numero (BOE's in-year sequential), borme_a_id (BORME-A-YYYY-NNN-PP province bulletin), provincia title, source_pdf_url, pagina_inicial/final, denominacion_upstream (as printed, including accent/punctuation drift), and texto_raw — the complete paragraph text from the `{Nº} - {DENOMINACIÓN}.` header to the next acto boundary. The adapter does NOT parse specific fields (Nombramientos / Ceses / Socio único / Capital / Datos registrales) — read texto_raw and extract inline. Performance: each day in the range costs ~N province PDF fetches (N ≤ 52 provinces but typically 20–40). Default window: last 30 days. Hard cap: 90 days per call. Chunk longer windows client-side. Supported on ES only. Cached on the VM (PDFs are immutable once published).

get_code_description

Resolve a registry code-list to a human-readable code → description map. Useful for decoding values seen in jurisdiction_data fields. ── FI (Finland PRH) ── Codes: YRMU (company forms), KRTILA (trade-register status), TOIMI4 (TOL 2008 industries), ALUE (regions). lang: en | fi | sv (default en). ── CZ (Czechia ARES) ── Codes: PravniForma / FinancniUrad / TypAngazma / TypOrganu / StavZdroje / TypAkcie. Czech only. ── CH (Switzerland Zefix) ── Codes: legalForm (entity types — AG/Sàrl/Verein/...), registryOfCommerce (26 cantonal registries), community (Swiss communes by BFS ID). Multilingual (de/fr/it/en). Returns a flat object: { code: description, … }. Pricing: free. Other jurisdictions return 501.

count_companies

Return the total number of companies that would match a search, without fetching the candidates themselves. Useful before paginating very large result sets to decide whether to narrow the query. ⚠️ **Performance note**: this is NOT cheaper than search_companies — CRO's /companycount endpoint runs the same underlying query and takes ~2s on average (similar to a full search). Only use it when the raw count is what you actually need (e.g. 'how many Coffee business names exist in Ireland?'). For 'is this query narrow enough to paginate?', it's faster to call search_companies with limit=1 — you'll get the first hit AND a sense of recall in one round-trip. ── IE (Ireland CRO) ── Maps to the /companycount endpoint. Supports the same filters as search_companies (query, match_type, bus_ind, include_business_names, address, alpha). Returns a plain integer. Pricing: free. Other jurisdictions return 501 — Companies House/Brreg/ABR don't expose a count-only endpoint.

search_officers

Find people who hold or have held officer positions (director, secretary, member, partner) at companies registered in a jurisdiction, by name. Returns a list of officer candidates each with an officer_id, name, and (where the registry exposes it) the number of appointments held. Use the officer_id in get_officer_appointments to retrieve every company that person has been appointed to. This is the entry point for 'follow the human, not the company' investigations.

get_company_profile

Fetch the full profile of a company by its registry-specific ID. Returns unified top-level fields (jurisdiction, company_id, company_name, status, status_detail, incorporation_date, registered_address) plus a `jurisdiction_data` object carrying the raw upstream fields verbatim. The `status` field is a coarse four-value enum (active / inactive / dissolved / unknown) safe for cross-country comparison; `status_detail` carries the registry's native status string. The registered_address top-level field is a flattened string; the original nested address (when upstream provides one) is preserved in jurisdiction_data. Does NOT include filings, officers, PSCs, shareholders, or charges — call the dedicated tools (`list_filings`, `get_officers`, `get_persons_with_significant_control`, `get_shareholders`, `get_charges`) for those. Input `company_id` is the registry's canonical identifier for the jurisdiction; shapes vary (8-digit numbers, prefixed alphanumerics, hyphenated forms, multi-shape routing by length, etc.) and many registries accept light normalisation (leading-zero padding, whitespace / hyphen stripping, alternate equivalents). Pull a `company_id` from `search_companies` whenever possible rather than guessing. Optional flags `include_vr`, `include_history`, `include_establishments` enable extra upstream fetches on jurisdictions that support them and are ignored elsewhere. `fresh: true` bypasses the cache. Per-country caveats (ID format, accepted input shapes, jurisdiction_data field catalogue, paid-tier gates, status taxonomy) are available on demand — call `list_jurisdictions({jurisdiction:"<code>"})` for the full schema, or `list_jurisdictions({supports_tool:"get_company_profile"})` for the country-support matrix. All registries are official government sources.

list_filings

Return a company's filing history. Each filing has a `filing_id`, `filing_date`, `category`, `description`, and (when upstream exposes one) a `document_id` that round-trips to `get_document_metadata` / `fetch_document`. Raw upstream fields come through verbatim under `jurisdiction_data`. Results are newest-first. Use the optional `category` parameter to filter. Common normalized categories: 'accounts', 'annual-return', 'capital', 'charges', 'confirmation-statement', 'incorporation', 'insolvency', 'liquidation', 'mortgage', 'officers', 'persons-with-significant-control', 'resolution'. Some jurisdictions also accept native form codes directly — pass the upstream code through unchanged if you have one. Pagination: `limit` (default 25, max 1000). Some adapters use cursor pagination — pass back `next_cursor` as `cursor` to continue. Others use numeric `offset`. `has_document` flags whether the body can actually be retrieved via `fetch_document`; some registries expose only the metadata listing with the body paywalled or unavailable. Not every registry publishes a filing list; unsupported jurisdictions return 501. Per-country caveats (ID format, accepted category values, cursor vs offset, document availability and pricing, paid-tier gates) — call `list_jurisdictions({jurisdiction:"<code>"})`.

get_financials

Return annual-accounts filings (financial statements) for a company. Convenience wrapper over `list_filings(category='accounts')` that normalizes the fiscal-period shape across registries and pre-computes the download URL so callers don't need a second `get_document_metadata` round-trip. Each item has `period_end` (fiscal-period end date, the primary sort key a user thinks in), optional `period_start` / `registration_date`, a `document_id` that can be passed to `fetch_document`, `document_format` (e.g. XBRL XML, XHTML, PDF — may be empty when the upstream negotiates format on fetch), `source_url` for direct download, and `jurisdiction_data` carrying raw upstream fields verbatim. Results are newest-first. Filters: `year=YYYY` keeps periods ending in that calendar year; `period_end=YYYY-MM-DD` pinpoints a single period (takes precedence over `year`). `limit` caps the post-filter slice — omit to return all matches. The whole accounts history is walked per query because late-filed amendments can land out of order. If the adapter doesn't implement `list_filings` at all, this returns 501. Per-country caveats (ID format, document format availability, whether bodies are paid) — call `list_jurisdictions({jurisdiction:"<code>"})`.

get_shareholders

Return the shareholders / members / quota-holders of a company — the legal-statutory equity roster published by the company registry, with no ownership-threshold filter. **When to call this tool.** Use this whenever the user asks about 'shareholders', 'members', 'quota-holders', or equivalents in other languages ('股东', '股東', 'actionnaires', 'socios', 'Gesellschafter', 'aksjonærer', 'aandeelhouders' etc.). This is a DIFFERENT concept from `get_persons_with_significant_control` (PSC / beneficial owners / UBO), which returns only persons above a statutory control threshold (typically >25%) on a separate beneficial-ownership register. Do NOT substitute PSC for a plain shareholder question — the two registers can disagree (a 10% shareholder is on the members register but not the PSC register; a corporate trustee can be a PSC without appearing on the members register). Call PSC only when the user explicitly asks about 'beneficial owners', 'who controls', 'PSC', 'UBO', or the threshold register. Public disclosure is strongly legal-form-conditional. Private-limited / LLC forms typically disclose quota-holders in the public register; joint-stock / public-limited forms typically keep shareholders in a private book, so this tool may return an empty list, a pointer to the relevant filing, or a statutory explanation. Response shape varies by jurisdiction: some return a structured array, some return the filing(s) that carry the roster (you then call `fetch_document` on the returned document_id to read the actual list), some return threshold-crossing events for listed issuers. Every response includes a disclosure flag and/or explanatory note. Always returns a `jurisdiction_data` object with the raw upstream fields verbatim. `fresh: true` bypasses the cache. Jurisdictions without this capability return 501. Per-country caveats (which legal forms disclose, response shape, how to reconstruct a current roster from delta filings) are available on demand — call `list_jurisdictions({jurisdiction:"<code>"})` for the full schema, or `list_jurisdictions({supports_tool:"get_shareholders"})` for the country-support matrix. All registries are official government sources.

get_officers

Return the officers of a company — current directors, secretaries, members, partners, board members, procurists / authorised signatories, liquidators, and (by default, where upstream exposes them) historical resignations. Each officer has a unified shape (jurisdiction, officer_id, name, role, appointed_on, resigned_on, is_active) plus a `jurisdiction_data` object carrying the raw upstream fields verbatim. Role labels are passed through in the registry's native language (e.g. Styremedlem, Předseda představenstva, Président, PREZES ZARZĄDU) — translate client-side as needed. Birth-date precision varies by jurisdiction (some registries publish YYYY-MM-DD, some only month + year, some nothing). `officer_id`, when present, can be passed to `get_officer_appointments` to retrieve every other company this person has been appointed to — cross-company tracing is one of the most powerful uses of this tool. Not every jurisdiction issues stable person IDs; corporate officers are usually keyed by the corporate's own company_id, natural persons may be keyed by a synthetic index. Some registries mask officer names under GDPR / privacy rules — that masking is upstream, not server-side. Flags: `include_resigned` (default true) toggles historical entries on jurisdictions that expose both; `group_by_person` deduplicates the same person across consecutive appointments on jurisdictions that support it; `fresh: true` bypasses the cache. Flags are ignored on registries that don't support them. Jurisdictions that don't publish officer data (or that gate it behind paid extracts) return 501. Per-country caveats (role-label vocabulary, birth-date precision, resignation coverage, GDPR masking, 501 gating, delta-vs-snapshot semantics) are available on demand — call `list_jurisdictions({jurisdiction:"<code>"})` for the full schema, or `list_jurisdictions({supports_tool:"get_officers"})` for the country-support matrix. All registries are official government sources.

get_officer_appointments

Given an officer_id (from get_officers or search_officers), return every company in the registry where that person has held an appointment, with role, appointed_on, and resigned_on dates. This is the cross-company tracing tool — use it to follow a person's full corporate footprint across the registry. Results are paginated.

get_persons_with_significant_control

Return the persons with significant control (PSCs / beneficial owners) of a company — persons on a statutory-threshold register (typically >25% ownership or voting rights). **When to call this tool.** Only when the user explicitly asks about 'beneficial owners', 'UBO', 'PSC', 'who controls', or the >25% threshold register. For plain 'shareholders' / 'members' / '股东' / '持股人' questions, call `get_shareholders` instead — it is a DIFFERENT register (the full equity roster with no threshold). A 10% shareholder shows up on the members register but not here; a corporate trustee can show up here without being on the members register. Each entry has `name`, `kind` (individual / corporate-entity / etc.), `nature_of_control` (e.g. ownership-of-shares-75-to-100-percent, voting-rights-25-to-50-percent), `notified_on`, and `ceased_on` if applicable. Raw upstream fields come through verbatim under `jurisdiction_data`. Returns an empty list (not an error) for companies whose registry supports PSCs but has no filing on record. Many countries keep beneficial-ownership data in a separate register from the main company registry, or restrict it to authenticated / AML-obliged callers. Unsupported jurisdictions return 501, sometimes with `alternative_tool='get_shareholders'` when the caller probably wanted registered shareholders instead. Per-country availability, historical-entry behaviour, and paid-tier gates — call `list_jurisdictions({jurisdiction:"<code>"})`.

get_charges

Return charges (mortgages, fixed and floating charges, pledges, security interests) registered against a company. Primary tool for security-interest and lender analysis. Each charge has `charge_id`, `status` (outstanding / satisfied / part-satisfied), `classification` (e.g. 'fixed charge', 'floating charge', 'pledge on share stake'), `created_on`, `satisfied_on` if applicable, and `persons_entitled` (lenders / chargeholders). Raw upstream fields come through verbatim under `jurisdiction_data`. Returns an empty list (not an error) for companies with no registered charges. Scope is registry-specific: some jurisdictions keep real-estate mortgages, movable-asset pledges, or receivables in separate registers this tool does not reach. Unsupported jurisdictions return 501; some return 501 and suggest `list_filings(category='charges')` as an alternative. Per-country scope, classifications, and caveats — call `list_jurisdictions({jurisdiction:"<code>"})`.

get_document_metadata

Retrieve metadata about a filing document by its `document_id` (obtained from `list_filings`). Returns available content formats with byte sizes (when known), page count, source URL, and creation date. Raw upstream fields come through verbatim under `jurisdiction_data`. Call this before `fetch_document` when the document might be large or you don't yet know the format — it lets you decide whether to download inline or hand the `source_url` to the user. **Do NOT construct or guess `document_id` values** — some registries use composite IDs (multi-part, colon- or slash-separated) that must come from a previous `list_filings` response. Synthesized IDs will 404 or 502. `available_formats` may be empty when the body is paywalled or the registry doesn't publish bodies at all — in those cases `fetch_document` returns 501 / a purchase link. Unsupported jurisdictions return 501. Per-country ID format, pricing, and availability — call `list_jurisdictions({jurisdiction:"<code>"})`.

fetch_document

Primary tool for reading a filing's content. Pass a `document_id` from `list_filings` / `get_financials`. MANDATORY for any substantive answer — filing metadata (dates, form codes, descriptions) alone doesn't answer the user; the numbers and text live inside the document. ── RESPONSE SHAPES ── • `kind='embedded'` (PDF up to ~20 MB; structured text up to `max_bytes`): returns `bytes_base64` with the full document, `source_url_official` (evergreen registry URL for citation, auto-resolved), and `source_url_direct` (short-TTL signed proxy URL). For PDFs the host converts bytes into a document content block — you read it natively including scans. • `kind='resource_link'` (document exceeds `max_bytes`): NO `bytes_base64`. Returns `reason`, `next_steps`, the two source URLs, plus `index_preview` for PDFs (`{page_count, text_layer, outline_present, index_status}`). Use the navigation tools below. ── WORKFLOW FOR kind='resource_link' ── 1. Read `index_preview.text_layer`. Values: `full` (every page has real text), `partial` (mixed), `none` (scanned / image-only), `oversized_skipped` (indexing skipped), `encrypted` / `failed`. 2. If `full` / `partial`: call `get_document_navigation` (outline + previews + landmarks) and/or `search_document` to locate pages. If `none` / `oversized_skipped`: skip search. 3. Call `fetch_document_pages(pages='N-M', format='pdf'|'text'|'png')` to get actual content. Prefer `pdf` for citations, `text` for skim, `png` for scanned or oversized. ── CRITICAL RULES ── • **Navigation-aids-only**: previews, snippets, landmark matches, and outline titles returned by the navigation tools are for LOCATING pages. NEVER cite them as source material — quote only from `fetch_document_pages` output or this tool's inline bytes. • **No fallback to memory**: if this tool fails (rate limit, 5xx, disconnect), do NOT fill in names / numbers / dates from training data. Tell the user what failed and offer retry or `source_url_official`. • Don't reflexively retry with a larger `max_bytes` — for big PDFs the bytes are unreadable to you anyway. Use the navigation tools instead. `source_url_official` is auto-resolved from a session-side cache populated by the most recent `list_filings` call. The optional `company_id` / `transaction_id` / `filing_type` / `filing_description` inputs are OVERRIDES for the rare case where `document_id` didn't come through `list_filings`. Per-country document availability, format, and pricing — call `list_jurisdictions({jurisdiction:"<code>"})`.

get_document_navigation

For PDFs that don't fit in a single document block (>~20 MB or >100 pages) OR whenever you need to locate specific sections, call this FIRST before fetching content. Returns outline (PDF bookmarks), per-page text previews (first ~200 chars), keyword-matched landmarks (balance sheet, directors report, auditor report etc.), text_layer classification, and source URLs. CRITICAL — these are NAVIGATION AIDS ONLY. Page previews, outline titles, landmark matches, and search snippets may be truncated, contain OCR errors, or match false positives. NEVER cite them as source material for numbers, quotes, legal text, financial figures, dates, or names. Always follow up with fetch_document_pages(pages=<n>) to retrieve authoritative content before answering. Requires the document bytes to already be cached — call fetch_document once first if this is a new document.

search_document

Locate pages containing a phrase. Returns matching page numbers + short context snippets for navigation. Useful when the outline/landmarks don't list your target (e.g. you want 'directors' remuneration' but only 'Directors Report' is a landmark). Up to `max_hits` pages (default 20) are returned; `total_hits` counts raw matches across the document. CRITICAL — snippets are NAVIGATION AIDS ONLY and may contain OCR errors. Once you've identified target pages, call fetch_document_pages(pages=<n>) to read the authoritative text / bytes before citing anything. Requires get_document_navigation (or fetch_document on a PDF) to have run first so the per-page text index exists in R2.

fetch_document_pages

Return specific pages of a PDF in one of three formats: • format='pdf' — pdf-lib page slice, preserves the original text layer and fonts (no re-encoding). This is the ONLY format that gives you byte-exact, citation-grade content. Use this for financial numbers, legal quotes, and any answer requiring precision. • format='text' — raw extracted text from pdfjs. Machine-readable but NOT authoritative — OCR errors on bad-quality text layers can silently garble digits. Use only for summarisation / light reading, and cross-check numbers by re-fetching with format='pdf'. • format='png' — page rasterization via Cloudflare Browser Rendering, for documents with text_layer='none' (scanned PDFs). Phase 6 — may return 'not implemented' in current deployment. The response includes at most 100 pages (Anthropic document-block hard cap). Split larger ranges into multiple calls. Requires the document's bytes to already be cached — call fetch_document on the full document first if this is a new filing.

about

Compact self-description (default response <1KB): server name, version, list of supported jurisdiction codes, list of tool names, pricing, rate limits. Pass `section` to expand a specific slice — 'principles', 'tools', 'data_licenses', 'jurisdictions' (compact capability map for every registered adapter), or 'jurisdiction' + `jurisdiction` (full metadata for one country). For the full per-jurisdiction schema (field lists, status mappings, ID formats, notes), prefer list_jurisdictions.

Claude Desktop / Cursor

Paste into your MCP client config file to install this server.

{
    "mcpServers": {
        "openregistry": {
            "openregistry": {
                "url": "https://openregistry.sophymarine.com/mcp",
                "transport": "streamable-http"
            }
        }
    }
}

McpServers

{
    "openregistry": {
        "url": "https://openregistry.sophymarine.com/mcp",
        "transport": "streamable-http"
    }
}

Real-time direct access to unmodified data and raw filings of 30 official government registries via MCP.

Tools: search companies, get profiles, officers, shareholders, charges, filings, and financial-statement documents.

Covers UK Companies House, Ireland CRO, France RNE, Spain BORME, Italy InfoCamere, Norway Brreg, Poland KRS, Netherlands KVK, Belgium KBO, Switzerland Zefix, Finland, Czechia, Korea, Taiwan, New Zealand, Cayman Island, Australia, Canada and a lot more.

Free tier; paid keys for higher quota and depth.

Data licensed from🇬🇧UK Companies House· 🇮🇪CRO Ireland· 🇳🇴Brønnøysund· 🇨🇭Zefix· 🇵🇱KRS Ministry of Justice— and22 more national registriesunder their respective open-data licences.

Above:an AI agent walks the shareholders ofIceland Foods Ltdthrough 4 UK holding companies —WD FF MIDCO → ICELAND VLNCO → LANNIS → WD FF LIMITED— and surfaces the 8 individuals who actually own the chain (Tarsem Dhaliwal41.35%as the largest shareholder, Walker family51.31%combined). Every share count, every percentage, read verbatim from the registry's own CS01 PDFs.

OpenRegistry is your AI agent's live hotline to 30 national company registries — UK Companies House, France RNE, Germany Handelsregister, Italy InfoCamere (via EU BRIS), Spain BORME, Poland KRS, Korea OpenDART, Canada CBCA, 10 US states, and more.

We return the registry's own response — unmodified.Every field name, every status value, every raw filing byte (XHTML iXBRL / PDF / XBRL) is preserved exactly as the government's system emits it. The identifiers and jurisdiction routing let you reconstruct the government URL for any record. No aggregator markup. No field renames. No document re-rendering. No AI reinterpretation. No stale cache.

Chain queries across borders in a single prompt— a UK Ltd → its Luxembourg SARL → its Cayman LP → the Jersey trust → the individual beneficiary, all in one conversation. Walk ownership structures through 30 jurisdictions to unmask the real person behind any company.

Hosted endpoint:https://openregistry.sophymarine.com/mcp

One-liner.OpenCorporates and BvD areaggregatorsthat re-shape and cache; CH-direct is single-jurisdiction. OpenRegistry is the layer between an AI agent and the original government APIs — verbatim, live, multi-country, no API key for the free tier.

Where OpenRegistry deliberately doesn't have data (statutorily restricted BO registers post-CJEU C-37/20: DE, ES, IT, NL, LU, AT, MT, PT), the response carries a structuredalternative_urlpointing at the AML-obliged-only statutory portal. We don't pretend to have data we don't.

Three full request → response examples for the most common tools. All three reproducible on the free tier. Calls are JSON-RPC over MCP Streamable HTTP athttps://openregistry.sophymarine.com/mcp; for brevity we show the tool name + arguments + the unwrapped response.

// Request { "name": "search_companies", "arguments": { "jurisdiction": "GB", "query": "Monzo Bank", "limit": 5 } } // Response (truncated to 1 result) { "jurisdiction": "GB", "count": 5, "results": [ { "jurisdiction": "GB", "company_id": "09446231", "company_name": "MONZO BANK LIMITED", "status": "active", "incorporation_date": "2015-02-06", "registered_address": "Broadwalk House, 5 Appold Street, London, England, EC2A 2AG", "jurisdiction_data": { "company_number": "09446231", "company_status": "active", "company_type": "ltd", "date_of_creation": "2015-02-06", "title": "MONZO BANK LIMITED", "address_snippet": "Broadwalk House, 5 Appold Street, London, England, EC2A 2AG", "kind": "searchresults#company", "links": { "self": "/company/09446231" } // ... 20+ verbatim CH fields } } ] }

2.get_persons_with_significant_control— UK PSC for a known company

// Request { "name": "get_persons_with_significant_control", "arguments": { "jurisdiction": "GB", "company_id": "OC404063" } } // Response [ { "jurisdiction": "GB", "psc_id": "...", "name": "[REDACTED — UK CH residential-address suppression]", "kind": "individual-person-with-significant-control", "nature_of_control": ["ownership-of-shares-25-to-50-percent"], "notified_on": "2024-08-15", "is_active": true, "jurisdiction_data": { "etag": "...", "natures_of_control": ["ownership-of-shares-25-to-50-percent"], "notified_on": "2024-08-15", "country_of_residence": "United Kingdom", "date_of_birth": { "month": 7, "year": 1985 }, "address": { "country": "United Kingdom" }, "links": { "self": "/company/OC404063/persons-with-significant-control/individual/..." } // ... full CH PSC record } } ]

PSC ≠ shareholders.UK Companies House publishes a structured PSC register and aseparate(filing-only) statement of capital. They disagree: a 10% shareholder appears in the statement of capital but not in PSC; a corporate trustee appears in PSC without being a shareholder. We surface both viaget_persons_with_significant_controlandget_shareholdersrespectively — see theshareholders-vs-PSC case study.

3.fetch_document— raw iXBRL annual accounts bytes

// Request — get the document_id from list_filings or get_financials first { "name": "fetch_document", "arguments": { "document_id": "MzQ0MTUyNDU5N2FkaXF6a2N4", "max_bytes": 5000000 } } // Response (metadata + base64-encoded body) { "jurisdiction": "GB", "document_id": "MzQ0MTUyNDU5N2FkaXF6a2N4", "content_type": "application/xhtml+xml", "size_bytes": 348721, "encoding": "base64", "content": "PCFET0NUWVBFIGh0bWwgUFVCTElDIC...", // signed proxy URL for human download / out-of-band fetch "proxy_url": "https://openregistry.sophymarine.com/document/gb/MzQ0MTUyNDU5N2FkaXF6a2N4/content?token=..." }

Thecontentis theliteral iXBRL bytesCompanies House sends — your AI agent parses or re-renders as it sees fit. We don't re-encode, normalise tags, or extract figures into our own schema. Passformat: "png"(Browser Rendering required) to receive a rasterised page-by-page render of scanned PDFs instead.

OpenRegistry surfaces three distinct kinds of failure with structured responses so AI agents can branch on them.

Per-IP for anonymous, per-user for signed-in. The cross-borderfan-out capis a separate counter that limits how manydistinctjurisdictions a caller can hit viasearch_companiesin a rolling 60-second window.

When you exceed either limit, the response is HTTP429:

{ "jsonrpc": "2.0", "error": { "code": -32000, "message": "rate-limited", "data": { "reason": "rate-limited", "retry_after_ms": 12400, "scope": "ip" // or "user" or "fanout" } } }

The HTTP layer also sets the standardRetry-After: 13header (seconds, rounded up).Honourretry_after_msexactly— exponential back-off on top is unnecessary; the limit window is fixed-rolling, not adaptive. Fan-out cap (scope: "fanout") is a 60-second rolling window — the second your oldest country falls off, you can hit a new one. Pro tier caps at 10 distinct countries / 60s, Max at 30, Enterprise unlimited.

Statutorily restricted (CJEU C-37/20 and similar)

Some beneficial-ownership registers became access-restricted to AML-obliged entities post-CJEU C-37/20 (DE, ES, IT, NL, LU, AT, MT, PT) and the Cayman Beneficial Ownership Transparency Act. We don't proxy these — the tool returns HTTP501with structured guidance:

{ "jurisdiction": "DE", "error": "not_proxied_by_design", "reason": "CJEU-C-37-20", "alternative_url": "https://www.transparenzregister.de", "alternative_access": "AML-obliged entities only (banks, lawyers, notaries, etc.)", "human_message": "The German Transparency Register is statutorily gated since 22 Nov 2022." }

This is adesignresponse, not a transient failure — retrying won't help. Thealternative_urlis the canonical statutory portal where qualified entities can register for access.

Upstream errors and tool-level structured 501s

When the upstream registry has its own outage, we surface its error verbatim with a structured wrapper:

{ "jurisdiction": "ES", "error": "upstream_error", "upstream_status": 524, "human_message": "Spain BORME upstream timed out (Madrid bulletin renderer slow). Retry in 30-60s.", "retry_after_ms": 45000 }

Some tools also return501with analternative toolsuggestion when the upstream registry doesn't expose the requested concept (e.g. CZ political parties don't have officers in the standard sense — callsearch_specialised_recordswithsource="rpsh"instead):

{ "error": "alternative_tool_required", "alternative_tool": "search_specialised_records", "alternative_args": { "jurisdiction": "CZ", "source": "rpsh", "...": "..." }, "human_message": "Czech political parties register is exposed via the RPSH sub-source." }

A reference back-off implementation is published in every framework integration guide under/docs/integrations.

We publish 10 professional Claude Agent Skills for the most common OpenRegistry workflows. Drop them into your Claude Code project's.claude/skills/directory or into any Claude-compatible agent — invoke by intent.

Seeskills/README.mdfor the skillpack overview.

Every skill above is also served by the MCP server as a namedprompt— so any MCP-compatible client (Claude Desktop, Cursor, Cline, Goose, Zed, …) shows them in its prompt picker without installing skill files. Callprompts/listto discover them,prompts/getto invoke. Same names:kyc_cross_border_due_diligence,ubo_cross_border_chain_walker,director_search_pep_screening,live_company_accounts_xbrl,corporate_filing_monitor,global_company_name_availability,industry_competitor_search,shell_company_detector,phoenix_company_radar,sector_gatekeeper_list.

OpenRegistry works with every major MCP-capable client. The samehttps://openregistry.sophymarine.com/mcpendpoint works across all of them.

Settings → Connectors → Add custom connector → pastehttps://openregistry.sophymarine.com/mcp.

For older builds without the Connectors UI, add toclaude_desktop_config.json:

{ "mcpServers": { "openregistry": { "command": "npx", "args": ["-y", "mcp-remote", "https://openregistry.sophymarine.com/mcp"] } } }
claude mcp add --transport http openregistry https://openregistry.sophymarine.com/mcp

On Claude Code 2.1.1+ you can also use the JSON form:

claude mcp add-json openregistry '{"type":"http","url":"https://openregistry.sophymarine.com/mcp"}'

One-line install via thegemini-extension.jsonmanifest in this repo:

gemini extensions install https://github.com/sophymarine/openregistry

Or add to~/.gemini/settings.jsonmanually (Gemini useshttpUrl, noturl):

{ "mcpServers": { "openregistry": { "httpUrl": "https://openregistry.sophymarine.com/mcp" } } }

Google's consumer Gemini app at gemini.google.com does not support custom MCP today — only the CLI and Gemini Enterprise (Google Cloud admin path) do.

Plus / Pro / Business / Enterprise / Education plans only (Free tier doesn't expose Developer Mode).
- Settings → Apps & Connectors → Advanced settings → enableDeveloper Mode.
- On the Connectors page, clickCreateand pastehttps://openregistry.sophymarine.com/mcp.

See OpenAI'sdeveloper-mode help article.

Pro / Max / Enterprise plans only. Settings → Connectors → Add custom remote connector → paste the URL → choose OAuth. Works in regular chat, the Comet browser, and Computer agent workflows. (Changelog 2026-03-13.)

{ "mcpServers": { "openregistry": { "url": "https://openregistry.sophymarine.com/mcp" } } }

Or add to.vscode/mcp.json(workspace) or User Settings → MCP. VS Code usesservers(notmcpServers) and requirestype: "http":

{ "servers": { "openregistry": { "type": "http", "url": "https://openregistry.sophymarine.com/mcp" } } }

GitHub Copilot in JetBrains, Visual Studio, Xcode, and Eclipse also supports custom MCP via the samemcp-config.jsonpattern — seedocs.github.com/copilotfor the IDE-specific setup. Copilot CLI uses~/.copilot/mcp-config.jsonor the interactive/mcp addcommand.

Microsoft 365 Copilot (Word / Excel / PowerPoint / Teams / Outlook)

Organization-level deployment via Microsoft Copilot Studio agent path. Requires a Microsoft 365 Copilot license.
- InMicrosoft Copilot Studio, open or create an agent →ToolsAdd a toolNew toolModel Context Protocol.
- Pastehttps://openregistry.sophymarine.com/mcp, then forAuthenticationpickOAuth 2.0 → Dynamic discovery(OpenRegistry implements DCR with discovery — zero config).
- Publish the agent and submit it for admin approval. After your Global / Teams Admin approves it in the Microsoft 365 admin center, it appears in theAgent Storeacross Teams, Outlook, Word, Excel, and PowerPoint.

See Microsoft'sCopilot Studio MCP docsand theAgent Store guide.

Settings → Cline → MCP Servers → Edit settings → paste intocline_mcp_settings.json:

{ "mcpServers": { "openregistry": { "url": "https://openregistry.sophymarine.com/mcp", "transport": "streamable-http" } } }

Seellms-install.mdfor automated LLM-driven installs.

Cascade panel → hammer icon (🔨) →Configureopens~/.codeium/windsurf/mcp_config.json. Add this block (note Windsurf usesserverUrl, noturl), then clickRefresh(🔄):

{ "mcpServers": { "openregistry": { "serverUrl": "https://openregistry.sophymarine.com/mcp" } } }

Zed, Goose, Continue, and any other MCP 2025-06-18 client work with the standard config:

{ "mcpServers": { "openregistry": { "url": "https://openregistry.sophymarine.com/mcp" } } }

Streamable HTTP transport perMCP spec 2025-06-18. OAuth 2.1 authorization flow (Dynamic Client Registration per RFC 7591 — no API key to paste).

Every major agent framework ships a generic MCP adapter, so OpenRegistry's 27 tools + 10 prompt workflows plug in with zero framework-specific code. Minimum working example per framework:

- LangChain / LangGraph(Python) →openregistry.sophymarine.com/docs/integrations/langchain
- LlamaIndex(Python) →
/docs/integrations/llamaindex
- CrewAI(Python) →
/docs/integrations/crewai
- Haystack(Python) →
/docs/integrations/haystack
- AutoGen (Microsoft)(Python) →
/docs/integrations/autogen
- Vercel AI SDK(TypeScript) →
/docs/integrations/vercel-ai-sdk

All tiers receive the full unmodified upstream data — the only thing Enterprise adds is pre-built source-URL fields for audit-trail convenience.

Every response preserves the upstream registry's identifiers so any fact can be verified at the government record:

- jurisdiction+company_id→ reconstruct the government URL (e.g.https://find-and-update.company-information.service.gov.uk/company/09446231)
- document_id→ the government's own filing identifier, resolvable back to their portal
- jurisdiction_data→ the raw upstream object with every field name preserved
- Filing documents (XHTML iXBRL / PDF / XBRL) returned as raw bytes — no re-rendering

Enterprise tier pre-synthesisessource_url/registry_url/registry_name/data_license/alternative_urlinto every response for one-click audit-trail in compliance reports.

- Auth: OAuth 2.1 + PKCE, passwordless email magic links, RFC 7591 Dynamic Client Registration. No pre-shared API keys.
- Privacy: OpenRegistry proxies official public-registry data. Beneficial-ownership registers that became access-restricted post-CJEU C-37/20 (DE, ES, IT, NL, LU, AT, MT, PT) are not proxied — the tool returns501 alternative_urlpointing at the statutory gated portal (AML-obliged entities only). We explicitly flag where AML gates block the ownership chain.
- Rate limits: per-user for authenticated traffic, per-IP for anonymous — plus a per-jurisdiction upstream-protection cap shared across all users, to keep OpenRegistry a good citizen with the registries we depend on.

- Hosted app + account management:openregistry.sophymarine.com/account
- Tool capability matrix: calllist_jurisdictionsor visit
openregistry.sophymarine.com/jurisdictions
- Enterprise inquiries / partnerships:
contact@sophymarine.com
- Status + uptime:
openregistry.sophymarine.com/status
- This repois documentation only. The OpenRegistry service implementation is closed-source; raise issues here for theintegration experience(documentation, examples, install flows).

Found a vulnerability? Please emailsecurity@sophymarine.comrather than opening a public issue. SeeSECURITY.mdfor the full reporting policy, scope, and safe-harbor terms.

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.