About envspeak
envspeak is an MCP server and CLI for developers and AI agents to determine how application variables resolve across configuration sources and environments. It also traces origins, previews change impacts, and flags potential risks.
Key features
- 01Resolves variables to their effective values
- 02Traces variable sources across files and environments
- 03Previews downstream effects of configuration changes
- 04Creates project variable inventories and risk flags
- 05Compares variables across environments or services
Use cases
- 01Investigate why a production variable has its current value
- 02Check which services a configuration change may affect
- 03Find variables with no source or potential secret exposure
- 04Compare development and production configuration
MCP support
The MCP server provides tools for variable resolution, source tracing, impact previews, configuration manifests, and environment comparisons. MCP calls can be scoped to explicitly selected files.
Configuration
Local server config is the same for every client. Copy it into your client’s MCP config file.
Tools
5Saved tool list · updated 2w ago
| Parameter | Type | Required | Description |
|---|---|---|---|
| files | array | Yes | Paths (relative to projectRoot) to .env*, compose, and k8s manifest files to consider |
| service | string | No | docker-compose service name to resolve for |
| variable | string | Yes | The variable name, e.g. DATABASE_URL |
| workload | string | No | Kubernetes workload (Deployment/Pod/etc.) name to resolve for |
| container | string | No | Kubernetes container name within the workload |
| environment | string | No | Target NODE_ENV-style value for dotenv resolution, e.g. "production" |
| projectRoot | string | No | Directory the file paths are relative to |
Details
From the project READMEEnvSpeak
MCP server and CLI that resolves config/env-var cascade across .env files, Docker Compose, and Kubernetes — tells AI agents (and you) what a variable actually evaluates to at runtime, and why.
Same problem shape as CSS cascade — several sources, non-obvious precedence rules, and a value that "wins" only because of where it's defined — applied to application configuration instead of stylesheets. A sibling project to stylesafe and stylespeak, which do the same thing for CSS.
The problem
A real app's config comes from .env, .env.local, .env.production, docker-compose.yml (environment: vs env_file:), Kubernetes ConfigMap/Secret objects, and hard-coded fallbacks in code — five-plus layers, each with its own precedence rules that don't compose the way you'd guess. The best-known gotcha: a plain .env.local overrides .env.production unless you also have a .env.production.local — because "local" outranks "environment-specific" in the conventional dotenv cascade. An agent editing config has no way to know what a variable actually resolves to, or what breaks if it changes one layer.
Tools
resolve_variable— what doesDATABASE_URLactually evaluate to, and which file wins?trace_variable— every place this variable is set, across every domain and environment.impact_preview— if I change this value in this file, what actually changes downstream — and what's shielded by something higher-precedence?config_manifest— a compressed, whole-project summary: every variable, its sources, and risk hotspots (secrets sitting in a tracked file, variables read in code with no fallback and no source anywhere).diff_environments— resolve every variable under two environments/services/workloads and see what's actually different between them.
Install
npm install -g @patrizzos/envspeak
As an MCP server
{
"mcpServers": {
"envspeak": {
"command": "envspeak"
}
}
}
As a CLI
envspeak resolve DATABASE_URL --environment production
envspeak trace LOG_LEVEL
envspeak impact --file .env --variable LOG_LEVEL --newValue debug
envspeak manifest
envspeak diff --a '{"nodeEnv":"development"}' --b '{"nodeEnv":"production"}'
If --files is omitted, envspeak auto-discovers .env*, Compose, and Kubernetes manifest files under --projectRoot (default: current directory). Pass --files a,b,c to scope it explicitly — recommended for MCP calls, so the agent controls exactly what's read.
Precedence conventions encoded
dotenv (Next.js/Vite-style, the de facto standard): process.env (shell) > .env.[env].local > .env.local > .env.[env] > .env > code fallback (process.env.X || 'default'). Note .env.local outranks .env.[env] — the gotcha above.
Docker Compose: docker compose run -e (CLI) > environment: > env_file: (last file in the list wins on conflicts) > Dockerfile ENV (not analyzed).
Kubernetes: inline env: always overrides envFrom: (bulk ConfigMap/Secret import; last entry in the list wins among those). Env values are frozen at pod start — editing a referenced ConfigMap/Secret does not reach a running pod without a restart or rollout. impact_preview flags this.
Every result includes a confidence level and a caveat string, because a shell-exported or CLI-passed override is always possible and never visible to static analysis — envspeak says so explicitly rather than pretending certainty it doesn't have.
Security
- Zero runtime dependencies. The YAML subset parser used for Compose/Kubernetes files is hand-written rather than pulled in from npm, so there's no third-party supply-chain surface.
npm auditis clean by construction. - Path-traversal guarded. File reads are resolved against
projectRootand refuse to escape it, even if a tool call is given a crafted relative path. - Prototype-pollution guarded. Object keys parsed from YAML content (
__proto__,constructor,prototype) are never used for property assignment. - Secrets are redacted by default. Kubernetes
Secretvalues are shown only asab***yz, never in full, regardless of which tool surfaces them. - Secret-likelihood heuristics. Variable names and value shapes (AWS keys, GitHub tokens, PEM blocks, high-entropy credential-shaped strings) are flagged, cross-referenced against
.gitignore, and surfaced as asecretFlag/ risk hotspot rather than silently passed through. - Bounded, non-backtracking regexes. Pattern matching used for code-default scanning caps match length and avoids nested quantifiers to avoid ReDoS on large files.
- Regardless of these guards, envspeak reads whatever files you point it at — scope the
fileslist an agent can pass, the same way you'd scope any tool with filesystem access.
Development
npm test # zero dependencies — no install step needed
License
MIT
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.