Labsco
MCP SERVER

MCP Chain

by ruliana

Wrap any MCP server in Python middleware — add auth, logging or request rewriting — without touching the server you are wrapping.

MCP Plumbing: Proxies, Registries & Inspectors
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 — `CLIMCPServer` takes 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