Managing Multiple MCP Server Tools in a Single Server: A Complete Guide

You can host unlimited MCP tools on a single server by registering them to a shared FastMCP instance, allowing clients to discover and invoke multiple capabilities through one endpoint.

The cr2007/mcp-wordle-python repository demonstrates this pattern by implementing a lightweight MCP server that exposes Wordle puzzle data alongside extensible tool registration. By leveraging the FastMCP library, developers can consolidate multiple services—read-only queries, data transformations, and external API calls—within a single Python runtime.

Understanding the FastMCP Architecture

The FastMCP Instance as Central Dispatcher

At the heart of multi-tool management lies the FastMCP class, which acts as a central dispatcher for tool registration and request routing. In src/mcp_wordle/main.py, the server initializes a single instance that coordinates all subsequent tool definitions:

from fastmcp import FastMCP

mcp = FastMCP("WordleMCP")

This instance, named WordleMCP, maintains an internal registry of available tools. When an MCP-compatible client (such as Claude Desktop) connects, it queries this registry to discover all exposed capabilities, enabling multiple tools to coexist under one server identity.

Tool Registration via Decorators

The @mcp.tool() decorator transforms Python coroutines into discoverable MCP tools. The Wordle server registers its primary functionality—fetching puzzle solutions—using this pattern in src/mcp_wordle/main.py:

@mcp.tool(
    name="get_wordle_solution",
    description="Fetches the Wordle solution for a specific date.",
)
async def get_wordle_data(target_date: str) -> dict:
    # Implementation details...

Metadata parameters like name, description, and hints (e.g., readOnlyHint) provide clients with semantic context. This declarative approach allows you to register dozens of tools without modifying server infrastructure—simply add new decorated functions to the same file.

Implementing Multiple Tools in One Server

Adding a Second Tool to the Wordle Server

To demonstrate extensibility, you can register additional tools alongside the existing Wordle fetcher. The following example adds an echo utility to src/mcp_wordle/main.py, sharing the same FastMCP instance:

@mcp.tool(
    name="echo_message",
    description="Returns the same string that was sent, useful for testing.",
)
async def echo(message: str) -> str:
    return message

Because both tools attach to the mcp instance, clients receive a unified tool catalog containing get_wordle_solution and echo_message. The FastMCP runtime handles routing each invocation to the appropriate coroutine based on the tool name specified in client requests.

Type Safety with TypedDict Definitions

Robust multi-tool servers require strict type contracts to prevent runtime errors. The Wordle repository defines TypedDict structures in src/mcp_wordle/main.py to validate API responses:

from typing import TypedDict

class WordleAPIData(TypedDict):
    solution: str
    print_date: str
    days_since_launch: int
    editor: str

class WordleError(TypedDict):
    error: str

These definitions ensure that get_wordle_solution returns predictable structures, while allowing other tools in the same server to define their own TypedDict contracts. Type safety becomes critical when managing multiple tools, as it prevents cross-tool contamination of data schemas.

Deployment Strategies for Multi-Tool Servers

Docker Containerization

Containerizing multi-tool MCP servers enables horizontal scaling and environment consistency. The repository provides a Dockerfile that packages the FastMCP application:

FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install -e .
CMD ["python", "-m", "mcp_wordle"]

When building multi-tool deployments, you can extend this base image to include additional tool modules. A Docker Compose configuration orchestrates multiple MCP servers on the same host, each exposing distinct toolsets:

services:
  wordle:
    image: ghcr.io/cr2007/mcp-wordle-python:latest
    environment:
      - DOCKER_CONTAINER=true

  another-mcp:
    build: ./another-mcp
    depends_on:
      - wordle

UVX Quick Deployment

For rapid prototyping, the uvx package manager allows zero-installation execution of MCP servers. The repository supports this pattern via pyproject.toml configuration:

uvx mcp-wordle-python

This command downloads and executes the server without permanent installation, ideal for testing multi-tool configurations. When managing multiple servers, you can chain uvx commands or configure Claude Desktop's mcpServers settings to point to various uvx invocations, effectively running disparate tool collections within isolated processes.

Summary

  • FastMCP instances serve as centralized registries for multiple tools, enabling single-server deployment of diverse capabilities.
  • The @mcp.tool() decorator registers Python functions as discoverable endpoints, supporting unlimited tool additions without infrastructure changes.
  • TypedDict definitions enforce type safety across multiple tools, preventing schema conflicts in shared servers.
  • Docker and uvx provide flexible deployment paths for multi-tool architectures, from containerized clusters to lightweight process isolation.

Frequently Asked Questions

How many tools can a single MCP server host?

A single FastMCP instance can host unlimited tools limited only by system resources and Python's concurrency model. Each tool registered via @mcp.tool() consumes minimal memory overhead, allowing production servers to expose dozens of endpoints—from data queries to computational utilities—within one process.

Can I mix read-only and write tools in the same server?

Yes, FastMCP supports heterogeneous tool types in one registry. You can combine read-only tools (marked with readOnlyHint=True) like the Wordle fetcher with mutating tools that modify external state. The MCP protocol handles permission scopes at the client level, while the server simply exposes available capabilities.

How do clients distinguish between tools on the same server?

Clients receive a tool catalog upon connection containing unique names and descriptions for each registered tool. When invoking get_wordle_solution versus echo_message, the client specifies the exact tool name in the request payload, and FastMCP routes execution to the corresponding Python coroutine automatically.

Is FastMCP the only library for building multi-tool MCP servers?

While FastMCP is the dominant Python SDK for MCP implementations, the protocol itself is language-agnostic. Alternative implementations exist for TypeScript, Rust, and Go. However, FastMCP's decorator-based registration and automatic type inference make it the most ergonomic choice for Python developers building multi-tool servers.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →