Skip to main content
Glama

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

dar_status

no

Connectivity check, configured access paths, sunset countdown

dar_get_address

no

One unit address (floor/door) by UUID

dar_get_access_address

no

One access address (entrance / husnummer) by UUID

dar_list_addresses

no

Units at one access address

dar_list_access_addresses

no

Enumerate a street (municipality + road code), a postcode or a cadastral parcel, paginated

dar_get_street

no

Named road by UUID or municipality + road code

dar_get_postcode

no

Postcode by 4-digit code or UUID

dar_search_addresses

yes

Prefix search on street names, access addresses and unit addresses

dar_graphql

yes

Raw GraphQL passthrough to DAR/v2

dar_get_graphql_schema

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-mcp

Claude 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.

  1. Create a free account at https://datafordeler.dk (Datafordeler Administration). An e-mail user is enough; MitID Erhverv is optional.

  2. Create an IT-system and add an API key to it.

  3. 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 Vesterbro

With 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. th

What 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 virkningstid and/or registreringstid, or filter on id_lokalId. Pass both set to now for the current state; with virkningstid alone you also get superseded registrations.

  • startsWith exists only on adgangsadressebetegnelse, adressebetegnelse, vejnavn, postnr and navn, and is case-sensitive. Everything else takes eq and in. There is no fuzzy, substring or ranked search, and no autocomplete.

  • References are ids. A DAR_Husnummer holds the UUIDs of its street, postcode and access point; coordinates live on DAR_Adressepunkt.

  • Field names transliterate æ/ø/å as ae/oe/aa (doerbetegnelse).

  • Paging is forward-only: first (max 1000) and after.

  • 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.dk

With 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 tools
dar_get_access_addressGet access address by idA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
access_address_idYesDAR/DAWA access-address UUID (id_lokalId of a Husnummer).

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 idA
Read-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).

ParametersJSON Schema
NameRequiredDescriptionDefault
address_idYesDAR/DAWA address UUID (id_lokalId of an Adresse).

TDQS

A4.6/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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)A
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
filterNoSubstring of a type name to keep, e.g. "DAR_Adresse".
include_docsNoKeep the """doc comment""" blocks (Danish definitions, legal sources).

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 postcodeA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
postcodeNo4-digit postcode, e.g. "8000".
postcode_idNoPostnummer UUID.

TDQS

A4.1/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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)A
Read-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).

ParametersJSON Schema
NameRequiredDescriptionDefault
road_codeNo
street_idNoNavngivenVej UUID.
municipality_codeNo

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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)A
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesGraphQL query document.
variablesNoOptional GraphQL variables object.

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 parcelA
Read-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).

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo1-based page number.
statusNo"current" returns only status 3 (gældende) records; "all" includes preliminary, discontinued and cancelled.current
page_sizeNo
road_codeNoVejkode within the municipality, 4 digits, e.g. "5240".
street_idNoNavngivenVej UUID.
postcode_idNoPostnummer UUID (not the 4-digit code).
municipality_codeNoKommunekode, 4 digits, e.g. "0101".
cadastral_parcel_idNoJordstykke id.

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 addressA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
statusNo"current" returns only status 3 (gældende) records; "all" includes preliminary, discontinued and cancelled.current
access_address_idYesDAR/DAWA access-address UUID.

TDQS

A4.1/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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)A
Read-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 }).

ParametersJSON Schema
NameRequiredDescriptionDefault
afterNoCursor from a previous result's next_cursor, for the next page.
levelNoaccess_address
limitNo
queryYesText prefix, e.g. "Rentemestervej 8" or, for level "street", "Rentemester".
only_currentNoKeep only status 3 (gældende) records.

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 statusA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

  1. 10 tool updatesv0.1.0
    • First observeddar_get_access_address
    • First observeddar_get_address
    • First observeddar_get_graphql_schema
    • First observeddar_get_postcode
    • First observeddar_get_street
    • First observeddar_graphql
    • First observeddar_list_access_addresses
    • First observeddar_list_addresses
    • First observeddar_search_addresses
    • First observeddar_status

TDQS

A4.4/5.0

Scored across 10 tools

Disambiguation5/5

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.

Naming Consistency4/5

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.

Tool Count5/5

10 tools is well-scoped for the DAR domain, with no redundant or filler entries. Each tool covers a distinct lookup or discovery need.

Completeness4/5

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

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    B
    quality
    Not graded
    maintenance
    Enables 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.
    3
    1
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    MCP server for the Danish Address Web API (DAWA), enabling free-text address search, house number search, and detailed address lookup by ID.
    -
  • A
    license
    A
    quality
    B
    maintenance
    Enables users to retrieve Danish property information from official registers, covering addresses, buildings, valuations, trades, and more, through MCP tools.
    13
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables 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 npm
    MIT