This project provides a fully containerized, secure, and unified Model Context Protocol (MCP) stack using Nginx as a high-performance proxy. It is specifically optimized to run on macOS Apple Silicon using OrbStack, avoiding common issues with Docker socket dependencies.
The stack consists of three primary services running in isolated Docker containers:
- Unified Nginx Proxy: Acts as a central gateway. It routes traffic based on the URL path.
- Context7 MCP Server: Provides documentation and code context.
- SearXNG MCP Server: Provides web search capabilities.
- Zero Port Exposure: All port numbers are abstracted into the
.envfile for maximum security and flexibility. - Dynamic Configuration: Uses
nginx.conf.templateto automatically inject environment variables at startup. - Zero Docker Socket Dependency: The proxy does not require
/var/run/docker.sock, significantly improving security. - Unified Access: Both MCP servers are aggregated behind a single entry point.
- Hardened Security:
- Containers run with
read_only: truefilesystems. - Capabilities are dropped (
cap_drop: ALL). - No privilege escalation allowed (
no-new-privileges: true). - Internal servers are not exposed to the host/internet; only the Proxy is reachable.
- Containers run with
- OrbStack (or Docker Desktop)
- An Olares instance for SearXNG (configured in
.env)
-
Start the stack:
docker-compose up -d
-
Verify the services:
docker-compose ps
Zed is already configured to use the following endpoints:
- Context7:
http://localhost:${GATEWAY_PORT}/context7/mcp - SearXNG:
http://localhost:${GATEWAY_PORT}/searxng/mcp
You can verify these settings in your Zed settings.json file (cmd+,).
docker-compose.yml: The main orchestration file. Uses environment variables for all network settings.nginx.conf.template: The routing template that dynamically configures the proxy..env: The only place where secrets, URLs, and port numbers are stored.
- Port Busy: If the
${GATEWAY_PORT}is already in use, simply change it in the.envfile and restart. - Configuration Sync: If you change ports in
.env, rundocker-compose up -dto regenerate the proxy configuration.