Introduce Capability Registry & Discovery
This commit is contained in:
parent
09707b4798
commit
da0d5a87a0
6 changed files with 7063 additions and 8 deletions
38
src/Capability/Attribute/CompletionProvider.php
Normal file
38
src/Capability/Attribute/CompletionProvider.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?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\Capability\Attribute;
|
||||
|
||||
use Mcp\Capability\Prompt\Completion\ProviderInterface;
|
||||
use Mcp\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
|
||||
*/
|
||||
#[\Attribute(\Attribute::TARGET_PARAMETER)]
|
||||
class CompletionProvider
|
||||
{
|
||||
/**
|
||||
* @param class-string<ProviderInterface>|ProviderInterface|null $provider if a class-string, it will be resolved
|
||||
* from the container at the point of use
|
||||
* @param ?array<int, int|float|string> $values a list of values to use for completion
|
||||
*/
|
||||
public function __construct(
|
||||
public ?string $providerClass = null,
|
||||
public string|ProviderInterface|null $provider = null,
|
||||
public ?array $values = null,
|
||||
public ?string $enum = null,
|
||||
) {
|
||||
if (1 !== \count(array_filter([$provider, $values, $enum]))) {
|
||||
throw new InvalidArgumentException('Only one of provider, values, or enum can be set.');
|
||||
}
|
||||
}
|
||||
}
|
||||
32
src/Capability/Attribute/McpPrompt.php
Normal file
32
src/Capability/Attribute/McpPrompt.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?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\Capability\Attribute;
|
||||
|
||||
/**
|
||||
* Marks a PHP method as an MCP Prompt generator.
|
||||
* The method should return the prompt messages, potentially using arguments for templating.
|
||||
*
|
||||
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
|
||||
*/
|
||||
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
|
||||
final class McpPrompt
|
||||
{
|
||||
/**
|
||||
* @param ?string $name overrides the prompt name (defaults to method name)
|
||||
* @param ?string $description Optional description of the prompt. Defaults to method DocBlock summary.
|
||||
*/
|
||||
public function __construct(
|
||||
public ?string $name = null,
|
||||
public ?string $description = null,
|
||||
) {
|
||||
}
|
||||
}
|
||||
42
src/Capability/Attribute/McpResource.php
Normal file
42
src/Capability/Attribute/McpResource.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?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\Capability\Attribute;
|
||||
|
||||
use Mcp\Schema\Annotations;
|
||||
|
||||
/**
|
||||
* Marks a PHP class as representing or handling a specific MCP Resource instance.
|
||||
* Used primarily for the 'resources/list' discovery.
|
||||
*
|
||||
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
|
||||
*/
|
||||
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
|
||||
final class McpResource
|
||||
{
|
||||
/**
|
||||
* @param string $uri The specific URI identifying this resource instance. Must be unique within the server.
|
||||
* @param ?string $name A human-readable name for this resource. If null, a default might be generated from the method name.
|
||||
* @param ?string $description An optional description of the resource. Defaults to class DocBlock summary.
|
||||
* @param ?string $mimeType the MIME type, if known and constant for this resource
|
||||
* @param ?int $size the size in bytes, if known and constant
|
||||
* @param Annotations|null $annotations optional annotations describing the resource
|
||||
*/
|
||||
public function __construct(
|
||||
public string $uri,
|
||||
public ?string $name = null,
|
||||
public ?string $description = null,
|
||||
public ?string $mimeType = null,
|
||||
public ?int $size = null,
|
||||
public ?Annotations $annotations = null,
|
||||
) {
|
||||
}
|
||||
}
|
||||
40
src/Capability/Attribute/McpResourceTemplate.php
Normal file
40
src/Capability/Attribute/McpResourceTemplate.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?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\Capability\Attribute;
|
||||
|
||||
use Mcp\Schema\Annotations;
|
||||
|
||||
/**
|
||||
* Marks a PHP class definition as representing an MCP Resource Template.
|
||||
* This is informational, used for 'resources/templates/list'.
|
||||
*
|
||||
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
|
||||
*/
|
||||
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
|
||||
final class McpResourceTemplate
|
||||
{
|
||||
/**
|
||||
* @param string $uriTemplate the URI template string (RFC 6570)
|
||||
* @param ?string $name A human-readable name for the template type. If null, a default might be generated from the method name.
|
||||
* @param ?string $description Optional description. Defaults to class DocBlock summary.
|
||||
* @param ?string $mimeType optional default MIME type for matching resources
|
||||
* @param ?Annotations $annotations optional annotations describing the resource template
|
||||
*/
|
||||
public function __construct(
|
||||
public string $uriTemplate,
|
||||
public ?string $name = null,
|
||||
public ?string $description = null,
|
||||
public ?string $mimeType = null,
|
||||
public ?Annotations $annotations = null,
|
||||
) {
|
||||
}
|
||||
}
|
||||
33
src/Capability/Attribute/McpTool.php
Normal file
33
src/Capability/Attribute/McpTool.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?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\Capability\Attribute;
|
||||
|
||||
use Mcp\Schema\ToolAnnotations;
|
||||
|
||||
/**
|
||||
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
|
||||
*/
|
||||
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
|
||||
class McpTool
|
||||
{
|
||||
/**
|
||||
* @param string|null $name The name of the tool (defaults to the method name)
|
||||
* @param string|null $description The description of the tool (defaults to the DocBlock/inferred)
|
||||
* @param ToolAnnotations|null $annotations Optional annotations describing tool behavior
|
||||
*/
|
||||
public function __construct(
|
||||
public ?string $name = null,
|
||||
public ?string $description = null,
|
||||
public ?ToolAnnotations $annotations = null,
|
||||
) {
|
||||
}
|
||||
}
|
||||
258
src/Capability/Attribute/Schema.php
Normal file
258
src/Capability/Attribute/Schema.php
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
<?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\Capability\Attribute;
|
||||
|
||||
/**
|
||||
* Defines a JSON Schema for a method's input or an individual parameter.
|
||||
*
|
||||
* When used at the method level, it describes an object schema where properties
|
||||
* correspond to the method's parameters.
|
||||
*
|
||||
* When used at the parameter level, it describes the schema for that specific parameter.
|
||||
* If 'type' is omitted at the parameter level, it will be inferred.
|
||||
*
|
||||
* @phpstan-type SchemaAttributeData array{
|
||||
* definition?: array<string, mixed>,
|
||||
* type?: string,
|
||||
* description?: string,
|
||||
* enum?: array<int, float|string|int>,
|
||||
* gormat?: string,
|
||||
* minLength?: int,
|
||||
* maxLength?: int,
|
||||
* pattern?: string,
|
||||
* minimum?: int,
|
||||
* maximum?: int,
|
||||
* exclusiveMinimum?: int,
|
||||
* exclusiveMaximum?: int,
|
||||
* multipleOf?: int|float,
|
||||
* items?: array<string, mixed>,
|
||||
* minItems?: int,
|
||||
* maxItems?: int,
|
||||
* uniqueItems?: bool,
|
||||
* properties?: array<string, mixed>,
|
||||
* required?: array<int, string>,
|
||||
* additionalProperties?: bool|array<string, mixed>,
|
||||
* }
|
||||
*
|
||||
* @author Kyrian Obikwelu <koshnawaza@gmail.com>
|
||||
*/
|
||||
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PARAMETER)]
|
||||
class Schema
|
||||
{
|
||||
/**
|
||||
* The complete JSON schema array.
|
||||
* If provided, it takes precedence over individual properties like $type, $properties, etc.
|
||||
*
|
||||
* @var ?array<string, mixed>
|
||||
*/
|
||||
public ?array $definition = null;
|
||||
|
||||
/**
|
||||
* Alternatively, provide individual top-level schema keywords.
|
||||
* These are used if $definition is null.
|
||||
*/
|
||||
public ?string $type = null;
|
||||
public ?string $description = null;
|
||||
public mixed $default = null;
|
||||
/**
|
||||
* @var ?array<int, float|string|int>
|
||||
*/
|
||||
public ?array $enum = null; // list of allowed values
|
||||
public ?string $format = null; // e.g., 'email', 'date-time'
|
||||
|
||||
// Constraints for string
|
||||
public ?int $minLength = null;
|
||||
public ?int $maxLength = null;
|
||||
public ?string $pattern = null;
|
||||
|
||||
// Constraints for number/integer
|
||||
public int|float|null $minimum = null;
|
||||
public int|float|null $maximum = null;
|
||||
public ?bool $exclusiveMinimum = null;
|
||||
public ?bool $exclusiveMaximum = null;
|
||||
public int|float|null $multipleOf = null;
|
||||
|
||||
// Constraints for array
|
||||
/**
|
||||
* @var ?array<string, mixed>
|
||||
*/
|
||||
public ?array $items = null; // JSON schema for array items
|
||||
public ?int $minItems = null;
|
||||
public ?int $maxItems = null;
|
||||
public ?bool $uniqueItems = null;
|
||||
|
||||
// Constraints for object (primarily used when Schema is on a method or an object-typed parameter)
|
||||
/**
|
||||
* @var ?array<string, mixed>
|
||||
*/
|
||||
public ?array $properties = null; // [propertyName => [schema array], ...]
|
||||
/**
|
||||
* @var ?array<int, string>
|
||||
*/
|
||||
public ?array $required = null; // [propertyName, ...]
|
||||
/**
|
||||
* @var bool|array<string, mixed>|null
|
||||
*/
|
||||
public bool|array|null $additionalProperties = null; // true, false, or a schema array
|
||||
|
||||
/**
|
||||
* @param ?array<string, mixed> $definition A complete JSON schema array. If provided, other parameters are ignored.
|
||||
* @param ?string $type the JSON schema type
|
||||
* @param ?string $description description of the element
|
||||
* @param ?array<int, float|string|int> $enum allowed enum values
|
||||
* @param ?string $format String format (e.g., 'date-time', 'email').
|
||||
* @param ?int $minLength minimum length for strings
|
||||
* @param ?int $maxLength maximum length for strings
|
||||
* @param ?string $pattern regex pattern for strings
|
||||
* @param int|float|null $minimum minimum value for numbers/integers
|
||||
* @param int|float|null $maximum maximum value for numbers/integers
|
||||
* @param ?bool $exclusiveMinimum exclusive minimum
|
||||
* @param ?bool $exclusiveMaximum exclusive maximum
|
||||
* @param int|float|null $multipleOf must be a multiple of this value
|
||||
* @param ?array<string, mixed> $items JSON Schema for items if type is 'array'
|
||||
* @param ?int $minItems minimum items for an array
|
||||
* @param ?int $maxItems maximum items for an array
|
||||
* @param ?bool $uniqueItems whether array items must be unique
|
||||
* @param ?array<string, mixed> $properties Property definitions if type is 'object'. [name => schema_array].
|
||||
* @param ?array<int, string> $required list of required properties for an object
|
||||
* @param bool|array<string, mixed>|null $additionalProperties policy for additional properties in an object
|
||||
*/
|
||||
public function __construct(
|
||||
?array $definition = null,
|
||||
?string $type = null,
|
||||
?string $description = null,
|
||||
?array $enum = null,
|
||||
?string $format = null,
|
||||
?int $minLength = null,
|
||||
?int $maxLength = null,
|
||||
?string $pattern = null,
|
||||
int|float|null $minimum = null,
|
||||
int|float|null $maximum = null,
|
||||
?bool $exclusiveMinimum = null,
|
||||
?bool $exclusiveMaximum = null,
|
||||
int|float|null $multipleOf = null,
|
||||
?array $items = null,
|
||||
?int $minItems = null,
|
||||
?int $maxItems = null,
|
||||
?bool $uniqueItems = null,
|
||||
?array $properties = null,
|
||||
?array $required = null,
|
||||
bool|array|null $additionalProperties = null,
|
||||
) {
|
||||
if (null !== $definition) {
|
||||
$this->definition = $definition;
|
||||
} else {
|
||||
$this->type = $type;
|
||||
$this->description = $description;
|
||||
$this->enum = $enum;
|
||||
$this->format = $format;
|
||||
$this->minLength = $minLength;
|
||||
$this->maxLength = $maxLength;
|
||||
$this->pattern = $pattern;
|
||||
$this->minimum = $minimum;
|
||||
$this->maximum = $maximum;
|
||||
$this->exclusiveMinimum = $exclusiveMinimum;
|
||||
$this->exclusiveMaximum = $exclusiveMaximum;
|
||||
$this->multipleOf = $multipleOf;
|
||||
$this->items = $items;
|
||||
$this->minItems = $minItems;
|
||||
$this->maxItems = $maxItems;
|
||||
$this->uniqueItems = $uniqueItems;
|
||||
$this->properties = $properties;
|
||||
$this->required = $required;
|
||||
$this->additionalProperties = $additionalProperties;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the attribute's definition to a JSON schema array.
|
||||
*
|
||||
* @return SchemaAttributeData
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
if (null !== $this->definition) {
|
||||
return [
|
||||
'definition' => $this->definition,
|
||||
];
|
||||
}
|
||||
|
||||
$schema = [];
|
||||
if (null !== $this->type) {
|
||||
$schema['type'] = $this->type;
|
||||
}
|
||||
if (null !== $this->description) {
|
||||
$schema['description'] = $this->description;
|
||||
}
|
||||
if (null !== $this->enum) {
|
||||
$schema['enum'] = $this->enum;
|
||||
}
|
||||
if (null !== $this->format) {
|
||||
$schema['format'] = $this->format;
|
||||
}
|
||||
|
||||
// String
|
||||
if (null !== $this->minLength) {
|
||||
$schema['minLength'] = $this->minLength;
|
||||
}
|
||||
if (null !== $this->maxLength) {
|
||||
$schema['maxLength'] = $this->maxLength;
|
||||
}
|
||||
if (null !== $this->pattern) {
|
||||
$schema['pattern'] = $this->pattern;
|
||||
}
|
||||
|
||||
// Numeric
|
||||
if (null !== $this->minimum) {
|
||||
$schema['minimum'] = $this->minimum;
|
||||
}
|
||||
if (null !== $this->maximum) {
|
||||
$schema['maximum'] = $this->maximum;
|
||||
}
|
||||
if (null !== $this->exclusiveMinimum) {
|
||||
$schema['exclusiveMinimum'] = $this->exclusiveMinimum;
|
||||
}
|
||||
if (null !== $this->exclusiveMaximum) {
|
||||
$schema['exclusiveMaximum'] = $this->exclusiveMaximum;
|
||||
}
|
||||
if (null !== $this->multipleOf) {
|
||||
$schema['multipleOf'] = $this->multipleOf;
|
||||
}
|
||||
|
||||
// Array
|
||||
if (null !== $this->items) {
|
||||
$schema['items'] = $this->items;
|
||||
}
|
||||
if (null !== $this->minItems) {
|
||||
$schema['minItems'] = $this->minItems;
|
||||
}
|
||||
if (null !== $this->maxItems) {
|
||||
$schema['maxItems'] = $this->maxItems;
|
||||
}
|
||||
if (null !== $this->uniqueItems) {
|
||||
$schema['uniqueItems'] = $this->uniqueItems;
|
||||
}
|
||||
|
||||
// Object
|
||||
if (null !== $this->properties) {
|
||||
$schema['properties'] = $this->properties;
|
||||
}
|
||||
if (null !== $this->required) {
|
||||
$schema['required'] = $this->required;
|
||||
}
|
||||
if (null !== $this->additionalProperties) {
|
||||
$schema['additionalProperties'] = $this->additionalProperties;
|
||||
}
|
||||
|
||||
return $schema;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue