openregistry
OpenRegistry
Unmodified government company records, live. Cross-border ownership chain walker. 27 national registries.
Above: an AI agent walks the shareholders of Iceland Foods Ltd through 4 UK holding companies — WD FF MIDCO → ICELAND VLNCO → LANNIS → WD FF LIMITED — and surfaces the 8 individuals who actually own the chain (Tarsem Dhaliwal 41.35% as the largest shareholder, Walker family 51.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 27 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 27 jurisdictions to unmask the real person behind any company.
Hosted endpoint: https://openregistry.sophymarine.com/mcp
A platform by Sophymarine.
The 6 pillars
1. Live | Every tool call is a real-time query to the upstream government registry API at the moment you ask. |
2. Direct-to-government | No aggregator, no third-party data warehouse, no nightly scrape. Your AI talks to UK Companies House, France INSEE, German Registerportal, Korean FSS OpenDART directly. |
3. Unmodified + source-linked | Every field name, every status code, every raw filing byte returned verbatim. The registry's own identifiers are preserved so any response traces back to the government record. Enterprise tier adds pre-synthesised |
4. Zero-stale | No cache layer we control can ever go stale. You see an update the moment the government records it. Contrast with commercial data providers that serve 6-24 hour-old snapshots. |
5. Stable | Production-grade reliability, running on Cloudflare Workers' global edge + a warm pool of per-jurisdiction workers for stateful registries. |
6. Cross-border | Chain queries across 27 registries in a single prompt. Walk UK Ltd → LU SARL → KY LP → individual without leaving the conversation. |
Related MCP server: Norwegian Business Registry MCP Server
Ready-to-use skills
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.
# | Skill | Outcome in one prompt |
1 | Full statutory dossier: profile + directors + UBO + shareholders + charges + latest accounts | |
2 ⭐ | Walk the ownership chain across jurisdictions until you reach the real individual | |
3 | Every company a person has run + co-director network | |
4 | Latest statutory accounts as machine-readable XBRL / iXBRL / PDF + key figures | |
5 | Material filings in a window, categorised and flagged | |
6 | Is a name free to register across 10+ countries? | |
7 | Every company in a sector across N jurisdictions, ranked + enriched | |
8 | Flag 1-director + no-accounts + overseas-office shells (AML signal) | |
9 | Detect dissolved-then-reborn fraud patterns (same director, same address) | |
10 | Every CIMA / FCA / BaFin / FSS-licensed regulated entity |
See skills/README.md for the skillpack overview.
Same 10 workflows, also as MCP prompts
Every skill above is also served by the MCP server as a named prompt — so any MCP-compatible client (Claude Desktop, Cursor, Cline, Goose, Zed, …) shows them in its prompt picker without installing skill files. Call prompts/list to discover them, prompts/get to 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.
Connect
Claude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"openregistry": {
"url": "https://openregistry.sophymarine.com/mcp",
"transport": "http"
}
}
}Cursor
Add to ~/.cursor/mcp.json:
{
"mcpServers": {
"openregistry": {
"url": "https://openregistry.sophymarine.com/mcp"
}
}
}Claude Code
claude mcp add --transport http OpenRegistry https://openregistry.sophymarine.com/mcpCline (VS Code)
Settings → Cline → MCP Servers → Add:
{
"openregistry": {
"url": "https://openregistry.sophymarine.com/mcp",
"transport": "streamable-http"
}
}See llms-install.md for automated LLM-driven installs.
Anything else speaking MCP
Streamable HTTP transport per MCP spec 2025-06-18. OAuth 2.1 authorization flow for authenticated tiers (Dynamic Client Registration per RFC 7591 — no API key to paste).
AI agent frameworks (code samples)
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
Tiers
Tier | Price | Rate limit | Cross-border fan-out | Source URLs |
Anonymous | free | 20/min per IP | 3 countries / 60s | identifiers only (URL reconstructable) |
Free (signed in) | free | 30/min per user | 3 countries / 60s | identifiers only |
Pro | $9/mo | 180/min per user | 10 countries / 60s | identifiers only |
Max | $29/mo | 900/min per user | 30 countries / 60s | identifiers only |
Enterprise | contact | 3000/min per user | unlimited |
|
All tiers receive the full unmodified upstream data — the only thing Enterprise adds is pre-built source-URL fields for audit-trail convenience.
Provenance & Auditability
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 portaljurisdiction_data→ the raw upstream object with every field name preservedFiling documents (XHTML iXBRL / PDF / XBRL) returned as raw bytes — no re-rendering
Enterprise tier pre-synthesises source_url / registry_url / registry_name / data_license / alternative_url into every response for one-click audit-trail in compliance reports.
Security and compliance
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 returns
501 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.
Support
Hosted app + account management: openregistry.sophymarine.com/account
Tool capability matrix: call
list_jurisdictionsor visit openregistry.sophymarine.com/jurisdictionsEnterprise inquiries / partnerships: contact@sophymarine.com
Status + uptime: openregistry.sophymarine.com/status
This repo is documentation only. The OpenRegistry service implementation is closed-source; raise issues here for the integration experience (documentation, examples, install flows).
OpenRegistry is a platform by Sophymarine.
© 2026 Sophymarine. OpenRegistry and Sophymarine are trademarks of Sophymarine. Documentation in this repository is published under CC-BY-4.0.
Available Tools
10 toolsfetch_documentFetch documentARead-onlyIdempotentInspect
Read a filing's content by document_id (from list_filings). Filing metadata alone doesn't answer most questions — the numbers and text live inside the document.
RESPONSE SHAPES:
• kind='embedded' (under max_bytes ≈ 20 MB) — returns full bytes_base64, source_url_official (evergreen registry URL), and source_url_direct (short-TTL signed proxy URL). PDFs render as a document block you can read natively.
• kind='resource_link' (oversized) — NO bytes_base64. Returns reason, next_steps, both source URLs, and index_preview {page_count, text_layer, outline_present}. Use get_document_navigation to locate pages, then re-call this tool with pages='N-M' and format='pdf'|'text'|'png' for the content.
CRITICAL: if this tool fails (rate limit, 5xx, timeout), do NOT fill in names / numbers / dates from memory — tell the user what failed and offer retry or source_url_official. Outline titles, previews, and snippets from navigation tools are for LOCATING pages, never for quoting.
source_url_official is auto-resolved from 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.
| Name | Required | Description | Default |
|---|---|---|---|
| jurisdiction | Yes | ISO 3166-1 alpha-2 country code (uppercase). All registries are official government sources. Currently supported: AU, BE, CA, CA-BC, CA-NT, CH, CY, CZ, DE, ES, FI, FR, GB, HK, IE, IM, IS, IT, KR, KY, LI, MC, MX, MY, NL, NO, NZ, PL, RU, TW. Per-country capability, ID format, examples, status mapping, and caveats: call `list_jurisdictions({jurisdiction:'<code>'})`. To find which countries support a specific tool: `list_jurisdictions({supports_tool:'<tool>'})`. | |
| document_id | Yes | Document ID from list_filings; do not synthesize (composite IDs will 404). | |
| format | No | Preferred content type: application/xhtml+xml, application/pdf, application/xml, application/json. Omit to let the adapter pick the most structured option (XHTML > XML > JSON > PDF). | |
| max_bytes | No | Inline-size cutoff. Default ~20 MB. Documents above this return as `kind='resource_link'` — call `get_document_navigation` for them. | |
| fresh | No | Bypass R2 cache. Filings are immutable; rarely needed. | |
| company_id | No | Override; auto-resolved from list_filings side-cache. | |
| transaction_id | No | Override; auto-resolved from list_filings side-cache. | |
| filing_type | No | Override; auto-resolved from list_filings side-cache. | |
| filing_description | No | Override; auto-resolved from list_filings side-cache. |
Output Schema
| Name | Required | Description |
|---|---|---|
| queried_at | Yes | ISO-8601 + Europe/London timezone stamp for when the registry was queried. |
| jurisdiction | No | |
| document_id | No | |
| source_url | No | |
| available_formats | No | |
| chosen_format | No | |
| size_bytes | No | |
| pages | No | |
| bytes_base64 | No | |
| bytes_omitted_reason | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, destructiveHint, idempotentHint, openWorldHint. The description adds detailed response shapes, behavior for oversized documents, and instructions on not quoting from navigation tools. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured with sections and front-loaded purpose. Some redundancy exists, but it remains efficient for the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (9 params, output schema), the description covers error behavior, response types, oversized documents, and usage with sibling tools. The output schema likely documents return values, so no gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, baseline 3. The description adds meaning beyond the schema by explaining the purpose of document_id, the effect of max_bytes, and the role of override parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool reads a filing's content by document_id. It distinguishes itself from siblings like list_filings (metadata) and get_document_navigation (navigation).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use the tool (to get actual content) and provides critical instructions for failure scenarios. It does not explicitly state when not to use it, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_company_profileCompany profileARead-onlyIdempotentInspect
Fetch the structured profile of a company by its registry-specific ID. Returns unified top-level fields (company_id, company_name, status, status_detail, incorporation_date, registered_address) plus raw upstream fields under jurisdiction_data. status is a coarse active/inactive/dissolved/unknown enum; status_detail keeps the registry's native string. registered_address is a flat string; the upstream nested form (when present) stays in jurisdiction_data.
Does not bundle officers / shareholders / filings / charges — call those tools separately. ID format varies per registry; pull company_id from search_companies rather than guessing. For per-country ID format and the full jurisdiction_data field catalogue call list_jurisdictions({jurisdiction:'<CC>'}).
| Name | Required | Description | Default |
|---|---|---|---|
| jurisdiction | Yes | ISO 3166-1 alpha-2 country code (uppercase). All registries are official government sources. Currently supported: AU, BE, CA, CA-BC, CA-NT, CH, CY, CZ, DE, ES, FI, FR, GB, HK, IE, IM, IS, IT, KR, KY, LI, MC, MX, MY, NL, NO, NZ, PL, RU, TW. Per-country capability, ID format, examples, status mapping, and caveats: call `list_jurisdictions({jurisdiction:'<code>'})`. To find which countries support a specific tool: `list_jurisdictions({supports_tool:'<tool>'})`. | |
| company_id | Yes | Registry-specific identifier. Examples: GB '00445790' (8-digit Companies House number, or 'SC123456' for Scotland / 'NI...' / 'OC...' / 'LP...'); NO '923609016' (9-digit); AU 11-digit ABN or 9-digit ACN; FR 9-digit SIREN or 14-digit SIRET; PL 10-digit KRS; CZ 8-digit IČO; FI Y-tunnus '0112038-9'. Call list_jurisdictions for the full per-country format. | |
| include | No | Optional per-country extra fetches; ignored where unsupported. | |
| fresh | No | Bypass cache; call upstream directly. |
Output Schema
| Name | Required | Description |
|---|---|---|
| queried_at | Yes | ISO-8601 + Europe/London timezone stamp for when the registry was queried. |
| jurisdiction | No | |
| company_id | No | |
| company_name | No | |
| status | No | Four-value unified status safe for cross-jurisdiction comparison. |
| status_detail | No | |
| incorporation_date | No | |
| registered_address | No | |
| jurisdiction_data | No | Full original response fields from the upstream registry, field names unchanged. Shape is jurisdiction-specific - see `list_jurisdictions({ jurisdiction: '<CODE>' })`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnlyHint, idempotentHint, openWorldHint), the description adds operational details: explains field split (unified vs. raw), status enum, address flattening, per-country include options, and cache bypass via 'fresh' parameter. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is lengthy but well-structured, front-loading the main purpose and then covering fields, exclusions, and usage tips. Each sentence adds value, though slight condensation could improve conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (4 params, output schema, sibling tools), the description covers all essential aspects: what is returned, what is excluded, how to get related data, parameter usage via cross-tool references, and cache behavior. It is fully complete for an AI agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with already detailed parameter descriptions (e.g., jurisdiction lists countries, company_id gives examples, include describes per-country fetches). The tool description does not significantly enhance these explanations, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'Fetch the structured profile of a company by its registry-specific ID', providing a specific verb and resource. It explicitly distinguishes from siblings by noting what it does not bundle (officers, shareholders, etc.), ensuring clear differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: 'Does not bundle officers / shareholders / filings / charges — call those tools separately.' It also instructs to pull company_id from search_companies and to call list_jurisdictions for per-country details, providing clear context and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_document_metadataDocument metadataARead-onlyIdempotentInspect
Retrieve metadata for a filing document by document_id (from list_filings). Returns available content formats with byte sizes, page count, source URL, creation date. Raw upstream fields preserved under jurisdiction_data. Call this before fetch_document when a document may be large or its format is unknown.
Do NOT construct or guess document_id — some registries use composite IDs that must come from list_filings. Synthesized IDs will 404. Empty available_formats means the body is paywalled or unavailable upstream. Unsupported jurisdictions return 501.
| Name | Required | Description | Default |
|---|---|---|---|
| jurisdiction | Yes | ISO 3166-1 alpha-2 country code (uppercase). All registries are official government sources. Currently supported: AU, BE, CA, CA-BC, CA-NT, CH, CY, CZ, DE, ES, FI, FR, GB, HK, IE, IM, IS, IT, KR, KY, LI, MC, MX, MY, NL, NO, NZ, PL, RU, TW. Per-country capability, ID format, examples, status mapping, and caveats: call `list_jurisdictions({jurisdiction:'<code>'})`. To find which countries support a specific tool: `list_jurisdictions({supports_tool:'<tool>'})`. | |
| document_id | Yes | Document ID from a previous list_filings call; do not synthesize. | |
| fresh | No | Bypass cache. Filings are immutable; rarely needed. |
Output Schema
| Name | Required | Description |
|---|---|---|
| queried_at | Yes | ISO-8601 + Europe/London timezone stamp for when the registry was queried. |
| jurisdiction | No | |
| document_id | No | |
| source_url | No | |
| created_at | No | |
| pages | No | |
| available_formats | No | |
| size_bytes_by_format | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotated readOnlyHint true, destructiveHint false, idempotentHint true, openWorldHint true. Description augments with: raw upstream fields in jurisdiction_data, 404 on synthesized IDs, 501 for unsupported jurisdictions, paywalled body on empty formats. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise, well-structured: purpose first, then usage guidelines, then caveats. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-param tool with output schema and annotations, description covers all critical aspects: purpose, inputs, usage flow, error conditions, and behavioral notes. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage 100%, each parameter has description. Description reinforces document_id origin and jurisdiction support via list_jurisdictions. Adds meaning beyond schema with caveats and context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Explicitly states it retrieves metadata for a filing document by document_id from list_filings. Distinguishes from sibling fetch_document by advising to call this tool first when document may be large or format unknown.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear when-to-use guidance: before fetch_document, when size or format uncertainty. Also gives explicit warnings: do not construct document_id, synthesized IDs will 404, empty formats indicate paywalled content, unsupported jurisdictions return 501.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_officersOfficersARead-onlyIdempotentInspect
Return a company's officers — current directors, secretaries, members, partners, board members, procurists, liquidators, plus historical resignations by default. Each officer has a unified shape (officer_id, name, role, appointed_on, resigned_on, is_active) plus raw upstream fields in jurisdiction_data. Role labels pass through in the registry's native language (e.g. Styremedlem, Předseda představenstva, Président); translate client-side. Birth-date precision varies by registry.
Officer-ID stability varies: corporate officers usually carry the corporate's own company_id; natural persons may carry a synthetic index. Some registries mask names under GDPR — that masking is upstream. Jurisdictions without an officer feed return 501.
| Name | Required | Description | Default |
|---|---|---|---|
| jurisdiction | Yes | ISO 3166-1 alpha-2 country code (uppercase). All registries are official government sources. Currently supported: AU, BE, CA, CA-BC, CA-NT, CH, CY, CZ, DE, ES, FI, FR, GB, HK, IE, IM, IS, IT, KR, KY, LI, MC, MX, MY, NL, NO, NZ, PL, RU, TW. Per-country capability, ID format, examples, status mapping, and caveats: call `list_jurisdictions({jurisdiction:'<code>'})`. To find which countries support a specific tool: `list_jurisdictions({supports_tool:'<tool>'})`. | |
| company_id | Yes | Registry company ID, from search_companies. | |
| include_resigned | No | Include resigned officers. Default true; set false for currently-serving only. | |
| group_by_person | No | CZ only. Dedupe the same person across consecutive appointments (board member → chair → vice-chair) into one entry; appointments list under `jurisdiction_data._appointments[]`. Default false. | |
| fresh | No | Bypass cache; refetch from upstream. |
Output Schema
| Name | Required | Description |
|---|---|---|
| queried_at | Yes | ISO-8601 + Europe/London timezone stamp for when the registry was queried. |
| officers | No | |
| items | No | |
| data | No | Adapter returns a bare array; textResult() wraps under `data`. |
| total_count | No | |
| next_cursor | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations confirm read-only, non-destructive, idempotent behavior. The description adds valuable behavioral details: default include_resigned flag, handling of role labels in native language, birth-date precision variations, corporate officer ID mapping, GDPR masking, and 501 for unsupported jurisdictions. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is moderately sized but efficiently front-loaded with core purpose and key behavioral details. Each sentence adds value, though could be slightly more structured (e.g., bullet points for limitations).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (multiple jurisdictions, officer types, data nuances), the description covers all critical aspects: scope, defaults, language, privacy, id stability, error handling. With full schema coverage, annotations, and an output schema, the description is sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with parameter descriptions. The description adds extra meaning: group_by_person is CZ-only, jurisdiction string refers to full capability via list_jurisdictions, and fresh bypasses cache. This enhances understanding beyond schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns a company's officers including current and historical, with specific roles enumerated. It differentiates the tool's scope from siblings like get_shareholders or search_officers, making purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides usage context like default behavior (include_resigned=true), language handling for role labels, birth-date precision, and id stability. It mentions unsupported jurisdictions returning 501 and directs to list_jurisdictions for details. Lacks explicit when-not-to-use versus siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_filingsFiling historyARead-onlyIdempotentInspect
Return a company's filing history, newest first. Each filing has 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 preserved under jurisdiction_data.
Filter via the optional category. Common normalized values: 'accounts', 'annual-return', 'capital', 'charges', 'confirmation-statement', 'incorporation', 'insolvency', 'liquidation', 'mortgage', 'officers', 'resolution'. Native upstream form codes also accepted.
This tool returns metadata only — call fetch_document on document_id for the actual filing bytes. has_document=false means the body is paywalled or unavailable upstream. Pagination uses limit (default 25, max 1000) plus cursor (GB) or offset (IE). Unsupported jurisdictions return 501; call list_jurisdictions for per-country category values and pagination style.
| Name | Required | Description | Default |
|---|---|---|---|
| jurisdiction | Yes | ISO 3166-1 alpha-2 country code (uppercase). All registries are official government sources. Currently supported: AU, BE, CA, CA-BC, CA-NT, CH, CY, CZ, DE, ES, FI, FR, GB, HK, IE, IM, IS, IT, KR, KY, LI, MC, MX, MY, NL, NO, NZ, PL, RU, TW. Per-country capability, ID format, examples, status mapping, and caveats: call `list_jurisdictions({jurisdiction:'<code>'})`. To find which countries support a specific tool: `list_jurisdictions({supports_tool:'<tool>'})`. | |
| company_id | Yes | Registry-specific company ID. IE accepts an optional '/B' suffix for the business-name register. | |
| category | No | Optional category filter. Use a normalized value or the registry's native form code. Call `list_jurisdictions({jurisdiction:'<CC>'})` for the accepted values per country. | |
| limit | No | Items per page. Default 25. | |
| offset | No | Pagination offset (IE). | |
| cursor | No | Opaque pagination cursor returned as `next_cursor` (GB). Omit for first page. | |
| fresh | No | Bypass cache; refetch from upstream. |
Output Schema
| Name | Required | Description |
|---|---|---|
| queried_at | Yes | ISO-8601 + Europe/London timezone stamp for when the registry was queried. |
| items | No | |
| total_count | No | |
| next_cursor | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses behavioral traits beyond annotations, such as the preservation of raw upstream fields under jurisdiction_data, the meaning of has_document=false (paywalled/unavailable), and the cache-bypass behavior of the fresh parameter. Annotations already declare readOnlyHint, destructiveHint, idempotentHint, and openWorldHint, and the description does not contradict them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with the core purpose. It uses short, informative paragraphs covering response fields, filtering, usage notes, pagination, and error handling. Every sentence adds value without redundancy. It is concise yet comprehensive.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (7 parameters, multiple jurisdictions, pagination, output schema), the description covers all essential aspects: core function, response structure, optional filtering, how to retrieve document bytes, pagination details, error codes, and cache bypass. It references sibling tools for further details, making it complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage, the baseline is 3, but the description adds significant value: it explains the category parameter's normalized vs native values, the pagination parameters (cursor for GB, offset for IE), and the fresh parameter's meaning. It also clarifies the jurisdiction parameter's format and how to get per-country info. This enriches the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns a company's filing history, newest first, specifying the verb 'return' and resource 'filing history'. It distinguishes from sibling tools like fetch_document (actual bytes) and search_companies (search). The description also lists common categories and mentions unsupported jurisdictions, providing a clear purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool (for metadata only) and when not to (call fetch_document for actual filing bytes). It provides guidance on filtering by category, pagination with limit/cursor/offset, and error handling for unsupported jurisdictions. It also directs users to list_jurisdictions for per-country details, offering clear usage guidelines.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_jurisdictionsCountry and tool matrixARead-onlyIdempotentInspect
Per-country reference. Pass EXACTLY ONE of:
• jurisdiction='GB' — registry name + URL, data license, company-ID format with examples, native-to-unified status enum mapping, and the list of tools supported.
• supports_tool='get_officers' — which jurisdictions implement a given tool.
| Name | Required | Description | Default |
|---|---|---|---|
| jurisdiction | No | ISO 3166-1 alpha-2 country code (case-insensitive; CA subdivisions hyphenated like 'CA-BC'). Returns the full per-country schema. Mutually exclusive with `supports_tool`. | |
| supports_tool | No | Tool name (e.g. 'get_officers', 'get_shareholders'). Returns the matrix of which jurisdictions implement this tool. Mutually exclusive with `jurisdiction`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| queried_at | Yes | ISO-8601 + Europe/London timezone stamp for when the registry was queried. |
| jurisdiction | No | Populated in single-country mode: carries the JurisdictionMetadata for the requested country. |
| tool | No | Populated in cross-country support-matrix mode: echoes the tool name that was queried. |
| supported_count | No | |
| supported_in | No | |
| not_supported_count | No | |
| not_supported_in | No | |
| hint | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, non-destructive, idempotent behavior. The description adds value by specifying the detailed return content for each parameter, without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, using bullet-like formatting with backticks. Every sentence is necessary, and the key instruction is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema, the description need not detail return values. It completely explains the two usage modes and their outputs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions. The description adds significant context beyond the schema, listing specifics like registry name, data license, and tool support matrix.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly defines the tool as a per-country reference with two mutually exclusive parameters. It specifies exact outputs for each parameter, distinguishing it from other tools that fetch company data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states to pass exactly one parameter, making usage clear. It does not explicitly mention alternatives, but the context shows it is for metadata lookup, distinct from sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_companiesSearch companiesARead-onlyIdempotentInspect
Search a national company registry by name or keyword. Pass EXACTLY ONE of:
• jurisdiction='GB' - single country, direct.
• jurisdictions=['GB','NO','FR'] - multi-country when you're unsure; the server asks the user to confirm (clients with MCP elicitation) or errors back asking you to ask in chat. Per-tier cap on distinct countries per call: anonymous=3, pro=10, max=30, enterprise=unlimited.
Returns candidates with unified fields (company_id, company_name, status, incorporation_date, registered_address) plus raw upstream jurisdiction_data. For country-specific filters (FR ca_min, CZ czNace, CH canton, etc.) pass the filters object — call list_jurisdictions for the per-country schema.
| Name | Required | Description | Default |
|---|---|---|---|
| jurisdiction | No | ISO 3166-1 alpha-2 country code (uppercase; CA subdivisions hyphenated, e.g. 'CA-BC'). Use this when one country is known. Mutually exclusive with `jurisdictions`. | |
| jurisdictions | No | Array of ISO codes when the country is uncertain. The server asks the user to confirm the list (clients with MCP elicitation) or returns an error so you can ask in chat. Mutually exclusive with `jurisdiction`. | |
| query | No | Company name or keyword. May be empty for FR / IE when searching purely by structured `filters`. AU also accepts structured `key:value` pairs in this field (e.g. 'postcode:2000 type:PUB active:Y'). | |
| limit | No | Max candidates to return (1-250). Default 10. | |
| offset | No | Pagination offset (IE / FR). | |
| filters | No | Country-specific advanced filters. Flat object keyed by the upstream field name (e.g. FR `code_postal` / `ca_min`, CZ `czNace`, CH `canton`, FI `companyForm`, IE `alpha`, IS `vat_number`). Call `list_jurisdictions({jurisdiction:'<CC>'})` for the per-country schema. | |
| fresh | No | Bypass cache; call upstream directly. |
Output Schema
| Name | Required | Description |
|---|---|---|
| queried_at | Yes | ISO-8601 + Europe/London timezone stamp for when the registry was queried. |
| jurisdiction | No | Single-country mode. |
| jurisdictions | No | Multi-country fan-out mode. |
| query | No | |
| count | No | |
| cached_at | No | |
| results | No | Candidate list (single-country key). |
| candidates | No | Candidate list (multi-country fan-out key). |
| per_jurisdiction | No | |
| partial_failures | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnly, idempotent), the description adds behavioral details: fresh parameter bypasses cache, multi-country elicitation, tier limits, and return fields. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with bullet points for options, front-loaded purpose, and every sentence adds value. No fluff; appropriately sized for the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all key aspects: required/optional params, mutual exclusivity, caching, pagination, user confirmation, tier limits, filter delegation, and return fields. Output schema exists, so return value details are handled there.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even with 100% schema coverage, the description adds significant meaning: clarifies mutual exclusivity of jurisdiction/jurisdictions, provides examples for query (e.g., AU key:value pairs), and explains filters as per-country schemas referencing list_jurisdictions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Search a national company registry by name or keyword.' It uses a specific verb (search) and resource (company registry), and distinguishes from sibling tools like search_officers and list_jurisdictions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance on when to use jurisdiction vs jurisdictions, explains user confirmation for multi-country, mentions per-tier caps, and directs to list_jurisdictions for country-specific filters. This covers when to use and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_officersSearch officers by nameARead-onlyIdempotentInspect
Find people holding or who held officer positions (director, secretary, member, partner) in a jurisdiction's registry by name. Returns candidates with officer_id, name, and (where exposed) appointment count. Entry point for person-centric investigations.
| Name | Required | Description | Default |
|---|---|---|---|
| jurisdiction | Yes | ISO 3166-1 alpha-2 country code (uppercase). All registries are official government sources. Currently supported: AU, BE, CA, CA-BC, CA-NT, CH, CY, CZ, DE, ES, FI, FR, GB, HK, IE, IM, IS, IT, KR, KY, LI, MC, MX, MY, NL, NO, NZ, PL, RU, TW. Per-country capability, ID format, examples, status mapping, and caveats: call `list_jurisdictions({jurisdiction:'<code>'})`. To find which countries support a specific tool: `list_jurisdictions({supports_tool:'<tool>'})`. | |
| query | Yes | Officer name. Full names work best ('John Smith'). Partial names return more candidates. | |
| limit | No | Max officer candidates to return. Range 1-100, default 20. |
Output Schema
| Name | Required | Description |
|---|---|---|
| queried_at | Yes | ISO-8601 + Europe/London timezone stamp for when the registry was queried. |
| jurisdiction | No | |
| query | No | |
| count | No | |
| officers | No | |
| data | No | Adapters returning a bare array are wrapped here by textResult(). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as read-only, non-destructive, and idempotent. The description adds value by specifying the return structure ('candidates with officer_id, name, and (where exposed) appointment count') and directing users to list_jurisdictions for per-country details. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the core action, and no redundant words. Every sentence provides value: first sentence defines purpose, second clarifies output and usage context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity (3 params, output schema, annotations), the description adequately covers purpose, output structure, and provides a usage hint. It references additional resources (list_jurisdictions) for completeness. Could be slightly more explicit about error or edge cases, but overall sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All three parameters are fully documented in the schema (100% coverage). The description adds useful context for the jurisdiction parameter, listing supported countries and referencing list_jurisdictions for more details, which goes beyond the schema's description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Find people holding or who held officer positions... by name' and specifies officer types (director, secretary, member, partner). It also positions the tool as an 'Entry point for person-centric investigations,' distinguishing it from sibling tools like get_officers which are company-centric.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for person-centric investigations but does not explicitly state when not to use this tool or provide direct alternatives. For example, it doesn't mention that get_officers should be used for officers of a known company.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
27 tool updates
v1.0.4- Removed
about - Removed
check_name_availability - Removed
count_companies - Changed
fetch_document8 fields changed- changed
Input schema / properties / company_id / descriptionPrevious value: -"OVERRIDE (rare use). Normally auto-resolved from the list_filings side-cache. Only pass this when invoking fetch_document on a document_id that did NOT come through list_filings in this session."New value: +"Override; auto-resolved from list_filings side-cache." - added
Input schema / properties / document_id / descriptionAdded value: +"Document ID from list_filings; do not synthesize (composite IDs will 404)." - changed
Input schema / properties / filing_description / descriptionPrevious value: -"OVERRIDE (rare use). Normally auto-resolved."New value: +"Override; auto-resolved from list_filings side-cache." - changed
Input schema / properties / filing_type / descriptionPrevious value: -"OVERRIDE (rare use). Normally auto-resolved. Pass only to override the cached value."New value: +"Override; auto-resolved from list_filings side-cache." - changed
Input schema / properties / format / descriptionPrevious value: -"Optional preferred content type. Common: application/xhtml+xml, application/pdf, application/xml, application/json. Omit to let the adapter choose the most structured format available (recommended — XHTML > XML > JSON > PDF)."New value: +"Preferred content type: application/xhtml+xml, application/pdf, application/xml, application/json. Omit to let the adapter pick the most structured option (XHTML > XML > JSON > PDF)." - changed
Input schema / properties / fresh / descriptionPrevious value: -"Set true to bypass the R2 cache and re-fetch from upstream. Use sparingly — CH filings are immutable, the cache is safe."New value: +"Bypass R2 cache. Filings are immutable; rarely needed." - changed
Input schema / properties / max_bytes / descriptionPrevious value: -"Optional inline-size cutoff. Defaults to ~20 MB. Documents above this come back as kind='resource_link' (use navigation tools). Raising this is NOT the right way to read a big PDF — use fetch_document_pages instead."New value: +"Inline-size cutoff. Default ~20 MB. Documents above this return as `kind='resource_link'` — call `get_document_navigation` for them." - changed
Input schema / properties / transaction_id / descriptionPrevious value: -"OVERRIDE (rare use). Normally auto-resolved from the list_filings side-cache. Pass only to override the cache."New value: +"Override; auto-resolved from list_filings side-cache."
- Removed
fetch_document_pages - Removed
get_charges - Removed
get_code_description - Changed
get_company_profile7 fields changed- changed
Input schema / properties / company_id / descriptionPrevious value: -"Registry-specific company identifier. GB: 8-digit Companies House number (e.g. '00445790'), or SC/NI/OC/LP prefix (e.g. 'SC123456'). NO: 9-digit organisation number (e.g. '923609016'). AU: 11-digit ABN (e.g. '16009661901') or 9-digit ACN (e.g. '009661901'). IE: numeric (e.g. '104547'); add '/B' suffix to query the business-name register (e.g. '540274/B'). FR: 9-digit SIREN (e.g. '652014051') or 14-digit SIRET (auto-resolved to parent SIREN). FI: Y-tunnus '7digits-1digit' (e.g. '0112038-9'); 8-digit no-dash form auto-reformatted. CZ: 8-digit IČO (e.g. '27074358'); 1-7 digit values auto-padded. PL: 10-digit KRS number (e.g. '0000635012'); 1-9 digit values auto-padded. See the tool description for full details."New value: +"Registry-specific identifier. Examples: GB '00445790' (8-digit Companies House number, or 'SC123456' for Scotland / 'NI...' / 'OC...' / 'LP...'); NO '923609016' (9-digit); AU 11-digit ABN or 9-digit ACN; FR 9-digit SIREN or 14-digit SIRET; PL 10-digit KRS; CZ 8-digit IČO; FI Y-tunnus '0112038-9'. Call list_jurisdictions for the full per-country format." - changed
Input schema / properties / fresh / descriptionPrevious value: -"Bypass cache. Default false."New value: +"Bypass cache; call upstream directly." - added
Input schema / properties / includeAdded value: +{ + "additionalProperties": false, + "description": "Optional per-country extra fetches; ignored where unsupported.", + "properties": { + "establishments": { + "description": "BE only. Graft the vestiginglijst (establishment-units list) onto jurisdiction_data.establishments[].", + "type": "boolean" + }, + "history": { + "description": "PL only. Graft the full /OdpisPelny historical entry log (every recorded change) onto jurisdiction_data.", + "type": "boolean" + }, + "vr": { + "description": "CZ only. Merge the VR (commercial register) record under jurisdiction_data._vr — case file, share-capital history, registered activities, insolvency, public-register type.", + "type": "boolean" + } + }, + "type": "object" +} - removed
Input schema / properties / include_establishmentsRemoved value: -{ - "default": false, - "description": "BE only. When true, ALSO fetch the vestiginglijst (establishment-units list) and graft it onto jurisdiction_data.establishments[] — each unit's 10-digit vestigingsnummer, status, start date, name, and address. One extra upstream call; omit to just get the count + establishments_list_url.", - "type": "boolean" -} - removed
Input schema / properties / include_historyRemoved value: -{ - "default": false, - "description": "PL only. When true, ALSO fetch /OdpisPelny and graft the full historical entry log (naglowekP.wpis[] — every change ever made to the KRS record, with numerWpisu / opis / dataWpisu / sygnaturaAktSprawyDotyczacejWpisu) onto jurisdiction_data. Doubles upstream calls.", - "type": "boolean" -} - removed
Input schema / properties / include_vrRemoved value: -{ - "default": false, - "description": "CZ only. When true, also fetch the VR (commercial register) record and merge it under jurisdiction_data._vr — adds spisovaZnacka (case file number array; use latest by datumZapisu), zakladniKapital (share capital history with vklad/splaceni), akcie (share emissions), cinnosti (registered business activities), insolvence + konkursy (insolvency proceedings — full records, not just the administrators surfaced via get_officers), rejstrik (public-register type), stavSubjektu. Slower than the basic profile (one extra upstream call) but avoids needing get_officers/PSC/charges just to inspect these fields.", - "type": "boolean" -} - changed
Output schema / properties / jurisdiction_data / descriptionPrevious value: -"Full original response fields from the upstream registry, field names unchanged. Shape is jurisdiction-specific — see `list_jurisdictions({ jurisdiction: '<CODE>' })`."New value: +"Full original response fields from the upstream registry, field names unchanged. Shape is jurisdiction-specific - see `list_jurisdictions({ jurisdiction: '<CODE>' })`."
- Changed
get_document_metadata2 fields changed- changed
Input schema / properties / document_id / descriptionPrevious value: -"Document ID from a previous list_filings call."New value: +"Document ID from a previous list_filings call; do not synthesize." - added
Input schema / properties / fresh / descriptionAdded value: +"Bypass cache. Filings are immutable; rarely needed."
- Changed
get_document_navigation4 fields changed- changed
Input schema / properties / company_id / descriptionPrevious value: -"OVERRIDE (rare use). Normally auto-resolved from the list_filings side-cache."New value: +"Override; auto-resolved from list_filings side-cache." - added
Input schema / properties / document_id / descriptionAdded value: +"Document ID from list_filings; document must already be cached via fetch_document." - changed
Input schema / properties / fresh / descriptionPrevious value: -"Set true to ignore the cached index.json and re-run pdfjs against the stored source bytes. Does not re-pull from upstream."New value: +"Re-run pdfjs against the cached bytes (does not re-pull from upstream)." - changed
Input schema / properties / transaction_id / descriptionPrevious value: -"OVERRIDE (rare use). Normally auto-resolved."New value: +"Override; auto-resolved from list_filings side-cache."
- Removed
get_financials - Removed
get_officer_appointments - Changed
get_officers5 fields changed- added
Input schema / properties / company_id / descriptionAdded value: +"Registry company ID, from search_companies." - added
Input schema / properties / fresh / descriptionAdded value: +"Bypass cache; refetch from upstream." - changed
Input schema / properties / group_by_person / descriptionPrevious value: -"CZ only. When true, dedupe the same person across multiple appointments (e.g. board member → chair → vice-chair) into a single entry. Identity key is (name + datumNarozeni for natural persons, or pravnickaOsoba.ico for corporate). Each grouped entry's jurisdiction_data._appointments[] lists all roles with their dates. Default false (returns one entry per appointment, matching GB behaviour)."New value: +"CZ only. Dedupe the same person across consecutive appointments (board member → chair → vice-chair) into one entry; appointments list under `jurisdiction_data._appointments[]`. Default false." - changed
Input schema / properties / include_resigned / descriptionPrevious value: -"Include officers who have resigned. Default true. Set to false to get only currently serving officers."New value: +"Include resigned officers. Default true; set false for currently-serving only." - changed
Output schema / properties / officers / items / properties / jurisdiction_data / descriptionPrevious value: -"Full original response fields from the upstream registry, field names unchanged. Shape is jurisdiction-specific — see `list_jurisdictions({ jurisdiction: '<CODE>' })`."New value: +"Full original response fields from the upstream registry, field names unchanged. Shape is jurisdiction-specific - see `list_jurisdictions({ jurisdiction: '<CODE>' })`."
- Removed
get_persons_with_significant_control - Changed
get_shareholders2 fields changed- added
Input schema / properties / company_id / descriptionAdded value: +"Registry company ID, from search_companies." - added
Input schema / properties / fresh / descriptionAdded value: +"Bypass cache; refetch from upstream."
- Removed
get_specialised_record - Removed
list_actos_inscritos - Removed
list_change_batches - Removed
list_establishments - Changed
list_filings5 fields changed- changed
Input schema / properties / category / descriptionPrevious value: -"Optional filter on standardized category. GB: native Companies House category strings. IE: 'accounts'|'annual-return'|'capital'|'charges'|'incorporation'|'insolvency'|'officers'|'prospectus'|'registered-office'|'resolution'. IM: 'annual-return'|'articles'|'memorandum'|'incorporation'|'name-change'|'officers'|'resolution'|'charges' (mapped to upstream AR/AA/MA/INC/CCN/9N/RES/CRS; pass the raw upstream code directly for any other IoM document type). IS: 'annual-return'|'incorporation'|'articles'|'supplementary-notice'|'other', or the Icelandic column names ('Stofngögn'/'Samþykktir'/'Aukatilkynningar'/'Önnur gögn'), or the raw numeric typeid (1/4/5/6/7)."New value: +"Optional category filter. Use a normalized value or the registry's native form code. Call `list_jurisdictions({jurisdiction:'<CC>'})` for the accepted values per country." - changed
Input schema / properties / cursor / descriptionPrevious value: -"GB only. Opaque pagination cursor returned by a previous call as 'next_cursor'. Omit for the first page."New value: +"Opaque pagination cursor returned as `next_cursor` (GB). Omit for first page." - added
Input schema / properties / fresh / descriptionAdded value: +"Bypass cache; refetch from upstream." - changed
Input schema / properties / offset / descriptionPrevious value: -"IE only. Skip the first N filings (pagination). Combine with limit."New value: +"Pagination offset (IE)." - changed
Output schema / properties / items / items / properties / jurisdiction_data / descriptionPrevious value: -"Full original response fields from the upstream registry, field names unchanged. Shape is jurisdiction-specific — see `list_jurisdictions({ jurisdiction: '<CODE>' })`."New value: +"Full original response fields from the upstream registry, field names unchanged. Shape is jurisdiction-specific - see `list_jurisdictions({ jurisdiction: '<CODE>' })`."
- Changed
list_jurisdictions1 field changed- changed
Input schema / properties / supports_tool / descriptionPrevious value: -"Tool name (e.g. 'get_officers', 'get_persons_with_significant_control'). Returns the matrix of which jurisdictions implement this tool. Mutually exclusive with `jurisdiction`."New value: +"Tool name (e.g. 'get_officers', 'get_shareholders'). Returns the matrix of which jurisdictions implement this tool. Mutually exclusive with `jurisdiction`."
- Removed
search_addresses - Changed
search_companies64 fields changed- removed
Input schema / properties / activeOnlyRemoved value: -{ - "description": "CH only. If true, returns only ACTIVE companies (excludes CANCELLED and BEING_CANCELLED).", - "type": "boolean" -} - removed
Input schema / properties / activite_principaleRemoved value: -{ - "description": "FR / FR-near-point only. NAF/APE industry code (e.g. '64.20Z').", - "type": "string" -} - removed
Input schema / properties / addressRemoved value: -{ - "description": "Registered-address substring filter. IE: free-text substring of the company address. IS: prefix of the 'heimili' field on Skatturinn's /leit form (upstream accepts a single word or street prefix; Icelandic-dative form when searching by street name).", - "type": "string" -} - removed
Input schema / properties / alphaRemoved value: -{ - "description": "IE only. Alphabetic prefix filter on the company name.", - "type": "string" -} - removed
Input schema / properties / bus_indRemoved value: -{ - "description": "IE only. Which CRO register to search: 'C' = companies (default), 'B' = business names, 'E' = both (slowest).", - "enum": [ - "C", - "B", - "E" - ], - "type": "string" -} - removed
Input schema / properties / ca_maxRemoved value: -{ - "description": "FR only. Maximum chiffre d'affaires (revenue) in EUR.", - "type": "number" -} - removed
Input schema / properties / ca_minRemoved value: -{ - "description": "FR only. Minimum chiffre d'affaires (revenue) in EUR.", - "type": "number" -} - removed
Input schema / properties / cantonRemoved value: -{ - "description": "CH only. 2-letter canton abbreviation (ZH / BE / GE / VD / VS / TI / ...). Mutually exclusive with registryOfCommerceId or legalSeatId.", - "maxLength": 2, - "minLength": 2, - "type": "string" -} - removed
Input schema / properties / categorie_entrepriseRemoved value: -{ - "description": "FR only. Company size category.", - "enum": [ - "PME", - "ETI", - "GE" - ], - "type": "string" -} - removed
Input schema / properties / code_communeRemoved value: -{ - "description": "FR only. INSEE commune code.", - "type": "string" -} - removed
Input schema / properties / code_postalRemoved value: -{ - "description": "FR only. 5-digit French postal code (e.g. '75001'). Note: filters companies whose ANY establishment is at this postcode — the company's siège social may be elsewhere. Check `jurisdiction_data.matching_etablissements` to see which establishment matched.", - "type": "string" -} - removed
Input schema / properties / companyFormRemoved value: -{ - "description": "FI only. Company form code: OYJ (public Ltd), OY (private Ltd), KY (limited partnership), AY (partnership), OK (cooperative), SÄÄ (foundation), AOY (housing company), etc.", - "type": "string" -} - removed
Input schema / properties / czNaceRemoved value: -{ - "anyOf": [ - { - "pattern": "^([0-9]{5}|[A-U])$", - "type": "string" - }, - { - "items": { - "pattern": "^([0-9]{5}|[A-U])$", - "type": "string" - }, - "type": "array" - } - ], - "description": "CZ only. NACE industry code(s). ARES requires 5-DIGIT or single-LETTER form: 5 digits for sub-class (e.g. '62010' programming), single letter A-U for the section (e.g. 'G' wholesale & retail). 4-digit (class) or 2-digit (division) values are rejected by zod — they would otherwise silently return 0 results from ARES. Filtering by section alone usually exceeds the >1000 cap; combine with another filter." -} - removed
Input schema / properties / date_naissance_personne_maxRemoved value: -{ - "description": "FR only. Maximum birth date of a person (YYYY-MM-DD).", - "type": "string" -} - removed
Input schema / properties / date_naissance_personne_minRemoved value: -{ - "description": "FR only. Minimum birth date of a person (YYYY-MM-DD).", - "type": "string" -} - removed
Input schema / properties / departementRemoved value: -{ - "description": "FR only. 2-3 digit department code (e.g. '75', '971').", - "type": "string" -} - removed
Input schema / properties / epciRemoved value: -{ - "description": "FR only. EPCI (intermunicipal grouping) SIREN.", - "type": "string" -} - removed
Input schema / properties / est_associationRemoved value: -{ - "description": "FR only. Only entities registered as associations (RNA).", - "type": "boolean" -} - removed
Input schema / properties / est_bioRemoved value: -{ - "description": "FR only. Only Agence Bio certified establishments.", - "type": "boolean" -} - removed
Input schema / properties / est_collectivite_territorialeRemoved value: -{ - "description": "FR only. Only territorial collectivities.", - "type": "boolean" -} - removed
Input schema / properties / est_entrepreneur_individuelRemoved value: -{ - "description": "FR only. Only sole traders.", - "type": "boolean" -} - removed
Input schema / properties / est_essRemoved value: -{ - "description": "FR only. Only social/solidarity-economy entities.", - "type": "boolean" -} - removed
Input schema / properties / est_organisme_formationRemoved value: -{ - "description": "FR only. Only training organisations.", - "type": "boolean" -} - removed
Input schema / properties / est_qualiopiRemoved value: -{ - "description": "FR only. Only Qualiopi-certified training organisations.", - "type": "boolean" -} - removed
Input schema / properties / est_rgeRemoved value: -{ - "description": "FR only. Only RGE (environmental) certified.", - "type": "boolean" -} - removed
Input schema / properties / est_service_publicRemoved value: -{ - "description": "FR only. Only public-service entities.", - "type": "boolean" -} - removed
Input schema / properties / est_societe_missionRemoved value: -{ - "description": "FR only. Only mission-driven companies.", - "type": "boolean" -} - removed
Input schema / properties / etat_administratifRemoved value: -{ - "description": "FR only. 'A'=active, 'C'=ceased. Note: the establishment-level 'F'=Fermé state appears in the data but is NOT a valid filter value upstream — use 'C' for closed entities.", - "enum": [ - "A", - "C" - ], - "type": "string" -} - added
Input schema / properties / filtersAdded value: +{ + "additionalProperties": {}, + "description": "Country-specific advanced filters. Flat object keyed by the upstream field name (e.g. FR `code_postal` / `ca_min`, CZ `czNace`, CH `canton`, FI `companyForm`, IE `alpha`, IS `vat_number`). Call `list_jurisdictions({jurisdiction:'<CC>'})` for the per-country schema.", + "type": "object" +} - removed
Input schema / properties / financniUradRemoved value: -{ - "anyOf": [ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } - ], - "description": "CZ only. Tax-office code(s) — see FinancniUrad code-list." -} - removed
Input schema / properties / force_name_searchRemoved value: -{ - "description": "IS only. When true, treats the query as a plain name search even if it happens to be a 10-digit string (otherwise the adapter treats 10 digits as a kennitala direct-lookup).", - "type": "boolean" -} - changed
Input schema / properties / fresh / descriptionPrevious value: -"Bypass the search cache and call upstream registries directly. Default false."New value: +"Bypass cache; call upstream directly." - removed
Input schema / properties / icoRemoved value: -{ - "anyOf": [ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } - ], - "description": "CZ only. One or more exact IČO values to look up." -} - removed
Input schema / properties / include_business_namesRemoved value: -{ - "description": "IE only. Convenience flag — when true, sets bus_ind='E' to search both registers.", - "type": "boolean" -} - changed
Input schema / properties / jurisdiction / descriptionPrevious value: -"EXACTLY ONE of `jurisdiction` or `jurisdictions` must be provided. Use `jurisdiction` (singular) when the user has clearly specified ONE country — a direct lookup, no confirmation screen shown. ISO 3166-1 alpha-2 country code. Supported values: 'GB', 'NO', 'AU', 'IE', 'FR', 'FI', 'CZ', 'PL', 'CA', 'CA-BC', 'CA-NT', 'BE', 'IM', 'IS', 'CY', 'CH', 'TW', 'LI', 'DE', 'NZ', 'NL', 'MC', 'IT', 'RU'. Use the exact uppercase code (ISO-3166-2 hyphenated form for CA subdivisions)."New value: +"ISO 3166-1 alpha-2 country code (uppercase; CA subdivisions hyphenated, e.g. 'CA-BC'). Use this when one country is known. Mutually exclusive with `jurisdictions`." - changed
Input schema / properties / jurisdictions / descriptionPrevious value: -"EXACTLY ONE of `jurisdiction` or `jurisdictions` must be provided. Use `jurisdictions` (plural) when you are UNCERTAIN which country the company is in and want to search multiple candidates. Pass an array of 2–N ISO codes representing your best guesses based on company name / domain / user hints. The server will SHOW THE USER your picks in a confirmation dialog (on clients that support it — Claude Desktop, Claude Code, Cursor, and new Gemini CLI) and let them edit before running any search. On clients without that support, the call returns an error telling you to ask the user in chat. Per-tier caps on how many countries can be searched in one call: anonymous/free=3, pro=10, max=30, enterprise=unlimited. If you pass more than the user's cap, the confirmation form will trim to the cap."New value: +"Array of ISO codes when the country is uncertain. The server asks the user to confirm the list (clients with MCP elicitation) or returns an error so you can ask in chat. Mutually exclusive with `jurisdiction`." - removed
Input schema / properties / legalFormIdRemoved value: -{ - "description": "CH only. Internal legal-form ID (1-999). Use get_code_description(CH, legalForm) to discover codes. Example: 9 = Aktiengesellschaft (AG).", - "maximum": 999, - "minimum": 1, - "type": "integer" -} - removed
Input schema / properties / legalFormUidRemoved value: -{ - "description": "CH only. Public legal-form code per eCH-0097 data standard (4 chars). Example: '0106' = AG, '0108' = Sàrl. Alternative to legalFormId.", - "maxLength": 4, - "minLength": 4, - "type": "string" -} - removed
Input schema / properties / legalSeatIdRemoved value: -{ - "description": "CH only. BFS commune number of the legal seat. Use get_code_description(CH, community) to discover. Example: 261 = Zurich city. Mutually exclusive with registryOfCommerceId or canton.", - "type": "integer" -} - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum candidates to return (1-250). Default 10. Per-jurisdiction upstream caps: GB 100, NO 1000, AU 200, IE 250."New value: +"Max candidates to return (1-250). Default 10." - removed
Input schema / properties / locationRemoved value: -{ - "description": "FI only. Town or city name (any of FI/SV/EN names match).", - "type": "string" -} - removed
Input schema / properties / mainBusinessLineRemoved value: -{ - "description": "FI only. Statistics Finland TOL 2008 industry code (e.g. '6201') or text.", - "type": "string" -} - removed
Input schema / properties / match_typeRemoved value: -{ - "description": "IE only. Match strategy for the company_name parameter. 'exact' is fastest (~300ms), 'starts_with' moderate, 'contains' slowest (~3s) — default contains.", - "enum": [ - "exact", - "starts_with", - "contains" - ], - "type": "string" -} - removed
Input schema / properties / nature_juridiqueRemoved value: -{ - "description": "FR only. Legal-form code (INSEE).", - "type": "string" -} - removed
Input schema / properties / nom_personneRemoved value: -{ - "description": "FR only. Surname of a dirigeant or elected official to filter by.", - "type": "string" -} - changed
Input schema / properties / offset / descriptionPrevious value: -"IE / FR only. Skip the first N results (pagination). CRO caps each page at 250; FR at 25. Combine with limit to walk large result sets."New value: +"Pagination offset (IE / FR)." - removed
Input schema / properties / pageRemoved value: -{ - "description": "FI only. Page number (1-indexed). PRH paginates with `page` not offset.", - "minimum": 1, - "type": "integer" -} - removed
Input schema / properties / postCodeRemoved value: -{ - "description": "FI only. 5-digit Finnish postcode.", - "type": "string" -} - removed
Input schema / properties / pravniFormaRemoved value: -{ - "anyOf": [ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } - ], - "description": "CZ only. Legal-form code(s) — see PravniForma code-list (e.g. '112'=s.r.o./LLC, '121'=a.s./joint-stock, '100'=sole trader). Use get_code_description for the full list." -} - removed
Input schema / properties / pravniFormaRosRemoved value: -{ - "anyOf": [ - { - "type": "string" - }, - { - "items": { - "type": "string" - }, - "type": "array" - } - ], - "description": "CZ only. Legal-form code(s) from the ROS public-registers source — usually equivalent to pravniForma." -} - removed
Input schema / properties / prenoms_personneRemoved value: -{ - "description": "FR only. Given name(s) of a dirigeant/elected official.", - "type": "string" -} - changed
Input schema / properties / query / descriptionPrevious value: -"Company name or keyword. May be EMPTY for FR/IE when you're searching purely by structured filters (e.g. code_postal + ca_min for FR; address + alpha for IE). For AU only, also accepts structured filter syntax: space-separated key:value pairs such as 'postcode:2000 type:PUB active:Y' or 'charity:Y state:NSW postcode:2000'. All other jurisdictions use plain name search."New value: +"Company name or keyword. May be empty for FR / IE when searching purely by structured `filters`. AU also accepts structured `key:value` pairs in this field (e.g. 'postcode:2000 type:PUB active:Y')." - removed
Input schema / properties / regionRemoved value: -{ - "description": "FR only. 2-digit region code.", - "type": "string" -} - removed
Input schema / properties / registrationDateEndRemoved value: -{ - "description": "FI only. Filter companies registered on/before this date (YYYY-MM-DD).", - "type": "string" -} - removed
Input schema / properties / registrationDateStartRemoved value: -{ - "description": "FI only. Filter companies registered on/after this date (YYYY-MM-DD).", - "type": "string" -} - removed
Input schema / properties / registryOfCommerceIdRemoved value: -{ - "description": "CH only. Internal office number of the cantonal registry of commerce. Use get_code_description(CH, registryOfCommerce) to discover. Example: 20 = Zurich. Mutually exclusive with legalSeatId or canton.", - "type": "integer" -} - removed
Input schema / properties / resultat_net_maxRemoved value: -{ - "description": "FR only. Maximum résultat net in EUR.", - "type": "number" -} - removed
Input schema / properties / resultat_net_minRemoved value: -{ - "description": "FR only. Minimum résultat net (net profit) in EUR (can be negative).", - "type": "number" -} - removed
Input schema / properties / section_activite_principaleRemoved value: -{ - "description": "FR only. Single-letter NAF section A-U.", - "type": "string" -} - removed
Input schema / properties / sidloRemoved value: -{ - "additionalProperties": false, - "description": "CZ only. Registered-office address filter. Full ARES AdresaFiltr schema supported — use structured RÚIAN codes (kodObce/kodUlice/...) when you have them for exact matches, or free-text (obec/ulice/psc/textovaAdresa) for fuzzy searches. Resolve text to codes via the search_addresses tool.", - "properties": { - "cisloDomovni": { - "description": "House number (before the slash).", - "maximum": 9999, - "minimum": 0, - "type": "integer" - }, - "cisloOrientacni": { - "description": "Orientation number (after the slash).", - "maximum": 999, - "minimum": 0, - "type": "integer" - }, - "cisloOrientacniPismeno": { - "description": "Orientation number letter suffix.", - "maxLength": 1, - "type": "string" - }, - "kodCastiObce": { - "description": "RÚIAN district code within municipality.", - "maximum": 999999, - "minimum": 0, - "type": "integer" - }, - "kodMestskeCastiObvodu": { - "description": "City district code for statutory cities.", - "maximum": 999999, - "minimum": 0, - "type": "integer" - }, - "kodObce": { - "description": "RÚIAN municipality code (authoritative).", - "maximum": 999999, - "minimum": 0, - "type": "integer" - }, - "kodSpravnihoObvodu": { - "description": "Prague admin district code.", - "maximum": 999, - "minimum": 0, - "type": "integer" - }, - "kodUlice": { - "description": "RÚIAN street code.", - "maximum": 9999999, - "minimum": 0, - "type": "integer" - }, - "obec": { - "description": "Municipality name (free-text, e.g. 'Praha').", - "type": "string" - }, - "psc": { - "description": "Postal code (5 digits, optional space).", - "type": "string" - }, - "textovaAdresa": { - "description": "Unstructured full-text address (overrides free-text obec/psc/ulice).", - "type": "string" - }, - "ulice": { - "description": "Street name (free-text).", - "type": "string" - } - }, - "type": "object" -} - removed
Input schema / properties / tranche_effectif_salarieRemoved value: -{ - "description": "FR only. INSEE employee-count band code.", - "type": "string" -} - removed
Input schema / properties / type_personneRemoved value: -{ - "description": "FR only. Restrict person filter to officers or elected officials.", - "enum": [ - "dirigeant", - "elu" - ], - "type": "string" -} - removed
Input schema / properties / vat_numberRemoved value: -{ - "description": "IS only. Icelandic VSK-númer (VAT number). Usually 5–6 digits (e.g. '11459'). Skatturinn's upstream /leit form redirects a VSK hit straight to the company profile; the adapter surfaces this as a single-candidate result.", - "type": "string" -} - changed
Output schema / properties / results / items / properties / jurisdiction_data / descriptionPrevious value: -"Full original response fields from the upstream registry, field names unchanged. Shape is jurisdiction-specific — see `list_jurisdictions({ jurisdiction: '<CODE>' })`."New value: +"Full original response fields from the upstream registry, field names unchanged. Shape is jurisdiction-specific - see `list_jurisdictions({ jurisdiction: '<CODE>' })`."
- Removed
search_companies_near_point - Removed
search_document - Changed
search_officers2 fields changed- added
Input schema / properties / limit / descriptionAdded value: +"Max officer candidates to return. Range 1-100, default 20." - changed
Output schema / properties / officers / items / properties / jurisdiction_data / descriptionPrevious value: -"Full original response fields from the upstream registry, field names unchanged. Shape is jurisdiction-specific — see `list_jurisdictions({ jurisdiction: '<CODE>' })`."New value: +"Full original response fields from the upstream registry, field names unchanged. Shape is jurisdiction-specific - see `list_jurisdictions({ jurisdiction: '<CODE>' })`."
- Removed
search_specialised_records
27 tool updates
v1.0.3- First observed
about - First observed
check_name_availability - First observed
count_companies - First observed
fetch_document - First observed
fetch_document_pages - First observed
get_charges - First observed
get_code_description - First observed
get_company_profile - First observed
get_document_metadata - First observed
get_document_navigation - First observed
get_financials - First observed
get_officer_appointments - First observed
get_officers - First observed
get_persons_with_significant_control - First observed
get_shareholders - First observed
get_specialised_record - First observed
list_actos_inscritos - First observed
list_change_batches - First observed
list_establishments - First observed
list_filings - First observed
list_jurisdictions - First observed
search_addresses - First observed
search_companies - First observed
search_companies_near_point - First observed
search_document - First observed
search_officers - First observed
search_specialised_records
TDQS
Scored across 10 tools
Each tool has a uniquely defined purpose: filings, documents, company profile, officers, shareholders, jurisdictions, and search. No overlap in functionality; descriptions clearly differentiate their roles.
All tool names follow a consistent verb_noun pattern (e.g., fetch_document, get_company_profile, list_filings) using lowercase snake_case throughout, ensuring predictability.
With 10 tools covering search, retrieval, metadata, navigation, and reference for company registry data, the count is well-scoped and appropriate for the domain.
The tool set covers the full read lifecycle: searching companies, listing filings, fetching documents with metadata and navigation, and retrieving officers and shareholders. Gaps like beneficial owners are acknowledged as separate, making the surface complete for its purpose.
Maintenance
Related MCP Connectors
UBO, sanctions & ownership graph. 23 tools, 130.7M entities, 31 registries.
Global B2B intelligence for AI agents: 35M+ companies, 1.6M sanctions, KYB pack. 78 tools.
US public-records intelligence for AI agents — companies, SEC, courts, spending, licenses.
French & European company registry for AI agents: KYB, sanctions, annual accounts. x402, no API key.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables mapping JavaScript error stack traces back to original source code, extracting context information to help developers locate and fix issues.344 npm2MIT
- AlicenseBqualityDmaintenanceEnables comprehensive access to the Norwegian Business Registry API for querying company information, board members, subsidiaries, organizational data, and voluntary organizations. Provides real-time access to over 1 million registered Norwegian entities with detailed corporate structure and governance data.154 npm8MIT
- AlicenseAqualityDmaintenanceProvides access to a suite of Nordic data tools covering Danish business records, addresses, weather, and energy prices, alongside Norwegian and Finnish company information. This unified server enables users to query public APIs for regional data across Denmark, Norway, and Finland without requiring individual API keys.335 npm2MIT
- FlicenseBqualityDmaintenanceAn MCP adapter that maps Coffee Company B2B HTTP APIs to MCP tools, allowing AI agents to query member information, benefits, coupons, and payment statuses. It enables seamless integration for AI assistants to manage coffee-related customer assets and loyalty details through natural language.101-