Locking down MCP servers with managed-mcp.json (MDM)
Claude Code lets any user connect any MCP server they choose by default. For an MSP managing a customer’s fleet, that is shadow IT waiting to happen — one user adds an untrusted MCP server and there is no record of it, no review, and no way to know it happened. managed-mcp.json closes that off entirely: deploy it to a managed device and Claude Code on that device can only use the MCP servers the file lists. Users cannot add, modify, or connect to anything else — not through claude mcp add, not through a plugin, not through claude.ai connectors.
Conduit generates this file for you, pre-filled with your organization’s Conduit MCP endpoint, from the Managed Policy page in the org portal (Org Settings → Managed Policy, /org/mdm). This guide covers what the file does, why it’s the recommended v1 mechanism, and how to deploy it to a Windows fleet via Intune.
Why managed-mcp.json, not an allowlist
Section titled “Why managed-mcp.json, not an allowlist”Claude Code actually supports two different mechanisms for restricting MCP servers:
allowedMcpServers(inmanaged-settings.json) — a policy-based allowlist. It only filters servers a user, a plugin, or another config file has already configured; it doesn’t deploy anything itself, and depending on how it’s set, a user’s own settings can still broaden it.managed-mcp.json— exclusive control. Claude Code loads only the servers this file defines. There’s no allowlist to have gaps in, because there’s nothing left for a user to add.
For an MSP governing a customer’s fleet, exclusive control is the stronger and simpler guarantee: instead of maintaining an allowlist and hoping it’s never misconfigured or bypassed, the fleet simply cannot reach any MCP server other than Conduit. That’s why managed-mcp.json is the recommended mechanism for v1 — Conduit doesn’t yet generate an allowedMcpServers policy, and for the org-wide lockdown use case, it doesn’t need to.
Get your org’s managed-mcp.json
Section titled “Get your org’s managed-mcp.json”-
Sign in to Conduit and go to Org Settings → Managed Policy (
/org/mdm). Admin role required. -
The page shows the exact
managed-mcp.jsoncontents for your organization, pre-filled with your Conduit MCP endpoint:{"mcpServers": {"conduit": {"type": "http","url": "https://conduit.wyre.ai/v1/mcp"}}} -
Use Copy to copy the JSON, or Download to save it as
managed-mcp.json— you’ll need the contents (or the file) for the deployment step below.
This is the same /v1/mcp endpoint used for connecting an individual AI client — managed-mcp.json deploys that same endpoint fleet-wide instead of relying on each user to connect it themselves.
Windows/Intune deployment
Section titled “Windows/Intune deployment”Claude Code on Windows reads its managed MCP policy from a fixed system path:
C:\Program Files\ClaudeCode\managed-mcp.jsonWriting to that path requires administrator privileges, so it’s deployed through device-management tooling — an Intune Platform Script for Windows.
The script
Section titled “The script”Save this as Deploy-ConduitManagedMcp.ps1, with the JSON block replaced by the exact contents from your org’s Managed Policy page:
<#Deploys Conduit's managed-mcp.json to lock this device's Claude Codeinstallation to Conduit as its only MCP server.
Intune: Devices > Scripts and remediations > Platform scripts > Add (Windows 10 and later). Run this script using the logged on credentials: No Run script in 64 bit PowerShell Host: Yes
Claude Code reads C:\Program Files\ClaudeCode\managed-mcp.json at startup and,once present, refuses to load or add any MCP server that isn't listed in it.Replace the JSON below with the exact contents from your org's Managed Policypage (Org Settings > Managed Policy) in Conduit if you're deploying to adifferent Conduit deployment (e.g. staging or a white-labeled domain).#>
$ErrorActionPreference = 'Stop'
$dir = Join-Path $env:ProgramFiles 'ClaudeCode'New-Item -ItemType Directory -Path $dir -Force | Out-Null
$json = @'{ "mcpServers": { "conduit": { "type": "http", "url": "https://conduit.wyre.ai/v1/mcp" } }}'@
$path = Join-Path $dir 'managed-mcp.json'[System.IO.File]::WriteAllText($path, $json, (New-Object System.Text.UTF8Encoding($false)))Write-Output "Wrote $path"Deploying via Intune
Section titled “Deploying via Intune”- In the Microsoft Intune admin center, go to Devices → Scripts and remediations → Platform scripts → Add → Windows 10 and later.
- Upload
Deploy-ConduitManagedMcp.ps1. - Script settings:
- Run this script using the logged on credentials: No — the script needs administrator rights to write under
C:\Program Files, which the logged-on user typically doesn’t have. - Enforce script signature check: your organization’s usual policy.
- Run script in 64-bit PowerShell Host: Yes.
- Run this script using the logged on credentials: No — the script needs administrator rights to write under
- Assign the script to the device group(s) you want locked down — typically the same group scoped to your managed Claude Code rollout.
- Save. Intune runs the script on its normal check-in cadence; you can also force a sync from a test device to verify sooner.
Claude Code picks up managed-mcp.json the next time it starts — no reinstall needed. A session already running when the file lands picks it up on its next restart.
Verifying the lockdown
Section titled “Verifying the lockdown”managed-mcp.json being present isn’t itself proof it’s working — verify the exclusive-control behavior directly on a managed device, after the Intune script has run:
-
Confirm only Conduit is loaded: run
claude mcp list. It should show only theconduitserver. If a user’s own previously-configured servers still appear, the file isn’t being read yet — check the path and that Intune actually applied the script to that device. -
Confirm adding another server is blocked: run
claude mcp add --transport http test https://example.com/mcp(the URL doesn’t need to resolve to anything real — Claude Code rejects the command before it ever contacts it). Withmanaged-mcp.jsonactive, this fails with:Cannot add MCP server: enterprise MCP configuration is active and has exclusive control over MCP serversSeeing this error is the confirmation that exclusive control is enforced on that device — a plain “server added” result means the policy file isn’t in effect there.
This is a manual, per-device check rather than something Conduit can assert from the server side — Conduit generates the policy file, but whether an individual managed device is actually enforcing it depends on Claude Code reading it from that device’s local filesystem, which only a real Claude Code process on that device can confirm. Run it against a representative device (or a few, across your device groups) after each rollout or policy change, the same way you’d spot-check any other Intune Platform Script deployment.
Why this matters
Section titled “Why this matters”For an MSP operating a customer’s fleet under Conduit, this is the difference between restricting shadow-IT MCP servers and eliminating them:
- No allowlist gaps. An allowlist is only as good as its maintenance — a server added to the list and never removed, or a misconfiguration that lets a user’s own settings widen it, both leave a gap. Exclusive control has no list to maintain and nothing left for a user to add.
- One governed path for every tool call. Every MCP tool call from a locked-down device goes through Conduit, which means every one of them is subject to Conduit’s own access grants, audit log, and vendor connections — the same governance surface you already use for the rest of the fleet.
- A concrete compliance artifact. “We deploy
managed-mcp.jsonfleet-wide via Intune” is a specific, auditable control you can point to in a security review or a client’s compliance questionnaire — not a policy statement, an enforced technical control with a device-level verification step.
Related
Section titled “Related”- Connecting an AI client — the individual self-serve connection flow this policy replaces fleet-wide.
- Managing access — governing what each user can do once connected through Conduit.
- Getting support — how to reach us if a device isn’t picking up the policy.

