Skip to content

Local MCP servers

For local development and testing, MCP servers often use stdio transport for communication with clients. This is perfect for using varlock run to securely load environment variables before starting your server.

Create a .env.schema file for your MCP server:

.env.schema
# @plugin(@varlock/1password-plugin)
# @initOp(allowAppAuth=true)
# @defaultSensitive=true
# @defaultRequired=true
# ---
# Database connection for MCP server
# @type=url
DATABASE_URL=
# API key for external service
# @type=string(startsWith="sk_")
EXTERNAL_API_KEY=
# Authentication secret
# @type=string(minLength=32)
AUTH_SECRET=
# Server configuration
# @sensitive=false
# @type=number(min=1024, max=65535)
SERVER_PORT=3000
# @sensitive=false
# @type=enum(debug, info, warn, error)
LOG_LEVEL=info

Create your local .env.local file with values from your 1Password vault:

.env.local
DATABASE_URL=op(op://devTest/myVault/database-url)
EXTERNAL_API_KEY=op(op://devTest/myVault/external-api-key)
AUTH_SECRET=op(op://devTest/myVault/auth-secret)
LOG_LEVEL=debug

Update your MCP server’s package.json to use varlock run:

package.json
{
"name": "my-mcp-server",
"scripts": {
"start": "varlock run -- node server.js",
"dev": "varlock run -- node --watch server.js"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^0.4.0"
}
}

For containerized local development, create a Dockerfile that uses varlock:

Dockerfile
FROM node:22-alpine
# Install varlock
RUN npm install -g @varlock/cli
WORKDIR /app
# Copy package files
COPY package*.json ./
COPY pnpm-lock.yaml ./
# Install dependencies
RUN npm install -g pnpm && pnpm install
# Copy application files
COPY . .
# Build the application
RUN pnpm build
# Use varlock run to start the server
CMD ["varlock", "run", "--", "node", "dist/server.js"]

Build and run your Docker container:

Terminal window
# Build the image
docker build -t my-mcp-server:latest .
# Run the container (for testing)
docker run --rm -it my-mcp-server:latest

Create a Cursor configuration file to connect to your local MCP server:

~/.cursor/mcp-servers.json
{
"mcpServers": {
"my-local-server": {
"command": "npm",
"args": ["start"],
"cwd": "/path/to/your/mcp-server",
"env": {
"NODE_ENV": "development"
}
}
}
}

For local MCP servers running in Docker: In this case an off-the-shelf MCP server is used, so we need to use varlock run to load the GITHUB_TOKEN environment variable and pass it to the server.

~/.cursor/mcp-servers.json
{
"mcpServers": {
"github": {
"command": "varlock",
"args": [
"run",
"--",
"docker",
"run",
"--rm",
"-i",
"ghcr.io/github/github-mcp-server:latest"
],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
}
}
}

And the corresponding .env.schema file would look something like this:

.env.schema
# @defaultSensitive=true
# @defaultRequired=true
# ---
# GitHub token
# @type=string(startsWith="ghp_")
GITHUB_TOKEN=op(op://devTest/myVault/github-token)