A powerful, production-ready framework for composing and orchestrating Model Context Protocol (MCP) servers with advanced management capabilities, REST API, and modern Web UI.
MCP Server Composer is a comprehensive solution for managing multiple MCP servers in a unified environment. It provides automatic discovery, intelligent composition, protocol translation, real-time monitoring, and a beautiful web interface for managing your MCP infrastructure.
π§ Multi-Server Management - Start, stop, and monitor multiple MCP servers from a single interface
π REST API - Complete REST API with 32 endpoints for programmatic control
π¨ Modern Web UI - Beautiful React-based interface with real-time updates
π Protocol Translation - Seamlessly translate between STDIO and SSE protocols
π Real-Time Monitoring - Live metrics, logs, and health checks
π Security First - Token authentication, CORS support, rate limiting
π¦ Easy Deployment - Docker support with docker-compose orchestration
π§ͺ Well Tested - 95% test coverage with 265+ tests
π Comprehensive Docs - Full API reference, user guide, and deployment guide
# Install from PyPI
pip install mcp-server-composer
# Or install from source
git clone https://github.com/datalayer/mcp-server-composer.git
cd mcp-server-composer
pip install -e .# Clone repository
git clone https://github.com/datalayer/mcp-server-composer.git
cd mcp-server-composer
# Start with docker-compose (includes Prometheus & Grafana)
docker-compose up -d
# Access the Web UI
open http://localhost:8000# Start the server with Web UI
mcp-composer serve --config examples/mcp_server_composer.toml
# Access Web UI at http://localhost:8000
# Access API at http://localhost:8000/api/v1
# Access API docs at http://localhost:8000/docs
# Discover available MCP servers
mcp-composer discover
# Invoke a tool
mcp-composer invoke-tool calculator:add '{"a": 5, "b": 3}'from mcp_server_composer import MCPServerComposer
# Create composer and start servers
composer = MCPServerComposer()
composer.load_config("config.toml")
# Start all servers
for server in composer.servers.values():
await composer.start_server(server.name)
# List available tools
tools = await composer.list_tools()
print(f"Available tools: {[t.name for t in tools]}")
# Invoke a tool
result = await composer.invoke_tool("calculator:add", {"a": 5, "b": 3})
print(f"Result: {result}")The modern web interface provides:
- π Dashboard - Overview of all servers, tools, and system metrics
- π₯οΈ Server Management - Start, stop, restart servers with real-time status
- π§ Tool Browser - Search and invoke tools with interactive forms
- βοΈ Configuration Editor - Edit and validate configuration files
- π Log Viewer - Real-time log streaming with filtering
- π Metrics Dashboard - Charts for CPU, memory, and request metrics
- π Translator Management - Create and manage protocol translators
- βοΈ Settings - Configure theme, API settings, and preferences
- User Guide - Complete guide for using MCP Server Composer
- API Reference - Full REST API and Python API documentation
- Deployment Guide - Production deployment with Docker & Kubernetes
- Architecture - System architecture and design decisions
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Web UI (React) β
β Dashboard β Servers β Tools β Config β Logs β Metrics β
ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββ
β HTTP/WebSocket
ββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββ
β REST API (FastAPI) β
β /servers β /tools β /config β /translators β /metrics β
ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββ
β MCP Server Composer Core β
β Server Manager β Tool Broker β Config Manager β
βββββββββ¬βββββββββββ¬βββββββββββ¬βββββββββββ¬βββββββββββββββββββββ
β β β β
ββββββ΄ββββ βββββ΄βββββ βββββ΄βββββ βββββ΄βββββ
β Server β β Server β β Server β β Server β
β A β β B β β C β β D β
ββββββββββ ββββββββββ ββββββββββ ββββββββββ
- Multi-Server Orchestration - Run multiple MCP servers simultaneously
- Lifecycle Management - Start, stop, restart, and monitor server health
- Auto-restart - Automatically restart failed servers
- Environment Isolation - Each server runs in its own isolated environment
- Configuration Hot-Reload - Update configuration without restarting
- Automatic Discovery - Find tools and prompts from all running servers
- Intelligent Composition - Combine capabilities from multiple sources
- Conflict Resolution - Handle naming conflicts with prefix/suffix/override strategies
- Dynamic Loading - Tools appear as servers start
- Unified Interface - Single API to access all tools
- STDIO β SSE - Translate between different transport protocols
- Transparent Bridging - No changes needed to existing servers
- Bidirectional - Full request/response support
- Multiple Translators - Run many translators simultaneously
- Real-Time Metrics - CPU, memory, request rates, and latency
- Structured Logging - JSON logs with correlation IDs
- Health Checks - Continuous monitoring of server health
- Prometheus Integration - Export metrics for Prometheus
- WebSocket Streaming - Live log and metric updates
- Token Authentication - Secure API access
- CORS Support - Configurable origin policies
- Rate Limiting - Prevent abuse
- Input Validation - Comprehensive request validation
- Non-root Containers - Run as unprivileged user
Create mcp_server_composer.toml:
[composer]
name = "my-composer"
conflict_resolution = "prefix"
[[servers]]
name = "filesystem"
command = "python"
args = ["-m", "mcp_server_filesystem", "/data"]
transport = "stdio"
auto_start = true
[[servers]]
name = "calculator"
command = "python"
args = ["-m", "mcp_server_calculator"]
transport = "stdio"
auto_start = true
[logging]
level = "INFO"
format = "json"
[security]
auth_enabled = true
cors_origins = ["http://localhost:3000"]See User Guide for complete configuration options.
# Health & Status
GET /api/v1/health
GET /api/v1/version
GET /api/v1/status
GET /api/v1/status/composition
# Server Management
GET /api/v1/servers
POST /api/v1/servers/{id}/start
POST /api/v1/servers/{id}/stop
POST /api/v1/servers/{id}/restart
# Tool Management
GET /api/v1/tools
POST /api/v1/tools/{name}/invoke
# Configuration
GET /api/v1/config
PUT /api/v1/config
POST /api/v1/config/validate
POST /api/v1/config/reload
# Translators
GET /api/v1/translators
POST /api/v1/translators
DELETE /api/v1/translators/{id}
# WebSocket
WS /ws/logs
WS /ws/metricsSee API Reference for complete documentation.
# Run all tests
make test
# Run with coverage
make test-coverage
# Run specific test
pytest tests/test_composer.py -v
# Type checking
make type-check
# Linting
make lint# Clone repository
git clone https://github.com/datalayer/mcp-server-composer.git
cd mcp-server-composer
# Install development dependencies
pip install -e ".[dev]"
# Install UI dependencies
cd ui
npm install
npm run dev
# Run tests
make test
# Build UI
make build-ui
# Run server
mcp-composer serve# Build and run
docker-compose up -d
# View logs
docker-compose logs -f
# Stop
docker-compose down# Build with production settings
docker build -t mcp-composer:prod .
# Run with environment variables
docker run -d \
-p 8000:8000 \
-v $(pwd)/config.toml:/app/config.toml:ro \
-e MCP_COMPOSER_AUTH_TOKEN=secret \
--name mcp-composer \
mcp-composer:prodSee Deployment Guide for Kubernetes and production setup.
A complete example demonstrating how to orchestrate Git and Filesystem MCP servers with anonymous access.
Location: examples/git-file/
Features:
- Git operations (status, log, diff, commit)
- Filesystem operations (read, write, list)
- Unified API with tool prefixing
- No authentication required
- Full Makefile for easy management
Quick Start:
cd examples/git-file
make install
make start
make open-uiSee the Git-File Example README for complete documentation.
Production-ready example with GitHub OAuth2 authentication.
Location: examples/mcp-auth/
Features:
- OAuth2 authentication flow
- JWT tokens
- Protected MCP server endpoints
- Pydantic AI agent integration
See the MCP Auth Example README for details.
Configuration files and infrastructure resources are located in the resources/ directory:
nginx.conf- Nginx reverse proxy configurationprometheus.yml- Prometheus metrics collectiongrafana/- Grafana dashboards and datasources
Week 13-16 Deliverables:
- β Modern React-based Web UI with 8 pages
- β Real-time monitoring dashboard
- β Log viewer with streaming
- β Metrics visualization with Recharts
- β Protocol translator management
- β Settings and preferences
- β Comprehensive documentation
- β Docker deployment setup
- β Production-ready configuration
Test Coverage: 95% (265+ tests)
Code Quality: Type-checked with mypy
Lines of Code: ~15,000 (including UI)
- β Core composition engine
- β CLI interface
- β REST API (32 endpoints)
- β Web UI (8 pages)
- β Real-time monitoring
- β Protocol translation
- β Docker deployment
- β Comprehensive documentation
- π Plugin system for custom extensions
- π GraphQL API support
- π Advanced caching strategies
- π Distributed deployment support
- π Enhanced analytics
- π CLI auto-completion
Contributions are welcome! Please see our Contributing Guide for details.
# Fork and clone
git clone https://github.com/YOUR_USERNAME/mcp-server-composer.git
# Create feature branch
git checkout -b feature/amazing-feature
# Make changes and test
make test
# Commit and push
git commit -m "Add amazing feature"
git push origin feature/amazing-feature
# Create Pull RequestBSD 3-Clause License - see LICENSE for details.
- Built on FastMCP framework
- Inspired by the Model Context Protocol specification
- UI built with React, TypeScript, and Recharts
- Special thanks to all contributors
- Documentation: Full documentation
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Sponsor: Become a sponsor
Made with β€οΈ by Datalayer composer = MCPServerComposer( composed_server_name="unified-data-server", conflict_resolution=ConflictResolution.PREFIX )
unified_server = composer.compose_from_pyproject()
summary = composer.get_composition_summary() print(f"Created server with {summary['total_tools']} tools")
#### Advanced Configuration
```python
from pathlib import Path
from mcp_server_composer import MCPServerComposer, ConflictResolution
# Specify custom pyproject.toml location
composer = MCPServerComposer(
composed_server_name="my-server",
conflict_resolution=ConflictResolution.SUFFIX
)
# Compose with filtering
unified_server = composer.compose_from_pyproject(
pyproject_path=Path("custom/pyproject.toml"),
include_servers=["jupyter-mcp-server", "earthdata-mcp-server"],
exclude_servers=["deprecated-server"]
)
# Access composed tools and prompts
tools = composer.list_tools()
prompts = composer.list_prompts()
source_info = composer.get_source_info()
print(f"Tools: {', '.join(tools)}")
print(f"Sources: {', '.join(source_info.keys())}")
from mcp_server_composer import MCPServerDiscovery
# Discover MCP servers without composing
discovery = MCPServerDiscovery()
servers = discovery.discover_from_pyproject("pyproject.toml")
for name, info in servers.items():
print(f"{name}: {len(info.tools)} tools, {len(info.prompts)} prompts")When multiple servers provide tools or prompts with the same name, you can choose how to resolve conflicts:
- PREFIX (default): Add server name as prefix (
server1_tool_name) - SUFFIX: Add server name as suffix (
tool_name_server1) - OVERRIDE: Last server wins (overwrites previous)
- IGNORE: Skip conflicting items
- ERROR: Raise an error on conflicts
# If two servers both have a "search" tool:
# PREFIX: jupyter_mcp_server_search, earthdata_mcp_server_search
# SUFFIX: search_jupyter_mcp_server, search_earthdata_mcp_server
# OVERRIDE: Only the last server's "search" tool is keptCreate a unified MCP server combining Jupyter notebook capabilities with Earth science data access:
# pyproject.toml
[project]
dependencies = [
"jupyter-mcp-server>=1.0.0",
"earthdata-mcp-server>=0.1.0",
"weather-mcp-server>=2.0.0"
]# Discover available tools
python -m mcp_server_composer discover
# Create unified server for data science workflow
python -m mcp_server_composer compose \
--name "data-science-server" \
--conflict-resolution prefix \
--output unified_server.pyThis creates a server with tools like:
jupyter_create_notebook- Create analysis notebooksearthdata_search_datasets- Find Earth science dataweather_get_forecast- Access weather data- Combined prompts for data analysis workflows
Combine development tools and documentation servers:
from mcp_server_composer import MCPServerComposer, ConflictResolution
composer = MCPServerComposer(
composed_server_name="dev-environment",
conflict_resolution=ConflictResolution.PREFIX
)
# Compose development-focused servers
dev_server = composer.compose_from_pyproject(
include_servers=[
"code-review-mcp-server",
"documentation-mcp-server",
"testing-mcp-server"
]
)
# Access all development tools in one place
print("Available tools:", composer.list_tools())from mcp_server_composer import MCPServerComposer
from my_custom_server import MyMCPServer
# Create composer
composer = MCPServerComposer()
# Compose discovered servers
unified_server = composer.compose_from_pyproject()
# Add your custom server manually if needed
composer.add_server("custom", MyMCPServer())
# Get final composition summary
summary = composer.get_composition_summary()
print(f"Final server has {summary['total_tools']} tools from {summary['source_servers']} sources")When using MCP Server Composer, structure your project like this:
my-project/
βββ pyproject.toml # Define MCP server dependencies
βββ src/
β βββ my_project/
β βββ __init__.py
β βββ main.py # Use composed server
βββ composed_server.py # Generated unified server (optional)
βββ README.md
[project]
name = "my-data-project"
dependencies = [
"jupyter-mcp-server>=1.0.0",
"earthdata-mcp-server>=0.1.0",
"fastmcp>=1.2.0"
]
[project.optional-dependencies]
dev = [
"pytest>=7.0.0",
"mcp-server-composer>=1.0.0"
]The library provides comprehensive error handling:
from mcp_server_composer import MCPServerComposer, MCPComposerError, MCPDiscoveryError
try:
composer = MCPServerComposer()
server = composer.compose_from_pyproject()
except MCPDiscoveryError as e:
print(f"Discovery failed: {e}")
print(f"Search paths: {e.search_paths}")
except MCPComposerError as e:
print(f"Composition failed: {e}")
print(f"Server count: {e.server_count}")- No MCP servers found: Ensure your dependencies include packages with "mcp" in the name
- Import errors: Check that MCP server packages are properly installed
- Naming conflicts: Use appropriate conflict resolution strategy
- Missing tools: Verify that server packages export an
appvariable
# Enable verbose logging
python -m mcp_server_composer discover --verbose
# Check specific package
python -c "
from mcp_server_composer import MCPServerDiscovery
discovery = MCPServerDiscovery()
result = discovery._analyze_mcp_server('your-package-name')
print(result)
"
## API Reference
### MCPServerComposer
Main class for composing MCP servers:
```python
MCPServerComposer(
composed_server_name: str = "composed-mcp-server",
conflict_resolution: ConflictResolution = ConflictResolution.PREFIX
)
Methods:
compose_from_pyproject(pyproject_path, include_servers, exclude_servers)- Compose servers from dependenciesget_composition_summary()- Get summary of composition resultslist_tools()- List all available toolslist_prompts()- List all available promptsget_source_info()- Get mapping of tools/prompts to source servers
Class for discovering MCP servers:
MCPServerDiscovery(mcp_server_patterns: List[str] = None)Methods:
discover_from_pyproject(pyproject_path)- Discover servers from pyproject.tomlget_package_version(dependency_spec)- Extract version from dependency string
Enum for conflict resolution strategies:
PREFIX- Add server name as prefixSUFFIX- Add server name as suffixOVERRIDE- Last server winsIGNORE- Skip conflicting itemsERROR- Raise error on conflicts
- Python 3.8+
- FastMCP >= 1.2.0
- TOML parsing support
We welcome contributions! Please see our Contributing Guidelines for details.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes and add tests
- Ensure all tests pass (
pytest) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
See CHANGELOG.md for version history and changes.
- π Documentation: Full API documentation and examples in this README
- π Issues: Report bugs and request features on GitHub Issues
- π¬ Discussions: Join the conversation in GitHub Discussions
- FastMCP - Python SDK for Model Context Protocol
- MCP Specification - Official MCP specification
- Jupyter MCP Server - MCP server for Jupyter functionality
- Earthdata MCP Server - MCP server for NASA Earthdata access
Made with β€οΈ by the Datalayer team
- Earthdata MCP Server - MCP server for NASA Earthdata
See CHANGELOG.md for a detailed history of changes.
- GitHub Issues: Report bugs or request features
- Documentation: Full documentation
- Community: Join the discussion