1: <?php
2:
3: declare(strict_types=1);
4:
5: /**
6: * This file is part of the Nexus MCP SDK package.
7: *
8: * (c) 2026 John Paul E. Balandan, CPA <paulbalandan@gmail.com>
9: *
10: * For the full copyright and license information, please view
11: * the LICENSE file that was distributed with this source code.
12: */
13:
14: namespace Nexus\Mcp\Server\Attribute;
15:
16: use Nexus\Assert\Assert;
17:
18: /**
19: * JSON Schema constraints for a discovered tool's input, applied at the parameter or method level.
20: */
21: #[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PARAMETER)]
22: final readonly class InputSchema
23: {
24: /**
25: * @param null|non-empty-array<string, mixed> $definition Explicit input schema, advertised verbatim with every top-level JSON Schema 2020-12 keyword preserved
26: * @param null|list<mixed> $enum
27: * @param null|array<string, mixed> $items
28: * @param null|array<string, mixed> $properties
29: * @param null|list<string> $required
30: * @param null|array<string, mixed>|bool $additionalProperties
31: */
32: public function __construct(
33: public ?array $definition = null,
34: public ?string $type = null,
35: public ?string $description = null,
36: public ?array $enum = null,
37: public ?string $format = null,
38: public ?int $minLength = null,
39: public ?int $maxLength = null,
40: public ?string $pattern = null,
41: public null|float|int $minimum = null,
42: public null|float|int $maximum = null,
43: public null|float|int $exclusiveMinimum = null,
44: public null|float|int $exclusiveMaximum = null,
45: public null|float|int $multipleOf = null,
46: public ?array $items = null,
47: public ?int $minItems = null,
48: public ?int $maxItems = null,
49: public ?bool $uniqueItems = null,
50: public ?array $properties = null,
51: public ?array $required = null,
52: public null|array|bool $additionalProperties = null,
53: ) {
54: if (null !== $definition) {
55: Assert::that($definition)->not()->isIdentical([], 'input schema "definition" must not be an empty array.');
56: }
57: }
58:
59: /**
60: * @return array<string, mixed>
61: */
62: public function toArray(): array
63: {
64: if (null !== $this->definition) {
65: return $this->definition;
66: }
67:
68: return array_filter([
69: 'type' => $this->type,
70: 'description' => $this->description,
71: 'enum' => $this->enum,
72: 'format' => $this->format,
73: 'minLength' => $this->minLength,
74: 'maxLength' => $this->maxLength,
75: 'pattern' => $this->pattern,
76: 'minimum' => $this->minimum,
77: 'maximum' => $this->maximum,
78: 'exclusiveMinimum' => $this->exclusiveMinimum,
79: 'exclusiveMaximum' => $this->exclusiveMaximum,
80: 'multipleOf' => $this->multipleOf,
81: 'items' => $this->items,
82: 'minItems' => $this->minItems,
83: 'maxItems' => $this->maxItems,
84: 'uniqueItems' => $this->uniqueItems,
85: 'properties' => $this->properties,
86: 'required' => $this->required,
87: 'additionalProperties' => $this->additionalProperties,
88: ], static fn(mixed $value): bool => null !== $value);
89: }
90: }
91: