Defining MCP Tools with the Python SDK

Defining MCP Tools with the Python SDK

Dive into the practical aspects of defining and building MCP tools using the Python SDK. This section covers testing methodologies to ensure that your MCP servers are functioning as expected.

6 audio · 3:17

Nortren·

Why use the Python MCP SDK instead of writing tools by hand?

0:33
Building an MCP server becomes much simpler when you use the official Python SDK. Instead of writing complex JSON schemas by hand for every tool parameter, you can define tools with decorators and let the SDK generate the schemas for you. The SDK handles the protocol-level message exchange, the schema generation from Python type hints, the registration of your tool functions, and the integration with the Inspector for testing. The result is that you get to focus on the actual behavior of your tools, written as plain Python functions, while the SDK takes care of everything that makes those functions usable from the protocol side.

How do you initialize a new MCP server with the Python SDK?

0:33
The Python MCP SDK makes server creation straightforward. You can initialize a new MCP server with just a single line of code that creates a server instance you can then attach tools, resources, and prompts to. For a document management example, you might also set up a simple in-memory data structure, like a dictionary where the keys are document identifiers and the values are the document contents. That dictionary is your storage for the lifetime of the server. Once the server instance exists, you decorate Python functions to register them as tools, and the SDK wires everything up automatically when the server starts.

How do MCP decorators turn Python functions into tools?

0:31
The SDK uses decorators to register tools. Instead of writing JSON schemas manually, you apply a decorator named mcp dot tool to a regular Python function. The decorator marks that function as an MCP tool. The function name becomes the tool's name. The function's docstring becomes the tool's description that Claude reads when deciding whether to use it. The function's parameters, with their Python type hints, become the tool's input schema. And if you add Pydantic Field annotations to those parameters, the descriptions you provide become argument descriptions that help Claude understand exactly what each parameter expects.

How do you build a simple document reading tool in MCP?

0:32
Imagine the first tool in a document management server: a function that reads a document's contents by ID. You write a normal Python function that takes a document ID as its only parameter, looks the ID up in your in-memory dictionary, and returns the contents. You add the mcp tool decorator to register it. The decorator specifies the tool name and the description. The Pydantic Field class on the parameter provides a clear description of what the document ID argument expects. With those few lines, Claude can now discover the tool, see its schema, and decide to call it whenever a user asks to read a document.

How does an MCP find-and-replace tool work end to end?

0:34
The second tool in a document server performs a simple find-and-replace operation on a document. The function takes three parameters: the document ID, the text to find, and the replacement text. The implementation first checks that the document exists and raises an error if it does not. Then it performs a straightforward string replacement on the document's contents and stores the updated version back in the dictionary. The mcp tool decorator exposes this function to Claude with all three arguments described. From Claude's perspective, it just calls a tool with three string arguments and gets back a result indicating success or failure.

What are the key benefits of defining MCP tools with decorators?

0:34
The decorator approach gives you several practical benefits. There is no manual JSON schema writing required, because the SDK generates the schema from your Python type hints. Type hints also provide automatic validation, so invalid arguments are rejected before your code even runs. Clear parameter descriptions, supplied through Pydantic Field, help Claude understand correct tool usage. Error handling integrates naturally with regular Python exceptions, so you raise an error and the protocol layer reports it cleanly to the client. And tool registration happens automatically through the decorators themselves, so adding a new tool is just adding a new decorated function.