Skip to main content
Glama
README.md
# mcp-lovdata

MCP-server for **norske lover og sentrale forskrifter** fra Lovdatas åpne datasett.
Korpuset lastes ned, parses og indekseres lokalt i SQLite med FTS5, slik at søk går
på millisekunder uten nettverk.

## Hvorfor lokal indeks

Lovdata har ikke et gratis spørrings-API. Det som er åpent er to bulk-arkiver som
legges ut på nytt hver natt:

- `gjeldende-lover.tar.bz2` — 758 lover
- `gjeldende-sentrale-forskrifter.tar.bz2` — 5 114 forskrifter, delegeringer,
  instrukser og stortingsvedtak

Til sammen 27 MB komprimert. Alt annet — rettspraksis, forarbeider, historiske
versjoner, lokale forskrifter — ligger bak betaling i Lovdata Pro. Dataene her er
lisensiert under **NLOD 2.0** og kan fritt brukes til alle formål.

Filene er XHTML med semantiske klassenavn, ikke et maskinformat. `src/parse.js` leser
metadata, kapittelstruktur, paragrafer og endringshistorikk ut av dem.

## Verktøy

| Verktøy | Hva det gjør |
| --- | --- |
| `search` | Fulltekstsøk i alle paragrafer, med utdrag. Kan avgrenses til én lov, én type eller ett departement. |
| `get_document` | Slår opp en lov på vanlig navn, dokid eller LOV-kode. Metadata, hjemmel og innholdsfortegnelse. |
| `get_article` | Én paragraf ordrett, med endringshistorikk. Bruk denne før du siterer. |
| `list_documents` | Bla etter type, departement eller endringsdato. |
| `status` | Når indeksen sist ble bygget, og hvor mye den inneholder. |
| `sync` | Henter ferske datapakker og bygger indeksen om. |
| `caselaw_search` | Søker i EMD-praksis via Europarådets åpne HUDOC-base. |
| `caselaw_get` | Henter én EMD-dom i fulltekst, med mulighet for å hoppe til en seksjon. |
| `preparatory_search` | Søker i Stortingets saker fra 1986 — forarbeidene. |
| `preparatory_get` | Saksgang, vedtak og dokumenttekst for én stortingssak. |
| `ombudsman_search` | Søker i Sivilombudets uttalelser. |
| `ombudsman_get` | Henter én uttalelse i fulltekst. |

## Rettspraksis

Norsk rettspraksis finnes ikke i noen fri, maskinlesbar kilde. Lovdata Pro tar betalt
for Høyesterett og lagmannsrettene, og domstol.no sperrer `/api` i robots.txt.

Det som derimot er åpent, er Den europeiske menneskerettsdomstolen gjennom Europarådets
HUDOC-base — og den er ikke et sidespor: menneskerettsloven § 2 gjør EMK til norsk lov,
og § 3 gir den forrang ved motstrid med annen lovgivning. Basen har 906 avgjørelser mot
Norge, med fulltekst, artikkelhenvisninger og konklusjon.

`caselaw_search` går live mot HUDOC — ingen lokal indeks, ingen autentisering. Vær
oppmerksom på to feller i deres spørresyntaks:

- **`sort` er obligatorisk.** Uten den svarer HUDOC med en 404-side i HTML.
- **Ukjente sorteringsfelt gir stille null treff**, ikke en feilmelding. `rank` er ett
  av dem, så relevanssortering finnes ikke — bruk `caseName` for å finne én bestemt sak.

## Forarbeider

Stortingets API (`data.stortinget.no`, versjon 1.6) er åpent og uten autentisering,
men har **ingen fritekstsøk** — bare uttrekk per sesjon. Sakslistene er små og gamle
sesjoner endrer seg aldri, så de indekseres lokalt sammen med lovtekstene: 24 870 saker
fra 1986-87 til i dag. Bare de to nyeste sesjonene hentes på nytt ved hver sync.

Søket dekker sakstitler, henvisninger og emneord — ikke dokumentteksten. Selve teksten
i innstillinger og proposisjoner hentes live på forespørsel.

To ting API-et krever at man vet:

- **Datoene er lokal midnatt** i formatet `/Date(1787522400000+0200)/`. Uten å legge til
  offsetet havner man konsekvent på dagen før.
- **Samme sak ligger i to sesjoner** — den den ble fremmet i og den den ble behandlet i,
  med samme id. Nøkkelen må være sak pluss sesjon, ellers forsvinner 1 100 saker.

## Forvaltningspraksis

Sivilombudets uttalelser via WordPress' åpne REST-API: 1 965 saker med fulltekst og
fungerende serversøk. Ikke bindende som en dom, men forvaltningen retter seg etter dem,
og de er en etablert rettskilde i forvaltningsretten.

## Det som ikke er med

**EFTA-domstolen** ble undersøkt og forkastet. REST-API-et deres gir bare saksnummer
(«E-12/26») uten parter, tema eller sammendrag, og sakssidene rendres med JavaScript.
Det finnes ingen maskinlesbar inngang til innholdet.

