Skip to content

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

Closed

Description

@acencyril

Description

Follow-up to #397/#422 and #612/#613: those fixed int<…> ranges and nullable or union keys in shapes, but on main (after #613) other PHPDoc types still fall through to object.

Since #422, int<0, max> maps to integer, but other PHPDoc types that override the native type still fall through to object: non-empty-string, numeric-string, class-string, lowercase-string, positive-int, non-negative-int, array-key, literals ('a'|'b'), non-empty-list<T>, non-empty-array<T>. Inside an array shape, keys typed list<T>, mixed, array<K, V> or any of the above also become object. The tool then rejects every valid call with -32602.

How to reproduce

final class Shop
{
    /** @param non-empty-string $name */
    public function greet(string $name): string
    {
        return "hello $name";
    }

    /** @param array{tags: list<string>} $a */
    public function tag(array $a): string
    {
        return 'ok';
    }
}

// tools/call {"name":"greet","arguments":{"name":"Ada"}}

Actual: -32602 Invalid parameters for tool 'greet': Property '/name': Invalid type. Expected object, but received string. (tag with {"a":{"tags":["x"]}} is rejected the same way.)
Expected: string, and an array of string, as the native type or the PHPStan meaning says.

Possible solution

In SchemaGenerator, when a DocBlock type maps to nothing known, fall back to the native reflection type instead of object (getParameterTypeString(), mapPhpTypeToJsonSchemaType() default), and map the common pseudo-types to their base type. In shapes, mapTypeToSchema() / mapSimpleTypeToJsonSchema() need the same, plus list<T> and a split of shape keys that is aware of <…> (the comma in array<int, string> currently splits the key).

Versions: mcp/sdk main (5d311d6) and v0.9.0, PHP 8.3.

Activity

  1. added a commit that references this issue on Nov 3, 2026
    b98d468
  2. added a commit that references this issue on Nov 3, 2026
    2b336ac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions