---
title: @envlock/mcp
description: A Model Context Protocol server that lets coding agents validate env contracts, render examples, and explain issues.
url: https://pr-1-7abef52380a8.thally.app/envlock-mcp
---

# @envlock/mcp

A Model Context Protocol server that lets coding agents validate env contracts, render examples, and explain issues.

`@envlock/mcp` is a stdio MCP server that exposes Envlock to coding agents such
as Claude Code, Claude Desktop, and Cursor. It registers five tools and one
resource template.

## Setup

Add the server to your project's `.mcp.json` (Claude Code, Cursor) or
`claude_desktop_config.json` (Claude Desktop):

```json
{
  "mcpServers": {
    "envlock": {
      "command": "npx",
      "args": ["-y", "@envlock/mcp"]
    }
  }
}
```

If `@envlock/mcp` is already a devDependency of the project,
`"command": "npx", "args": ["envlock-mcp"]` also works and skips the download.

Paths in tool arguments are resolved against the server's working directory.
Paths that resolve outside it are rejected with an error to prevent path
traversal.

## Tools

Every JSON-returning tool provides both a text block and `structuredContent`.
Loader failures come back as `isError: true` results with the reason.

### `envlock_check`

Validates env against a contract.

| Input field | Type | Description |
| --- | --- | --- |
| `schemaPath` | `string` | Path to the config file. |
| `envFilePath` | `string` (optional) | Dotenv file to validate. Without it, the server validates its own `process.env`. |
| `strict` | `boolean` (optional) | Report undeclared keys. Applies to files only. |

Returns `{ ok, issues, source }`.

### `envlock_inspect`

Describes the contract.

| Input field | Type | Description |
| --- | --- | --- |
| `schemaPath` | `string` | Path to the config file. |

Returns `{ schemaPath, variables: SchemaDescription[] }`.

### `envlock_render_example`

Renders `.env.example` text from the contract.

| Input field | Type | Description |
| --- | --- | --- |
| `schemaPath` | `string` | Path to the config file. |

Returns the `.env.example` text as a text content block.

### `envlock_diff`

Diffs a dotenv file against the contract.

| Input field | Type | Description |
| --- | --- | --- |
| `schemaPath` | `string` | Path to the config file. |
| `envFilePath` | `string` | Dotenv file to diff. |

Returns `{ ok, missing, unknown, invalid, source }`.

### `envlock_explain_issue`

Explains an issue code with remediation steps. This is a pure function — it
does not access any files.

| Input field | Type | Description |
| --- | --- | --- |
| `code` | `"missing" \| "invalid" \| "unknown"` | The issue code. |
| `key` | `string` | The variable name. |
| `message` | `string` (optional) | The original issue message for extra context. |

Returns `{ code, key, summary, steps }`.

## Resource template

The server registers `envlock://schema/{schemaPath}` (URL-encode the path),
which returns the `describeSchema()` JSON for the given schema file.

## Programmatic use

```ts
import { createEnvlockServer } from "@envlock/mcp";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const server = createEnvlockServer({ cwd: "/path/to/project" });
await server.connect(new StdioServerTransport());
```

### Exported API

| Export | Description |
| --- | --- |
| `createEnvlockServer(options?)` | Creates an un-connected MCP server with all tools registered. |
| `explainIssue(input)` | Pure function returning `IssueExplanation`. |
| `loadSchemaFile(schemaPath, cwd?)` | Resolves, imports, and validates a schema file within cwd. |
| `loadEnvFile(envFilePath, cwd?)` | Reads and parses a dotenv file within cwd. |
| `resolveInsideCwd(cwd, filePath)` | Resolves a path and throws if it escapes the working directory. |
| `SERVER_INFO` | `{ name: "envlock", version: "0.1.0" }` |
| `TOOL_NAMES` | `{ check: "envlock_check", inspect: "envlock_inspect", renderExample: "envlock_render_example", diff: "envlock_diff", explainIssue: "envlock_explain_issue" }` |
| `SCHEMA_RESOURCE_TEMPLATE` | `"envlock://schema/{schemaPath}"` |

`EnvlockServerOptions` accepts an optional `cwd` string (defaults to
`process.cwd()`).