← 输入框|github.com|刷新
Skip to content

[Capability] Map PHPDoc pseudo-types to the JSON Schema type of their base type - #643

Merged
chr-hertel merged 6 commits into
modelcontextprotocol:mainfrom
sarankumar1325:fix/phpdoc-pseudo-types
Nov 3, 2026
Merged

chr-hertel merged 6 commits into
modelcontextprotocol:mainfrom
sarankumar1325:fix/phpdoc-pseudo-types

Conversation

@sarankumar1325

@sarankumar1325 sarankumar1325 commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #641

PHPStan/Psalm pseudo-types and literal types in a tool's DocBlock fell through to the default => 'object' branch of the type mapping, so a tool taking e.g. @param non-empty-string $name advertised {"type": "object"} and rejected a valid string argument with -32602.

This change maps them to their base type, both for parameters and for keys of an array shape:

DocBlock type Before After
non-empty-string, numeric-string, class-string, lowercase-string, … object string
positive-int, non-negative-int, negative-int, … object integer
array-key object ["integer", "string"]
'asc'|'desc' / 1|2 / true object string / integer / boolean
?non-empty-string, ?positive-int, ?list<T>, … ["null", "object"] their base type and null
non-empty-list<T>, non-empty-array<T> object array with items of T
non-empty-array<string, V> object object
non-empty-array<int, V>, non-empty-array<array-key, V> object ["array", "object"]

Inside an array shape:

  • list<T> and non-empty-list<T> keys become arrays.
  • array<K, V> keys depend on K: string-like keys become objects with additionalProperties, every other key (int, array-key, int|string) allows both arrays and objects, as sparse int keys arrive as an object.
  • mixed keys get the empty schema {}, so they accept any value.

Splitting a union or a shape now skips quoted literals and tracks <>, so 'a|b', 'a,b', '<' and the comma of array<int, T> stay in their key. Nested mixed encodes as items: {} instead of [], and the existing int<min, max> handling moved into the same helper.

Not covered:

  • An empty array<string, V> map and {"0": 1} are still rejected, as {} decodes to [] - that's SchemaValidator rejects nested empty JSON objects as arrays #586.
  • A plain top-level array<string, V> and array<int, V> stay array, like on main.
  • Other pseudo-types like value-of<X> or int-mask<…> still become object, there is no native type fallback.

Requires reflection-docblock ^6.0 from #657, older parsers drop the @param for types like non-empty-array<T>.

Tests: testMapsPhpStanAndPsalmPseudoTypesToTheirBaseType plus data-provider tests that check the schema and run valid & invalid arguments through SchemaValidator. Passes with lowest & highest dependencies. I also added a CHANGELOG entry under 0.10.0.

I used an AI assistant to help write this change. I reviewed and tested it.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-10-31T00:56:56.458125Z
We couldn’t complete this review. Comment @codex review to try again.
db1cab5 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved schema-generation defects produce invalid nested-array schemas, mishandle quoted literals and associative key types, and drop shape fields, potentially causing clients to reject schemas or valid inputs.

4 open issues
What changed in this PR

This PR addresses #641 by extending PHPDoc-to-JSON Schema mapping so supported pseudo-types and literals use their base types rather than defaulting to object.

Changes:

  • Adds shared mappings for string and integer pseudo-types, literals, and non-empty collections.
  • Expands array-shape handling for generic collections, string-keyed maps, and mixed values.
  • Adds regression coverage and documents the behavior in the changelog.
File Description
tests/​Unit/​Capability/​Discovery/​SchemaGeneratorTest.php Adds assertions for pseudo-types and collection types within shapes.
tests/​Unit/​Capability/​Discovery/​SchemaGeneratorFixture.php Adds a PHPDoc fixture covering the new mappings.
src/​Capability/​Discovery/​SchemaGenerator.php Implements pseudo-type mappings and expands generic and shape parsing.
CHANGELOG.md Documents the schema-generation fixes under 0.10.0.

Review effort: Balanced

@chr-hertel
chr-hertel force-pushed the fix/phpdoc-pseudo-types branch from 7a9176f to c3cbbb1 Compare November 3, 2026 00:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Schema generation misclassifies quoted-literal arrays and rejects valid sparse integer-keyed and empty string-keyed maps, causing valid arguments to fail validation.

3 open issues
4 resolved since last review

Review effort: Balanced

@chr-hertel chr-hertel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks @sarankumar1325 - extended it with more test cases and bumped some libs with #657 for better support 👍

@chr-hertel
chr-hertel merged commit 2b336ac into modelcontextprotocol:main Nov 3, 2026
28 checks passed
@chr-hertel chr-hertel added the Server Issues & PRs related to the Server component label Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Server Issues & PRs related to the Server component

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PHPDoc pseudo-types (non-empty-string, positive-int, list<T> in shapes…) become {"type":"object"} and valid calls are rejected

3 participants