@lawpatch/sdk
v0.6.1
Published
Lawpatch legal guardian SDK & CLI — local-first legal risk scanning for software teams. Source code never leaves your machine.
Maintainers
Readme
@lawpatch/sdk
The Lawpatch CLI, programmatic API and MCP server.
Lawpatch is a legal guardian for software teams. It works out what your product does with personal data, matches that against real court decisions and regulator actions across the US, UK, EU and Türkiye, models how each problem plays out, and hands the fix to Cursor, Claude Code or Codex.
Your source code never leaves the machine. Detection runs entirely locally. What is uploaded is
a payload of rule hits: rule id, file path, line number, a redacted one-line message, and the shape
of your app (route names, entity names, third-party vendors). Secrets are reported by location, never
by value, and .env files are never read. Run lawpatch scan --dry-run to print the exact payload
before anything is sent.
Install
npx @lawpatch/sdk initOr, with a pairing code from your project's Connect page, npx @lawpatch/sdk pair ABCD-EFGH-JKMN.
Either writes a lawpatch.config.json, then:
npx @lawpatch/sdk scanCommands
| Command | What it does |
| --- | --- |
| lawpatch pair <code> | Connect this repository with a pairing code from the dashboard |
| lawpatch init | Connect this repository interactively with an API key |
| lawpatch scan | Scan locally and send derived signals for analysis (--dry-run sends nothing) |
| lawpatch areas | List the project's areas and the ones your key may scan |
| lawpatch areas suggest | Propose areas from the repository's CODEOWNERS file (prints JSON; nothing is saved) |
| lawpatch findings | List open findings from the latest scan |
| lawpatch fix <id> | Hand a finding to Cursor, Claude Code or Codex |
| lawpatch connect <tool> | Install the MCP server into cursor, claude, codex or vscode |
| lawpatch mcp | Run the MCP server over stdio |
| lawpatch whoami | Show which project this key belongs to |
In CI, lawpatch scan --fail-on high --comment posts inline annotations and a sticky PR comment,
and exits non-zero when a finding at or above that severity exists.
Scanning part of a project
Large projects can be split into areas in the dashboard — named path globs such as src/payments/**.
lawpatch scan --area payments # only this area (repeat the flag for several)
lawpatch scan --changed # CI: only the areas this branch changes
lawpatch scan --changed --base origin/main # choose what --changed compares withA scoped scan reads only the files in its areas (plus dependency manifests) and leaves out
repository-wide "not found" signals, which say nothing about part of a codebase. The server refuses a
scoped payload that names any file outside the chosen areas. With --changed, a change outside every
area — a dependency bump, a shared helper — scans the whole project if the key allows it, and a branch
with no changes skips the scan.
Personal keys. A developer who pairs from the dashboard gets a key tied to them and limited to
their areas: lawpatch scan covers exactly those by default, and the key stops working when their
access changes.
MCP
claude mcp add lawpatch -- npx -y @lawpatch/sdk mcp
codex mcp add lawpatch -- npx -y @lawpatch/sdk mcpTools: setup_project, select_project, check_connection, check_files, scan_project,
get_scan_status, list_findings, get_fix_brief, get_legal_feedback, get_plan,
search_precedents, mark_finding.
check_files runs the detectors on the files or folders you name, locally, and sends nothing — use it
right after an edit. scan_project takes an optional areas list, or paths: the files you changed,
from which it works out the areas to scan (a path outside every area scans the whole project). Paths
that lead outside the project are refused. get_legal_feedback returns what counsel decided: published
solutions with their requirements, accepted risks, matters still under review and the facts counsel asked
engineering to confirm — never drafts or privileged notes. When counsel has approved a solution for a finding in the
Lawpatch legal workspace, get_fix_brief (and lawpatch fix) hands the agent that approved brief instead
of the scanner's suggestion. mark_finding cannot accept a risk: that is decided in the dashboard by
someone authorised to.
Call check_connection first to verify the project. scan_project starts a fresh
analysis by default and returns its scan ID without waiting for the model. Poll
get_scan_status later; once completed, pass scan_id to list_findings to read
that exact scan. A manual resolved status is not proof of a verified fix.
The server finds the project itself: from LAWPATCH_PROJECT_ROOT if set, else its working directory,
else — when started outside any paired repository, as a global install is — from the workspace folders
the client shares (MCP roots), preferring a paired one. The agent can switch with select_project
(no path lists the workspace folders). Setting LAWPATCH_PROJECT_ROOT still works, e.g. in Codex with
--env LAWPATCH_PROJECT_ROOT=/path/to/repo.
Reads are retried on dropped connections, timeouts and 429/5xx answers; a scan submission is retried only when the server said "not now" (429/503), so it is never submitted twice.
Programmatic use
import { analyze } from "@lawpatch/sdk";
// Verifies the project's API key, scans locally, and waits for the analysis.
const { findings, riskScore } = await analyze();
// or only some areas: await analyze({ areas: ["payments"] });
console.log(riskScore, findings.length, "findings");Every command and analyze() need a Lawpatch account: the API key is checked with the server before anything is scanned,
--dry-run included. Sign in at https://www.lawpatch.studio, create a project and pair the repository.
Configuration
lawpatch.config.json:
{
"$schema": "https://www.lawpatch.studio/schema/lawpatch.config.json",
"projectId": "...",
"apiUrl": "https://www.lawpatch.studio",
"context": { "markets": ["EU"], "businessModel": "b2c", "sector": null, "description": null, "audienceIncludesChildren": false },
"exclude": ["**/dist/**"]
}The API key is never written to the config file: it comes from LAWPATCH_API_KEY, or from
~/.lawpatch/credentials.json, where pair and init store it outside the repository.
Because the config is committed, its apiUrl is not trusted with your key: a key is only sent to the hosted API, a loopback address, the server it was paired
against, or a server you name yourself in LAWPATCH_API_URL. A config pointing anywhere else stops with an error instead of sending the key.
The full reference — every command and flag, the config fields, the MCP tools and the REST API — is at https://www.lawpatch.studio/docs.
MIT © Lawpatch
