What is a rogue MCP server and how do you detect one?

A rogue MCP server is one that your agents can call but that your organization hasn't reviewed or can't trust. It can be unreviewed, typosquatted, compromised, or attacker-hosted. Restrict calls to an allowlist written into policy, score the hosts that calls would contact with threat intelligence, and record every call. Arcjet applies all three before the tool runs, with one policy across Claude Code, GitHub Copilot, Cursor, and OpenAI Codex and the same check in custom agents. Coding agents don't let a hook withhold a tool's response, so Arcjet decides every call that follows against the same policies.

10 min read
In short: A rogue MCP server is one that your agents can call but that your organization hasn't reviewed or can't trust. It can be unreviewed, typosquatted, compromised, or attacker-hosted. Restrict calls to an allowlist written into policy, score the hosts that calls would contact with threat intelligence, and record every call. Arcjet applies all three before the tool runs, with one policy across Claude Code, GitHub Copilot, Cursor, and OpenAI Codex and the same check in custom agents. Coding agents don't let a hook withhold a tool's response, so Arcjet decides every call that follows against the same policies.

What is a rogue MCP server?

A rogue MCP server is a Model Context Protocol server that an AI agent can call but that your organization hasn't reviewed or can't trust. It might be malicious from the start, or it might be a legitimate server that someone replaced, compromised, or configured without approval. Either way, the agent treats its tools as trusted capabilities and its responses as useful context.

MCP is an open protocol that lets an agent call tools that a separate server provides. Adding a server is a configuration change. A developer can connect a coding agent to a server in a few lines of settings, and a custom agent can load servers from a config file. As a result, the set of servers that your agents talk to can grow without anyone approving the additions.

Three controls address the risk: restrict calls to a list of approved servers, score the hosts that each call would contact, and record every call. Arcjet applies all three before the tool runs. On coding agents such as Claude Code, GitHub Copilot, Cursor, and OpenAI Codex, one policy decides each MCP call from the hooks that the agents already fire. In custom agents, Arcjet runs the same check inside your code before it connects to a server.

How does a rogue MCP server get into an agent?

Most rogue servers arrive through one of the following routes:

  • Unreviewed. A developer installs a server from a public listing because it solves a problem, and nobody checks who publishes it or what it does.
  • Typosquatted. The server's package or listing name is one character away from a popular one, so a developer installs the wrong one.
  • Compromised. An attacker takes over the package, the repository, or the host behind a server you already reviewed, and changes what it does. For the package side of this, see package hijacking.
  • Attacker-hosted. A remote server is run by the attacker from day one, often promoted as a free integration.

Security teams often ask how to limit the damage when a developer installs an MCP server that a bad actor published. The answer is layered: narrow which servers can be called, check where calls are going, and record what happened. Arcjet does all three in one place, as the following sections show.

What can a rogue MCP server do?

A server controls three things an agent relies on: the tools it advertises, what those tools do when called, and what they return. That gives it several ways to cause harm:

  • Receive data. Whatever the agent passes as tool arguments reaches the server, including file contents, secrets it read earlier, or customer records.
  • Return instructions. A tool response is text in the model's context. A response that tells the agent to fetch a URL, run a command, or send a file is an indirect prompt injection. For more information, see indirect prompt injection in agentic workflows.
  • Point the agent elsewhere. A response can name a download URL or an upload endpoint that the agent then contacts with its next tool call.

These combine into the pattern Simon Willison named the lethal trifecta: private data, untrusted content, and a way to send data out, all in one agent.

How do you restrict agents to approved MCP servers?

Write an allowlist of approved servers into a policy that runs before every tool call, and deny any MCP call to a server that isn't on the list. On a coding agent, Arcjet maps every MCP tool name, such as mcp__github__create_issue in Claude Code, to a tool_kind value of mcp. It also fills mcp_server with the server name. The following policy is the coding-agent.mcp-allowlist starter in the Arcjet Console:

package arcjet.guard
import rego.v1
deny contains "unlisted-mcp-server" if {
input.values.tool_kind == "mcp"
not input.values.mcp_server in {"arcjet", "github", "sentry"}
}

Replace the set with the servers your organization has reviewed. A built-in tool isn't an MCP call, so mcp_server is empty and the rule doesn't fire for it.

Keep the list in the policy, not in anything that the agent supplies. If the agent could send the list, it could also add servers to it.

In custom agents, the same pattern works with inputs that your application fills. Because the policy is Rego, you can go finer than a server list. The following policy from the Arcjet policy examples also restricts one server to read-only tools:

deny contains "unapproved-server" if {
not input.values.mcp_server in input.values.approved_servers
}
deny contains "unapproved-tool" if {
input.values.mcp_server == "internal-ops"
not startswith(input.values.tool_name, "read_")
}

Here approved_servers must come from your application's configuration, never from the model.

How does threat scoring apply to MCP calls?

An allowlist tells you whether a server is approved. Arcjet destination threat analysis tells you whether the hosts that a call touches are known to be malicious, using Arcjet threat intelligence.

