MCP-server til AI-agenter
Grundfasts MCP-server giver en AI-agent adgang til registrene som værktøjer. Agenten forbinder med en almindelig API-nøgle og får de samme svar som REST-API’et.
Endpoint og protokol
| Egenskab | Værdi |
|---|---|
| Endpoint | https://api.grundfast.dk/mcp |
| Transport | Streamable HTTP: hver JSON-RPC 2.0-besked sendes som POST og besvares med JSON. |
| Protokolversion | 2025-06-18 |
| Tilstand | Stateless — ingen session-id, hvert kald står alene. |
| Godkendelse | Authorization: Bearer gf_live_... (eller gf_test_...). Kan klienten ikke sætte en header, accepteres nøglen også som ?token= på URL’en — men brug headeren, hvor du kan. |
| Metoder | initialize, tools/list, tools/call, ping og notifikationer. |
- Forbrug: hvert vellykket
tools/calltæller som ét kald, præcis som et REST-kald.initialize,tools/list,pingog værktøjskald, der fejler, faktureres ikke. - Grænser: samme nøgle, burst-grænse og månedskvote som REST. Rammer agenten en grænse, svarer serveren HTTP
429medRetry-After. Se Rate limits. - Fejl: et værktøj, der fejler (ugyldigt argument, ukendt BFE, en kilde der er nede), svarer med
isError: trueog API’ets fejltekst i resultatet — ikke med en protokolfejl. Et ukendt værktøjsnavn er JSON-RPC-fejl-32601. - Testnøgler virker også, så du kan bygge og teste en agent uden at blive faktureret.
Værktøjerne
Hvert værktøj svarer til et REST-endpoint og returnerer den samme JSON som tekst i content. tools/list returnerer den aktuelle liste med JSON Schema for argumenterne.
| Værktøj | Argumenter | Hvad det svarer på |
|---|---|---|
| bbr_ejendom | { bfe } | Hele BBR-ejendommen: bygninger, enheder, grund — med fredning og SAVE-bevaringsværdi pr. bygning. |
| bbr_historik | { bfe } | Versionshistorikken for hver af ejendommens nuværende bygninger, nyeste først. |
| bbr_bygningssoegning | { kommunekode | postnr, anvendelse?, opfoert_fra?, opfoert_til?, varme?, opvarmning?, tag?, ydervaeg?, asbest?, areal_min?, areal_max?, olietank?, side?, per_side? } | Alle stående bygninger i en kommune eller et postnummer, der matcher BBR-fakta: anvendelse, alder, varme, materialer, asbest, areal og olietank. Antal og første side på alle planer. |
| matrikel_ejendom | { bfe } | Jordstykker og ejerlav for ejendommen. |
| ejendomsvurdering | { bfe } | Ejendoms- og grundværdier pr. vurderingsår. |
| geodanmark_bygninger | { bfe } | Bygningernes omrids som WGS84-polygoner. |
| dhm_bygningshoejder | { bfe } | Målt højde på hver bygning, målt inde i omridset, i DVR90. |
| adresse_soeg | { q, per_side? } | Adressesøgning i fritekst. |
| adresse_opslag | { uuid } | En adresse på DAR-UUID, med BFE. |
| adresse_historik | { uuid } | Versionshistorikken for en adresse eller et husnummer. |
| adresse_datavask | { betegnelse } | Vask en uren adressestreng til rangerede kandidater med A/B/C-kategori. |
| adgangsadresse_reverse | { lon, lat, radius_m? } | De nærmeste adgangsadresser til et punkt. |
| adresse_aendringer | { kommunekode?, postnr?, adgangsadresse_id?, haendelse?, efter?, antal? } | Nye, ændrede og nedlagte adresser i et område fra den daglige DAR-opdatering. Kræver Pro. |
| cvr_virksomhed | { cvr } | En virksomhed på CVR-nummer. |
| dagi_reverse | { lon, lat } | Region, kommune, sogn, retskreds, politikreds og opstillingskreds for et punkt. |
| dagi_omraade | { tema, kode } | Ét administrativt område på tema og kode, fx kommune 101. |
| dhm_hoejde | { lon, lat } | Terræn- og overfladekote i et punkt. |
| stednavne_naer | { lon, lat, radius_m? } | Stednavne nær et punkt. |
| jord_omraadeklassificering | { lon, lat } | Om punktet er områdeklassificeret (§ 50 a), og om det er analysefrit. |
| natur_skovbyggelinje | { lon, lat } | Om punktet ligger inden for en gældende eller ophævet skovbyggelinje (§ 17). |
| natur_byggelinjer | { lon, lat } | Alle byggelinjer og § 3-beskyttelser på punktet med afstand til kanten. |
| plan | { lon, lat } | Zone, lokalplaner, delområder og kommuneplanrammer på punktet (Plandata). |
| plan_ejendom | { bfe } | Planerne for en ejendom plus vejledende restbyggeret fra Matriklen og BBR. |
| miljoe_screening | { bfe } | Miljø-forhåndsscreening pr. bygningsdel (asbest, PCB, bly, PAH, klorparaffiner, tungmetaller) plus jord, bindinger og affald. |
| miljoe_stoej | { lon, lat } | Vej-, jernbane-, lufthavns- og industristøj på punktet (Miljøstyrelsens støjkortlægning, 2017). |
| orto_luftfoto_aargange | { lon, lat } | De luftfoto-årgange, der er fløjet over punktet. |
Agenten får kun offentlige registerdata i samme form som REST. Koordinater er WGS84 lon/lat og skal ligge i Danmark.
Opsætning
Claude Code
claude mcp add --transport http grundfast https://api.grundfast.dk/mcp \
--header "Authorization: Bearer gf_live_..."Claude Desktop
Claude Desktops konfigurationsfil tager lokale servere (en kommando), ikke en fjern-URL med headere. Brug broen mcp-remote, som kører lokalt via npx (kræver Node) og videresender til Grundfast med din nøgle:
{
"mcpServers": {
"grundfast": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://api.grundfast.dk/mcp",
"--header",
"Authorization:${GRUNDFAST_AUTH}"
],
"env": {
"GRUNDFAST_AUTH": "Bearer gf_live_..."
}
}
}
}Bemærk, at der ikke er mellemrum efter kolonet i Authorization:${GRUNDFAST_AUTH}; mellemrummet ligger i værdien af GRUNDFAST_AUTH. Det undgår, at argumentet bliver delt i to. Genstart Claude Desktop efter ændringen.
Cursor
{
"mcpServers": {
"grundfast": {
"url": "https://api.grundfast.dk/mcp",
"headers": { "Authorization": "Bearer gf_live_..." }
}
}
}ChatGPT og OpenAI
ChatGPTs forbindelser til egne MCP-servere understøtter OAuth eller ingen godkendelse, ikke en fast Bearer-header, så Grundfast kan ikke tilføjes dér. Via OpenAI’s Responses API kan du derimod angive headeren på MCP-værktøjet:
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-4.1",
tools=[
{
"type": "mcp",
"server_label": "grundfast",
"server_url": "https://api.grundfast.dk/mcp",
"headers": {"Authorization": "Bearer gf_live_..."},
"require_approval": "never",
}
],
input="Hvornår er hovedbygningen på BFE 5651067 opført, og hvad er taget lavet af?",
)
print(response.output_text)Andre MCP-klienter, der understøtter Streamable HTTP med egne headere, forbindes på samme måde: URL’en ovenfor og Authorization-headeren.
Rå JSON-RPC
Vil du teste serveren uden en klient, kan du sende beskederne med curl. Hver besked er ét JSON-objekt; batches af flere beskeder understøttes ikke.
KEY="gf_test_..."
# 1. Håndtryk
curl -s https://api.grundfast.dk/mcp \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'
# 2. List værktøjerne
curl -s https://api.grundfast.dk/mcp \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
# 3. Kald et værktøj
curl -s https://api.grundfast.dk/mcp \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"bbr_ejendom","arguments":{"bfe":5651067}}}'{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-06-18",
"capabilities": { "tools": {} },
"serverInfo": { "name": "grundfast", "title": "Grundfast", "version": "1.0.0" }
}
}{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [{ "type": "text", "text": "{\"type\":\"ejendom\",\"bfe_nummer\":5651067, … }" }]
}
}Et værktøj, der fejler, svarer med "isError": true og fejlteksten i content. En notifikation (en besked uden id) besvares med 202 uden indhold, og GET på endpointet giver 405. Uden gyldig nøgle svarer serveren 401 med en WWW-Authenticate-header, der beskriver det forventede format.