Honeytoken Deployment in MCP Server Environments
Fake credentials hidden in MCP configs catch attackers the moment they try to use them.

I've spent enough time in MCP server logs at this point to say this plainly: the attack surface is not theoretical. Astrix Research looked at over 5,200 open-source MCP server implementations and found that 88% require credentials to operate. Fine, that's expected. But 53% of them lean on long-lived static secrets, API keys, personal access tokens, the kind of thing that sits in a config file for months. Modern auth methods like OAuth show up in only about 8.5% of implementations. That gap is the whole story.
And here's the detail that actually keeps me up at night: 79% of those API keys get passed through environment variables. Any process, any agent, any script with filesystem access on that same host can enumerate them. No exploit required. Just env and a few minutes of patience.
Once you have a stolen key, it looks exactly like a real one. That's the credential exposure problem in a sentence. There's no visual tell, no expiration warning, nothing. If a defender has no canary sitting in that pile of secrets, they have no way of knowing a key walked out the door until someone uses it for something big enough to notice.
The vulnerability research backs this up with real numbers, not hypotheticals. CurXecute, tracked as CVE-2025-54135 with a CVSS score of 8.6, showed a full attack chain inside Cursor: a Slack message rewrote the MCP config and auto-executed a brand-new server, no user click required. Then there's the "rug pull" pattern, where a hosted MCP server's tool definitions change weeks after a user approved them. A tool that read as safe on day one becomes a credential exfiltration pipe by day thirty, and the user never re-approved anything because nothing in the UI told them to.
BlueRock Security scanned over 7,000 MCP servers and found 36.7% potentially exposed to server-side request forgery. Their proof of concept against Microsoft's MarkItDown MCP server pulled live AWS IAM keys straight from the EC2 metadata endpoint. And mcp-remote, a package with more than 437,000 downloads, carried CVE-2025-6514, an OS command injection bug scoring 9.6 on CVSS, the first confirmed case of full remote code execution triggered just by connecting to an untrusted remote MCP server.
Tool poisoning, rug pulls, tool shadowing, cross-server attacks, prompt injection chains that turn an agent hostile. Different names, same forensic hole underneath: by the time anyone reads the log, the action already happened. These attacks come in through the tool layer, not the network perimeter firewalls were built to watch. So the signal has to live at that same layer, or it doesn't exist at all.
What honeytokens are and why they generate high-confidence signals
A honeytoken is a fake credential, document, API key, or database record with exactly one job: sit there and do nothing, until someone touches it who shouldn't.
That's it. No real permissions attached, no legitimate workflow that ever calls it. Which is precisely why the signal is so clean. A triggered honeytoken has close to a zero percent false-positive rate, because there's no automated job, no scheduled task, no authorized user on earth with a reason to touch it. Any interaction is unauthorized by definition. You don't need to interpret the alert. You just need to respond to it.
Compare that to behavioral anomaly detection, the machine-learning approach a lot of security vendors sell. Those systems need training data. They need tuning, retuning, and a team willing to sit through weeks of false positives while the baseline settles. A honeytoken doesn't ask for any of that. It fires once, and it's right.
A few forms show up again and again in MCP environments:
Fake AWS IAM credentials trip CloudTrail the second anyone tries to use them, and AWS Canarytoken makes the instrumentation almost trivial. Honeytoken API keys seeded into config files or env var stores turn into confirmed unauthorized probes the moment they're called. Canary database records, a synthetic row that should never surface in a query result, catch an agent reading data it was never supposed to see. Decoy MCP server entries, which I'll get into next, catch lateral movement on a compromised workstation before it goes anywhere.
Some of the more advanced platforms have taken this further: instead of just alerting when a token gets used, they redirect the attacker into a fully operational fake environment and let them keep working inside it while the defenders watch. For MCP specifically, that turns a single probe into an entire intelligence-gathering session. You learn what they're after, not just that they showed up.
One thing I'll flag now because it matters more than people expect: placement is the whole craft. A honeytoken sitting somewhere a legitimate automated process happens to touch will flood your team with noise, and noisy alerts train people to ignore them. That's worse than having no honeytoken at all.
How a decoy MCP server entry functions as a workstation tripwire
Picture the scenario this is built for: an attacker gets code execution on a developer's laptop, and the first thing they do is read the agent's MCP config to figure out what's reachable and where to pivot next.
Those config files are the pivot point, and they're not hidden. Claude Code keeps ~/.claude.json at user scope and .mcp.json at the project root. Any agent framework that stores server registrations in a plain, readable file has the same exposure.
So you plant a fake entry. A decoy MCP server pointed at something you control, a Cloudflare Worker works fine, that looks like an internal service but does one thing: log the connection and fire an alert.
Naming matters here more than almost anything else. Call it secretsvaultread or productiondbquery, and an attacker reads it as a real internal system worth exploring. Call it query, and they'll skip right past it, because it smells like bait. Credible naming is what makes someone actually commit to the interaction.
When they do, have it return isError: true with a message like "Access denied. Incident logged." The attacker reads that as a real security control doing its job. What they don't know is that you've already captured the tool name they called and the arguments they sent, which tells you exactly what they were fishing for.
Chain it further: embed AWS Canarytoken credentials inside the fake server's responses, so if the attacker extracts those and tries to use them somewhere else, a second, independent alert fires. Two tripwires, one config entry.
The intelligence value here is real. The first tools/call event alone tells you which tool they picked and what arguments they passed. That's the difference between "someone probed us" and "someone was looking specifically for database credentials." One of those tells you where to look next.
Now, the practical catch: your own agent reads that same config file, and it'll connect to the honeypot on every session unless you stop it. In Claude Code, add the honeypot's server name to disabledMcpjsonServers in settings.json. Skip this step and you'll spend your first week chasing your own agent's traffic instead of an attacker's.
Seeding honeytokens inside real MCP servers — credentials, records, and tool responses
Decoy servers catch lateral movement. Seeding honeytokens inside real, production MCP servers catches something different: someone who's already inside a legitimate tool and looking for data to take.
Credential seeding. Plant fake API keys or IAM credentials in the same environment variable stores and secret managers that your real MCP servers reach into. Bind those fake credentials to audit-only cloud policies, no actual permissions, but any attempt to use them trips CloudTrail or your provider's equivalent. This targets that 79% figure directly: an attacker enumerating environment variables on a compromised host is going to pick up the canary right alongside the real keys, and they won't be able to tell the difference.
Honeytoken database records. Drop a fake row into any database exposed through MCP tools. A synthetic user, a fictional customer, a decoy key stored as a field value. Doesn't matter what shape it takes, only that it should never appear in a legitimate query result. If it shows up somewhere, in a log, in an agent's response, in an outbound request, someone touched data they had no business touching. This one's especially good against tool poisoning and rug-pull attacks, where a compromised tool definition starts quietly exfiltrating whatever it can query.
Canary tool responses. Instrument a production server to return a specific honeytoken value in response to a synthetic query, something no real workflow would ever construct. If that value later turns up downstream, in a log file, in a request to some external endpoint, you've confirmed the exfiltration path and gotten a partial trace on it for free.
The design judgment across all three is the same, and it's harder than it sounds: the token needs to sit close enough to real data that it attracts genuine attacker behavior, but far enough from actual workflows that no authorized process ever brushes against it. Get that balance wrong in either direction and the token is either useless or a nuisance.
Here's why the data-layer approach matters so much for rug pulls specifically. Tool definitions can get silently modified after a user already approved them, which means the tool itself might be compromised without anyone knowing. A honeytoken planted in the data layer doesn't care. Even if the tool has been poisoned, the canary fires the moment the exfiltration actually runs, because the alert lives with the data, not with the tool's code.
HoneyMCP and purpose-built tooling for MCP deception infrastructure
Most of what I've described so far you can build yourself with a Cloudflare Worker and some patience. But purpose-built tooling has started catching up to the threat model, and it's worth knowing what exists.
HoneyMCP, open source on GitHub since June 2026, is a honeypot server built specifically for this threat landscape. It runs eleven separate threat detectors on every single request, prompt injection, shell injection, secret exfiltration attempts, IMDS-SSRF probing, path traversal, tool enumeration, scanner fingerprinting, and a handful of others, tagging events the moment they're written. Every detection carries its MITRE ATT&CK or ATLAS technique ID right in the event record, so whoever's watching the SIEM can pivot straight to the technique without doing the mapping work themselves.
It ships with four built-in personas: postgres-admin, github-admin, vercel-admin, and stripe-finance. Those cover the surfaces attackers actually go after, source code, deployment pipelines, environment configs, financial data. Personas matter because they're what makes a honeypot believable to someone doing real reconnaissance instead of just poking around.
Deployment is light. We're talking a single Rust binary, roughly 15 MB, SQLite for storage, running comfortably inside 256 MiB of RAM. You can drop it alongside existing MCP infrastructure without provisioning new hardware for it.
GreyNoise has taken a different angle, deploying MCP honeypots at scale across their network to observe what attackers actually do once they land on an MCP endpoint. That kind of field data is genuinely useful for calibrating your own setup, which tool names draw the most attention, which personas get probed hardest.
For teams already living inside a cloud-native audit pipeline, the instrumented credential pattern, fake keys bound to audit-only policies plus native logging, requires nothing beyond key generation and a policy binding. AWS Canarytoken remains free and about as well-suited to this as anything out there, and it plugs directly into the chained-canary pattern I described with the decoy server.
So the choice comes down to what you're already running. HoneyMCP if you want MCP-specific detection with MITRE mapping out of the box. Instrumented credentials if your cloud audit pipeline is already mature. Decoy server entries if you need something on developer workstations tomorrow, with zero new infrastructure.
Operational discipline that separates a working honeytoken program from a noise generator
None of this works if you skip the boring part.
Before you deploy a single token, map every CI/CD pipeline, every scheduled job, every agent workflow that touches the environment you're instrumenting. A honeytoken sitting in a path that any legitimate process reads isn't a tripwire, it's a false-positive factory, and it'll get muted within a month.
Naming and believability cut both ways. Too fake, and no one bites, attacker or otherwise. Too real, and you risk pulling in curious authorized users along with actual attackers. What you want is "plausible but orphaned": a credential or record that looks completely legitimate but belongs to absolutely no active workflow.
Alert routing deserves its own line item. Honeytoken alerts should skip the normal triage queue entirely and go straight to incident response. A triggered canary isn't a "maybe look into this later" ticket, it's a confirmed unauthorized access event, full stop. Teams that let these alerts sit in a general backlog are throwing away the one advantage a tripwire actually gives them: time.
Real-time matters more than people give it credit for. A batch export read the next morning is a postmortem, not a detection. If your logging pipeline can't stream or notify near-instantly, you've built a very expensive record-keeping system, not an alarm.
Maintenance can't be an afterthought either. Rotate honeytoken credentials on a schedule so they don't go stale or get mistaken for decommissioned real keys. Review placement every time your MCP server inventory changes, because a new server that unknowingly reads from an instrumented env var store can accidentally legitimize a canary and kill its signal. And document every single token you place in a private registry. An undocumented honeytoken eventually gets treated as a real credential by someone who has no idea what it's actually for, or worse, gets decommissioned entirely.
None of this replaces access control. Honeytokens detect access, they don't prevent it. They have to run alongside authentication enforcement and policy guardrails, because the canary only tells you the fence got crossed. The fence still has to exist in the first place.
Where honeytokens fit inside a broader MCP governance and access control architecture
A triggered alert asks one question: who or what accessed this? Answering that requires a server registry, agent identity records, and access logs that were already in place before the alert fired. Without them, the honeytoken confirms a breach happened but can't tell you how far it went.
That's why the registry comes first, not the tokens. Every MCP server that isn't in a registry is a surface you can't instrument, because honeytoken placement assumes you already know what you're placing tokens around. Build the registry, and it does double duty: it tells you where canaries belong, and it surfaces the ungoverned servers sitting outside the registry entirely, which are almost always your highest-priority gaps to close.
I've said this a few times now because it's the point that gets missed most often: a canary is a signal, not a control. It's one layer in a stack that also needs real authentication, real access policy, and real visibility into what's actually running. Get the governance foundation in place first. The tripwires work a lot better once you know exactly what they're guarding.


