The five-call cross-border KYB workflow — walking a UBO chain across jurisdictions in a single prompt
KYB ("Know Your Business") used to mean "pull a company report and check the directors." That stopped being enough around the time the FATF revised Recommendation 24 in March 2022 and AMLD5 transposition deadlines started biting. A modern KYB review for a counterparty of any meaningful size has to:
- Identify the legal entity in the jurisdiction it claims to be incorporated in,
- Identify everyone who owns more than 25 % (or controls via voting / appointment / contract),
- Walk through any corporate layer above that — because step 2 will almost always return another company rather than a human,
- Repeat until you reach a natural person, a listed issuer, a state, or a bona-fide statutory exception,
- Cite the registry of record at every hop so the audit trail survives a regulatory review.
That last point is what breaks every "we have a company-data API" SaaS: the moment the counterparty is in a different jurisdiction from your aggregator's strongest coverage, you start joining records the aggregator opined about rather than records the government asserted. When the FCA / FinCEN / BaFin auditor asks "where did this PSC entry come from?" the answer needs to be a registry URL, not "BvD says".
The rest of this post walks through the canonical five-call cross-border KYB workflow, what it looks like in practice on a real UK→Holdco chain, and the eight EU registers that will currently — post-CJEU C-37/20 — return a structured 501 regardless of which vendor you query.
This is the workflow OpenRegistry was built to serve: 27 national company registries behind one MCP endpoint, byte-identical responses, source-linked, no aggregator layer between the AI agent and the statutory record.
Why "look up the company in country X" doesn't generalize
Every KYB SaaS does step 1 reasonably well in its strongest jurisdictions. Steps 2 → 5 are where the wheels come off:
- Step 2 (PSC / UBO layer) — Every member state of the EU plus the UK has its own legal definition of "beneficial owner," its own threshold (25 % is most common but Cyprus uses 10 %, Estonia uses "any control"), its own filing window, and its own access regime. Post CJEU C-37/20 (2022), eight EU UBO registers became AML-obliged-only — meaning no commercial vendor can legally republish them.
- Step 3 (corporate-layer recursion) — When the PSC of a UK Ltd is a Luxembourg SARL, you have left the British Companies House schema and entered the Luxembourg RCS schema. These have different identifier formats, different officer-role enumerations, different statuses. Aggregators paper over this with their own canonical schema; that paper covers the gap that gets you in trouble at audit.
- Step 4 (terminating in a natural person) — In the UK 80 %+ of PSC chains terminate in 1-2 hops. In Luxembourg, Cayman, BVI, Jersey, Liechtenstein it's routinely 4-6 hops, sometimes through a trust that legally has no UBO at all.
-
Step 5 (citing the registry) — Aggregators almost universally strip the upstream URL because it's how they justify their licensing. If you can't link to
https://find-and-update.company-information.service.gov.uk/company/01107406/persons-with-significant-controlon your KYB report, your audit trail is "we trust our vendor."
The five-call workflow below assumes you have direct, byte-identical access to the registry of record at every step. With that assumption, the workflow becomes mechanical and the AI agent can run it without supervision.
The canonical five-call workflow
This is the prompt-time tool sequence an AI agent runs against the OpenRegistry MCP endpoint for every cross-border KYB:
1. search_companies({ jurisdiction, query, limit: 5 })
→ resolve the legal name to a registry-issued company_id
2. get_company_profile({ jurisdiction, company_id })
→ registered office, status, incorporation date, officers (where included)
3. get_persons_with_significant_control({ jurisdiction, company_id })
→ the PSC / UBO / beneficial-owner layer, with type=individual|corporate|trust
4. for each PSC of type 'corporate' or 'trust':
→ recurse from step 1 with the PSC's jurisdiction + name (or registry id if printed)
5. fetch_document({ document_id })
→ the statutory filing that backs the assertion (Confirmation Statement,
Comptes annuels, Jahresabschluss, opinion of independent registrar, etc.)
That's the full agent loop. Five calls, recursing on step 4 until the chain terminates in a natural person, a state actor, a listed issuer, or a structured 501 (the statutory wall — more on those below).
The cross-border part is what eats most KYB SaaS implementations: each recursion of step 4 hops to a different national registry with a different schema, different identifier format, different language. Hand-stitching this in a SaaS UI takes an analyst 30-90 minutes per counterparty. With a unified MCP gateway and a halfway-decent AI client, the same chain runs in ~30 seconds.
Worked example — Iceland Foods Ltd → Iceland Topco Limited → individuals
Let's run it on a real, public, legally-trivial UK chain. Iceland Foods Ltd is a UK private company; its PSCs trace through three corporate layers before reaching individuals. The full walked example with raw JSON is on the OpenRegistry Iceland Foods cross-border chain walk — what follows is the abridged structural view.
Step 1 — resolve the legal name
{
"tool": "search_companies",
"args": { "jurisdiction": "GB", "query": "Iceland Foods Ltd", "limit": 3 }
}
The first hit returns company_id: "01107406", status active, incorporated 1973-04-26. We have a stable identifier.
Step 2 — pull the profile
{
"tool": "get_company_profile",
"args": { "jurisdiction": "GB", "company_id": "01107406" }
}
This returns the full Companies House profile — registered office, accounts category (group, full), confirmation-statement date, SIC codes, and the officers array. The schema is exactly Companies House's; nothing is renamed or merged.
Step 3 — pull the PSC layer
{
"tool": "get_persons_with_significant_control",
"args": { "jurisdiction": "GB", "company_id": "01107406" }
}
The response gives us the registered PSCs. For Iceland Foods Ltd this is one corporate PSC: Iceland Topco Limited, Companies House 08723490, "ownership of shares 75 % or more, voting rights 75 % or more." That's a corporate PSC — we recurse.
Step 4 — recurse on the corporate PSC
{
"tool": "get_persons_with_significant_control",
"args": { "jurisdiction": "GB", "company_id": "08723490" }
}
Iceland Topco's PSCs are themselves four individuals — Sir Malcolm Walker, Tarsem Dhaliwal, Andrew Pritchard, Nigel Broadhurst — each declaring "ownership of shares more than 25 % but not more than 50 %" or similar. We've terminated in natural persons after one recursion.
Step 5 — fetch the statutory backing document
{
"tool": "list_filings",
"args": { "jurisdiction": "GB", "company_id": "08723490", "category": "confirmation-statement" }
}
Pick the most recent confirmation-statement filing, then:
{
"tool": "fetch_document",
"args": { "document_id": "<from list_filings>", "max_bytes": 5000000 }
}
This returns the literal XHTML iXBRL bytes of the filing — not a vendor's parsed extract. Your AI agent can quote the actual filed text in the audit-trail report, and the report links to https://find-and-update.company-information.service.gov.uk/company/08723490/filing-history/<id> so the auditor can verify independently.
Five calls, three of them recursive on step 4. This is the entire KYB workflow for that chain.
A real-world chain that crosses borders — say a UK Ltd whose PSC is a Luxembourg SARL whose PSC is a Cayman LP whose ultimate beneficial owner is an individual in a third country — runs the same loop, just more iterations, with each recursion hitting a different national registry through the same MCP interface.
The eight EU UBO registers that will return 501
Post CJEU C-37/20 (Luxembourg Business Registers, November 2022), public access to UBO registers in the EU was found to violate Article 7 and 8 of the Charter of Fundamental Rights. The court did not abolish UBO transparency — it required a "legitimate-interest" gating layer for non-AML-obliged requesters. Implementation has been jurisdiction-by-jurisdiction and the result is that as of today the following UBO registers are not publicly queryable, and no company-data vendor can legally proxy them:
- Germany — Transparenzregister, AML-obliged-only since 2022-11-22, BMF guidance updates ongoing
- Spain — Registro de Titulares Reales (RETIR), Ley 6/2023 transposition gates access at the AML-obliged level
- Italy — Registro dei titolari effettivi, Consiglio di Stato 2024-10 referred C-37/20 + C-601/20 back to CJEU; currently frozen
- Netherlands — UBO-register, post-2022 access scheme limited to obliged entities
- Luxembourg — RBE, the register at the centre of C-37/20 itself
- Austria — WiEReG, AML-obliged-only since 2023
- Malta — BORM, restricted access regime
- Portugal — RCBE, AML-obliged-only since 2023
Plus, outside the EU but on the same trajectory:
- Cayman Islands — Beneficial Ownership Transparency Act 2023; "legitimate-interest access" only (CI$250/year application fee + CI$75/search; reaffirmed 2026 against UK pressure)
- Hong Kong — SCR (Significant Controllers Register) is filed at the company's registered office, not centrally queryable
- Malaysia — Section 56 Companies Act 2016 BO register is reporting-institution-only
When an AI agent calls get_persons_with_significant_control for one of these jurisdictions, OpenRegistry returns a structured 501 Not Implemented with alternative_url pointing at the legitimate-interest application page (where one exists) and reason carrying the legal citation. That structured response is the right answer — pretending to have the data when you legally cannot is the wrong answer.
PSC / shareholder layers that are publicly queryable (and thus walkable end-to-end through OpenRegistry today): UK, Ireland, Iceland, Norway, France (RNE / RBE since 2024 partial reopen), Belgium, Cyprus, Isle of Man, Liechtenstein (Vollauszug, paid tier), Monaco, plus the non-UBO shareholder layers in Czechia, Switzerland, Taiwan, South Korea (top shareholder + 5 %+ disclosure).
The split matters because a KYB workflow that cannot tell apart "no UBO record found" from "UBO record exists but is statutorily gated" is a workflow that will silently approve every counterparty operating out of one of those eight EU jurisdictions.
Why MCP-native delivery matters for KYB-as-an-LLM-task
The five-call workflow above is a recursive graph traversal with conditional document fetches. That class of task is what LLMs are now reliably good at — with one caveat: the LLM has to be able to invoke the tools without leaving the conversation.
Pre-MCP, plugging a company-registry API into an AI agent meant either (a) writing a custom tool wrapper for every framework (LangChain, CrewAI, AutoGen, the assistant-builder du jour), or (b) putting the LLM in front of a UI and letting it click. Both add a 200-2000 ms latency floor per call and a maintenance burden per framework.
MCP (Model Context Protocol, the spec Anthropic, OpenAI and Google CLIs all consume natively) collapses that — a single endpoint URL drops into a Claude Desktop / Cursor / Claude Code / Gemini CLI config and the agent has all 14 tools available. No SDK install, no API key (for anonymous tier), no per-framework adapter.
For KYB specifically that means:
- The search_companies → get_company_profile → get_persons_with_significant_control → recurse → fetch_document loop runs as a single agent prompt rather than five UI button-clicks.
- The audit log is the MCP transcript — every tool call with its arguments and the registry's actual response — which is structurally what auditors want anyway.
- Cross-jurisdictional recursion is a parameter swap (
jurisdiction: "GB"→jurisdiction: "LU") rather than a vendor swap. The loop body is identical.
If you're building KYB tooling that bills itself as "AI-native," this is the integration shape that delivers what that phrase implies. See the full KYB & UBO solution page for the productised version, including pricing tiers, fan-out caps, and source-provenance fields on the enterprise tier.
Plugging it into a real KYB pipeline
A few patterns we've seen work in production deployments:
- Async pre-fetch on counterparty intake. When the sales / onboarding system creates a "potential customer" record with a legal name + jurisdiction, fire the five-call workflow asynchronously. By the time the human reviewer opens the case, the PSC chain is already walked, the documents are already cached, and the analyst is reviewing rather than fetching. Median analyst time per case drops from 45 minutes to 8 minutes in our walked benchmarks.
-
Periodic re-walks for high-risk counterparties. PSC entries change. UK Companies House's
confirmation-statementfiling is annual but PSC notifications are real-time; Brønnøysundregistrene pushes daily deltas. Schedule a weekly re-walk for any counterparty above your AML risk threshold and diff against the previous walk; surface only the deltas to the analyst. -
Hard
501handling. When the workflow hits an AML-gated UBO register, the only correct programmatic response is to flag the case for human review with the structuredalternative_urlfrom the response. Soft-failing (e.g., assuming "no UBO" because the register is gated) is the auditor's first finding. -
Document fetch is the last call, not the first. A surprising amount of KYB tooling fetches every filing of a company "just in case." It's a waste —
list_filingsreturns metadata cheaply, you fetch the one document the PSC trace actually needs, and you stay well below the upstream-registry rate-limit ceilings.
Coverage today
- 27 national registries live: GB, IE, NO, FI, FR, BE, IS, IM, CH, CY, MC, LI, DE, NL (KVK), CZ, PL, LU (search-only), AU, NZ, TW, KR (OpenDART), HK, MY, ID, IN, ES (BORME), IT (BRIS), CA (federal + BC + NT), US (NY + CA), MX, RU, KY (CIMA + general register).
- Free anonymous tier (20 req/min/IP), free signed-in tier, paid tiers for higher fan-out and source-provenance fields.
- Connect from Claude Desktop / Cursor / Claude Code / Gemini CLI with a single line of config:
{
"mcpServers": {
"openregistry": {
"url": "https://openregistry.sophymarine.com/mcp"
}
}
}
Or via Claude Code:
claude mcp add --transport http openregistry https://openregistry.sophymarine.com/mcp
The KYB-specific landing page with the full source-provenance matrix, jurisdiction-by-jurisdiction PSC availability, and the productised five-call workflow is at openregistry.sophymarine.com/solutions/kyb. Free to evaluate, no signup required for the anonymous tier.
If you're building cross-border KYB tooling on top of LLMs, the five-call loop is the bit you want to get right first. The rest — data quality, jurisdiction coverage, statutory gating — is what the gateway is for.
Top comments (0)