Skip to main content

The toolsets example

examples/mcp-toolsets — two MCP toolsets in one wheel, served by any reactor_mcp_server host.

An MCP extension is a reactor plugin whose contributions are tools. This example is two of them, each declaring one toolset, and the smallest amount of code that shows the two ways a toolset is served: to everybody, or only to the client that asks.

ToolsetToolsServed
mathadd, multiplyTo every client — on by default, with instructions for the model
geoget_capital_of_country, get_country_of_capitalOnly to a client that asks with ?geo — and its extension is not even woken until one does

Run it​

Installed, the two extensions are found through their entry points by the generic reactor-mcp-server command. Nothing names them:

pip install -e "examples/mcp-toolsets[server]"
reactor-mcp-server --port 4040

Or from code, with nothing installed but the server:

python examples/mcp-toolsets/serve.py # http://localhost:4040/mcp

Then choose with the URL an MCP client connects to:

URLTools
http://localhost:4040/mcpadd, multiply, list_server_toolsets
http://localhost:4040/mcp?geothe above, and the two geo tools
http://localhost:4040/mcp?only=geothe geo tools, and list_server_toolsets
http://localhost:4040/mcp?without=mathlist_server_toolsets alone

/toolsets answers the same question over plain HTTP, without opening an MCP session:

curl -s "http://localhost:4040/toolsets?geo" | python -m json.tool

A client that launches the server itself has no URL, so the command line selects:

{
"mcpServers": {
"toolsets-example": {
"command": "reactor-mcp-server",
"args": ["--transport", "stdio", "--toolsets", "geo"]
}
}
}

What is in it​

FileWhat it shows
reactor_mcp_toolsets_example/math.pyAn McpExtension with one Toolset — title, description, instructions — and two @tool methods annotated as pure functions
reactor_mcp_toolsets_example/geo.pyThe same, opt-in: default=False keeps its tools off a bare /mcp, and activation_events=[on_toolset("geo")] keeps the extension asleep until a URL names it
pyproject.tomlBoth extensions published on the reactor.mcp.extensions entry-point group — installing the wheel is publishing them
serve.pyThe host built in code: build_host([...], toolsets_tool=True) and create_mcp_app
tests/test_toolsets.pyThe toolsets as a client sees them — in process, over HTTP with a real MCP client, and over stdio through the entry points

The core of geo.py:

class GeoExtension(McpExtension):
def manifest(self) -> PluginManifest:
return PluginManifest(
name="geo",
version="0.1.0",
activation_events=[on_toolset("geo")],
)

def toolsets(self):
return (Toolset(name="geo", title="Geography", default=False),)

@tool(title="Get Capital of Country", annotations=LOOKUP)
async def get_capital_of_country(self, country: str) -> str:
"""Return the capital city of a country, by the country's English name."""
...

Test it​

pip install -e "examples/mcp-toolsets[test]"
pytest examples/mcp-toolsets/tests -v

The stdio test runs only when the example is installed, since that is how the command finds the extensions; CI installs it.

Where to read more​

  • Example toolsets walks the same two extensions through the MCP server's model, with the exchange a client has when it discovers geo and reconnects for it.
  • Toolsets is the URL grammar, instructions, list_server_toolsets and what a deployment decides.
  • Serving lists every option of reactor-mcp-server.

The same shape serves real data: NASA Earthdata ships an opt-in earthdata toolset, and installing it beside any host serves it at /mcp?earthdata.