Directory · tool · Legal
jurisd
An open-source, local-first research tool for Australian and New Zealand law, formerly AusLaw MCP, with AGLC4 citations and citing-case tracing. Not legal advice.
Credit: russellbrenner, jurisd
GitHub: russellbrenner/jurisd · 40 stars as of Oct 22, 2026
A drafting and review aid for lawyers and compliance teams. It does not give legal advice, and a qualified lawyer should check anything it produces before it is relied on or sent.
License: Apache-2.0
Hosted copy
This file is the upstream README.md, unchanged. Credit stays with russellbrenner, jurisd. The license is Apache-2.0.
Download README.md License file
# jurisd
**Source-grounded Australian & New Zealand legal research, on your own machine.**
jurisd is an open, local-first research and drafting workbench for AU/NZ law. It
gives you, or the AI assistant you already use, fast answers from legislation and
case law where **every claim traces back to the primary source**. It runs locally
by default, so confidential and privileged work never has to leave your machine.
```mermaid
flowchart LR
q["Query: a case name<br/>or cases citing X"]
q --> route{"In a local module"}
route -->|"yes, offline"| local["Local recall:<br/>provision lookup,<br/>semantic search,<br/>citation graph"]
route -->|no| live{"AustLII reachable"}
live -->|"Cloudflare-blocked"| exa["Exa discovery<br/>or direct citation URL"]
live -->|yes| fetch
exa --> fetch["Fetch AustLII document<br/>HTML or PDF"]
local --> src["Primary source obtained"]
fetch --> src
src --> aglc4["Format AGLC4 citation"]
aglc4 --> trace["Trace cited-by and<br/>citing cases<br/>via the citation graph"]
trace --> out["Result:<br/>case text, AGLC4 citation,<br/>and citing cases,<br/>each linked to its source"]
```
Guiding principle: **no source span, no trusted legal claim.** Vector recall is
recall, not authority; a model's output is a candidate until you can see its
source and check it.
> _Previously published as `auslaw-mcp`._
**Status:** v0.5.0, pre-1.0. The surface that ships today is a CLI, a TUI search
shell, and a set of tools the AI assistant you already run can call, across live
research, citation and bibliography work, and local data modules. The longer arc
is in [Where this is heading](#where-this-is-heading).
## Why jurisd is different
- **Traceable, not hallucinated.** Every result links to its primary source (an
`austlii.edu.au` URL, the provision text, an AGLC4 citation). You verify it; you
do not take its word.
- **Local-first and private.** Recall, provision lookup, and the citation graph
work offline over installed corpora. Your matter stays on your machine.
- **Australian-law-native.** All AU/NZ jurisdictions, jurisdiction-aware search,
AGLC4 citation formatting.
- **Degrades visibly, never silently.** A missing key, dependency, or module
disables only the feature that needs it and says so. With no key and no network,
local-module recall still answers.
## Who it's for
- The **practitioner** who just wants to ask a question and get an answer they can
stand behind in front of a client or a court.
- The **researcher or student** who needs to trace authority, not just read a
summary.
- The **terminal-native power user** who wants scriptable, composable legal tools.
- The **builder** wiring AU/NZ legal research into their own AI agent.
## How jurisd answers
jurisd has three answer sources, tried in precedence order:
1. **Local data modules** (offline, no network, no key). Installed parquet bundles
holding legislation and decisions with provision-level structure, citation
edges, and chunk embeddings. This is the local-first core: deterministic
provision lookup, an Act containment tree, an offline citation graph, and local
semantic search.
2. **Live research over AustLII.** Natural-language case and legislation search,
full-text fetch (HTML and PDF), and AGLC4 formatting. AustLII's own search sits
behind a Cloudflare challenge, so discovery is recovered through Exa-backed
search (and direct citation URLs); the documents returned are AustLII primary
sources throughout. See [Tools](#tools) for the detail.
3. **OALC fallback.** An Open Australian Legal Corpus layer that backs the live
layer when a direct fetch is blocked.
## Quick start
### Run with npx (no clone)
```bash
npx -y jurisd
```
`npx` installs the package from its built distribution and launches the server
over stdio in one step. Before the npm registry package is published, use
`npx -y github:russellbrenner/jurisd`.
### Install the CLI persistently from NPM or directly from GitHub
#### npm published package
```bash
npm install -g jurisd
jurisd --help
```
#### npm install via git directly, including your own fork
```bash
npm install -g https://github.com/russellbrenner/jurisd/archive/refs/heads/main.tar.gz
jurisd --help
```
**NB:** Bare git installs such as `npm install -g github:russellbrenner/jurisd` depend
on npm's `install-links` setting and can leave a broken global bin on hosts where
`install-links=false`.
### Register with Your Coding Agent
```bash
claude mcp add jurisd -- npx -y github:russellbrenner/jurisd
```
Or add it to your client config directly:
```json
{
"mcpServers": {
"jurisd": {
"command": "npx",
"args": ["-y", "github:russellbrenner/jurisd"]
}
}
}
```
Using a different agent? [docs/HARNESS-SETUP.md](docs/HARNESS-SETUP.md) has
copy-paste configs for Cursor, Windsurf, VS Code, Cline, Continue, Codex CLI,
Zed, Gemini CLI, and more.
All environment variables are **optional** — with none set, the live AustLII
layer and the local-module recall layer both work. See
[docs/INSTALL.md](docs/INSTALL.md) for the local-clone path, every config option,
and the offline/baseline guarantee.
### Claude Code skill
A bundled [Claude Code skill](skills/jurisd-research/SKILL.md) teaches the agent
expert jurisd usage from day 0 — which of the 12 tools to reach for, the
local-first/live-fallback rule, AGLC4 citation workflows, and a
[worked research session](skills/jurisd-research/examples/research-session.md).
Install it by copying the skill folder into your skills directory:
```bash
cp -r skills/jurisd-research ~/.claude/skills/
```
(or your plugin's skills path). The skill activates automatically on legal-research
and AGLC4 prompts once the `jurisd` MCP server is registered.
## Tools
12 tools in three groups. Operation variants are selected via a
`mode` / `op` / `action` / `by` discriminator on the relevant tool.
### Live research (AustLII)
| Tool | What it does |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `search_cases` | Natural-language case-law search across all AU/NZ jurisdictions; authority ranking; title/phrase/boolean methods; pagination. |
| `search_legislation` | Search AU/NZ legislation with the same method/jurisdiction/sort controls. |
| `fetch_document_text` | Fetch full text from an AustLII URL (HTML, PDF). |
> **AustLII sits behind Cloudflare.** AustLII now serves a JavaScript
> managed-challenge that automated clients — including TLS-impersonating ones —
> cannot clear, so `search_cases` / `search_legislation` cannot query AustLII
> directly. Configure a **fallback source**; results are still AustLII primary
> sources (`austlii.edu.au` URLs) recovered through another channel.
>
> | Fallback | Env var | Cost | You gain | You lose |
> | ------------------- | ------------- | -------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
> | **Direct citation** | none | Free | Queries containing a neutral citation such as `[2018] HCA 9` resolve directly to the canonical AustLII case URL. | Citation-only. It is not general natural-language search. |
> | **Exa** | `EXA_API_KEY` | Paid/free tier | Search discovery returns canonical AustLII case/legislation URLs, even for obscure cases. | Discovery only (URL + citation); full text is fetched separately. |
> | **none** | - | - | - | Search returns a degraded result whose warning names the env vars; document fetch still falls back to the local OALC corpus when available. |
>
> Resolution order: direct citation URL when present, then Exa, then a degraded
> result. The document source remains AustLII throughout.
When AustLII search is Cloudflare-blocked, the tools degrade gracefully rather
than failing: `search_cases` returns any Exa results it can find
plus a `warning`, `sources`, and `degraded: true`, and reports incomplete
configured coverage (for example `exa: "not_configured"`) instead of hiding
that source status. `search_legislation` returns an empty degraded result with
the same machine-readable status instead of failing the tool call. CLI search
commands exit 4 for degraded source coverage.
### Citation + bibliography (AGLC4)
| Tool | What it does |
| ------------------ | -------------------------------------------------------------------------------------------------------------------- |
| `format_citation` | Format an AGLC4 citation. `mode`: `full` (default), `short`, `ibid`, `subsequent`, `pinpoint`. |
| `resolve_citation` | Resolve a citation to its source. `mode`: `auto` (default), `validate` (AustLII existence check), `search`. Falls back to the direct citation URL and Exa when AustLII is Cloudflare-blocked; `validate` reports `status` (`found`, `not_found`, `blocked`, `unreachable`, `invalid`) so a challenge is never mistaken for "not found". |
| `cite` | Write to the local citation cache. `action`: `add` (default) or `refresh_source` (conditional-HEAD freshness check). |
| `bibliography` | Read the local citation cache (no network). `op`: `get`, `list` (default), `export` (`.bib`), `cited_by`. |
### Local data modules (offline recall)
These five tools serve installed offline data modules. They require the optional
`@duckdb/node-api` dependency and at least one installed module;
`semantic_search_local` additionally needs `@huggingface/transformers`. Every
answer carries `metadata.source = "local_module"` with the module name, version,
and snapshot date (plus a staleness advisory when the snapshot is old).
| Tool | What it does |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `get_provision` | Deterministic provision lookup (e.g. `s 18` of an Act). No embedding, no ranking; typed not-found so the router can fall through. |
| `get_act_structure` | Containment tree of an Act (Act → Part → Division → section/schedule/clause) over `act_provision` edges, closed-world. |
| `find_citing` | Documents in installed modules that cite a target, with each citation's provenance span. |
| `semantic_search_local` | Vector recall: the query is embedded locally (bge-small, offline, no key) and ranked by cosine over chunk embeddings, with optional facet pre-filters. |
| `list_data_modules` | Introspect installed modules: coverage, doc/chunk counts, embedding descriptor, load status, snapshot date and staleness. |
Full parameter tables for every tool are in
[docs/AGENT-GUIDE.md](docs/AGENT-GUIDE.md).
## CLI foundation and compatibility
jurisd keeps the MCP server as the compatibility surface while the CLI is being
reorganised around task-oriented command contracts.
- CLI guide: [docs/CLI.md](docs/CLI.md)
- MCP compatibility reference: [docs/MCP-COMPATIBILITY.md](docs/MCP-COMPATIBILITY.md)
- Security and authority model: [docs/SECURITY-AUTHORITY.md](docs/SECURITY-AUTHORITY.md)
Existing flat CLI commands remain available during the foundation work.
## Data modules
A **data module** is a self-describing parquet bundle (documents, chunks, edges,
unmatched citations, plus a `manifest.json`) published as a Hugging Face dataset.
Everything needed to load and query a module — schema version, coverage,
embedding descriptor, file hashes, and licence posture — is in its manifest. No
out-of-band config.
> **Status: first module published.** `legislation-cth` is available from
> `workingmem/legislation-cth` on Hugging Face. It provides Commonwealth primary
> and secondary legislation, 32,143 documents, 857,262 chunks, citation edges,
> unmatched citations, and local bge-small embeddings. Running
> `jurisd fetch-module legislation-cth` downloads the manifest and parquet files
> from Hugging Face, verifies every file against the manifest sha256 values, and
> installs the module atomically.
Modules are queried in place: DuckDB scans the parquet on disk and never
materialises a whole table into memory, so a host can install many modules
(Commonwealth legislation + per-state + decisions) and stay flat in RSS.
### Installing modules
Modules are **operator-installed via the CLI** (kept off the tool surface so an
LLM never triggers a large download mid-conversation):
```bash
jurisd fetch-module <name> [--modules-dir DIR] # download + sha256-verify + atomic install
jurisd verify-module <name> [--modules-dir DIR] # re-verify installed files against the manifest
jurisd list-modules [--modules-dir DIR] # list installed modules (incl. refused)
```
The default install root is `~/.jurisd/modules/` (override with
`JURISD_MODULES_DIR` or `--modules-dir`). `fetch-module` validates the manifest
and checks the schema version **before** downloading any parquet, sha256-verifies
every file against the manifest, installs atomically (temp-then-rename, so a
half-written module never appears), and prints the licence attribution lines at
install time.
Advanced operators can pass `--manifest-url URL` to install from an explicitly
trusted manifest. The sha256 checks prove downloaded files match that manifest;
they do not prove the manifest's provenance or protect against a malicious or
compromised manifest source.
### Baseline vs domain-specialised variants
A module's identity is `(name, module_version)`. The `module_version` handle
distinguishes a module's **variant** — a **baseline** module is the standard
build (deterministic structure, citation edges, bge-small embeddings); a
**domain-specialised** variant is a build tuned for a particular corpus or task.
Use `list_data_modules` to see the variant, coverage, and embedding descriptor of
each installed module, and pin a specific one with the `module` argument on any
recall tool.
### BYOK provider adapter
`semantic_search_local` has two optional enhancement slots that operate **over
the locally-retrieved top-k results** — they never replace local recall, they
refine it:
- **rerank** — reorder the local top-k by a stronger relevance model.
- **extractive-QA** — return the best answer span within a retrieved chunk.
Both are expressed through one vendor-neutral `DomainAdapter` interface. The
distinction is **capability presence**, framed as **baseline vs
domain-specialised** with a **provider-interpolated display label**:
- **Baseline** (always present): pure local cosine order. No network, no key.
- **Domain-specialised** (slot): selected only if a provider is configured **and
reachable** via a BYOK key. With `ISAACUS_API_KEY` set and the endpoint
reachable, the capability probe reports
`domain_adapter: { label: "Isaacus-enhanced", canRerank: true, canExtractiveQA: true }`
and responses carry `metadata.enhancement = "Isaacus-enhanced"`.
If the key is unset, or set-but-unreachable, the adapter degrades to baseline and
the tool still returns local cosine results — reported by the probe, never thrown
into a tool result.
## Quality
jurisd's local data layer is built and scored honestly against a gold set. The
`jurisd-data` gold-set evaluation measures the local enricher (segments, defined
terms, citation crossrefs) against 90 Open Australian Legal Corpus / Kanon ILDGS
documents, under two parallel metrics:
- **strict** — the conservative audit metric: every typed prediction unmatched
within its type is a false positive.
- **aligned** — the decision metric: a strict false positive whose span
co-locates an _untyped_ gold sub-span at IoU ≥ 0.9 is credited as a granularity
agreement (a vocabulary disagreement with the silver standard, not an extraction
error) rather than penalised.
The current baseline **does not yet pass all four gate thresholds** (segment F1,
citation precision, citation recall, defined-term F1). Headline segment F1 is
0.44 strict / 0.64 aligned against a 0.85 gate. The report localises every gap
to a specific rule (the residual segment gap is genuine over-segmentation, chiefly
an endnotes-boundary flood; citation precision is internal-ref over-firing on
structural lines). The published module exposes the resulting data artefacts;
evaluation reports remain part of the module publishing workflow until a public
report location is available.
## Where this is heading
The sections above describe what ships today. The longer arc for jurisd is a
secure, local-first workbench for high-trust legal work, built so serious
reasoning can happen on your own machine with every act provable and nothing
leaving without your say-so. Planned directions (design intent, not yet built):
- **A sandboxed local agent runtime.** Run a research and drafting agent over your
own sources inside an isolated, encrypted workspace, so sensitive and privileged
material cannot leak.
- **Tamper-evident provenance.** An auditable record of every step, and an
Evidence Pack you can hand a reviewer to verify process and sources (not legal
correctness).
- **A first-class desktop app and TUI.** Matter view, source and provenance pane,
review queue, and a drafting canvas, for both terminal-native researchers and
practitioners who just want a clean interface.
- **An SDK and plugin base,** with connectors for the tools you already use (Word,
Obsidian, Zotero).
- **Source-anchored drafting.** Work-product where every assertion carries its
citation, gated by human review.
Nothing in this list is claimed as built. See [ROADMAP.md](docs/ROADMAP.md) for
the sequenced workstreams and review gates.
## Licensing
- **Code:** Apache-2.0 (see [LICENSE](LICENSE)). Third-party dependency licences are
catalogued in [LICENSE-THIRD-PARTY.md](LICENSE-THIRD-PARTY.md).
- **Module data:** licensed **per source**, declared in each module's
`manifest.json` `licence` block, and surfaced at `fetch-module` install time.
The aggregate is CC-BY-4.0 (Open Australian Legal Corpus), but redistribution is
decided per source, not in aggregate:
- **AustLII-sourced rows are excluded from published modules by default** — the
AustLII Terms of Service is restrictive, and re-importing it is exactly what
the live transport layer routes around. They remain available **recipe-only**
(rebuild locally).
- **VIC** and **NT** legislation are **not redistributable** (Government Printer
/ Crown copyright, no open licence) — **recipe-only**.
- Commonwealth (FRL), NSW, QLD, SA, TAS, WA legislation and HCA/FCA/NSW
case-law sources are redistributable under the CC-BY-4.0 aggregate, subject to
per-source confirmation before each module publishes.
Each published module carries its own `licence` block in `manifest.json`,
surfaced at `fetch-module` install time.
## Documentation
| Document | Description |
| -------------------------------------------------------- | -------------------------------------------------------------------------- |
| [INSTALL.md](docs/INSTALL.md) | Day-0 install paths, Claude Code config, env vars, module flow |
| [HARNESS-SETUP.md](docs/HARNESS-SETUP.md) | Copy-paste MCP config for every popular coding agent (CC, Cursor, Zed, …) |
| [CLI.md](docs/CLI.md) | CLI command shape, compatibility aliases, output rules, exit codes |
| [MCP-COMPATIBILITY.md](docs/MCP-COMPATIBILITY.md) | Compatibility reference for the current MCP tool surface |
| [SECURITY-AUTHORITY.md](docs/SECURITY-AUTHORITY.md) | Command authority, side-effect classes, terminal safety, credential rules |
| [jurisd-research skill](skills/jurisd-research/SKILL.md) | Claude Code skill: tool decision guidance, AGLC4 workflows, worked example |
| [AGENT-GUIDE.md](docs/AGENT-GUIDE.md) | Agent-facing usage guide with full tool catalog and examples |
| [ARCHITECTURE.md](docs/ARCHITECTURE.md) | System architecture, deployment topology, CI/CD |
| [DOCKER.md](docs/DOCKER.md) | Docker deployment guide |
| [ROADMAP.md](docs/ROADMAP.md) | Forward-looking project roadmap and review gates |
## Jurisdictions
| Code | Jurisdiction |
| --------- | ------------------------------ |
| `cth` | Commonwealth of Australia |
| `federal` | Federal courts (alias for cth) |
| `vic` | Victoria |
| `nsw` | New South Wales |
| `qld` | Queensland |
| `sa` | South Australia |
| `wa` | Western Australia |
| `tas` | Tasmania |
| `nt` | Northern Territory |
| `act` | Australian Capital Territory |
| `nz` | New Zealand |
| `other` | All jurisdictions (no filter) |
## Example queries for AI assistants
Once connected, ask natural-language questions:
- "Find the High Court decision in Mabo v Queensland (No 2) and explain native title."
- "Search for recent NSW cases about defamation on social media."
- "What does section 18 of the Australian Consumer Law say?" (answered offline if the module is installed)
- "Find cases that cite Mabo v Queensland (No 2)."
- "Format `Mabo v Queensland (No 2) [1992] HCA 23 (1992) 175 CLR 1` per AGLC4 at [64]."
- "Compare how Victoria and NSW courts have treated non-compete clauses."
## Development
```bash
git clone https://github.com/russellbrenner/jurisd.git
cd jurisd
npm install
npm run dev # hot reload
npm run build # TypeScript compile
npm start # run the built server
npm test # unit + integration + perf (integration hits live services)
npm run lint # ESLint (flat config)
```
### Docker
```bash
./build.sh # build the image
docker-compose up # run locally
```
See [docs/DOCKER.md](docs/DOCKER.md) for details.
### Kubernetes (k3s)
```bash
./build.sh
# import the image to k3s nodes (see k8s/README.md)
./deploy-k8s.sh
```
See [k8s/README.md](k8s/README.md).
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md) and [SECURITY.md](SECURITY.md) for
responsible disclosure.
**Key principles:**
- Primary sources only (no journal articles)
- Citation accuracy is paramount
- Degrade visibly, never silently
- All unit tests must pass before committing
## Disclaimer
**This tool is for legal research purposes only and does not constitute legal
advice.**
- Search results may not be comprehensive and should not be relied upon as a
complete statement of the law.
- Source databases may not include all decisions or the most recent updates.
- Always verify citations and check for subsequent treatment of cases.
- Legal advice should be sought from a qualified legal practitioner for any
specific legal matter.
- The authors and contributors accept no liability for any loss or damage arising
from use of this tool.
## License
Apache-2.0
Know a good one? Submit it.
YourAIKit products are workflow tools. They are not legal, tax, or financial advice.