Skip to main content

Notes3 min read

Running coding agents without handing them your .env file

Why we built an MCP server into Relic so Cursor and Claude Code can run tests and migrations without reading plaintext secrets.

Written by Can Vardar

If you use Cursor or Claude Code every day, you have probably run into the .env problem.

Your test suite, database migrations, and local dev server need environment variables to run. So you keep a .env file in the root of your repo. The moment you let an AI agent run commands or search your workspace, nothing stops it from reading that file and sending your staging or production keys straight into an LLM prompt.

If you block .env with .cursorignore, the agent stops reading the file, but now it cannot run bun test or prisma migrate when those commands expect credentials in the environment.

We built relic mcp so we wouldn't have to pick between the two.

Keep the workflow, drop the plaintext file

You don't need to change how your app reads process.env or os.environ. If you already have a .env file, you can pull it into Relic in one command (or paste it straight into the relic terminal UI):

Terminal
relic login
relic init
relic import .env -e development

Relic encrypts the values on your machine with AES-256-GCM before uploading anything. Once they are imported, you can delete the local .env file.

For your own terminal sessions, relic run -e development -- bun run dev or relic shell -e development decrypts your variables in memory and injects them into the process through a small Rust runner. Nothing is written back to disk.

How the MCP server works

To give an AI assistant the same capability without exposing the values, register relic mcp:

Terminal
claude mcp add relic -- relic mcp

Or drop it into .cursor/mcp.json:

JSON
{
  "mcpServers": {
    "relic": {
      "command": "relic",
      "args": ["mcp"]
    }
  }
}

Now the assistant has two main tools:

list-secrets returns the key names in an environment (DATABASE_URL, STRIPE_SECRET_KEY, REDIS_URL) and their scopes, but never the decrypted values. The model knows what variables exist without seeing what is inside them.

run-with-secrets runs a command like ["bun", "test"] with the environment injected. Before the command's stdout and stderr are returned to the model, Relic scrubs any occurrence of your secret values and replaces them with [REDACTED:KEY]:

Output
Connecting to [REDACTED:DATABASE_URL]...
PASS src/billing.test.ts

Even if a failing test logs a connection string by mistake, the secret stays on your machine.

Guardrails before git commit

Because agents also write code and run git commands, we added two extra checks that work alongside MCP:

relic check -e production --scan src scans your TypeScript, JavaScript, or Python files for process.env and os.environ reads and tells you if a key is missing in Relic before you deploy. Our VS Code and Cursor extension does the same thing inline while you edit.

relic guard install adds a pre-commit hook that blocks staged .env files and scans git diffs against your actual decrypted secret values locally.

Both the CLI and the MCP server are open source and included in the free plan. You can grab the CLI from GitHub or read the MCP docs.

  • #mcp
  • #cursor
  • #claude-code
  • #security

Keep secrets out of plaintext

Install the CLI, import your .env, and run anything with secrets injected in memory. Free and open source.

Read the docs
curl -fsSL https://withrelic.com/install | bash