Skip to main content

An extensible MCP server

reactor_mcp_server is a foundation for building Model Context Protocol servers out of plugins. A deployment adds tools by installing a distribution; nothing in the server is edited, and nothing in the server names what is installed.

It is a reactor plugin package, and an MCP extension is a reactor plugin: the tools, toolsets, resources and prompts it offers are ordinary contributions at four contribution points, so what a server is made of can be listed, grouped and drawn before anything is built.

pip install reactor_mcp_server

Three ideas​

A tool is a contribution. An extension does not reach into a server object and register a function on it. It offers a ToolSpec, and the host builds a server from what has been offered. See Tools.

A contribution can be extended. An extension may narrow, wrap or re-describe a tool that another extension offered, by name and in a declared order. See Extending a tool.

The URL decides what is served. Tools belong to named toolsets, and a client says which ones it wants in the URL it connects to. A toolset carries its own title, description and instructions, can be opt-in and not woken until asked for, and is listed at /toolsets and by the list_server_toolsets tool. See Toolsets.

The smallest server that works​

from reactor import PluginManifest
from reactor_mcp_server import McpExtension, build_host, create_mcp_app, tool


class Notebooks(McpExtension):
def manifest(self) -> PluginManifest:
return PluginManifest(name="notebooks", version="1.0.0")

@tool(title="List Notebooks")
async def list_notebooks(self) -> list[str]:
"""Every notebook the caller can reach."""
return ["Titanic", "Pyramid"]


app = create_mcp_app(build_host([Notebooks()], name="my-server"), path="/mcp")

app is a Starlette application: serve it with uvicorn, or mount it in one you already have. A deployment that wants the installed extensions and no code at all runs the module instead — see Serving.

What the pieces are called​

ConstructWhat it is
McpExtensionA reactor plugin that offers tools. One subclass per extension.
ToolSpecOne tool, as an extension offers it: a name, a handler, what a model reads.
ToolExtensionWhat one extension does to another extension's tool.
ToolsetA named group of tools, the thing a URL switches on.
McpHostThe platform, the extensions on it, and the servers built from them.
BuiltServerA server and what it was built from — so a host can say why these tools.
ToolsetRouterThe ASGI application that reads the URL and routes to the right built server.

Where to go next​