Microsoft 365 Copilot Extensibility - Building Plugins That Connect to Your Business Systems
Most organisations using Microsoft 365 Copilot are getting about 30% of the value they could be getting. The reason is simple - out of the box, Copilot can summarise your emails, draft documents, and help with Teams meetings. But it doesn't know anything about your business systems. It can't check your CRM, query your internal databases, or interact with your custom applications.
That's what Copilot extensibility fixes. And specifically, that's what plugins do.
We've been building Copilot extensions for clients since the extensibility framework launched, and the pattern is consistent: the moment Copilot can talk to your actual business data, adoption goes from "nice to have" to "can't work without it." The official extensibility documentation covers the technical reference well. Here's what we've learned putting these into production.
What Copilot Plugins Actually Do
A plugin lets a declarative agent in Microsoft 365 Copilot interact with an MCP server or REST API. That's the one-sentence version.
In practice, it means a user can ask a question in natural language - "How much is left in the Melbourne office renovation budget?" - and Copilot figures out which plugin to call, what parameters to pass, makes the API call, and turns the response into a conversational answer.
It's not just read operations either. Users can create records, update data, and trigger workflows through natural language. "Charge $500 to the Melbourne office renovation budget for the new desks" works too. Copilot translates the intent into the right API call with the right parameters.
The key thing to understand is that plugins only work inside declarative agents. They're not enabled directly in the base Microsoft 365 Copilot experience. You build a declarative agent, attach plugins to it, and deploy that agent to your users. This is an important architectural decision that some teams miss early on.
How the Architecture Works
The flow is surprisingly straightforward once you see it laid out.
A user asks the agent a question. The agent looks at its available plugins and figures out which one (if any) can answer it. It maps parts of the user's question to the tool's parameters. Before sending any data to the plugin for the first time, Copilot asks the user for permission - this is a nice privacy touch that builds trust.
If authentication is needed, the system handles token management through its token store. The agent sends the request to your MCP server or REST API - which lives outside Microsoft 365 - and gets back a response. Then it generates a conversational answer using that response data.
For read operations after the initial permission grant, subsequent calls happen without prompting. Write operations always require confirmation. Plugin developers can override these defaults, which is worth doing when you want tighter control over what happens automatically.
MCP Servers vs REST APIs - Choosing the Right Approach
You've got two paths for building plugins - MCP (Model Context Protocol) servers and traditional REST APIs with OpenAPI descriptions.
For teams already building with MCP, the server approach is natural. You define tools on your MCP server, and Copilot calls them through the standard protocol. The budget example from Microsoft's docs shows this well - a get-budgets tool and a charge-budget tool exposed through MCP endpoints.
For teams with existing REST APIs, you describe them with an OpenAPI specification and Copilot figures out how to call them. If you already have well-documented APIs, this path is faster because you're building on what exists.
Our recommendation? If you're starting fresh, go with MCP. The protocol is designed for agent-to-tool communication and it handles things like tool discovery more naturally. If you've got existing APIs with good OpenAPI descriptions, start with REST and consider migrating to MCP later.
Either way, both approaches use the same plugin manifest format, and both get the same treatment from the Copilot orchestrator.
Writing Descriptions That Actually Work
Here's the bit that makes or breaks your plugin, and most documentation glosses over it.
Copilot uses a language model to decide which plugin to call. It reads the descriptions in your plugin manifest and matches them against the user's intent. A vague description means Copilot guesses. A specific description means Copilot picks correctly.
For API plugins, the magic happens in your OpenAPI description. Operation summaries, parameter descriptions, response schemas - all of this feeds into Copilot's decision-making. Microsoft has specific guidance on this, and it's worth reading carefully. The difference between "Get data" and "Retrieve the current available balance and spending history for a specific department budget by name" is the difference between a plugin that works and one that frustrates people.
For Copilot Studio actions, descriptions live in the conversation map. For message extension plugins, they're in the app manifest. Different locations, same principle - be specific about what the tool does, what parameters it needs, and what it returns.
We've found that testing with ambiguous prompts is the best way to refine descriptions. Ask your agent something that could match multiple plugins and see which one it picks. If it picks wrong, the descriptions need work.
Declarative Agent Limits You Should Know About
There are some practical constraints that affect how you architect your solution.
When a declarative agent has up to five plugins, they're all injected into the prompt. Every request, all five are available. When you go beyond five, the system switches to semantic matching based on the plugin's description (not the individual functions). This means your plugin-level description becomes even more important at scale.
Within a single plugin, you can have unlimited functions. But context window limits mean quality can degrade if you pack in more than ten functions. We've found that keeping plugins focused - one plugin per business domain - works better than building a mega-plugin that does everything.
Token windows also limit how much data you can send and receive. If your API returns massive JSON payloads, you'll want to trim responses to only what's relevant. The functional limits will improve as models get better, but for now, design for efficiency.
Generating Plugin Packages
Microsoft provides two tools for building plugins. The Microsoft 365 Agents Toolkit works in Visual Studio and Visual Studio Code - it can generate plugin packages from an existing MCP server or OpenAPI description and includes starter projects. Kiota is a command line tool that generates packages from OpenAPI specs.
For most teams we work with, the Agents Toolkit in VS Code is the faster path. It handles the manifest generation, project scaffolding, and testing workflow. Kiota is useful when you want to automate plugin generation as part of a CI/CD pipeline.
Adaptive Cards for Better Responses
By default, Copilot generates conversational text responses from your API data. But you can provide Adaptive Card templates that display data in a structured, visual format. This matters more than you'd think for business users.
A budget query that returns "The Melbourne office renovation budget has $5,000 remaining" is fine. But an Adaptive Card that shows the budget name, remaining funds, recent transactions, and a progress bar? That's the kind of response that makes people actually use the tool daily.
Building Adaptive Cards adds development time, but the user experience improvement is significant for data-heavy use cases.
Authentication Patterns
Plugin authentication supports account keys, SAS tokens, service principals, and system-assigned managed identities. For most enterprise deployments, service principals with Azure AD are the way to go - they integrate cleanly with existing identity management.
The token store handles refresh flows automatically, which is one less thing to worry about. Users only need to authenticate once, and subsequent calls reuse the stored credentials.
One gotcha we've seen - if your API uses a less common authentication method, you might need to implement a custom auth flow. The standard patterns cover maybe 90% of cases, but that remaining 10% can burn a surprising amount of time.
What We'd Suggest for Getting Started
If you're already running Microsoft 365 Copilot, building a plugin should be near the top of your priority list. The gap between generic Copilot and Copilot-with-your-business-data is massive.
Start with a single read-only use case. Pick the system your team queries most often - your CRM, your project management tool, your internal knowledge base. Build a plugin that lets Copilot answer questions from that system. Deploy it to a small pilot group and see what happens.
Once people experience asking Copilot a business question and getting a real answer in seconds, they'll start asking for more. That's when you expand - add write operations, connect more systems, build custom Adaptive Cards.
For organisations looking at Copilot Studio consulting or broader AI integration services, extending Copilot with plugins is often the highest-ROI starting point. It builds on a platform your team already uses, it doesn't require new software rollouts, and the time-to-value is measured in weeks rather than months.
If you want help scoping what a Copilot plugin could look like for your specific systems, our Microsoft AI consulting team has been through this process with a range of Australian enterprises. We can usually give you a realistic assessment in a single workshop - what's feasible, what's hard, and what the expected payoff looks like.
The official plugin documentation is solid technical reference material. Between that and what I've covered here about the practical side, you'll have a good foundation for deciding whether this is worth your team's time. (Spoiler - it almost certainly is.)