MCP Chain
Um framework de middleware componível para construir cadeias sofisticadas de servidores MCP, inspirado no Ruby Rack.
Documentação
Tradução
MCP Chain
Um framework de middleware componível para construir cadeias de servidores MCP, inspirado no Ruby Rack. O MCP Chain permite criar proxies transparentes que ficam entre clientes e servidores MCP, transformando requisições e respostas usando funções Python.
O MCP Chain resolve o problema de adicionar preocupações transversais (autenticação, registro de logs, transformação de requisições) a servidores MCP existentes sem modificá-los. Ele usa um padrão de proxy transparente onde cada camada de middleware aparece como um servidor MCP padrão para os clientes, enquanto encaminha requisições para servidores downstream. O middleware também pode orquestrar múltiplas chamadas MCP nos bastidores usando IA, transformando APIs granulares em MCPs inteligentes que executam tarefas complexas de múltiplas etapas.
Início Rápido
Instale e execute com uvx - nenhuma configuração necessária:
# cli_server.py
from mcp_chain import mcp_chain, CLIMCPServer
cli_server = CLIMCPServer(
name="dev-tools",
commands=["git", "ls", "grep"],
descriptions={
"git": "Git version control operations",
"ls": "List directory contents",
"grep": "Search text patterns"
}
)
# Auto-detected by CLI
chain = mcp_chain().then(cli_server)
uvx mcp-chain cli_server.py
Adicione ao seu mcp.json:
{
"mcpServers": {
"dev-tools": {
"command": "uvx",
"args": ["mcp-chain", "cli_server.py"]
}
}
}
Exemplos
Middleware de Autenticação
Adicione autenticação a qualquer servidor MCP:
from mcp_chain import mcp_chain, ExternalMCPServer, serve
def require_auth(next_server, request_dict):
if not request_dict.get("auth_token"):
return {"error": "Authentication required", "code": 401}
return next_server.handle_request(request_dict)
chain = (mcp_chain()
.then(None, require_auth)
.then(ExternalMCPServer("postgres", "postgres-mcp")))
serve(chain, name="Authenticated Postgres")
Transformação de Requisição/Resposta
Transforme metadados e requisições:
from mcp_chain import mcp_chain, CLIMCPServer
def add_company_context(next_server, metadata_dict):
metadata = next_server.get_metadata()
for tool in metadata.get("tools", []):
tool["description"] = f"ACME Corp: {tool.get('description', '')}"
return metadata
def add_headers(next_server, request_dict):
request_dict["headers"] = {"X-Company": "ACME"}
response = next_server.handle_request(request_dict)
response["processed_by"] = "acme-proxy"
return response
cli_server = CLIMCPServer(name="tools", commands=["git", "docker"])
chain = (mcp_chain()
.then(add_company_context, add_headers)
.then(cli_server))
Cadeia de Múltiplos Middlewares
Empilhe autenticação, registro de logs e transformação:
import logging
from mcp_chain import mcp_chain, ExternalMCPServer, serve
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("mcp-chain")
def auth_middleware(next_server, request_dict):
if not request_dict.get("auth_token"):
return {"error": "Authentication required", "code": 401}
return next_server.handle_request(request_dict)
def logging_middleware(next_server, request_dict):
logger.info(f"Request: {request_dict.get('method')}")
response = next_server.handle_request(request_dict)
logger.info(f"Response: {response.get('result', 'error')}")
return response
def context_middleware(next_server, metadata_dict):
metadata = next_server.get_metadata()
for tool in metadata.get("tools", []):
tool["description"] = f"Enterprise: {tool.get('description', '')}"
return metadata
chain = (mcp_chain()
.then(context_middleware, auth_middleware)
.then(None, logging_middleware)
.then(ExternalMCPServer("postgres", "postgres-mcp")))
serve(chain, name="Enterprise Postgres")
Uso Programático
Use a função serve() diretamente:
from mcp_chain import mcp_chain, CLIMCPServer, serve
def rate_limit_middleware(next_server, request_dict):
# Add rate limiting logic
return next_server.handle_request(request_dict)
cli_server = CLIMCPServer(name="secure-tools", commands=["git"])
chain = mcp_chain().then(None, rate_limit_middleware).then(cli_server)
serve(chain, name="Rate Limited Tools", port=8000)
Arquitetura
O MCP Chain usa um padrão de middleware funcional onde cada camada transforma requisições/respostas e encaminha para a próxima camada:
graph TD
A["MCP Client"] --> B["FastMCP"]
B --> C["mcp_chain()"]
C --> D1["middleware_1"]
D1 --> D2["middleware_2"]
D2 --> E["downstream_server"]
E -- "response" --> D2
D2 -- "response" --> D1
D1 -- "response" --> C
C -- "response" --> B
B -- "response" --> A
Cada camada de middleware:
- Recebe requisições da camada anterior (ou do cliente)
- Transforma a requisição/metadados usando dicionários Python
- Encaminha para a próxima camada (ou servidor downstream)
- Recebe a resposta de volta
- Transforma a resposta conforme necessário
- Retorna para a camada anterior (ou cliente)
Princípios Fundamentais:
- Proxy Transparente: Cada middleware aparece como um servidor MCP padrão para os clientes
- Processamento Baseado em Dicionários: O processamento interno usa dicionários Python, não strings JSON
- Componível: Middlewares podem ser encadeados, pois cada camada é um servidor MCP
- Zero Overhead: Sem serialização/desserialização na cadeia de middleware
Construído sobre o SDK oficial FastMCP para conformidade completa com o protocolo MCP.
API
Funções Principais
from mcp_chain import mcp_chain, serve, CLIMCPServer, ExternalMCPServer
# Create a chain
chain = mcp_chain()
# Add middleware layers
chain = chain.then(metadata_transformer, request_transformer)
chain = chain.then(downstream_server)
# Start server
serve(chain, name="My Server", port=8000)
Construção de Cadeias
# Metadata transformer (transforms server capabilities)
def metadata_transformer(next_server, metadata_dict):
metadata = next_server.get_metadata()
# Transform metadata dict and return
return metadata
# Request transformer (transforms requests/responses)
def request_transformer(next_server, request_dict):
# Transform request dict
response = next_server.handle_request(request_dict)
# Transform response dict and return
return response
# Add to chain
chain = mcp_chain().then(metadata_transformer, request_transformer)
Servidores Integrados
# CLI server - exposes command-line tools as MCP tools
cli_server = CLIMCPServer(
name="my-tools",
commands=["git", "docker", "npm"],
descriptions={
"git": "Git operations",
"docker": "Container management",
"npm": "Package management"
}
)
# External server proxy
external_server = ExternalMCPServer("server-name", "command-to-run")
Auto-Detecção
A CLI detecta automaticamente variáveis de cadeia em seus arquivos Python:
# Any of these variable names work:
chain = mcp_chain().then(...)
my_chain = mcp_chain().then(...)
server_chain = mcp_chain().then(...)
proxy = mcp_chain().then(...)
Execute com: uvx mcp-chain filename.py
Desenvolvimento
Este projeto foi desenvolvido principalmente com assistentes de IA e é projetado para fluxos de trabalho de desenvolvimento assistidos por IA. A base de código é estruturada para ser facilmente compreendida e modificada por ferramentas de IA. A pasta ai/ contém documentos de contexto e notas de design especificamente para assistentes de IA que trabalham neste repositório.
Instalação
# Development install
git clone https://github.com/ronie-uliana/mcp-chain
cd mcp-chain
uv sync
Testes
# Fast unit tests
uv run pytest tests/ -m "not integration" -v
# Integration tests (with timeout protection)
timeout 30 uv run pytest tests/ -m integration -v
# All tests
timeout 45 uv run pytest tests/ -v
# Local CI pipeline
./scripts/test-ci.sh
Publicação
uv build && uv publish
As versões são publicadas automaticamente no PyPI via GitHub Actions em novos lançamentos.
Opções de Instalação
# Recommended: Run with uvx (no installation)
uvx mcp-chain my_chain.py
# Install from PyPI
pip install mcp-chain
# Run installed version
python -m mcp_chain my_chain.py
# or
mcp-chain my_chain.py