Skip to main content
Glama
KauaLealz

secrets-mcp-server

by KauaLealz

secrets-mcp-server

An MCP server for storing secrets (API keys, tokens, credentials) encrypted at rest on your own machine, built so an AI agent can manage them without the plaintext value ever entering its context. There is no get_secret tool that returns a value as text — that was a deliberate design decision, not an oversight. Using a secret is always indirect: run a command with the value injected into its environment, or write the value straight into a destination file.

Why

Giving an agent free-form shell access to your .env files means every secret it touches can end up echoed back into its own transcript, its logs, or a chat history — anywhere from a debugging session to a support ticket. This server keeps secrets in one encrypted store and only exposes them through two narrow, auditable operations: inject-into-subprocess and write-to-file. The agent can use a secret to authenticate a request or populate a config file; it can never see, print, or leak the raw value through a normal tool call.

Related MCP server: enigmagent-mcp

Tools

Category

Tool

Description

CRUD

create_secret(name, value, description=None)

Creates a secret; fails if name already exists

CRUD

create_secrets_batch(items)

Creates several at once (items: [{name, value, description?}]). Does not abort on the first error — each item reports its own status (created/skipped_exists/error)

CRUD

import_secrets_from_file(source_path, name_pattern=None, prefix=None, overwrite=False)

