Tools, Resources, and Prompts
Advanced Tool Patterns
5 min read
Let's explore advanced patterns for building sophisticated MCP tools.
Tool Composition
Combine multiple operations into a single tool:
@server.list_tools()
async def list_tools():
return [
Tool(
name="search_and_summarize",
description="Search documents and return a summary",
inputSchema={
"type": "object",
"properties": {
"query": {"type": "string"},
"max_results": {"type": "integer", "default": 5}
},
"required": ["query"]
}
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "search_and_summarize":
# Step 1: Search
results = await search_documents(arguments["query"])
# Step 2: Summarize
summary = await generate_summary(results[:arguments.get("max_results", 5)])
return [TextContent(type="text", text=summary)]
Streaming Results
For long-running operations, stream results:
@server.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "analyze_large_dataset":
results = []
async for batch in process_in_batches(arguments["data"]):
results.append(batch)
# Yield intermediate results
yield [TextContent(type="text", text=f"Processed batch: {len(results)}")]
# Final result
yield [TextContent(type="text", text=json.dumps(results))]
Confirmable Actions
For dangerous operations, require confirmation:
Tool(
name="delete_all_files",
description="Delete all files in a directory. DESTRUCTIVE ACTION.",
inputSchema={
"type": "object",
"properties": {
"directory": {"type": "string"},
"confirm": {
"type": "boolean",
"description": "Must be true to proceed"
}
},
"required": ["directory", "confirm"]
}
)
@server.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "delete_all_files":
if not arguments.get("confirm"):
return [TextContent(
type="text",
text="Action not confirmed. Set confirm=true to proceed."
)]
# Proceed with deletion
await delete_files(arguments["directory"])
Tool Dependencies
Build tools that depend on other tools:
class ToolRegistry:
def __init__(self):
self.tools = {}
def register(self, name, handler):
self.tools[name] = handler
async def call(self, name, arguments):
return await self.tools[name](arguments)
registry = ToolRegistry()
async def get_user_handler(args):
return await db.get_user(args["id"])
async def get_user_orders_handler(args):
# Depends on get_user
user = await registry.call("get_user", {"id": args["user_id"]})
return await db.get_orders(user["id"])
registry.register("get_user", get_user_handler)
registry.register("get_user_orders", get_user_orders_handler)
Next, we'll explore advanced resource patterns. :::