Skip to content

fix: recognize typing_extensions.TypedDict input schemas on Python 3.11+ - #1341

Open
redswimmer wants to merge 2 commits into
anthropics:mainfrom
redswimmer:claude/nice-einstein-awk4o1
Open

redswimmer wants to merge 2 commits into
anthropics:mainfrom
redswimmer:claude/nice-einstein-awk4o1

Conversation

@redswimmer

Copy link
Copy Markdown

Fixes #1337

Problem

On Python 3.11+, the SDK uses stdlib typing.is_typeddict, which returns False for classes built on typing_extensions.TypedDict (a separate implementation since typing_extensions 4.6). _build_input_schema then falls through to {"type": "object", "properties": {}}, so the tool reaches the model with no parameters and no warning. 3.10 is unaffected because it already uses typing_extensions.is_typeddict.

class Args(typing_extensions.TypedDict):
    latitude: Annotated[float, "Latitude coordinate"]

@tool("probe", "probe", Args)
async def probe(args): ...

_build_input_schema(probe)  # 3.11+: {"properties": {}, "type": "object"}

Fix

  • Import is_typeddict from typing_extensions on every Python version; it accepts both TypedDict spellings.
  • Make typing_extensions an unconditional dependency, since the SDK now imports it on every version. Raise the floor from 4.0.0 to 4.1.0: is_typeddict doesn't exist in 4.0.0, so the old floor also broke the import on 3.10. mcp/pydantic already require a newer version, so resolved installs don't change.

Verification

Ran the reproduction script from the issue with typing_extensions 4.16.0:

Python before after
3.10 ✅ full schema ✅ full schema
3.11 / 3.12 / 3.13 ❌ empty schema ✅ full schema, required: ["latitude"]
  • New test_typeddict_schema_for_either_typeddict_spelling registers a tool through create_sdk_mcp_server, reads the schema back via list_tools, and covers both spellings, Annotated, NotRequired and a nested TypedDict. It fails on main (assert {} == {...}) and passes with the fix.
  • pytest on 3.10–3.13: all pass · mypy: clean · ruff: clean

claude added 2 commits October 1, 2026 00:47
On 3.11+ the SDK used the stdlib is_typeddict, which does not recognize
classes built on typing_extensions.TypedDict (typing_extensions ships its
own TypedDict implementation from 4.6 onward). @tool then published such
tools with an empty input schema and no warning.

Use typing_extensions.is_typeddict on every Python version (it accepts
both spellings) and declare typing_extensions as an unconditional
dependency. The floor moves to 4.1.0, the first release with
is_typeddict.

Adds a regression test covering both TypedDict spellings, NotRequired,
Annotated descriptions and a nested TypedDict through
create_sdk_mcp_server.

Fixes anthropics#1337

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EDXJ5Yg4PTHTtKeDw3b7CY
Parametrize directly on the two TypedDict bases with readable ids,
describe the behavior in a docstring like the surrounding tests, and
drop the importlib indirection and type-ignore comments.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EDXJ5Yg4PTHTtKeDw3b7CY

@sigley sigley left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validated exact head d433bf6 independently. On current main, a typing_extensions.TypedDict input schema reproduces as an empty object schema; this head recognizes the same class and emits the expected typed properties/required set. The branch merges cleanly with current main, the targeted TypedDict cases pass 6/6, the full MCP integration slice passes 146/146, and compile/diff checks are clean. One non-blocking integration note: if #1325 lands first, the pyproject conflict should preserve its AnyIO 4.5 floor while keeping this PR's unconditional typing_extensions>=4.1.0 requirement.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@tool builds an empty input schema, with no error, for an input_schema it does not recognize (typing_extensions.TypedDict on Python 3.11 and later)

3 participants