Giving an agent write access to your API: what to exclude first
A tool call is a real request against a real API. Before you connect one, the question is not which endpoints to expose. It is which ones an agent must never reach.

There is a moment in setting up an agent integration where the demo works, and the temptation is to leave it there. The agent read your documentation, wrote a correct call, executed it, and showed you the response. Everything you wanted.
The thing to notice is that the response was real. The agent did not simulate a request. It made one, against whatever environment you configured, with whatever credentials you gave it. If that endpoint writes, it wrote.
That is not a flaw. It is the capability, and it is why the integration is useful rather than a search box. But it means the setup question is inverted from how people usually approach an integration. The question is not which endpoints to expose. It is which ones must never be reachable, and answering that before you connect anything is the whole job.
Exclusion beats instruction
The instinct is to handle this in the prompt. Tell the agent not to delete anything. Add a rule about production. Put a warning in the tool description.
This does not hold, and the reason is structural rather than a comment on any particular model. An instruction is a strong suggestion evaluated against everything else in the context, including whatever the agent is being asked to accomplish and whatever it has read from your documentation, your data, or a web page along the way. It is a preference, competing with other preferences.
An endpoint that is not exposed as a tool is not a preference. There is no tool to call. The agent cannot be persuaded, confused or prompt-injected into calling something that does not exist in its tool list.
So the control that works is the one applied before the agent starts: decide the surface, remove what should not be on it, and let the remaining tools be the boundary.
The list to remove first
Work in this order, because it goes from unambiguous to judgement.
Anything that deletes. Hard deletes, purges, bulk removals. Not because an agent is careless, but because the failure is unrecoverable and the value of automating it is near zero. Nobody needs an agent to empty a table.
Anything that moves money or sends messages. Charges, refunds, payouts, transfers, and anything that emails or texts a human. These share a property: the effect leaves your system and cannot be undone from inside it. A duplicated charge is a support case, and a duplicated email to a customer list is a much worse one.
Anything that changes access. Creating users, granting roles, rotating or issuing credentials, changing permissions. An agent that can grant permissions can widen its own reach, and that is the one category where a mistake compounds rather than staying contained.
Anything that changes billing or plan state. Subscriptions, plan changes, cancellations. Same reasoning as money, with a slower blast radius and a more annoying cleanup.
Anything administrative or internal. Endpoints your own staff use, debugging routes, anything under an admin scope. These are usually excluded from public SDKs already, which is the useful shortcut below.
What is left after that is most of your API: reads, searches, and the ordinary creates that make up the integration work you actually want help with.
Your SDK exclusion list is a good starting permission list
If you publish client libraries, you have already made most of these decisions.
The endpoints you kept out of your public SDK are, with few exceptions, the endpoints that should not be in an agent's hands: internal tooling, admin operations, things that only make sense from your own dashboard. The judgement transfers because it came from the same question, which is what a third party should be able to do with your API without you supervising.
Start there, then subtract further. An agent is a less careful consumer than a developer reading your docs, and the endpoints where the difference matters are the irreversible ones.
Point it at staging until you have watched it work
The single highest-value setting in an agent integration is the base URL, and the right initial value is not production.
Evaluate against staging first, with staging credentials, and watch what the agent actually calls rather than what you expected it to call. This is where you learn that a read-only-looking endpoint has a side effect, or that the agent likes to list before every write and your rate limit does not love that.
The move to production should be a deliberate change made after you have seen the traffic, not the default because it was the URL you had handy.
Scope the credential, not just the tool list
Two layers, and the second is the one people skip.
The tool list controls what the agent can attempt. The credential controls what those attempts are permitted to do. If your API has scopes, the token you give an agent should carry the narrowest set that covers the tools you exposed, so that a bug in the tool layer does not become unlimited access.
This is ordinary least-privilege, and it applies here with more force than usual because the caller is generating its own requests. A human integrator with an over-scoped key calls the endpoints they meant to. An agent with an over-scoped key calls the endpoints it reasons its way to.
Log it like production traffic, because it is
Agent calls are real API calls and should be visible in the same place as everything else: which tool, which endpoint, what came back. Not because you expect misbehaviour, but because the first surprising thing an agent does is information you want, and reconstructing it afterwards from application logs is worse than seeing it.
It also tells you which tools are worth keeping. Most integrations discover that a handful of endpoints carry all the value and the rest of the surface is noise, and a smaller tool list is both safer and produces better results.
The default that makes this manageable
The reason this is tractable rather than a security review per endpoint is that the surface is derived from configuration you already maintain. Excluding an endpoint from your SDK excludes it from the tools; renaming a method renames the tool; marking something deprecated surfaces that to the agent. One decision, applied in both places, rather than a separate agent permissions system to keep in sync.
If you are setting this up, generating an MCP server from an OpenAPI spec covers the mechanics, including the environment variable that decides which API the tools actually hit. And for the reading half rather than the writing half, why agents invent endpoints covers what changes when an agent can look your API up instead of recalling it.



