lovspor
Norwegian law change tracker. Engine that produces the lovverk corpus from Lovdata's public-data API and serves it to AI assistants over MCP (Model Context Protocol).
Status
Production. A scheduled GitHub Actions workflow runs daily at 04:00 UTC, pulls the latest tarballs from Lovdata, classifies each document as new / updated / renamed / removed, renders the changes to Markdown, and pushes the diff to lovverk as conventional-commit history. The corpus mirrors close to 6 000 acts (Norwegian lover and central forskrifter), each with a structured per-act change history under <dataset>/history/<slug>.json. The exact live count is always available from the MCP corpus_status tool.
Distribution (updated 2026-08-03). Lovspor is open infrastructure for trustworthy access to Norwegian legal sources. The engine is MIT-licensed and public on GitHub, and Lovspor is distributed on PyPI as
lovspor— publishing resumed at0.4.0, the earlier0.2.0–0.3.0releases having been withdrawn during a July 2026 pivot (those two version numbers are permanently burned; PyPI never reuses a filename). Release process:docs/releasing.md.lovverkis the public generated corpus (NLOD 2.0 / CC0 boundary). The hosted MCP endpoint athttps://lovspor.bartoszkobylinski.com/mcp(live since 2026-07-18) is an optional operated access layer: every request requires authentication and per-credential quotas apply; access is operator-provisioned (seedocs/mcp.md). Hosted-service auth and quotas do not change the open nature of the engine. Historical note: a 2026-07-14 pivot briefly made a closed commercial hosted service the primary direction; that decision was superseded on 2026-07-30 by the open-infrastructure ruling recorded indocs/decisions.md.
Sprint 9 (MERGED 2026-05-06) added per-section embeddings to the corpus and a four-layer grounding-and-verification path to the MCP surface: semantic_search (cosine over embeddings), verify_quote (verbatim-citation guard), validated cross_references on get_section, and validate_citation as the off-ramp for ambiguous citations.
See docs/decisions.md for the full architecture and design rationale.
Install
From PyPI:
pip install lovspor # or: uv tool install lovspor, or run ad hoc with uvx lovspor
From source (contributors, and anyone running unreleased changes):
git clone https://github.com/bartoszkobylinski/lovspor
cd lovspor
./scripts/bootstrap.sh # uv sync + pre-commit hooks
uv run lovspor --help
Maintainer release process: docs/releasing.md.
MCP server
lovspor ships a stdio MCP server that exposes the lovverk corpus to AI assistants — Claude Desktop, Claude Code, or any MCP client. Once configured, you can ask "what changed in Skatteloven this year?" or "are there forskrifter about jernbane?" and the assistant answers from the live corpus instead of stale training data.
Setup — three steps:
-
Install
uv. The server runs straight from PyPI viauvx lovspor— no clone needed. (To run unreleased changes instead, replaceuvx lovsporwithuv run --project /path/to/lovspor lovsporagainst a checkout in every command below.) -
Fetch the corpus. One command shallow-clones the legal text to the default cache (
~/.cache/lovverk):uvx lovspor fetch-corpus
Re-run it any time to update — it reports
cloned,updated, orunchanged. -
Register the server.
lovspor mcpfinds that cache automatically. With Claude Code:claude mcp add lovverk -- uvx lovspor mcp
Or add it to your client config directly — Claude Desktop's
claude_desktop_config.json, or~/.claude.jsonfor Claude Code:{ "mcpServers": { "lovverk": { "command": "uvx", "args": ["lovspor", "mcp"] } } }
Restart the client and lovverk appears in its MCP list. Fifteen of the sixteen tools work immediately — no key, and no network access beyond your local corpus clone.
Optional — enable semantic_search. Lovspor core needs no embedding provider; the one search-by-meaning tool does. It embeds your query at call time (the corpus vectors ship pre-computed, so you never re-embed the corpus yourself) using OpenAI, the default and currently only supported embedding adapter — the provider sits behind an abstraction so others can be added, which is not the same as claiming any model works today (docs/embeddings.md). Bring your own key via the server's env:
{
"mcpServers": {
"lovverk": {
"command": "uvx",
"args": ["lovspor", "mcp"],
"env": { "OPENAI_API_KEY": "sk-...your-own-key..." }
}
}
}
It's your key in your own local config file — keep that file private and never commit it. Without a key, semantic_search is simply disabled; the other fifteen tools are unaffected.
Keep the corpus fresh by re-running uvx lovspor fetch-corpus (the engine re-syncs daily at 04:00 UTC); the corpus_status tool tells the assistant when your clone has drifted.
On invocation:
uvx lovsporresolves the latest release from PyPI — versioned and immutable (uvx lovspor@0.4.0 …pins one). To run unreleased changes, use the from-source formuv run --project /path/to/lovspor lovspor …against your checkout. Release process:docs/releasing.md.
See docs/mcp.md for the full setup guide, all sixteen tools documented with examples (get_law, get_law_at, list_law_versions, diff_law_versions, get_section, list_sections, get_law_history, list_recent_changes, search_laws, search_body, semantic_search, validate_citation, verify_quote, get_eu_basis, search_eu_implementations, corpus_status), troubleshooting, and limitations. The binary embedding format that powers semantic_search is documented in docs/embeddings.md.
Persona-driven offline evals for the MCP tool surface live in evals/. They are repo-only tooling — run them from a checkout with uv run python -m evals.runner.
Sources
https://api.lovdata.no/v1/publicData/get/gjeldende-lover.tar.bz2— current Norwegian lawshttps://api.lovdata.no/v1/publicData/get/gjeldende-sentrale-forskrifter.tar.bz2— current central regulations
Data is licensed under Norsk lisens for offentlige data (NLOD) 2.0.
License
The engine code in this repository is licensed under MIT. See LICENSE.
The legal text produced by this engine is published in the lovverk repository under NLOD 2.0, with attribution to Lovdata.
Related work
cloveras/lovdata2— JSON tooling and MCP server for the same Lovdata public data.lovsporis complementary, focused on Markdown rendering, Git-based change tracking, and an MCP server scoped to thelovverkcorpus shape.
Metadata
Release files for lovspor 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| lovspor-0.5.0.tar.gz | 390.5 kB | With provenance | Details for lovspor-0.5.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| lovspor-0.5.0-py3-none-any.whl | Python 3 | none | any | Details for lovspor-0.5.0-py3-none-any.whl |
Total release size: 654.1 kB
Release files / lovspor-0.5.0.tar.gz
| Download URL | lovspor-0.5.0.tar.gz |
|---|---|
| Size | 390.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d4d29b3e0b9783394e60a562827840577e870e447bac800297d0184640047c40
|
|
BLAKE2b-256 checksum How to use checksums |
00d1dcdd8b04676592c911b4be59a8c9e41acc1ea3f97850fb032bc1ea9a547e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 5, 2026.
Transparency logRelease files / lovspor-0.5.0-py3-none-any.whl
| Download URL | lovspor-0.5.0-py3-none-any.whl |
|---|---|
| Size | 263.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ff6915f2d35fabc35c6a09b4b24eaedeab011ae4412e20833a1ce3d7b133e1a3
|
|
BLAKE2b-256 checksum How to use checksums |
58fddc102551c8b6a955f97ce313ea82de61af4dd73c14aa238041e538690b4a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 5, 2026.
Transparency logSecurity for lovspor 0.5.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for lovspor-0.5.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 5, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.