Introduce schema component
This commit is contained in:
parent
ee0dffe369
commit
6025f890f9
12 changed files with 5419 additions and 0 deletions
126
src/Schema/Result/CallToolResult.php
Normal file
126
src/Schema/Result/CallToolResult.php
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the official PHP MCP SDK.
|
||||
*
|
||||
* A collaboration between Symfony and the PHP Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Mcp\Schema\Result;
|
||||
|
||||
use Mcp\Exception\InvalidArgumentException;
|
||||
use Mcp\Schema\Content\AudioContent;
|
||||
use Mcp\Schema\Content\Content;
|
||||
use Mcp\Schema\Content\EmbeddedResource;
|
||||
use Mcp\Schema\Content\ImageContent;
|
||||
use Mcp\Schema\Content\TextContent;
|
||||
use Mcp\Schema\JsonRpc\Response;
|
||||
use Mcp\Schema\JsonRpc\ResultInterface;
|
||||
|
||||
/**
|
||||
* The server's response to a tool call.
|
||||
*
|
||||
* Any errors that originate from the tool SHOULD be reported inside the result
|
||||
* object, with `isError` set to true, _not_ as an MCP protocol-level error
|
||||
* response. Otherwise, the LLM would not be able to see that an error occurred
|
||||
* and self-correct.
|
||||
*
|
||||
* However, any errors in _finding_ the tool, an error indicating that the
|
||||
* server does not support tool calls, or any other exceptional conditions,
|
||||
* should be reported as an MCP error response.
|
||||
*
|
||||
* @phpstan-import-type TextContentData from TextContent
|
||||
* @phpstan-import-type ImageContentData from ImageContent
|
||||
* @phpstan-import-type AudioContentData from AudioContent
|
||||
* @phpstan-import-type EmbeddedResourceData from EmbeddedResource
|
||||
*
|
||||
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
|
||||
*/
|
||||
class CallToolResult implements ResultInterface
|
||||
{
|
||||
/**
|
||||
* Create a new CallToolResult.
|
||||
*
|
||||
* @param array<TextContent|ImageContent|AudioContent|EmbeddedResource> $content The content of the tool result
|
||||
* @param bool $isError Whether the tool execution resulted in an error. If not set, this is assumed to be false (the call was successful).
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly array $content,
|
||||
public readonly bool $isError = false,
|
||||
) {
|
||||
foreach ($this->content as $item) {
|
||||
if (!$item instanceof Content) {
|
||||
throw new InvalidArgumentException('Content must be an array of Content objects.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CallToolResult with success status.
|
||||
*
|
||||
* @param array<TextContent|ImageContent|AudioContent|EmbeddedResource> $content The content of the tool result
|
||||
*/
|
||||
public static function success(array $content): self
|
||||
{
|
||||
return new self($content, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CallToolResult with error status.
|
||||
*
|
||||
* @param array<TextContent|ImageContent|AudioContent|EmbeddedResource> $content The content of the tool result
|
||||
*/
|
||||
public static function error(array $content): self
|
||||
{
|
||||
return new self($content, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{
|
||||
* content: array<TextContentData|ImageContentData|AudioContentData|EmbeddedResourceData>,
|
||||
* isError?: bool,
|
||||
* } $data
|
||||
*/
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
if (!isset($data['content']) || !\is_array($data['content'])) {
|
||||
throw new InvalidArgumentException('Missing or invalid "content" array in CallToolResult data.');
|
||||
}
|
||||
|
||||
$contents = [];
|
||||
|
||||
foreach ($data['content'] as $item) {
|
||||
$contents[] = match ($item['type'] ?? null) {
|
||||
'text' => TextContent::fromArray($item),
|
||||
'image' => ImageContent::fromArray($item),
|
||||
'audio' => AudioContent::fromArray($item),
|
||||
'resource' => EmbeddedResource::fromArray($item),
|
||||
default => throw new InvalidArgumentException(\sprintf('Invalid content type in CallToolResult data: "%s".', $item['type'] ?? null)),
|
||||
};
|
||||
}
|
||||
|
||||
return new self($contents, $data['isError'] ?? false);
|
||||
}
|
||||
|
||||
public static function fromResponse(Response $response): self
|
||||
{
|
||||
return self::fromArray($response->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* content: array<TextContent|ImageContent|AudioContent|EmbeddedResource>,
|
||||
* isError: bool,
|
||||
* }
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'content' => $this->content,
|
||||
'isError' => $this->isError,
|
||||
];
|
||||
}
|
||||
}
|
||||
63
src/Schema/Result/CompletionCompleteResult.php
Normal file
63
src/Schema/Result/CompletionCompleteResult.php
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the official PHP MCP SDK.
|
||||
*
|
||||
* A collaboration between Symfony and the PHP Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Mcp\Schema\Result;
|
||||
|
||||
use Mcp\Exception\InvalidArgumentException;
|
||||
use Mcp\Schema\JsonRpc\ResultInterface;
|
||||
|
||||
/**
|
||||
* The server's response to a completion/complete request.
|
||||
*
|
||||
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
|
||||
*/
|
||||
class CompletionCompleteResult implements ResultInterface
|
||||
{
|
||||
/**
|
||||
* @param string[] $values An array of completion values. Must not exceed 100 items.
|
||||
* @param int|null $total The total number of completion options available. This can exceed the number of values actually sent in the response.
|
||||
* @param bool|null $hasMore indicates whether there are additional completion options beyond those provided in the current response, even if the exact total is unknown
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly array $values,
|
||||
public readonly ?int $total = null,
|
||||
public readonly ?bool $hasMore = null,
|
||||
) {
|
||||
if (\count($this->values) > 100) {
|
||||
throw new InvalidArgumentException('Values must not exceed 100 items');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* completion: array{
|
||||
* values: string[],
|
||||
* total?: int,
|
||||
* hasMore?: bool,
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
$completion = [
|
||||
'values' => $this->values,
|
||||
];
|
||||
|
||||
if (null !== $this->total) {
|
||||
$completion['total'] = $this->total;
|
||||
}
|
||||
if (null !== $this->hasMore) {
|
||||
$completion['hasMore'] = $this->hasMore;
|
||||
}
|
||||
|
||||
return ['completion' => $completion];
|
||||
}
|
||||
}
|
||||
65
src/Schema/Result/CreateSamplingMessageResult.php
Normal file
65
src/Schema/Result/CreateSamplingMessageResult.php
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the official PHP MCP SDK.
|
||||
*
|
||||
* A collaboration between Symfony and the PHP Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Mcp\Schema\Result;
|
||||
|
||||
use Mcp\Schema\Content\AudioContent;
|
||||
use Mcp\Schema\Content\ImageContent;
|
||||
use Mcp\Schema\Content\TextContent;
|
||||
use Mcp\Schema\Enum\Role;
|
||||
use Mcp\Schema\JsonRpc\ResultInterface;
|
||||
|
||||
/**
|
||||
* The client's response to a sampling/create_message request from the server. The client should inform the user before
|
||||
* returning the sampled message, to allow them to inspect the response (human in the loop) and decide whether to allow
|
||||
* the server to see it.
|
||||
*
|
||||
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
|
||||
*/
|
||||
class CreateSamplingMessageResult implements ResultInterface
|
||||
{
|
||||
/**
|
||||
* @param Role $role the role of the message
|
||||
* @param TextContent|ImageContent|AudioContent $content the content of the message
|
||||
* @param string $model the name of the model that generated the message
|
||||
* @param string|null $stopReason the reason why sampling stopped, if known
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly Role $role,
|
||||
public readonly TextContent|ImageContent|AudioContent $content,
|
||||
public readonly string $model,
|
||||
public readonly ?string $stopReason = null,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* role: string,
|
||||
* content: TextContent|ImageContent|AudioContent,
|
||||
* model: string,
|
||||
* stopReason?: string,
|
||||
* }
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
$result = [
|
||||
'role' => $this->role->value,
|
||||
'content' => $this->content,
|
||||
'model' => $this->model,
|
||||
];
|
||||
|
||||
if (null !== $this->stopReason) {
|
||||
$result['stopReason'] = $this->stopReason;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
39
src/Schema/Result/EmptyResult.php
Normal file
39
src/Schema/Result/EmptyResult.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the official PHP MCP SDK.
|
||||
*
|
||||
* A collaboration between Symfony and the PHP Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Mcp\Schema\Result;
|
||||
|
||||
use Mcp\Schema\JsonRpc\ResultInterface;
|
||||
|
||||
/**
|
||||
* A generic empty result that indicates success but carries no data.
|
||||
*
|
||||
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
|
||||
*/
|
||||
class EmptyResult implements ResultInterface
|
||||
{
|
||||
/**
|
||||
* Create a new EmptyResult.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static function fromArray(): self
|
||||
{
|
||||
return new self();
|
||||
}
|
||||
|
||||
public function jsonSerialize(): \stdClass
|
||||
{
|
||||
return new \stdClass();
|
||||
}
|
||||
}
|
||||
86
src/Schema/Result/GetPromptResult.php
Normal file
86
src/Schema/Result/GetPromptResult.php
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the official PHP MCP SDK.
|
||||
*
|
||||
* A collaboration between Symfony and the PHP Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Mcp\Schema\Result;
|
||||
|
||||
use Mcp\Exception\InvalidArgumentException;
|
||||
use Mcp\Schema\Content\PromptMessage;
|
||||
use Mcp\Schema\JsonRpc\Response;
|
||||
use Mcp\Schema\JsonRpc\ResultInterface;
|
||||
|
||||
/**
|
||||
* @phpstan-import-type PromptMessageData from PromptMessage
|
||||
*
|
||||
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
|
||||
*/
|
||||
class GetPromptResult implements ResultInterface
|
||||
{
|
||||
/**
|
||||
* Create a new GetPromptResult.
|
||||
*
|
||||
* @param PromptMessage[] $messages The messages in the prompt
|
||||
* @param string|null $description Optional description of the prompt
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly array $messages,
|
||||
public readonly ?string $description = null,
|
||||
) {
|
||||
foreach ($this->messages as $message) {
|
||||
if (!$message instanceof PromptMessage) {
|
||||
throw new InvalidArgumentException('Messages must be an array of PromptMessage objects.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{
|
||||
* messages: array<PromptMessageData>,
|
||||
* description?: string,
|
||||
* } $data
|
||||
*/
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
if (!isset($data['messages']) || !\is_array($data['messages'])) {
|
||||
throw new InvalidArgumentException('Missing or invalid "messages" array in GetPromptResult data.');
|
||||
}
|
||||
|
||||
$messages = [];
|
||||
foreach ($data['messages'] as $message) {
|
||||
$messages[] = PromptMessage::fromArray($message);
|
||||
}
|
||||
|
||||
return new self($messages, $data['description'] ?? null);
|
||||
}
|
||||
|
||||
public static function fromResponse(Response $response): self
|
||||
{
|
||||
return self::fromArray($response->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* messages: array<PromptMessage>,
|
||||
* description?: string,
|
||||
* }
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
$result = [
|
||||
'messages' => $this->messages,
|
||||
];
|
||||
|
||||
if (null !== $this->description) {
|
||||
$result['description'] = $this->description;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
103
src/Schema/Result/InitializeResult.php
Normal file
103
src/Schema/Result/InitializeResult.php
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the official PHP MCP SDK.
|
||||
*
|
||||
* A collaboration between Symfony and the PHP Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Mcp\Schema\Result;
|
||||
|
||||
use Mcp\Exception\InvalidArgumentException;
|
||||
use Mcp\Schema\Constants;
|
||||
use Mcp\Schema\Implementation;
|
||||
use Mcp\Schema\JsonRpc\Response;
|
||||
use Mcp\Schema\JsonRpc\ResultInterface;
|
||||
use Mcp\Schema\ServerCapabilities;
|
||||
|
||||
/**
|
||||
* After receiving an initialize request from the client, the server sends this response.
|
||||
*
|
||||
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
|
||||
*/
|
||||
class InitializeResult implements ResultInterface
|
||||
{
|
||||
/**
|
||||
* Create a new InitializeResult.
|
||||
*
|
||||
* @param ServerCapabilities $capabilities the capabilities of the server
|
||||
* @param Implementation $serverInfo information about the server
|
||||
* @param string|null $instructions Instructions describing how to use the server and its features. This can be used by clients to improve the LLM's understanding of available tools, resources, etc. It can be thought of like a "hint" to the model. For example, this information MAY be added to the system prompt.
|
||||
* @param array<string,mixed>|null $_meta optional _meta field
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly ServerCapabilities $capabilities,
|
||||
public readonly Implementation $serverInfo,
|
||||
public readonly ?string $instructions = null,
|
||||
public readonly ?array $_meta = null,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{
|
||||
* protocolVersion: string,
|
||||
* capabilities: array<string, mixed>,
|
||||
* serverInfo: array<string, mixed>,
|
||||
* instructions?: string,
|
||||
* _meta?: array<string, mixed>,
|
||||
* } $data
|
||||
*/
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
if (!isset($data['protocolVersion']) || !\is_string($data['protocolVersion'])) {
|
||||
throw new InvalidArgumentException('Missing or invalid "protocolVersion".');
|
||||
}
|
||||
if (!isset($data['capabilities']) || !\is_array($data['capabilities'])) {
|
||||
throw new InvalidArgumentException('Missing or invalid "capabilities".');
|
||||
}
|
||||
if (!isset($data['serverInfo']) || !\is_array($data['serverInfo'])) {
|
||||
throw new InvalidArgumentException('Missing or invalid "serverInfo".');
|
||||
}
|
||||
|
||||
return new self(
|
||||
ServerCapabilities::fromArray($data['capabilities']),
|
||||
Implementation::fromArray($data['serverInfo']),
|
||||
$data['instructions'] ?? null,
|
||||
$data['_meta'] ?? null
|
||||
);
|
||||
}
|
||||
|
||||
public static function fromResponse(Response $response): self
|
||||
{
|
||||
return self::fromArray($response->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* protocolVersion: string,
|
||||
* capabilities: ServerCapabilities,
|
||||
* serverInfo: Implementation,
|
||||
* instructions?: string,
|
||||
* _meta?: array<string, mixed>,
|
||||
* }
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
$data = [
|
||||
'protocolVersion' => Constants::JSONRPC_VERSION,
|
||||
'capabilities' => $this->capabilities,
|
||||
'serverInfo' => $this->serverInfo,
|
||||
];
|
||||
if (null !== $this->instructions) {
|
||||
$data['instructions'] = $this->instructions;
|
||||
}
|
||||
if (null !== $this->_meta) {
|
||||
$data['_meta'] = $this->_meta;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
81
src/Schema/Result/ListPromptsResult.php
Normal file
81
src/Schema/Result/ListPromptsResult.php
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the official PHP MCP SDK.
|
||||
*
|
||||
* A collaboration between Symfony and the PHP Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Mcp\Schema\Result;
|
||||
|
||||
use Mcp\Exception\InvalidArgumentException;
|
||||
use Mcp\Schema\JsonRpc\Response;
|
||||
use Mcp\Schema\JsonRpc\ResultInterface;
|
||||
use Mcp\Schema\Prompt;
|
||||
|
||||
/**
|
||||
* The server's response to a prompts/list request from the client.
|
||||
*
|
||||
* @phpstan-import-type PromptData from Prompt
|
||||
*
|
||||
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
|
||||
*/
|
||||
class ListPromptsResult implements ResultInterface
|
||||
{
|
||||
/**
|
||||
* @param array<Prompt> $prompts the list of prompt definitions
|
||||
* @param string|null $nextCursor An opaque token representing the pagination position after the last returned result.
|
||||
*
|
||||
* If present, there may be more results available.
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly array $prompts,
|
||||
public readonly ?string $nextCursor = null,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{
|
||||
* prompts: array<PromptData>,
|
||||
* nextCursor?: string,
|
||||
* } $data
|
||||
*/
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
if (!isset($data['prompts']) || !\is_array($data['prompts'])) {
|
||||
throw new InvalidArgumentException('Missing or invalid "prompts" array in ListPromptsResult data.');
|
||||
}
|
||||
|
||||
return new self(
|
||||
array_map(fn (array $prompt) => Prompt::fromArray($prompt), $data['prompts']),
|
||||
$data['nextCursor'] ?? null
|
||||
);
|
||||
}
|
||||
|
||||
public static function fromResponse(Response $response): self
|
||||
{
|
||||
return self::fromArray($response->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* prompts: array<Prompt>,
|
||||
* nextCursor?: string,
|
||||
* }
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
$result = [
|
||||
'prompts' => $this->prompts,
|
||||
];
|
||||
|
||||
if ($this->nextCursor) {
|
||||
$result['nextCursor'] = $this->nextCursor;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
81
src/Schema/Result/ListResourceTemplatesResult.php
Normal file
81
src/Schema/Result/ListResourceTemplatesResult.php
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the official PHP MCP SDK.
|
||||
*
|
||||
* A collaboration between Symfony and the PHP Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Mcp\Schema\Result;
|
||||
|
||||
use Mcp\Exception\InvalidArgumentException;
|
||||
use Mcp\Schema\JsonRpc\Response;
|
||||
use Mcp\Schema\JsonRpc\ResultInterface;
|
||||
use Mcp\Schema\ResourceTemplate;
|
||||
|
||||
/**
|
||||
* The server's response to a resources/templates/list request from the client.
|
||||
*
|
||||
* @phpstan-import-type ResourceTemplateData from ResourceTemplate
|
||||
*
|
||||
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
|
||||
*/
|
||||
class ListResourceTemplatesResult implements ResultInterface
|
||||
{
|
||||
/**
|
||||
* @param array<ResourceTemplate> $resourceTemplates the list of resource template definitions
|
||||
* @param string|null $nextCursor An opaque token representing the pagination position after the last returned result.
|
||||
*
|
||||
* If present, there may be more results available.
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly array $resourceTemplates,
|
||||
public readonly ?string $nextCursor = null,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{
|
||||
* resourceTemplates: array<ResourceTemplateData>,
|
||||
* nextCursor?: string
|
||||
* } $data
|
||||
*/
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
if (!isset($data['resourceTemplates']) || !\is_array($data['resourceTemplates'])) {
|
||||
throw new InvalidArgumentException('Missing or invalid "resourceTemplates" array in ListResourceTemplatesResult data.');
|
||||
}
|
||||
|
||||
return new self(
|
||||
array_map(fn (array $resourceTemplate) => ResourceTemplate::fromArray($resourceTemplate), $data['resourceTemplates']),
|
||||
$data['nextCursor'] ?? null
|
||||
);
|
||||
}
|
||||
|
||||
public static function fromResponse(Response $response): self
|
||||
{
|
||||
return self::fromArray($response->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* resourceTemplates: array<ResourceTemplate>,
|
||||
* nextCursor?: string,
|
||||
* }
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
$result = [
|
||||
'resourceTemplates' => $this->resourceTemplates,
|
||||
];
|
||||
|
||||
if ($this->nextCursor) {
|
||||
$result['nextCursor'] = $this->nextCursor;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
81
src/Schema/Result/ListResourcesResult.php
Normal file
81
src/Schema/Result/ListResourcesResult.php
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the official PHP MCP SDK.
|
||||
*
|
||||
* A collaboration between Symfony and the PHP Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Mcp\Schema\Result;
|
||||
|
||||
use Mcp\Exception\InvalidArgumentException;
|
||||
use Mcp\Schema\JsonRpc\Response;
|
||||
use Mcp\Schema\JsonRpc\ResultInterface;
|
||||
use Mcp\Schema\Resource;
|
||||
|
||||
/**
|
||||
* The server's response to a resources/list request from the client.
|
||||
*
|
||||
* @phpstan-import-type ResourceData from Resource
|
||||
*
|
||||
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
|
||||
*/
|
||||
class ListResourcesResult implements ResultInterface
|
||||
{
|
||||
/**
|
||||
* @param array<resource> $resources the list of resource definitions
|
||||
* @param string|null $nextCursor An opaque token representing the pagination position after the last returned result.
|
||||
*
|
||||
* If present, there may be more results available.
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly array $resources,
|
||||
public readonly ?string $nextCursor = null,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{
|
||||
* resources: array<ResourceData>,
|
||||
* nextCursor?: string,
|
||||
* } $data
|
||||
*/
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
if (!isset($data['resources']) || !\is_array($data['resources'])) {
|
||||
throw new InvalidArgumentException('Missing or invalid "resources" array in ListResourcesResult data.');
|
||||
}
|
||||
|
||||
return new self(
|
||||
array_map(fn (array $resource) => Resource::fromArray($resource), $data['resources']),
|
||||
$data['nextCursor'] ?? null
|
||||
);
|
||||
}
|
||||
|
||||
public static function fromResponse(Response $response): self
|
||||
{
|
||||
return self::fromArray($response->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* resources: array<resource>,
|
||||
* nextCursor?: string,
|
||||
* }
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
$result = [
|
||||
'resources' => $this->resources,
|
||||
];
|
||||
|
||||
if (null !== $this->nextCursor) {
|
||||
$result['nextCursor'] = $this->nextCursor;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
54
src/Schema/Result/ListRootsResult.php
Normal file
54
src/Schema/Result/ListRootsResult.php
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the official PHP MCP SDK.
|
||||
*
|
||||
* A collaboration between Symfony and the PHP Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Mcp\Schema\Result;
|
||||
|
||||
use Mcp\Schema\JsonRpc\ResultInterface;
|
||||
use Mcp\Schema\Root;
|
||||
|
||||
/**
|
||||
* The client's response to a roots/list request from the server.
|
||||
* This result contains an array of Root objects, each representing a root directory
|
||||
* or file that the server can operate on.
|
||||
*
|
||||
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
|
||||
*/
|
||||
class ListRootsResult implements ResultInterface
|
||||
{
|
||||
/**
|
||||
* @param Root[] $roots an array of root URIs
|
||||
* @param ?array<string, mixed> $_meta optional metadata about the result
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly array $roots,
|
||||
public readonly ?array $_meta = null,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* roots: Root[],
|
||||
* _meta?: ?array<string, mixed>
|
||||
* }
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
$result = [
|
||||
'roots' => $this->roots,
|
||||
];
|
||||
|
||||
if (null !== $this->_meta) {
|
||||
$result['_meta'] = $this->_meta;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
81
src/Schema/Result/ListToolsResult.php
Normal file
81
src/Schema/Result/ListToolsResult.php
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the official PHP MCP SDK.
|
||||
*
|
||||
* A collaboration between Symfony and the PHP Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Mcp\Schema\Result;
|
||||
|
||||
use Mcp\Exception\InvalidArgumentException;
|
||||
use Mcp\Schema\JsonRpc\Response;
|
||||
use Mcp\Schema\JsonRpc\ResultInterface;
|
||||
use Mcp\Schema\Tool;
|
||||
|
||||
/**
|
||||
* The server's response to a tools/list request from the client.
|
||||
*
|
||||
* @phpstan-import-type ToolData from Tool
|
||||
*
|
||||
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
|
||||
*/
|
||||
class ListToolsResult implements ResultInterface
|
||||
{
|
||||
/**
|
||||
* @param array<Tool> $tools the list of tool definitions
|
||||
* @param string|null $nextCursor An opaque token representing the pagination position after the last returned result.
|
||||
*
|
||||
* If present, there may be more results available.
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly array $tools,
|
||||
public readonly ?string $nextCursor = null,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{
|
||||
* tools: array<ToolData>,
|
||||
* nextCursor?: string,
|
||||
* } $data
|
||||
*/
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
if (!isset($data['tools']) || !\is_array($data['tools'])) {
|
||||
throw new InvalidArgumentException('Missing or invalid "tools" array in ListToolsResult data.');
|
||||
}
|
||||
|
||||
return new self(
|
||||
array_map(fn (array $tool) => Tool::fromArray($tool), $data['tools']),
|
||||
$data['nextCursor'] ?? null
|
||||
);
|
||||
}
|
||||
|
||||
public static function fromResponse(Response $response): self
|
||||
{
|
||||
return self::fromArray($response->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* tools: array<Tool>,
|
||||
* nextCursor?: string,
|
||||
* }
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
$result = [
|
||||
'tools' => $this->tools,
|
||||
];
|
||||
|
||||
if ($this->nextCursor) {
|
||||
$result['nextCursor'] = $this->nextCursor;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
81
src/Schema/Result/ReadResourceResult.php
Normal file
81
src/Schema/Result/ReadResourceResult.php
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the official PHP MCP SDK.
|
||||
*
|
||||
* A collaboration between Symfony and the PHP Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Mcp\Schema\Result;
|
||||
|
||||
use Mcp\Exception\InvalidArgumentException;
|
||||
use Mcp\Schema\Content\BlobResourceContents;
|
||||
use Mcp\Schema\Content\TextResourceContents;
|
||||
use Mcp\Schema\JsonRpc\Response;
|
||||
use Mcp\Schema\JsonRpc\ResultInterface;
|
||||
|
||||
/**
|
||||
* The server's response to a resources/read request from the client.
|
||||
*
|
||||
* @phpstan-import-type TextResourceContentsData from TextResourceContents
|
||||
* @phpstan-import-type BlobResourceContentsData from BlobResourceContents
|
||||
*
|
||||
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
|
||||
*/
|
||||
class ReadResourceResult implements ResultInterface
|
||||
{
|
||||
/**
|
||||
* Create a new ReadResourceResult.
|
||||
*
|
||||
* @param array<TextResourceContents|BlobResourceContents> $contents The contents of the resource
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly array $contents,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{
|
||||
* contents: array<TextResourceContentsData|BlobResourceContentsData>,
|
||||
* } $data
|
||||
*/
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
if (!isset($data['contents']) || !\is_array($data['contents'])) {
|
||||
throw new InvalidArgumentException('Missing or invalid "contents" array in ReadResourceResult data.');
|
||||
}
|
||||
|
||||
$contents = [];
|
||||
foreach ($data['contents'] as $content) {
|
||||
if (isset($content['text'])) {
|
||||
$contents[] = TextResourceContents::fromArray($content);
|
||||
} elseif (isset($content['blob'])) {
|
||||
$contents[] = BlobResourceContents::fromArray($content);
|
||||
} else {
|
||||
throw new InvalidArgumentException('Invalid content type in ReadResourceResult data: '.json_encode($content));
|
||||
}
|
||||
}
|
||||
|
||||
return new self($contents);
|
||||
}
|
||||
|
||||
public static function fromResponse(Response $response): self
|
||||
{
|
||||
return self::fromArray($response->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* contents: array<BlobResourceContents|TextResourceContents>,
|
||||
* }
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'contents' => $this->contents,
|
||||
];
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue