fastmcp icon indicating copy to clipboard operation
fastmcp copied to clipboard

Input schemas of custom objects are very large

Open strawgate opened this issue 8 months ago • 2 comments

A custom object as the input to a tool where the custom object has two fields and the tool takes a third parameter results in a 1.1kb input schema (1/3rd of which is whitespace). It would be nice if this could be significantly reduced.

Perhaps refs could be output once for the whole list of tools?

class KnowledgeBaseUpdateProto(ExportableModel):
    """Model for requesting an update to a Knowledge Base"""

    name: str = kb_name_field
    description: str = kb_description_field

async def update_by_backend_id(self, backend_id: str, knowledge_base_update: KnowledgeBaseUpdateProto) -> None:
    ...
- knowledge_base_update_by_backend_id: Update the metadata of an existing knowledge base by its backend ID.
    Input Schema:
		{
      "type": "object",
      "properties": {
        "backend_id": {
          "title": "Backend Id",
          "type": "string"
        },
        "knowledge_base_update": {
          "$ref": "#/$defs/KnowledgeBaseUpdateProto"
        }
      },
      "$defs": {
        "KnowledgeBaseUpdateProto": {
          "description": "Model for requesting an update to a Knowledge Base",
          "properties": {
            "name": {
              "description": "The name of the knowledge base, used for identification and retrieval.",
              "title": "Name",
              "type": "string"
            },
            "description": {
              "description": "A brief description of the knowledge base, providing context and purpose.",
              "title": "Description",
              "type": "string"
            }
          },
          "required": [
            "name",
            "description"
          ],
          "title": "KnowledgeBaseUpdateProto",
          "type": "object"
        }
      },
      "required": [
        "backend_id",
        "knowledge_base_update"
      ],
      "title": "update_by_backend_idArguments"
    }

strawgate avatar Apr 20 '25 00:04 strawgate

In my server I have a second version of most tools which allows bulk actions, so I have one version which allows creating a knowledge base which takes primitives as parameters and one version which allows creating many knowledge bases and takes a list of objects where the objects have those primitives.

I'll probably explore three paths:

  1. Can I reduce the size of the input schema via model config
  2. Can I just add a bulk_action tool which takes a tool name and a list of dictionaries of parameters and calls the tool name times
  3. Can I just switch the bulk tools to taking a list of dictionaries
  4. And I'll explore hiding some of the tools initially and allow them to be enabled at runtime if needed, though this will make using the decorators less fun

strawgate avatar Apr 20 '25 01:04 strawgate

looking at this further it's probably the host deciding to not compress the json its putting in instructions

I was able to prune the Title from the field schema


from typing import Any
from pydantic import BaseModel, ConfigDict


def prune_schema(schema: dict[str, Any]) -> None:

    schema.pop('title', None)
    for prop in schema.get('properties', {}).values():
        prop.pop('title', None)

class ExportableModel(BaseModel):
    """Base model for exportable objects, providing a method to convert to a dictionary."""

    model_config = ConfigDict(json_schema_extra=prune_schema)

which helped a little bit...

strawgate avatar Apr 20 '25 03:04 strawgate