Fix return type in abstract methods from self to static (#53)

* Change return type of abstract request methods

* Change return type of `fromParams` method to `static` in request classes

(cherry picked from commit 94799ab66ff60d4b2305aadb6b73aaa4c805221e)

* Make request classes final and update `getParams` return types for improved type safety

(cherry picked from commit d6be496f89cc0e6d30f519792d0dc902685c4178)
This commit is contained in:
Igor Markin 2025-09-09 19:22:29 +03:00 • committed by GitHub
commit 20e789d402
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 97 additions and 46 deletions

View file

@ -36,7 +36,7 @@ abstract class Request implements HasMethodInterface, MessageInterface
/**
* @param RequestData $data
*/
public static function fromArray(array $data): self
public static function fromArray(array $data): static
{
if (($data['jsonrpc'] ?? null) !== MessageInterface::JSONRPC_VERSION) {
throw new InvalidArgumentException('Invalid or missing "jsonrpc" version for Request.');
@ -68,7 +68,7 @@ abstract class Request implements HasMethodInterface, MessageInterface
/**
* @param array<string, mixed>|null $params
*/
abstract protected static function fromParams(?array $params): self;
abstract protected static function fromParams(?array $params): static;
public function getId(): string|int
{
@ -97,7 +97,7 @@ abstract class Request implements HasMethodInterface, MessageInterface
}
/**
* @return array<string, mixed>|null
* @return array<non-empty-string, mixed>|null
*/
abstract protected function getParams(): ?array;
}

View file

@ -19,7 +19,7 @@ use Mcp\Schema\JsonRpc\Request;
*
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
*/
class CallToolRequest extends Request
final class CallToolRequest extends Request
{
/**
* @param string $name the name of the tool to invoke
@ -36,7 +36,7 @@ class CallToolRequest extends Request
return 'tools/call';
}
protected static function fromParams(?array $params): Request
protected static function fromParams(?array $params): static
{
if (!isset($params['name']) || !\is_string($params['name'])) {
throw new InvalidArgumentException('Missing or invalid "name" parameter for tools/call.');
@ -58,7 +58,10 @@ class CallToolRequest extends Request
);
}
protected function getParams(): ?array
/**
* @return array{name: string, arguments: array<string, mixed>}
*/
protected function getParams(): array
{
return [
'name' => $this->name,

View file

@ -21,7 +21,7 @@ use Mcp\Schema\ResourceReference;
*
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
*/
class CompletionCompleteRequest extends Request
final class CompletionCompleteRequest extends Request
{
/**
* @param PromptReference|ResourceReference $ref the prompt or resource to complete
@ -38,7 +38,7 @@ class CompletionCompleteRequest extends Request
return 'completion/complete';
}
protected static function fromParams(?array $params): Request
protected static function fromParams(?array $params): static
{
if (!isset($params['ref']) || !\is_array($params['ref'])) {
throw new InvalidArgumentException('Missing or invalid "ref" parameter for completion/complete.');
@ -57,7 +57,13 @@ class CompletionCompleteRequest extends Request
return new self($ref, $params['argument']);
}
protected function getParams(): ?array
/**
* @return array{
* ref: PromptReference|ResourceReference,
* argument: array{ name: string, value: string }
* }
*/
protected function getParams(): array
{
return [
'ref' => $this->ref,

View file

@ -23,7 +23,7 @@ use Mcp\Schema\ModelPreferences;
*
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
*/
class CreateSamplingMessageRequest extends Request
final class CreateSamplingMessageRequest extends Request
{
/**
* @param SamplingMessage[] $messages the messages to send to the model
@ -59,7 +59,7 @@ class CreateSamplingMessageRequest extends Request
return 'sampling/createMessage';
}
protected static function fromParams(?array $params): Request
protected static function fromParams(?array $params): static
{
if (!isset($params['messages']) || !\is_array($params['messages'])) {
throw new InvalidArgumentException('Missing or invalid "messages" parameter for sampling/createMessage.');
@ -86,7 +86,19 @@ class CreateSamplingMessageRequest extends Request
);
}
protected function getParams(): ?array
/**
* @return array{
* messages: SamplingMessage[],
* maxTokens: int,
* preferences?: ModelPreferences,
* systemPrompt?: string,
* includeContext?: string,
* temperature?: float,
* stopSequences?: string[],
* metadata?: array<string, mixed>
* }
*/
protected function getParams(): array
{
$params = [
'messages' => $this->messages,

View file

@ -19,7 +19,7 @@ use Mcp\Schema\JsonRpc\Request;
*
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
*/
class GetPromptRequest extends Request
final class GetPromptRequest extends Request
{
/**
* @param string $name the name of the prompt to get
@ -36,7 +36,7 @@ class GetPromptRequest extends Request
return 'prompts/get';
}
protected static function fromParams(?array $params): Request
protected static function fromParams(?array $params): static
{
if (!isset($params['name']) || !\is_string($params['name']) || empty($params['name'])) {
throw new InvalidArgumentException('Missing or invalid "name" parameter for prompts/get.');
@ -55,7 +55,10 @@ class GetPromptRequest extends Request
return new self($params['name'], $arguments);
}
protected function getParams(): ?array
/**
* @return array{name: string, arguments?: array<string, mixed>}
*/
protected function getParams(): array
{
$params = ['name' => $this->name];

View file

@ -21,7 +21,7 @@ use Mcp\Schema\JsonRpc\Request;
*
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
*/
class InitializeRequest extends Request
final class InitializeRequest extends Request
{
/**
* @param string $protocolVersion The latest version of the Model Context Protocol that the client supports. The client MAY decide to support older versions as well.
@ -40,7 +40,7 @@ class InitializeRequest extends Request
return 'initialize';
}
protected static function fromParams(?array $params): Request
protected static function fromParams(?array $params): static
{
if (!isset($params['protocolVersion'])) {
throw new InvalidArgumentException('protocolVersion is required');
@ -59,7 +59,10 @@ class InitializeRequest extends Request
return new self($params['protocolVersion'], $capabilities, $clientInfo);
}
protected function getParams(): ?array
/**
* @return array{protocolVersion: string, capabilities: ClientCapabilities, clientInfo: Implementation}
*/
protected function getParams(): array
{
return [
'protocolVersion' => $this->protocolVersion,

View file

@ -18,7 +18,7 @@ use Mcp\Schema\JsonRpc\Request;
*
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
*/
class ListPromptsRequest extends Request
final class ListPromptsRequest extends Request
{
/**
* If provided, the server should return results starting after this cursor.
@ -35,11 +35,14 @@ class ListPromptsRequest extends Request
return 'prompts/list';
}
protected static function fromParams(?array $params): Request
protected static function fromParams(?array $params): static
{
return new self($params['cursor'] ?? null);
}
/**
* @return array{cursor:string}|null
*/
protected function getParams(): ?array
{
$params = [];

View file

@ -18,7 +18,7 @@ use Mcp\Schema\JsonRpc\Request;
*
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
*/
class ListResourceTemplatesRequest extends Request
final class ListResourceTemplatesRequest extends Request
{
/**
* @param string|null $cursor An opaque token representing the current pagination position.
@ -35,11 +35,14 @@ class ListResourceTemplatesRequest extends Request
return 'resources/templates/list';
}
protected static function fromParams(?array $params): Request
protected static function fromParams(?array $params): static
{
return new self($params['cursor'] ?? null);
}
/**
* @return array{cursor:string}|null
*/
protected function getParams(): ?array
{
$params = [];

View file

@ -18,7 +18,7 @@ use Mcp\Schema\JsonRpc\Request;
*
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
*/
class ListResourcesRequest extends Request
final class ListResourcesRequest extends Request
{
/**
* @param string|null $cursor An opaque token representing the current pagination position.
@ -35,11 +35,14 @@ class ListResourcesRequest extends Request
return 'resources/list';
}
protected static function fromParams(?array $params): Request
protected static function fromParams(?array $params): static
{
return new self($params['cursor'] ?? null);
}
/**
* @return array{cursor:string}|null
*/
protected function getParams(): ?array
{
$params = [];

View file

@ -24,7 +24,7 @@ use Mcp\Schema\JsonRpc\Request;
*
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
*/
class ListRootsRequest extends Request
final class ListRootsRequest extends Request
{
public function __construct(
) {
@ -35,7 +35,7 @@ class ListRootsRequest extends Request
return 'roots/list';
}
protected static function fromParams(?array $params): Request
protected static function fromParams(?array $params): static
{
return new self();
}

View file

@ -18,7 +18,7 @@ use Mcp\Schema\JsonRpc\Request;
*
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
*/
class ListToolsRequest extends Request
final class ListToolsRequest extends Request
{
/**
* @param string|null $cursor An opaque token representing the current pagination position.
@ -35,11 +35,14 @@ class ListToolsRequest extends Request
return 'tools/list';
}
protected static function fromParams(?array $params): Request
protected static function fromParams(?array $params): static
{
return new self($params['cursor'] ?? null);
}
/**
* @return array{cursor:string}|null
*/
protected function getParams(): ?array
{
$params = [];

View file

@ -19,14 +19,14 @@ use Mcp\Schema\JsonRpc\Request;
*
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
*/
class PingRequest extends Request
final class PingRequest extends Request
{
public static function getMethod(): string
{
return 'ping';
}
protected static function fromParams(?array $params): Request
protected static function fromParams(?array $params): static
{
return new self();
}

View file

@ -19,10 +19,10 @@ use Mcp\Schema\JsonRpc\Request;
*
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
*/
class ReadResourceRequest extends Request
final class ReadResourceRequest extends Request
{
/**
* @param string $uri the URI of the resource to read
* @param non-empty-string $uri the URI of the resource to read
*/
public function __construct(
public readonly string $uri,
@ -34,7 +34,7 @@ class ReadResourceRequest extends Request
return 'resources/read';
}
protected static function fromParams(?array $params): Request
protected static function fromParams(?array $params): static
{
if (!isset($params['uri']) || !\is_string($params['uri']) || empty($params['uri'])) {
throw new InvalidArgumentException('Missing or invalid "uri" parameter for resources/read.');
@ -43,7 +43,10 @@ class ReadResourceRequest extends Request
return new self($params['uri']);
}
protected function getParams(): ?array
/**
* @return array{uri: non-empty-string}
*/
protected function getParams(): array
{
return [
'uri' => $this->uri,

View file

@ -20,10 +20,10 @@ use Mcp\Schema\JsonRpc\Request;
*
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
*/
class ResourceSubscribeRequest extends Request
final class ResourceSubscribeRequest extends Request
{
/**
* @param string $uri the URI of the resource to subscribe to
* @param non-empty-string $uri the URI of the resource to subscribe to
*/
public function __construct(
public readonly string $uri,
@ -35,7 +35,7 @@ class ResourceSubscribeRequest extends Request
return 'resources/subscribe';
}
protected static function fromParams(?array $params): Request
protected static function fromParams(?array $params): static
{
if (!isset($params['uri']) || !\is_string($params['uri']) || empty($params['uri'])) {
throw new InvalidArgumentException('Missing or invalid "uri" parameter for resources/subscribe.');
@ -44,7 +44,10 @@ class ResourceSubscribeRequest extends Request
return new self($params['uri']);
}
protected function getParams(): ?array
/**
* @return array{uri: non-empty-string}
*/
protected function getParams(): array
{
return ['uri' => $this->uri];
}

View file

@ -20,10 +20,10 @@ use Mcp\Schema\JsonRpc\Request;
*
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
*/
class ResourceUnsubscribeRequest extends Request
final class ResourceUnsubscribeRequest extends Request
{
/**
* @param string $uri the URI of the resource to unsubscribe from
* @param non-empty-string $uri the URI of the resource to unsubscribe from
*/
public function __construct(
public readonly string $uri,
@ -35,7 +35,7 @@ class ResourceUnsubscribeRequest extends Request
return 'resources/unsubscribe';
}
protected static function fromParams(?array $params): Request
protected static function fromParams(?array $params): static
{
if (!isset($params['uri']) || !\is_string($params['uri']) || empty($params['uri'])) {
throw new InvalidArgumentException('Missing or invalid "uri" parameter for resources/unsubscribe.');
@ -44,7 +44,10 @@ class ResourceUnsubscribeRequest extends Request
return new self($params['uri']);
}
protected function getParams(): ?array
/**
* @return array{uri: non-empty-string}
*/
protected function getParams(): array
{
return ['uri' => $this->uri];
}

View file

@ -20,7 +20,7 @@ use Mcp\Schema\JsonRpc\Request;
*
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
*/
class SetLogLevelRequest extends Request
final class SetLogLevelRequest extends Request
{
/**
* @param LoggingLevel $level The level of logging that the client wants to receive from the server. The server
@ -37,7 +37,7 @@ class SetLogLevelRequest extends Request
return 'logging/setLevel';
}
protected static function fromParams(?array $params): self
protected static function fromParams(?array $params): static
{
if (!isset($params['level']) || !\is_string($params['level']) || empty($params['level'])) {
throw new InvalidArgumentException('Missing or invalid "level" parameter for "logging/setLevel".');
@ -46,7 +46,10 @@ class SetLogLevelRequest extends Request
return new self(LoggingLevel::from($params['level']));
}
protected function getParams(): ?array
/**
* @return array{level: value-of<LoggingLevel>}
*/
protected function getParams(): array
{
return [
'level' => $this->level->value,

View file

@ -24,7 +24,7 @@ final class RequestTest extends TestCase
return 'foo/bar';
}
public static function fromParams(?array $params): self
public static function fromParams(?array $params): static
{
return new self();
}