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\Core\Schema\Prompt;
15:
16: use Nexus\Assert\Assert;
17: use Nexus\Mcp\Core\Schema\Arrayable;
18: use Nexus\Mcp\Core\Schema\BaseMetadata;
19: use Nexus\Mcp\Core\Validation\IdentifierNameValidator;
20:
21: /**
22: * Describes an argument that a prompt can accept.
23: *
24: * @implements Arrayable<array{
25: * name: non-empty-string,
26: * title?: non-empty-string,
27: * description?: non-empty-string,
28: * required?: bool,
29: * }>
30: *
31: * @see https://modelcontextprotocol.io/specification/draft/schema#promptargument
32: */
33: final readonly class PromptArgument extends BaseMetadata implements Arrayable
34: {
35: /**
36: * @var null|non-empty-string
37: */
38: public ?string $description;
39:
40: public function __construct(
41: string $name,
42: ?string $title = null,
43: ?string $description = null,
44: public ?bool $required = null,
45: ) {
46: parent::__construct(name: $name, title: $title);
47:
48: IdentifierNameValidator::validate($name, '"arguments.name"');
49: Assert::that($description)->nullOr()->isNonEmptyString('"arguments.description" must be a non-empty string or null.');
50:
51: $this->description = $description;
52: }
53:
54: #[\Override]
55: public static function fromArray(array $data): static
56: {
57: Assert::that($data)->hasOffset('name', '"arguments" is missing the required "name" key.');
58: $name = $data['name'];
59: Assert::that($name)->isString('"arguments.name" must be a string, {type} given.');
60:
61: $title = $data['title'] ?? null;
62: Assert::that($title)->nullOr()->isString('"arguments.title" must be a string or null, {type} given.');
63:
64: $description = $data['description'] ?? null;
65: Assert::that($description)->nullOr()->isString('"arguments.description" must be a string or null, {type} given.');
66:
67: $required = $data['required'] ?? null;
68: Assert::that($required)->nullOr()->isBool('"arguments.required" must be a bool or null, {type} given.');
69:
70: return new self(name: $name, title: $title, description: $description, required: $required);
71: }
72:
73: #[\Override]
74: public function toArray(): array
75: {
76: $data = ['name' => $this->name];
77:
78: if (null !== $this->title) {
79: $data['title'] = $this->title;
80: }
81:
82: if (null !== $this->description) {
83: $data['description'] = $this->description;
84: }
85:
86: if (null !== $this->required) {
87: $data['required'] = $this->required;
88: }
89:
90: return $data;
91: }
92:
93: #[\Override]
94: public function jsonSerialize(): array
95: {
96: return $this->toArray();
97: }
98: }
99: