# Agent 365 plus API Management: MCP tool governance you can actually enforce

> Microsoft's Agent 365 and Azure API Management preview puts MCP tool blocking at the gateway. Who should care, what it costs you, and where it stops.

Published: 2026-10-12
Author: Ihor Seleznov
Tags: AI/ML, Azure, Applied AI
Canonical: https://www.techfabric.com/blog/agent-365-api-management-mcp-governance

---

One of our clients runs software from many vendors, and most of those products now ship an MCP server. When we went to make those products available to AI agents, so an agent could query them or take an action, we ended up with more than fifty MCP servers in the registry. Every user was wiring servers into their own agent harness or AI tool by hand, with little to no governance over which tools anyone could reach.

What we wanted was one MCP server in front of the registry, a reverse proxy that agents connect to once, which authenticates the user and carries that identity down to the servers behind it. That shape is the whole ask. One door, one identity, one place to say no.

Agent 365's new integration with Azure API Management, now in public preview, does half of that job. Governance decisions stay centralized in Agent 365 and get enforced inline by API Management. Agent 365 holds the inventory of your gateway-managed MCP servers and makes the access decision; API Management enforces it inline, as real policy on a gateway running in your own subscription. The decision and the enforcement stop drifting apart, which is the failure mode of every tool registry maintained in a spreadsheet.

In this post I'll explain what the integration actually controls, where the gateway has to do work the integration doesn't do for you, and what we'd build on it.

## Who should care this quarter, and who can skip it

If your agents call tools directly, through a framework's own registry or a hosted MCP endpoint nobody fronted with a gateway, this does nothing for you yet. No gateway, no governance. The real decision in front of most teams isn't whether to turn on the preview. It's whether the gateway becomes the single door agents walk through. That is the harder, duller project, and it's the one that pays.

For a mid-sized company with one API Management instance and a handful of agents, we'd put the gateway consolidation first and the Agent 365 wiring second. Fifty servers wired per-user is a problem you fix by moving the servers behind a gateway. Once they're there, an admin console that can block a server tenant-wide is worth having.

```mermaid
%% caption: Agent 365 decides, API Management enforces. An agent that skips the gateway skips the governance.
flowchart TD
  A["AI agent"] --> B["API Management gateway"]
  B --> C["Vendor MCP servers"]
  D["Agent 365 admin console"] --> E["Managed policy on gateway"]
  E --> B
  F["Agent wired direct to server"] --> C
  class B accent
  class F legacy
```

## Getting the servers behind the gateway

API Management gives you two routes in. You can expose a REST API you already manage as an MCP server, where the API operations become tools, or you can front an MCP server somebody else wrote. For a registry of vendor servers, the second route is the one that matters. You point API Management at the existing server's base URL, pick a transport, and give it a base path for its tools. [The external server has to conform to MCP version 2025-06-18 or later, with Streamable HTTP or SSE transport, and either no authorization or a compliant authorization protocol](https://learn.microsoft.com/en-us/azure/api-management/expose-existing-mcp-server).

That version floor is the first thing we'd check against a vendor's server, because it decides whether this plan works at all for that product. A vendor shipping an older server is a vendor you're going to be chasing.

We'd put a policy on each server before anyone connects an agent. Rate limiting plus a trace of the calling agent tells you who is hammering what, and the inbound section is where both go:

```xml
<inbound>
    <base />
    <rate-limit-by-key calls="5" renewal-period="30" counter-key="@(context.Request.IpAddress)" remaining-calls-variable-name="remainingCallsPerIP" />
    <trace source="My MCP" severity="information">
        <message>My MCP trace info</message>
        <metadata name="agent-id" value="@(context.Request.Headers.GetValueOrDefault("agent-id", "n/a"))" />
    </trace>
</inbound>
```

## The identity question the integration doesn't answer

This is where we'd push back on the framing. Agent 365 decides which servers and tools exist and which are blocked, tenant-wide. It does not carry a user's identity to a downstream MCP server. That part is still yours to build, in gateway policy.

For inbound, we'd validate Entra tokens at the gateway instead of trusting whatever the client claims. [The `validate-azure-ad-token` policy names the tenant and the client application IDs you accept](https://learn.microsoft.com/en-us/azure/api-management/secure-mcp-servers):

```xml
<validate-azure-ad-token tenant-id="your-entra-tenant-id" header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized. Access token is missing or invalid.">
    <client-application-ids>
        <application-id>your-client-application-id</application-id>
    </client-application-ids>
</validate-azure-ad-token>
```

For outbound, request headers are forwarded to tool invocations automatically with certain exclusions, so a naive setup sometimes works by accident and then stops working when the exclusion list bites. One deliberate option is to declare `Authorization` as a required header and forward it in the outbound policy with `set-header`. The other is credential manager, where you register an app with the identity provider, create a credential provider in API Management, configure the connection, then fetch and attach the token with `get-authorization-context` and `set-header` on the way out. Credential manager is the one we'd reach for across fifty servers, because the alternative is fifty copies of a token-forwarding snippet nobody owns.

> "Govern at the gateway, not in the agent. Any control that lives inside the agent's own code is a control you have to re-implement for the next framework."
>
> Preetham Reddy, TechFabric