## Kommandolinje

De samme kildene finnes som kommandoen `lovdata`. Den importerer modulene direkte —
ingen JSON-RPC-omvei — så lokale søk svarer på under et tiendedels sekund.

```bash
lovdata sok '"organinterne dokumenter"'      # søk i alle paragrafer
lovdata p offentleglova 11                   # én paragraf ordrett
lovdata lov arbeidsmiljøloven                # metadata og innholdsfortegnelse
lovdata fa offentleglova                     # forarbeider
lovdata sak 89888 --tekst                    # stortingssak med dokumenttekst
lovdata emd --art 8 --viktighet 1            # EMD-dommer mot Norge
lovdata dom 001-214433 --del "FOR THESE REASONS"
lovdata ombud innsyn byggesak                # Sivilombudet
lovdata status
```

`--json` gir rå JSON på stdout for videre behandling. `lovdata hjelp` viser alt.

Installer wrapperen:

```bash
ln -sf ~/Work/mcp-lovdata/src/cli.js ~/.local/bin/lovdata
```

## Installasjon

```bash
npm install
npm run sync          # ~3 minutter, laster ned 27 MB
```

Registrer serveren i Claude Code:

```bash
claude mcp add --scope user lovdata -- node ~/Work/mcp-lovdata/src/index.js
```

Indeksen havner i `~/.local/share/mcp-lovdata/lovdata.db` (~150 MB). Overstyr med
`LOVDATA_DB`, eller flytt hele mappa med `XDG_DATA_HOME`.

## Slik er det bygget

- **Ingen avhengigheter utover MCP-SDK-en.** SQLite kommer fra `node:sqlite`, som har
  FTS5 innebygd fra Node 22. Utpakkingen bruker systemets `tar`.
- **Arkivene pakkes ut i `/tmp`, ikke i hjemmemappa.** Tusenvis av små filer er det
  dyreste man kan skrive til en mekanisk disk; det som blir liggende igjen er én fil.
- **`remove_diacritics 0` i tokenizeren.** Æ, ø og å er egne bokstaver på norsk, ikke
  aksenter over a og o.
- **Bindeord fjernes fra søket.** FTS5 krever at alle ord finnes, så «oppsigelse i
  prøvetiden» mistet ellers treff bare fordi «i» ikke sto i paragrafen. Fraser i
  anførselstegn røres ikke.
- **Rangering.** Paragrafsøk vekter paragrafnavn og overskrift over brødtekst.
  Navneoppslag løfter treff der navnet står i tittelens parentes — det er der
  kortnavnet står, som i «Lov om arbeidsmiljø … (arbeidsmiljøloven)» — og foretrekker
  lov framfor delegeringsvedtak med samme ord i tittelen.

## Grenser

- **Bare gjeldende rett.** Ingen opphevede lover, ingen historiske versjoner, ingen
  rettsavgjørelser eller forarbeider.
- **Bare sentrale forskrifter.** Lokale og kommunale forskrifter er ikke med.
- **Indeksen er et øyeblikksbilde.** Lovdata legger ut nye pakker hver natt; `status`
  viser alderen, `sync` henter på nytt.
- **Dette er ikke juridisk rådgivning.** Verktøyet finner og siterer lovtekst.

## Utvikling

```bash
npm test              # enhetstester for parser og søkesyntaks, ingen nettverk
npm start             # kjør serveren på stdio
```

## Kilder

- [Om Lovdatas API-tjeneste](https://api.lovdata.no/om-api-tjenesten/)
- [NLOD 2.0](https://data.norge.no/nlod/no/2.0)

## Lisens

MIT for koden. Lovtekstene er NLOD 2.0 fra Stiftelsen Lovdata.

TDQS

A4/5.0

Scored across 12 tools

Disambiguation5/5

Each corpus has its own clearly namespaced search/get pair (caselaw_, preparatory_, ombudsman_), and the generic search tool is explicitly scoped to statute paragraphs. get_document vs get_article are also clearly separated by document-level vs article-level retrieval, so there is no real overlap.

Naming Consistency4/5

The dominant pattern is clear: `domain_search` and `domain_get` for the three secondary legal sources. However, the main corpus uses get_document and get_article rather than law_document/law_get, and status/sync are bare words that don't follow the verb_noun or domain_action pattern. Still, all names are readable and predictable once the pattern is understood.

Tool Count5/5

Twelve tools is well within the ideal range for a legal research server with four distinct source types. Each tool covers a necessary retrieval or maintenance need, and none feel redundant.

Completeness5/5

The surface is comprehensive for its stated domain: statute search and retrieval, document listing, article-level detail with history, ECHR case law retrieval, preparatory works, and ombudsman opinions all have search and get coverage. The only notable absence is Norwegian court caselaw, but the tool descriptions explicitly explain that no free machine-readable source exists, so it is a data-availability limitation rather than a design gap.

Maintenance

ActivityMaintained
ResponsivenessNo issues