Every MCP plugin used to carry a frozen snapshot of its tools. You picked the tools, captured their descriptions, packaged them into the plugin manifest, and shipped that version of the agent. Then your MCP server evolved. A new tool shipped. A parameter changed. A description got better. The server was ready, but the agent still lived in yesterday’s manifest until you repackaged, revalidated, and republished it.
Dynamic tool discovery changes that contract. Instead of making the agent carry a fixed tool list forever, Microsoft 365 Copilot can resolve the current tools directly from the MCP server at runtime. The tool surface follows the server, not the package.
That sounds like a small manifest change. It is actually a platform shift: MCP plugins become living integrations.
The Old Model: Pinned Tools
Pinned tools are explicit and predictable. The plugin manifest lists the functions the agent can call, and the MCP runtime is bound to those names. The package includes the tool definitions, usually in an mcp-tools.json file generated from the MCP server’s tools/list response.
{
"functions": [
{ "name": "search_repositories" },
{ "name": "search_users" }
],
"runtimes": [
{
"type": "RemoteMCPServer",
"spec": {
"url": "https://api.contoso.com/mcp",
"mcp_tool_description": {
"file": "mcp-tools.json"
}
},
"run_for_functions": [
"search_repositories",
"search_users"
]
}
]
}
That model is still useful when you want a curated, stable subset of a larger server. Maybe your MCP server exposes twenty internal tools, but this specific agent should only use two of them. Maybe a regulated workflow requires the exact tool list to be reviewed before rollout. Pinned tools give you that control.
But pinned tools also turn every tool change into an agent release:
- Add a new tool: update the manifest, package, validate, publish.
- Remove a deprecated tool: update the manifest, package, validate, publish.
- Rename a parameter: update the tool definition, package, validate, publish.
- Improve a tool description so the model calls it more reliably: update the package again.
That is the wrong feedback loop for MCP servers that are supposed to evolve quickly.
The New Model: Runtime Discovery
With dynamic tool discovery, the manifest stops carrying the complete tool list. The runtime points at the MCP server, and run_for_functions uses a wildcard.
{
"functions": [],
"runtimes": [
{
"type": "RemoteMCPServer",
"spec": {
"url": "https://api.contoso.com/mcp"
},
"run_for_functions": [
"*"
]
}
]
}
Now the platform fetches tool definitions from the MCP server at runtime. If the server exposes a new tool, the agent can see it after the server deployment and runtime validation pass. If the server returns a different tool set for different users, the agent can operate against that user-specific surface.
That last point is the sleeper feature.
Pinned tools assume every user sees the same tool list. Dynamic discovery lets the MCP server tailor tools by SKU, license, role, entitlement, geography, or tenant configuration. An admin might see approve_budget_exception; an employee might only see request_budget_exception. The same agent package can adapt because the server owns the tool surface.
Dynamic tool discovery is the default configuration when Microsoft 365 Agents Toolkit creates a new MCP plugin. You only need to pin tools when you intentionally want a fixed, curated set.
What Actually Changes in Your Project
If you create an MCP plugin with Microsoft 365 Agents Toolkit, this is mostly handled for you. Start with an MCP server, choose the authentication type, and the generated ai-plugin.json is configured for dynamic discovery by default.
The practical differences are:
| Concern | Pinned tools | Dynamic discovery |
|---|---|---|
| Tool source | Plugin manifest package | MCP server at runtime |
functions | Lists selected tools | Empty array |
run_for_functions | Lists selected tool names | ["*"] |
| Tool definition file | Required for selected tools | Not required for discovery |
| New server tool | Requires republishing | Picked up after runtime validation |
| User-specific tools | Not supported | Supported by server-specific tools/list responses |
You can still switch back to pinned tools. Agents Toolkit can fetch the MCP server actions and let you select a subset. When you do that, it updates the manifest with the selected functions, run_for_functions, and tool descriptions.
Use dynamic discovery as the default. Pin only when there is a product, compliance, or safety reason to freeze the tool surface.
The Zava Example: Benefits Without Repackaging
Let’s go back to Zava Insurance, the fictional company from our earlier MCP server walkthrough. The first version of the helpdesk MCP server exposes two tools:
createTicketgetTicketStatus
The HR onboarding agent launches with those tools. A few weeks later, the helpdesk team adds:
escalateTicketattachScreenshotlistKnownOutages
With pinned tools, the server team is done but the agent team is not. Someone has to update the plugin manifest, regenerate the tool description file, package the app, publish it again, and wait for users to get the new version.
With dynamic discovery, the server deployment is the main release vehicle. Once the MCP server exposes the new tools, Copilot can discover them at runtime, validate them, and make them available to the agent.
The conversation changes from:
to:
No agent republish. No manifest churn. The server shipped the capability, and the agent followed.
Why Runtime Discovery Still Needs Governance
Dynamic discovery does not mean “anything the server says goes.” The platform still preserves the trust model around declarative agents and plugins.
The official docs call out three important controls:
- Publish-time validation still applies to the agent. The agent package and plugin configuration are still reviewed through the normal flow.
- Runtime validation applies to discovered tools. Newly discovered or modified tools are checked before activation, including responsible AI and cross-prompt injection attack validation.
- Admins can see the discovery model. The Microsoft 365 admin center surfaces when an agent uses dynamic discovery in the agent details view.
That means dynamic discovery shifts tool freshness to runtime without removing admin visibility. Admins can still disable or scope the agent through existing agent-management controls, and Copilot interactions continue to appear in Microsoft Purview audit logs under the Copilot workload.
Dynamic discovery makes your MCP server’s tool descriptions production-critical. Treat tools/list output like an API contract. Review names, descriptions, schemas, and destructive-action semantics before deploying them.
Design Rules for Dynamic Tool Surfaces
The server is now closer to the product boundary, so design it that way.
Keep tool names stable. Rename a tool only when you are willing to treat it like a breaking change. The model learns when to use tools from names, descriptions, and schemas. Stability helps.
Write descriptions for orchestration, not humans. A tool description is not marketing copy. Tell the model when to call the tool, what it does, and what not to use it for.
Use role-specific discovery intentionally. If a user is not allowed to use a tool, prefer not returning it from discovery instead of returning it and failing at invocation time. The agent cannot call what it cannot see.
Keep destructive operations explicit. Tools like deleteRecord, submitOrder, or closeCase should have clear names, clear schemas, and confirmation-oriented instructions in the agent. Dynamic discovery does not remove the need for safe tool design.
Version server behavior behind stable tools. If you need to evolve internals, keep the tool contract stable and change the implementation. If you need a new contract, add a new tool before removing the old one.
Dynamic Discovery and MCP Apps
Dynamic tool discovery also includes tools that return interactive UI widgets, or MCP apps. If your MCP server exposes a tool that returns a widget, Copilot can discover that tool at runtime and render the UI without extra manifest wiring.
That matters because MCP is no longer just a text-action protocol inside Copilot. A server can expose:
- a search tool that returns structured results,
- a create tool that asks for confirmation,
- and a dashboard tool that renders an inline widget.
With dynamic discovery, the widget-returning tool can be added after the first agent release, as long as it passes the runtime checks.
When to Pin Instead
Dynamic discovery should be your default, but not your only option. Pin tools when:
- The agent must expose a deliberately small subset of a broad MCP server.
- A compliance process needs a fixed tool list per agent version.
- You are testing a new MCP server and want to limit blast radius.
- The server has experimental tools that should not appear in Copilot yet.
- You want deterministic demos or training labs where the tool list never changes.
Pinned tools are a product choice. Dynamic discovery is the better operating model for most production MCP servers.
The Value You Just Unlocked
Dynamic tool discovery turns an MCP plugin from a static integration into a runtime contract:
- Faster capability rollout: Server-side tool changes can appear without repackaging the agent.
- Lower release overhead: Fewer manifest updates for routine tool additions and description improvements.
- User-specific tools: The MCP server can tailor tools by role, entitlement, tenant, or license.
- Built-in governance: Runtime validation and admin visibility preserve trust and safety.
- Widget-ready extensibility: Tools that return MCP app UI widgets can be discovered at runtime too.
If MCP is the protocol for portable agent tools, dynamic discovery is what lets those tools keep moving after the agent ships.
Resources
Have questions or want to share what you're building? Connect with me on LinkedIn or check out more on The Manifest.