Error Handling in FastMCP Servers
So what does the LLM actually understand?
Only the text of the error message. If you raise ToolError("amount must be positive"), the LLM sees "amount must be positive". It doesn't know it was a ToolError and doesn't care about the exception type. For a developer, this means some important things:
Write error messages for the LLM (not necessarily for developers).
Use plain language that the LLM can understand and act on, rather than relying on exception types or structured data.
Don't rely on exception type to communicate meaning; the type is lost
Regular Python exceptions (caught internally and re-raised, or unhandled) work too, but their full message including the class name may leak internals, thus
ToolErroris recommended for controlled messages.
In practice, for server-side errors you control:
from fastmcp.exceptions import ToolError
@mcp.tool()
def divide(a: float, b: float) -> float:
"""Divide two numbers."""
if b == 0:
# LLM reads: "Cannot divide by zero. Please provide a non-zero divisor."
raise ToolError("Cannot divide by zero. Please provide a non-zero divisor.")
return a / b
For errors you don't control (third-party libraries, I/O failures), catch the exception and convert it to a ToolError with a clean message:
@mcp.tool()
async def fetch_data(urlPractical MCP with FastMCP & LangChain
Engineering the Agentic ExperienceEnroll now to unlock current content and receive all future updates for free. Your purchase supports the author and fuels the creation of more exciting content. Act fast, as the price will rise as the course nears completion!
