*/ class ClientCapabilities implements \JsonSerializable { /** * @param array $experimental * @param ?array $extensions protocol extensions the client supports (e.g. io.modelcontextprotocol/ui) * @param ?bool $samplingContext the `sampling.context` sub-capability * @param ?bool $samplingTools the `sampling.tools` sub-capability * * The two sampling sub-capabilities trail `extensions` rather than sitting next to * `sampling` so that existing positional calls keep working. Pass them by name. */ public function __construct( public readonly ?bool $roots = false, public readonly ?bool $rootsListChanged = null, public readonly ?bool $sampling = null, public readonly ?bool $elicitation = null, public readonly ?array $experimental = null, public readonly ?array $extensions = null, public readonly ?bool $samplingContext = null, public readonly ?bool $samplingTools = null, ) { } /** * @param array{ * roots?: array{ * listChanged?: bool, * }, * sampling?: array{context?: mixed, tools?: mixed}|object, * elicitation?: bool, * experimental?: array, * extensions?: array, * } $data */ public static function fromArray(array $data): self { $rootsEnabled = isset($data['roots']); $rootsListChanged = null; if ($rootsEnabled) { if (\is_array($data['roots']) && \array_key_exists('listChanged', $data['roots'])) { $rootsListChanged = (bool) $data['roots']['listChanged']; } elseif (\is_object($data['roots']) && property_exists($data['roots'], 'listChanged')) { $rootsListChanged = (bool) $data['roots']->listChanged; } } $sampling = null; $samplingContext = null; $samplingTools = null; if (isset($data['sampling'])) { $sampling = true; if (\is_array($data['sampling'])) { $samplingContext = isset($data['sampling']['context']); $samplingTools = isset($data['sampling']['tools']); } elseif (\is_object($data['sampling'])) { $samplingContext = property_exists($data['sampling'], 'context'); $samplingTools = property_exists($data['sampling'], 'tools'); } } $elicitation = null; if (isset($data['elicitation'])) { $elicitation = true; } return new self( $rootsEnabled, $rootsListChanged, $sampling, $elicitation, \is_array($data['experimental'] ?? null) ? $data['experimental'] : null, \is_array($data['extensions'] ?? null) ? $data['extensions'] : null, $samplingContext, $samplingTools, ); } /** * @return array{ * roots?: object, * sampling?: object, * elicitation?: object, * experimental?: object, * extensions?: object, * }|\stdClass */ public function jsonSerialize(): array|object { $data = []; if ($this->roots || $this->rootsListChanged) { $data['roots'] = new \stdClass(); if ($this->rootsListChanged) { $data['roots']->listChanged = $this->rootsListChanged; } } if ($this->sampling || $this->samplingContext || $this->samplingTools) { $data['sampling'] = new \stdClass(); if ($this->samplingContext) { $data['sampling']->context = new \stdClass(); } if ($this->samplingTools) { $data['sampling']->tools = new \stdClass(); } } if ($this->elicitation) { $data['elicitation'] = new \stdClass(); } if ($this->experimental) { $data['experimental'] = (object) $this->experimental; } if ($this->extensions) { $data['extensions'] = (object) $this->extensions; } return $data ?: new \stdClass(); } }