Skip to content
Status

Security and Policy / Shadow MCP

Shadow MCP

The inventory of MCP servers discovered in agent traffic, with policy status, review states, and evidence-backed access decisions.

The MCPs tab of the Shadow AI page inventories every MCP server the project knows about: servers observed in agent traffic that aren’t managed by the platform, and servers raised in an access request. Each server carries an access review with gathered evidence, everyone who asked for it, and a recorded approve or deny decision enforced across the project’s blocking policies.

Open it from Security and Policy > Shadow AI in the dashboard and select the MCPs tab.

Viewing the tab and deciding access require the org:admin scope.

This page covers:

Every MCP-routed tool call in an instrumented agent session records which server it resolved to. The shadow MCP scanner replays that provenance for each call and classifies it:

  • Calls that resolve to a platform-hosted MCP host are clean, including hosts on a custom domain registered to the organization.
  • Calls that resolve to anything else are flagged as shadow MCP. That covers third-party remote server URLs and local stdio servers launched by a command on the member’s machine.

Codex’s built-in MCP resource tools (list_mcp_resources, list_mcp_resource_templates, and read_mcp_resource) name their target server in the call input rather than in the tool name. The scanner resolves that name against the MCP server inventory the session reports, so these calls face the same policy, and a target that cannot be resolved to a platform-hosted server is treated as shadow.

Classified calls carry a Shadow MCP source badge in Tool Logs, the per-call view behind the inventory, under Observability > Tool Logs. To see exactly which calls the inventory was built from, narrow the Type facet in the filter rail to Shadow MCP Servers.

Tool Logs filtered to Shadow MCP servers, with a Shadow MCP badge, tool name, user, and agent on each row

When provenance can’t be resolved, because the hook event hasn’t landed yet or the sender never resolved a server, the scanner falls back to checking the server identifier the platform injects into hosted tool schemas. A call missing that identifier is treated as shadow.

Discovery depends on agent sessions reaching the platform. Sessions from an uninstrumented client produce no traffic to scan. See Device Agent for how sessions are instrumented.

Servers are identified by canonical URL. Two members hitting the same server at different paths or with different query strings collapse to one inventory row.

The indicator above the inventory reports what the active policy set does with a server that has no approval:

The policy status indicator highlighted, reporting that a block policy is enabled and unapproved servers are not allowed

  • Blocking: a blocking shadow MCP policy is enabled, and servers without allow rules are not allowed
  • Flagging: only a flagging policy is enabled, so servers without approvals are recorded but calls still succeed
  • No Policy: no shadow MCP policy is enabled, and every discovered server is allowed

Flagging is the safe starting posture. It builds the inventory without interrupting anyone, so the approved set is curated from real usage rather than guessed at. See Shadow MCP allow and block lists for the rollout sequence.

The status is driven by the project’s shadow MCP policies, created on the Guardrails page. Decisions recorded here take effect through those blocking policies: without one nothing is enforced, and the indicator says so. Decisions still count, though. A blocking policy created later honors those already on record.

  1. Find the server: search by name or URL, sort any column, or open More filters to filter by review state. Search and sorting cover the full inventory, not only the loaded page.

    The inventory with the server search field and the More filters control highlighted

  2. Read the row: the server’s name and URL, its status with the reason, its review state, when it was last called and last seen, and its usage as calls and users.

    The Shadow MCP inventory listing discovered servers with status, review state, last called, last seen, and usage columns

  3. Select a server to open its access review. A server referenced by URL opens a detail page; a local command server (a stdio target, such as an npx invocation) opens its review in a sheet from the inventory row.

Each row carries one of six statuses, shown with the reason beneath it:

StatusMeaning
AllowedAn approval or allow rule covers this server
BlockedA blocking policy or a denial applies to everyone in the project
RestrictedBlocked for some users only, by a policy scoped to a targeted audience
ObservedSeen in traffic, with no blocking policy applying to it
PendingAt least one member has an unresolved access request for this server
UnknownThe policy status could not be loaded

Pending takes precedence over the other statuses, so a server with an open request surfaces for review even when it is already allowed.