Strake
all systems normal sign in create your endpoint
all systems normal
Blog / Security

Your MCP Config Has Tokens in It. Have You Looked Lately?

Everyone's gotten the memo on API keys.

Don't commit them. Don't paste them in Slack. Don't hardcode them. Rotate them. Use environment variables. Use a vault. The community has drilled this for a decade, and most developers have at least internalized the shape of the risk, even if they haven't fully acted on it.

So here's a question: when was the last time you audited your mcp.json?

What's actually sitting on your disk

If you're using Claude Desktop, Cursor, Windsurf, or any MCP-aware tool, you probably have a config file that looks something like this:

{
  "mcpServers": {
    "github": {
      "url": "https://mcp.github.com/sse",
      "headers": {
        "Authorization": "Bearer ghp_aB7cD9eF1gH3jK5mN7pQ9rS1tU3vW5xY7z"
      }
    },
    "linear": {
      "url": "https://mcp.linear.app/sse",
      "headers": {
        "Authorization": "Bearer lin_api_9xK2mP4qR6tY8wZ1aB3cD5eF7gH0jL2n"
      }
    },
    "slack": {
      "url": "https://mcp.slack.com/sse",
      "headers": {
        "Authorization": "Bearer xoxb-1234567890-0987654321-aBcDeFgHiJkLmNoPqRsT"
      }
    }
  }
}

That file is sitting on disk, in plaintext, right now.

On your machine. Probably in ~/.config/claude/. Maybe also backed up to iCloud, or Time Machine, or synced to a cloud storage folder you set up years ago and forgot about. Maybe in a dotfiles repo you made public on GitHub to share your setup with someone.

These aren't API keys in the abstract. They're live tokens for your GitHub account, your Linear workspace, your Slack. Tokens with real permissions attached.

This is actually worse than the .env problem

When developers talk about the risk of .env files, the concern is usually accidental git commits, CI system exposure, or a platform breach. One key in one place that might get compromised.

MCP configs carry all of that risk, plus some that are easy to miss.

Your GitHub Personal Access Token in that config probably isn't scoped to "let a chatbot read one repo." It's whatever permissions you set when you created it. Often repo, read:org, sometimes more, because the setup docs just said to create a token and paste it. A GitHub PAT with write access is a pretty interesting thing for an attacker to stumble across.

There's also no real feedback loop when an MCP token gets used against you. If a .env key leaks and someone runs with it, you might catch it from an unusual billing spike, a provider alert, or a usage anomaly. An attacker quietly reading every issue in your Linear workspace through a leaked token might generate no signal you'd ever notice. By the time you find out, you've already missed it.

The other thing that catches people off guard is how freely MCP configs get shared. Developers post their configs constantly: blog posts, Discord threads, dotfiles repos. The instinct to share "here's my setup" is completely natural, and configs look like configuration. The env block at the bottom doesn't read like credentials, so it doesn't get treated like credentials. But it is.

And the ecosystem is moving too fast for security norms to keep up. There are hundreds of MCP servers now. New ones every week. Most setup instructions say the same thing: create a token, paste it into env. Because that's the path of least resistance. There isn't a cleaner default yet.

It's not a hypothetical

Search GitHub for mcp.json with a token pattern in the env block. I'm not going to screenshot what comes up, but the results are not empty.

These aren't mistakes made by people who don't know better. They're made by developers who absolutely do. The pattern is just so ingrained (follow the setup guide, paste the token, move on) that the config file doesn't register as a threat surface the same way a .env would.

The .env ecosystem had ten years to build up the muscle memory of "this file is dangerous." MCP configs are a year old.

What to actually do about it

Switching from hardcoded tokens to environment variables helps a little, but it doesn't close the actual problem: your real upstream token is still touching every tool you hand it to. One rogue tool call in a chain is all it takes.

What actually works is keeping the real token out of the config entirely. With Strake, two things change: the URL becomes a Strake subdomain that proxies to the real MCP server, and the bearer becomes a disposable Strake token. The real credential never touches the file.

{
  "mcpServers": {
    "github": {
      "url": "https://my-github.strake.sh/sse",
      "headers": {
        "Authorization": "Bearer ct_live_7a3f8b91d4c0e2..."
      }
    }
  }
}

If that config leaks — GitHub, iCloud, Discord, a screenshot, whatever — you go to your Strake dashboard and revoke the token. The real GitHub PAT doesn't move. No emergency rotation, no frantic search for everywhere it was used. You update one line in one config.

The specific tool doesn't matter much. Strake, a secrets manager you run yourself, an internal gateway. The pattern is what counts. The credential in the config should be something throwaway. The real key should live somewhere you control, with revocation that takes seconds.

Before you close this tab

Open ~/.config/claude/claude_desktop_config.json, or wherever your tool stores its config. Take five minutes and actually look at what's in the env blocks. Count the tokens. Check what permissions they carry. Most PATs and API keys were created with broader access than they need, because the docs didn't say to scope them down.

Then check if that file is anywhere it shouldn't be. Dotfiles repo. A backup system. Anywhere it might have been shared or synced. GitHub's secret scanning catches some patterns, but not all, and only after the push already happened.

Most developers who do this find at least one token broader than it needs to be, sitting in a place they'd forgotten about. That's not a dig. It's just how the tooling got built, and the habits haven't caught up yet.

The good news is this one is fixable in an afternoon.

Try Strake

One endpoint. Every tool. Zero exposed keys.

Paste your API key once. Get a revocable endpoint URL. Hand that to anything — MCP servers, Claude Code, Cursor, CI runners, teammates — and revoke in seconds if something leaks.