Tool Definition Structure
Learn the complete structure of tool definitions including name, description, and inputSchema.
The Tool Object
Every tool in MCP is defined by a Tool object with three required fields. Let's examine each in detail.
{
"name": "tool_name",
"description": "What the tool does",
"inputSchema": {
"type": "object",
"properties": { ... },
"required": [ ... ]
}
}
The name Field
The name is a unique identifier for the tool. It's used when
calling the tool via tools/call.
Use snake_case for tool names. Keep names descriptive but concise.
Good: get_weather, send_email, calculate_sum.
Avoid: doThing, x, my-tool-1.
The description Field
The description tells the AI model what the tool does. This is
crucial — the model uses this to decide when to use the tool.
// Good description - specific and actionable
{
"name": "search_files",
"description": "Search for files matching a pattern in a directory. Returns a list of matching file paths. Use this when you need to find files by name or extension."
}
// Bad description - vague and unhelpful
{
"name": "search_files",
"description": "Searches files"
}
The inputSchema Field
The inputSchema defines what arguments the tool accepts using
JSON Schema. This is a standard format for describing JSON data structures.
Basic JSON Schema Structure
{
"type": "object",
"properties": {
"param1": {
"type": "string",
"description": "What this parameter does"
},
"param2": {
"type": "number",
"description": "Another parameter"
}
},
"required": ["param1"]
}
Common JSON Schema Types
| Type | Description | Example |
|---|---|---|
string |
Text values | "hello" |
number |
Any numeric value | 42, 3.14 |
integer |
Whole numbers only | 42 |
boolean |
True or false | true |
array |
List of items | [1, 2, 3] |
object |
Nested structure | {"key": "value"} |
Advanced Schema Features
{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Search query",
"minLength": 1,
"maxLength": 100
},
"limit": {
"type": "integer",
"description": "Max results to return",
"minimum": 1,
"maximum": 100,
"default": 10
},
"format": {
"type": "string",
"description": "Output format",
"enum": ["json", "csv", "xml"]
},
"tags": {
"type": "array",
"description": "Filter by tags",
"items": {
"type": "string"
}
}
},
"required": ["query"]
}
Defining Tools in Python
Here's how to define tools as Python dictionaries that can be serialized to JSON:
"""
tools.py - Tool definitions for an MCP server.
"""
# Define your tools as dictionaries
TOOLS = [
{
"name": "add",
"description": "Add two numbers together and return the sum",
"inputSchema": {
"type": "object",
"properties": {
"a": {
"type": "number",
"description": "First number"
},
"b": {
"type": "number",
"description": "Second number"
}
},
"required": ["a", "b"]
}
},
{
"name": "multiply",
"description": "Multiply two numbers and return the product",
"inputSchema": {
"type": "object",
"properties": {
"a": {
"type": "number",
"description": "First number"
},
"b": {
"type": "number",
"description": "Second number"
}
},
"required": ["a", "b"]
}
}
]
# Function to get all tool definitions
def get_tools():
"""Return all available tools."""
return TOOLS
# Function to find a tool by name
def get_tool(name):
"""Find a tool by name, returns None if not found."""
for tool in TOOLS:
if tool["name"] == name:
return tool
return None
While MCP doesn't require servers to validate arguments against the schema,
it's good practice to do so. Libraries like jsonschema can help
validate arguments before executing tools.
Complete Tool Example
Here's a more complete example with a file search tool:
FILE_SEARCH_TOOL = {
"name": "search_files",
"description": (
"Search for files in a directory matching a pattern. "
"Returns a list of file paths that match. Useful for finding "
"files by name, extension, or pattern."
),
"inputSchema": {
"type": "object",
"properties": {
"directory": {
"type": "string",
"description": "Directory path to search in"
},
"pattern": {
"type": "string",
"description": "Glob pattern to match (e.g., '*.py', 'test_*.txt')"
},
"recursive": {
"type": "boolean",
"description": "Search subdirectories recursively",
"default": False
},
"max_results": {
"type": "integer",
"description": "Maximum number of results to return",
"minimum": 1,
"maximum": 1000,
"default": 100
}
},
"required": ["directory", "pattern"]
}
}