# envspeak [Health: Active]

**Category:** ☁️ Cloud Platforms  
**Repository:** https://github.com/patrizzos/envspeak  
**GitHub Stars:** 0  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/envspeak

## Description
MCP server and CLI that resolves config/env-var cascade across .env, docker-compose, and Kubernetes

## Tools
Capabilities this server exposes over MCP:

- **resolve_variable**
- **DATABASE_URL**
- **trace_variable**
- **impact_preview**
- **config_manifest**
- **diff_environments**

## Claude Desktop Quick Installation
Heuristic fallback — verify the package name and runner against the repository README before running it. Uses `npx` (confidence: low):

```json
"mcpServers": {
  "envspeak": {
    "command": "npx",
    "args": ["-y","envspeak"]
  }
}
```

## Documentation & README

# EnvSpeak

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](https://github.com/Patrizzos/stylesafe) and [stylespeak](https://github.com/Patrizzos/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 does `DATABASE_URL` actually 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

```bash
npm install -g @patrizzos/envspeak
```

### As an MCP server

```json
{
  "mcpServers": {
    "envspeak": {
      "command": "envspeak"
    }
  }
}
```

### As a CLI

```bash
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 audit` is clean by construction.
- **Path-traversal guarded.** File reads are resolved against `projectRoot` and 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 `Secret` values are shown only as `ab***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 a `secretFlag` / 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 `files` list an agent can pass, the same way you'd scope any tool with filesystem access.

## Development

```bash
npm test   # zero dependencies — no install step needed
```

## License

MIT

