Skip to content

qforge-dev/qmcp

Repository files navigation

QMCP - Docker Wrapper for MCP Servers

This project provides Docker wrappers for running Model Context Protocol (MCP) servers that are typically executed with uvx (Python), npx (Node.js), or plain Docker commands. Instead of installing dependencies locally, you can run MCP servers in isolated Docker containers.

Overview

MCP servers can be written in different languages and use different package managers. This Docker wrapper supports:

  • Python-based servers using uvx (the successor to pipx)
  • Node.js-based servers using npx
  • Plain Docker images for any pre-built MCP servers

These Docker wrappers allow you to:

  • Run MCP servers without installing Python dependencies locally
  • Maintain isolation between different MCP servers
  • Avoid conflicts with local Python environments
  • Easily manage and deploy MCP servers across different environments

Quick Installation

The easiest way to get started is to use the installation script:

curl -fsSL https://raw.githubusercontent.com/qforge-dev/qmcp/main/install.sh | sh

This will:

  • Install qmcp-uvx, qmcp-npx, and qmcp wrapper commands
  • Pull the necessary Docker images
  • Set up everything needed to use QMCP

After installation, you can use qmcp-uvx instead of uvx, qmcp-npx instead of npx, and qmcp for plain Docker images in your MCP configurations.

Building the Docker Images (Optional)

If you prefer to build the images locally instead of using the pre-built ones:

Python MCP Servers (uvx)

To build the Python Docker image, run:

./build-uvx.sh

Or manually:

docker build -f Dockerfile.uvx -t qmcp-uvx .

Node.js MCP Servers (npx)

To build the Node.js Docker image, run:

./build-node.sh

Or manually:

docker build -f Dockerfile.npx -t qmcp-npx .

Usage

Simple Usage with Wrapper Commands

After installation, you can use the wrapper commands directly:

Python MCP Servers (qmcp-uvx)

Instead of running:

uvx elevenlabs-mcp

You can now run:

qmcp-uvx elevenlabs-mcp

Environment variables with the MCP_ prefix are automatically forwarded to the container. For other environment variables, you'll need to prefix them with MCP_ or use the direct Docker approach.

For the plain Docker wrapper qmcp, environment variables with the MCP_ prefix are also automatically forwarded with the prefix removed.

Node.js MCP Servers (qmcp-npx)

Instead of running:

npx @example/mcp-server

You can now run:

qmcp-npx @example/mcp-server

Plain Docker Images (qmcp)

Instead of running:

docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN ghcr.io/github/github-mcp-server

You can now run:

qmcp ghcr.io/github/github-mcp-server

Docker Usage (Direct)

If you prefer to use Docker directly without the wrapper commands:

Python MCP Servers (uvx)

# Basic usage
docker run --rm -i ghcr.io/qforge-dev/qmcp-uvx uvx elevenlabs-mcp

# With environment variables
docker run --rm -i -e ELEVENLABS_API_KEY="your-api-key-here" ghcr.io/qforge-dev/qmcp-uvx uvx elevenlabs-mcp

Node.js MCP Servers (npx)

# Basic usage
docker run --rm -i ghcr.io/qforge-dev/qmcp-npx npx @example/mcp-server

# With environment variables
docker run --rm -i -e API_KEY="your-api-key-here" ghcr.io/qforge-dev/qmcp-npx npx @example/mcp-server

Integration with MCP Client Configuration

In your MCP client configuration (like Claude Desktop), you can configure the server like this:

Before (using uvx directly):

{
  "mcpServers": {
    "ElevenLabs": {
      "command": "uvx",
      "args": ["elevenlabs-mcp"],
      "env": {
        "ELEVENLABS_API_KEY": "<insert-your-api-key-here>"
      }
    }
  }
}

After (using QMCP wrapper):

{
  "mcpServers": {
    "ElevenLabs": {
      "command": "qmcp-uvx",
      "args": ["elevenlabs-mcp"],
      "env": {
        "ELEVENLABS_API_KEY": "<insert-your-api-key-here>"
      }
    }
  }
}

That's it! Just replace uvx with qmcp-uvx and everything else stays the same.

Node.js Example

Before (using npx directly):

{
  "mcpServers": {
    "ExampleNodeServer": {
      "command": "npx",
      "args": ["@example/mcp-server"],
      "env": {
        "API_KEY": "<insert-your-api-key-here>"
      }
    }
  }
}

After (using QMCP wrapper):

{
  "mcpServers": {
    "ExampleNodeServer": {
      "command": "qmcp-npx",
      "args": ["@example/mcp-server"],
      "env": {
        "MCP_API_KEY": "<insert-your-api-key-here>"
      }
    }
  }
}

Just replace npx with qmcp-npx and you're done!

Plain Docker Example

Before (using docker directly):

{
  "mcpServers": {
    "GitHubMCP": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e",
        "GITHUB_PERSONAL_ACCESS_TOKEN",
        "ghcr.io/github/github-mcp-server"
      ],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "<insert-your-github-token-here>"
      }
    }
  }
}

After (using QMCP wrapper):

{
  "mcpServers": {
    "GitHubMCP": {
      "command": "qmcp",
      "args": ["ghcr.io/github/github-mcp-server"],
      "env": {
        "MCP_GITHUB_PERSONAL_ACCESS_TOKEN": "<insert-your-github-token-here>"
      }
    }
  }
}

Much simpler! Just use qmcp with the Docker image name and prefix your environment variables with MCP_.

Environment Variable Handling

The wrapper commands (qmcp-uvx, qmcp-npx, and qmcp) have a secure approach to environment variable forwarding:

MCP_ Prefix Convention

