Skip to content

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

Open
sarankumar1325 wants to merge 3 commits into
modelcontextprotocol:mainfrom
sarankumar1325:fix/phpdoc-pseudo-types
Open

sarankumar1325 wants to merge 3 commits into
modelcontextprotocol:mainfrom
sarankumar1325:fix/phpdoc-pseudo-types

Conversation

@sarankumar1325

Copy link
Copy Markdown

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-list<T>, non-empty-array<T> object array with items of T

Inside an array shape:

  • list<T>, non-empty-list<T> and array<int, T> keys become arrays. The comma of array<int, T> no longer splits the shape key in two, because parseObjectLikeArray() now tracks <> depth as well as {}.
  • array<string, T> keys become objects with additionalProperties.
  • mixed keys get the empty schema {}, so they accept any value.

The existing int<min, max> handling moved into the same helper.

Tests: added testMapsPhpStanAndPsalmPseudoTypesToTheirBaseType with a pseudoTypes fixture. It fails before this change and passes after. vendor/bin/phpunit --testsuite unit (2696 tests) passes, as do php-cs-fixer fix --dry-run and phpstan. 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

Comment on lines +833 to +834
if (preg_match('/^(\'[^\']*\'|"[^"]*")$/', $type)) {
return ['string'];
Comment on lines +880 to +882
if (!isset($itemSchema['type'])) {
return 'any';
}
Comment on lines +929 to +932
if ('{' === $char || '<' === $char) {
++$depth;
$buffer .= $char;
} elseif ('}' === $char) {
} elseif ('}' === $char || '>' === $char) {
Comment on lines +1018 to +1020
if (preg_match('/^(?:non-empty-)?array\s*<\s*(?:string|non-empty-string|class-string)\s*,\s*(.+?)\s*>$/is', $type, $matches)) {
return ['type' => 'object', 'additionalProperties' => $this->mapTypeToSchema($matches[1]) ?: true];
}

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.

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

3 participants