{
  "markdown": "<div align=\"center\">\n\n<a href=\"https://gntai.dev\">\n<picture>\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\".github/brand/wordmark-dark-bg.svg\">\n  <img src=\".github/brand/wordmark.svg\" alt=\"gnt\" width=\"220\">\n</picture>\n</a>\n\n[![License](https://shieldcn.dev/github/license/gnt-ai/gnt.svg?variant=secondary)](LICENSE) [![npm](https://shieldcn.dev/npm/@gnt-ai/cli.svg?variant=secondary)](https://www.npmjs.com/package/@gnt-ai/cli) [![Release](https://shieldcn.dev/github/release/gnt-ai/gnt.svg?variant=secondary)](https://github.com/gnt-ai/gnt/releases/latest) [![RepoGrade](https://www.repo-grade.com/api/badge/gnt-ai/gnt)](https://www.repo-grade.com/report/gnt-ai/gnt)\n\n</div>\n\nRun the setup below once and every agent your team runs has a **git-native rulebook** it has to check over **MCP** before it acts, approved the same way your code already is: a **merged pull request**.\n\n- Rules live in your repo as files and ship through normal PRs, not a dashboard click.\n- Agents call `check_action` over MCP before anything risky (a refund, a delete, a message to a customer) and get back an allow/block/escalate verdict.\n- Every rule traces back to the git file and the PR that approved it, so \"why did the agent do that\" always has a paper trail.\n\n> Prefer not to run any of this yourself? The hosted version at [gntai.dev](https://gntai.dev) does the same thing without you standing up a Postgres instance.\n\n## Get started (30 seconds)\n\n```bash\nnpm install -g @gnt-ai/cli\ngnt login\ngnt connect github\ngnt prebrain\n# merge the opened PR on GitHub. that merge is the approval\n```\n\n### Try it with Docker first\n\nTo see a real `check_action` response before installing Node or npm, clone\nthe repository and run the Docker-only demo:\n\n```bash\n./demo.sh\n```\n\nIt builds the full local stack in an isolated `gnt-demo` Compose project,\nseeds an approved refund rule, calls `check_action`, and prints a curl command\nyou can run again. Without an Anthropic key the real fail-closed path returns\n`needs_human`; pass `GNT_DEMO_ANTHROPIC_API_KEY=sk-ant-... ./demo.sh` to opt in\nto the model's grounded policy verdict. The demo uses deterministic local embeddings and\nthrowaway localhost-only secrets, so it does not need a ZeroEntropy key.\n\n![gnt connect's interactive picker, and what gnt prebrain's draft-PR output looks like](.github/assets/cli-demo.gif)\n\n> Nothing for `gnt prebrain` to scan yet? Run `gnt init` first — it scaffolds `rules/` locally\n> with a couple of example rule files so there's something real to look at and edit, and points\n> you at `gnt prebrain --starter-packs` for a curated pack to start from instead.\n\nThat merge lands a rule file in your connected repo, shaped like this:\n\n```\nyour-repo/\n└── rules/\n    ├── refund-approval-threshold.md\n    └── contract-legal-cc.md\n```\n\nEach file is plain markdown with YAML frontmatter:\n\n```markdown\n---\ntitle: Never refund over $500 without a manager\nstatus: approved\nconfidence: 0.91\nowner_id: finance-team\nsource_citations: [...]\nsource: slack\ntags: [refunds, finance]\nlast_validated_at: 2026-07-20\nversion: 1\nsuperseded_by: null\napproved_by: jane@company.com\napproved_at: 2026-07-21T14:03:00Z\ncreated_at: 2026-07-18T09:12:00Z\npr_number: 142\npr_url: https://github.com/your-org/your-repo/pull/142\n---\n\nRefunds over $500 need manager sign-off before they go out...\n```\n\n## See it in action\n\nThere's no captured transcript to show yet (see the gap noted at the bottom of this README).\nHere's the actual response shape a `check_action` call returns, straight from the tool's\ncontract:\n\n```json\n{\n  \"verdict\": \"blocked\",\n  \"reason\": \"Refund exceeds the $500 threshold without manager sign-off (rules/refund-approval-threshold.md)\",\n  \"cited_rules\": [\n    { \"id\": \"refund-approval-threshold\", \"title\": \"Never refund over $500 without a manager\" }\n  ],\n  \"rules_retrieved\": 3\n}\n```\n\n`verdict` is one of `allowed`, `blocked`, or `needs_human`. `needs_human` is the fail-closed\ndefault: no approved rule covers the action, retrieval failed, or the check couldn't complete.\nIt never guesses.\n\n## What it does\n\nOne MCP endpoint, five tools:\n\n| Tool | What it does |\n| --- | --- |\n| `check_action` | Checks a described action against your approved rules before an agent takes it. Returns `allowed`, `blocked`, or `needs_human` with cited rules and a one-line reason. |\n| `search_rules` | Semantic search over your org's approved rules, optionally filtered by tag. An empty list means no approved rule covers the query. |\n| `get_rule` | Fetches one approved rule by id, with its provenance (who approved it, when, what it was cited from). |\n| `list_skill_packs` | Lists every compiled skill pack version for your org, newest first. |\n| `get_skill_pack` | Fetches a compiled skill pack's manifest and file list by id. |\n\n## Prerequisites\n\n| Requirement | Check | Get it |\n| --- | --- | --- |\n| Node >=22.13 | `node --version` | [nodejs.org](https://nodejs.org) |\n\n## Install\n\n| Method | Command |\n| --- | --- |\n| curl | `curl -fsSL gntai.dev/install.sh \\| sh` |\n| npm | `npm install -g @gnt-ai/cli` |\n\n> gnt needs Node >=22.13. If the CLI fails to start with a version error, update Node first and confirm with `node --version`.\n\n## Common commands\n\n```bash\ngnt login                # sign in, store an API key locally\ngnt init                 # scaffold a local rules/ dir with example rule files\ngnt connect github       # connect the repo your rules PRs open against\ngnt prebrain             # scan sources, extract candidate rules, open PRs\ngnt review               # review rules awaiting approval\ngnt status               # show brain status\ngnt pull                 # download the latest skill pack\ngnt gaps                 # list uncovered queries with no approved rule\n```\n\n## Config\n\n| Variable | Default | What it controls |\n| --- | --- | --- |\n| `GNT_API_URL` | `https://api.gntai.dev` | API endpoint the CLI and MCP calls hit |\n| `GNT_WEB_URL` | `https://gntai.dev` | Web app used for `gnt login`'s browser step |\n| `GNT_CONFIG_DIR` | `~/.gnt` | Where `credentials.json` and local config live |\n\n## Privacy\n\n- No analytics or telemetry dependency in the CLI or the web app.\n- `gnt prebrain`'s default extraction mode is cloud, not on-device: your source text goes straight to Anthropic's API (or Vercel AI Gateway with zero-data-retention, if you configure it), never to gnt's own servers. Fully on-device extraction needs `--mode local` against a local Ollama daemon.\n- The extracted rule candidates still get sent to gnt's API to open the PR. Raw source text stays off gnt's servers in cloud mode; the resulting rule text doesn't.\n- Rules live in your connected GitHub repo and in gnt's own database. The MCP tools read from gnt's store, not by cloning your repo on every call.\n- Self-hosting: `apps/api` only sends error data to Sentry if you set `SENTRY_DSN` yourself. Leave it unset and nothing goes out.\n\n## Team setup\n\n- **Who writes rules**: anyone with access to your connected repo, either through `gnt prebrain` (batch-extracted from real sources) or `gnt review` (hand-proposed).\n- **How approval works**: merging the PR is the approval. There's no separate publish step.\n- **What gets committed**: `rules/<rule-id>.md` files with the frontmatter shown above and a plain markdown body.\n- **Catching a malformed rule before it's reviewed**: `gnt rules lint` checks a rule file's frontmatter locally, and [`gnt-ai/gnt/.github/actions/lint-rules`](.github/actions/lint-rules) runs the same check as a CI step on your rules repo's own PRs, so a bad frontmatter fails the PR instead of the review.\n\n## Troubleshooting\n\n> **Self-hosting: `gnt login`'s browser step has nowhere to land.** `gnt login` opens a browser to a `/cli-login` page and polls the API for the resulting key — that page is served by the hosted product's web app, which isn't part of this repo. There's no CLI-only login flow (device code or otherwise) today, and no `gnt` command to set a key manually. Self-hosting this stack currently means building your own thin frontend for that one route (it just needs to complete the sign-in flow and hand the CLI a key). This is a real, open gap in the self-host path, not a config issue — closing it properly means adding a CLI-only login flow.\n\n> **`ValueError: refusing to start: these settings still have their .env.example placeholder value...`** A `change-me-...` string is still sitting in `apps/api/.env`. The error names every offending field; generate a real value for each and retry.\n\n> **`store` fails to start with `GNT_STORE_INTERNAL_API_SECRET is not set`.** `apps/store/.env` wasn't filled in, or wasn't picked up. Confirm the file exists at that exact path, not still named `.env.example`.\n\n> **Every store-to-api call gets rejected with 401 or 403, even though both services are up.** `STORE_INTERNAL_API_SECRET` / `APPROVAL_SIGNING_SECRET` in `apps/api/.env` don't byte-for-byte match `GNT_STORE_INTERNAL_API_SECRET` / `GNT_APPROVAL_SIGNING_SECRET` in `apps/store/.env`. This fails closed by design. Regenerate both pairs so the two files agree.\n\n> **A rule fails to save with an embedding or rerank error.** `apps/store/.env` is missing `ZEROENTROPY_API_KEY`, or it's still empty. Get a real one from zeroentropy.dev.\n\n## Full command reference\n\n```\ngnt login\ngnt logout\ngnt init                 scaffold a local rules/ dir with example rule files (--dir <path>)\ngnt connect <app>        github, slack, notion-mcp, monday-mcp, linear-mcp, jira-mcp,\n                          sentry-mcp, granola-mcp, zoom-mcp, figma, datadog,\n                          gitlab-threads, hubspot, airtable, openclaw, hermes\ngnt disconnect <app>\ngnt status\ngnt billing\ngnt review\ngnt pull\ngnt gaps\ngnt prebrain              scan local sources, extract candidate rules, open batched draft\n                           PRs (~60 flags for source paths and extraction mode, see\n                           `gnt prebrain --help`; --mode cloud|local, cloud is the default)\ngnt stale\ngnt keys list|create|revoke|rotate\ngnt webhook list|create|revoke\ngnt org show|rename|invite|remove\n```\n\n### Shell completion\n\n```bash\n# bash, add to ~/.bashrc\neval \"$(gnt completion bash)\"\n\n# zsh, add to ~/.zshrc\neval \"$(gnt completion zsh)\"\n\n# fish, add to ~/.config/fish/config.fish\ngnt completion fish | source\n```\n\n## Learn more\n\n- Self-hosting walkthrough, including the production-hardening path: [`docs/self-hosting/README.md`](docs/self-hosting/README.md)\n- Security policy: [`SECURITY.md`](SECURITY.md)\n\nSelf-hosting is a first-class, fully supported path — Apache-2.0 from day one, run it on your own infra with your own keys, or use the hosted version at [gntai.dev](https://gntai.dev). The homepage FAQ and the self-hosting docs both describe this same path; there is no \"not today\" caveat.\n\n## License\n\nCopyright © 2026 gnt.ai. Licensed under Apache-2.0 — see [`LICENSE`](LICENSE) for the terms and [`NOTICE`](NOTICE) for the trademark rule on forks.\n\n### Why is this free?\n\nSelf-hosting gnt costs you nothing, forever — clone it, run `docker compose up`, bring your own keys. What we sell is the part self-hosting doesn't give you: hosting at [gntai.dev](https://gntai.dev), managed OAuth connectors (GitHub, Slack, Linear, Notion, Zendesk — no app-approval process on your end), and usage-based AI features. If you'd rather run it yourself, that's a fully supported, fully free path, not a crippled trial of the real thing.\n\n## Contributing\n\nSee [`CONTRIBUTING.md`](CONTRIBUTING.md) for dev setup and how to open a PR. Every commit needs a `Signed-off-by` trailer (`git commit -s`), the [Developer Certificate of Origin](https://developercertificate.org/) instead of a CLA. No separate form, just the flag.\n\nThanks to everyone who's sent a PR:\n\n<a href=\"https://github.com/gnt-ai/gnt/graphs/contributors\">\n  <img src=\"https://contrib.rocks/image?repo=gnt-ai/gnt\" alt=\"gnt contributors\" />\n</a>\n\n<div align=\"center\">\n\n[![Discussions](https://shieldcn.dev/badge/discussions-github.svg?variant=secondary)](https://github.com/gnt-ai/gnt/discussions) [![Issues](https://shieldcn.dev/github/issues/gnt-ai/gnt.svg?variant=secondary)](https://github.com/gnt-ai/gnt/issues) [![Code of conduct](https://shieldcn.dev/badge/code%20of%20conduct-CODE_OF_CONDUCT.md.svg?variant=secondary)](CODE_OF_CONDUCT.md)\n\n</div>\n",
  "bytes": 12275,
  "sha": "9f8ca0b7e18bd147d838b101900c9c4b3bbf4e6b151c1f4633660e84d579b998",
  "repo_slug": "gnt-ai/gnt",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_gnt_ai_gnt_10a21af2/readme"
}