datafordeler-dar
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@datafordeler-dar look up Oehlenschlægersgade 35, st. tv and its coordinates"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
datafordeler-dar-mcp
MCP server for Danish addresses from Danmarks Adresseregister (DAR) on Datafordeleren, the official national data distributor.
DAWA (dawa.aws.dk, api.dataforsyningen.dk) closed on 1 October 2026
and now returns HTTP 410. Every address tool that was built on it is dead.
Klimadatastyrelsen's replacement is Datafordeleren, which is keyed, bitemporal
and GraphQL-first. This server gives AI agents (Claude, Cursor, VS Code, any
MCP client) the DAR data through ten small, documented tools, with the
coordinates converted to WGS84 and the DAR UUIDs that DAWA also used.
Status: v0.1, a probe. It exists to find out whether anyone wants a maintained MCP layer over Danish public data. Stars, npm downloads and issues are the signal. It is deliberately thin: no caching, no metering, one source.
What it does
Tool | Needs API key | Purpose |
| no | Connectivity check, configured access paths, sunset countdown |
| no | One unit address (floor/door) by UUID |
| no | One access address (entrance / husnummer) by UUID |
| no | Units at one access address |
| no | Enumerate a street (municipality + road code), a postcode or a cadastral parcel, paginated |
| no | Named road by UUID or municipality + road code |
| no | Postcode by 4-digit code or UUID |
| yes | Prefix search on street names, access addresses and unit addresses |
| yes | Raw GraphQL passthrough to |
| yes | Fetch the GraphQL schema, compacted and filterable |
Every result carries attribution (CC BY 4.0, Klimadatastyrelsen), DAR
status codes with English labels, and points in both EPSG:25832 and WGS84.
Errors are typed (config, bad_request, auth, not_found,
rate_limited, upstream, timeout, network) and say what to do next.
Related MCP server: mcp-dawa
Install
Requires Node.js 20 or newer.
Claude Code:
claude mcp add datafordeler-dar -- npx -y datafordeler-dar-mcpClaude Desktop, Cursor, VS Code and other clients (mcp.json /
claude_desktop_config.json):
{
"mcpServers": {
"datafordeler-dar": {
"command": "npx",
"args": ["-y", "datafordeler-dar-mcp"],
"env": { "DATAFORDELER_API_KEY": "your-key-here" }
}
}
}Getting an API key, and why you will need one
Anonymous access to the legacy REST service works today, which is why the seven lookup tools need no key. Klimadatastyrelsen has announced that after 15 January 2027 Datafordeleren only serves authenticated requests (API key or OAuth). Text search already needs a key because it runs on the GraphQL service.
Create a free account at https://datafordeler.dk (Datafordeler Administration). An e-mail user is enough; MitID Erhverv is optional.
Create an IT-system and add an API key to it.
Set
DATAFORDELER_API_KEY.
No approval step is needed for DAR. A new key takes up to 15 minutes to
activate; until then the service answers 401 "Unrecognized Authentication
key". Rate limits are not published; the server surfaces HTTP 429 as
rate_limited.
Optional legacy credentials (DATAFORDELER_USERNAME, DATAFORDELER_PASSWORD)
are passed through to the REST service if set.
Examples an agent can chain
dar_get_postcode({ postcode: "1663" })
-> postcodes[0].id = d4a3a5ad-...
dar_list_access_addresses({ postcode_id: "d4a3a5ad-...", page_size: 50 })
-> entrances with lat/lon
dar_list_addresses({ access_address_id: "0a3f507a-d330-32b8-e044-0003ba298018" })
-> 12 units at Oehlenschlægersgade 35
dar_get_address({ address_id: "0a3f50a0-0000-32b8-e044-0003ba298018" })
-> "Oehlenschlægersgade 35, st. tv, 1663 København V", municipality 0101, parish VesterbroWith a key:
dar_search_addresses({ query: "rentemester", level: "street" })
-> Rentemestervej, København (0101), id 831a760e-...
dar_list_access_addresses({ street_id: "831a760e-4e3f-42e8-a9a5-0b771f72880a" })
-> every house number on the street, with lat/lon
dar_search_addresses({ query: "Rentemestervej 8, 2400" })
-> "Rentemestervej 8, 2400 København NV"
dar_search_addresses({ query: "Oehlenschlægersgade 35, st", level: "address" })
-> st. tv and st. thWhat the GraphQL service actually does
Verified against the live service on 2026-10-01. Several points differ from Datafordeleren's published transition guide (v2.3, January 2025):
DAR is served at
/DAR/v2./DAR/v1, which the guide documents, returns 404.Every entity query must carry
virkningstidand/orregistreringstid, or filter onid_lokalId. Pass both set to now for the current state; withvirkningstidalone you also get superseded registrations.startsWithexists only onadgangsadressebetegnelse,adressebetegnelse,vejnavn,postnrandnavn, and is case-sensitive. Everything else takeseqandin. There is no fuzzy, substring or ranked search, and no autocomplete.References are ids. A
DAR_Husnummerholds the UUIDs of its street, postcode and access point; coordinates live onDAR_Adressepunkt.Field names transliterate æ/ø/å as ae/oe/aa (
doerbetegnelse).Paging is forward-only:
first(max 1000) andafter.Responses are fast: 30 to 150 ms per query in testing.
dar_search_addresses handles the time arguments, the status filter and
the first letter's case for you. dar_graphql passes queries through
untouched and returns the service's errors verbatim.
Data, licence and attribution
Source: Danmarks Adresseregister via Datafordeleren, Klimadatastyrelsen.
Licence: CC BY 4.0 per
Datafordeleren's terms of use. You must credit Klimadatastyrelsen "på et
passende sted"; the attribution field in every response is there to be
passed on. Addresses are not personal data. The server stores nothing and
logs nothing.
Known limits of the legacy REST service this version leans on: no text search, no reverse geocoding, no autocomplete, pagination by page number only, and a scheduled shutdown on 15 January 2027. The replacement for all of those is the GraphQL service behind the three keyed tools.
Development
npm install
npm test # build + unit tests + stdio integration tests (offline)
npm run test:live # also hits services.datafordeler.dkWith DATAFORDELER_API_KEY set, test:live also exercises the three
GraphQL tools; without it those tests are skipped.
Layout: src/client.ts (REST and GraphQL fetch, typed errors),
src/normalise.ts (flattening, status labels, UTM32 to WGS84),
src/server.ts (tool registrations), src/index.ts (stdio entry point).
Tests use fixtures captured from the live service on 2026-10-01.
Feedback
If this is useful to you, or missing something you need (other registers, reverse geocoding, a hosted endpoint), please open an issue. Issues and stars are how this project decides what to build next.
Licence
MIT. See LICENSE.
Available Tools
10 toolsdar_get_access_addressGet access address by idARead-onlyIdempotent
Fetch one access address (husnummer: street + house number, the entrance) from DAR by its UUID.
The id is the same UUID DAWA used for /adgangsadresser. Returns street, house number, municipality, postcode, supplementary town name, parish, cadastral parcel (jordstykke), GeoDanmark building id, and access/road point coordinates (EPSG:25832 and WGS84).
Example: dar_get_access_address({ access_address_id: "0a3f507a-d330-32b8-e044-0003ba298018" }) -> "Oehlenschlægersgade 35, 1663 København V".
To list the individual units (floors/doors) at this entrance, call dar_list_addresses with the same id.
Inputs: access_address_id (required).
dar_get_addressGet address by idARead-onlyIdempotent
Fetch one Danish address (adresse: a specific door/floor unit) from DAR by its UUID.
The id is the same UUID DAWA used for /adresser, so stored DAWA ids keep working. Returns the normalised address with its access address (husnummer) embedded: street, house number, municipality, postcode, parish, cadastral parcel, building id and the access point coordinates in both EPSG:25832 (x, y) and WGS84 (lat, lon).
Example: dar_get_address({ address_id: "0a3f50a0-0000-32b8-e044-0003ba298018" }) -> "Oehlenschlægersgade 35, st. tv, 1663 København V".
Not for text search: use dar_search_addresses (API key) or dar_list_access_addresses (municipality + road code).
Inputs: address_id (required).
dar_get_graphql_schemaGet DAR GraphQL schema (API key)ARead-onlyIdempotent
Fetch the GraphQL schema (SDL) for DAR/v2. REQUIRES DATAFORDELER_API_KEY.
The full schema is about 80,000 characters, mostly Danish field documentation. By default the doc comments are stripped, which leaves a compact list of types, fields and filter inputs. Pass filter to keep only type/input/enum blocks whose name contains the text (case-insensitive), e.g. filter: "DAR_Husnummer" (type, filter input, connection) or filter: "OperationFilterInput" (available operators). Set include_docs: true to keep the field definitions and legal references. Output is truncated at 60000 characters.
Inputs: filter, include_docs.
dar_get_postcodeGet postcodeARead-onlyIdempotent
Fetch a Danish postcode (postnummer) by its 4-digit code or by UUID. Returns id, code, name and status.
Example: dar_get_postcode({ postcode: "1663" }) -> "København V", id d4a3a5ad-.... Use the returned id as postcode_id in dar_list_access_addresses to enumerate addresses in that postcode.
Inputs: postcode, postcode_id.
dar_get_streetGet street (named road)ARead-onlyIdempotent
Fetch a named road (NavngivenVej) by UUID, or by municipality_code + road_code.
Returns the street name, the municipality that administers it, its road codes per municipality (a street can span municipalities) and the postcodes it runs through.
Example: dar_get_street({ municipality_code: "0101", road_code: "5240" }) -> "Oehlenschlægersgade", København.
Does NOT search by name (see dar_search_addresses for text search, API key required).
Inputs: road_code, street_id, municipality_code.
dar_graphqlRun a raw DAR GraphQL query (API key)ARead-onlyIdempotent
Send any GraphQL query to https://graphql.datafordeler.dk/DAR/v2. REQUIRES DATAFORDELER_API_KEY.
Entities: DAR_Adresse, DAR_Husnummer, DAR_NavngivenVej, DAR_NavngivenVejKommunedel, DAR_NavngivenVejPostnummer, DAR_Postnummer, DAR_SupplerendeBynavn, DAR_Adressepunkt, DAR_Events.
Rules the service enforces:
Every entity query needs virkningstid and/or registreringstid (ISO timestamp), or a where filter on id_lokalId. Pass BOTH set to the current time to get the current state; with only one you also get superseded versions.
Filters: where: { field: { eq | in } }. startsWith exists only on adgangsadressebetegnelse, adressebetegnelse, vejnavn, postnr and navn, and is case-sensitive. Dates and ints also take gt/gte/lt/lte. Geometry fields take spatial filters (intersects, within, contains ...) with { wkt, crs: 25832 }.
Paging: first (max 1000, default 100) and after (cursor); read pageInfo { endCursor hasNextPage }.
References are ids, not nested objects: DAR_Husnummer.navngivenVej, .postnummer and .adgangspunkt hold UUIDs; fetch coordinates from DAR_Adressepunkt { position { wkt crs } }.
Field names with æ/ø/å use ae/oe/aa (doerbetegnelse, virkningsaktoer).
Example: query { DAR_Husnummer(first: 5, virkningstid: "2026-10-01T12:00:00Z", registreringstid: "2026-10-01T12:00:00Z", where: { adgangsadressebetegnelse: { startsWith: "Rentemestervej 8" }, status: { eq: "3" } }) { pageInfo { endCursor hasNextPage } nodes { id_lokalId adgangsadressebetegnelse status } } }
Returns the raw { data, errors } envelope. Use dar_get_graphql_schema to discover fields.
Inputs: query (required), variables.
dar_list_access_addressesList access addresses by street, postcode or parcelARead-onlyIdempotent
List access addresses (husnumre) filtered by one of:
municipality_code + road_code (kommunekode + vejkode, both 4-digit strings), e.g. "0101" + "5240" = Oehlenschlægersgade, København
street_id (NavngivenVej UUID, from dar_get_street or an earlier result)
postcode_id (Postnummer UUID, from dar_get_postcode; NOT the 4-digit postcode)
cadastral_parcel_id (jordstykke id, from an earlier access-address result)
This is the anonymous way to enumerate a street when no API key is set. Paginated: page (1-based) and page_size (max 100). has_more is true when a full page came back; request the next page to continue. Results include coordinates (EPSG:25832 and WGS84).
Example: dar_list_access_addresses({ municipality_code: "0101", road_code: "5240", page_size: 50 }).
Does NOT search by street name. For that use dar_search_addresses (needs DATAFORDELER_API_KEY). Danish municipality codes are 4 digits with a leading zero (København 0101, Aarhus 0751, Odense 0461, Aalborg 0851).
Inputs: page, status, page_size, road_code, +4 more.
dar_list_addressesList addresses at an access addressARead-onlyIdempotent
List the unit addresses (floors/doors) that belong to one access address (husnummer).
Example: dar_list_addresses({ access_address_id: "0a3f507a-d330-32b8-e044-0003ba298018" }) -> 12 addresses at Oehlenschlægersgade 35 (st. tv, st. th, 1. tv, ...).
Returns compact records (id, text, floor, door, status). Fetch one with dar_get_address for full detail. A single-family house typically has exactly one address with no floor/door.
Inputs: access_address_id (required), status.
dar_search_addressesSearch streets and addresses by text prefix (API key)ARead-onlyIdempotent
Find streets, access addresses or unit addresses whose official text starts with a prefix, via the Datafordeler GraphQL service. REQUIRES DATAFORDELER_API_KEY.
The service supports prefix matching only (startsWith): no fuzzy, substring or typo-tolerant search, and it is CASE-SENSITIVE. Write the prefix the way DAR writes it: "Vejnavn husnummer, postnr By". This tool upper-cases the first letter for you; the rest must match exactly, including Danish letters (æ, ø, å).
level:
"street": match street names (NavngivenVej), e.g. "Rentemester" -> Rentemestervej in København (0101) and Hvidovre. Returns street id, name and administering municipality code. Feed the id to dar_list_access_addresses({ street_id }) to enumerate house numbers.
"access_address" (default): match entrances, e.g. "Rentemestervej 8" -> Rentemestervej 8, 80, 82, ... Results are NOT ranked; an exact house number is one of several prefix matches, so add ", 2400" or pick by house_number.
"address": match unit addresses including floor/door, e.g. "Oehlenschlægersgade 35, st".
Returns ids and text only. Follow up with dar_get_access_address / dar_get_address for coordinates, municipality and postcode. Paginate with the returned next_cursor.
Example: dar_search_addresses({ query: "Rentemestervej 8, 2400", limit: 5 }).
Inputs: query (required), after, level, limit, +1 more.
dar_statusDAR connection statusARead-onlyIdempotent
Check connectivity to Datafordeleren (DAR) and report which access paths are configured.
Returns: whether the legacy REST service answers (and its latency), whether an API key for the GraphQL service is configured, the REST sunset date (2027-01-15; after it only API-key/OAuth access exists), and the attribution text that must accompany the data (CC BY 4.0, Klimadatastyrelsen).
Use first when a DAR call fails unexpectedly, or to decide whether text search (dar_search_addresses, needs API key) is available.
Inputs: no named parameters.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 10 tools
Each tool targets a distinct resource+action, and the descriptions explicitly cross-reference siblings (e.g. 'Not for text search: use dar_search_addresses'). The subtle get_address vs get_access_address (unit vs entrance) distinction is spelled out with examples, and search vs list vs get roles are clearly separated.
Strong, predictable dar_ prefix with verb_noun structure (dar_get_street, dar_list_addresses, dar_search_addresses). Minor deviations are the noun-only dar_status and dar_graphql, but these are still readable and coherent with the set.
10 tools is well-scoped for the DAR domain, with no redundant or filler entries. Each tool covers a distinct lookup or discovery need.
Covers connectivity, streets, addresses, access addresses, postcodes, text search, plus a raw GraphQL escape hatch and schema discovery, which fills most gaps. Minor omissions like dedicated building/history tooling are mitigated by dar_graphql.
Maintenance
Related MCP Connectors
Danish address & property lookup: BBR, Matriklen, DAR, CVR. A DAWA/Datafordeler-compatible source.
Danish companies (CVR), vehicles (DMR), addresses (DAR/BBR) and phone numbers. Live, read-only.
Address validation & geocoding for AI agents: 240+ countries, UK PAF, free US/CA enrichment
Norwegian property, company, land register and zoning plan data. Requires a Placepoint licence.
Related MCP Servers
- FlicenseBqualityNot gradedmaintenanceEnables AI assistants to search and analyze Swedish real estate data from Booli.se using natural language queries. Supports property searches with comprehensive filtering options and location discovery through GraphQL API integration.31-
- FlicenseNot gradedqualityDmaintenanceMCP server for the Danish Address Web API (DAWA), enabling free-text address search, house number search, and detailed address lookup by ID.-
- AlicenseAqualityBmaintenanceEnables users to retrieve Danish property information from official registers, covering addresses, buildings, valuations, trades, and more, through MCP tools.13MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to query official Statistics Denmark data without an API key — pulling national population counts and trends, browsing the subject tree, searching available tables, inspecting variable metadata, and retrieving detailed breakdowns by region, age, sex, and period in JSON-stat, bulk, or CSV format.140 npmMIT