Get a scoped key
Keys live in the dashboard under Project → Connect → Agents. They are scoped to a single project and revocable, never a root credential, and every call made with one is rate-limited, quota-tracked, and written to the project's change ledger.
Decide read-only or read-write when you mint the key, because an agent cannot change its own and no endpoint flips an existing one. A read-only key is served 6 tools instead of 20 — `read_backend_state`, `get_table_schema`, `run_query`, `generate_types`, `fetch_docs`, and `check_approval`. Every write door is withheld, `backend_chat` included, because the brain can apply non-destructive changes without ever reaching the destructive gate, so a key that could reach it would not be read-only. Calling a mutating tool anyway is refused with `READ_ONLY_KEY` before it runs, and nothing is partially applied.
Pick a transport
Two transports, the same 20 tools behind both. Local runs the npm package over stdio and works in every host. Remote is Streamable-HTTP straight to Backenly, with nothing to install and no Node process on your machine.
claude mcp add backenly -- npx -y @backenly/mcp-server --project <PROJECT_ID> --key <KEY>claude mcp add --transport http backenly https://backenly.com/api/mcp --header "x-api-key: <KEY>"For a host that configures MCP through a file rather than a CLI, the Connect → Agents tab renders the exact config for Cursor, Codex, and Cline with your project id and key already filled in. Three host-specific details are worth knowing before you hand-write one:
- Cursor infers the transport from the presence of a `url` key, so a remote entry needs `url` + `headers` and no `type` field.
- Cline remote must set `"type": "streamableHttp"` — camelCase, no hyphen. Omit it and Cline falls back to the legacy SSE transport and gets a 405 from our Streamable-HTTP endpoint. This is the most common Cline setup failure.
- The Codex CLI has no header flag, so an `x-api-key` server can only be configured by editing `~/.codex/config.toml`, where headers live under `http_headers`. If it is not picked up, add `[beta] rmcp = true`.
If you would rather be walked through it, the package has an interactive setup that verifies the key against the live manifest before it writes any config:
npx @backenly/mcp-server init
✓ Verified. Connected to project 4f2a… (20 tools).
Setup complete. Restart your MCP host and Backenly is wired in.Restart the host — this is not optional
MCP hosts connect their servers at process start and read each manifest once. A server registered mid-session is written to config and connected to nothing, so Backenly's tools are absent from the session that installed them. No amount of retrying changes that.
This matters more than it sounds, because of what a capable agent does next. Told to install the server and then call a tool, it installs the server, finds no tools, and improvises a way to reach us anyway — a stdio bridge, a raw HTTP call with the MCP key. The permission classifier blocks those, and you watch three failures scroll past in the first minute of using the product. Nothing is broken. The instructions asked for something impossible.
- VS Code family — Claude Code, Cursor, Cline: Reload Window.
- Codex CLI: quit and relaunch.
- Claude Desktop: quit and reopen.
Verify it connected
After the restart, ask for a read. `read_backend_state` is the one read door for project state and it is on the advertised surface, so it is a safe first call:
Call Backenly's read_backend_state tool and tell me what exists in this project.A fresh project answers with almost nothing, and that is correct rather than broken. A new project has a `users` table and no exposed REST resources, because `/db/users` is deliberately never served — that table holds password hashes and is reached only through `/auth/*`. An empty resource list on a project whose only table is `users` is the right answer.
In Claude Code, `/mcp` lists `backenly` once the connection is live. If the tools are still missing after a restart, the usual causes are a key that was revoked, a Cline remote entry without `"type": "streamableHttp"`, or a Codex entry whose header never made it into `config.toml`.
What your agent can now do
The manifest advertises 20 tools. That number is a deliberate cap, not a roadmap gap: tool-selection accuracy degrades as a catalog grows, so the surface is an allowlist where every request has one obvious door. `tools/list` on the server is the authority — trust it over any document, including this one.
| Group | Tools |
|---|---|
| Understand | read_backend_state · get_table_schema · run_query · fetch_docs |
| Build | apply_migration · enable_auth · set_rls · create_bucket · generate_function · enable_realtime |
| Data | db_insert · db_update · db_delete |
| Operate | branch · create_api_key · set_env_var · get_database_credentials · check_approval · generate_types |
| Natural language | backend_chat — the fall-through for anything not named above |
Anything not on that list is reached by describing it to `backend_chat`, which plans and executes through the same governed path. Your agent does not need to learn Backenly's vocabulary to be useful — "add likes and comments to my posts table" is a complete instruction.
Agents can also browse live project state as MCP resources — `backenly://state`, `tables`, `apis`, `buckets`, `triggers` — instead of spending a tool call to ask.
What your agent cannot do
Destructive tools are not on the MCP surface at all. `drop_table`, `truncate_table`, `drop_column`, `delete_bucket` and their relatives are dashboard-only, because a host LLM auto-confirming a drop is a failure mode worth designing out rather than warning about.
Agent
Describes the destructive operation
Through `backend_chat`, since there is no direct tool. The call returns an approval id instead of a result.
Backenly
Parks it in the Review Queue
The dashboard card names the target, the live row count where it can read one, and whether the data is recoverable.
You
Approve or reject in the dashboard
Nothing runs until a human confirms. Approval replays the exact stored call rather than re-deriving it from prose.
Agent
Polls `check_approval`
Terminal statuses distinguish `failed` (nothing applied — safe to retry) from `partial` (some changes landed — verify current state instead of replaying).
Backenly does
- Serves the tool manifest and enforces key scope on every call.
- Refuses destructive operations over MCP and routes them to human approval.
- Records every governed change with an audit entry.
- Verifies the key against the live manifest during `init` before writing config.
You own
- Restart the MCP host after installing.
- Choose read-only or read-write when you mint the key, and revoke keys you stop using.
- Approve or reject anything that reaches the Review Queue.
- Keep the key out of your repository — it is a credential, not configuration.
In short
Mint a scoped key, add the server on either transport, restart the host, and confirm with one `read_backend_state` call. From there your agent reads the live schema instead of guessing at it, and the operations it should never perform unattended are structurally out of reach rather than discouraged in a prompt.
Adarsh Chiriyamkandath Jose
Founder, Backenly · Updated August 29, 2026
Try it on a live project
One free project, no credit card. Connect your agent over MCP and read the verification evidence yourself.
Create a project