## The tier decision carries most of the weight

The announcement presents this as one capability. It's two. [API Management v2 tiers give you centralized MCP inventory and blocking or unblocking a whole server through Agent 365; the AI Gateway tier (preview) adds blocking of individual tools, tool activity observability, and tool threat protection](https://techcommunity.microsoft.com/blog/integrationsonazureblog/microsoft-agent-365-and-azure-api-management-integration-for-mcp-governance/4563335).

Server-level blocking is a crude instrument against a vendor server that exposes twenty tools, nineteen of them read-only and one that deletes things. Turning the server off takes the useful nineteen with it. So for a registry of third-party servers, tool-level control is the feature itself, and it only exists in a preview tier.

There's a configuration detail to plan for here. To get tool-level control from Agent 365 at all, each MCP server needs a static list of allowed tools configured. We'd make that a gating question when we evaluate a vendor's MCP server: does it present a fixed tool surface, or does it change under us?

Platform teams configure evaluation before invocation, after invocation, or both, and with blocking configured a pre-invocation check can stop a disallowed call executing while a post-invocation check can withhold an unsafe result before it reaches the agent. Post-invocation evaluation is the half we'd care about most for a tool that returns customer records into a model's context.

## What a blocked tool does to your agent

The enforcement behaviour matters before you ship anything. When an admin blocks a tool, [Agent 365 uses API Management control-plane operations to insert a managed policy, and a blocked call returns HTTP 200 with a JSON-RPC body carrying `isError=True`, a denial code of `ToolNotAvailable`, a correlation ID, and text telling the agent not to retry](https://learn.microsoft.com/en-us/azure/api-management/agent-365).

```http
HTTP/1.1 200 OK
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "id": 42,
  "result": {
    "content": [{"type": "text", "text": "Tool 'delete_file' is blocked by the gateway. Do not retry this tool."}],
    "isError": true
  }
}
```

A 200 carrying an error is a sensible protocol choice and a trap for anyone whose retry logic keys off status codes. We'd test agents against that shape deliberately, with a case in the evaluation suite asserting the agent explains the denial to the user instead of looping, and the correlation ID captured in the agent's own logs so a support ticket can be joined to a gateway decision.

## What it costs and what it puts at risk

After a customer administrator grants the A365 MCP Gateway Policy Operator Azure role at the tenant level with a one-time consent, governance operations run under Microsoft Agent 365's app-only identity, so individual Agent 365 administrators don't need separate Azure permissions to act on AI assets in the gateway.

Read that again as a platform engineer. You're giving Agent 365's service identity the ability to read and write API-scoped policies on your gateway, and to discover supported resources in existing and future tenant subscriptions. For most mid-sized companies that's a fair trade for not maintaining a parallel approval process.

## Where this stops

This governs the tool call. It says nothing about what the tool returns once called. Where agents read governed data, the row and column decisions belong in the data platform, and the gateway decides only whether the tool may be called at all. Two layers asking two different questions, and we'd keep them separate on purpose. When a tool reads from a lakehouse, the filter on the data is the control that survives someone standing up a second gateway. That's also where [getting ERP or CRM data into a governed platform](/databricks/data-integration) earns its keep, because a tool is only as governable as the table underneath it.

It also won't fix an agent that has too many tools. Blocking is applied after someone notices. The design work, deciding which tools an agent gets and scoping each one narrowly, is still yours.

And it's a preview, in both the integration and the tier carrying the interesting half. We wouldn't put a compliance commitment on top of tool-level blocking this quarter, and we'd be careful putting even inventory and server-level blocking in front of an auditor, because the integration delivering them is itself in public preview. Preview features, regions, limits and APIs can change before general availability.

## Try it on one MCP server behind your gateway

That round trip tells you more about whether this model fits your organisation than any amount of reading. If it holds, the question that follows is the real one. Which agents are still reaching tools without passing through that gateway, and what would it take to move them?

## Frequently asked questions

### Does Agent 365 work with MCP servers that aren't behind Azure API Management?

Not through this integration. Agent 365 discovers `Microsoft.ApiManagement` resources in your tenant and the MCP servers and tools they expose, so a tool reached by any other path gets no gateway enforcement from it.

### What's the difference between the v2 tiers and the AI Gateway tier here?

The v2 tiers give you centralized MCP server inventory in Agent 365 plus blocking and unblocking a whole server, while the AI Gateway tier (preview) adds blocking of individual tools, tool activity observability and the tool threat protection policy backed by Defender and Purview. If you need to leave a server running while disabling one destructive tool on it, you need the AI Gateway tier.

### What does an agent see when a tool is blocked?

An HTTP 200 response whose JSON-RPC body has `isError` set to true, a denial code of `ToolNotAvailable`, a correlation ID and text telling the agent not to retry that tool. Agents keying retries off HTTP status codes will treat it as success, so test that path before you rely on it.

### Can I pass the signed-in user's identity through to a downstream MCP server?

Yes, but you build it in gateway policy instead of getting it from Agent 365. Validate the inbound Entra token with `validate-azure-ad-token`, then either forward the `Authorization` header explicitly with `set-header` in the outbound policy or use API Management credential manager with `get-authorization-context` to attach a token for the backend call.
