What an AI agent can safely do in your CRM, and how you stop it
What an AI agent can safely do in your CRM over an MCP server: read narrowly, propose with evidence, change a record only once a person approves that exact call, never anything irreversible — and a stop sized to the problem.
Updated
The short version
- Give the agent rungs to climb, not a master key: read, propose, change with a person's go-ahead, and nothing irreversible at all.
- Work out what it may do on every request, from permissions as they stand right now, and answer a refused request the same way as a request for something that isn't there.
- Make approval a record a person writes about one exact call, never a flag the agent sets.
- Keep a stop that fits the problem — one tool, one project, one person's connections or the whole workspace — and ask for a reason every time it moves.
Hand your agent a ladder, not a master key
It's Monday. Someone on the team has wired an AI assistant into the CRM over MCP, it's already useful, and by lunch it's asking for write access to deals. The honest answer to what an agent can safely do is less a list of tools than a ladder: each rung gives the agent more reach, and each one asks more of the system before it lets the agent climb.
Runner's MCP endpoint is built on that ladder. Every tool carries a grade, from a plain read of non-sensitive data up to destructive or wide-reaching, and the server reads that grade when it decides. The top grade is never served over the connection at all. That isn't a setting anyone can change — the endpoint has no path to serve it.
One detail worth copying into anything you build. The hints a tool gives about itself — read-only, harmless, safe to repeat — are passed to the agent's client for display and never used to decide anything. A tool that doesn't say it's read-only is treated as the stricter kind.
- Read — look things up, narrowly, inside the projects someone approved.
- Propose — draft a change, with the records it's based on, somewhere that belongs to the agent.
- Change — commit one, only after a person has approved that exact call.
- The missing rung — anything irreversible, destructive or wide-reaching, which is never offered to the agent.
Your agent's permissions get worked out again on every request
The risky part of a connected agent is rarely what it was allowed on day one. It's what it's still allowed after someone changed their mind. So the check belongs on every request, read from the permissions as they stand at that moment.
An agent connects to Runner with OAuth, and PKCE is required of every client, using the SHA-256 method only — there's no API key to paste into a config file. The person approving the connection picks the projects it may reach. Every request names one project and is refused unless that project was on the list, and the organization is then read from the project on the server, never taken from the agent.
Nothing is remembered between requests. No session holds on to yesterday's permissions, so a revoked grant stops working on the agent's next request, and a changed role shows up the next time it asks. A tool is offered only when the role of the person who connected the agent carries that tool's permission on that project.
Owners and admins can read a log of what each connection did — opened, listed, called — with the refusals in it too.
Try it
Point any MCP client at a server you're evaluating. Call a tool name you just made up, then one you know exists but weren't granted. If the two errors read differently, the server is telling a stranger what exists. Runner's endpoint gives both the same generic answer, and a revoked token gets the same answer as one that never existed.
Reads come first, and the good ones answer small
Most of what makes an agent useful in a CRM is orientation. Which account is this? Is there a deal open? Did that conversation ever get linked to anyone? When did we last meet? An agent that answers those without somebody clicking through a string of screens has earned its place, and none of it changes a thing.
Runner's read tools sit on the same searches its own screens use, and each answers at the smallest size that's still useful. The account search returns an id and a name, nothing else. The meetings list says when and in what state, without attendees, notes or the briefing. The conversation search gives a label for conversations nobody has linked yet, never the messages inside them. Campaigns come back with their status and counts, not their content.
Every tool also declares the exact shape of its answer and the most sensitive class of data that answer may carry. A result that doesn't match its declared shape is a failed call, never something passed along anyway.
The agent proposes, and a person writes
The first time an agent has something to say about a customer's record, it shouldn't land on the record. It should land somewhere that belongs to the agent, carry what it's based on, and wait for a person.
Where this stands, before how it works: over a connection made today the agent acts as the person who connected it, so the database refuses its proposals under the first of the rules below. The tool is built and the rules are live; the separate identity for the agent that they need is not there yet.
That's how Runner's first proposing tool is built, and the record it aims at is deliberately the one where a wrong word costs least and shows most: a note on a contact. The proposal goes into the agent's own ledger, never onto the contact. It has to cite at least one record and say, for each, why it supports the note. A person applies it, edits it or throws it away where they already write notes, and what they actually wrote is recorded against the proposal so the two can be compared.
Three rules are held by the database rather than the application. A proposal names the agent that made it separately from the person it acts for, and one filed under the person's own identity is refused. The agent may not record the outcome of its own proposal. And an outcome is written once. On top of that, the tool caps how many proposals one agent can hold against one contact and make in an hour, so a looping agent produces a refusal someone notices rather than a queue someone abandons.
There's deliberately no approved status in that ledger — approving a proposal would mean the system had written it, which is the one thing this rung exists to hold back. The review page puts the proposal beside what the person wrote and calls the overlap agreement, never accuracy, because someone who applies a proposal without reading it looks exactly like someone who agreed with every word.
How Runner's own agents cite the record behind every claimA change runs only after a person approves that exact call
The next rung is an agent that commits something. The trap here is the confirm flag: one tool with a yes-or-no argument the agent fills in for itself.
Runner treats a change as two acts. When an agent calls a tool that commits something, the endpoint files a request for approval and refuses the call. A person decides it in Runner, and only then does the same call go through. The approval is bound to that call — the tool, its version, the organization, the accountable person and the exact arguments — so change one argument and it's a different call needing its own approval. An approval with no expiry counts as expired, and a call with no accountable person behind it is refused before approval is even considered.
The same holds one step earlier. When a person's own permissions say an action needs approval, the endpoint reads that as a no. Treating needs-approval as allowed at the door would be precisely the bypass the design exists to prevent.
Before a tool that changes anything is served at all, it has to declare the approval it needs, the evidence it carries, how it's undone and how often it may run — miss one and the server doesn't start. The undo plan has to point at a field the tool actually returns, there's no way to declare a change irreversible, and no ceiling may mean unlimited. The ceiling is checked before anyone is asked to approve, so nobody spends an approval on a call that was going to be refused anyway.
Today no tool on this rung touches your accounts, opportunities, conversations, meetings or campaigns. New tools are added one at a time, each with its own review.
The short version
Approval is a record a person makes about one exact call. It is never an argument the agent passes.
Stop it at the size of the problem
Every connected agent needs a stop, and the useful kind is sized to the problem. A switch that can only pause the whole workspace is a switch nobody wants to pull.
Owners and admins in Runner can stop agent traffic for the whole workspace, one project, one person's connections, or calls to a single tool. Stopping takes a reason, and so does releasing, because the decision to resume deserves the same record as the decision to stop. A stop can carry an expiry, after which it lifts on its own, and the record of it stays.
There's no allow record anywhere in that model, only stops. So nothing narrower can reopen what a broader stop closed — that isn't a precedence rule someone has to get right, it's the shape of the data. The stop is also checked first on every call, ahead of the permission check, and a stopped workspace doesn't even get its tool list back.
The answer a stopped agent receives is the same whatever the reason. A paused project and a paused platform return identical words, so a stop on one project never tells anyone that the project exists.
Picture this
It's 2am and an agent is calling the same tool over and over. Whoever is on call stops that one tool, types why, and sets the stop to lift at nine. Everything else keeps working. At nine the stop lifts itself, and the reason is waiting in the record for whoever asks what happened.
Ask any MCP server these before it touches customer data
Whether you build the connection yourself or buy one, these are the questions that separate an agent you can leave running from one somebody has to watch. A good answer to each is a sentence about the software, never a promise about intent.
Every one of them describes how Runner's endpoint behaves today, with the edges stated in the sections above.
- Does an agent connect with OAuth and PKCE, or with a long-lived key someone pastes into a config file?
- Are permissions worked out on every request, or remembered from the moment the agent connected?
- When a permission says an action needs approval, does the server read that as a no?
- Is an approval bound to one exact call, or is it a flag the agent sets?
- Does every change declare how it's undone before it's allowed to run?
- Does a refused request look exactly like a request for something that isn't there?
- Is there a stop sized to the problem, and does pulling it — or releasing it — take a reason?
One system for the whole path
The mechanism above is one of the jobs Runner does on one record, under one login. Access is by application.





