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. :::

Quiz

Module 3 Quiz: Tools, Resources, and Prompts

Take Quiz