
BaseMcpServer
A minimal containerized base for MCP servers using the MCP Python SDK
3 years
Works with Finder
0
Github Watches
0
Github Forks
0
Github Stars
BaseMcpServer
A minimal containerized base for MCP servers using the MCP Python SDK.
Overview
BaseMcpServer provides a standardized Docker base image for building Model Context Protocol (MCP) servers. It is:
- Simple: Designed as a minimal implementation using the MCP Python SDK
- Containerized: Built specifically for Docker deployment
- Protocol-specific: Uses both HTTP+SSE and stdio protocols
- Reusable: Serves as a foundation for derived MCP server implementations
This image provides all the common dependencies and configuration needed for MCP servers, so that derived projects can focus solely on implementing their specific tools and resources.
Local Development
For local development without Docker, each MCP server includes setup scripts to create and manage Python virtual environments with the necessary dependencies.
Prerequisites
- Python 3.11+ installed (recommended)
- Git (to clone this repository)
Using Setup and Run Scripts
Each MCP server includes two shell scripts for easy setup and execution:
1. Setup Script
The setup.sh
script creates a virtual environment and installs all dependencies:
# Navigate to the desired MCP server directory
cd example/
# Run the setup script
./setup.sh
This will:
- Create a
.venv
directory with a Python virtual environment - Install all required dependencies from
requirements.txt
- Configure the environment for local development
2. Run Script
The run.sh
script activates the virtual environment and runs the MCP server:
# Start with SSE protocol (for Claude/Cline integration)
./run.sh sse
# Or start with stdio protocol (for direct stdin/stdout communication)
./run.sh stdio
Manual Setup (If Scripts Don't Work)
If the scripts don't work on your system, you can manually set up the environment:
# Navigate to the desired MCP server directory
cd example/
# Create a virtual environment
python3.11 -m venv .venv
# Activate the virtual environment
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Set PYTHONPATH and run the server
export PYTHONPATH="$PWD/src:$PYTHONPATH" # On Windows: set PYTHONPATH=%CD%\src;%PYTHONPATH%
cd src
python main.py sse # Or: python main.py stdio
Virtual Environment Structure
The virtual environment approach:
- Creates an isolated Python environment for each MCP server
- Installs only the dependencies needed for that specific server
- Allows for easy activation/deactivation
- Sets the correct PYTHONPATH automatically
- Provides a consistent environment across different systems
Best Practices for Custom MCP Servers
When creating custom MCP servers based on this template, follow these best practices to avoid common issues:
Port Configuration
-
Use the Correct Ports: The base image exposes port
7501
. Always align your configuration with this port:- In the
.env
file, setPORT=7501
- When running the container, map the external port to 7501:
docker run -p EXTERNAL_PORT:7501
- In the VSCode/Claude settings, use the external port with the SSE suffix:
"url": "http://localhost:EXTERNAL_PORT/sse"
- In the
-
Consistent Port Usage: Be consistent with your port numbering. If you choose external port 7777:
- Docker command:
docker run -p 7777:7501
- VSCode/Claude settings:
"url": "http://localhost:7777/sse"
- Docker command:
-
Port Conflicts: If you get connection errors, check for port conflicts with
lsof -i :PORT_NUMBER
Environment Variables
-
Mounting vs. Copying: For development, you can copy the
.env
file into the container:COPY ./.env ./.env
For production, mount it at runtime:
docker run -p 7777:7501 --env-file .env your-image
-
Robust Config Loading: Implement robust environment variable loading with logging and fallbacks:
# Add logging of loaded configuration values logger.info(f"JIRA_URL: {settings.JIRA_URL}") logger.info(f"Using port: {settings.port}")
-
Verify Environment: Use explicit validation of required environment variables with clear error messages
MCP Manager Utility
The project now includes an mcp-manager
utility for easy installation and management of MCP servers. This tool simplifies the process of setting up, configuring, and running MCP servers.
Installing MCP Manager
# Install directly from the repository
pipx install git+https://github.com/yourusername/BaseMcpServer.git#subdirectory=utils/mcp_manager
Key Features
- Server Installation: Install MCP servers from local directories or Git repositories
- Server Configuration: Configure servers for use with VS Code/Cline
- Server Management: List, run, and manage installed servers
- Isolated Environments: Each server runs in its own Python virtual environment
Basic Usage
# Install a local MCP server
mcp-manager install local example-server --source ./example
# Install from a Git repository
mcp-manager install git jira-server --repo https://github.com/example/jira-mcp-server.git
# List installed servers
mcp-manager list
# Configure VS Code integration
mcp-manager configure vscode
# Run a server manually (if needed)
mcp-manager run server-name --transport stdio
Connecting to Claude/Cline
To connect your MCP server to Claude Desktop or Cline in VS Code:
-
For locally installed servers using mcp-manager:
- You do NOT need to manually start the server - VS Code will start it automatically when needed
- Make sure to restart VS Code completely after installing or updating servers
- The server will run with stdio transport by default
-
For manually running servers:
./run.sh sse # For local development with HTTP+SSE transport
or
docker run -p 7501:7501 your-image # For Docker
-
For Cline in VS Code:
With mcp-manager, you can simply run:
mcp-manager configure vscode
Or manually edit the settings file: Path:
~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json
Example configuration:
{ "mcpServers": { "example-mcp-server": { "url": "http://localhost:7501/sse", "apiKey": "example_key", "disabled": false, "autoApprove": [] }, "directlyruntest": { "command": "/home/user/.mcp_servers/bin/directlyruntest.sh", "disabled": false, "autoApprove": [] } } }
Notes:
- For HTTP+SSE servers, use the correct server name from config.py (server_name setting)
- For stdio servers, use the command path generated by mcp-manager
- Ensure the port matches your configuration (default is 7501) for HTTP+SSE servers
- Include "/sse" at the end of the URL for HTTP+SSE servers
-
For Claude Desktop, go to: Settings → Advanced → MCP Servers → Add MCP Server
Enter:
- Name: example-mcp-server (or your custom server name)
- URL: http://localhost:7501
- API Key: example_key (or your custom API key)
-
Restart VS Code completely after making any changes to MCP server configuration
VS Code Integration
-
Restart VS Code When Needed: When installing or updating MCP servers, you must restart VS Code completely:
- Simply installing a server with mcp-manager is not enough
- You must exit VS Code fully and restart it for changes to take effect
- This is especially important for stdio-based servers
-
Automatic Server Startup: For servers installed with mcp-manager:
- VS Code will automatically start the server when needed
- You do NOT need to manually run the server with
mcp-manager run
- This happens transparently when Claude/Cline attempts to use the server
-
Clear Connection Errors: When you see "Not connected" errors from Claude, it usually indicates:
- VS Code hasn't been fully restarted after installation
- The server configuration is incorrect
- For HTTP+SSE servers, the server might not be running or has a port mismatch
Debugging Techniques
-
Add Detailed Logging: Enhance logging, especially for configuration and initialization:
logger.info(f"Starting MCP server on {settings.host}:{settings.port}") logger.info(f"Using API key: {'Yes' if settings.api_key else 'No'}")
-
Check Server Logs: Always check the Docker container logs with
docker logs CONTAINER_ID
-
Verify Docker Container: Use
docker ps
to ensure your container is running and the port mapping is correct
Testing Approach
- Incremental Development: Start with a known working example (like the example server)
- Make Small Changes: Make one change at a time and test after each change
- Test Core Functionality: Test with simple tools like the calculator before adding complex integrations
- Examine Error Messages: Pay close attention to error messages in both the server logs and Claude's responses
For more detailed debugging notes, see debugging_notes.md
in the project root.
Key Features
- Python 3.11+ environment with all MCP SDK dependencies pre-installed
- Multi-stage Docker build for optimized image size
- Non-root user for improved security
- HTTP+SSE protocol support via Starlette and Uvicorn
- Environment variable configuration via pydantic-settings
- Local development support with virtual environments
- Dual transport support (HTTP+SSE and stdio)
Usage
Building the Base Image
./build.sh base-mcp-server latest 7501 <your-docker-username>
Parameters:
-
base-mcp-server
: Image name (default) -
latest
: Tag (default) -
7501
: Port to expose (default) -
<your-docker-username>
: Required - Your Docker Hub username
This will:
- Build the base image
- Tag it for Docker Hub
- Push it to Docker Hub if you're logged in
Using the Base Image in Derived Projects
In your Dockerfile:
# Define build argument for Docker Hub username
ARG DOCKER_USERNAME
# Use the base MCP server image from Docker Hub
FROM docker.io/${DOCKER_USERNAME}/base-mcp-server:latest
# Copy your application code
COPY ./src ./src
# Set PYTHONPATH to include src as a sources root
ENV PYTHONPATH="/app/src:${PYTHONPATH}"
# Set working directory to src
WORKDIR /app/src
# Command to run your MCP server with sse transport
CMD ["python", "main", "sse"]
Technical Details
Protocol Support
BaseMcpServer now supports both HTTP+SSE and stdio protocols:
- HTTP+SSE: Ideal for containerized deployments and network-based integrations
- stdio: Useful for local development and direct integration with command-line tools
What is HTTP+SSE in MCP?
HTTP+SSE (Server-Sent Events) is one of the standard transports supported by the MCP protocol:
- HTTP: Used for client-to-server communication (requests)
- SSE: Used for server-to-client communication (responses and events)
HTTP+SSE is designed for networked environments, making it ideal for:
- Web-based LLM integrations
- Service-to-service MCP communication
- Containerized deployments (like this one)
- Cloud environments
What is stdio in MCP?
The stdio transport uses standard input/output streams for communication:
- stdin: Used for receiving client requests
- stdout: Used for sending server responses
This transport is primarily used for:
- Local development
- Direct integration with command-line tools
- Desktop applications that can spawn processes
Implementation Details
This base image uses:
- Starlette: A lightweight ASGI framework that handles the HTTP+SSE protocol
- Uvicorn: An ASGI server that serves the Starlette application
- Native Python I/O: For stdio transport mode
The implementation is provided by the MCP Python SDK through:
- The
.sse_app()
method for HTTP+SSE - Direct
run("stdio")
support for stdio mode
Mounting the MCP Server
When extending this base image, your MCP server is automatically served via HTTP+SSE. For more advanced scenarios where you need to integrate with existing web services, you can mount the MCP server to an existing ASGI application:
from starlette.applications import Starlette
from starlette.routing import Mount, Host
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("My App")
# Mount the MCP server to an existing ASGI application
app = Starlette(
routes=[
Mount('/mcp', app=mcp.sse_app()),
]
)
# Or mount it as a subdomain
app.router.routes.append(Host('mcp.example.com', app=mcp.sse_app()))
Security Considerations
When using HTTP+SSE in production:
- Always use HTTPS in production environments
- Consider implementing authentication for the HTTP endpoints
- If exposing your MCP server publicly, use API keys or other authentication mechanisms
- Implement rate limiting for public-facing servers
Python SDK Implementation
The image directly uses the MCP Python SDK with minimal abstraction:
- FastMCP for ergonomic tool definitions
- Built-in schema generation based on Python type hints
- Automatic validation of input/output formats
- Support for both HTTP+SSE and stdio transport modes
Environment Variables and Configuration
The base image supports configuration through environment variables, which can be passed to derived images in several ways:
Available Environment Variables
-
HOST
: Interface to bind to (default: 0.0.0.0) -
PORT
: Port to listen on (default: 7501) -
API_KEY
: Required for authentication (must be provided) -
SERVER_NAME
: Unique identifier for your MCP server - Any additional environment variables required by your specific implementation
Configuration Methods for Derived Images
1. Using Command Line Environment Variables
docker run -p 7501:7501 \
-e API_KEY=your_api_key \
-e SERVER_NAME=your-mcp-server \
yourdockerusername/your-mcp-server:latest
2. Using an Environment File
Create a .env
file with your configuration:
API_KEY=your_api_key
SERVER_NAME=your-mcp-server
HOST=0.0.0.0
PORT=7501
Then run with:
docker run -p 7501:7501 --env-file .env yourdockerusername/your-mcp-server:latest
3. Using Docker Secrets (for Docker Swarm)
For production deployments using Docker Swarm:
echo "your_api_key" | docker secret create api_key -
echo "your_server_name" | docker secret create server_name -
docker service create \
--name your-mcp-server \
--secret api_key \
--secret server_name \
--publish 7501:7501 \
yourdockerusername/your-mcp-server:latest
4. Building Configuration into Derived Images
For development or testing purposes, you can build configuration directly into derived images:
FROM docker.io/yourusername/base-mcp-server:latest
# Configure environment variables (non-sensitive only!)
ENV HOST=0.0.0.0
ENV PORT=7501
ENV SERVER_NAME=example-mcp-server
# Copy application code
COPY ./src ./src
CMD ["python", "main", "sse"]
Security Best Practices
- Never include sensitive API keys or secrets in Dockerfiles or images
- Use environment variables or mounted secrets for sensitive values
- Consider using Docker secrets or a vault service for production
- The container runs as a non-root user for improved security
- Rotate API keys and secrets regularly
Development
This repository contains:
-
docker/Dockerfile
: Multi-stage Dockerfile for the base image -
build.sh
: Build script with Docker Hub integration -
requirements-base.txt
: Base Python dependencies - Server-specific implementation directories (example/, jira-clone/)
- Local development scripts (setup.sh, run.sh)
License
相关推荐
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
🔥 1Panel provides an intuitive web interface and MCP Server to manage websites, files, containers, databases, and LLMs on a Linux server.
PDF scientific paper translation with preserved formats - 基于 AI 完整保留排版的 PDF 文档全文双语翻译,支持 Google/DeepL/Ollama/OpenAI 等服务,提供 CLI/GUI/MCP/Docker/Zotero
Easily create LLM tools and agents using plain Bash/JavaScript/Python functions.
Artifact2MCP Generator allows generation of MCP server automatically & dynamically given smart contract's compiled artifact (chain‑agnostic)