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-darlook 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.
| Name | Required | Description | Default |
|---|---|---|---|
| access_address_id | Yes | DAR/DAWA access-address UUID (id_lokalId of a Husnummer). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description adds real behavioral value beyond them by enumerating the returned fields and coordinate systems (EPSG:25832 and WGS84), which matters since there is no output schema.
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?
Front-loaded with the operation, followed by id provenance, return contents, a worked example, and sibling routing. Every sentence earns its place; only the enumerated field list is slightly long but justified by the absence of an output 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?
With no output schema, the description compensates by listing the returned fields, and it documents the single required parameter's provenance plus an end-to-end example. An agent has everything needed to call it correctly.
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% and the pattern is enforced there, so baseline would be 3. The description adds meaning beyond the schema by identifying the id as the same UUID DAWA uses for /adgangsadresser and giving a concrete example invocation with a real id and expected output.
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?
Specific verb+resource with a precise domain gloss ('husnummer: street + house number, the entrance') and explicit source (DAR). It distinguishes itself from siblings dar_get_address and dar_list_addresses by naming exactly what it returns and routing unit-listing elsewhere.
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?
Gives a clear alternative with condition: to list floors/doors at this entrance, call dar_list_addresses with the same id. Also clarifies the id is the same UUID DAWA used for /adgangsadresser, which helps an agent decide it can reuse an id from elsewhere. No explicit when-not guidance relative to dar_get_address or dar_get_street.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| address_id | Yes | DAR/DAWA address UUID (id_lokalId of an Adresse). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description adds genuinely useful behavior: the returned record embeds the husnummer and includes coordinates in two CRS. It does not say what happens for an unknown UUID (empty vs error), which is the remaining gap.
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?
Front-loaded purpose, then the id provenance, then the return payload, then a concrete example call with sample output, then the exclusion. Every sentence carries distinct information with no repetition.
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 no output schema, the description takes on the return-value burden and discharges it by enumerating the embedded fields and coordinate systems, plus a worked example. Only error/not-found behavior is unaddressed, which is minor for a single-id lookup.
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% and the schema already documents the UUID format and pattern, so the baseline is 3. The description adds real meaning beyond the schema by clarifying that the id is the same UUID DAWA used for /adresser, which tells the agent where to source valid values.
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?
States a specific verb and resource ('Fetch one Danish address ... from DAR by its UUID') and immediately disambiguates the granularity by defining adresse as a specific door/floor unit, which distinguishes it from dar_get_access_address and dar_get_street.
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 names the exclusion ('Not for text search') and routes to the two correct alternatives with the conditions that select them (API key for dar_search_addresses, municipality + road code for dar_list_access_addresses). It also tells the agent when the id is valid (stored DAWA ids keep working).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| filter | No | Substring of a type name to keep, e.g. "DAR_Adresse". | |
| include_docs | No | Keep the """doc comment""" blocks (Danish definitions, legal sources). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, openWorld, non-destructive), and the description adds substantial context beyond them: the API key requirement, the ~80,000-character raw size, that doc comments are stripped by default, and that output truncates at 60,000 characters. These are exactly the operational facts an agent needs and cannot get from annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well front-loaded with the auth requirement and resource first, then size/behavior, then the two params with examples. Every sentence carries actionable information (auth, size, default stripping, filter syntax, docs toggle, truncation) with no filler.
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?
There is no output schema, yet the description compensates fully by describing the return shape: SDL text, doc comments stripped by default, and truncation at 60,000 characters. Combined with the auth requirement and filter semantics, an agent has everything needed to call it correctly.
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, but the description genuinely enriches both params: filter is explained as matching type/input/enum blocks by case-insensitive name substring with two illustrative examples, and include_docs is clarified as retaining field definitions and legal references. This goes beyond the terse schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Fetch the GraphQL schema (SDL) for DAR/v2'. This is clearly distinguishable from the sibling dar_graphql, which executes queries, since this tool retrieves the schema itself.
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?
Explains the operative context well: it requires DATAFORDELER_API_KEY and describes the default doc-stripped behavior versus include_docs. It gives concrete filter usage examples, but never explicitly states when to prefer this over dar_graphql (e.g. before writing a query), so routing to the alternative is left implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| postcode | No | 4-digit postcode, e.g. "8000". | |
| postcode_id | No | Postnummer UUID. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint, so the safety profile is covered. The description adds value by naming the return fields and the downstream id handoff, but says nothing about lookup-miss behavior or the fact that both parameters are optional (required: 0), leaving the 'neither supplied' case undefined.
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 compact sentences, front-loaded with the core action and return shape, followed by a concrete example and a workflow handoff. The example earns its place; nothing is padded, though the second sentence carries two distinct ideas.
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 only two params, no output schema and no nested objects, the definition is nearly self-contained: it names the return fields and the follow-up tool. The remaining gap is the optional-parameter edge case, which neither the description nor the schema resolves.
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 baseline is 3, but the description adds real semantics beyond the schema: it frames the two parameters as alternative lookup keys ('by its 4-digit code or by UUID'), which the schema does not state, and ties the returned id to the postcode_id parameter of another tool.
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?
States a specific verb (Fetch) and resource (Danish postcode/postnummer) with the two accepted key forms, and enumerates the returned fields (id, code, name, status). This clearly separates it from sibling getters like dar_get_street, dar_get_address and dar_get_access_address, which target different entities.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a concrete example call and, more importantly, states the downstream usage: pass the returned id as postcode_id to dar_list_access_addresses. That routes the agent through a real workflow. It stops short of explicit when-not guidance or stating what happens if neither identifier is supplied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| road_code | No | ||
| street_id | No | NavngivenVej UUID. | |
| municipality_code | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, openWorld, non-destructive), so the bar is lower. The description adds real value by disclosing the return shape (name, administering municipality, per-municipality road codes, postcodes) and the fact that a street can span municipalities, plus an auth note for the alternative tool. It does not address what happens when no key is supplied, which is the remaining gap.
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?
Front-loaded purpose sentence, then return contents, then a concrete worked example, then the exclusion and sibling routing. Every sentence carries information and the example disambiguates the composite key format.
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?
No output schema exists, so the description correctly compensates by enumerating the returned fields. It is nearly complete for a read lookup, with the only omission being behavior when no identifying parameter is provided.
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 only 33% and 0 parameters are required, so the description's labeling of municipality_code + road_code as a composite key and street_id as a UUID is genuinely useful. However it never states how the two lookup modes interact if both are supplied, nor what error surfaces with zero parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Fetch) and resource (named road / NavngivenVej) with the two accepted lookup keys (UUID or municipality_code + road_code). It explicitly names the sibling it is not (dar_search_addresses) and clarifies it does not search by name.
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 lists the two use conditions (by UUID, or by municipality_code + road_code) and an exclusion clause ('Does NOT search by name') that routes the agent to dar_search_addresses, noting the API key requirement there. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | GraphQL query document. | |
| variables | No | Optional GraphQL variables object. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnly/openWorld/idempotent), and the description adds substantial context beyond them: the API key requirement, the service-enforced virkningstid/registreringstid rule and its consequence (superseded versions), paging caps (first max 1000, default 100), the { data, errors } envelope, and reference-vs-nested-object behavior. This is exactly the kind of behavioral detail an agent cannot infer from 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?
Despite its length, it is front-loaded (purpose, endpoint, auth) and then organized into a scannable rules block plus a complete example and return-shape note. Every line carries operational information the agent needs to build a valid query.
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 no output schema, the description compensates by describing the raw return envelope, and it covers auth, entity inventory, mandatory filters, paging, spatial filters, and field-name quirks. Nothing an agent needs to issue a correct first query appears to be 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% for the two parameters (query, variables), so the schema baseline already carries the parameter contract. The description goes further by specifying what the query string must contain (entity names, required time filters, filter operators, cursor paging, ae/oe/aa field encoding) and provides a worked example, adding real meaning beyond 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?
States a specific verb and resource ('Send any GraphQL query') plus the exact endpoint (graphql.datafordeler.dk/DAR/v2), and the 'raw' framing implicitly separates it from the typed sibling helpers like dar_get_address. An agent can identify this as the escape-hatch tool without opening a schema.
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?
Gives clear context for what the tool is for and directs the agent to dar_get_graphql_schema to discover fields, but never states when to prefer this raw tool over the typed siblings (dar_get_address, dar_list_addresses, etc.) or what it cannot do. Context is clear; exclusions and alternative-selection criteria are absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | 1-based page number. | |
| status | No | "current" returns only status 3 (gældende) records; "all" includes preliminary, discontinued and cancelled. | current |
| page_size | No | ||
| road_code | No | Vejkode within the municipality, 4 digits, e.g. "5240". | |
| street_id | No | NavngivenVej UUID. | |
| postcode_id | No | Postnummer UUID (not the 4-digit code). | |
| municipality_code | No | Kommunekode, 4 digits, e.g. "0101". | |
| cadastral_parcel_id | No | Jordstykke id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), so the description's value is in the extras it supplies: anonymous access when no API key is set, 1-based pagination with page_size capped at 100, and the has_more/full-page continuation rule. It stops short of error behavior or rate limits, but the added operational context is substantial.
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?
Front-loaded with purpose and filters in a scannable bulleted block, then pagination, then the exclusion. Slightly long overall, and the Danish municipality-code examples in the final sentence are borderline redundant, but nearly every line carries actionable information.
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 an 8-parameter, no-required-parameter list tool with no output schema, the description covers filter selection, pagination, auth mode and result contents (coordinates in EPSG:25832 and WGS84). Only minor gaps remain, such as the default page_size behavior and what happens with conflicting filters.
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 88% so the baseline would be 3, but the description goes further: it frames the four filter parameters as an either/or choice ('filtered by one of'), explains the provenance of each UUID, warns that postcode_id is NOT the 4-digit postcode, and gives a worked call example plus leading-zero municipality codes.
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?
States a specific verb and resource ('List access addresses (husnumre)') and immediately distinguishes itself from dar_search_addresses by scope. The parenthetical Danish term and the filter list make the resource unambiguous among the many dar_* siblings.
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 names when to use each filter mode (municipality_code+road_code, street_id, postcode_id, cadastral_parcel_id), where each id comes from (dar_get_street, dar_get_postcode, earlier results), and closes with the exclusion: 'Does NOT search by street name. For that use dar_search_addresses (needs DATAFORDELER_API_KEY).' Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | "current" returns only status 3 (gældende) records; "all" includes preliminary, discontinued and cancelled. | current |
| access_address_id | Yes | DAR/DAWA access-address UUID. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description adds real value beyond that: it discloses the return granularity ('compact records'), names the returned fields, and explains the expected cardinality for single-family houses.
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?
Front-loaded with purpose, then example, then return shape, then the pointer to dar_get_address. Four short sentences with little waste; the single-family-house note is marginally tangential but earns its place by setting cardinality expectations.
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 no output schema, the description correctly compensates by naming the return fields and describing their compactness. Nothing essential to correct invocation is missing for a simple two-parameter read tool; pagination or ordering behavior is unstated but unlikely to matter at this scope.
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 both parameters (access_address_id and the status enum) are already fully documented in structured data. The inline example illustrates realistic ID usage but adds no syntax or semantic detail beyond the schema, so the baseline 3 applies.
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?
States a specific verb and resource with scope: 'List the unit addresses (floors/doors) that belong to one access address (husnummer).' The concrete example output (12 addresses at Oehlenschlægersgade 35) lets an agent distinguish it immediately from sibling tools like dar_get_access_address and dar_get_address.
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 routes to dar_get_address for full detail and notes that a single-family house typically yields one address with no floor/door, which tells the agent when this tool is useful but may return little. It does not explicitly contrast with the closely named siblings dar_list_access_addresses or dar_get_access_address, so the routing guidance is clear but partial.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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 }).
| Name | Required | Description | Default |
|---|---|---|---|
| after | No | Cursor from a previous result's next_cursor, for the next page. | |
| level | No | access_address | |
| limit | No | ||
| query | Yes | Text prefix, e.g. "Rentemestervej 8" or, for level "street", "Rentemester". | |
| only_current | No | Keep only status 3 (gældende) records. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly/idempotent/openWorld/destructive=false, but the description adds substantial non-obvious behavior: the API key requirement, case-sensitivity, automatic first-letter upper-casing, exact-match requirement for Danish letters, unranked results, and cursor pagination. This is well beyond what the structured fields convey.
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 critical operational facts (prefix-only, case-sensitive, API key) are front-loaded, and the level breakdown is well structured with examples. It is somewhat long, with a few redundant asides (e.g. the worked example plus inline examples), but nearly every sentence carries load.
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?
There is no output schema, and the description explicitly says the return is ids and text only, tells the agent which sibling to call for coordinates/postcode, and covers pagination. Nothing needed to call 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?
With 60% schema coverage, the description compensates well: it explains the query prefix format ('Vejnavn husnummer, postnr By'), the meaning of each level enum value, and the after cursor for pagination. It does not cover limit behavior or only_current beyond what the schema already states (status 3 gældende), so it stops short of a 5.
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?
States a specific verb (find) and resource (streets, access addresses, unit addresses) plus the matching semantics (official text starts with a prefix). It clearly distinguishes itself from sibling getters by framing itself as the prefix-search entry point and naming the follow-up tools (dar_list_access_addresses, dar_get_access_address).
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 enumerates the three level modes with when-to-use guidance and examples for each, states the default, and names the alternative tools to call afterward. It also states the negative constraint (no fuzzy, substring or typo-tolerant search) and how to disambiguate unranked results.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint/idempotentHint/destructiveHint=false, so the safety profile is covered. The description adds genuinely non-obvious operational context: the REST sunset date of 2027-01-15 and what changes after it, plus the CC BY 4.0 attribution obligation. It stops short of stating latency expectations or failure modes, but the added value over annotations is substantial.
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?
Front-loads the action, then a structured 'Returns:' list of the four reportable facts, then a 'Use first when...' routing sentence. Every sentence carries distinct information with no repetition of the title.
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 no output schema, the description must enumerate what comes back, and it does — REST reachability and latency, API-key configuration, sunset date, and attribution text. That is exactly the information an agent needs to interpret the response and act on it.
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 tool takes zero parameters, so the baseline of 4 applies per the rubric. There is nothing for the description to clarify about inputs, and it correctly spends no words on parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — check connectivity to DAR and report which access paths are configured — which is clearly a diagnostic/status operation distinct from the data-retrieval siblings (dar_get_address, dar_list_addresses, etc.). An agent can identify this as the health-check tool without opening any schema.
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?
Gives explicit trigger conditions ('Use first when a DAR call fails unexpectedly') and a concrete decision use case, naming the sibling dar_search_addresses and the prerequisite (needs API key) that this tool answers. Both when-to-use and which-alternative-is-affected are spelled out.
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.
10 tool updates
v0.1.0- First observed
dar_get_access_address - First observed
dar_get_address - First observed
dar_get_graphql_schema - First observed
dar_get_postcode - First observed
dar_get_street - First observed
dar_graphql - First observed
dar_list_access_addresses - First observed
dar_list_addresses - First observed
dar_search_addresses - First observed
dar_status
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.
Address validation & geocoding for AI agents: 240+ countries, UK PAF, free US/CA enrichment
Australian address autocomplete, validation and geocoding from G-NAF, the national register.
Routing, geocoding, places, matrix and map tools for location-aware AI workflows.
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.8 npmMIT