# Environment Variable Patterns for Configuring STDIO MCP Servers in MetaMCP

> Configure MetaMCP STDIO MCP servers using environment variables. Explore raw values, runtime references with ${VAR_NAME}, and auto-matching for flexible setup.

- Repository: [metatool-ai/metamcp](https://github.com/metatool-ai/metamcp)
- Tags: how-to-guide
- Published: 2026-03-07

---

**MetaMCP supports three distinct environment variable patterns for STDIO MCP servers: raw values, runtime references using `${VAR_NAME}` syntax, and automatic forwarding via auto-matching.**

The **metatool-ai/metamcp** repository provides flexible configuration options for STDIO-type MCP servers that run as local processes. Understanding these environment variable patterns is essential for securely managing secrets and configuration data without exposing sensitive values in your version control.

## Three Supported Patterns for STDIO MCP Server Environment Variables

MetaMCP implements three distinct approaches for handling environment variables in STDIO MCP server configurations, each documented in the [`README.md`](https://github.com/metatool-ai/metamcp/blob/main/README.md) (lines 102-119).

### 1. Raw Values

The simplest pattern stores values directly in the configuration. This approach works well for non-sensitive data like debug flags or port numbers, though it offers no protection for secrets.

```json
{
  "HackerNews": {
    "type": "STDIO",
    "command": "uvx",
    "args": ["mcp-hn"],
    "env": {
      "DEBUG": "true",
      "PORT": "8080"
    }
  }
}

```

According to the source code in [`packages/zod-types/src/mcp-servers.zod.ts`](https://github.com/metatool-ai/metamcp/blob/main/packages/zod-types/src/mcp-servers.zod.ts), the `env` field uses `z.record(z.string())` validation, ensuring all values are stored as strings in the configuration object.

### 2. Environment Variable References

For production deployments requiring secret management, MetaMCP supports placeholder syntax that resolves variables at runtime within the MetaMCP container.

```json
{
  "HackerNews": {
    "type": "STDIO",
    "command": "uvx",
    "args": ["mcp-hn"],
    "env": {
      "API_KEY": "${OPENAI_API_KEY}",
      "DATABASE_URL": "${DB_CONNECTION_STRING}"
    }
  }
}

```

When the container starts with `OPENAI_API_KEY` and `DB_CONNECTION_STRING` defined in its environment, MetaMCP replaces the placeholders before spawning the STDIO process. This pattern keeps actual secret values out of configuration files and Git history.

### 3. Auto-Matching

The most streamlined approach leverages automatic forwarding when variable names align between the tool's expectations and the container's environment.

```json
{
  "HackerNews": {
    "type": "STDIO",
    "command": "uvx",
    "args": ["mcp-hn"]
  }
}

```

By omitting the `env` object entirely, MetaMCP automatically forwards any environment variable that matches what the target tool expects. If both the tool and container define `API_KEY`, the value propagates without explicit configuration.

## How Environment Variable Resolution Works

The resolution logic resides in [`apps/backend/src/lib/metamcp/utils.ts`](https://github.com/metatool-ai/metamcp/blob/main/apps/backend/src/lib/metamcp/utils.ts), which implements the `resolveEnvVariables` function. This utility expands `${VAR_NAME}` placeholders at runtime for STDIO servers by querying the container's current environment.

After resolution completes, [`apps/backend/src/lib/metamcp/client.ts`](https://github.com/metatool-ai/metamcp/blob/main/apps/backend/src/lib/metamcp/client.ts) handles the actual process spawning, passing the resolved environment variables to the STDIO server subprocess. The Zod schema defined in [`packages/zod-types/src/mcp-servers.zod.ts`](https://github.com/metatool-ai/metamcp/blob/main/packages/zod-types/src/mcp-servers.zod.ts) validates the configuration shape before resolution occurs, ensuring type safety across the environment variable handling pipeline.

## Security Considerations for STDIO MCP Server Configuration

References using `${VAR_NAME}` syntax resolve **inside** the MetaMCP container at runtime, ensuring secret values never enter the Git repository or configuration storage. Raw values, conversely, store data directly in JSON configuration files, exposing them to version control if committed.

Auto-matching provides the cleanest security posture by eliminating configuration entries entirely while still maintaining runtime secret injection. This approach minimizes the attack surface by reducing the number of locations where sensitive data appears in configuration files.

## Summary

- **Raw values** store data directly in configuration files using the `env` object field, suitable for non-sensitive data only.
- **Environment variable references** use `${VAR_NAME}` syntax to inject container environment values at runtime, keeping secrets out of source control.
- **Auto-matching** eliminates the need for explicit `env` configuration when variable names align between the container and target tool.
- The `resolveEnvVariables` function in [`apps/backend/src/lib/metamcp/utils.ts`](https://github.com/metatool-ai/metamcp/blob/main/apps/backend/src/lib/metamcp/utils.ts) handles placeholder expansion before [`apps/backend/src/lib/metamcp/client.ts`](https://github.com/metatool-ai/metamcp/blob/main/apps/backend/src/lib/metamcp/client.ts) spawns the STDIO process.

## Frequently Asked Questions

### How do I reference environment variables in MetaMCP STDIO server configuration?

Use the `${VAR_NAME}` syntax within the `env` object values. For example, `"API_KEY": "${OPENAI_API_KEY}"` tells MetaMCP to substitute the placeholder with the `OPENAI_API_KEY` value from the container's environment at runtime. This pattern is documented in [`README.md`](https://github.com/metatool-ai/metamcp/blob/main/README.md) and processed by the `resolveEnvVariables` function.

### Are raw environment variable values secure in MetaMCP?

No, raw values store configuration data directly in JSON files. Since these files typically reside in repositories, committing them exposes secrets to version control. Use environment variable references or auto-matching for any sensitive configuration data.

### What happens if an environment variable is not defined in the container?

When using the `${VAR_NAME}` reference pattern, MetaMCP attempts to resolve the placeholder against the container's environment. If the variable is undefined, the resolution logic in [`apps/backend/src/lib/metamcp/utils.ts`](https://github.com/metatool-ai/metamcp/blob/main/apps/backend/src/lib/metamcp/utils.ts) typically leaves the placeholder unchanged or resolves it to an empty string, depending on the specific implementation version.

### Where is the environment variable resolution logic implemented?

The core resolution functionality lives in [`apps/backend/src/lib/metamcp/utils.ts`](https://github.com/metatool-ai/metamcp/blob/main/apps/backend/src/lib/metamcp/utils.ts) within the `resolveEnvVariables` function. This utility processes the placeholder expansion before [`apps/backend/src/lib/metamcp/client.ts`](https://github.com/metatool-ai/metamcp/blob/main/apps/backend/src/lib/metamcp/client.ts) passes the final environment map to the spawned STDIO process.