Skip to content

Add support for tool annotations & filtering #2895

@phemmer

Description

@phemmer

Description

The MCP specification defines several tool annotations that can be used for filtering tools. I would like to be able to do so. In addition to these annotations being on the MCP tools, I would like to apply them on local tools as well. I have both MCP and local tools which attributes like "destructive" and "readOnly" and "openWorld" apply, and which I want to filter using based on what the agent is supposed to be doing at that time.

From looking at the pydantic-ai code, it looks like filtering might currently be accomplished by going through the ToolDefinition.parameters_json_schema, and something like FunctionToolset.add_function(schema_generator=...) for defining local tools. But this would be a fairly cumbersome process, and I think this would be suited to having first class support instead.

References

https://github.com/modelcontextprotocol/modelcontextprotocol/blob/199754c8141b0b709f4a5f9caf38a708bf8552ef/schema/2025-06-18/schema.json#L2438-L2461

{
    "definitions": {
        "Tool": {
            "description": "Definition for a tool the client can call.",
            "properties": {
                "annotations": {
                    "$ref": "#/definitions/ToolAnnotations",
                    "description": "Optional additional tool information.\n\nDisplay name precedence order is: title, annotations.title, then name."
                },
        },
        "ToolAnnotations": {
            "description": "Additional properties describing a Tool to clients.\n\nNOTE: all properties in ToolAnnotations are **hints**.\nThey are not guaranteed to provide a faithful description of\ntool behavior (including descriptive properties like `title`).\n\nClients should never make tool use decisions based on ToolAnnotations\nreceived from untrusted servers.",
            "properties": {
                "destructiveHint": {
                    "description": "If true, the tool may perform destructive updates to its environment.\nIf false, the tool performs only additive updates.\n\n(This property is meaningful only when `readOnlyHint == false`)\n\nDefault: true",
                    "type": "boolean"
                },
                "idempotentHint": {
                    "description": "If true, calling the tool repeatedly with the same arguments\nwill have no additional effect on the its environment.\n\n(This property is meaningful only when `readOnlyHint == false`)\n\nDefault: false",
                    "type": "boolean"
                },
                "openWorldHint": {
                    "description": "If true, this tool may interact with an \"open world\" of external\nentities. If false, the tool's domain of interaction is closed.\nFor example, the world of a web search tool is open, whereas that\nof a memory tool is not.\n\nDefault: true",
                    "type": "boolean"
                },
                "readOnlyHint": {
                    "description": "If true, the tool does not modify its environment.\n\nDefault: false",
                    "type": "boolean"
                },
                "title": {
                    "description": "A human-readable title for the tool.",
                    "type": "string"
                }
            },
            "type": "object"
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions