Metadata-Version: 2.4
Name: lovspor
Version: 0.5.1
Summary: Norwegian law change tracker — produces the lovverk corpus from Lovdata public data
Project-URL: Homepage, https://github.com/bartoszkobylinski/lovspor
Project-URL: Corpus, https://github.com/bartoszkobylinski/lovverk
Project-URL: Issues, https://github.com/bartoszkobylinski/lovspor/issues
Author-email: Bartosz Kobylinski <bartosz.kobylinski@gmail.com>
License: MIT License
        
        Copyright (c) 2026 Bartosz Kobylinski
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: legal-corpus,lovdata,mcp,model-context-protocol,nlod,norwegian-law,rag
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Text Processing :: Markup
Requires-Python: >=3.12
Requires-Dist: anyio>=4.0.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: lxml>=5.3.0
Requires-Dist: mcp<2,>=1.28.1
Requires-Dist: numpy>=1.26.0
Requires-Dist: pydantic>=2.9.0
Requires-Dist: pyjwt[crypto]>=2.10.0
Requires-Dist: python-dotenv>=1.0.1
Requires-Dist: starlette>=0.27
Requires-Dist: tiktoken>=0.7.0
Requires-Dist: typer>=0.12.5
Requires-Dist: uvicorn>=0.31.1
Provides-Extra: embeddings
Requires-Dist: sentence-transformers>=3.0.0; extra == 'embeddings'
Description-Content-Type: text/markdown

# lovspor

Ask an AI assistant about Norwegian law and you get a confident answer — statute name,
section number, sometimes a quote. Nothing in that loop checks whether the section
actually exists. Lovspor does.

Lovspor keeps an open, daily-updated copy of Norwegian law — close to 6,000 acts and
central regulations from [Lovdata's public data](https://api.lovdata.no), with full
version history — and gives any AI assistant (Claude Desktop, Claude Code, Cursor, any
MCP client) tools to search it, quote it, and verify citations against the real text.

## What you can ask

Once connected, your assistant answers from the live corpus instead of stale training data:

- *"What changed in skatteloven this year?"*
- *"What did husleieloven § 9-6 say in March 2023?"* — full version history, diffable between any two dates
- *"Does this paragraph exist?"* — `validate_citation` answers instead of guessing
- *"Is this quote verbatim?"* — `verify_quote` checks it against the actual text

## Quickstart

Requires [uv](https://docs.astral.sh/uv/). No clone, no account, no API key.

```bash
# 1. Fetch the legal corpus to ~/.cache/lovverk (re-run any time to update)
uvx lovspor fetch-corpus

# 2. Connect your AI client — Claude Code:
claude mcp add lovverk -- uvx lovspor mcp
```

Other MCP clients (Claude Desktop's `claude_desktop_config.json`, etc.):

```jsonc
{
  "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.

Full setup guide, all sixteen tools with examples, troubleshooting and limitations:
[`docs/mcp.md`](docs/mcp.md).

## What's inside — and what's not

**Inside:** all current Norwegian acts (*lover*) and central regulations (*sentrale
forskrifter*) from Lovdata's public-data API, re-synced daily at 04:00 UTC, each with a
structured per-act change history. Live count: the `corpus_status` tool.

**Not inside:** court decisions, preparatory works (*forarbeider*), agency circulars
(*rundskriv*), municipal regulations. A rule can be binding and absent here — an empty
result is not evidence that no such rule exists.

## Optional: search by meaning

`semantic_search` is the one tool that needs an embedding key (OpenAI; the corpus
vectors ship pre-computed — only your query is embedded). Bring your own key via the
server's `env`:

```jsonc
{
  "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. Details: [`docs/embeddings.md`](docs/embeddings.md).

## Optional: hosted endpoint

Don't want to self-host? A hosted MCP endpoint runs at
`https://lovspor.bartoszkobylinski.com/mcp` — ask for access, or see
[`docs/mcp.md`](docs/mcp.md) to run the same thing yourself.

## How it works

A scheduled workflow pulls Lovdata's public-data tarballs daily, classifies each
document as new / updated / renamed / removed, renders deterministic Markdown, and
pushes the diff to [`lovverk`](https://github.com/bartoszkobylinski/lovverk) — the
public corpus repo — as conventional-commit history. `lovspor` (this repo, on
[PyPI](https://pypi.org/project/lovspor/)) is the engine and MCP server; legal text
never lives here.

Architecture and design rationale: [`docs/decisions.md`](docs/decisions.md).
Release process: [`docs/releasing.md`](docs/releasing.md).
Offline evals for the MCP surface: [`evals/`](evals/) (repo-only tooling).

## Install from source

```bash
git clone https://github.com/bartoszkobylinski/lovspor
cd lovspor
./scripts/bootstrap.sh     # uv sync + pre-commit hooks
uv run lovspor --help
```

## Sources

- `https://api.lovdata.no/v1/publicData/get/gjeldende-lover.tar.bz2` — current Norwegian laws
- `https://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](https://data.norge.no/nlod/no/2.0/).

## License

The engine code in this repository is licensed under MIT. See [LICENSE](LICENSE).

The legal text produced by this engine is published in the
[`lovverk`](https://github.com/bartoszkobylinski/lovverk) repository under NLOD 2.0,
with attribution to Lovdata.

## Related work

- [`cloveras/lovdata2`](https://github.com/cloveras/lovdata2) — JSON tooling and MCP
  server for the same Lovdata public data. `lovspor` is complementary, focused on
  Markdown rendering, Git-based change tracking, and an MCP server scoped to the
  `lovverk` corpus shape.
