Contributing to legal-text-mcp-de¶
Thanks for your interest in contributing. This project follows the guidelines below to keep contributions reviewable and the codebase healthy.
Code of Conduct¶
All participants are expected to follow the
Contributor Covenant 2.1. Report unacceptable
behaviour to martin@klein.business.
Reporting security issues¶
Do not open a public issue for security vulnerabilities. See SECURITY.md for the disclosure process.
Where to ask questions¶
- General questions and discussions: GitHub Discussions
- Bug reports and feature requests: GitHub Issues (use the appropriate template)
Your first contribution¶
New here? Two curated entry points:
- 🌱 Good first issues — small, self-contained, well-specified tasks with a clear acceptance criterion. Each issue links to the exact files to touch and the tests to add. Typical scope: 1–4 hours.
- 🆘 Help wanted — larger items where outside expertise would speed things up (extra jurisdictions, alternative deployment recipes, integration recipes for new MCP clients).
Workflow for first-time contributors:
- Comment on the issue to claim it (avoids two people working in parallel).
- Fork → branch off
mainusingfeat/<topic>/fix/<topic>/docs/<topic>. uv sync --all-groups && uv run --group dev pytestto confirm a green baseline.- Implement → add tests →
uv run --group dev ruff check . && ruff format .. - Commit with
git commit -s(DCO sign-off — see below) and push. - Open a PR — CI runs ~16 checks; turnaround on review is usually <48 h.
If anything is unclear, post in the issue or in Q&A Discussions. No question is too small.
Architecture tour¶
Five-minute mental map before you change code:
src/legal_text_mcp_de/
├── cli/ # Typer CLI (14 subcommands)
│ ├── _lookups.py # read-only commands: laws, law, norm, cite, …
│ ├── _server.py # `serve` (MCP) and `http` (FastAPI)
│ ├── _corpus.py # `corpus pull/verify/info` (ORAS-backed)
│ └── …
├── http_api.py # FastAPI app (mirrors the MCP tool surface)
├── http_models.py # Pydantic v2 schemas — single source of truth for
│ # both HTTP and CLI JSON envelopes
├── server.py # MCP server entry point (delegates to legal_texts/)
├── config.py # pydantic-settings — all env-driven config
└── legal_texts/ # Domain core: loading, parsing, search, citing
├── models.py # normalised data model (Law, Norm, Source, …)
├── sources/ # one adapter per upstream feed
├── search.py # rapidfuzz-backed search
└── citation.py # citation parser + resolver
The MCP tools, HTTP routes, and CLI subcommands all delegate to the
same underlying LegalTextRuntime. So a fix in legal_texts/ automatically
benefits all three surfaces — and one new HTTP route gets a CLI subcommand by
adding ~30 lines in cli/_lookups.py.
Full module-level documentation lives at docs/modules/.
Development setup¶
Requires Python 3.12 or 3.13 and uv.
git clone https://github.com/klein-business/legal-text-mcp-de.git
cd legal-text-mcp-de
uv sync --all-groups
uv run --group dev pre-commit install # optional but recommended
uv run --group dev pytest
Justfile shortcuts (optional)¶
The repository ships a Justfile with thin wrappers around
the canonical uv invocations. Install just
(brew install just) and run any of:
just # list all targets
just install # uv sync --all-groups
just test # uv run --group dev pytest
just lint # ruff check + format --check
just fix # ruff check --fix + format
just typecheck # mypy scripts/
just docs # mkdocs serve at localhost:8000
just run # MCP server on fixture corpus
just api # HTTP API on :8080 on fixture corpus
just verify-release # the same release-gate the CI runs
The Justfile is a documentation artefact — using uv directly is
always equivalent. CI only invokes uv, never just.
Branch and PR conventions¶
- Branch names:
feat/<short-description>,fix/<short-description>,chore/<short-description>— no GitHub username prefix. - PR titles must follow Conventional Commits:
feat: ...,fix: ...,chore: ...,refactor: ...,docs: ...,test: ...,ci: ...,perf: ...,build: ...,style: .... - Every commit must carry a
Signed-off-by:trailer (DCO). Usegit commit -s(or configurecommit.gpgsign trueplus a matching identity).
Tests and quality gates¶
- Every new feature, bug fix, or refactor must include corresponding
tests. Run the full suite before submitting:
uv run --group dev pytest mcp/tests. - Linting:
uv run --group dev ruff check .anduv run --group dev ruff format --check .. - Type-checking on
scripts/:uv run --group dev mypy scripts. - Coverage floor is enforced in CI via
[tool.coverage.report] fail_underinpyproject.toml.
Issue before PR for non-trivial work¶
For larger changes (new MCP tools, schema changes, architectural adjustments), please open an issue first to discuss approach. Small fixes and clear improvements can go directly to a PR.
Licence¶
By contributing you agree that your contributions are licensed under the Apache License 2.0.