DEV Community

Kartik Anand
Kartik Anand

Posted on • Originally published at Medium on

# Your Security Team Is Right to Block Local MCP Connections. Here’s the Alternative.

# Your Security Team Is Right to Block Local MCP Connections. Here’s the Alternative.

**By Kartik Anand, Cloud & AI Architect | Agentic Systems on Azure**

— -

A healthcare enterprise I work with recently blocked their developers from connecting to MCP servers from local machines. The security team’s reasoning was straightforward: no audit trail, no identity enforcement, no rate limiting, no data loss prevention. Any developer connecting their laptop directly to a Fabric or Power BI MCP server is an ungoverned connection in an environment that can’t afford ungoverned connections.

They were right to block it.

The problem is they had no alternative to offer. Developers who wanted to use AI agents with their Fabric data were told no — full stop. The capability existed, the need existed, and the security posture made it inaccessible.

I built a POC in an afternoon that changes that answer from “no” to “yes, through the right channel.”

— -

## The Problem With Local MCP Connections at Scale

Model Context Protocol is the right abstraction for connecting AI agents to enterprise data systems. Snowflake, Microsoft Fabric, Power BI, Databricks — they’re all building managed MCP servers. The protocol is winning and the ecosystem is accelerating.

But the default implementation pattern looks like this:


Developer laptop → Fabric MCP server (direct)

Developer laptop → Power BI MCP server (direct)

Developer laptop → Snowflake MCP server (direct)

Enter fullscreen mode Exit fullscreen mode

Point-to-point. Each developer managing their own connection, their own credentials, their own everything. No consistency. No governance. No visibility into who called what and when.

For a consumer use case, that’s fine. For an enterprise healthcare environment handling PHI-adjacent data, that’s a compliance problem waiting to happen. The security team’s instinct to block it isn’t obstruction — it’s the right call.

— -

## The Pattern: API Management as an Enterprise MCP Gateway

Azure API Management is already the right answer to ungoverned API access. It’s what you put in front of APIs when you need consistent auth, retry, rate limiting, versioning, and observability across heterogeneous backends. MCP servers are APIs. The same governance logic applies.

The architecture:

Developer Machine (VS Code / Claude Desktop)

→ Enterprise APIM Gateway (/mcp/fabric)

→ Microsoft Fabric Core MCP Server

(api.fabric.microsoft.com/v1/mcp/core)


The developer never touches the MCP server directly. They point their MCP client at the APIM endpoint. APIM validates their identity, enforces rate limits, exchanges tokens, forwards the request, logs the result, and returns the response. The MCP server sees a valid, governed request. The developer gets their answer.

What the security team gets:

- **\*\*Identity enforcement\*\***  — every call validated against Entra ID before it reaches Fabric

- **\*\*Audit trail\*\***  — every call logged with caller identity, timestamp, status, and duration

- **\*\*Rate limiting\*\***  — one developer can’t hammer a shared MCP server and impact others

- **\*\*No credential sprawl\*\***  — developers never hold Fabric credentials directly, only an APIM subscription key and their own Entra token

- **\*\*Single revocation point\*\***  — disable a developer’s subscription key without touching Fabric or the MCP server

What the developer gets: full Fabric MCP access, from VS Code or Claude Desktop, governed and audited. The answer changes from “no” to “yes, through the right channel.”

**— -**

**## What Microsoft Fabric Core MCP Actually Exposes**

Before building the gateway, it’s worth knowing what’s on the other side. Microsoft Fabric Core MCP Server is a remote, Microsoft-hosted endpoint at:

Enter fullscreen mode Exit fullscreen mode

https://api.fabric.microsoft.com/v1/mcp/core


It exposes 27 tools across five capability areas:

- **\*\*Workspace management\*\***  — list, get, create, update, delete workspaces

- **\*\*Item management\*\***  — list, get, create, update, delete, move Fabric items (Lakehouses, Warehouses, Notebooks, Data Agents, Semantic Models, Eventhouses, Pipelines)

- **\*\*Role management\*\***  — full RBAC management via natural language

- **\*\*Catalog search\*\***  — search across the entire Fabric estate

- **\*\*Knowledge\*\***  — Fabric documentation and capability discovery

In practice, a developer in VS Code with GitHub Copilot Agent mode can ask:

Enter fullscreen mode Exit fullscreen mode

What Fabric workspaces do I have access to?

List all items in the Clinical Data workspace

Search the catalog for anything related to claims


And get structured, accurate responses drawn from their actual Fabric environment — through the governed gateway, with every call logged.

**— -**

**## Building It: The APIM Policy That Makes It Work**

The core of the implementation is an APIM inbound/backend/outbound policy that handles auth, token exchange, retry, rate limiting, and audit logging in one place.

**\*\*Step 1 — Create a backend pointing to Fabric Core MCP:\*\***

In APIM → Backends → Add:

- Name: `fabric-core-mcp-backend`

- Runtime URL: `https://api.fabric.microsoft.com/v1/mcp/core`

**\*\*Step 2 — Create an API with suffix `/mcp/fabric` and a wildcard POST operation.\*\***

**\*\*Step 3 — Apply this policy:\*\***

Enter fullscreen mode Exit fullscreen mode


xml

<! — Validate the developer’s Entra ID token →

<validate-jwt header-name=”Authorization”

failed-validation-httpcode=”401"

failed-validation-error-message=”Valid Entra ID token required”>

https://api.fabric.microsoft.com

https://sts.windows.net/{tenant-id}/

<! — Capture caller identity for audit →

<set-variable name=”caller-upn”

value=”@(context.Request.Headers.GetValueOrDefault(“Authorization”, “unknown”))” />

<! — Exchange for managed identity token to call Fabric →

<authentication-managed-identity

