← All posts

Does Your MCP Secret Server Hand the Plaintext to the Model?

Many 'secrets for AI agents' MCP servers return the raw secret value straight into the model's context. Here's how to tell which ones do, why it matters, and the architecture that makes it structurally impossible.

If you connect a secrets manager to an AI coding agent over the Model Context Protocol (MCP), there is one question that decides whether the setup is safe: does any tool return the plaintext secret value into the model’s context?

If the answer is yes, then the secret is no longer just in your vault. It is in the model’s context window — which means it can land in chat history, in transcripts, in logs and traces, and in any place that context is later persisted. A vault that encrypts at rest but then reads the value back to the model has moved the exposure, not removed it.

Here is how the major MCP secret servers actually behave, and where the line falls.

Does Infisical’s MCP server expose secret values to the AI?

Yes, by default. Infisical’s official MCP server (@infisical/mcp) ships a get-secret tool that returns the secret’s value in its response, and a list-secrets tool that returns the value of every secret in an environment in a single call. Those responses go straight into the agent’s context.

Infisical’s own SDK exposes a viewSecretValue option that can mask the value, but the MCP server does not set it — so returning plaintext is the default behavior, not an opt-in. You can confirm this in the public source of the MCP server: the get-secret and list-secrets handlers serialize the secret object, value included, into the tool’s text response.

To be fair to Infisical: this is a design choice, not a bug, and their server-side logging hygiene is sound — secret values ride in encrypted request bodies, and the backend logs metadata, not values. The exposure is specifically at the MCP boundary: the value is delivered to the model.

Why is returning a value over MCP the whole risk?

Because once a value enters the model’s context, you have lost control of it. The context can be summarized, logged by the client, included in a support bundle, or retained by whatever sits downstream. A prompt-injected agent that can call a value-returning tool can exfiltrate an entire environment’s credentials with one tool call — no exploit required, just a tool doing exactly what it was built to do.

This is why the safest designs never expose a value-returning tool at all.

Which MCP secret servers return values to the model?

Most of them can. The dividing line is not open vs. closed source, or cloud vs. local — it is whether the protocol has a tool that can hand a value to the model in the first place. Based on each project’s public documentation and source:

MCP server Returns secret values to the model?
Infisical @infisical/mcp Yesget-secret and list-secrets return plaintext by default
HashiCorp Vault MCP Yes — the read_secret KV tool returns the secret value; Vault’s own security-model docs warn secrets may be exposed to LLMs, despite a marketing line that “secrets are never shared”
Doppler MCP Yes, by default — can read secret values; read-only mode is opt-in and only removes write tools, not value reads
NoxKey Effectively yes — decrypts to a file in /tmp whose path is handed to the model, plus a “peek” that returns the first 8 characters (it does ship a separate output-scanning guard to catch leaked values)
1Password Environments MCP No — returns secret names only; values are injected into an authorized process at run time
OpaqueVault No — there is no value-returning tool in the protocol

Two servers that market a metadata-only or “never shared” framing — Vault and Doppler — nonetheless ship a tool that returns values (Vault’s read_secret; Doppler’s default read mode). Read the tool list, not the tagline.

Sources: Infisical MCP server source · Vault MCP security model and tool reference · Doppler MCP docs · NoxKey source · 1Password Environments MCP.

How does OpaqueVault make it structural instead of optional?

OpaqueVault has no get-secret tool, and it never will. That is a fixed invariant of the design, not a configuration flag you can leave in the wrong position.

Instead, the agent calls vault_run, which injects the requested secrets as environment variables into the subprocess it launches and returns only the exit code and injection metadata — subprocess stdout and stderr are structurally omitted from the response and go to your terminal or the agent log instead. The model orchestrates the command; it does not receive the plaintext, and output can’t smuggle a value back into its context. A separate context interceptor is a second layer that catches secret-shaped strings before any tool response reaches the model.

An honest boundary is worth stating plainly: a subprocess you deliberately hand a secret to can still use that secret however it likes — that is what running a command means, and the interceptor is a hygiene check, not an airtight boundary. OpaqueVault’s guarantee is narrower and more useful than “the AI can never touch a secret”: secret values never enter the model’s context, chat history, logs, or .env files on normal or accidental paths, which is where credential leaks actually happen. The value lives only where a command genuinely needs it, for as long as the command runs.

The takeaway

When you wire a secrets manager to an AI agent, read the tool list before you trust it — not the marketing page. If there is a tool whose job is to return a secret value, then your model will, sooner or later, be holding your credentials in its context. The safer architecture is the one where that tool does not exist.


OpaqueVault is a zero-knowledge secret manager built for AI coding agents: the server stores only ciphertext, transport uses an ML-KEM-768 + X25519 hybrid, and no MCP tool ever returns a secret value to the model. See how it works.

Zero-knowledge secrets for AI agents

Keep credentials out of Claude's context window.

OpaqueVault encrypts secrets client-side and injects them into subprocesses — your AI agent never sees the plaintext value.

Get started free →← More posts