nordic-data
Server Details
Company, KYB, VAT, sanctions, LEI and address data for 15 EU countries.
- Status
- Healthy
- Uptime
- 100.0% over 38 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- Mnymann/nordic-data-mcp
- GitHub Stars
- 1
- Server Listing
- nordic-data-mcp
TDQS
Scored across 11 tools
Most tools target distinct resources (address, VAT, LEI, sanctions, French history), but lookup_company, company_enriched, and kyb_full all return overlapping company registry data; the descriptions clarify the differences well enough to avoid serious misselection.
The dominant verb_noun pattern (lookup_company, validate_vat, list_endpoints, screen_sanctions) is clear and consistent. Minor deviations like company_enriched and fr_history break the pattern slightly but remain readable and predictable.
Eleven tools is well within the ideal 3-15 range and matches the server's broad but focused purpose: Nordic/EU company data, VAT, sanctions, LEI, address, and API discovery. Each tool earns its place, including the three discovery meta-tools.
The tool surface covers the core read-only data needs of the domain: basic lookup, enriched stats, full KYB, VAT validation, sanctions screening, LEI resolution, and address autocomplete. The list_endpoints/call_endpoint pair additionally exposes 230+ endpoints, so there are no significant coverage gaps.
Available Tools
11 toolsautocomplete_addressARead-onlyIdempotentInspect
Address autocomplete with coordinates. Sources: DAWA (DK, official address register), Kartverket/Geonorge (NO, official), BAN (FR, official Base Adresse Nationale), and OpenStreetMap Nominatim (SE, FI). Returns ranked address suggestions with lat/lng and a match confidence. Supports 5 countries: DK, NO, SE, FI, FR.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Partial address — street name, postcode, city, or any combination. Min 2 characters. | |
| country | Yes | ISO 3166-1 alpha-2 country code, lowercase. Only dk, no, se, fi and fr are supported. |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | No | Ranked address candidates, best match first. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, covering the safety profile. The description adds valuable context beyond annotations: the specific official sources (DAWA, Kartverket, BAN, Nominatim) and the output structure (ranked suggestions with lat/lng and confidence). This enriches the agent's understanding without contradiction.
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 with no wasted words. It front-loads the core purpose ('Address autocomplete with coordinates'), then lists sources and return details efficiently. Every sentence earns its place.
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 (which covers return values), the description sufficiently covers purpose, sources, supported countries, and output highlights. Nothing critical is missing for an agent to call this tool correctly. The tool is simple and the description is 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 description coverage is 100%, and both parameters (query and country) have clear descriptions in the schema. The tool description reiterates the supported countries but adds no new parameter-specific semantics beyond what the schema already provides. Baseline 3 is appropriate given full coverage.
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 a specific verb (autocomplete) and resource (addresses), and explicitly lists the data sources and supported countries. It is unambiguous and distinct from any sibling tool, none of which handle address autocomplete.
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 makes it clear this is the tool for address autocomplete in DK, NO, SE, FI, and FR, and that it returns ranked suggestions with coordinates. It does not explicitly mention alternatives, but no sibling tool competes for this use case, so the context is sufficient without exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
call_endpointARead-onlyIdempotentInspect
Discovery meta-tool. Executes a read-only HTTP request against the Nordic Data API for any data endpoint discovered via list_endpoints, and returns the response. Authenticates with the same scoped API key as the curated tools. Strictly read-only: only GET/HEAD requests are permitted, plus POST to three allowlisted screening endpoints (/api/sanctions/screen, /api/adverse/screen, /api/peps/nl/screen) that are pure queries using POST only to carry a large request body. All state-changing operations (watch lists, webhooks, DELETE/PUT/PATCH) and all /admin endpoints are refused. Use list_endpoints and get_endpoint_schema first to find the correct path, method, and parameters.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Concrete endpoint path, e.g. '/api/company/dk/22756214'. Path templates with {placeholders} are also accepted when you supply the values in `params`. | |
| method | No | HTTP method to use. Read-only methods only: GET or HEAD, plus POST solely for the allowlisted screening query endpoints (/api/sanctions/screen, /api/adverse/screen, /api/peps/nl/screen). Defaults to GET. | GET |
| params | No | Parameters for the call. Values whose keys match {placeholders} in the path are substituted into the path. Remaining values become query-string params for GET/DELETE, or the JSON request body for POST/PUT/PATCH. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, destructiveHint=false, and idempotentHint=true, so the safety profile is well covered. The description adds valuable context beyond these: the specific allowlist of three POST screening endpoints, the refusal of all state-changing operations and /admin endpoints, and the scoped authentication detail. It explains the unusual behavior that POST is permitted only for three specific pure-query endpoints. Minor gap: doesn't describe error/refusal response format or rate-limit behavior, but the added context genuinely enhances the 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 a dense, well-structured paragraph covering purpose, constraints, authentication, and usage flow in a single block. Every sentence contributes meaningful information: the read-only scope, the POST allowlist rationale ('pure queries using POST only to carry a large request body'), the refusal list, and the discovery workflow. It's more verbose than the minimal ideal but earns its length given the complexity of the constraints. Could be slightly tightened but is appropriately front-loaded with purpose.
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 this is an open-ended, discovery-oriented tool with no output schema, the description provides substantial completeness: it covers authentication, allowed methods, the specific POST allowlist, refused operations, and the associated discovery tools. The nuanced constraint handling (path placeholders, query-string vs request-body semantics) is captured in both schema and description. It doesn't detail pagination or error handling for the response, but for a generic endpoint-call tool with strong annotations and full schema coverage, this is adequately 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 description coverage is 100%, so the schema already explains all three parameters thoroughly (path with placeholder substitution, method with read-only constraints and defaults, params with URL substitution vs query-string/body semantics). The description adds the relationship to list_endpoints/get_endpoint_schema discovery flow and the allowlist constraint, which supplements rather than repeats the schema. Baseline 3 is appropriate since schema carries the heavy lifting and the description adds minor selection-context value.
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 identifies this as a read-only HTTP client for the Nordic Data API, specifying the verb (execute a request) and resource (data endpoints discovered via list_endpoints). It distinguishes from curated siblings by emphasizing its generic/discovery nature: 'any data endpoint discovered via list_endpoints'. However, it doesn't explicitly name sibling alternatives like get_endpoint_schema or list_endpoints in the purpose statement itself, and the contrast with curated tools is implicit rather than naming them.
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?
Excellent usage guidance: explicitly instructs 'Use list_endpoints and get_endpoint_schema first to find the correct path, method, and parameters.' Clearly differentiates from curated tools by noting it 'Authenticates with the same scoped API key as the curated tools,' implied that one would use this only when curated tools don't cover the endpoint. Also gives explicit exclusions: all state-changing operations (watch lists, webhooks, DELETE/PUT/PATCH) and /admin endpoints are refused.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
company_enrichedARead-onlyIdempotentInspect
Company registry data plus national industry statistics in one call. Returns company (same shape as lookup_company) and industryStats — a time series from the national statistics office for the company's industry code (currently Danmarks Statistik for DK); industryStats.available is false when no statistics exist. Supports 4 countries: DK, NO, SE, FI. For other countries use lookup_company (basic registry data) or kyb_full (full due-diligence report).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | National company identifier — same format as lookup_company. | |
| country | Yes | ISO 3166-1 alpha-2 country code, lowercase. Only dk, no, se and fi are supported. |
Output Schema
| Name | Required | Description |
|---|---|---|
| company | No | Registry data — same shape as lookup_company output. |
| industryStats | No | National industry statistics (DST for DK, SSB for NO, etc.). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive, and the description adds further behavior: it returns a company object plus an industryStats time series, with industryStats.available false when no statistics exist, and names the data source (Danmarks Statistik for DK). 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?
The description is dense but every clause earns its place: core promise, return shape, edge-case flag, data source, country scope, and fallback routing. It remains readable and 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 output schema and complete parameter schema, the description provides enough extra context for correct invocation: country constraints, id format reference, the availability flag, and alternatives for unsupported countries. Nothing critical is omitted.
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%, but the description still adds value: it clarifies id uses the same format as lookup_company and explains the country enum values are lowercase codes for DK/NO/SE/FI only. This supplements the schema rather than repeating it.
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 opens with a specific verb/resource: 'Company registry data plus national industry statistics in one call.' It clearly distinguishes itself from siblings by naming lookup_company and kyb_full as fallbacks for other countries, so an agent can tell what this tool adds.
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?
It explicitly states the supported countries (DK, NO, SE, FI) and instructs: 'For other countries use lookup_company (basic registry data) or kyb_full (full due-diligence report).' This gives both when-to-use and when-not-to-use guidance with named alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fr_historyARead-onlyIdempotentInspect
French company history timeline. Returns one event per change to the company's name, activity (NAF code), status (active/closed), legal form, or social-economy flag, derived from INSEE Sirene 3.11's bitemporal periodesUniteLegale array. Includes 'initial:' events that show the state at company creation (date, name, NAF code, etc.). Input: 9-digit SIREN number. Cost: 1 quota unit; free tier supported (France is not tier-gated, unlike NL and DE). Cache: 24h server-side. Errors: 400 invalid_id_format (not 9 digits), 403 non_diffusible (SIREN exists but is privacy-protected under art. R123-232-1), 404 not_found, 503 upstream_unavailable.
| Name | Required | Description | Default |
|---|---|---|---|
| siren | Yes | 9-digit French SIREN number. Examples: 652014051 (Carrefour), 775670417 (LVMH). No spaces or punctuation. |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | No | Number of history events derived. |
| sigle | No | Acronym / short name, if any. |
| siren | No | 9-digit SIREN echoed back. |
| events | No | Chronologically ordered events. Each event has 'initial:<field>' type for the baseline period or a plain field name for subsequent changes. |
| source | No | Upstream data source — 'api.insee.fr'. |
| fetchedAt | No | ISO-8601 timestamp when the data was fetched upstream. |
| sourceNote | No | Provenance note describing the upstream API and field set used. |
| periodCount | No | Number of bitemporal periods returned by INSEE. |
| dateCreation | No | ISO-8601 date the legal entity was created. |
| categorieEntreprise | No | INSEE company size category: PME, ETI, GE. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnly, openWorld, idempotent, and non-destructive. The description adds concrete behavioral details: quota cost (1 unit), 24h server-side cache, and a breakdown of four error conditions with their triggers (invalid ID, privacy-protected, not found, upstream unavailable). It also reveals the internal bitemporal derivation and initial events, going far beyond annotation coverage.
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 dense but well-structured: purpose and event types are front-loaded, then input, cost, cache, and error conditions follow in a logical order. Every sentence conveys a distinct operational detail (quota, free tier, errors) and none are wasted.
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 that output schema exists, the description covers the necessary input requirements, data scope, error semantics, caching, cost, and notifies the agent about free tier availability. This is complete enough for an agent to decide to use the tool and handle failure modes—nothing necessary is missing.
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?
The input schema has 100% description coverage, including pattern, format, and examples for the 'siren' parameter. The description's one-line 'Input: 9-digit SIREN number' adds no extra semantic information or operational nuance beyond what the schema already provides.
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: 'French company history timeline' and enumerates exactly which events are returned (name, activity, status, legal form, social-economy flag) and the data source (INSEE Sirene bitemporal periodesUniteLegale). This distinguishes it from sibling tools like lookup_company that provide current snapshots.
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 makes clear that the tool is for France and SIREN input, mentions the free tier and the 'unlike NL and DE' comparison, which implies geographic restriction. However, it does not explicitly name alternative tools or state 'when not to use this'. The usage guidance is clear but lacks an explicit exclusionary statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_endpoint_schemaARead-onlyIdempotentInspect
Discovery meta-tool. Returns the full parameter and response schema for a single Nordic Data API endpoint (path + method), read from the backend's live OpenAPI spec with $refs resolved inline. Use after list_endpoints to learn exactly which parameters an endpoint takes before calling it with call_endpoint. Admin endpoints are rejected.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Endpoint path from list_endpoints, e.g. '/api/company/{country}/{id}'. Concrete paths like '/api/company/dk/22756214' are also accepted. | |
| method | No | HTTP method for the endpoint (e.g. GET, POST). Defaults to GET. Must be a method the endpoint actually defines. | GET |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint, it reveals that data is read from the 'backend's live OpenAPI spec with $refs resolved inline' and that admin endpoints are rejected. This adds meaningful behavioral context about data source, processing, and restrictions that annotations do not capture.
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?
Two sentences, front-loaded with the core purpose and followed by concise usage guidance. Every word earns its place with no 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 meta-tool, the description is complete: it states what it returns, where data comes from, when to use it, and an exclusion. Combined with the rich annotations and schema, it leaves no major 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 description coverage is 100%, with path and method already documented with examples and defaults. The description does not add parameter-level detail beyond what the schema provides, so the 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 opens with 'Discovery meta-tool' and clearly states it 'Returns the full parameter and response schema for a single Nordic Data API endpoint (path + method)'. The verb is specific and the resource is well-defined, distinguishing it from siblings like list_endpoints and call_endpoint.
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?
Explicitly instructs to 'Use after list_endpoints to learn exactly which parameters an endpoint takes before calling it with call_endpoint', providing clear sequencing and placing it between list and call operations. Also notes that admin endpoints are rejected, which is a usage constraint.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kyb_fullARead-onlyIdempotentInspect
Run before a consequential decision — onboarding a counterparty, approving a payment, extending credit, or signing a contract. Full Know-Your-Business master report for a company across 15 EU countries (DK, NO, SE, FI, IE, UK, FR, DE, CZ, PL, LV, EE, NL, BE, LU). Aggregates 9 sections: identity, registered address (geocoded), key persons & directors, financial statements, official filings, LEI + corporate ownership, VAT registration, sanctions + PEP screening, adverse media (GDELT 2.0), and a composite risk score. Single call. Cold cache typically completes in 10-15s; warm cache returns in <100ms. Cached 6h on success, 60s when partial. Partial responses: if any of the 9 sections time out, the report still returns with 'truncated: true' and 'sectionsUnavailable: [{section, reason}]' — caller can retry in 60s for a complete report. Tier note: NL and DE use paid upstream registries — free-tier API keys receive HTTP 402 'upgrade_required'; do NOT retry on 402. On paid tiers, NL costs 5x quota and DE costs 3x. Disclaimer: this report is informational decision-support aggregated from official and public sources — NOT legal, compliance, or financial advice and not a definitive determination. The risk score and findings indicate areas to verify, not verdicts; the response includes a 'disclaimer' field stating this.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | National company identifier — same format as lookup_company (e.g. DK CVR 8 digits, NO orgnr 9 digits). | |
| country | Yes | ISO 3166-1 alpha-2 country code, lowercase. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly/idempotent/non-destructive, and the description dramatically extends this with rich behavioral disclosures: cold vs warm cache timing, 6h/60s cache policies, partial response structure ('truncated: true', 'sectionsUnavailable'), the 402 upgrade_required retry warning, and quota costs for NL/DE. It also adds a legal disclaimer clarifying the report is informational, not a definitive determination.
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 content is information-dense and valuable, but it's a single large paragraph covering many distinct concerns (purpose, performance, caching, partial responses, tier caveats, legal disclaimer) with no structural separation. Front-loading is good (opens with use cases), but a long block of text is harder for an agent to parse than a structured or bulleted layout.
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?
This is a complex, high-consequence tool with no output schema, so the description carries the full burden — and it meets it comprehensively: 9 sections enumerated, country list, performance expectations, partial-response handling, retry semantics, tier-specific costs, and legal framing. Every ambiguity an agent might face is addressed.
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% — both id and country already carry descriptive text (with format hints like 'CVR 8 digits' and enum values). The description adds the reference to lookup_company for the id format, which adds a small cross-tool tie-in, but mostly the schema handles parameters. Baseline 3 is appropriate since the description doesn't add significant param semantics beyond schema coverage.
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 opens with a concrete use-case framing ('Run before a consequential decision...') and specifies the exact output ('Full Know-Your-Business master report') with country scope and a detailed list of the 9 aggregated sections. It clearly distinguishes from siblings like lookup_company, screen_sanctions, and validate_vat by covering the full composite report across 15 countries.
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 ('before onboarding a counterparty, approving a payment, extending credit, signing a contract'), covers caching behavior, partial-response retry semantics, and includes a crucial tier note (NL/DE paid registries, do NOT retry on 402). This gives the agent strong decision guidance on when the tool is appropriate and what pitfalls to avoid.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_endpointsARead-onlyIdempotentInspect
Discovery meta-tool. Lists ALL available Nordic Data API data endpoints (HTTP method, path, short description) by reading the backend's live OpenAPI spec at runtime — far beyond the curated high-level tools. Use this to discover capabilities the dedicated tools do not cover, then call get_endpoint_schema for parameter details and call_endpoint to execute one. Only read-only operations are listed (GET/HEAD plus the POST screening queries); admin and state-changing endpoints are never returned. Supports an optional search keyword filter. The catalog has 230+ endpoints.
| Name | Required | Description | Default |
|---|---|---|---|
| search | No | Optional case-insensitive keyword filter, matched against each endpoint's path, summary, and tags. Examples: 'sanction', 'address', 'cvr', 'history', 'vat', 'lei'. Omit to list every available data endpoint. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description reveals key behavioral traits: it reads a live OpenAPI spec at runtime, covers only read-only operations (GET/HEAD plus POST screening queries), never returns admin/state-changing endpoints, and notes the catalog has 230+ endpoints. This adds substantial value beyond the annotations about the tool's runtime behavior and coverage boundaries.
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?
Four dense sentences with zero waste — every sentence earns its place. The purpose, usage workflow, behavioral boundary (read-only only), and catalog size are all conveyed efficiently. Front-loaded with the purpose verb in the first word.
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 this is a discovery meta-tool with a single optional parameter and no output schema, the description is fully complete. It discloses the runtime mechanism (live OpenAPI read), the coverage boundary (read-only only, 230+ endpoints), and the full follow-up workflow with named sibling tools. No information gap for the agent to fill.
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%, so the schema fully documents the search parameter and its matching semantics. While the description doesn't add much beyond the schema (it mentions the filter exists), it does note case-insensitivity is covered by schema, and use of the search parameter is contextualized in the discovery workflow. This is at or slightly above baseline.
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 uses a specific verb ('Lists') with a clear resource ('ALL available Nordic Data API data endpoints') and scope ('HTTP method, path, short description'). It explicitly distinguishes from the curated high-level tools and names sibling tools (get_endpoint_schema, call_endpoint) as follow-up actions, making this a distinct discovery meta-tool.
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?
Explicit guidance states when to use it ('discover capabilities the dedicated tools do not cover') and when not to use it (admin/state-changing endpoints never returned). It also provides a clear workflow chain: call get_endpoint_schema for params, call_endpoint to execute. The search filter examples ('sanction', 'address', 'cvr') give concrete usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_companyARead-onlyIdempotentInspect
Call before onboarding a supplier or customer to confirm the legal entity exists and is active. Look up basic company data (name, address, status, industry, VAT registration, founding date) from official European business registries. Supports 15 countries: DK (CVR), NO (Brønnøysund), SE (Bolagsverket), FI (YTJ/PRH), IE (CRO), UK (Companies House), FR (INSEE Sirene), DE (Handelsregister), CZ (ARES), PL (KAS+KRS), LV (Uzņēmumu reģistrs), EE (Ariregister), NL (KvK), BE (KBO), LU (RCSL). Tier note: NL and DE use paid upstream registries (KvK and Handelsregister). Free-tier API keys will receive HTTP 402 with error 'upgrade_required' — do NOT retry on 402; the error message includes an upgrade URL. On paid tiers, NL calls cost 5x quota units and DE calls cost 3x; all other countries cost 1x.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | National company identifier. DK=CVR (8 digits), NO=orgnr (9), SE=orgnr (10), FI=Y-tunnus (NNNNNNN-D), IE=CRO (1-7), UK=8 chars, FR=SIREN (9), DE=HRB number, CZ=IČO (8), PL=NIP (10) or KRS (10), LV=11 digits, EE=8 digits, NL=KvK (8 digits), BE=BCE/KBO (10 digits), LU=RCSL (B + digits). | |
| country | Yes | ISO 3166-1 alpha-2 country code, lowercase. One of: dk, no, se, fi, ie, uk, fr, de, cz, pl, lv, ee, nl, be, lu. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | National company identifier. |
| name | No | Registered legal name. |
| source | No | Upstream registry name (CVR, Brønnøysund, etc.). |
| status | No | Registry status, e.g. active, dissolved, bankrupt. |
| address | No | Registered address: an object ({street, city, zip}) or a single formatted string, depending on the registry. |
| country | No | Country code or name as returned by the source registry. |
| founded | No | ISO-8601 founding date, if known. |
| industry | No | Industry classification ({code, description}; NACE or national code). |
| fetchedAt | No | ISO-8601 timestamp when the data was fetched upstream. |
| legalForm | No | Legal form: an object ({code, description}) or a string, depending on the registry. |
| vatRegistered | No | Whether the company is VAT-registered, where the registry reports it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description discloses the 402 'upgrade_required' failure mode, instructs not to retry on 402, and quantifies quota consumption (NL 5x, DE 3x, others 1x). This is actionable behavioral detail the schema and annotations don't provide.
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 front-loaded with the trigger and then lays out countries, then tier/error behavior in a logical order. The country list partly repeats the schema enum, but it's not padded; every section adds operational 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?
With an output schema present and read-only/idempotent annotations, the description covers the key operational aspects: use case, country coverage, failure/retry behavior, and quota impact. No essential information for calling the tool correctly is missing.
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%, so the baseline is 3; the description adds the country-specific quota costs (NL/DE premium tiers), which is meaningful semantics for choosing among country values. It doesn't add id-format detail, but that's already in the schema.
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 names a specific verb ('look up'), a concrete resource ('legal entity ... from official European business registries'), and a clear purpose ('confirm the legal entity exists and is active'). It also scopes to basic company data, which distinguishes it from sibling enrichment/validation tools like company_enriched and validate_vat.
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?
It gives a clear trigger: 'Call before onboarding a supplier or customer...' This is explicit context, though it doesn't name alternatives or when-not-to-use relative to siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_leiARead-onlyIdempotentInspect
Look up a Legal Entity Identifier (LEI) via GLEIF — the global standard for entity identification. Returns legal name, registered address, status, parent + ultimate parent relationships, and child entities (subsidiaries). Also supports reverse lookup from a national company number to LEI across 15 countries (DK, NO, SE, FI, IE, UK, FR, DE, CZ, PL, LV, EE, NL, BE, LU). Tier note (reverse mode only): NL and DE use paid upstream registries — free-tier API keys receive HTTP 402 'upgrade_required'; do NOT retry on 402.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | National company ID. Required when mode='reverse'. | |
| lei | No | 20-character ISO 17442 Legal Entity Identifier. Required when mode='lei'. | |
| mode | Yes | 'lei' = look up by LEI directly. 'reverse' = look up LEI from national company number. | |
| country | No | ISO 3166-1 alpha-2 country code, lowercase. Required when mode='reverse'. | |
| include_relationships | No | If true, also fetch parent and child entities. Only applies when mode='lei'. |
Output Schema
| Name | Required | Description |
|---|---|---|
| lei | No | 20-character ISO 17442 identifier (mode='lei'). |
| count | No | mode='reverse': number of LEI records found. |
| found | No | mode='reverse': whether any LEI exists for the national ID. |
| source | No | |
| status | No | Entity status, e.g. ACTIVE / INACTIVE. |
| records | No | mode='reverse': matching LEI records (same shape as a mode='lei' result). |
| fetchedAt | No | |
| legalForm | No | ISO 20275 entity legal form code. |
| legalName | No | Registered legal name (mode='lei'). |
| jurisdiction | No | |
| legalAddress | No | |
| registeredAs | No | National registry identifier. |
| registration | No | GLEIF registration metadata (initial, lastUpdate, status ISSUED/LAPSED/..., nextRenewal). |
| relationships | No | Only present when include_relationships=true. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description discloses the returned data shape and adds a concrete failure mode: NL and DE require paid upstream registries, and free-tier keys get HTTP 402 'upgrade_required' with a do-not-retry instruction. This is exactly the kind of behavioral context annotations do not carry.
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 three sentences, front-loaded with the core purpose and return values, then reverse mode, then the critical error caveat. No filler or redundant restatement of the schema.
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 an output schema and rich annotations, the description covers purpose, modes, country coverage, return fields, and the one environment-specific error behavior. An agent has enough to invoke it correctly and know what to expect.
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 description coverage is 100%, so the description does not need to explain each parameter. It reinforces the mode/country relationship and relationship-fetching behavior, but adds no parameter-level detail beyond what the schema already provides; 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 opens with a specific verb and resource ('Look up a Legal Entity Identifier (LEI) via GLEIF') and immediately lists what it returns. It also covers the reverse lookup mode, which distinguishes it from sibling company-lookup tools even without naming them.
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?
It clearly states the two lookup modes and the 15 supported reverse-lookup countries, so an agent knows when the tool applies. It also gives an explicit do-not-retry rule for HTTP 402 in NL/DE, but it does not name sibling alternatives or state when another tool should be chosen.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
screen_sanctionsARead-onlyIdempotentInspect
Screen one or more person or company names against UN, EU, OFAC and PEP sanctions lists (768K+ entries via OpenSanctions). Typical use: counterparty checks before onboarding or processing a payment. Returns per-name match lists with fuzzy match scores, source-list attribution and risk topics, plus a 'disclaimer' field. Matches are informational decision-support from public sources, not legal or compliance advice — a match indicates a potential hit that requires verification, not a confirmed listing.
| Name | Required | Description | Default |
|---|---|---|---|
| fuzzy | No | Enable fuzzy matching. Default true. | |
| names | Yes | Array of person or company names to screen. Max 1000 names per call. | |
| min_score | No | Minimum fuzzy match score, 0-1. Default 0.7. Lower values return more (lower-confidence) matches. |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | No | Number of names screened. |
| matched | No | Number of names with matched=true. |
| results | No | One entry per input name, in submission order. |
| disclaimer | No | |
| indexUpdated | No | ISO-8601 last refresh per source list. |
| sourcesUnavailable | No | Lists that could not be checked on this call; non-empty means the screening is incomplete. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds substantial context beyond those: it discloses the return structure (per-name match lists, fuzzy scores, source attribution, risk topics, disclaimer) and, crucially, sets expectations that matches are 'informational decision-support... not legal or compliance advice' and that a match 'requires verification, not a confirmed listing.' This is exactly the kind of behavioral caveat agents need and that annotations cannot express.
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?
Four tight sentences with zero filler. The core purpose is front-loaded, followed by use case, return format, and the decision-support caveat. Every sentence earns its place and nothing is redundant with the schema or annotations.
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?
With an output schema present, return-value explanation is unnecessary, and the description still sketches the output fields. Combined with 100% schema coverage and full annotations (read-only, idempotent, non-destructive, open-world), the description covers purpose, usage, behavior, and limitations. Nothing an agent needs to invoke this correctly is missing.
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 description coverage is 100% — names, fuzzy, and min_score each have meaningful descriptions in the schema itself. The tool description references fuzzy match scores but adds no syntax or formatting detail beyond what the schema already documents. The baseline of 3 applies correctly since the schema carries the parameter-semantics burden.
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 opens with a specific verb+resource: 'Screen one or more person or company names against UN, EU, OFAC and PEP sanctions lists'. It names the exact list sources (UN, EU, OFAC, PEP) and the data provider (OpenSanctions, 768K+ entries), making it clearly distinguishable from sibling tools like lookup_company, lookup_lei, or validate_vat, which serve different counterparty-check purposes.
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 an explicit typical use case — 'counterparty checks before onboarding or processing a payment' — which tells an agent when to reach for this tool. It does not, however, explicitly name alternative tools or state when NOT to use it, leaving some routing to inference. Given the siblings include overlapping due-diligence tools (kyb_full, company_enriched, lookup_company), an explicit exclusion would have pushed this to 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_vatARead-onlyIdempotentInspect
Call before issuing an invoice, processing a cross-border payment, or storing a counterparty's VAT number. Validate a VAT registration number for any of the 27 EU member states against the official EU VIES service (DK is checked against the national CVR register). Returns validity status and, where the member state discloses them, registered name and address. Use EL for Greece. Not supported: United Kingdom (GB) and Norway (NO) — for a Norwegian company, lookup_company with country 'no' reports vatRegistered from Brønnøysund. HTTP 503 upstream_unavailable means that member state's VIES node is temporarily down; retry later.
| Name | Required | Description | Default |
|---|---|---|---|
| country | Yes | VIES country code, UPPERCASE. Supports the 27 EU member states. Use EL for Greece (not GR). The United Kingdom (GB) and Norway (NO) are not supported. | |
| vat_number | Yes | VAT number WITHOUT country prefix — just the digits/characters. Example: for DK29403473, pass '29403473'. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | Registered company name. null when the member state does not disclose trader details via VIES (e.g. DE, ES) — the number can still be valid. |
| valid | No | True if the source confirms the number is registered and active. |
| source | No | Validation source, e.g. 'VIES' or 'CVR' (DK). |
| address | No | Registered address. null when not disclosed by the member state. |
| vatNumber | No | Full VAT number including country prefix, e.g. DE143454214. |
| countryCode | No | Country code (uppercase). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, openWorldHint, and idempotentHint, but the description adds valuable context beyond them: the data source (VIES, with DK via CVR), the return fields (validity status, possibly registered name/address), and the meaning of HTTP 503 upstream_unavailable with retry guidance. This enriches the agent's understanding of behavior without contradicting the 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 compact and front-loaded with the most critical usage guidance, followed by purpose, return info, edge cases, and error handling. It is dense but every sentence carries relevant information; a slightly more structured layout could improve scannability, but there is no waste.
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 2-parameter read-only tool with an output schema, the description covers everything needed to invoke it correctly: when to use it, unsupported cases, alternative tools, special country handling, and error semantics. The output schema covers return values, so the description is contextually 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 description coverage is 100%, so the schema fully documents both parameters. The description largely repeats schema facts ('Use EL for Greece', 'VAT number WITHOUT country prefix') rather than adding new semantic meaning. Baseline 3 applies because the schema carries the load adequately.
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 a specific verb and resource: 'Validate a VAT registration number for any of the 27 EU member states against the official EU VIES service.' It clearly distinguishes itself from sibling tools by explicitly naming lookup_company as the alternative for Norway, so an agent can tell them apart.
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 opens with explicit when-to-use guidance: 'Call before issuing an invoice, processing a cross-border payment, or storing a counterparty's VAT number.' It also states what is not supported (GB, NO) and gives a concrete alternative for Norway, making the selection criteria fully explicit.
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.
3 tool updates
- Changed
autocomplete_address3 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code, lowercase."New value: +"ISO 3166-1 alpha-2 country code, lowercase. Only dk, no, se, fi and fr are supported." - changed
Input schema / properties / country / enumPrevious value: -[ - "dk", - "no", - "se", - "fi", - "ie", - "uk", - "fr", - "de", - "cz", - "pl", - "lv", - "ee", - "nl", - "be", - "lu" -]New value: +[ + "dk", + "no", + "se", + "fi", + "fr" +] - changed
Output schema / properties / results / items / properties / source / descriptionPrevious value: -"DAWA / Kartverket / BAN / MML / Nominatim."New value: +"DAWA / Geonorge / BAN / Nominatim."
- Changed
company_enriched2 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code, lowercase."New value: +"ISO 3166-1 alpha-2 country code, lowercase. Only dk, no, se and fi are supported." - changed
Input schema / properties / country / enumPrevious value: -[ - "dk", - "no", - "se", - "fi", - "ie", - "uk", - "fr", - "de", - "cz", - "pl", - "lv", - "ee", - "nl", - "be", - "lu" -]New value: +[ + "dk", + "no", + "se", + "fi" +]
- Changed
validate_vat4 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code, UPPERCASE. Use GB for the United Kingdom (HMRC), not UK. Supports all EU member states plus GB and NO."New value: +"VIES country code, UPPERCASE. Supports the 27 EU member states. Use EL for Greece (not GR). The United Kingdom (GB) and Norway (NO) are not supported." - changed
Input schema / properties / country / enumPrevious value: -[ - "DK", - "NO", - "SE", - "FI", - "NL", - "BE", - "IE", - "GB", - "FR", - "DE", - "CZ", - "PL", - "LV", - "EE", - "AT", - "BG", - "CY", - "HR", - "ES", - "IT", - "LU", - "MT", - "PT", - "RO", - "SI", - "SK", - "HU", - "GR", - "LT" -]New value: +[ + "AT", + "BE", + "BG", + "CY", + "CZ", + "DE", + "DK", + "EE", + "EL", + "ES", + "FI", + "FR", + "HR", + "HU", + "IE", + "IT", + "LT", + "LU", + "LV", + "MT", + "NL", + "PL", + "PT", + "RO", + "SE", + "SI", + "SK" +] - changed
Output schema / properties / source / descriptionPrevious value: -"Either 'VIES' or 'HMRC'."New value: +"Validation source, e.g. 'VIES' or 'CVR' (DK)." - changed
Output schema / properties / valid / descriptionPrevious value: -"True if VIES / HMRC confirms the number is registered and active."New value: +"True if the source confirms the number is registered and active."
7 tool updates
- Changed
autocomplete_address2 fields changed- added
Output schema / properties / resultsAdded value: +{ + "description": "Ranked address candidates, best match first.", + "items": { + "additionalProperties": true, + "properties": { + "city": { + "type": [ + "string", + "null" + ] + }, + "confidence": { + "description": "Match confidence 0-1.", + "type": [ + "number", + "null" + ] + }, + "coordinates": { + "additionalProperties": true, + "description": "WGS-84 {lat, lng}.", + "type": [ + "object", + "null" + ] + }, + "displayName": { + "description": "Formatted address suitable for display.", + "type": [ + "string", + "null" + ] + }, + "number": { + "description": "House number.", + "type": [ + "string", + "null" + ] + }, + "postalCode": { + "type": [ + "string", + "null" + ] + }, + "source": { + "description": "DAWA / Kartverket / BAN / MML / Nominatim.", + "type": [ + "string", + "null" + ] + }, + "street": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "type": [ + "array", + "null" + ] +} - removed
Output schema / properties / suggestionsRemoved value: -{ - "description": "Ranked address candidates, best match first.", - "items": { - "additionalProperties": true, - "properties": { - "city": { - "type": "string" - }, - "country": { - "description": "ISO 3166-1 alpha-2 code.", - "type": "string" - }, - "house_number": { - "type": "string" - }, - "lat": { - "description": "Latitude (WGS-84).", - "type": "number" - }, - "lon": { - "description": "Longitude (WGS-84).", - "type": "number" - }, - "postcode": { - "type": "string" - }, - "source": { - "description": "DAWA / Kartverket / BAN / MML / Nominatim.", - "type": "string" - }, - "street": { - "type": "string" - }, - "text": { - "description": "Formatted address suitable for display.", - "type": "string" - } - }, - "type": "object" - }, - "type": "array" -}
- Changed
company_enriched6 fields changed- removed
Output schema / properties / addressRemoved value: -{ - "additionalProperties": true, - "description": "DAWA-validated address with lat/lng (or country equivalent).", - "properties": { - "formatted": { - "type": "string" - }, - "lat": { - "type": "number" - }, - "lon": { - "type": "number" - } - }, - "type": "object" -} - added
Output schema / properties / companyAdded value: +{ + "additionalProperties": true, + "description": "Registry data — same shape as lookup_company output.", + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / industryStatsAdded value: +{ + "additionalProperties": true, + "description": "National industry statistics (DST for DK, SSB for NO, etc.).", + "properties": { + "available": { + "description": "False when no statistics exist for the company's industry code.", + "type": [ + "boolean", + "null" + ] + }, + "data": { + "description": "Time series of {year, value, unit} rows.", + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": [ + "array", + "null" + ] + }, + "source": { + "type": [ + "string", + "null" + ] + } + }, + "type": [ + "object", + "null" + ] +} - removed
Output schema / properties / industry_statsRemoved value: -{ - "additionalProperties": true, - "description": "National industry statistics (DST for DK, SSB for NO, etc.).", - "type": "object" -} - removed
Output schema / properties / registryRemoved value: -{ - "additionalProperties": true, - "description": "Same shape as lookup_company output.", - "type": "object" -} - removed
Output schema / properties / wikidataRemoved value: -{ - "additionalProperties": true, - "description": "Public profile from Wikidata.", - "properties": { - "ceo": { - "type": "string" - }, - "employees": { - "type": "number" - }, - "logo": { - "description": "URL to company logo.", - "type": "string" - }, - "ticker": { - "type": "string" - }, - "website": { - "type": "string" - }, - "wikipedia": { - "description": "URL to English Wikipedia article.", - "type": "string" - } - }, - "type": "object" -}
- Changed
fr_history11 fields changed- changed
Output schema / properties / categorieEntreprise / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / count / typePrevious value: -"integer"New value: +[ + "integer", + "null" +] - changed
Output schema / properties / dateCreation / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / events / items / properties / date / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / events / items / properties / type / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / events / typePrevious value: -"array"New value: +[ + "array", + "null" +] - changed
Output schema / properties / fetchedAt / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / periodCount / typePrevious value: -"integer"New value: +[ + "integer", + "null" +] - changed
Output schema / properties / siren / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / source / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / sourceNote / typePrevious value: -"string"New value: +[ + "string", + "null" +]
- Changed
lookup_company17 fields changed- changed
Output schema / properties / address / descriptionPrevious value: -"Registered address as returned by the source registry."New value: +"Registered address: an object ({street, city, zip}) or a single formatted string, depending on the registry." - changed
Output schema / properties / address / typePrevious value: -"object"New value: +[ + "object", + "string", + "null" +] - changed
Output schema / properties / country / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code (lowercase)."New value: +"Country code or name as returned by the source registry." - changed
Output schema / properties / country / typePrevious value: -"string"New value: +[ + "string", + "null" +] - added
Output schema / properties / fetchedAtAdded value: +{ + "description": "ISO-8601 timestamp when the data was fetched upstream.", + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / founded / descriptionPrevious value: -"ISO-8601 founding date."New value: +"ISO-8601 founding date, if known." - changed
Output schema / properties / founded / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / id / descriptionPrevious value: -"National company identifier as supplied."New value: +"National company identifier." - changed
Output schema / properties / id / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / industry / descriptionPrevious value: -"Industry classification (NACE / national code + label)."New value: +"Industry classification ({code, description}; NACE or national code)." - changed
Output schema / properties / industry / typePrevious value: -"object"New value: +[ + "object", + "null" +] - added
Output schema / properties / legalFormAdded value: +{ + "additionalProperties": true, + "description": "Legal form: an object ({code, description}) or a string, depending on the registry.", + "type": [ + "object", + "string", + "null" + ] +} - changed
Output schema / properties / name / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / source / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / status / typePrevious value: -"string"New value: +[ + "string", + "null" +] - removed
Output schema / properties / vatRemoved value: -{ - "additionalProperties": true, - "description": "VAT registration metadata (number, registered flag).", - "type": "object" -} - added
Output schema / properties / vatRegisteredAdded value: +{ + "description": "Whether the company is VAT-registered, where the registry reports it.", + "type": [ + "boolean", + "null" + ] +}
- Changed
lookup_lei26 fields changed- added
Output schema / properties / countAdded value: +{ + "description": "mode='reverse': number of LEI records found.", + "type": [ + "integer", + "null" + ] +} - added
Output schema / properties / fetchedAtAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / foundAdded value: +{ + "description": "mode='reverse': whether any LEI exists for the national ID.", + "type": [ + "boolean", + "null" + ] +} - removed
Output schema / properties / headquarters_addressRemoved value: -{ - "additionalProperties": true, - "type": "object" -} - added
Output schema / properties / jurisdictionAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / legalAddressAdded value: +{ + "additionalProperties": true, + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / legalFormAdded value: +{ + "description": "ISO 20275 entity legal form code.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / legalNameAdded value: +{ + "description": "Registered legal name (mode='lei').", + "type": [ + "string", + "null" + ] +} - removed
Output schema / properties / legal_addressRemoved value: -{ - "additionalProperties": true, - "type": "object" -} - removed
Output schema / properties / legal_nameRemoved value: -{ - "type": "string" -} - changed
Output schema / properties / lei / descriptionPrevious value: -"20-character ISO 17442 identifier."New value: +"20-character ISO 17442 identifier (mode='lei')." - changed
Output schema / properties / lei / typePrevious value: -"string"New value: +[ + "string", + "null" +] - added
Output schema / properties / recordsAdded value: +{ + "description": "mode='reverse': matching LEI records (same shape as a mode='lei' result).", + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": [ + "array", + "null" + ] +} - added
Output schema / properties / registeredAsAdded value: +{ + "description": "National registry identifier.", + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / registration / descriptionPrevious value: -"GLEIF registration metadata (initial date, last update, status)."New value: +"GLEIF registration metadata (initial, lastUpdate, status ISSUED/LAPSED/..., nextRenewal)." - changed
Output schema / properties / registration / typePrevious value: -"object"New value: +[ + "object", + "null" +] - added
Output schema / properties / relationships / properties / children / additionalPropertiesAdded value: +true - changed
Output schema / properties / relationships / properties / children / descriptionPrevious value: -"Known subsidiary LEI records."New value: +"Paginated subsidiaries: {total, page, totalPages, children: [LEI records]}." - removed
Output schema / properties / relationships / properties / children / itemsRemoved value: -{ - "additionalProperties": true, - "type": "object" -} - changed
Output schema / properties / relationships / properties / children / typePrevious value: -"array"New value: +[ + "object", + "null" +] - changed
Output schema / properties / relationships / properties / parent / descriptionPrevious value: -"Direct parent LEI record or null."New value: +"{directParent, ultimateParent, isUltimate}; directParent/ultimateParent are null for a top-level entity." - changed
Output schema / properties / relationships / properties / parent / typePrevious value: -"object"New value: +[ + "object", + "null" +] - changed
Output schema / properties / relationships / typePrevious value: -"object"New value: +[ + "object", + "null" +] - added
Output schema / properties / sourceAdded value: +{ + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / status / descriptionPrevious value: -"ISSUED / LAPSED / RETIRED / etc."New value: +"Entity status, e.g. ACTIVE / INACTIVE." - changed
Output schema / properties / status / typePrevious value: -"string"New value: +[ + "string", + "null" +]
- Changed
screen_sanctions16 fields changed- removed
Output schema / properties / checked_atRemoved value: -{ - "description": "ISO-8601 timestamp of the screening.", - "type": "string" -} - added
Output schema / properties / disclaimerAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / indexUpdatedAdded value: +{ + "additionalProperties": true, + "description": "ISO-8601 last refresh per source list.", + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / matchedAdded value: +{ + "description": "Number of names with matched=true.", + "type": [ + "integer", + "null" + ] +} - added
Output schema / properties / results / items / properties / classificationAdded value: +{ + "description": "Outcome for this name: none / potential_match / confirmed.", + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / results / items / properties / countAdded value: +{ + "description": "Number of fuzzy candidates returned, including unflagged low-confidence ones — not a match count.", + "type": [ + "integer", + "null" + ] +} - added
Output schema / properties / results / items / properties / flaggedCountAdded value: +{ + "description": "Number of hits classified as a match.", + "type": [ + "integer", + "null" + ] +} - added
Output schema / properties / results / items / properties / hitsAdded value: +{ + "description": "Fuzzy candidates, each with its own classification ('none' = not flagged).", + "items": { + "additionalProperties": true, + "properties": { + "classification": { + "description": "none / potential_match / confirmed.", + "type": [ + "string", + "null" + ] + }, + "countries": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "name": { + "description": "Listed entity name.", + "type": [ + "string", + "null" + ] + }, + "programs": { + "description": "Sanctions programmes.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "score": { + "description": "Fuzzy match score 0-1.", + "type": [ + "number", + "null" + ] + }, + "source": { + "description": "Source list (UN, EU FSF, US OFAC SDN, OpenSanctions PEPs).", + "type": [ + "string", + "null" + ] + }, + "type": { + "description": "individual / entity.", + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "type": [ + "array", + "null" + ] +} - added
Output schema / properties / results / items / properties / matchedAdded value: +{ + "description": "The screening outcome for this name: true only if at least one hit is classified as a match.", + "type": [ + "boolean", + "null" + ] +} - removed
Output schema / properties / results / items / properties / matchesRemoved value: -{ - "description": "Matched sanctioned / PEP entities, ranked by score descending.", - "items": { - "additionalProperties": true, - "properties": { - "datasets": { - "description": "Source lists (UN, EU, OFAC, PEP, ...).", - "items": { - "type": "string" - }, - "type": "array" - }, - "name": { - "description": "Matched entity name.", - "type": "string" - }, - "schema": { - "description": "OpenSanctions schema, e.g. Person, Company.", - "type": "string" - }, - "score": { - "description": "Fuzzy match score 0-1.", - "type": "number" - }, - "topics": { - "description": "Risk topics tagged on the entity.", - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - }, - "type": "array" -} - changed
Output schema / properties / results / items / properties / query / typePrevious value: -"string"New value: +[ + "string", + "null" +] - added
Output schema / properties / results / items / properties / requiresManualReviewAdded value: +{ + "description": "True when hits need human verification.", + "type": [ + "boolean", + "null" + ] +} - added
Output schema / properties / results / items / properties / topScoreAdded value: +{ + "description": "Highest fuzzy score among candidates; null when there are none. A high score alone is not a match — see classification.", + "type": [ + "number", + "null" + ] +} - changed
Output schema / properties / results / typePrevious value: -"array"New value: +[ + "array", + "null" +] - added
Output schema / properties / sourcesUnavailableAdded value: +{ + "description": "Lists that could not be checked on this call; non-empty means the screening is incomplete.", + "type": [ + "array", + "null" + ] +} - added
Output schema / properties / totalAdded value: +{ + "description": "Number of names screened.", + "type": [ + "integer", + "null" + ] +}
- Changed
validate_vat11 fields changed- changed
Output schema / properties / address / descriptionPrevious value: -"Registered address, if disclosed."New value: +"Registered address. null when not disclosed by the member state." - changed
Output schema / properties / address / typePrevious value: -"string"New value: +[ + "string", + "null" +] - removed
Output schema / properties / checked_atRemoved value: -{ - "description": "ISO-8601 timestamp of the validation.", - "type": "string" -} - removed
Output schema / properties / countryRemoved value: -{ - "description": "Country code echoed back (uppercase).", - "type": "string" -} - added
Output schema / properties / countryCodeAdded value: +{ + "description": "Country code (uppercase).", + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / name / descriptionPrevious value: -"Registered company name, if disclosed by the source."New value: +"Registered company name. null when the member state does not disclose trader details via VIES (e.g. DE, ES) — the number can still be valid." - changed
Output schema / properties / name / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / source / typePrevious value: -"string"New value: +[ + "string", + "null" +] - changed
Output schema / properties / valid / typePrevious value: -"boolean"New value: +[ + "boolean", + "null" +] - added
Output schema / properties / vatNumberAdded value: +{ + "description": "Full VAT number including country prefix, e.g. DE143454214.", + "type": [ + "string", + "null" + ] +} - removed
Output schema / properties / vat_numberRemoved value: -{ - "description": "Submitted VAT number (without country prefix).", - "type": "string" -}
1 tool update
- Changed
call_endpoint1 field changed- changed
Input schema / properties / method / descriptionPrevious value: -"HTTP method to use, e.g. GET or POST. Must be a method the endpoint actually supports (see get_endpoint_schema). Defaults to GET."New value: +"HTTP method to use. Read-only methods only: GET or HEAD, plus POST solely for the allowlisted screening query endpoints (/api/sanctions/screen, /api/adverse/screen, /api/peps/nl/screen). Defaults to GET."
3 tool updates
- Added
call_endpoint - Added
get_endpoint_schema - Added
list_endpoints
1 tool update
- Changed
kyb_full1 field changed- changed
Output schema / (root)Previous value: -{ - "additionalProperties": true, - "properties": { - "adverse_media": { - "additionalProperties": true, - "description": "GDELT 2.0 adverse-media signal summary.", - "type": "object" - }, - "cached": { - "description": "True if served from the 6h cache.", - "type": "boolean" - }, - "financials": { - "additionalProperties": true, - "description": "Latest filed financial statements / key figures.", - "type": "object" - }, - "generated_at": { - "description": "ISO-8601 timestamp the report was assembled.", - "type": "string" - }, - "identity": { - "additionalProperties": true, - "description": "Core registry data (name, number, status, address, founded, industry).", - "type": "object" - }, - "lei": { - "additionalProperties": true, - "description": "GLEIF LEI record + parent / ultimate parent if any.", - "type": "object" - }, - "persons": { - "description": "Directors, beneficial owners and other key persons.", - "items": { - "additionalProperties": true, - "type": "object" - }, - "type": "array" - }, - "risk_score": { - "additionalProperties": true, - "properties": { - "reasons": { - "description": "Human-readable contributors to the score.", - "items": { - "type": "string" - }, - "type": "array" - }, - "score": { - "description": "Composite risk score 0-100.", - "type": "number" - }, - "tier": { - "description": "Risk tier label (low / medium / high).", - "type": "string" - } - }, - "type": "object" - }, - "sanctions": { - "additionalProperties": true, - "description": "Sanctions + PEP screening results for the company and key persons.", - "type": "object" - }, - "vat": { - "additionalProperties": true, - "description": "VAT registration status (VIES / HMRC).", - "type": "object" - } - }, - "type": "object" -}New value: +null
1 tool update
- Added
fr_history
7 tool updates
- First observed
autocomplete_address - First observed
company_enriched - First observed
kyb_full - First observed
lookup_company - First observed
lookup_lei - First observed
screen_sanctions - First observed
validate_vat
Related MCP Connectors
11.3M entities, 10 countries, 12 tools. EU VAT (VIES), BORME, GLEIF, KYB. Free: 100 req/month.
European business data — French company check, EU VAT validation, legal search.
B2B data enrichment for 375M+ companies: legal entities, corporate hierarchies, and contacts.
Live data from 27 official national company registries. Unmodified. For KYB and due diligence.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceCompany data for Spain, France, the UK, Ireland and Poland — registry, KYB and sanctions.189 npmMIT
- AlicenseAqualityCmaintenanceStructured business intelligence for AI agents. 5.5M verified entities across 34 countries, 40.3M BORME mercantile acts, EU VAT validation, GLEIF, healthcare registries. 20 tools.61MIT
- AlicenseBqualityDmaintenanceProvides access to European company data and financial filings from multiple sources including GLEIF (1.6M+ EU companies), ESEF XBRL filings (FR, DK, GB, LT, UA), UK Companies House (5M+ companies), and curated major index lists (DAX40, FTSE100, SIX).1MIT
- AlicenseAqualityDmaintenanceMCP server for EU company and business data. 9 tools: company search (GLEIF, 2M+ entities), LEI lookup, corporate structures (parent/subsidiaries), trade register search, EU VAT validation (VIES), GDP, unemployment, inflation, and business demography (Eurostat). All APIs free, no keys required.95MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.