LABSCO SUMMARY
Solves the "I need auth on someone else's server" problem.
Most MCP servers have no notion of who is calling; forking one to add a check means maintaining the fork. A proxy layer that rejects before forwarding avoids that entirely, and the same seam lets you relabel tool descriptions or collapse several calls into one. The chain is plain Python, so what you can express is not limited by a config schema.
What it is
A composable middleware framework for MCP, modelled on Ruby Rack. Each layer looks like a standard MCP server to the client while forwarding to the next one downstream, so you can add cross-cutting behaviour to a server you did not write and cannot change.
What you get
- A transparent proxy pattern —
mcp_chain()builds a chain,.then()adds a layer,serve()runs it - Two middleware positions per layer: one that transforms metadata (the tool list a client sees) and one that transforms requests and responses
- Requests rejected before they reach the downstream server — the auth example returns
{"error": "Authentication required", "code": 401}when no token is present - Tool descriptions rewritten in flight, so the same downstream server presents differently to different clients
- An existing MCP server wrapped by name —
ExternalMCPServer("postgres", "postgres-mcp") - Shell commands exposed as tools without writing a server —
CLIMCPServertakes a name, a list of commands and a description for each - Middleware that can orchestrate several MCP calls behind one tool, turning a granular API into a single higher-level operation
Requirements
Python and uvx — no setup beyond that. Write a small Python file that builds the chain, then run uvx mcp-chain your_server.py and point the client's config at that command. The package is mcp-chain 0.1.9 with the entry point mcp-chain. Chains are ordinary Python functions taking (next_server, request_dict), so logging, rate limiting and header injection are a few lines each.
Setup effort
One command — uvx mcp-chain cli_server.py
USE CASES
01
Putting a gate in front of a server that has none
Add an auth layer that checks for a token and returns an error before the request ever reaches the downstream server.
02
Seeing what an agent is actually calling
Insert a logging layer that records the method on the way in and the outcome on the way out.
03
Making a generic server speak your organisation's language
Rewrite tool descriptions in the metadata layer so the model sees context specific to your setup.
04
Exposing a few CLI commands as tools
Declare the commands with a description each and serve them, instead of writing an MCP server from scratch.
BEFORE YOU INSTALL
What to know first
Requires
uvx on PATH
Where it runs
The documented client runs the server on your machine.
INSTALLATION
Connect your client
Server setup
TERMINAL
uvx mcp-chain cli_server.pyMCP Clients
Any MCP client
ANY MCP CLIENT · JSON
{
"mcpServers": {
"dev-tools": {
"command": "uvx",
"args": [
"mcp-chain",
"cli_server.py"
]
}
}
}