Reads a .env-style file (KEY=VALUE per line, export KEY=VALUE and # comments supported) and imports each key as a secret. name_pattern (regex) filters which keys get imported; prefix is prepended to the name; overwrite controls whether existing secrets get updated

CRUD

update_secret(name, value)

Overwrites the value; fails if the secret doesn't exist

CRUD

delete_secret(name)

Removes a secret

CRUD

list_secrets()

Lists name/description/timestamps for every secret. Never includes the value

Opaque use

run_with_secret(secret_name, command, env_var_name=None, cwd=None, timeout=None)

Runs command (a list of args, no shell) with the value injected as an environment variable (env_var_name, or the secret name upper-cased by default) only inside that subprocess. Returns exit_code/stdout/stderr, with the value redacted if the command happens to print it

Opaque use

apply_secrets_to_file(names, dest_path, key_names=None, format="env")

Writes one or more secrets straight into dest_path (env-style .env, or json), never returning any value as text. names is always an explicit list — there is no "export everything" option

run_with_secret never uses a shell (shell=False, command is a list of args) — this avoids command injection even if an argument comes from untrusted text.

apply_secrets_to_file only writes inside directories listed in SECRETS_MCP_ALLOWED_WRITE_DIRS — without that configured, every write is rejected.

import_secrets_from_file can read any file the process has OS permission to read — this is a deliberate choice, with no read-side allowlist (unlike writes). If you need to restrict that, add a SECRETS_MCP_ALLOWED_READ_DIRS check following the same pattern as validate_dest_path in security.py.

Environment variables

Variable

Default

Purpose

SECRETS_MCP_MASTER_PASSPHRASE

(required)

Passphrase used to derive the store's encryption key. Without it, the server refuses every operation

SECRETS_MCP_STORE_PATH

~/.secrets-mcp/store.enc

Where the encrypted store file lives

SECRETS_MCP_ALLOWED_WRITE_DIRS

(empty)

Comma-separated list of directories apply_secrets_to_file may write into. Empty means no writes are allowed

SECRETS_MCP_COMMAND_TIMEOUT_SECONDS

30

Timeout for run_with_secret (1-300)

Security model

  • The store is a single file (salt + ciphertext) encrypted as a whole with Fernet (cryptography); the key is derived from the passphrase via Scrypt with a fresh random salt on every write. A wrong passphrase or a corrupted file fails loudly — there is no silent fallback.

  • The store file and any file written by apply_secrets_to_file end up with 0600 permissions.

  • run_with_secret never uses shell=True; command is always a list of args, never a shell string.

  • apply_secrets_to_file resolves the destination path (realpath, following symlinks) and rejects anything outside SECRETS_MCP_ALLOWED_WRITE_DIRS.

  • No tool logs or returns a raw value. run_with_secret does a best-effort redaction (security.redact) that strips literal occurrences of the value from stdout/stderr in case the command echoes it by accident — this is not a guarantee against every leak (e.g. a command that writes the value to a file outside this tool's control), but it covers the common case.

Requirements

  • Python 3.11+

  • uv to install dependencies and run the server

Installation

From PyPI, no clone needed:

uvx secrets-mcp-server

or install it as a persistent CLI tool:

uv tool install secrets-mcp-server
# or: pipx install secrets-mcp-server

From source, for local development:

git clone https://github.com/KauaLealz/secrets-mcp-server.git
cd secrets-mcp-server
uv sync

Registering with Claude Code

Using the published package (no clone required):

claude mcp add --scope user secrets \
  --env SECRETS_MCP_MASTER_PASSPHRASE=<your-passphrase> \
  --env SECRETS_MCP_ALLOWED_WRITE_DIRS=/path/to/your/projects \
  -- uvx secrets-mcp-server

Using a local clone instead:

claude mcp add --scope user secrets \
  --env SECRETS_MCP_MASTER_PASSPHRASE=<your-passphrase> \
  --env SECRETS_MCP_ALLOWED_WRITE_DIRS=/path/to/your/projects \
  -- uv run --directory /path/to/secrets-mcp-server secrets-mcp-server

Replace /path/to/your/projects with whichever directories apply_secrets_to_file should be allowed to write into (comma-separated for more than one), and /path/to/secrets-mcp-server with wherever you cloned the repo, if using the local-clone form.

--scope user makes it available in every Claude Code session. Changing the passphrase between registrations produces a different store (the encryption key depends on it) — keep the same passphrase to keep accessing an existing store, and store it somewhere safe (a password manager). There is no recovery if you lose it.

A .env.example is included as a reference for every variable below — it is not auto-loaded, it just documents the shape a .env for this project would take if you build tooling around it.

Registering with other MCP clients

Any MCP client that supports stdio servers can run this the same way: launch uvx secrets-mcp-server (or uv run --directory /path/to/secrets-mcp-server secrets-mcp-server for a local clone) with the environment variables above set in its process environment. Check your client's documentation for how it declares stdio MCP servers (e.g. a mcpServers entry in its config file).

Tests

uv run pytest

Contributing

Issues and pull requests are welcome. See AGENTS.md for the design constraint this project is built around (no tool ever returns a raw secret value) — please keep new tools consistent with it, or open an issue to discuss before changing it.

License

MIT — see LICENSE.

Available Tools

8 tools
apply_secrets_to_fileA

Writes one or more secrets into dest_path without ever returning the value. key_names is an optional {name: key_in_file} map — without an entry, it defaults to the secret name upper-cased (e.g. 'db-pass' -> 'DB_PASS').

ParametersJSON Schema
NameRequiredDescriptionDefault
namesYes
formatNoenv
dest_pathYes
key_namesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description carries the behavioral disclosure burden. It does reveal the critical property that values are never returned and explains the default key-mapping behavior. However, it omits other important behavioral details such as whether dest_path is overwritten, what happens when a referenced secret doesn't exist, and how the format parameter affects the write.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two tight sentences with the main action and security-critical behavior front-loaded. The key_names explanation with example is concise and high-value, with no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is strong on key_names and the non-return guarantee, and an output schema exists, so return values are covered. However, the missing format semantics and lack of file-overwrite behavior leave gaps that could cause incorrect calls, especially for non-env formats. Overall it's adequate for the most common path but not fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description explains dest_path, names implicitly as 'one or more secrets', and key_names in detail with an example. It does not mention the format parameter at all, which is a genuine gap given that schema description coverage is 0% and format has a default of 'env'. Thus it compensates for most parameters but leaves one key parameter obscure.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific action: writes one or more secrets into dest_path, and highlights a key behavioral trait (never returns the value). The operation is clearly distinct from sibling tools like create_secret/update_cret/list_crets because it targets a file path rather than managing the secret store.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides no guidance on when to use this tool versus alternatives like import_secrets_from_file or run_with_secret. The description only states what the tool does, leaving the agent to infer the appropriate context. It doesn't mention exclusions, prerequisites, or when another sibling would be better.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_secretD
ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
valueYes
descriptionNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

D1/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Tool has no description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness1/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Tool has no description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has no description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Tool has no description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose1/5

Does the description clearly state what the tool does and how it differs from similar tools?

Tool has no description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Tool has no description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_secrets_batchD

items: list of {"name": str, "value": str, "description": optional str}

ParametersJSON Schema
NameRequiredDescriptionDefault
itemsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

D1.9/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must disclose the operation's effects, but it mentions no behavior at all. It does not state that secrets are created, whether existing secrets are overwritten, what authorization is required, or what the response contains.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely terse, but this is under-specification rather than efficient conciseness. It omits the purpose and behavioral context that a tool description needs, so the single line does not earn its place as an adequate description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a batch creation tool with no annotations, the description is far from complete. It gives only the item payload shape and leaves the agent to infer the operation, scope, side effects, and appropriate usage from the tool name and siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema only says items is an array of objects with additionalProperties true, so the description adds meaningful structure by specifying name, value, and optional description fields. It helps an agent construct valid input, though it stops short of explaining the meaning of each field.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose1/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description is only a data-format note ('items: list of...') and never states that the tool creates secrets or performs a batch operation. The tool name implies purpose, but the description itself provides no verb, resource, or functional statement.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance about when to use this tool versus the siblings like create_secret or import_secrets_from_file. No conditions, exclusions, or alternative routing are provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_secretD
ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

D1/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Tool has no description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness1/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Tool has no description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has no description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Tool has no description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose1/5

Does the description clearly state what the tool does and how it differs from similar tools?

Tool has no description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Tool has no description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

import_secrets_from_fileA

Reads a .env-style file (KEY=VALUE per line) and imports each key as a secret. name_pattern (regex) filters which keys get imported; prefix is prepended to the created secret name; overwrite controls whether existing secrets get updated.

ParametersJSON Schema
NameRequiredDescriptionDefault
prefixNo
overwriteNo
source_pathYes
name_patternNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must disclose side effects itself. It does explain that overwrite controls whether existing secrets get updated, and describes prefixing and regex filtering. However, it does not state what happens when overwrite=false and a secret already exists, whether non-matching keys are silently skipped, or how malformed lines are handled. No annotation contradiction exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly written sentences: the first states the core operation and file format, the second systematically covers all three optional parameters. Every sentence earns its place with no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the input file format and the semantics of each parameter, and an output schema exists for return values. It lacks edge-case behavior such as existing-secret handling when overwrite is false, handling of malformed lines, or file access assumptions, but for typical calls it gives enough to use the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description compensates by explaining name_pattern as a regex filter, prefix as prepended to the secret name, and overwrite as controlling existing secret updates. source_path is only implied by 'Reads a .env-style file', not explicitly tied to the parameter, so a slight gap remains.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear, specific action: reads a .env-style file and imports each key as a secret. It also names the filtering, prefixing, and overwrite behaviors, which clearly differentiates it from siblings like create_secret, create_secrets_batch, and apply_secrets_to_file.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is for importing secrets from a .env-style file, but it gives no explicit guidance on when to choose it over alternatives like create_secrets_batch, nor any conditions or exclusions. The context is clear but the agent is left to infer the decision boundary.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_secretsD
ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

D1/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Tool has no description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness1/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Tool has no description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has no description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Tool has no description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose1/5

Does the description clearly state what the tool does and how it differs from similar tools?

Tool has no description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Tool has no description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_with_secretD
ParametersJSON Schema
NameRequiredDescriptionDefault
cwdNo
commandYes
timeoutNo
secret_nameYes
env_var_nameNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

D1/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Tool has no description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness1/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Tool has no description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has no description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Tool has no description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose1/5

Does the description clearly state what the tool does and how it differs from similar tools?

Tool has no description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Tool has no description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_secretD
ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
valueYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

D1/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Tool has no description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness1/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Tool has no description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has no description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Tool has no description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose1/5

Does the description clearly state what the tool does and how it differs from similar tools?

Tool has no description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Tool has no description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 8 tool updatesv0.1.0
    • First observedapply_secrets_to_file
    • First observedcreate_secret
    • First observedcreate_secrets_batch
    • First observeddelete_secret
    • First observedimport_secrets_from_file
    • First observedlist_secrets
    • First observedrun_with_secret
    • First observedupdate_secret

TDQS

C2.5/5.0

Scored across 8 tools

Disambiguation5/5

Each tool targets a clearly distinct operation: individual CRUD, batch creation, file import, and two separate consumption modes (file substitution vs command execution). There is no meaningful overlap or ambiguity between tool responsibilities.

Naming Consistency4/5

Core operations follow a consistent verb_noun pattern such as create_secret, update_secret, delete_secret, and list_secrets. The batch, import, and application tools use slightly different phrasal forms, but they remain readable and predictable.

Tool Count5/5

Eight tools is well-scoped for a secrets management server. It covers single operations, batch creation, file-based import, and secure usage without unnecessary redundancy or bloat.

Completeness5/5

The toolset provides full lifecycle coverage for secrets: create, update, delete, and list, with batch and import variants for efficiency. The absence of a plain get_secret action appears intentional for security and does not create a workflow dead end.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to write .env files with secrets stored locally, allowing search by name/description while keeping actual secret values private and never exposed to the AI.
    5
    -
  • A
    license
    A
    quality
    D
    maintenance
    Local AES-256-GCM encrypted vault for AI agents. Resolve {{PLACEHOLDER}} secrets in prompts at runtime — LLMs never see real API keys. Argon2id key derivation, zero cloud.
    2
    58 npm
    2
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables secure credential storage for AI agents by encrypting secrets and providing agent-invisible references, ensuring sensitive data never leaks to the model.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Encrypts and stores API keys and environment variables locally, providing them to AI agents via MCP with tools for listing, describing, getting secrets, and running commands with secret values redacted.
    2
    MIT