Skip to content
Open to board advisory and board seats: 2H 2026, then CY 2027-2028.
See details →
AI

Your Tool Catalog Is Standing Access

A resident tool definition is a standing grant with no request, no approver, and no expiry. We scoped the MCP servers and never scoped the catalog.

By Michael YorkJuly 29, 2026 10 min read 2,206 words All AITable of contents

Every tool definition sitting in a model's context is an access grant that nobody requested, nobody approved, and nobody set to expire. We scoped the servers one at a time and never scoped the catalog.

I have sat in a lot of MCP reviews this year, and they all follow the same shape. Which server, which credential, which actions, read or write, what shows up in CloudTrail. It is a good review. I helped write the version my team uses. I have also come to think it starts one question too late.

The question it skips is which tools are resident in the session at all. Not what a tool can do once the model calls it. Whether its full definition is sitting in the context window, described in detail, before anyone types a word.

Anthropic published the number, and it is worse than I would have guessed. In its advanced tool use writeup (opens in new tab), the company puts a representative multi-server setup at "58 tools consuming approximately 55K tokens before the conversation even starts," and notes that internally it has "seen tool definitions consume 134K tokens before optimization." The platform documentation (opens in new tab) names the servers (GitHub, Slack, Sentry, Grafana, and Splunk) consuming roughly 55k tokens "in definitions before Claude does any work."

Read that as a token bill and it is an optimization ticket someone gets to next quarter. Read it as an access-control artifact and it is something else. That is the complete capability menu of five systems of record, resident and fully legible to a non-deterministic caller, in every session, by default, from the first token.

A resident tool definition satisfies none of the three access processes

The FFIEC IT Examination Handbook is unglamorous and precise about what governing access requires. Its logical security guidance (opens in new tab) breaks logical user access rights administration into three processes: "Enrolling new users to the system. Authorizing modifications to user access and deletions. Monitoring access rights granted to each user, including periodic review and validation of access rights." Assignment of those rights, it says, is "typically performed by the employee's manager and the application or data owners responsible for each accessed resource, with documented approval."

Now run a resident tool definition against those three. There is no enrollment event, because the tool arrived bundled with the server and nobody named it individually. There is no authorization, because a line in a config file is not a documented approval by a data owner. And there is no monitoring, because nothing in your telemetry separates a tool the agent invoked from one that merely sat there available all quarter. Zero of three.

A standing grant with no request, no approver, and no expiry is the exact control we spent fifteen years removing from human identity. We built whole product categories to kill it. Then we reintroduced it as a JSON array and filed the ticket under context management.

The non-human identities' turn arrived sooner than I said it would

When I wrote about just-in-time access for humans, I argued that standing access is the liability rather than the login, that least privilege is a flow rate and not a static map, and that the trick is making the default state low-privilege while making elevation cheap, fast, logged, and temporary. I closed by saying the non-human identities could wait their turn. Their turn came faster than I expected, and it did not arrive as credentials. It arrived as catalogs.

My own MCP guidance has the same blind spot. In the IAM playbook I published for MCP servers I argued for one role per server, policies generated from the tool manifest, read separated from write, conditions pushed down to the call. All of that governs what a server can do once the model reaches for it. None of it governs whether the server's menu is in the room.

The distinction matters because the failure modes differ. A badly scoped role is a blast-radius problem: the wrong thing happens. A badly scoped catalog is a legibility problem: capabilities the task never needed are described, with argument schemas, to a caller an outsider may be able to steer using your own data. One of those you catch in CloudTrail. The other never generates an event at all.

Tool search is just-in-time access wearing a token-budget costume

Anthropic shipped the fix, and shipped it as a cost feature. Its tool search tool lets you mark definitions defer_loading: true so they stay out of context until the model searches for them. The documentation is explicit about effect and trigger: deferral "typically reduces this by over 85 percent, loading only the 3-5 tools Claude needs for a given request," and you should reach for it when "you have 10 or more tools available" or "your tool definitions consume more than 10k tokens." The ceiling is 10,000 deferred tools per request.

Two details in that documentation are governance decisions wearing implementation clothes. The API rejects any request in which everything is deferred, because "at least one tool must have defer_loading=false," and the guidance is to keep "your 3-5 most frequently used tools non-deferred." A permanent resident set is mandatory, which means somebody is choosing standing grants whether or not they know it. The second detail is granularity. For tools arriving through the MCP connector you "don't set defer_loading on individual tool definitions" at all. You set it on the toolset, once for the whole server or per tool inside that config, and the default path is the server. The default is what ships.

Strip the framing and describe the mechanism plainly. Default state: a search tool plus three to five tools you named. Elevation: cheap, fast, scoped to the request. Persistence: none past the session. That is just-in-time access built into the inference API, sold as a context optimization because that is what customers complained about.

The reliability numbers are what get it funded. Anthropic reports that selection accuracy "degrades once you exceed 30-50 available tools," and that with tool search enabled "Opus 4 improved from 49% to 74%, and Opus 4.5 improved from 79.5% to 88.1%." I have argued before that adoption is the control, because a secure path slower than the insecure path is a suggestion. A least-privilege change that measurably improves the agent's tool selection does not need me to sell it on risk. It sells itself on outcomes and pays the control as a dividend.

