What you, your agents, and your machines can jointly do — and where your own time is going.
Developer toolsTypeScript · CSSGitHub @zz-plantOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The meta-MCP capability graph for AI agent environments
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
What you, your agents, and your machines can jointly do — and where your own time is going.
One setup, mapped. Pick a tool and Ambit shows what depends on it; switch it off and it shows the fourteen things that stop working with it. Then which tools interrupt you most, and a change waiting on your approval.
brew install zz-plant/tap/ambit && ambit, or open the hosted demo and install nothing.
If you use AI agents, your setup is spread across LLM providers, MCP servers, local CLI tools, skill directories, credentials, and more than one machine. Every piece has its own config file.Read the full README ↗What you, your agents, and your machines can jointly do — and where your own time is going.
That is your ambit. Ambit reads the configs of Claude Code, Cursor, OpenCode and the other agent runtimes it knows into a local capability map: what you can do now, what one more step would unlock, and which configured tools are not working.
Try the live demo · Get started · Connect it to your agent · FAQ · Docs
One setup, mapped. Pick a next step and Ambit shows what it would open: two more capabilities. Pick one you rely on and switch it off, and it counts the nine working things that would stop with it. Then which tools interrupt you most, and a change waiting on your approval.
npx ambit-cli, or brew install zz-plant/tap/ambit && ambit, or open the hosted demo and install nothing.
An ambit (from Latin ambitus: circuit, perimeter, sphere of action) is the boundary of what someone can reach. Working with agents, yours is set by a stack spread across LLM providers, MCP servers, local CLI tools, skill directories, credentials and machines, each with its own config file.
What an agent setup can do is not written in any configuration file. It is composed from pieces configured separately, a configured piece may not work, and none of it says what the setup is allowed to do. Ambit computes that reach and helps you widen it: a declared check says whether a piece works, a grant you set says what may run without asking, and a work ledger records whether a change saved you time.
Ambit reads those configs into one model, the capability graph. Every server, model, skill and declared credential is a node, as is every capability of the curated tree, and an edge records what one needs from another or provides to it. My Setup lists what your configs declare, and the map draws the curated tree with your position on it. The edge of what you reach is the frontier, with the next steps just past it. From the graph, Ambit answers:
ambit verify) and keeps installed ≠ working ≠ authorized. An unverified capability stays available; one whose check fails is left out of plans and permissions until it passes again.You ask from the terminal. Your agents ask over MCP: what they can do before they try, and when they hit a limit, what would lift it, drafted as a change you approve. Ambit is itself an MCP server, speaking the same protocol as the tools it reads: a meta-MCP server.
The terminal and the map use the same words.
ambit goal. Blocked means a required prerequisite is missing.ambit status reports these as proven. Reached is a fact about the config; verified is a fact about a check that ran.combo:.Anyone running AI agents who wants them to do more. On a small setup, one runtime and a few MCP servers, Ambit mostly answers what to add next, and what a single missing prerequisite would open. On a larger one, with several runtimes, dozens of servers and a second machine, it mostly answers which configured tools fail their checks and what would stop with them.
The demo opens on a sample setup's next step, lighting what it would open, and asks which agent you use. Paste that agent's config, or tick the servers it runs, and yours is placed on the same map with nothing uploaded: how much of the tree it reaches and the three next steps worth taking, ranked as npx ambit-cli ranks them on the machine itself. The rest of the sample is there for whoever asks: the outage that shows what that reach rests on, a check that was already failing, and the approval every change waits for.
| Way in | What it gives you |
|---|---|
| In the browser | Open the hosted demo for a sample setup, or drop in your own MCP config from Claude Code, Claude Desktop, Cursor, Windsurf, Gemini CLI, Cline, Roo Code, Copilot CLI, Kiro or OpenCode, and it is placed on the map in the tab, uploading nothing, with what one more step would open for it. No file at hand? Tick the servers you run. |
| On your machine | npx ambit-cli (Node 22.18 or newer), or brew install zz-plant/tap/ambit && ambit, reads your real agent configs, names what it found, and shows what one more step would open. It ends on one thing to do, npx ambit-cli web: the same readout on the map, served on localhost. npm install -g ambit-cli puts ambit on your path. |
| With the map | git clone https://github.com/zz-plant/ambit.git && cd ambit && ./bootstrap.sh web builds the graph from your own configs and serves the map the pictures on this page show. |
| In a cloud IDE | A full checkout with the map running, in a browser tab, touching nothing on your machine. The container holds none of your configs, so the map it shows has nothing of yours on it: a way to try the code, not to map your setup. |
| From your agent | Register Ambit over MCP and the agent can ask what it is able to do before it tries. Connect it to your agent has the snippet. |
npm and Homebrew install the tagged release, on macOS or Linux. ./bootstrap.sh discovers OpenCode, Claude Code, Cursor, Windsurf, Gemini CLI, Claude Desktop, Codex CLI, Cline, Roo Code, Continue, Zed, VS Code, Copilot CLI, Amp, Goose and Kiro, the skill directories ~/.agents/skills, ~/.opencode/skills and ~/.config/opencode/skills, and the models Ollama and LM Studio keep on disk, builds a local SQLite graph, prints the same readout npx ambit-cli does, and links ambit into ~/.local/bin when that directory is on your PATH (or prints the ln -s line when it is not). ./bootstrap.sh --dry-run writes nothing: it reports whether there is an OpenCode config, a running Ollama and a skills directory.
Ambit sits above the protocol layer and below workflow orchestration. Its CLI, MCP server and gate neither route an agent's calls nor run them. The one part that can run an agent's step is the control plane, which you start yourself from a checkout, and only with its opt-in Docker adapter.
| System | Finds a tool | Knows prerequisite order | Tells working from configured | Prices human attention | Gates what an agent may do |
|---|---|---|---|---|---|
| Vector tool-RAG | by similarity | – | – | – | – |
| Workflow state machines (LangGraph) | – | within one task | – | – | within one task |
| Package managers (Nix, Homebrew) | – | for binaries | – | – | – |
| Flat MCP catalogs (Smithery, registries) | by name | – | – | – | – |
| Ambit | by what it needs | across the whole host | ✓ declared checks | ✓ work ledger | ✓ authority contracts, signed approvals |
For the architectural foundation, economic loop, and comparison to prior work, see The ideas behind Ambit, Your loadout, from A to B, and Building alone.
| Command | What it answers |
|---|---|
ambit status | Environment health: what is reached and how much of it is proven, what is failing its declared check, what has a single provider, pending approvals, and the one command to type next |
ambit goal <name> | The path to unlock a capability, in order, with setup estimates |
ambit impact <id> | What downstream stops working if this dependency fails |
ambit graph combos | Compound capabilities, including the ones you are one prerequisite away from |
ambit authority | Per-action permissions: what runs unattended, what needs confirmation |
ambit verify [id] | Run a capability's declared check and record whether it passes |
ambit weigh | What each tool server's tool list costs in context every session, per runtime, and which ones the ledger never saw called |
ambit history [since <when> [<until>]] | How the frontier moved, separating what you acquired from what emerged |
ambit share | A self-contained HTML snapshot of the map, written locally and safe to post |
ambit help covers a first session, ambit help --all the full surface, and ambit help <term> one concept.
The commands above read the capability graph. A second group (attention, work, usage, opportunities, roi, audit) reads a local work ledger: the human time and cost of running the stack. Until sessions are recorded they say which data is missing instead of printing a number, and they say more once a few weeks are recorded. The FAQ explains how to start recording.
$ ambit status
15 of 46 reached, and 24 of your own · 0 proven · 8 with a single provider
────────────────────────────────────────────────────────────────────────
proven 0
› unproven 15 11 provable now · 4 with no check
failing 0
entries 24 from your config; checks run on what they provide
last check never
actions: 18/66 reached
provable now: Automated Tests, Browser Automation, Code Intelligence, Continuous Delivery, Data Access, File Editing, Local Runtime, Shell Execution and 3 more
reach: 15 of 46 capabilities reached, and 24 of your own
domains:
████░░░░░░ ai-ml 5/13
██████░░░░ backend 7/11
…
Next ambit verify · turns 11 of the unproven into evidence
This is a fresh graph, before any check has run: reached and proven lead, the curated capabilities first and then the servers, models and runtimes of your own, the four counts under the rule add up to the two reached figures together, the › marks the count that wants a person, and the last line names the next command to type. CI captures the block from a fixture graph and fails if it drifts from what the command prints.
$ ambit impact mcp:playwright
If playwright went away
───────────────────────
› Stops working Automated Tests, Browser Automation, Continuous Delivery, Observability · and the 3 actions they confer
Survives Tool Protocol (12 other providers)
Affected capabilities are listed first, marked with ›, through the full dependency chain: if Continuous Delivery requires Automated Tests, it fails as well. Surviving capabilities show their remaining provider count, accounting for shared credentials that would fail together. Given a credential, impact answers what revoking it ends, matching ambit credentials.
ambit share builds its HTML from an allow-list: name, kind, category, domain, era, state, lifecycle, edges. Commands, URLs, paths, descriptions and economics cannot enter the file, people render as "a person", and --redact replaces every non-curated name with its category. Nothing is uploaded; writing the file locally is the whole command.
--json prints any answer as data, color is drawn only on a terminal, and the exit code says whether the command worked. Two commands can gate a script the way git diff --exit-code does:
ambit can shell-execution --exit-code # 0 go ahead, 1 put it to the person, 2 stop
ambit verify shell-execution --exit-code # 1 unless every check that ran passed
The CLI reference has every exit code and flag.
You can try Ambit before connecting it to anything: ambit status reads local agent configs and session token logs (Claude Code, Codex, OpenCode, Amp) and writes only to Ambit's own database (~/.local/share/ambit/graph.db). It modifies no configuration file and makes no network request, and deleting that file removes what it recorded. llms.txt outlines when an agent should recommend Ambit, and For agents shows session metrics from before and after.
Install the plugin from the marketplace:
claude plugin marketplace add zz-plant/ambit
claude plugin install ambit@ambit
Then type /ambit in a session for the readout of your own setup: what it read, how much of the tree that reaches, and the step that would open the most. The plugin registers the MCP server, gives the agent a briefing at session start, and logs tool execution and approval spans to ~/.local/state/ambit/claude-code.jsonl. It reads token usage from local session logs without writing to them. To disable recording, set AMBIT_NO_LEDGER=1.
To register manually without the plugin:
claude mcp add ambit -- ambit mcp --profile=agent
--profile=agent advertises ten tools, the planning and verification ones an agent uses to check before it acts, in about 4.4KB of prompt context. Omitting the flag advertises every tool (~19.5KB). The server answers an unlisted tool by name either way, but most clients call only what they were shown, so under --profile=agent the connect instructions send the agent to the ambit command for the rest: single points of failure, budgets, incidents, the audit trail, everything ambit help --all lists. The deep dive lists every tool and explains how calls are dispatched.
ambit-gate@ambit is a companion plugin that puts ambit gate on every tool call, so what you refused or set to ask first in Ambit is denied or put to you. The hook block below does the same by hand.
Ambit also publishes ambit://briefing, a resource a client reads on connect: what is reached and proven, what is failing, what is waiting on you, what blocked work in the last week, and what is worth reaching next with what each step would reach, in about 1,200 tokens. To put it at the top of every session yourself, add a hook to ~/.claude/settings.json:
{
"hooks": {
"SessionStart": [{ "hooks": [{ "type": "command", "command": "ambit briefing" }] }],
"PreToolUse": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "ambit gate", "timeout": 10 }] }]
}
}
The PreToolUse hook binds Ambit's gate to Claude Code. Before each tool call, ambit gate identifies the capability exercised: forbidden actions are denied, actions requiring human confirmation prompt the user, and permitted or unmapped actions defer to Claude Code's standard permission flow. The gate can only restrict permissions, never expand them. It adds about 130 ms per call (measured with 0.6.0 on an Apple M1 Max). Run ambit gate directly in a terminal to inspect its output.
ambit statusline prints a segment for Claude Code's status bar, refreshed after each message: failing checks, pending proposals, and verified capability counts (e.g. ! 1 failing: Browser Automation · › 2 proposals to decide). Inactive categories are omitted, so a healthy graph displays 12 verified. It queries the database read-only, writes nothing, and returns in about 80 ms (measured with 0.6.0 on an Apple M1 Max). Because plugins cannot configure status lines automatically, ambit connect claude-code --statusline adds the entry to ~/.claude/settings.json, backing up the existing file to settings.json.bak and never overwriting a status line you already have. To configure manually:
{ "statusLine": { "type": "command", "command": "ambit statusline" } }
Claude Code runs one status line command. To keep yours and add Ambit's, save these two lines as a script, with your command in place of npx ccstatusline, and point command at the script:
input=$(cat)
printf '%s %s\n' "$(printf '%s' "$input" | npx ccstatusline)" "$(printf '%s' "$input" | ambit statusline)"
ambit connect opencode adds the entry to ~/.config/opencode/opencode.json in whichever shape the file already uses, OpenCode 1's or 2's, and keeps what the file held in opencode.json.bak first. A file with comments is left alone, since writing it back would delete them. By hand, in OpenCode 1's shape:
{
"mcp": {
"ambit": {
"type": "local",
"command": ["ambit", "mcp", "--profile=agent"],
"enabled": true
}
}
}
OpenCode 2 puts the same entry under mcp.servers, with "disabled": false in place of "enabled": true.
Both clients assume ambit is on your PATH. Homebrew and npm install -g ambit-cli put it there, and bootstrap.sh does when ~/.local/bin is already on your PATH. Otherwise use npx -y ambit-cli mcp --profile=agent, or the absolute path to cli.js. An agent can read the map, ask what a goal is missing, and propose a configuration change. Applying one always requires an approval, and approving is a separate local operation, not an MCP tool.
ambit connect cursor adds the server to ~/.cursor/mcp.json. With --ledger it also adds a hook to ~/.cursor/hooks.json on four events, beside any hooks already there, keeping what the file held in hooks.json.bak; --dry-run prints the hook's command and events and writes nothing. The hook appends one line per event to the file the Claude Code plugin writes, ~/.local/state/ambit/claude-code.jsonl: when it ran and the conversation's id; for a shell command or MCP call that ran, the server's and tool's names and how long Cursor says it took, your wait for approval left out; for a failed call, Cursor's id for it, its error text, its failure kind and whether you stopped it; and why a conversation ended. Never a command's text or output, an MCP call's arguments or result, a file, your prompt or your email. Cursor's hooks report no token counts and no approval prompts, so a Cursor run records neither. The hook asks Cursor for nothing, so it can neither block a call nor allow one, and AMBIT_NO_LEDGER=1 turns it off. By hand, with the path the dry run prints:
{
"version": 1,
"hooks": {
"afterShellExecution": [{ "command": "node /path/to/ambit-cli/plugins/cursor/ambit-ledger.mjs", "timeout": 5 }],
"afterMCPExecution": [{ "command": "node /path/to/ambit-cli/plugins/cursor/ambit-ledger.mjs", "timeout": 5 }],
"postToolUseFailure": [{ "command": "node /path/to/ambit-cli/plugins/cursor/ambit-ledger.mjs", "timeout": 5 }],
"sessionEnd": [{ "command": "node /path/to/ambit-cli/plugins/cursor/ambit-ledger.mjs", "timeout": 5 }]
}
}
Before running a tool you have not used this session, call
ambit_canwith the capability. Onyes, act. Onask, put it to the person. Onno, it has already recorded the deficit, so do not retry it under another name.
The server sends this instruction in the MCP handshake. For clients that do not expose server instructions to the model context, ambit init-rules writes the guidance into CLAUDE.md, AGENTS.md, or .cursorrules. Agents with shell access but no MCP connection can check permissions using ambit can <capability> --exit-code. A refusal is recorded as a deficit in the work ledger, and a deficit that recurs moves up the ranking of what to set up next.
./bootstrap.sh web serves five views over the graph the CLI reads.
Selecting a node displays downstream dependencies that fail if it goes down, or missing prerequisites and estimated setup times needed to reach it. Simulate an outage renders that cascade, filled red for broken dependencies, a red outline for unconfigured nodes, and amber for capabilities losing redundant providers. Simulate unlocking highlights nodes made reachable by acquiring a single prerequisite. Neither simulation writes data. Three lenses filter the map: Standard (reached, next step, blocked), Attention (tools causing frequent human interruptions), and Authority (unattended, human confirmation required, forbidden).
When an agent proposes a configuration change over MCP, the Proposals view shows it as a plan before you sign: its steps, which of them cannot be undone, the capabilities it would unlock, its costs, and earlier approvals that bear on it. Approving creates a signed artifact, and ambit apply writes the change into Claude Code, Cursor, OpenCode or whichever runtime --to names, or prints that runtime's own command where it cannot.
The reference covers the rest: what each mark means, focus, the minimap, the timeline that replays the map as it was, deciding several drafts at once, and pushing one to your phone.
Discovery reads your host configs into an embedded SQLite graph, and three surfaces read it back out: the CLI, the MCP server and the map. Discovery, verification and the work ledger write to the graph. Your agent configuration changes only through a proposal you approve, or through the map's switch for an entry that already exists, which cannot create one.
Each client is read from its own standard config path, and every server stays attributed to the client that listed it. If two runtimes reference the same server, Ambit models it as a single capability with two providers, so one binary listed twice is not counted as redundancy. Local models are found in the folders Ollama and LM Studio keep on disk, so neither server has to be running. Each is filed under a local provider, keeping it separate from hosted inference costs.
Discovered capabilities are placed in a curated tree of nine eras: seven for the agent setup, from Foundation and Model Access through Tool Use, Memory, Autonomy and Assurance to Sovereignty, and two for the product it builds, Product (hosting, a production database, accounts, payments, email) and Operations (error tracking, analytics, uptime, backups, and Launch Ready, reached when the launch checklist is done). Each capability names its prerequisites, so what is reached is computed from them, not taken from what a config claims.
Ambit keeps two properties apart:
state is structural: is this thing configured, and what does it depend on. This is what the frontier ledger records.lifecycle is health: did its declared verification command actually pass. A capability can be fully configured and still broken, or degraded, which means it is recovering: its last check passed after one that failed.Availability is decided by lifecycle, not state, and a check can only take availability away: an unverified capability stays in plans, and one whose check fails is excluded from plans, simulations, goals, authority checks, and opportunity rankings. A single successful check restores a broken capability to unproven status, and it is marked as recovering until five consecutive checks pass. ambit status reports proven, unproven and failing counts, and the map badges each reached node: ✓ for a passing check, ! for a failing one, nothing for configured but never verified, or recovering.
credentials block enables ambit impact credential:... to analyze revocation impact.Ambit answers whether a step may run wherever it is asked, and the answer binds in three places: ambit apply, always; this interceptor, for execution routed through it; and Claude Code's tool calls, once the ambit gate hook is installed. Other runtimes choose whether to ask ambit_can.
It runs from a checkout. The interceptor is a reference implementation and not part of the ambit command, so npm and Homebrew do not install it. In a clone, npm run demo:incident replays the walkthrough at the end of this section on a throwaway graph, and node --experimental-sqlite src/control_plane/cli.ts --help lists its commands. exec <envDir> <dbPath> '<request>' routes one step through the gate against the graph at dbPath. The others serve the walkthrough: setup-env writes its fixture actors and capabilities into the graph it is given, replacing any row with the same id, and verify-node sets a lifecycle with no check run, so point both at a new file and never at the graph ambit where prints.
Host-level agent tooling is a real attack surface, so the interceptor can stand between an agent and the shell. Before a tool call routed through it reaches your machine, the proxy in src/control_plane/proxy.ts verifies three conditions: prerequisite capabilities are present, the capability is verified and functioning, and the caller has explicit authorization. A call that fails any condition is refused (AMBIT_BLOCKED_UNAUTHORIZED, exit code 2) and leaves system state unchanged. Blocked calls generate a draft proposal and an HMAC challenge; ambit approve <proposal-id> --by=<person> creates a signed authorization artifact verified by the executor, which expires or invalidates if the proposal is modified. Spans record each evaluation, challenge, and receipt.
The decision runs against the graph you name. What sits on the other side of the gate is chosen when the control plane starts, and every span names it. The default, simulatedAdapter, is a fixture: it merges the change into a JSON file and runs nothing.
AMBIT_ADAPTER=docker, or --adapter=docker on src/control_plane/cli.ts, puts a Docker adapter there instead, and an approved step's payload.command runs in a throwaway container. The approval names the command: the step a person signs shows it, and a retry carrying a different one is refused. Break-glass runs nothing there, since an agent cannot authorise its own command. Each step gets its own container from an image you pulled yourself (alpine:3.20 unless AMBIT_DOCKER_IMAGE names another), with no network, a read-only root, every Linux capability dropped, an unprivileged user, and limits on memory, CPU and processes. The container is removed afterwards and its output, capped, comes back in the result; a step that exits non-zero ends the run as failed. A step reaches the network only when you started the control plane with AMBIT_DOCKER_NETWORK=bridge and a grant for the network action on its capability answers ALLOW. Nothing from the host is mounted unless AMBIT_DOCKER_WORKDIR names a directory, which is mounted read-only, and never your home directory, its dot-directories or the Docker socket. If Docker cannot run the step, the control plane refuses before anything runs and does not fall back to the simulator.
Neither adapter deploys anything anywhere. Another one (Kubernetes, a deploy API) implements the same three-method EnvironmentAdapter, and nothing above the gate changes. INCIDENT_TRACE_001 walks a deploy agent blocked mid-flight and then remediated, and npm run demo:incident replays it in 90 seconds; with AMBIT_ADAPTER=docker the authorized deploy runs echo in a container.
Ambit reads developer toolchains and writes to agent configs, so the properties below are fixed. SECURITY.md states each in full, with what is in scope and what is not; AGENTS.md says where each is enforced.
127.0.0.1. No LAN, no tunnel.Origin is not Ambit's own page, a page on another localhost port included, is rejected with 403 before routing, because a simple request skips preflight and response headers alone would not stop it.llms.txt: the project in one page, for an agent that is deciding whether to recommend it.New capability models, runtime readers, visualization work and edge-case reports are all welcome. Issues labelled good first issue are scoped to an afternoon and name the files to start from. CONTRIBUTING.md gets you from a clone to a passing pull request and lists every check CI runs.
Ambit is a personal project. If it answered a question your config files could not, a star is how the next person with the same stack finds it.
ambit share --redact snapshot of your map. Paths never enter the file and --redact replaces every name the tree did not supply with its category, so a real setup can be shown without naming it.MIT © Kanav Jain