fix: extract and pass URI template variables to resource handlers (#123)
This commit is contained in:
parent
f41ea86608
commit
55f860808c
4 changed files with 19 additions and 29 deletions
|
|
@ -16,6 +16,7 @@ use Mcp\Capability\Attribute\McpPrompt;
|
||||||
use Mcp\Capability\Attribute\McpResource;
|
use Mcp\Capability\Attribute\McpResource;
|
||||||
use Mcp\Capability\Attribute\McpResourceTemplate;
|
use Mcp\Capability\Attribute\McpResourceTemplate;
|
||||||
use Mcp\Capability\Attribute\McpTool;
|
use Mcp\Capability\Attribute\McpTool;
|
||||||
|
use Mcp\Exception\InvalidArgumentException;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -47,7 +48,7 @@ final class McpElements
|
||||||
*
|
*
|
||||||
* @return User user profile data
|
* @return User user profile data
|
||||||
*
|
*
|
||||||
* @throws McpServerException if the user is not found
|
* @throws InvalidArgumentException if the user is not found
|
||||||
*/
|
*/
|
||||||
#[McpResourceTemplate(
|
#[McpResourceTemplate(
|
||||||
uriTemplate: 'user://{userId}/profile',
|
uriTemplate: 'user://{userId}/profile',
|
||||||
|
|
@ -61,8 +62,7 @@ final class McpElements
|
||||||
): array {
|
): array {
|
||||||
$this->logger->info('Reading resource: user profile', ['userId' => $userId]);
|
$this->logger->info('Reading resource: user profile', ['userId' => $userId]);
|
||||||
if (!isset($this->users[$userId])) {
|
if (!isset($this->users[$userId])) {
|
||||||
// Throwing an exception that Processor can turn into an error response
|
throw new InvalidArgumentException("User profile not found for ID: {$userId}");
|
||||||
throw McpServerException::invalidParams("User profile not found for ID: {$userId}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->users[$userId];
|
return $this->users[$userId];
|
||||||
|
|
@ -130,7 +130,7 @@ final class McpElements
|
||||||
*
|
*
|
||||||
* @return array<string, string>[] prompt messages
|
* @return array<string, string>[] prompt messages
|
||||||
*
|
*
|
||||||
* @throws McpServerException if user not found
|
* @throws InvalidArgumentException if user not found
|
||||||
*/
|
*/
|
||||||
#[McpPrompt(name: 'generate_bio_prompt')]
|
#[McpPrompt(name: 'generate_bio_prompt')]
|
||||||
public function generateBio(
|
public function generateBio(
|
||||||
|
|
@ -140,7 +140,7 @@ final class McpElements
|
||||||
): array {
|
): array {
|
||||||
$this->logger->info('Executing prompt: generate_bio', ['userId' => $userId, 'tone' => $tone]);
|
$this->logger->info('Executing prompt: generate_bio', ['userId' => $userId, 'tone' => $tone]);
|
||||||
if (!isset($this->users[$userId])) {
|
if (!isset($this->users[$userId])) {
|
||||||
throw McpServerException::invalidParams("User not found for bio prompt: {$userId}");
|
throw new InvalidArgumentException("User not found for bio prompt: {$userId}");
|
||||||
}
|
}
|
||||||
$user = $this->users[$userId];
|
$user = $this->users[$userId];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,5 @@
|
||||||
parameters:
|
parameters:
|
||||||
ignoreErrors:
|
ignoreErrors:
|
||||||
-
|
|
||||||
message: '#^Call to static method invalidParams\(\) on an unknown class Mcp\\Example\\HttpDiscoveryUserProfile\\McpServerException\.$#'
|
|
||||||
identifier: class.notFound
|
|
||||||
count: 2
|
|
||||||
path: examples/http-discovery-userprofile/McpElements.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: '#^PHPDoc tag @throws with type Mcp\\Example\\HttpDiscoveryUserProfile\\McpServerException is not subtype of Throwable$#'
|
|
||||||
identifier: throws.notThrowable
|
|
||||||
count: 2
|
|
||||||
path: examples/http-discovery-userprofile/McpElements.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: '#^Method Mcp\\Schema\\Result\\ReadResourceResult\:\:jsonSerialize\(\) should return array\{contents\: array\<Mcp\\Schema\\Content\\BlobResourceContents\|Mcp\\Schema\\Content\\TextResourceContents\>\} but returns array\{contents\: array\<Mcp\\Schema\\Content\\ResourceContents\>\}\.$#'
|
message: '#^Method Mcp\\Schema\\Result\\ReadResourceResult\:\:jsonSerialize\(\) should return array\{contents\: array\<Mcp\\Schema\\Content\\BlobResourceContents\|Mcp\\Schema\\Content\\TextResourceContents\>\} but returns array\{contents\: array\<Mcp\\Schema\\Content\\ResourceContents\>\}\.$#'
|
||||||
identifier: return.type
|
identifier: return.type
|
||||||
|
|
|
||||||
|
|
@ -57,18 +57,17 @@ class ResourceTemplateReference extends ElementReference
|
||||||
|
|
||||||
public function matches(string $uri): bool
|
public function matches(string $uri): bool
|
||||||
{
|
{
|
||||||
if (preg_match($this->uriTemplateRegex, $uri, $matches)) {
|
return 1 === preg_match($this->uriTemplateRegex, $uri);
|
||||||
$variables = [];
|
}
|
||||||
foreach ($this->variableNames as $varName) {
|
|
||||||
if (isset($matches[$varName])) {
|
|
||||||
$variables[$varName] = $matches[$varName];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
/** @return array<string, mixed> */
|
||||||
}
|
public function extractVariables(string $uri): array
|
||||||
|
{
|
||||||
|
$matches = [];
|
||||||
|
|
||||||
return false;
|
preg_match($this->uriTemplateRegex, $uri, $matches);
|
||||||
|
|
||||||
|
return array_filter($matches, fn ($key) => \in_array($key, $this->variableNames), \ARRAY_FILTER_USE_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -65,11 +65,14 @@ final class ReadResourceHandler implements RequestHandlerInterface
|
||||||
'_session' => $session,
|
'_session' => $session,
|
||||||
];
|
];
|
||||||
|
|
||||||
$result = $this->referenceHandler->handle($reference, $arguments);
|
|
||||||
|
|
||||||
if ($reference instanceof ResourceTemplateReference) {
|
if ($reference instanceof ResourceTemplateReference) {
|
||||||
|
$variables = $reference->extractVariables($uri);
|
||||||
|
$arguments = array_merge($arguments, $variables);
|
||||||
|
|
||||||
|
$result = $this->referenceHandler->handle($reference, $arguments);
|
||||||
$formatted = $reference->formatResult($result, $uri, $reference->resourceTemplate->mimeType);
|
$formatted = $reference->formatResult($result, $uri, $reference->resourceTemplate->mimeType);
|
||||||
} else {
|
} else {
|
||||||
|
$result = $this->referenceHandler->handle($reference, $arguments);
|
||||||
$formatted = $reference->formatResult($result, $uri, $reference->schema->mimeType);
|
$formatted = $reference->formatResult($result, $uri, $reference->schema->mimeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue