Lema Mcp — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Lema Mcp (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Your coding agent can read the code. It can't read the _argument_ behind it. lema-mcp gives your agent the recorded why — and the alternatives a project already ruled out — cited to the source. For React, Kubernetes, and Rust out of the box, and for your own repo with one command.
A local MCP server. No account, no database, no network for your own repo — install it in 30 seconds and ask why a project decided something, or whether the approach you're about to take was already rejected.
wrongly. The rationale lives in RFC / KEP / PR threads; it was never in the code.
because a rejected alternative leaves no trace in the source.
a real ruling from a hallucinated one.
[n]links to the RFC / PR where the call was made.
with the recorded reason and a pointer to where the docs say to do it instead.
recorded choice — the governing decision cited, with a docs pointer for the how.
unknown, not approved. lema never fills the gap with a guess.
lema holds reasoning — why a decision was made, what was rejected — not API syntax or code samples. For those, reach for a docs tool. lema is the right place for why.
npx lema-mcp try react # or: kubernetes · rustThat writes a read-only public server to your project's .mcp.json. Reload your agent's MCP servers (in Claude Code: /mcp) and try the flagship tool, `check_approach` — name a direction, get the recorded verdict:
> "Let's add a delayMs prop to Suspense to debounce the fallback." (repo: react)
⛔ ruled_out — the React team considered and rejected this.
"<the recorded rationale, summarized — not a quote>" [1]
Where to look instead → https://react.dev/reference/react
[1] reactjs/rfcs#212
> "I'll add a global event bus for cross-component communication." (repo: react)
◦ no_recorded_ruling — React's public record doesn't settle this.
(Unknown — not approved.)Or just ask in plain language — "why did React adopt Hooks over mixins?" — and get one cited answer, with an honest abstain when the record is silent.
Covered today: React · Kubernetes · Rust, served from lema's public API (api.lema.sh). Tokenless. It's a curated three-project demo corpus — not analytics over a graph you own.
npx needs only Node — no Go toolchain, no account. Two commands cover both ways to use lema:
npx lema-mcp try react # read-only: ask React/Kubernetes/Rust why + what's ruled out
npx lema-mcp init # your repo: decision capture + the never-reopen guardBoth are non-destructive and idempotent — they merge into existing config and re-running changes nothing. init and try share the same lema server key; the authed init server is a superset (it serves the public tools too), so the two coexist and try never downgrades it.
<details> <summary><b>Claude Code</b></summary>
Easiest — let lema write the config and hooks for you:
npx lema-mcp init # or: npx lema-mcp try reactOr add it by hand to .mcp.json (this gets the read + capture tools, but not the guard/nudge hooks that init installs):
{
"mcpServers": {
"lema": { "command": "npx", "args": ["-y", "lema-mcp@latest"] }
}
}</details>
<details> <summary><b>Cursor</b></summary>
Add to .cursor/mcp.json (project) or ~/.cursor/mcp.json (global):
{
"mcpServers": {
"lema": { "command": "npx", "args": ["-y", "lema-mcp@latest"] }
}
}For the no-account public demo instead, add the env block:
{
"mcpServers": {
"lema": {
"command": "npx",
"args": ["-y", "lema-mcp@latest"],
"env": { "LEMA_MCP_MODE": "public", "LEMA_PUBLIC_REPO": "react-rfcs" }
}
}
}</details>
<details> <summary><b>Claude Desktop</b></summary>
Settings → Developer → Edit Config, then add to mcpServers:
{
"mcpServers": {
"lema": {
"command": "npx",
"args": ["-y", "lema-mcp@latest"],
"env": { "LEMA_MCP_MODE": "public", "LEMA_PUBLIC_REPO": "react-rfcs" }
}
}
}</details>
<details> <summary><b>Windsurf</b></summary>
Add to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"lema": { "command": "npx", "args": ["-y", "lema-mcp@latest"] }
}
}</details>
<details> <summary><b>VS Code (GitHub Copilot)</b></summary>
Add to .vscode/mcp.json — note VS Code uses the servers key:
{
"servers": {
"lema": { "command": "npx", "args": ["-y", "lema-mcp@latest"] }
}
}</details>
<details> <summary><b>Go install / pinned binary</b></summary>
go install github.com/lemahq/lema-mcp/cmd/lema-mcp@latestFor the public demo, set LEMA_MCP_MODE=public and LEMA_PUBLIC_REPO=react-rfcs (k8s-enhancements · rust-rfcs). The public API URL is baked into the binary. </details>
The public config sets only LEMA_MCP_MODE + LEMA_PUBLIC_REPO (react-rfcs · k8s-enhancements · rust-rfcs) — the API URL is compiled in.
Ask why a popular project decided something, or check whether a direction was already rejected, over its recorded RFC/KEP deliberation. This is the try server.
Most "context" tools are read-only — a nicer way to grep your docs. lema reads too, but its real job is never-reopen:
chose and the alternatives it rejected, with why each was killed (the part that never survives into the code).
decision if that option is CLOSED.
init) reads the draftchange and surfaces a CLOSED decision before the dead option gets re-proposed — enforced off both your captured decisions and the repo's own ADRs.
Decisions are captured to .lema/decisions.jsonl — a plain append-only file you commit, so your whole team's agents share the same memory through git. No key, no LLM call on our side: your agent forms the decision; lema stores it and serves it back.
#### What never-reopen looks like
Your agent reaches for an option you already killed — and it comes back CLOSED, with the original reason attached:
⛔ CLOSED — do not propose "SWR": no first-class mutation / cache invalidation — we'd hand-roll it (decided 2026-06-04 · "Data fetching for the web app" · chose TanStack Query)
So the agent surfaces the prior decision instead of re-litigating it. Supersede a decision and the previously chosen option goes CLOSED too — enforced both ways. (That's the real output of npx lema-mcp demo, run against a throwaway temp dir.)
The guard is advisory and fail-open: in its default context mode it injects that note as a non-blocking nudge — it never hard-blocks and never auto-approves an edit. LEMA_GUARD_MODE=ask prompts you on a strong match; off is a kill switch. Any error → it emits nothing and gets out of the way.
Your agent calls these over MCP.
| Tool | What it does |
|---|---|
| `check_approach` ★ | Name an approach → a three-valued verdict: ruled_out (rejected, with the recorded why synthesized and cited), settled (it is the project's in-force recorded choice, the governing decision cited), or an honest no_recorded_ruling. Every verdict carries a pointer to where the docs cover the how. The one public door — it folds in the cited "why was this decided?" answer (the former why_decided) and the settled check. |
| Tool | What it does |
|---|---|
| `record_decision` | Capture a settled decision: the chosen option and the rejected alternatives (with why each was killed), plus rationale / refs / supersedes. Rejected and superseded options come back CLOSED. Append-only. |
| `check_decided` | Adjudicate one proposed direction against decisions already CLOSED → typed verdict (ruled_out / not_ruled_out / incomplete / error), off both your capture store and the repo's ADRs. |
| `search_decisions` | Natural-language query → the most relevant atomic claims (chosen / rejected / constraint / consequence) with their source ADR, under a token budget. |
| `get_decision` · `list_decisions` · `get_decision_graph` | One decision's full body; the list by status; traversal of typed edges (supersedes, depends_on, …). |
| `search_docs` · `get_doc` | Sectioned, budgeted retrieval over the repo's project markdown (local mode, once a doc tree is indexed) — the matching sections, not whole files. |
| `ask` | One cited, synthesized answer over your team's hosted decision graph (hosted mode). |
In your own repo the full server registers the read + capture tools (and the public check_approach too); the npx lema-mcp try server runs the public door only.
lema's brand is its honesty — that's what makes a "why" tool trustworthy:
"no recorded ruling" than manufacture one.
paraphrased ("the record indicates …"), each claim tied to a followable ref.
you own. No key, no upload, no model call on our side.
source-authored dates; lema shows what's actually on the record, nothing it can't stand behind.
We measured it on two real public repos we didn't write (Backstage, vite), transcribing six of their documented decisions into record_decision format and running the real `lema-mcp guard` binary on the agent's draft edits. 168 trials, 0 errors. The honest result is an existence proof, not "agents are wrong 58% of the time":
node-fetch →native fetch), a blind agent re-proposed the killed library 58.3% of the time (14/24); lema drove it to 0% — matching a docs-preloaded arm without carrying the doc in context.
re-proposal and 0% false-abstain** across 48 trials. No nagging.
A public-repo benchmark understates the value — public decisions are disproportionately the ones the model already absorbed in training. The decisions where enforcement moves the needle are proprietary, contrarian, recent, team-specific. Full method and every raw trial: ./docs/enforcement-lift.
context (default, non-blocking), ask (prompt the humanon a strong match), or off.
Otherwise queries are scrubbed for credential-shaped substrings before logging.
files; all off unless set.
<details> <summary><b>Subcommands & flags</b></summary>
.mcp.json,appends a managed capture-protocol block to AGENTS.md, and installs three hooks (a commit reminder, the nudge capture prompt on dependency-manifest edits, and the guard never-reopen check). Idempotent.
(nothing written to your repo). The fastest way to see the CLOSED behavior.
init installs; advisory, fail-open,always exit 0. You don't call them directly.
--http, default :4321) — serve the same engine over localhostHTTP for the lema Workbench desktop GUI instead of stdio MCP.
With no flags, lema auto-discovers a decisions directory (docs/adr, doc/adr, docs/adrs, docs/decisions, docs/architecture/decisions, architecture/decisions, adr, .adr) and an openspec/ tree. Point it explicitly with --adr-dir, --repo github.com/org/name (GITHUB_TOKEN for private), --ref, --pattern, --openspec-dir, or --capture-file.
Hosted retrieval (optional). Set LEMA_API_URL + LEMA_API_TOKEN to point search_decisions at hosted hybrid retrieval over your full decision layer (search-only in the MVP). Capture and enforcement are always local. </details>
MIT. lema-mcp is the free, local wedge of lema — the system of record for why. The hosted decision graph, the team why-surface, and the manager-facing Intelligence layer are at lema.sh.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.