AI & agents
Let an agent run your infrastructure: MCP, scopes and safety
Giving a model write access to your production platform sounds reckless. It is reckless — unless the blast radius is a number you set. Here is the full safety model, mechanism by mechanism.
"An agent may do everything you may" is a frightening sentence without a ceiling and a reasonable one with it. This post is about what makes the second version true.
Start with the honest version of the risk
An agent with platform access can create things that cost money, delete things you needed, and read things you would rather it did not. It can also be talked into doing all three by text it encounters while working — a log line, an error message, a README in a dependency.
Nothing about a system prompt fixes that. "Please do not delete the production database" is a request, and requests are not a security boundary. What follows are the six mechanisms that are.
1. The spending limit
The blast radius of a compromised or confused agent is bounded by a number you already agreed to. Anything that would cross the ceiling fails before it starts, with an error that says so.
Crucially, raising that number is not something any token can do. It is one of five permanently blocked operations. An agent that decides the correct solution to cap_exceeded is a bigger cap discovers there is no tool for it.
This is the load-bearing mechanism. The other five are refinements on it.
2. Scopes, in three presets
When you authorise an agent, you pick a profile — in your own browser, with a passkey. The agent never chooses its own scopes and never sees your credentials.
| Profile | Tools | What it is for |
|---|---|---|
read | 22 of 47 | Look, change nothing. Safe for any agent. |
build | 41 of 47 | Everything needed to go from nothing to live. Cannot permanently delete anything. |
full | 47 of 47 | Everything, with confirmation on destructive operations. |
build is the default, and the reason is that all three *:delete scopes are absent from it. An agent on build can create a project, deploy it, scale it, attach a database, connect a domain and diagnose it — and cannot throw any of it away. For most people that is precisely the shape of trust they want.
Note that read includes env:read. That gives the names of environment variables, never the values. An agent that has to understand your app needs to know a DATABASE_URL exists; it does not need to know what it is.
3. A daily action budget
Separate from the limit, and much smaller. Every agent token has a maximum number of actions and deploys per day.
This exists because the failure mode that actually happens is not a malicious agent — it is a loop. An agent that misreads an error and retries forever hits the action budget in minutes, long before it approaches your ceiling, and you get told about it.
The budget is in every response, alongside the spend cap:
"budget": {
"actions_today": 63, "actions_max": 400,
"deploys_today": 4, "deploys_max": 10
}
4. Confirmation tokens
Destructive operations require a confirmation token that the agent cannot mint. It has to come from your interface, which means it has to come back through you.
An agent can propose cmdz_delete_project. It cannot complete it alone, and there is no phrasing that changes that, because the check is on the server and the server does not read the conversation.
5. The emergency stop
One button revokes every agent token in the organisation. It propagates in under five seconds — measured, not estimated.
It is deliberately the most prominent control on the agents screen. A safety mechanism you have to look for is not one you will find at the moment you need it.
Afterwards, the agent timeline lists every action with its tool name, its arguments and its request id, in the brand's agent colour next to what people did. Anything an agent changed can be undone from that list.
6. Untrusted content is marked as untrusted
An agent reading your build log is reading text written by your dependencies. An agent reading an error message is reading text that may have come from user input three layers down.
All of it — log output, error text, repository content, environment variable names — is wrapped and labelled untrusted before it reaches the model. A prompt injection planted in a log line arrives as data with a fence around it rather than as an instruction in the middle of a tool result.
This is not a solved problem in the industry and we are not going to claim it is. Marking the boundary is the part we can do reliably; the rest is the client's job, and it is one of the reasons we keep the destructive operations behind a token the agent cannot produce.
The envelope
Every single response — all 47 tools, not just the cost ones — carries your limit status:
"spend_cap": {
"used": "412.55", "cap": "500.00",
"remaining": "87.45", "used_percent": 82.5,
"state": "warning"
}
The reason is small and important: an agent that does something a hundred times in a row must see the brake a hundred times, not once at the beginning. Context windows forget. The last response is what a model reads best.
The errors are written for the agent
403 Forbidden tells an agent nothing actionable, so it retries. Our refusals say what happened, whether retrying could ever help, and what to do instead:
"error": {
"code": "cap_exceeded",
"message": "This would reserve 1 240 credits but only 612 remain under the limit.",
"retryable": false,
"next_steps": [
"Ask the person to raise the limit — you cannot do this yourself.",
"Or choose a smaller instance size."
]
}
A useful refusal ends a loop. An opaque one starts a longer one.
Connecting it
claude mcp add --transport http cmdz https://mcp.cmdz.com/v1
OAuth 2.1 with PKCE, a passkey in your browser, pick the organisation, pick the profile, confirm. Start on read if you want to watch it work before you let it build. Everything above is on the MCP page.
Set your limit and start.
One click with a passkey, then you verify a payment method once to start your 14-day free trial (€ 10 of credit). After that it is prepaid pay-as-you-go — you only ever spend credit you have already bought, and no invoice ever arrives above the amount you set.