Skip to content

Fix Pydantic field alias consistency in structured output #1099

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

sjwhole
Copy link
Contributor

@sjwhole sjwhole commented Jul 7, 2025

Fix Pydantic field alias consistency in structured output

Summary

Fixes issue #1073. Fix inconsistency between schema and structured output when using Pydantic models with field aliases in tool return types. The schema would display aliased field names but the actual output would use original field names.

Motivation and Context

When defining Pydantic models with field aliases for tool return types, there was an inconsistency where:

  • The output schema would correctly show aliased field names (e.g., "first", "second")
  • The actual structured tool output would use the original field names (e.g., "field_first", "field_second")

This inconsistency made it difficult for clients to reliably consume structured tool outputs, as the field names in the schema didn't match the actual response data.

How Has This Been Tested?

  • Added comprehensive test case test_structured_output_aliases() that verifies both schema generation and output use consistent alias names
  • All existing pytest tests continue to pass

Breaking Changes

No breaking changes. This is a bug fix that makes the behavior consistent with what the schema advertises. Users who were working around this inconsistency may need to update their code to use the aliased field names consistently.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

The fix was a simple one-line change adding by_alias=True to the model_dump() call in func_metadata.py:114. This ensures that when Pydantic models are serialized for structured output, they use the same field names that appear in the generated JSON schema.

The test case covers both the schema generation and the actual output conversion to ensure they remain consistent. This addresses the core issue described in the original bug report where the schema and output used different field naming conventions.

Technical Details

Before the fix:

class Foo(BaseModel):
    field_first: str | None = Field(default=None, alias="first", description="The first field.")
    field_second: str | None = Field(default=None, alias="second", description="The second field.")
  • Schema would show: "first" and "second"
  • Output would contain: "field_first" and "field_second"

After the fix:

  • Both schema and output consistently use: "first" and "second"

Code change:

# Before
structured_content = validated.model_dump(mode="json")

# After  
structured_content = validated.model_dump(mode="json", by_alias=True)

Resolve inconsistency between schema and actual output when using Pydantic models with field aliases as tool return types:
- Add by_alias=True parameter to model_dump() call in func_metadata.py
- Add comprehensive test case to verify alias consistency
- Ensure schema generation and structured output use same aliased field names

Before: Schema shows "first", "second" but output uses "field_first", "field_second"
After: Both schema and output consistently use aliased field names
Copy link
Contributor

@ihrpr ihrpr left a comment

Choose a reason for hiding this comment

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

Thank you for working on this!

QQ:

Added comprehensive test case test_structured_output_aliases() that verifies both schema generation and output use consistent alias names

I don't see any tests added, please can this be checked?

Add comprehensive test_structured_output_aliases() that verifies:
- Schema generation uses aliased field names
- Structured output uses same aliased field names
- Both explicit values and default values work correctly
- Ensures consistency between schema and actual tool output
@sjwhole sjwhole requested a review from ihrpr July 7, 2025 08:59
@sjwhole
Copy link
Contributor Author

sjwhole commented Jul 7, 2025

I’m wondering why I can’t get some tests to pass on Windows.

Thank you for working on this!

QQ:

Added comprehensive test case test_structured_output_aliases() that verifies both schema generation and output use consistent alias names

I don't see any tests added, please can this be checked?

@bhosmer-ant bhosmer-ant self-requested a review July 7, 2025 14:14
Copy link
Contributor

@ihrpr ihrpr left a comment

Choose a reason for hiding this comment

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

Thank you!

@ihrpr ihrpr linked an issue Jul 7, 2025 that may be closed by this pull request
@ihrpr ihrpr merged commit 5c9cf29 into modelcontextprotocol:main Jul 7, 2025
27 of 30 checks passed
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.

Inconsistent Field Naming Between outputSchema and model_dump
2 participants