refactor: remove dead code and obsolete examples (#76)
- Remove ToolChain, ResourceChain, PromptChain classes - Remove Collection/Identifier/Metadata interfaces (only used by old Chains) - Remove ToolCollectionInterface (unused) - Delete obsolete examples 09-standalone-cli and 10-simple-http-transport - Fix STDERR handling in bootstrap.php for web environments - Clean up CHANGELOG.md
This commit is contained in:
parent
719262b15d
commit
9e168832ca
28 changed files with 5 additions and 1050 deletions
25
CHANGELOG.md
25
CHANGELOG.md
|
|
@ -1,24 +1,3 @@
|
|||
CHANGELOG
|
||||
=========
|
||||
# Changelog
|
||||
|
||||
0.1
|
||||
---
|
||||
|
||||
* Add Model Context Protocol (MCP) implementation for LLM-application communication
|
||||
* Add JSON-RPC based protocol handling with `JsonRpcHandler`
|
||||
* Add three core MCP capabilities:
|
||||
- Resources: File-like data readable by clients (API responses, file contents)
|
||||
- Tools: Functions callable by LLMs (with user approval)
|
||||
- Prompts: Pre-written templates for specific tasks
|
||||
* Add multiple transport implementations:
|
||||
- Symfony Console Transport for testing and CLI applications
|
||||
- Stream Transport supporting Server-Sent Events (SSE) and HTTP streaming
|
||||
- STDIO transport for command-line interfaces
|
||||
* Add capability chains for organizing features:
|
||||
- `ToolChain` for tool management
|
||||
- `ResourceChain` for resource management
|
||||
- `PromptChain` for prompt template management
|
||||
* Add Server component managing transport connections
|
||||
* Add request/notification handlers for MCP operations
|
||||
* Add standardized interface enabling LLMs to interact with external systems
|
||||
* Add support for building LLM "plugins" with extra context capabilities
|
||||
All notable changes to `mcp/sdk` will be documented in this file.
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
# Standalone example app with CLI
|
||||
|
||||
This is just for testing and debugging purposes. Different from the other examples, this one does not use the same
|
||||
autoloader, but installs the SDK via path repository and therefore has mostly decoupled dependencies.
|
||||
|
||||
Install dependencies:
|
||||
|
||||
```bash
|
||||
cd /path/to/your/project/examples/09-standalone-cli
|
||||
composer update
|
||||
```
|
||||
|
||||
Run the CLI with:
|
||||
|
||||
```bash
|
||||
DEBUG=1 php index.php
|
||||
```
|
||||
|
||||
You will see debug outputs to help you understand what is happening.
|
||||
|
||||
In this terminal you can now test by adding some JSON strings. See `example-requests.json`.
|
||||
|
||||
Run with Inspector:
|
||||
|
||||
```bash
|
||||
npx @modelcontextprotocol/inspector php index.php
|
||||
```
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
{
|
||||
"name": "mcp/cli-server-example",
|
||||
"description": "An example application for CLI",
|
||||
"license": "MIT",
|
||||
"type": "project",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Tobias Nyholm",
|
||||
"email": "tobias.nyholm@gmail.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"mcp/sdk": "@dev",
|
||||
"symfony/console": "^7.2"
|
||||
},
|
||||
"minimum-stability": "stable",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "src/"
|
||||
}
|
||||
},
|
||||
"repositories": [
|
||||
{ "type": "path", "url": "../../" }
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
[
|
||||
{"jsonrpc": "2.0", "id": 1, "method": "resources/list", "params": []},
|
||||
{"jsonrpc": "2.0", "id": 2, "method": "resources/read", "params": {"uri": "file:///project/src/main.rs"}},
|
||||
|
||||
{"jsonrpc": "2.0", "id": 1, "method": "tools/list"},
|
||||
{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "Current time"}},
|
||||
{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "Current time","arguments": {"format": "Y-m-d"}}},
|
||||
|
||||
{"jsonrpc": "2.0", "id": 1, "method": "prompts/list"},
|
||||
{"jsonrpc": "2.0", "id": 2 ,"method": "prompts/get", "params": {"name": "Greet"}},
|
||||
{"jsonrpc": "2.0", "id": 2 ,"method": "prompts/get", "params": {"name": "Greet", "arguments": { "firstName": "Tobias" }}}
|
||||
]
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
require __DIR__.'/vendor/autoload.php';
|
||||
|
||||
use Mcp\Server;
|
||||
use Mcp\Server\Transport\StdioTransport;
|
||||
use Symfony\Component\Console as SymfonyConsole;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
$debug = (bool) ($_SERVER['DEBUG'] ?? false);
|
||||
|
||||
// Setup input, output and logger
|
||||
$output = new SymfonyConsole\Output\ConsoleOutput($debug ? OutputInterface::VERBOSITY_VERY_VERBOSE : OutputInterface::VERBOSITY_NORMAL);
|
||||
$logger = new SymfonyConsole\Logger\ConsoleLogger($output);
|
||||
|
||||
$server = Server::make()
|
||||
->setServerInfo('Standalone CLI', '1.0.0')
|
||||
->setLogger($logger)
|
||||
->setDiscovery(__DIR__, ['.'])
|
||||
->build();
|
||||
|
||||
$transport = new StdioTransport(logger: $logger);
|
||||
|
||||
$server->connect($transport);
|
||||
|
||||
$transport->listen();
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
<?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 App;
|
||||
|
||||
use Mcp\Capability\PromptChain;
|
||||
use Mcp\Capability\ResourceChain;
|
||||
use Mcp\Capability\ToolChain;
|
||||
use Mcp\Server\MethodHandlerInterface;
|
||||
use Mcp\Server\NotificationHandler;
|
||||
use Mcp\Server\RequestHandler;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class Builder
|
||||
{
|
||||
/**
|
||||
* @return list<MethodHandlerInterface>
|
||||
*/
|
||||
public static function buildMethodHandlers(): array
|
||||
{
|
||||
$promptManager = new PromptChain([
|
||||
new ExamplePrompt(),
|
||||
]);
|
||||
|
||||
$resourceManager = new ResourceChain([
|
||||
new ExampleResource(),
|
||||
]);
|
||||
|
||||
$toolManager = new ToolChain([
|
||||
new ExampleTool(),
|
||||
]);
|
||||
|
||||
return [
|
||||
new NotificationHandler\InitializedHandler(),
|
||||
new RequestHandler\InitializeHandler(),
|
||||
new RequestHandler\PingHandler(),
|
||||
new RequestHandler\ListPromptsHandler($promptManager),
|
||||
new RequestHandler\GetPromptHandler($promptManager),
|
||||
new RequestHandler\ListResourcesHandler($resourceManager),
|
||||
new RequestHandler\ReadResourceHandler($resourceManager),
|
||||
new RequestHandler\CallToolHandler($toolManager),
|
||||
new RequestHandler\ListToolsHandler($toolManager),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
<?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 App;
|
||||
|
||||
use Mcp\Capability\Prompt\MetadataInterface;
|
||||
use Mcp\Capability\Prompt\PromptGetterInterface;
|
||||
use Mcp\Schema\Content\PromptMessage;
|
||||
use Mcp\Schema\Content\TextContent;
|
||||
use Mcp\Schema\Enum\Role;
|
||||
use Mcp\Schema\Request\GetPromptRequest;
|
||||
use Mcp\Schema\Result\GetPromptResult;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class ExamplePrompt implements MetadataInterface, PromptGetterInterface
|
||||
{
|
||||
public function get(GetPromptRequest $request): GetPromptResult
|
||||
{
|
||||
$firstName = $request->arguments['firstName'] ?? null;
|
||||
|
||||
return new GetPromptResult(
|
||||
[new PromptMessage(
|
||||
Role::User,
|
||||
new TextContent(\sprintf('Hello %s', $firstName ?? 'World')),
|
||||
)],
|
||||
$this->getDescription(),
|
||||
);
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return 'Greet';
|
||||
}
|
||||
|
||||
public function getDescription(): ?string
|
||||
{
|
||||
return 'Greet a person with a nice message';
|
||||
}
|
||||
|
||||
public function getArguments(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'name' => 'first name',
|
||||
'description' => 'The name of the person to greet',
|
||||
'required' => false,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
<?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 App;
|
||||
|
||||
use Mcp\Capability\Resource\MetadataInterface;
|
||||
use Mcp\Capability\Resource\ResourceReaderInterface;
|
||||
use Mcp\Schema\Content\TextResourceContents;
|
||||
use Mcp\Schema\Request\ReadResourceRequest;
|
||||
use Mcp\Schema\Result\ReadResourceResult;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class ExampleResource implements MetadataInterface, ResourceReaderInterface
|
||||
{
|
||||
public function read(ReadResourceRequest $request): ReadResourceResult
|
||||
{
|
||||
return new ReadResourceResult([
|
||||
new TextResourceContents($this->getUri(), null, 'Content of My Resource'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function getUri(): string
|
||||
{
|
||||
return 'file:///project/src/main.rs';
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return 'my-resource';
|
||||
}
|
||||
|
||||
public function getDescription(): ?string
|
||||
{
|
||||
return 'This is just an example';
|
||||
}
|
||||
|
||||
public function getMimeType(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getSize(): ?int
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
<?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 App;
|
||||
|
||||
use Mcp\Capability\Tool\MetadataInterface;
|
||||
use Mcp\Capability\Tool\ToolCallerInterface;
|
||||
use Mcp\Schema\Content\TextContent;
|
||||
use Mcp\Schema\Request\CallToolRequest;
|
||||
use Mcp\Schema\Result\CallToolResult;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class ExampleTool implements MetadataInterface, ToolCallerInterface
|
||||
{
|
||||
public function call(CallToolRequest $request): CallToolResult
|
||||
{
|
||||
$format = $request->arguments['format'] ?? 'Y-m-d H:i:s';
|
||||
|
||||
return new CallToolResult([
|
||||
new TextContent(
|
||||
(new \DateTime('now', new \DateTimeZone('UTC')))->format($format),
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return 'Current time';
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Returns the current time in UTC';
|
||||
}
|
||||
|
||||
public function getInputSchema(): array
|
||||
{
|
||||
return [
|
||||
'type' => 'object',
|
||||
'properties' => [
|
||||
'format' => [
|
||||
'type' => 'string',
|
||||
'description' => 'The format of the time, e.g. "Y-m-d H:i:s"',
|
||||
'default' => 'Y-m-d H:i:s',
|
||||
],
|
||||
],
|
||||
'required' => [],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,118 +0,0 @@
|
|||
<?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\Example\HttpTransportExample;
|
||||
|
||||
use Mcp\Capability\Attribute\McpPrompt;
|
||||
use Mcp\Capability\Attribute\McpResource;
|
||||
use Mcp\Capability\Attribute\McpTool;
|
||||
|
||||
class McpElements
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current server time.
|
||||
*/
|
||||
#[McpTool(name: 'current_time')]
|
||||
public function getCurrentTime(string $format = 'Y-m-d H:i:s'): string
|
||||
{
|
||||
try {
|
||||
return date($format);
|
||||
} catch (\Exception $e) {
|
||||
return date('Y-m-d H:i:s'); // fallback
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate simple math operations.
|
||||
*/
|
||||
#[McpTool(name: 'calculate')]
|
||||
public function calculate(float $a, float $b, string $operation): float|string
|
||||
{
|
||||
return match (strtolower($operation)) {
|
||||
'add', '+' => $a + $b,
|
||||
'subtract', '-' => $a - $b,
|
||||
'multiply', '*' => $a * $b,
|
||||
'divide', '/' => 0 != $b ? $a / $b : 'Error: Division by zero',
|
||||
default => 'Error: Unknown operation. Use: add, subtract, multiply, divide',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Server information resource.
|
||||
*
|
||||
* @return array{status: string, timestamp: int, version: string, transport: string, uptime: int}
|
||||
*/
|
||||
#[McpResource(
|
||||
uri: 'info://server/status',
|
||||
name: 'server_status',
|
||||
description: 'Current server status and information',
|
||||
mimeType: 'application/json'
|
||||
)]
|
||||
public function getServerStatus(): array
|
||||
{
|
||||
return [
|
||||
'status' => 'running',
|
||||
'timestamp' => time(),
|
||||
'version' => '1.0.0',
|
||||
'transport' => 'HTTP',
|
||||
'uptime' => time() - $_SERVER['REQUEST_TIME'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration resource.
|
||||
*
|
||||
* @return array{debug: bool, environment: string, timezone: string, locale: string}
|
||||
*/
|
||||
#[McpResource(
|
||||
uri: 'config://app/settings',
|
||||
name: 'app_config',
|
||||
description: 'Application configuration settings',
|
||||
mimeType: 'application/json'
|
||||
)]
|
||||
public function getAppConfig(): array
|
||||
{
|
||||
return [
|
||||
'debug' => $_SERVER['DEBUG'] ?? false,
|
||||
'environment' => $_SERVER['APP_ENV'] ?? 'production',
|
||||
'timezone' => date_default_timezone_get(),
|
||||
'locale' => 'en_US',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Greeting prompt.
|
||||
*
|
||||
* @return array{role: string, content: string}
|
||||
*/
|
||||
#[McpPrompt(
|
||||
name: 'greet',
|
||||
description: 'Generate a personalized greeting message'
|
||||
)]
|
||||
public function greetPrompt(string $firstName = 'World', string $timeOfDay = 'day'): array
|
||||
{
|
||||
$greeting = match (strtolower($timeOfDay)) {
|
||||
'morning' => 'Good morning',
|
||||
'afternoon' => 'Good afternoon',
|
||||
'evening', 'night' => 'Good evening',
|
||||
default => 'Hello',
|
||||
};
|
||||
|
||||
return [
|
||||
'role' => 'user',
|
||||
'content' => "# {$greeting}, {$firstName}!\n\nWelcome to our MCP HTTP Server example. This demonstrates how to use the Model Context Protocol over HTTP transport.",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
# HTTP MCP Server Example
|
||||
|
||||
This example demonstrates how to use the MCP SDK with HTTP transport using the StreamableHttpTransport. It provides a complete HTTP-based MCP server that can handle JSON-RPC requests over HTTP POST.
|
||||
|
||||
## Usage
|
||||
|
||||
**Step 1: Start the HTTP server**
|
||||
|
||||
```bash
|
||||
cd examples/10-simple-http-transport
|
||||
php -S localhost:8000 server.php
|
||||
```
|
||||
|
||||
**Step 2: Connect with MCP Inspector**
|
||||
|
||||
```bash
|
||||
npx @modelcontextprotocol/inspector http://localhost:8000
|
||||
```
|
||||
|
||||
## Available Features
|
||||
|
||||
- **Tools**: `current_time`, `calculate`
|
||||
- **Resources**: `info://server/status`, `config://app/settings`
|
||||
- **Prompts**: `greet`
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
require_once dirname(__DIR__).'/bootstrap.php';
|
||||
chdir(__DIR__);
|
||||
|
||||
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
|
||||
use Mcp\Server;
|
||||
use Mcp\Server\Session\FileSessionStore;
|
||||
use Mcp\Server\Transport\StreamableHttpTransport;
|
||||
use Nyholm\Psr7\Factory\Psr17Factory;
|
||||
use Nyholm\Psr7Server\ServerRequestCreator;
|
||||
|
||||
$psr17Factory = new Psr17Factory();
|
||||
$creator = new ServerRequestCreator($psr17Factory, $psr17Factory, $psr17Factory, $psr17Factory);
|
||||
|
||||
$request = $creator->fromGlobals();
|
||||
|
||||
$server = Server::make()
|
||||
->setServerInfo('HTTP MCP Server', '1.0.0', 'MCP Server over HTTP transport')
|
||||
->setContainer(container())
|
||||
->setSession(new FileSessionStore(__DIR__.'/sessions'))
|
||||
->setDiscovery(__DIR__, ['.'])
|
||||
->build();
|
||||
|
||||
$transport = new StreamableHttpTransport($request, $psr17Factory, $psr17Factory);
|
||||
|
||||
$server->connect($transport);
|
||||
|
||||
$response = $transport->listen();
|
||||
|
||||
(new SapiEmitter())->emit($response);
|
||||
|
|
@ -44,9 +44,9 @@ function logger(): LoggerInterface
|
|||
|
||||
if ($_SERVER['FILE_LOG'] ?? false) {
|
||||
file_put_contents('dev.log', $logMessage, \FILE_APPEND);
|
||||
} elseif (defined('STDERR')) {
|
||||
fwrite(\STDERR, $logMessage);
|
||||
}
|
||||
|
||||
fwrite(\STDERR, $logMessage);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -321,25 +321,6 @@ parameters:
|
|||
count: 1
|
||||
path: examples/08-schema-showcase-streamable/SchemaShowcaseElements.php
|
||||
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$registry of class Mcp\\Server\\RequestHandler\\ListPromptsHandler constructor expects Mcp\\Capability\\Registry\\ReferenceProviderInterface, Mcp\\Capability\\PromptChain given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: examples/09-standalone-cli/src/Builder.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$registry of class Mcp\\Server\\RequestHandler\\ListResourcesHandler constructor expects Mcp\\Capability\\Registry\\ReferenceProviderInterface, Mcp\\Capability\\ResourceChain given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: examples/09-standalone-cli/src/Builder.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$registry of class Mcp\\Server\\RequestHandler\\ListToolsHandler constructor expects Mcp\\Capability\\Registry\\ReferenceProviderInterface, Mcp\\Capability\\ToolChain given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: examples/09-standalone-cli/src/Builder.php
|
||||
|
||||
-
|
||||
message: '#^PHPDoc tag @return with type array is incompatible with native type object\.$#'
|
||||
identifier: return.phpDocType
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ class Discoverer
|
|||
$this->processFile($file, $discoveredCount);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$this->logger->error('Error during file finding process for MCP discovery', [
|
||||
$this->logger->error('Error during file finding process for MCP discovery'.json_encode($e->getTrace(), \JSON_PRETTY_PRINT), [
|
||||
'exception' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString(),
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
<?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\Prompt;
|
||||
|
||||
use Mcp\Exception\InvalidCursorException;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
interface CollectionInterface
|
||||
{
|
||||
/**
|
||||
* @param int $count the number of metadata items to return
|
||||
*
|
||||
* @return iterable<MetadataInterface>
|
||||
*
|
||||
* @throws InvalidCursorException if no item with $lastIdentifier was found
|
||||
*/
|
||||
public function getMetadata(int $count, ?string $lastIdentifier = null): iterable;
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
<?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\Prompt;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
interface IdentifierInterface
|
||||
{
|
||||
public function getName(): string;
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
<?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\Prompt;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
interface MetadataInterface extends IdentifierInterface
|
||||
{
|
||||
public function getDescription(): ?string;
|
||||
|
||||
/**
|
||||
* @return list<array{
|
||||
* name: string,
|
||||
* description?: string,
|
||||
* required?: bool,
|
||||
* }>
|
||||
*/
|
||||
public function getArguments(): array;
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
<?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;
|
||||
|
||||
use Mcp\Capability\Prompt\CollectionInterface;
|
||||
use Mcp\Capability\Prompt\IdentifierInterface;
|
||||
use Mcp\Capability\Prompt\MetadataInterface;
|
||||
use Mcp\Capability\Prompt\PromptGetterInterface;
|
||||
use Mcp\Exception\InvalidCursorException;
|
||||
use Mcp\Exception\PromptGetException;
|
||||
use Mcp\Exception\PromptNotFoundException;
|
||||
use Mcp\Schema\Request\GetPromptRequest;
|
||||
use Mcp\Schema\Result\GetPromptResult;
|
||||
|
||||
/**
|
||||
* A collection of prompts. All prompts need to implement IdentifierInterface.
|
||||
*
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
class PromptChain implements PromptGetterInterface, CollectionInterface
|
||||
{
|
||||
public function __construct(
|
||||
/**
|
||||
* @var IdentifierInterface[]
|
||||
*/
|
||||
private readonly array $items,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getMetadata(int $count, ?string $lastIdentifier = null): iterable
|
||||
{
|
||||
$found = null === $lastIdentifier;
|
||||
foreach ($this->items as $item) {
|
||||
if (!$item instanceof MetadataInterface) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (false === $found) {
|
||||
$found = $item->getName() === $lastIdentifier;
|
||||
continue;
|
||||
}
|
||||
|
||||
yield $item;
|
||||
if (--$count <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
throw new InvalidCursorException($lastIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
public function get(GetPromptRequest $request): GetPromptResult
|
||||
{
|
||||
foreach ($this->items as $item) {
|
||||
if ($item instanceof PromptGetterInterface && $request->name === $item->getName()) {
|
||||
try {
|
||||
return $item->get($request);
|
||||
} catch (\Throwable $e) {
|
||||
throw new PromptGetException($request, $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new PromptNotFoundException($request);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
<?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\Resource;
|
||||
|
||||
use Mcp\Exception\InvalidCursorException;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*/
|
||||
interface CollectionInterface
|
||||
{
|
||||
/**
|
||||
* @param int $count the number of metadata items to return
|
||||
*
|
||||
* @return iterable<MetadataInterface>
|
||||
*
|
||||
* @throws InvalidCursorException if no item with $lastIdentifier was found
|
||||
*/
|
||||
public function getMetadata(int $count, ?string $lastIdentifier = null): iterable;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue