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:
Kyrian Obikwelu 2025-09-21 19:23:59 +01:00 • committed by GitHub
commit 9e168832ca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 5 additions and 1050 deletions

View file

@ -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(),
]);

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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\Resource;
/**
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
interface IdentifierInterface
{
public function getUri(): string;
}

View file

@ -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;
/**
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
interface MetadataInterface extends IdentifierInterface
{
public function getName(): string;
public function getDescription(): ?string;
public function getMimeType(): ?string;
/**
* Size in bytes.
*/
public function getSize(): ?int;
}

View file

@ -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\Resource\CollectionInterface;
use Mcp\Capability\Resource\IdentifierInterface;
use Mcp\Capability\Resource\MetadataInterface;
use Mcp\Capability\Resource\ResourceReaderInterface;
use Mcp\Exception\InvalidCursorException;
use Mcp\Exception\ResourceNotFoundException;
use Mcp\Exception\ResourceReadException;
use Mcp\Schema\Request\ReadResourceRequest;
use Mcp\Schema\Result\ReadResourceResult;
/**
* A collection of resources. All resources need to implement IdentifierInterface.
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class ResourceChain implements CollectionInterface, ResourceReaderInterface
{
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->getUri() === $lastIdentifier;
continue;
}
yield $item;
if (--$count <= 0) {
break;
}
}
if (!$found) {
throw new InvalidCursorException($lastIdentifier);
}
}
public function read(ReadResourceRequest $request): ReadResourceResult
{
foreach ($this->items as $item) {
if ($item instanceof ResourceReaderInterface && $request->uri === $item->getUri()) {
try {
return $item->read($request);
} catch (\Throwable $e) {
throw new ResourceReadException($request, $e);
}
}
}
throw new ResourceNotFoundException($request);
}
}

View file

@ -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\Tool;
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;
}

View file

@ -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\Tool;
/**
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
interface IdentifierInterface
{
public function getName(): string;
}

View file

@ -1,32 +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\Tool;
/**
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
interface MetadataInterface extends IdentifierInterface
{
public function getDescription(): string;
/**
* @return array{
* type?: string,
* required?: list<string>,
* properties?: array<string, array{
* type: string,
* description?: string,
* }>,
* }
*/
public function getInputSchema(): array;
}

View file

@ -1,23 +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\Tool;
/**
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
interface ToolCollectionInterface
{
/**
* @return MetadataInterface[]
*/
public function getMetadata(): array;
}

View file

@ -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\Tool\CollectionInterface;
use Mcp\Capability\Tool\IdentifierInterface;
use Mcp\Capability\Tool\MetadataInterface;
use Mcp\Capability\Tool\ToolCallerInterface;
use Mcp\Exception\InvalidCursorException;
use Mcp\Exception\ToolCallException;
use Mcp\Exception\ToolNotFoundException;
use Mcp\Schema\Request\CallToolRequest;
use Mcp\Schema\Result\CallToolResult;
/**
* A collection of tools. All tools need to implement IdentifierInterface.
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class ToolChain implements ToolCallerInterface, CollectionInterface
{
public function __construct(
/**
* @var IdentifierInterface[] $items
*/
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 call(CallToolRequest $request): CallToolResult
{
foreach ($this->items as $item) {
if ($item instanceof ToolCallerInterface && $request->name === $item->getName()) {
try {
return $item->call($request);
} catch (\Throwable $e) {
throw new ToolCallException($request, $e);
}
}
}
throw new ToolNotFoundException($request);
}
}