resource=”https://api.fabric.microsoft.com"

output-token-variable-name=”fabric-mi-token” />

<! — Replace developer token with MI token →

@(“Bearer “ + (string)context.Variables[“fabric-mi-token”])

<! — Rate limit: 100 calls per minute per developer →

<rate-limit-by-key calls=”100"

renewal-period=”60"

counter-key=”@(context.Subscription.Id)”

increment-condition=”@(true)” />

<! — Route to Fabric Core MCP backend →

<! — Retry on transient failures and cold start →

<retry condition=”@(context.Response.StatusCode == 503 ||

context.Response.StatusCode == 429 ||

context.Response.StatusCode == 500)”

count=”3" interval=”2" delta=”2" max-interval=”10">

<! — Audit trace to Application Insights →

@(

“caller=” + (string)context.Variables[“caller-upn”] +

“ status=” + context.Response.StatusCode.ToString() +

“ duration_ms=” + context.Elapsed.TotalMilliseconds.ToString() +

“ api=fabric-core-mcp”

)

application/json

@(“{\”error\”: \”” + context.LastError.Message + “\”, \”status\”: “ + context.Response.StatusCode.ToString() + “}”)


Replace `{tenant-id}` with your Entra ID tenant ID. That’s it — the policy handles everything else.

**— -**

**## Configuring the Developer’s Machine**

**\*\*VS Code (recommended — handles token refresh automatically):\*\***

In `.vscode/mcp.json` or the user-level `mcp.json`:

Enter fullscreen mode Exit fullscreen mode


json

{

“servers”: {

“enterprise-fabric”: {

“type”: “http”,

“url”: “https://your-apim-instance.azure-api.net/mcp/fabric",

“headers”: {

“Ocp-Apim-Subscription-Key”: “{developer-subscription-key}”

}

}

}

}


VS Code with GitHub Copilot handles the Entra ID token automatically. The developer just needs their APIM subscription key — which the platform team distributes via Key Vault, not email.

**\*\*Claude Desktop:\*\***

Enter fullscreen mode Exit fullscreen mode


json

{

“mcpServers”: {

“enterprise-fabric”: {

“type”: “http”,

“url”: “https://your-apim-instance.azure-api.net/mcp/fabric",

“headers”: {

“Ocp-Apim-Subscription-Key”: “{developer-subscription-key}”,

“Authorization”: “Bearer {entra-token}”

}

}

}

}


Get the Entra token via `az account get-access-token — resource [https://api.fabric.microsoft.com](https://api.fabric.microsoft.com) — query accessToken -o tsv`. Note: tokens expire after 1 hour — VS Code handles this automatically, Claude Desktop requires manual refresh.

**— -**

**## What This Costs If You Already Have APIM**

Zero.

If your organization already runs an APIM instance — which most enterprise Azure environments do — this is one new backend, one new API route, and a policy. No new resource provisioning, no new monthly bill, no new approval process for infrastructure. You’re adding a capability to infrastructure you already own and operate.

If you need a new APIM instance, the Standard tier runs approximately $750/month and gives you a governed, audited, rate-limited gateway to your entire MCP estate for all developers — the cost of roughly one developer hour per day.

**— -**

**## The Registry Pattern: One Gateway for All MCP Servers**

The Fabric MCP connection is one spoke. The same APIM instance, the same policy pattern, the same auth and audit infrastructure extends to every MCP server your organization wants to expose:

Enter fullscreen mode Exit fullscreen mode


plaintext

Enterprise APIM Gateway

→ /mcp/fabric → Fabric Core MCP Server

→ /mcp/powerbi → Power BI Remote MCP

→ /mcp/snowflake → Snowflake Cortex MCP

→ /mcp/databricks → Databricks Genie MCP




Each addition is one new backend and one new API operation. The governance layer — auth, audit, rate limiting, retry — is inherited automatically. New MCP servers don’t require new governance conversations. They require a backend entry and a subscription key.

That is the enterprise MCP registry. It’s not a new product or a new platform. It’s a new use of infrastructure most organizations already have, applied to a problem that’s only going to get more urgent as MCP adoption accelerates.

**— -**

**## The Honest Production Checklist**

Before calling this production-ready for a regulated environment:

- [] APIM managed identity has minimum required permissions on Fabric — Viewer only, not Contributor

- [] Subscription keys distributed via Key Vault — never email or Slack

- [] Application Insights connected and retention policy set to meet audit requirements

- [] Conditional access policy enforces MFA before Entra token issuance

- [] Rate limits tuned per team, not just per individual developer

- [] Private endpoint for APIM if PHI boundary requires no public ingress

- [] Subscription approval required — no self-service access

**— -**

**## Why This Matters Now**

MCP adoption is accelerating faster than enterprise governance is keeping up. Most organizations are currently in one of two states: blocking MCP entirely (the security team wins, developers lose), or allowing ungoverned direct connections (developers win, security loses).

The gateway pattern is the third option that neither side has articulated yet. The security team gets everything they actually need — identity enforcement, audit trail, access control, revocation. The developers get the capability they want — natural language access to enterprise data through the tools they already use.

The organizations that build this registry now, before MCP sprawl sets in, will have a meaningfully better operational posture when the number of MCP connections scales from two to twenty.

**— -**

_\*Kartik Anand — Cloud & AI Architect | Building agentic AI systems on Azure, Snowflake, and Microsoft Fabric\*_

_\*[LinkedIn](_https://linkedin.com/in/kartanand_) · [GitHub](_https://github.com/kartikanand73_) · [HealthIQ Multi-Agent Reference Architecture](_https://github.com/kartikanand73/fabriciq-multi-agent-reference-architecture_)\*_
Enter fullscreen mode Exit fullscreen mode

Top comments (0)