Only environment variables that start with MCP_ are automatically forwarded to the Docker containers. The MCP_ prefix is stripped when forwarding, so MCP_ELEVENLABS_API_KEY becomes ELEVENLABS_API_KEY inside the container. This prevents system environment variables from interfering with the container environment.

Example usage:

# Set your API key with MCP_ prefix
export MCP_ELEVENLABS_API_KEY="your-api-key-here"

# Run the MCP server - the environment variable will be forwarded as ELEVENLABS_API_KEY
qmcp-uvx elevenlabs-mcp

# Or for a plain Docker image
export MCP_GITHUB_PERSONAL_ACCESS_TOKEN="your-token-here"
qmcp ghcr.io/github/github-mcp-server

Configuring MCP Servers with Environment Variables

When configuring your MCP servers, you have two options:

Option 1: Use MCP_ prefixed environment variables (Recommended)

Set your environment variables with the MCP_ prefix in your shell:

export MCP_ELEVENLABS_API_KEY="your-key"
export MCP_POSTGRES_HOST="localhost"
export MCP_API_TOKEN="your-token"

Then your MCP server configuration becomes much simpler since the variables are automatically forwarded:

{
  "mcpServers": {
    "ElevenLabs": {
      "command": "qmcp-uvx",
      "args": ["elevenlabs-mcp"]
    },
    "GitHubMCP": {
      "command": "qmcp",
      "args": ["ghcr.io/github/github-mcp-server"]
    }
  }
}

The MCP_ELEVENLABS_API_KEY and MCP_GITHUB_PERSONAL_ACCESS_TOKEN from your environment will automatically be available as ELEVENLABS_API_KEY and GITHUB_PERSONAL_ACCESS_TOKEN inside their respective containers.

Option 2: Set environment variables directly in the configuration

{
  "mcpServers": {
    "ElevenLabs": {
      "command": "qmcp-uvx",
      "args": ["elevenlabs-mcp"],
      "env": {
        "MCP_ELEVENLABS_API_KEY": "your-api-key-here"
      }
    },
    "GitHubMCP": {
      "command": "qmcp",
      "args": ["ghcr.io/github/github-mcp-server"],
      "env": {
        "MCP_GITHUB_PERSONAL_ACCESS_TOKEN": "your-github-token-here"
      }
    }
  }
}

Why the MCP_ Prefix?

This approach provides several benefits:

  • Security: Only explicitly intended environment variables are forwarded
  • Isolation: Prevents system paths and configurations from interfering
  • Clarity: Makes it obvious which variables are meant for MCP servers
  • No Permission Issues: Avoids Docker permission conflicts with system paths

How It Works

Python Container (qmcp-uvx)

  1. Base Image: Uses python:3.13-slim as the base image for a lightweight Python environment
  2. Dependencies: Installs uv (which includes uvx) and essential system tools
  3. User Security: Runs as a non-root user (mcpuser) for better security
  4. Entrypoint: Uses a custom entrypoint script that handles uvx command execution
  5. Path Setup: Configures the PATH to include uvx binary locations

Node.js Container (qmcp-npx)

  1. Base Image: Uses node:24-slim as the base image for a lightweight Node.js environment
  2. Dependencies: Includes npm and npx for package management
  3. User Security: Runs as a non-root user (mcpuser) for better security
  4. Entrypoint: Uses a custom entrypoint script that handles npx command execution
  5. Path Setup: Configures npm to install global packages in user directory

Supported MCP Servers

Python-based Servers (uvx)

This wrapper should work with any Python-based MCP server that can be installed and run with uvx. Examples include:

  • elevenlabs-mcp
  • filesystem-mcp
  • brave-search-mcp
  • postgres-mcp
  • Any other Python MCP server available on PyPI

Node.js-based Servers (npx)

This wrapper should work with any Node.js-based MCP server that can be installed and run with npx. Examples include:

  • @example/mcp-server
  • @nodeserver/filesystem-mcp
  • Any other Node.js MCP server available on npm

Docker-based Servers (plain Docker)

This wrapper works with any pre-built Docker image that implements an MCP server. Examples include:

  • ghcr.io/github/github-mcp-server
  • ghcr.io/modelcontextprotocol/servers/filesystem
  • Any other Docker image that provides an MCP server

Advanced Usage

Running Non-package-manager Commands

The containers can also run other commands:

Python container:

docker run --rm qmcp-uvx python --version
docker run --rm qmcp-uvx pip list

Node.js container:

docker run --rm qmcp-npx node --version
docker run --rm qmcp-npx npm list -g

Plain Docker (qmcp):

# Run any Docker image with MCP environment variable forwarding
qmcp your-registry.com/custom-mcp-server
qmcp ghcr.io/github/github-mcp-server --verbose

Mounting Volumes

If your MCP server needs access to local files:

docker run --rm -v /path/to/data:/data -e DATA_PATH=/data qmcp-uvx uvx your-mcp-server

Custom Networks

For MCP servers that need network access:

docker run --rm --network host qmcp-uvx uvx your-mcp-server

Troubleshooting

MCP Server Not Found

If you get an error that the MCP server package is not found, ensure:

  1. The package name is correct
  2. The package is available on PyPI
  3. You have internet access in the container

Permission Issues

If you encounter permission issues:

  • The container runs as user mcpuser (UID 1000) by default
  • Ensure any mounted volumes have appropriate permissions

Environment Variables Not Working

Make sure to:

  • Use the -e flag before each environment variable
  • Quote values that contain spaces or special characters
  • Reference environment variables correctly in your configuration

Contributing

Feel free to submit issues and pull requests to improve this Docker wrapper.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages