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/2025-11-25/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, $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: /**
55: * @param array<string, mixed> $data
56: */
57: #[\Override]
58: public static function fromArray(array $data): static
59: {
60: Assert::that($data)->hasOffset('name', '"arguments" missing the required "name" key.');
61: $name = $data['name'];
62: Assert::that($name)->isString('"arguments.name" must be a string, {type} given.');
63:
64: $title = $data['title'] ?? null;
65: Assert::that($title)->nullOr()->isString('"arguments.title" must be a string or null, {type} given.');
66:
67: $description = $data['description'] ?? null;
68: Assert::that($description)->nullOr()->isString('"arguments.description" must be a string or null, {type} given.');
69:
70: $required = $data['required'] ?? null;
71: Assert::that($required)->nullOr()->isBool('"arguments.required" must be a bool or null, {type} given.');
72:
73: return new self($name, $title, $description, $required);
74: }
75:
76: #[\Override]
77: public function toArray(): array
78: {
79: $data = ['name' => $this->name];
80:
81: if (null !== $this->title) {
82: $data['title'] = $this->title;
83: }
84:
85: if (null !== $this->description) {
86: $data['description'] = $this->description;
87: }
88:
89: if (null !== $this->required) {
90: $data['required'] = $this->required;
91: }
92:
93: return $data;
94: }
95:
96: #[\Override]
97: public function jsonSerialize(): array
98: {
99: return $this->toArray();
100: }
101: }
102: