Skip to main content

Microsoft Copilot Studio

Point a Copilot Studio agent at the Waxell MCP Gateway and every tool it calls flows through one governed endpoint — policy-checked, per-tool allow/deny/redact, and audited — reaching the same catalog of upstreams (GitHub, Slack, Notion, Linear, internal systems) your other agents use. The agent lives in Microsoft's world; the governance is yours.

The connection is a Power Platform custom connector that speaks MCP over Streamable HTTP. The x-ms-agentic-protocol: mcp-streamable-1.0 extension is what makes Copilot Studio treat the gateway as an MCP server and enumerate its tools.

Pick an attribution mode

The only real decision is which identity the gateway sees behind each call:

ModeGateway seesGood for
API keyone shared principal (the key's owner)read-only or low-risk tools; fastest to stand up
Per-user OAuththe signed-in end userwrite-heavy or sensitive tools — real per-human governance and audit

Copilot Studio always binds a tool connection per user, but with an API-key connector every user binds to the same key, so the gateway can't tell them apart. If accountability matters, use OAuth — each end user signs in and the gateway resolves and governs the call under the actual human.

You can create both connectors and use whichever fits an agent.

Prerequisites

  • A Waxell tenant with the gateway enabled, and a Waxell account you can sign in with.
  • Power Platform maker access to the environment your agents live in.
  • The Power Platform CLI (pac) — or use the maker portal's Import an OpenAPI file instead of pac connector create.

1. Define the connector

Both modes share the same OpenAPI definition — a single POST /mcp operation carrying the MCP protocol extension. Save this as apiDefinition.swagger.json:

{
"swagger": "2.0",
"info": { "title": "Waxell MCP Gateway", "version": "1.0" },
"host": "mcp-gateway.waxell.dev",
"basePath": "/",
"schemes": ["https"],
"paths": {
"/mcp": {
"post": {
"summary": "Waxell MCP Gateway (Streamable HTTP)",
"operationId": "InvokeMCP",
"x-ms-agentic-protocol": "mcp-streamable-1.0",
"responses": { "200": { "description": "Success" } }
}
}
}
}

The rest — the security scheme — differs by mode (below). A connector name with only letters, numbers, -, or _ avoids a pac validation error, so prefer Waxell MCP Gateway over anything with parentheses.

2a. API key (shared identity)

Add API-key security in the Authorization header. Save this as apiProperties.json:

{
"properties": {
"connectionParameters": {
"api_key": {
"type": "securestring",
"uiDefinition": {
"displayName": "Waxell API key",
"description": "Enter the full header value, e.g. 'Bearer wax_sk_...'",
"constraints": { "required": "true", "clearText": false }
}
}
}
}
}

…and add the matching securityDefinitions block to the swagger:

"securityDefinitions": {
"api_key": { "type": "apiKey", "in": "header", "name": "Authorization" }
},
"security": [ { "api_key": [] } ]

Create the connector and a connection:

pac connector create \
--api-definition-file apiDefinition.swagger.json \
--api-properties-file apiProperties.json \
--environment <ENVIRONMENT_ID>

Then in make.powerapps.com → Connections → + New connection, find Waxell MCP Gateway, and paste your key including the scheme into the Waxell API key field:

Bearer wax_sk_...

Every call from any agent using this connection is attributed to that key. Skip to step 3.

Here the connector points at the Waxell MCP authorization server, so each end user signs in and the gateway governs under their identity. The gateway advertises its authorization server via its protected-resource metadata:

curl https://mcp-gateway.waxell.dev/.well-known/oauth-protected-resource
# → "authorization_servers": ["https://app.waxell.dev"]
curl https://app.waxell.dev/.well-known/oauth-authorization-server
# → authorization_endpoint, token_endpoint, registration_endpoint

Create the connector first so Power Platform assigns its redirect URL — you need it in the next step. Use the swagger from step 1 with an OAuth 2.0 security scheme:

"securityDefinitions": {
"oauth2-auth": {
"type": "oauth2",
"flow": "accessCode",
"authorizationUrl": "https://app.waxell.dev/api/oauth/mcp/authorize/",
"tokenUrl": "https://app.waxell.dev/api/oauth/mcp/token/",
"scopes": {}
}
},
"security": [ { "oauth2-auth": [] } ]

Create it, then open it in make.powerapps.com → Custom connectors → Waxell MCP Gateway → Security and copy its Redirect URL. Power Platform appends the connector's unique name, so it looks like:

https://global.consent.azure-apim.net/redirect/<connector-unique-name>
Register the client with the exact redirect URL

Register with the bare .../redirect and the authorize step fails with Invalid redirect_uri. Use the full per-connector URL Power Platform shows on the Security tab.

Register an OAuth client with that redirect using Dynamic Client Registration:

curl -X POST https://app.waxell.dev/api/oauth/mcp/register/ \
-H "Content-Type: application/json" \
-d '{
"client_name": "Copilot Studio - Waxell MCP Gateway",
"redirect_uris": ["https://global.consent.azure-apim.net/redirect/<connector-unique-name>"],
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"token_endpoint_auth_method": "client_secret_post"
}'
# → { "client_id": "...", "client_secret": "..." }

Put the returned client_id / client_secret into the connector's OAuth settings (Security tab → Client id / Client secret, or the oAuthSettings block if you manage the connector with pac) and save. Leave Scope empty and the resource/audience unset — the gateway handles both.

Now create a connection: Connections → + New connection → Waxell MCP Gateway (OAuth) → Create. A Waxell sign-in window opens; authenticate and approve. The connection binds to your Waxell identity, and tokens refresh silently from then on. Each additional end user does this once.

3. Add the connector to an agent

In copilotstudio.microsoft.com, open your agent → Tools → + Add a tool, filter to Model Context Protocol, and pick your Waxell MCP Gateway connector. Select (or create) the connection when prompted.

Copilot Studio runs the MCP handshake and the agent's tool list gains the gateway's meta-tools — find_tools, use_tool, call_external_tool, get_tool_details. If your agent's instructions are narrowly scoped, add a line permitting it to use the gateway, e.g. "When asked, use the Waxell MCP Gateway tool to fetch live data from a connected system."

Test-pane connections

In the Test your agent pane, the invoking user (you) is prompted to connect the tool the first time. If it says the connection is stale or not connected, open the connection manager and bind the connection — this is Copilot Studio's per-user consent, and it's the same step every end user goes through.

4. Verify the governance

Ask the agent something that drives a tool call:

Use the Waxell MCP Gateway: find a tool to list Linear issues, then call it.

Then open Governance → MCP Gateway → Activity in the Waxell app. You'll see the call land in real time — the decision (allow / deny / redact), the tool, latency, and the identity:

  • with the API-key connector, the row is attributed to the key's owner;
  • with the OAuth connector, it's attributed to the signed-in end user — the whole point.

Flip a per-tool policy to deny or redact and re-run to watch the agent's call fail closed at the gateway. See Policies.

Troubleshooting

SymptomCause
Authorize step: Invalid redirect_uriThe registered client's redirect doesn't match the connector's per-connector redirect URL. Copy it from the connector's Security tab and re-register.
Tool call fails unauthorized / invalid_token on initializeThe connection's token predates the connector's OAuth config — delete the connection and reconnect so a fresh token is minted.
Agent says the tool "isn't available"The MCP tool failed to initialize (see above) or the agent's instructions forbid external tools — broaden them (step 3).
Connector doesn't appear under Model Context ProtocolThe swagger is missing x-ms-agentic-protocol: mcp-streamable-1.0 on the /mcp operation.

More gateway errors are in Troubleshooting.