Skip to content

Fastmcp tool parameter parsing type error #381

Open
@weester-yan

Description

@weester-yan

When I define the tool parameter as string, the parameter parsing function of fastmcp parses the numeric string I pass in into a numeric value.

  • mcp/server/fastmcp/utilities/func_metadata.py
    def pre_parse_json(self, data: dict[str, Any]) -> dict[str, Any]:
        """Pre-parse data from JSON.

        Return a dict with same keys as input but with values parsed from JSON
        if appropriate.

        This is to handle cases like `["a", "b", "c"]` being passed in as JSON inside
        a string rather than an actual list. Claude desktop is prone to this - in fact
        it seems incapable of NOT doing this. For sub-models, it tends to pass
        dicts (JSON objects) as JSON strings, which can be pre-parsed here.
        """
        new_data = data.copy()  # Shallow copy
        for field_name, field_info in self.arg_model.model_fields.items():
            import logging
            logging.info((field_name, field_info))
            logging.info("before parse: ", new_data)
            if field_name not in data.keys():
                continue
            if isinstance(data[field_name], str):
                try:
                    pre_parsed = json.loads(data[field_name])
                except json.JSONDecodeError:
                    continue  # Not JSON - skip
                if isinstance(pre_parsed, str):
                    # This is likely that the raw value is e.g. `"hello"` which we
                    # Should really be parsed as '"hello"' in Python - but if we parse
                    # it as JSON it'll turn into just 'hello'. So we skip it.
                    continue
                new_data[field_name] = pre_parsed
             logging.info("after parse: ", new_data)
        assert new_data.keys() == data.keys()
        return new_data

test output:

video-1  | ('cid', FieldInfo(annotation=str, required=True, description='xxx.'))
video-1  | before parse: {'cid': '1.2'}
video-1  | after parse: {'cid': 1.2}
video-1  | Error calling tool: Error executing tool getinfo: 1 validation error for getinfoArguments
video-1  | cid
video-1  |   Input should be a valid string [type=string_type, input_value=1.2, input_type=float]
video-1  |     For further information visit https://errors.pydantic.dev/2.10/v/string_type

Here, json.loads will parse the incoming string "1.2" into the floating point number 1.2

So, when I use pydantic to define parameters in tool, a validation error occurs

from pydantic import validate_call, Field

@server.tool(description="xxx")
@validate_call
async def getinfo(
        cid: str = Field(..., description="xxx."),
) -> bool | None:

Is my understanding correct?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions