# io.github.Mnymann/nordic-data (remote · nordic-data-mcp-production.up.railway.app)

Company, KYB, VAT, sanctions, LEI and address data for 15 EU countries.

- Trust score: 78/100 (medium)
- Change this week: +7
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- remote · `nordic-data-mcp-production.up.railway.app`: 78/100 (this document), [markdown](https://verifymcp.io/servers/mnymann-nordic-data/mcp-auth.md), [page](https://verifymcp.io/servers/mnymann-nordic-data/mcp-auth)
- npm · `nordic-data-mcp`: 35/100, [markdown](https://verifymcp.io/servers/mnymann-nordic-data/nordic-data-mcp.md), [page](https://verifymcp.io/servers/mnymann-nordic-data/nordic-data-mcp)

## Channel facts

- Endpoint: `https://nordic-data-mcp-production.up.railway.app/mcp/auth`
- Transports: `streamable-http`
- Auth: `required`
- Version: `1.5.1`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-03.

- **Endpoint Security**: 83/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation is enforced on tool calls, but the challenge carries no valid RFC 9728 metadata, so a client cannot discover where to get a token.
  - HTTPS is enforced; there's no plaintext access path.
  - HSTS check failed: the Strict-Transport-Security header is absent.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 78/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 3343 tokens (~238/item across 14 items; 11 tools + 3 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
  - Structured output schemas are declared (64% of tools); any adoption earns full credit.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add --transport http mnymann-nordic-data https://nordic-data-mcp-production.up.railway.app/mcp/auth
```

### Codex

```toml
[mcp_servers.mnymann-nordic-data]
url = "https://nordic-data-mcp-production.up.railway.app/mcp/auth"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "mnymann-nordic-data": {
      "type": "remote",
      "url": "https://nordic-data-mcp-production.up.railway.app/mcp/auth",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add mnymann-nordic-data --url https://nordic-data-mcp-production.up.railway.app/mcp/auth --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  mnymann-nordic-data:
    url: "https://nordic-data-mcp-production.up.railway.app/mcp/auth"
```

### Other

```json
{
  "mcpServers": {
    "mnymann-nordic-data": {
      "type": "http",
      "url": "https://nordic-data-mcp-production.up.railway.app/mcp/auth"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-03 (score 78, +1)

No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-08-01 (score 77, +1)

No change was recorded against any check on this day. Stability & Change Management went from 17 to 20. That category is still filling its 30-day observation window: 5 days of observed history at the previous scan, 6 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-31 (score 76, +3)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 73, +1)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-28 (score 72, +1)

No change was recorded against any check on this day. Stability & Change Management went from 3 to 7. That category is still filling its 30-day observation window: 1 days of observed history at the previous scan, 2 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-27 (score 71, +1)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-26 (score 70)

First indexed and scored.

## MCP tools (11)

### `lookup_company` (~415 tokens)

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; surface the upgrade URL from the error message to the user. On paid tiers, NL calls cost 5x quota units and DE calls cost 3x; all other countries cost 1x.

Input parameters:

- `country` (string, required): 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.
- `id` (string, required): 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…

Output parameters:

- `address` (object): Registered address as returned by the source registry.
- `country` (string): ISO 3166-1 alpha-2 country code (lowercase).
- `founded` (string): ISO-8601 founding date.
- `id` (string): National company identifier as supplied.
- `industry` (object): Industry classification (NACE / national code + label).
- `name` (string): Registered legal name.
- `source` (string): Upstream registry name (CVR, Brønnøysund, etc.).
- `status` (string): Registry status, e.g. active, dissolved, bankrupt.
- `vat` (object): VAT registration metadata (number, registered flag).

### `validate_vat` (~138 tokens)

Call before issuing an invoice, processing a cross-border payment, or storing a counterparty's VAT number. Validate a VAT registration number against the official EU VIES service (or HMRC for GB). Returns validity status, registered name, and registered address.

Input parameters:

- `country` (string, required): 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.
- `vat_number` (string, required): VAT number WITHOUT country prefix — just the digits/characters. Example: for DK29403473, pass '29403473'.

Output parameters:

- `address` (string): Registered address, if disclosed.
- `checked_at` (string): ISO-8601 timestamp of the validation.
- `country` (string): Country code echoed back (uppercase).
- `name` (string): Registered company name, if disclosed by the source.
- `source` (string): Either 'VIES' or 'HMRC'.
- `valid` (boolean): True if VIES / HMRC confirms the number is registered and active.
- `vat_number` (string): Submitted VAT number (without country prefix).

### `screen_sanctions` (~243 tokens)

Call before onboarding a counterparty or processing a payment. Screen one or more names against UN, EU, OFAC and PEP sanctions lists (768K+ entries via OpenSanctions). Returns match scores with source attribution. Disclaimer: matches are informational decision-support, NOT legal or compliance advice and not a definitive determination — a hit is a signal to investigate (confirm identity, rule out false positives) before any decision. When presenting results, give the user a recommended next step as guidance — clear, review, or escalate — framed as a signal to review, not a verdict. The response may carry a 'disclaimer' field — surface it to the user if present, otherwise state this guidance-only nature yourself; present the disclaimer in English verbatim (do not translate it), show it once, do not duplicate.

Input parameters:

- `fuzzy` (boolean): Enable fuzzy matching. Default true.
- `min_score` (number): Minimum fuzzy match score, 0-1. Default 0.7. Lower values return more (lower-confidence) matches.
- `names` (array, required): Array of person or company names to screen. Max 1000 names per call.

Output parameters:

- `checked_at` (string): ISO-8601 timestamp of the screening.
- `results` (array): One entry per input name, in submission order.

### `kyb_full` (~455 tokens)

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 are signals to review, not verdicts; verify independently and apply professional judgment before acting. When presenting results, give the user a recommended next step as guidance — clear, review, or escalate — framed as a suggestion to review, not an approval or decision. The response may carry a 'disclaimer' field — surface it to the user if present, otherwise state this guidance-only nature yourself; present the disclaimer in English verbatim (do not translate it), show it once, do not duplicate.

Input parameters:

- `country` (string, required): ISO 3166-1 alpha-2 country code, lowercase.
- `id` (string, required): National company identifier — same format as lookup_company (e.g. DK CVR 8 digits, NO orgnr 9 digits).

### `autocomplete_address` (~161 tokens)

Address autocomplete using each country's authoritative register: DAWA (DK), Kartverket (NO), BAN (FR official), MML (FI), and Nominatim (others). Returns ranked address suggestions with coordinates. Supports 15 countries (DK, NO, SE, FI, IE, UK, FR, DE, CZ, PL, LV, EE, NL, BE, LU). Tier note: NL and DE require a Starter+ subscription — free-tier API keys receive HTTP 402 'upgrade_required'; do NOT retry on 402.

Input parameters:

- `country` (string, required): ISO 3166-1 alpha-2 country code, lowercase.
- `query` (string, required): Partial address — street name, postcode, city, or any combination. Min 2 characters.

Output parameters:

- `suggestions` (array): Ranked address candidates, best match first.

### `lookup_lei` (~256 tokens)

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.

Input parameters:

- `country` (string): ISO 3166-1 alpha-2 country code, lowercase. Required when mode='reverse'.
- `id` (string): National company ID. Required when mode='reverse'.
- `include_relationships` (boolean): If true, also fetch parent and child entities. Only applies when mode='lei'.
- `lei` (string): 20-character ISO 17442 Legal Entity Identifier. Required when mode='lei'.
- `mode` (string, required): 'lei' = look up by LEI directly. 'reverse' = look up LEI from national company number.

Output parameters:

- `headquarters_address` (object)
- `legal_address` (object)
- `legal_name` (string)
- `lei` (string): 20-character ISO 17442 identifier.
- `registration` (object): GLEIF registration metadata (initial date, last update, status).
- `relationships` (object): Only present when include_relationships=true.
- `status` (string): ISSUED / LAPSED / RETIRED / etc.

### `company_enriched` (~185 tokens)

Enriched company data: basic registry data + DAWA-validated address with lat/lng + industry statistics (DST for DK, SSB for NO, etc.) + Wikidata enrichment (website, employees, CEO, ticker, logo, Wikipedia URL). One call, multiple sources. Supports 15 countries (DK, NO, SE, FI, IE, UK, FR, DE, CZ, PL, LV, EE, NL, BE, LU). 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.

Input parameters:

- `country` (string, required): ISO 3166-1 alpha-2 country code, lowercase.
- `id` (string, required): National company identifier — same format as lookup_company.

Output parameters:

- `address` (object): DAWA-validated address with lat/lng (or country equivalent).
- `industry_stats` (object): National industry statistics (DST for DK, SSB for NO, etc.).
- `registry` (object): Same shape as lookup_company output.
- `wikidata` (object): Public profile from Wikidata.

### `fr_history` (~223 tokens)

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:<field>' 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.

Input parameters:

- `siren` (string, required): 9-digit French SIREN number. Examples: 652014051 (Carrefour), 775670417 (LVMH). No spaces or punctuation.

Output parameters:

- `categorieEntreprise` (string): INSEE company size category: PME, ETI, GE.
- `count` (integer): Number of history events derived.
- `dateCreation` (string): ISO-8601 date the legal entity was created.
- `events` (array): Chronologically ordered events. Each event has 'initial:<field>' type for the baseline period or a plain field name for subsequent changes.
- `fetchedAt` (string): ISO-8601 timestamp when the data was fetched upstream.
- `periodCount` (integer): Number of bitemporal periods returned by INSEE.
- `sigle` (string|null): Acronym / short name, if any.
- `siren` (string): 9-digit SIREN echoed back.
- `source` (string): Upstream data source — 'api.insee.fr'.
- `sourceNote` (string): Provenance note describing the upstream API and field set used.

### `list_endpoints` (~156 tokens)

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. Admin endpoints are never returned. Supports an optional `search` keyword filter. The catalog has 230+ endpoints.

Input parameters:

- `search` (string): 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 e…

### `get_endpoint_schema` (~145 tokens)

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.

Input parameters:

- `method` (string): HTTP method for the endpoint (e.g. GET, POST). Defaults to GET. Must be a method the endpoint actually defines.
- `path` (string, required): Endpoint path from list_endpoints, e.g. '/api/company/{country}/{id}'. Concrete paths like '/api/company/dk/22756214' are also accepted.

### `call_endpoint` (~222 tokens)

Discovery meta-tool. Executes a real HTTP request against the Nordic Data API for any non-admin endpoint discovered via list_endpoints, and returns the response. Authenticates with the same scoped API key as the curated tools. Only HTTP methods declared in the spec for the given path are permitted; /admin endpoints are always refused. Use list_endpoints and get_endpoint_schema first to find the correct path, method, and parameters.

Input parameters:

- `method` (string): HTTP method to use, e.g. GET or POST. Must be a method the endpoint actually supports (see get_endpoint_schema). Defaults to GET.
- `params` (object): 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 POS…
- `path` (string, required): Concrete endpoint path, e.g. '/api/company/dk/22756214'. Path templates with {placeholders} are also accepted when you supply the values in `params`.

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/mnymann-nordic-data/mcp-auth#diagnostics

## Score history

- 2026-08-03: 78
- 2026-08-02: 77
- 2026-08-01: 77
- 2026-07-31: 76
- 2026-07-30: 73
- 2026-07-29: 72
- 2026-07-28: 72
- 2026-07-27: 71
- 2026-07-26: 70

## Links

- Remote endpoint: https://nordic-data-mcp-production.up.railway.app/mcp/auth
- Authorisation metadata: https://nordic-data-mcp-production.up.railway.app/.well-known/oauth-protected-resource/mcp/auth
- Repository: https://github.com/Mnymann/nordic-data-mcp
- Changelog RSS feed: https://verifymcp.io/servers/mnymann-nordic-data/mcp-auth/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/mnymann-nordic-data/mcp-auth/changelog.json
- HTML version of this page: https://verifymcp.io/servers/mnymann-nordic-data/mcp-auth