On a coding agent, Arcjet fills an input named destinations with the hosts of a tool call's URL arguments and the hosts of absolute URLs inside a shell command. A policy that declares an Arcjet threat intelligence detector over destinations denies the call when any host scores high or critical risk. That catches a common follow-up to a malicious tool response, where the agent's next call fetches the URL that the response named or passes it to curl. For the full policy, see how to stop an AI agent contacting malicious URLs and domains.

In custom agents, you decide what goes in the list. Before your code connects to a remote MCP server, map that server's host into a SERVER string list input and declare the threat intelligence detector over it. Arcjet then scores the server's own host, as well as any URLs that its tools are about to use. Arcjet skips private and loopback addresses, so a server on your internal network produces risk none.

How do you see which MCP servers your agents use?

Record every call, including the ones that you allow. Arcjet records each coding agent hook event in the Activity view of the Arcjet Console, whether or not a policy decides it. For MCP, that includes the tool call before it runs, the post-tool-use event with what the tool returned, and MCP elicitation requests, where a server asks the user for input. The Activity view shows which servers developers call, including servers that nobody approved.

Arcjet exports decisions to Datadog, Splunk, SentinelOne, Panther, and Amazon S3 (Enterprise plan), so an unapproved server call reaches your detection and alerting. OpenTelemetry and the Claude Compliance API add visibility into sessions that the hooks don't reach.

Which controls pair with Arcjet for MCP security?

Arcjet decides each tool call before it runs. Pair it with the following controls for the parts of MCP security that sit outside a tool call:

  • Managed settings that fix each server name. The allowlist identifies a server by the name that the agent reports, which is the name that it was configured under. Control which server each name points to through the agent's managed settings. Managed settings are configuration that an administrator deploys with a mobile device management (MDM) tool or the vendor's admin console, and a developer can't override them. For more information about locking MCP configuration on each vendor, see how to restrict MCP servers for coding agents.
  • Controls on the calls that follow a response. A hook is a request that the coding agent sends to an external service, such as Arcjet, before it runs a tool. Coding agents don't give hooks a point to withhold a tool result, so a poisoned MCP response reaches the model after the call is allowed. Arcjet records that response, and every call that follows still goes through policy, so the fetch, shell command, or write that the injected text asks for is denied when it breaks a rule.
  • A short, reviewed list of installed servers. A server that runs on the developer's machine can read files and open network connections on its own, outside any tool call that the agent reports. Review which servers are installed, and keep that list short.
  • A reliable hook path. Claude Code and Copilot HTTP hooks fail open on a timeout or network error, which means the tool call goes ahead. Arcjet evaluates at the edge in over 300 data centers, so the added latency stays small. For more information, see coding agent hooks fail open.

For a comparison of dedicated MCP security products, see MCP server security platforms.

Where does Arcjet fit in MCP security?

With Arcjet, every MCP call runs against your approved server list and a threat check before the tool runs, and you can see which servers your agents use. The following capabilities apply:

  • One policy across coding agents. On Claude Code, Copilot, Cursor, and Codex, one policy runs from each agent's hooks, with no SDK and no code change. You install the hooks through managed settings or MDM, so developers can't remove them without administrator access.
  • The same engine in custom agents. The same Rego runs inside your tool through guard(), with the approved servers taken from your own configuration.
  • Destination threat analysis. Arcjet threat intelligence scores the hosts that a call is about to contact.
  • A full record. Every session and decision is in the Arcjet Console, with export to your security tools.

To start, publish the coding-agent.mcp-allowlist starter in dry run. A dry-run rule records what it would deny without blocking anything, and every new rule in Arcjet starts that way. Read the Activity view to see which servers developers call, add the ones that you approve, and then set the rule live. Changes take effect in real time. For more information about the rollout, see secure MCP server agent tool calls.

Learn more: Coding agent policies · Destination threat detection · Secure coding agents

Frequently asked questions

What is a rogue MCP server?

A rogue MCP server is a Model Context Protocol server that an AI agent can call but that your organization hasn't reviewed or can't trust. It can be unreviewed, typosquatted, compromised after review, or run by an attacker from the start.

How do I stop a coding agent from using an unapproved MCP server?

Write the approved server names into a policy that runs before every tool call, and deny any MCP call to a server outside the list. Keep the list in the policy, not in anything that the agent supplies. Lock which server each name points to through the agent's managed settings, which a developer can't override. Arcjet ships this policy as the coding-agent.mcp-allowlist starter, and one policy covers Claude Code, GitHub Copilot, Cursor, and OpenAI Codex.

Can you block a malicious response from an MCP server?

Not with a coding agent hook. No supported coding agent offers a point where a hook can withhold a tool result, so the defense is on the calls that follow. Arcjet records the response and denies the fetch or shell command that the injected text asks for when it breaks a policy.

Can threat intelligence detect a malicious remote MCP server?

In custom agents, you map the remote MCP server's host into a policy input and score it with Arcjet threat intelligence before connecting. On a coding agent, Arcjet identifies the MCP server by name, and scores the hosts of URL arguments and absolute URLs in shell commands.

AI runtime security in your code

Protect your AI agent workflows with Arcjet

Publish an MCP server allowlist in dry run and see which servers your developers' agents actually call.