The load decision moved to the model, and that is a segregation-of-duties problem

Here is where I stop being enthusiastic. The MCP specification (opens in new tab) is blunt that "tools in MCP are designed to be model-controlled." Layer tool search on top and the sequence becomes: the model writes the query, the search runs, matching definitions expand into context, the model calls one. The requester and the approver have collapsed into one principal, and that principal is not deterministic.

I named the same collapse one layer down when I wrote that your prompt is the approval for a connector write. This is that shape moved up a level. The search query is the access request and the approval at once, and the entity issuing both is the entity you are trying to bound.

The search surface is also text you may not own. Anthropic's documentation notes that both search variants "search tool names, descriptions, argument names, and argument descriptions." The MCP spec, meanwhile, warns that clients "MUST consider tool annotations to be untrusted unless they come from trusted servers." For any server you did not write, description text you do not control is part of what decides which entitlements load. That is not fatal, and it is not a reason to go back to static loading. It does mean the catalog boundary is the only thing between a hijacked search and everything the catalog contains.

Which makes it a design instruction. Anthropic supports a custom client-side tool search that returns tool_reference blocks from your own code, and that hook is where policy belongs. What a search can draw from should be a set a human scoped for that workload, not everything the aggregator exposes. Wire 200 tools behind one broker and you have not built a catalog. You have built a shared privileged account with a search box on it.

Deferral is a context-window control, not a data-transmission control

This is the part I expect to see mis-filed in third-party risk questionnaires within a quarter, so I will state it flatly. Anthropic's documentation says defer_loading "controls what enters the context window, not what you send in the request," and that "you still send every tool's full definition in the tools array on every request, including the deferred ones." The search runs server-side, on the provider's infrastructure, which is why the definitions must be there.

So if the answer in your next vendor review is "we defer our tool catalog, so the provider does not receive our internal tool inventory," that answer is false. The catalog crosses the boundary on every call whether or not the model sees it. Deferral bounds what the model can act on. It does not bound what leaves your network.

Two controls, two obligations, and they are not substitutes. Least privilege at the context window is one. Data minimization at the trust boundary is another, and if your tool names and argument descriptions encode internal system names or topology, nothing above has touched it.

Put the catalog on the entitlement register before the next connector

None of this requires a program or a new vendor. It requires treating a tool definition as the grant it already is. Six moves cover most of the exposure, and all six work with the APIs as shipped today.

  • Inventory the catalog as entitlements, not integrations. "The agent has Slack and GitHub" is not a register entry. One row per tool, with server, action, read or write, and resident or deferred, is a register entry.
  • Make resident an allowlist with a human's name on it. The three to five non-deferred tools are the standing grants that survive every session. That set should be a decision an owner signed, reviewed on the same cadence as any privileged role.
  • Bound the search, not just the server. Use a scoped client-side search or per-workload toolsets so a compromised query can only reach a set someone deliberately drew. The catalog boundary is now a security control.
  • Harvest the load event as the grant record. Anthropic's documentation notes tool search "isn't metered as a separate server tool," so your invoice will never show you a load. The transcript will: the server_tool_use and tool_search_tool_result blocks name every tool discovered in a turn. Ship those to your log pipeline with the session and requesting identity attached.
  • Re-review on change, not on a calendar. MCP servers declaring listChanged emit notifications/tools/list_changed when their menu changes. A vendor adding a write tool to a server you approved as read-only is an entitlement change, and it should trigger a review rather than a silent re-fetch.
  • Decommission the catalog, not just the connector. A deferred tool nobody has called in six months is still shipped on every request and still expands on the right query.

That last one is the failure I keep watching teams repeat. We got very good at onboarding agents and never built the offboarding, and a tool catalog decays the way a service account does, because nothing breaks when an unused capability stays. One more note on logging. MCP tells clients to "log tool usage for audit purposes," which everyone reads as invocation logging. Under dynamic loading the load is the grant, and the invocation is only the exercise of a grant you never recorded issuing.

The examiner's question has not changed

Who had access to what, when, and why. That question survives every architecture shift I have lived through, and a context window cannot answer it. A context window is not queryable after the fact, not retained on your side, and not attributable to a request anyone approved. The FFIEC handbook puts the stake plainly: "access beyond the minimum required for work to be performed exposes the institution's systems and information to a potential loss of confidentiality, integrity, and availability." Fifty-eight tools resident for a task that needed three is access beyond the minimum, and the excess sitting in a prompt rather than an IAM policy does not change what it was.

I run information security and DevOps for a fintech platform serving more than 1,500 financial institutions, so I own both the pipelines that ship these agents and the controls someone examines afterward. I would rather have the boring artifact than the clever one: every tool that was resident, why, who decided, and when it stopped being resident. So pull the tool list for one agent you already approved, count the definitions, then count how many were actually called last month. If the first number is 58 and the second is 4, you never had a token problem. You have 54 standing grants nobody requested.

I would genuinely like to hear how other teams are drawing the resident-versus-deferred line in production agent systems, and specifically who signs off on the non-deferred set. That is the decision I have not yet seen anyone put an owner on.

AIAI AgentsAI SecurityNon-Human IdentityAI Governance