1: <?php
2:
3: declare(strict_types=1);
4:
5: /**
6: * This file is part of the Nexus MCP SDK package.
7: *
8: * (c) 2025 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\Schema\Tool\ToolSchema;
15:
16: use Nexus\Mcp\Schema\Arrayable;
17:
18: /**
19: * A JSON schema object defining the expected parameters for the tool or the structure of the tool's output
20: * returned in the `structuredContent` field of a `CallToolResult`.
21: *
22: * @template T
23: * @template U of array<string, mixed>
24: *
25: * @implements Arrayable<U>
26: */
27: abstract class ToolSchema implements \JsonSerializable, Arrayable
28: {
29: /**
30: * @var null|non-empty-string
31: */
32: protected ?string $title = null;
33:
34: /**
35: * @var null|non-empty-string
36: */
37: protected ?string $description = null;
38:
39: /**
40: * @var null|T
41: */
42: protected mixed $default = null;
43:
44: private bool $required = false;
45:
46: /**
47: * @param non-empty-string $name
48: */
49: protected function __construct(
50: public readonly string $name,
51: ) {}
52:
53: /**
54: * Sets the root object of the schema.
55: *
56: * @template Tu
57: * @template Tv of array<string, mixed>
58: *
59: * @param self<covariant Tu, covariant Tv> ...$properties
60: */
61: public static function root(self ...$properties): ObjectType
62: {
63: return new ObjectType('root', ...$properties);
64: }
65:
66: /**
67: * @param non-empty-string $name
68: */
69: public static function asArray(string $name): ArrayType
70: {
71: return new ArrayType($name);
72: }
73:
74: /**
75: * @param non-empty-string $name
76: */
77: public static function asBoolean(string $name): BooleanType
78: {
79: return new BooleanType($name);
80: }
81:
82: /**
83: * @param non-empty-string $name
84: */
85: public static function asInteger(string $name): IntegerType
86: {
87: return new IntegerType($name);
88: }
89:
90: /**
91: * @param non-empty-string $name
92: */
93: public static function asNull(string $name): NullType
94: {
95: return new NullType($name);
96: }
97:
98: /**
99: * @param non-empty-string $name
100: */
101: public static function asNumber(string $name): NumberType
102: {
103: return new NumberType($name);
104: }
105:
106: /**
107: * @template Tu
108: * @template Tv of array<string, mixed>
109: *
110: * @param non-empty-string $name
111: * @param self<covariant Tu, covariant Tv> ...$properties
112: */
113: public static function asObject(string $name, self ...$properties): ObjectType
114: {
115: return new ObjectType($name, ...$properties);
116: }
117:
118: /**
119: * @param non-empty-string $name
120: */
121: public static function asString(string $name): StringType
122: {
123: return new StringType($name);
124: }
125:
126: /**
127: * @param non-empty-string $title
128: */
129: public function title(string $title): static
130: {
131: $this->title = $title;
132:
133: return $this;
134: }
135:
136: /**
137: * @param non-empty-string $description
138: */
139: public function description(string $description): static
140: {
141: $this->description = $description;
142:
143: return $this;
144: }
145:
146: /**
147: * @param T $default
148: */
149: public function default(mixed $default): static
150: {
151: $this->default = $default;
152:
153: return $this;
154: }
155:
156: public function required(): static
157: {
158: $this->required = true;
159:
160: return $this;
161: }
162:
163: public function isRequired(): bool
164: {
165: return $this->required;
166: }
167:
168: /**
169: * @return template-type<static, Arrayable, 'T'>
170: */
171: #[\Override]
172: public function jsonSerialize(): array
173: {
174: return $this->toArray();
175: }
176: }
177: