# Publish an MCP Server to Microsoft 365 Copilot

How to register a remote MCP server as an agent connector for Microsoft 365 Copilot: the agentConnectors manifest array, five authentication modes, static versus dynamic tool discovery, validation, and what tenant admins gate.

Source: https://node8.ai/mcp-platforms/copilot/

---

[MCP Distribution](https://node8.ai/mcp-platforms/) · Microsoft 365 Copilot

# Publishing an MCP server to Microsoft 365 Copilot

Microsoft is the odd one out. There is no submission portal that reads your server and walks you through a listing. You declare the server in an app manifest, and the app is what gets validated and published. Get the manifest right and most of the work is administrative rather than technical.

Talk through a submission [The manifest](#manifest)

The shape of it

## The connector and the app are two different things

An agent connector is how a Microsoft 365 agent reaches an external system. For an MCP server the connector supplies four things: the network endpoint, the authentication configuration, the tool definitions, and optional metadata that helps an agent pick the right tool. You declare it in the manifest. Once registered, the server is available to any Microsoft 365 agent that can use MCP.

What surprises teams is that the connector and the store listing move on separate tracks. A server can be registered and reachable while the surrounding app package is still in validation, so "is it live?" has two answers depending on which thing you mean. Decide early which one your launch actually depends on, because they do not arrive together.

You need a test tenant to validate against before any of this reaches a customer. That is not optional in practice, and it is the difference between finding a broken redirect yourself and finding it in a reviewer's notes.

The manifest

## Declaring the server

Add a root-level `agentConnectors` array to `manifest.json`. Each connector needs an id unique within the manifest.

Field

What it is

manifestVersion

1.27 on current schemas

agentConnectors\[\].id

Unique within the manifest

displayName / description

What the agent and the admin see

toolSource.remoteMcpServer.mcpServerUrl

Your endpoint, HTTPS or WSS

…authorization.type

One of the five modes below

…authorization.referenceId

Points at a configuration registered in Developer Portal

…mcpToolDescription

Optional. Omit it for runtime tool discovery

Microsoft 365 agents open long-lived connections to this endpoint, so it has to be publicly reachable and stable, not a tunnel.

Authentication

## Five modes, and when each is right

### None

No authentication. Microsoft explicitly does not recommend it for production, and an enterprise tenant admin is unlikely to approve it.

### OAuthPluginVault

OAuth 2.0 tokens held in Microsoft’s vault, referenced by an ID you register in Developer Portal. The default choice for enterprise scenarios.

### ApiKeyPluginVault

An API key held in the vault and referenced by ID. Simpler, and weaker: it identifies your app, not the user.

### DynamicClientRegistration

Microsoft registers itself as an OAuth client at runtime via RFC 7591. Your server must expose a compliant registration endpoint, return a client\_id and client\_secret, and support token refresh.

### AzureKeyVault

Credentials in your own Key Vault, so you keep rotation, access policies and audit logging. You grant the Microsoft 365 service principal read access to the secret.

Secrets are never embedded in the manifest. Each mode stores the credential somewhere and the manifest carries only a `referenceId`. When you configure the OAuth app with your identity provider, add `https://teams.microsoft.com/api/platform/v1.0/oAuthRedirect` to the allowed redirect endpoints. Omitting it produces a failure that looks like a Microsoft problem and is not.

Tool discovery

## Static definitions or runtime discovery

Include an `mcpToolDescription` and you pin inline tool definitions that must match the schema your server returns from `tools/list`. Omit it and agents call `tools/list` at runtime, picking up added, changed or removed tools without a manifest republish.

For anything still evolving, dynamic discovery is the better default, and Microsoft recommends it for toolsets that change frequently. The trade is predictability: with runtime discovery, what an agent can do changes when you deploy, which is convenient for you and a governance question for the tenant admin who approved the app. Say which one you have chosen when you ask for that approval.

Before you publish

## Validate it yourself first

Validate the manifest with the Microsoft 365 app package validation tool in Developer Portal

Confirm the server answers MCP handshake messages on a public HTTPS or WSS endpoint

Check tools/list returns unique names, clear descriptions and valid JSON Schema for every input

Verify each referenceId resolves to a real secret, and that token refresh works for OAuth

Ensure the endpoint supports TLS 1.2 or higher

Check error messages and retry semantics for failed tool calls

Then test in a tenant with real natural-language requests rather than tool calls: check the tools appear in the agent's available actions, that consent prompts show where they should, that calls succeed, and that failures degrade gracefully. If you need multi-tenant support, test across more than one tenant before you find out the hard way.

Expect validation feedback to arrive as a list of must-fix items rather than a verdict, and expect publishing to take its own time after approval. The engineering is usually finished well before the process is.

FAQ

## Microsoft 365 Copilot questions

Do I submit an MCP server to a Copilot marketplace?

Not directly. You declare the server as an agent connector inside a Microsoft 365 app manifest, and it is the app that gets packaged, validated and published. That distinction matters because the two can move independently: the connector can be reachable while the app package is still working through store validation, which regularly confuses teams who expect one submission and one approval.

What is an agentConnectors array?

A root-level array in the Microsoft 365 app manifest where you declare each MCP server. A connector entry needs a unique id, a displayName, a description, and a toolSource pointing at your remoteMcpServer with its mcpServerUrl. Current manifests use manifestVersion 1.27. Once registered, the server becomes available to any Microsoft 365 agent capable of using MCP.

Should I list tools statically or let Copilot discover them?

Omit mcpToolDescription and Microsoft calls tools/list at runtime, so adding or changing tools does not require republishing the app. Include it and you pin an inline definition that must match your server’s tools/list response. Dynamic discovery is the right default for anything still evolving; static definitions suit a toolset that genuinely does not change.

How long does Microsoft validation take?

Longer than the engineering, and it is not a single decision. Validation typically comes back with a list of must-fix issues to close before you resubmit through Partner Center, and store publishing then takes its own time after approval. Plan in weeks rather than days, and keep a named contact on the thread, because progress often depends on a reply rather than on work.

What do I need for OAuth to work?

Register the OAuth configuration in Developer Portal and reference it by referenceId in the manifest rather than embedding secrets. When you set the app up with your identity provider, add https://teams.microsoft.com/api/platform/v1.0/oAuthRedirect to the allowed redirect endpoints. Missing that redirect is a common and undiagnosable-looking failure.

Does the tenant administrator have to approve it?

In practice yes, and it is the gating factor more often than engineering is. The customer’s IT organisation decides what reaches their users. That changes what you should prepare: a clear statement of what data the connector reaches, which authentication mode it uses, and what an admin is approving. Enterprise scenarios should prefer OAuth over API keys for exactly this reason.

The other surfaces

## Same server, different reviewers

### [Publishing to Claude](https://node8.ai/mcp-platforms/claude/)

A submission portal inside your organization settings, which needs a Team or Enterprise plan before you can submit at all.

### [Publishing to ChatGPT](https://node8.ai/mcp-platforms/chatgpt/)

Identity verification, a .well-known domain challenge, and eight test cases including three the app should refuse.

[Compare all four surfaces](https://node8.ai/mcp-platforms/) [The cross-platform playbook](https://node8.ai/kb/publishing-mcp-connectors-claude-chatgpt-copilot/)

## Want the submission handled, not explained?

Node8 builds the MCP server, gets the manifest, authentication and tenant story right, and takes it through validation. Most first connectors ship in eight to twelve weeks, and the build is rarely the long pole.

[MCP connector development](https://node8.ai/mcp) Book a strategy session
