{
  "markdown": "# lema-mcp\n\n**Your coding agent can read the code. It can't read the _argument_ behind it.**\n`lema-mcp` gives your agent the recorded *why* — and the alternatives a project\nalready ruled out — cited to the source. For React, Kubernetes, and Rust out of\nthe box, and for your own repo with one command.\n\n[![npm](https://img.shields.io/npm/v/lema-mcp)](https://www.npmjs.com/package/lema-mcp)\n[![license](https://img.shields.io/npm/l/lema-mcp)](./LICENSE)\n[![MCP](https://img.shields.io/badge/MCP-server-111)](https://modelcontextprotocol.io)\n\nA local [MCP](https://modelcontextprotocol.io) server. No account, no database, no\nnetwork for your own repo — install it in 30 seconds and ask why a project decided\nsomething, or whether the approach you're about to take was already rejected.\n\n---\n\n## ❌ Without lema\n\n- The agent invents the **why** from training recall — fluently, and sometimes\n  wrongly. The rationale lives in RFC / KEP / PR threads; it was never in the code.\n- It re-proposes the approach the maintainers **already rejected** two years ago —\n  because a rejected alternative leaves *no trace* in the source.\n- Ask \"was this ever ruled out?\" and you get a confident guess, with no way to tell\n  a real ruling from a hallucinated one.\n\n## ✅ With lema\n\n- One **cited** answer from the project's actual recorded deliberation — every `[n]`\n  links to the RFC / PR where the call was made.\n- A typed **`ruled_out`** verdict when a project already rejected your approach,\n  with the recorded reason *and* a pointer to where the docs say to do it instead.\n- A typed **`settled`** verdict when your approach *is* the project's in-force\n  recorded choice — the governing decision cited, with a docs pointer for the how.\n- An honest **\"no recorded ruling\"** when the record is silent — which means\n  *unknown*, **not** *approved*. lema never fills the gap with a guess.\n\n> lema holds **reasoning** — why a decision was made, what was rejected — not API\n> syntax or code samples. For those, reach for a docs tool. lema is the right place\n> for *why*.\n\n---\n\n## Try it in 30 seconds — no account\n\n```bash\nnpx lema-mcp try react        # or: kubernetes · rust\n```\n\nThat writes a read-only public server to your project's `.mcp.json`. Reload your\nagent's MCP servers (in Claude Code: `/mcp`) and try the flagship tool,\n**`check_approach`** — name a direction, get the recorded verdict:\n\n```text\n> \"Let's add a delayMs prop to Suspense to debounce the fallback.\"   (repo: react)\n\n  ⛔ ruled_out — the React team considered and rejected this.\n     \"<the recorded rationale, summarized — not a quote>\"  [1]\n     Where to look instead →  https://react.dev/reference/react\n     [1] reactjs/rfcs#212\n\n> \"I'll add a global event bus for cross-component communication.\"   (repo: react)\n\n  ◦ no_recorded_ruling — React's public record doesn't settle this.\n     (Unknown — not approved.)\n```\n\nOr just ask in plain language — *\"why did React adopt Hooks over mixins?\"* — and\nget one cited answer, with an honest abstain when the record is silent.\n\nCovered today: **React · Kubernetes · Rust**, served from lema's public API\n(`api.lema.sh`). Tokenless. It's a curated three-project demo corpus — not\nanalytics over a graph you own.\n\n---\n\n## Install\n\n**No-account public demo** (React's recorded decisions, zero setup):\n\n[![Add lema to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=lema&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImxlbWEtbWNwQGxhdGVzdCJdLCJlbnYiOnsiTEVNQV9NQ1BfTU9ERSI6InB1YmxpYyIsIkxFTUFfUFVCTElDX1JFUE8iOiJyZWFjdC1yZmNzIn19) &nbsp; [![Install lema in VS Code](https://img.shields.io/badge/VS_Code-Install_lema-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://vscode.dev/redirect?url=vscode%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522lema%2522%252C%2522command%2522%253A%2522npx%2522%252C%2522args%2522%253A%255B%2522-y%2522%252C%2522lema-mcp%2540latest%2522%255D%252C%2522env%2522%253A%257B%2522LEMA_MCP_MODE%2522%253A%2522public%2522%252C%2522LEMA_PUBLIC_REPO%2522%253A%2522react-rfcs%2522%257D%257D)\n\nIf the Cursor button doesn't open an install prompt (common when the browser can't hand off the `cursor://` deeplink), paste this into `.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (global):\n\n```json\n{\n  \"mcpServers\": {\n    \"lema\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"lema-mcp@latest\"],\n      \"env\": { \"LEMA_MCP_MODE\": \"public\", \"LEMA_PUBLIC_REPO\": \"react-rfcs\" }\n    }\n  }\n}\n```\n\nThat drops you into React's public record — ask *\"why did React rule out X?\"* and get a cited answer, no account. To wire **your own repo** for capture, or point the demo at Kubernetes or Rust, use the per-client setup below.\n\n`npx` needs only Node — no Go toolchain, no account. Two commands cover both ways\nto use lema:\n\n```bash\nnpx lema-mcp try react   # read-only: ask React/Kubernetes/Rust why + what's ruled out\nnpx lema-mcp init        # your repo: decision capture + the never-reopen guard\n```\n\nBoth are **non-destructive and idempotent** — they merge into existing config and\nre-running changes nothing. `init` and `try` share the same `lema` server key; the\nauthed `init` server is a superset (it serves the public tools too), so the two\ncoexist and `try` never downgrades it.\n\n<details>\n<summary><b>Claude Code</b></summary>\n\nEasiest — let lema write the config and hooks for you:\n\n```bash\nnpx lema-mcp init        # or: npx lema-mcp try react\n```\n\nOr add it by hand to `.mcp.json` (this gets the read + capture tools, but not the\nguard/nudge hooks that `init` installs):\n\n```json\n{\n  \"mcpServers\": {\n    \"lema\": { \"command\": \"npx\", \"args\": [\"-y\", \"lema-mcp@latest\"] }\n  }\n}\n```\n</details>\n\n<details>\n<summary><b>Cursor</b></summary>\n\nAdd to `.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (global):\n\n```json\n{\n  \"mcpServers\": {\n    \"lema\": { \"command\": \"npx\", \"args\": [\"-y\", \"lema-mcp@latest\"] }\n  }\n}\n```\n\nFor the no-account public demo instead, add the env block:\n\n```json\n{\n  \"mcpServers\": {\n    \"lema\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"lema-mcp@latest\"],\n      \"env\": { \"LEMA_MCP_MODE\": \"public\", \"LEMA_PUBLIC_REPO\": \"react-rfcs\" }\n    }\n  }\n}\n```\n</details>\n\n<details>\n<summary><b>Claude Desktop</b></summary>\n\nSettings → Developer → Edit Config, then add to `mcpServers`:\n\n```json\n{\n  \"mcpServers\": {\n    \"lema\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"lema-mcp@latest\"],\n      \"env\": { \"LEMA_MCP_MODE\": \"public\", \"LEMA_PUBLIC_REPO\": \"react-rfcs\" }\n    }\n  }\n}\n```\n</details>\n\n<details>\n<summary><b>Windsurf</b></summary>\n\nAdd to `~/.codeium/windsurf/mcp_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"lema\": { \"command\": \"npx\", \"args\": [\"-y\", \"lema-mcp@latest\"] }\n  }\n}\n```\n</details>\n\n<details>\n<summary><b>VS Code (GitHub Copilot)</b></summary>\n\nAdd to `.vscode/mcp.json` — note VS Code uses the `servers` key:\n\n```json\n{\n  \"servers\": {\n    \"lema\": { \"command\": \"npx\", \"args\": [\"-y\", \"lema-mcp@latest\"] }\n  }\n}\n```\n</details>\n\n<details>\n<summary><b>Go install / pinned binary</b></summary>\n\n```bash\ngo install github.com/lemahq/lema-mcp/cmd/lema-mcp@latest\n```\n\nFor the public demo, set `LEMA_MCP_MODE=public` and `LEMA_PUBLIC_REPO=react-rfcs`\n(`k8s-enhancements` · `rust-rfcs`). The public API URL is baked into the binary.\n</details>\n\nThe public config sets only `LEMA_MCP_MODE` + `LEMA_PUBLIC_REPO`\n(`react-rfcs` · `k8s-enhancements` · `rust-rfcs`) — the API URL is compiled in.\n\n### Hosted teams: sign in once; the repository resolves automatically\n\nAfter you sign in to Lema, save one Organization-scoped credential outside your\nrepositories. The normal setup contains identity credentials, not a copied\nworkspace UUID:\n\n```text\n# ~/.config/lema/credentials\nLEMA_API_URL=https://api.lema.sh\nLEMA_API_TOKEN=lema_live_...\n```\n\n```bash\nchmod 600 ~/.config/lema/credentials\nnpx lema-mcp@latest doctor context\n```\n\nRestart the coding agent after changing MCP configuration. From then on, Lema\nmatches the checkout's verified Git remote to a Repository, finds its Project,\nand passes one immutable target receipt to every operation. Opening two\nrepositories in parallel does not create a mutable “active repository,” and\neach user keeps their own Organization-scoped credential.\n\nFor multi-repo Projects, ambiguity recovery, repositories without a remote,\nworktrees, and compatibility overrides, read\n[Target context: Projects, repositories, and Runs](./docs/target-context.md).\n\n---\n\n## Two ways to use it\n\n### 1. The public record — React, Kubernetes, Rust (read-only, no account)\n\nAsk why a popular project decided something, or check whether a direction was\nalready rejected, over its recorded RFC/KEP deliberation. This is the `try` server.\n\n### 2. Your own repo — capture + never-reopen (local, no account)\n\nMost \"context\" tools are read-only — a nicer way to grep your docs. lema reads too,\nbut its real job is **never-reopen**:\n\n- Your agent settles a choice → it calls **`record_decision`** with the option it\n  chose **and the alternatives it rejected, with why each was killed** (the part\n  that never survives into the code).\n- Before anyone proposes a direction → **`check_decided`** returns the prior\n  decision if that option is **CLOSED**.\n- On every edit, a **PreToolUse guard hook** (installed by `init`) reads the draft\n  change and surfaces a CLOSED decision *before* the dead option gets re-proposed —\n  enforced off both your captured decisions **and the repo's own ADRs**.\n\nDecisions are captured to `.lema/decisions.jsonl` — a plain append-only file you\ncommit, so your whole team's agents share the same memory through git. No key, no\nLLM call on our side: your agent forms the decision; lema stores it and serves it\nback.\n\n#### What never-reopen looks like\n\nYour agent reaches for an option you already killed — and it comes back **CLOSED**,\nwith the original reason attached:\n\n> ⛔ **CLOSED — do not propose \"SWR\":** no first-class mutation / cache\n> invalidation — we'd hand-roll it *(decided 2026-06-04 · \"Data fetching for the\n> web app\" · chose TanStack Query)*\n\nSo the agent surfaces the prior decision instead of re-litigating it. Supersede a\ndecision and the *previously chosen* option goes CLOSED too — enforced both ways.\n(That's the real output of `npx lema-mcp demo`, run against a throwaway temp dir.)\n\nThe guard is **advisory and fail-open**: in its default `context` mode it injects\nthat note as a non-blocking nudge — it never hard-blocks and never auto-approves an\nedit. `LEMA_GUARD_MODE=ask` prompts *you* on a strong match; `off` is a kill switch.\nAny error → it emits nothing and gets out of the way.\n\n---\n\n## Available tools\n\nYour agent calls these over MCP.\n\n### The public record (no account)\n\n| Tool | What it does |\n|------|--------------|\n| **`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. |\n\n### Your own repo\n\n| Tool | What it does |\n|------|--------------|\n| **`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. |\n| **`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. |\n| **`search_decisions`** | Natural-language query → the most relevant atomic claims (chosen / rejected / constraint / consequence) with their source ADR, under a token budget. |\n| **`get_decision`** · **`list_decisions`** · **`get_decision_graph`** | One decision's full body; the list by status; traversal of typed edges (`supersedes`, `depends_on`, …). |\n| **`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. |\n| **`ask`** | One cited, synthesized answer over your team's **hosted** decision graph (hosted mode). |\n| **`get_state_brief`** | Resume a hosted Run with a Project-scoped brief: primary-repository state first, then ACL-filtered context from other visible repositories. |\n\nIn your own repo the full server registers the read + capture tools (and the public\n`check_approach` too); the `npx lema-mcp try` server runs the public door only.\n\n### `lema settle` — rule from the terminal (hosted mode)\n\nThe package also installs a `lema` command. `settle` is the terminal half of\nadjudication: it **drafts** a ruling on a hosted decision and prints the deep\nlink where your **browser click binds it** — a terminal credential never\nbinds anything (that split is structural: programmatic principals cannot\ncreate binding rulings, by design).\n\n```\nlema settle accept <decision-id>...              # draft an accept, print the bind link\nlema settle reject <decision-id> --reason <why>  # proposed drafts only; takes effect immediately\nlema settle supersede <decision-id> --by <decision-id>  # takes effect immediately\n```\n\n`accept` drafts; `reject` and `supersede` apply on the server in the same\nrequest (no browser confirm step exists for them — the command says so).\nDecision ids are full UUIDs or unique 6+ character UUID prefixes (`d_xxxxxx`\nlocators are content hashes and are refused). Requires hosted identity\ncredentials (`LEMA_API_URL` and `LEMA_API_TOKEN`). `LEMA_WORKSPACE_ID` is an\noptional CI, recovery, or ambiguity override—not normal repository setup.\n\n---\n\n## Why lema is different (the honest part)\n\nlema's brand *is* its honesty — that's what makes a \"why\" tool trustworthy:\n\n- **Abstain ≠ approval.** Silence is reported as silence. lema would rather say\n  \"no recorded ruling\" than manufacture one.\n- **Cited, summarized — not quoted.** Answers are grounded in recorded decisions and\n  paraphrased (\"the record indicates …\"), each claim tied to a followable ref.\n- **Local-first.** Capture and enforcement run entirely on your machine, in a file\n  you own. No key, no upload, no model call on our side.\n- **No fabricated graph.** A cold import writes no decision→decision edges and no\n  source-authored dates; lema shows what's actually on the record, nothing it can't\n  stand behind.\n\n---\n\n## Does enforcement change what the agent does?\n\nWe measured it on **two real public repos we didn't write** (Backstage, vite),\ntranscribing six of their documented decisions into `record_decision` format and\nrunning the **real `lema-mcp guard` binary** on the agent's draft edits. 168 trials,\n0 errors. The honest result is an **existence proof**, not \"agents are wrong 58% of\nthe time\":\n\n- On the one decision that cut against the 2026 frontier model (`node-fetch` →\n  native `fetch`), a blind agent re-proposed the killed library **58.3%** of the\n  time (14/24); lema drove it to **0%** — matching a docs-preloaded arm *without*\n  carrying the doc in context.\n- On the five decisions the model already gets right, lema stayed silent: **0%\n  re-proposal and 0% false-abstain** across 48 trials. No nagging.\n\nA public-repo benchmark *understates* the value — public decisions are\ndisproportionately the ones the model already absorbed in training. The decisions\nwhere enforcement moves the needle are proprietary, contrarian, recent,\nteam-specific. Full method and every raw trial:\n[`./docs/enforcement-lift`](./docs/enforcement-lift).\n\n---\n\n## Configuration & privacy\n\n- **`LEMA_GUARD_MODE`** — `context` (default, non-blocking), `ask` (prompt the human\n  on a strong match), or `off`.\n- **`LEMA_DISABLE_QUERY_LOGGING=1`** — drop query text from the usage log entirely.\n  Otherwise queries are scrubbed for credential-shaped substrings before logging.\n- **`LEMA_USAGE_LOG` / `LEMA_QUESTION_LOG` / `LEMA_GUARD_LOG`** — opt-in local log\n  files; all off unless set.\n- **`LEMA_API_URL` + `LEMA_API_TOKEN`** — hosted identity credentials. Environment\n  values take precedence over `~/.config/lema/credentials`.\n- **`LEMA_WORKSPACE_ID`** — validated explicit target for CI, recovery, or\n  ambiguity compatibility. Leave it unset for normal Git-backed repositories.\n\n<details>\n<summary><b>Subcommands & flags</b></summary>\n\n- **`init [dir]`** — wire a repo for capture: registers the server in `.mcp.json`,\n  appends a managed capture-protocol block to `AGENTS.md`, and installs three hooks\n  (a commit reminder, the `nudge` capture prompt on dependency-manifest edits, and\n  the `guard` never-reopen check). Idempotent.\n- **`try <react|kubernetes|rust>`** — wire the read-only public-demo server.\n- **`demo`** — a ~30-second never-reopen walkthrough against a throwaway temp dir\n  (nothing written to your repo). The fastest way to see the CLOSED behavior.\n- **`guard`** / **`nudge`** — the hook bodies `init` installs; advisory, fail-open,\n  always exit 0. You don't call them directly.\n- **`doctor context`** — resolve the current target and print only privacy-safe\n  evidence, redacted ID suffixes, and one corrective action.\n- **`context link --project ID --repository ID`** / **`context unlink`** — add or\n  recoverably remove a validated repository-local association for non-Git,\n  no-remote, or ambiguous checkouts.\n- **`serve`** (≡ `--http`, default `:4321`) — serve the engine over localhost\n  HTTP for the Lema Workbench GUI. This is not an MCP Streamable HTTP endpoint;\n  the supported MCP transport in this release is local stdio.\n\nWith no flags, lema auto-discovers a decisions directory (`docs/adr`, `doc/adr`,\n`docs/adrs`, `docs/decisions`, `docs/architecture/decisions`,\n`architecture/decisions`, `adr`, `.adr`) and an `openspec/` tree. Point it\nexplicitly with `--adr-dir`, `--repo github.com/org/name` (`GITHUB_TOKEN` for\nprivate), `--ref`, `--pattern`, `--openspec-dir`, or `--capture-file`.\n\n**Hosted retrieval (optional).** Set `LEMA_API_URL` + `LEMA_API_TOKEN` to point\n`search_decisions` at hosted hybrid retrieval over your full decision layer\n(search-only in the MVP). Capture and enforcement are always local.\n</details>\n\n---\n\n## License\n\nMIT. `lema-mcp` is the free, local wedge of [**lema**](https://lema.sh) — the system\nof record for *why*. The hosted decision graph, the team why-surface, and the\nmanager-facing Intelligence layer are at [lema.sh](https://lema.sh).\n",
  "bytes": 18560,
  "sha": "3a8bf325bedb7ccd206f66150a76df8e2df4b45f0f46b56a7cf7d4b773cc47b6",
  "repo_slug": "lemahq/lema-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_lemahq_lema_mcp_24ac682d/readme"
}