An AI agent that discovers its tools at run time can gain new capabilities, or have existing ones rewritten, without anyone in security approving the change. The Model Context Protocol makes discovery a first-class feature: clients call tools/list, servers can announce changes with notifications/tools/list_changed, and registries make thousands of servers one configuration line away. Static allowlists trade that flexibility for predictability. This guide compares the two approaches in depth: the threats each one is exposed to (tool poisoning, rug pulls, shadowed tools), what pinning and signing of tool definitions can and cannot prove, approval workflows, failure modes, controls per option and the criteria for choosing. It is for architects, platform owners and AppSec teams running MCP clients, gateways or agent frameworks. Detection of poisoned definitions is covered in MCP Tool Poisoning Detection; this page is about the governance model.
Key takeaways
- Discovery is not the problem; unreviewed change is. Dynamic discovery is safe enough when every new or changed definition passes through the same gate as the original approval.
- Static allowlists still drift. Pinning a tool name is not pinning a tool: the description, schema and server code behind an allowlisted name can all change.
- Pin three things separately. The definition (hash of the tools/list entry), the code (package version or image digest) and the server identity (verified namespace or endpoint) each fail independently.
- Signing proves origin, not safety. Provenance tells you who built a package and from which source; npm's own documentation says it "does not guarantee the package has no malicious code".
- Choose by blast radius. Agents holding write access to sensitive systems need static, pinned toolsets; exploratory, read-only or sandboxed agents can use governed discovery.
The short answer
Run production agents that hold meaningful credentials on a static allowlist of pinned tool definitions, with re-approval triggered by any change. Use dynamic discovery where it adds value, in development, research and read-only assistants, but route it through a gateway or curated subregistry that applies the same review, namespacing and pinning before a tool reaches the model. Never allow an agent to discover and use a new tool from the open internet in the same session in which it holds production credentials.
The underlying threat, an approved tool changing after approval, has a name in MITRE ATLAS: AML.T0109 AI Supply Chain Rug Pull, where adversaries "publish legitimate AI components or software, gain user adoption, then push an update with a malicious variant". AML.T0110 AI Agent Tool Poisoning covers altering tools "already integrated into the agent's environment". See MITRE ATLAS AML.T0109 AI Supply Chain Rug Pull and AML.T0110 AI Agent Tool Poisoning.
How each model works
Static allowlisting: an administrator approves a fixed set of servers and tools per agent. The client or gateway loads only those, ignores or quarantines additions, and compares each definition against a stored baseline. New tools need a change request. The agent's capability set is known before it runs.
Dynamic discovery: the client accepts whatever the connected servers currently expose. In the MCP tools specification (version 2026-07-28), servers that declare the listChanged capability SHOULD send notifications/tools/list_changed to clients that subscribed, and the client fetches an updated list. Discovery can also happen one level up, when an agent or user adds servers found through a registry. The official MCP Registry describes itself as "like an app store for MCP servers" and, as its repository states, is still a preview release in which "breaking changes or data resets may occur".
Between the two sits governed discovery: tools are discovered dynamically, but a gateway or client policy holds every new or changed definition in quarantine until it passes automated checks and, for higher-risk tools, human approval. Most mature deployments end up here.
Side by side comparison
| Dimension | Static tool allowlist | Dynamic tool discovery |
|---|---|---|
| Capability set | Fixed and known before run time | Whatever connected servers expose now |
| Change path | Change request, review, new baseline | Server-initiated list change or new server added |
| Rug pull exposure | Low for definitions if hashes are compared; remains for server code unless versions are pinned | High unless every change is re-reviewed |
| Tool shadowing exposure | Low; toolsets are reviewed together | High; any newly connected server shares the model's context with trusted tools |
| Name collision handling | Resolved at approval | Must be resolved by the client at run time by server-identifier prefixes |
| Operational cost | Review queue, slower adoption of new tools, baseline upkeep | Low setup cost; high monitoring and incident cost |
| Audit evidence | Approved register, baselines, change history | Only as good as the logging of tools/list responses over time |
| Best fit | Production agents with write access or sensitive data | Development, research, read-only or fully sandboxed agents |
Threats in depth
Tool poisoning
Instructions hidden in a tool's description, parameter descriptions or schema are read by the model as guidance. A static allowlist reviews this text once at approval. Dynamic discovery exposes the model to text nobody has read. Either way, the defence is reviewing definitions as untrusted input and re-reviewing on change. The MCP specification reinforces this by saying clients "MUST consider tool annotations to be untrusted unless they come from trusted servers".
Rug pulls
A rug pull exploits the gap between approval and use. It can happen at two layers. At the definition layer, the server changes a description or schema and announces it with list_changed. At the code layer, the definition stays identical but the implementation changes. The postmark-mcp malicious MCP server 2025 is the code-layer case: according to the incident analysis, versions 1.0.0 to 1.0.15 behaved as advertised and 1.0.16 added one line that blind-copied every outgoing email to an attacker. A definition hash would not have changed; only version pinning and review would have stopped it.
Shadowed tools and collisions
When several servers share one session, a description on a low-value server can instruct the model how to use a different, trusted tool. The MCP specification says tool names SHOULD be unique within a server, that clients aggregating several servers SHOULD implement disambiguation "such as prefixing tool names with a server identifier", and that the server's self-declared name "SHOULD NOT be relied upon for disambiguation". Dynamic discovery multiplies the number of servers whose text sits beside trusted tools.
Malicious or impersonating servers
Discovery through a registry introduces a server identity question. The MCP Registry validates namespace ownership at publication through GitHub OAuth, GitHub OIDC, DNS verification or HTTP verification, so a name such as io.github.example/server is tied to that GitHub account. That proves who published the entry. It does not prove the server is safe, and the registry repository makes no security scanning claims.
Pinning and signing tool definitions
"Pinning" is used loosely. Separate it into three pins, because each closes a different gap.
| Pin | What you record | What it catches | What it misses |
|---|---|---|---|
| Definition pin | Hash of each tool's name, title, description, inputSchema, outputSchema and annotations from tools/list, canonicalised | Rewritten descriptions, added parameters, new tools, removed tools | Behaviour changes in code with an unchanged definition |
| Code pin | Exact package version and integrity hash, or container image digest, installed from an internal mirror | Silent upstream releases such as the postmark-mcp change | Remote servers you do not run; malicious code present at first approval |
| Identity pin | Verified registry namespace, remote endpoint URL and its TLS identity, OAuth client and audience | Look-alike servers, endpoint substitution, typosquatted packages | A legitimate publisher going rogue or being compromised |
| Provenance check | Build attestation linking the package to a source repository and CI workflow | Packages built outside the claimed pipeline | Malicious code committed to the real repository |
On provenance, npm's documentation is precise: provenance "provides a verifiable link to the package's source code and build instructions", is generated through Sigstore from supported cloud CI, can be checked with npm audit signatures, and "does not guarantee the package has no malicious code". Treat signing as an identity and integrity control, not a review substitute. NIST SP 800-53 separates these too: CM-14 Signed Components, SR-4 Provenance and SI-7 Software, Firmware, and Information Integrity.
Remote MCP servers cannot be code-pinned by the consumer. For them, the definition pin and identity pin are the controls you own, and contractual and assurance controls cover the code. See the MCP Server Trust Assessment.
Approval workflows
Whichever model you choose, a change to a tool's capability is a change to an identity's entitlements, and it should be governed like one (NIST SP 800-53 CM-3 Configuration Change Control).
- Intake: a request names the agent, the server, the tools needed and the business purpose. Requests for an entire server with every tool are narrowed to the tools actually needed.
- Automated checks: verify namespace and provenance, scan descriptions for hidden instructions and cross-references to other tools, check names for collisions, and flag open-ended tools (shell, SQL, URL fetch). See the MCP Security Scanners Guide.
- Risk tiering: read-only internal tools may be auto-approved after checks; write, external-send, financial and code-executing tools need a named human approver.
- Baseline: store the definition, code and identity pins. Bind the tool to a scoped credential for that agent only.
- Change handling: on list_changed or a new version, suspend the affected tools, show the approver a diff of the definition and the package, and restore only on approval. A changed hash with no explanation is treated as a potential incident.
- Periodic review: remove tools unused for a set period. OWASP LLM06 gives the example of a plugin "trialled during a development phase" that "remains available to the LLM agent".
- Rollback: keep the previous approved baseline and package version so a bad update can be reverted without disabling the agent.
For synchronous versus asynchronous approval trade-offs see Synchronous Approval vs Asynchronous Review of Agent Actions.
Controls per option
| Control | Static allowlist | Governed dynamic discovery |
|---|---|---|
| Inventory | Approved register is the inventory | Continuous capture of every tools/list response per server, per agent |
| Change detection | Hash compare on connect and on list_changed | Same, plus quarantine of new tools by default |
| Namespacing | Fixed prefixes assigned at approval | Client-assigned server identifier prefixes applied automatically |
| Source control | Internal mirror, pinned versions and digests | Curated subregistry or allowlisted namespaces only |
| Credential binding | One scoped credential per tool server per agent | No credential issued until the tool is approved; discovery sessions hold read-only or no credentials |
| Session separation | High-impact toolsets kept apart from community tools | Newly discovered tools never loaded into sessions with high-impact tools |
| Execution containment | Local servers in an OS sandbox | All newly discovered local servers sandboxed, as the MCP best practices advise for local servers |
| Server-side enforcement | Servers return only tools the caller's scopes permit | Same; scopes become the real allowlist when clients vary |
The last row matters most. The MCP specification allows a server's tool list to vary "by the authorization presented on the request", so an authorisation server that issues narrow scopes per agent turns the allowlist into a server-enforced control that no client misconfiguration can widen. ATLAS lists AML.M0028 Enforce Access Controls for AI Agent Tools for this layer.
Decision criteria
| Question | If yes |
|---|---|
| Does the agent hold write, financial, external-send or production credentials? | Static allowlist with all three pins |
| Does the agent process untrusted content (web pages, inbound email, public issues)? | Static allowlist; injected text should not be able to pull in new tools |
| Is the agent read-only, sandboxed and without sensitive data? | Governed discovery acceptable |
| Are the servers remote and operated by third parties? | Definition and identity pins plus trust assessment; expect more frequent change reviews |
| Is this a developer workstation? | Allowlisted namespaces and sandboxed local servers; inventory what is installed |
| Do you lack capacity to review changes promptly? | Fewer tools on a static list; slow review on a dynamic model means unreviewed tools in use |
Small organisations usually do best with a short static list and a monthly review. Large organisations with many agent teams tend to run a central gateway that performs governed discovery against an internal subregistry, giving teams self-service within guardrails. See the MCP Gateway and MCP Server Governance Guide and the MCP Registry and Server Publishing Security Guide.
Worked scenario: a support agent gets a new tool
A customer support agent uses an approved ticketing server with three tools. The vendor ships an update that adds export_all_tickets and edits the description of search_tickets to mention that results should be "summarised via export_all_tickets for completeness".
Under unmanaged discovery the client receives list_changed, fetches the new list and the model now sees an export tool and an instruction to use it. Nobody approved either. If the agent's token allows export, a routine query becomes a bulk data pull.
Under a static allowlist without definition pins export_all_tickets is ignored because it is not on the list, but the edited search_tickets description still reaches the model. The model may try the export tool and fail, which is safe here only because the new tool was excluded.
Under a pinned allowlist or governed discovery the definition hash for search_tickets changes, the tool is suspended, the new tool is quarantined, and an approver sees a diff showing a cross-reference to another tool, a known poisoning signal. The approver accepts the original behaviour, rejects the export tool for this agent and asks the vendor about the description. The agent loses one tool for a few hours; nothing leaks.
Detection and measurement
- Log every tools/list response: store the definitions and hashes per server per connection so changes can be reconstructed. The MCP specification says clients SHOULD log tool usage for audit purposes.
- Alert on: hash changes without a matching change ticket, new tools appearing on production servers, descriptions that reference other tools or servers, duplicate names across servers, and package versions outside the pinned set.
- Endpoint inventory: scan developer machines for MCP client configurations and installed servers. See How to audit MCP servers on developer laptops.
Metrics:
- Percentage of production agents on a pinned allowlist.
- Number of unreviewed definition changes in use at any time (target zero).
- Median time from list_changed to approval or rejection.
- Percentage of local tool servers installed at a pinned version from an internal mirror.
- Tools unused for 90 days still approved, trending to zero.
- Percentage of tool servers whose tool list is filtered server-side by scope.
Common failure patterns
- Allowlisting names, not definitions: the name stays approved while its description and schema change underneath.
- Floating versions: installing local servers with latest or a caret range, so each upstream release lands unreviewed, the route the postmark-mcp malicious MCP server 2025 exploited.
- Treating registry presence as vetting: namespace verification proves the publisher, not the code.
- Auto-accepting list_changed: clients that refresh tools silently give a rug pull a built-in delivery channel.
- Mixing discovery and privilege: letting an agent explore new servers in the same session that holds production tokens.
- Client-only enforcement: an allowlist in one IDE extension while another client on the same machine loads every server in the configuration.
Framework mapping
| Framework | Reference | Relevance |
|---|---|---|
| MITRE ATLAS | AML.T0109 AI Supply Chain Rug Pull; AML.T0110 AI Agent Tool Poisoning | The threats static pinning and change review address |
| MITRE ATLAS | AML.M0028 Enforce Access Controls for AI Agent Tools; AML.M0038 AI Agent Scope Drift Detection | Server-side tool restriction and detecting capability creep |
| NIST SP 800-53 Rev 5 | CM-7(5) Authorized Software, Allow-by-exception; CM-3 Configuration Change Control | Allowlist model and change approval |
| NIST SP 800-53 Rev 5 | CM-14 Signed Components; SR-4 Provenance; SI-7 Software, Firmware, and Information Integrity | Code and identity pins |
| NIST CSF 2.0 | ID.AM-02 software and services inventories; PR.PS-02 software maintained commensurate with risk | Tool inventory and controlled updates |
| OWASP LLM Top 10 2025 | LLM06 Excessive Agency; LLM03 Supply Chain | Minimise extensions; third-party component risk |
| CIS Controls v8.1 | 2.5 Allowlist Authorized Software | Allowlisting principle applied to tool servers |
Practitioner checklist
- Decide per agent: static pinned allowlist, governed discovery or development-only discovery, and record why.
- Store definition, code and identity pins for every approved tool server.
- Suspend tools automatically on any definition hash or version change until reviewed.
- Prefix tool names with a client-assigned server identifier and block duplicates across servers.
- Install local servers only at pinned versions from an internal mirror, and sandbox them.
- Issue no credential to a tool until it is approved; keep discovery sessions free of production tokens.
- Filter tool lists server-side by scope wherever the server supports it.
- Log every tools/list response and alert on unapproved changes and cross-tool references.
- Remove tools unused for 90 days and re-review the remaining set quarterly.
Standards and references
- Model Context Protocol: Tools specification
- Model Context Protocol: Security Best Practices
- Model Context Protocol: MCP Registry repository
- MITRE: ATLAS
- OWASP: LLM06:2025 Excessive Agency
- NIST: SP 800-53 Rev. 5 Security and Privacy Controls
- npm: Generating provenance statements
Related NHI Mgmt Group resources: AI Agent Tool and Plugin Security Guide · MCP Tool Poisoning Detection · MCP Registry and Server Publishing Security Guide · Agent Sandboxing vs Tool Allowlisting · Top 10 MCP Security Risks