Skip to content

Commit e1f8038

Browse files
authored
feat: add Prompt/Resource/Tool Chain (#25)
* cleanup * feat: add Prompt/Resource/Tool Chain * feat: update comments * fix: rector
1 parent 296bf75 commit e1f8038

21 files changed

+226
-178
lines changed

examples/cli/index.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22

33
require __DIR__.'/vendor/autoload.php';
44

5+
use Symfony\Component\Console as SymfonyConsole;
56
use Symfony\Component\Console\Output\OutputInterface;
67

78
$debug = (bool) ($_SERVER['DEBUG'] ?? false);
89

910
// Setup input, output and logger
10-
$input = new Symfony\Component\Console\Input\ArgvInput($argv);
11-
$output = new Symfony\Component\Console\Output\ConsoleOutput($debug ? OutputInterface::VERBOSITY_VERY_VERBOSE : OutputInterface::VERBOSITY_NORMAL);
12-
$logger = new Symfony\Component\Console\Logger\ConsoleLogger($output);
11+
$input = new SymfonyConsole\Input\ArgvInput($argv);
12+
$output = new SymfonyConsole\Output\ConsoleOutput($debug ? OutputInterface::VERBOSITY_VERY_VERBOSE : OutputInterface::VERBOSITY_NORMAL);
13+
$logger = new SymfonyConsole\Logger\ConsoleLogger($output);
1314

14-
// Configure the JsonRpcHandler
15+
// Configure the JsonRpcHandler and build the functionality
1516
$jsonRpcHandler = new PhpLlm\McpSdk\Server\JsonRpcHandler(
1617
new PhpLlm\McpSdk\Message\Factory(),
1718
App\Builder::buildRequestHandlers(),

examples/cli/src/Builder.php

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
namespace App;
44

5-
use App\Manager\PromptManager;
6-
use App\Manager\ResourceManager;
7-
use App\Manager\ToolManager;
5+
use PhpLlm\McpSdk\Capability\PromptChain;
6+
use PhpLlm\McpSdk\Capability\ResourceChain;
7+
use PhpLlm\McpSdk\Capability\ToolChain;
88
use PhpLlm\McpSdk\Server\NotificationHandler;
99
use PhpLlm\McpSdk\Server\NotificationHandler\InitializedHandler;
1010
use PhpLlm\McpSdk\Server\RequestHandler;
@@ -24,9 +24,17 @@ class Builder
2424
*/
2525
public static function buildRequestHandlers(): array
2626
{
27-
$promptManager = new PromptManager();
28-
$resourceManager = new ResourceManager();
29-
$toolManager = new ToolManager();
27+
$promptManager = new PromptChain([
28+
new ExamplePrompt(),
29+
]);
30+
31+
$resourceManager = new ResourceChain([
32+
new ExampleResource(),
33+
]);
34+
35+
$toolManager = new ToolChain([
36+
new ExampleTool(),
37+
]);
3038

3139
return [
3240
new InitializeHandler(),

examples/cli/src/ExamplePrompt.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,24 @@
33
namespace App;
44

55
use PhpLlm\McpSdk\Capability\Prompt\MetadataInterface;
6+
use PhpLlm\McpSdk\Capability\Prompt\PromptGet;
7+
use PhpLlm\McpSdk\Capability\Prompt\PromptGetResult;
8+
use PhpLlm\McpSdk\Capability\Prompt\PromptGetResultMessages;
9+
use PhpLlm\McpSdk\Capability\Prompt\PromptGetterInterface;
610

7-
class ExamplePrompt implements MetadataInterface
11+
class ExamplePrompt implements MetadataInterface, PromptGetterInterface
812
{
9-
public function __invoke(?string $firstName = null): string
13+
public function get(PromptGet $input): PromptGetResult
1014
{
11-
return sprintf('Hello %s', $firstName ?? 'World');
15+
$firstName = $input->arguments['first name'] ?? null;
16+
17+
return new PromptGetResult(
18+
$this->getDescription(),
19+
[new PromptGetResultMessages(
20+
'user',
21+
sprintf('Hello %s', $firstName ?? 'World')
22+
)]
23+
);
1224
}
1325

1426
public function getName(): string
@@ -25,7 +37,7 @@ public function getArguments(): array
2537
{
2638
return [
2739
[
28-
'name' => 'firstName',
40+
'name' => 'first name',
2941
'description' => 'The name of the person to greet',
3042
'required' => false,
3143
],

examples/cli/src/ExampleResource.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,20 @@
33
namespace App;
44

55
use PhpLlm\McpSdk\Capability\Resource\MetadataInterface;
6+
use PhpLlm\McpSdk\Capability\Resource\ResourceRead;
7+
use PhpLlm\McpSdk\Capability\Resource\ResourceReaderInterface;
8+
use PhpLlm\McpSdk\Capability\Resource\ResourceReadResult;
69

7-
class ExampleResource implements MetadataInterface
10+
class ExampleResource implements MetadataInterface, ResourceReaderInterface
811
{
12+
public function read(ResourceRead $input): ResourceReadResult
13+
{
14+
return new ResourceReadResult(
15+
'Content of '.$this->getName(),
16+
$this->getUri(),
17+
);
18+
}
19+
920
public function getUri(): string
1021
{
1122
return 'file:///project/src/main.rs';

examples/cli/src/ExampleTool.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,19 @@
33
namespace App;
44

55
use PhpLlm\McpSdk\Capability\Tool\MetadataInterface;
6+
use PhpLlm\McpSdk\Capability\Tool\ToolCall;
7+
use PhpLlm\McpSdk\Capability\Tool\ToolCallResult;
8+
use PhpLlm\McpSdk\Capability\Tool\ToolExecutorInterface;
69

7-
class ExampleTool implements MetadataInterface
10+
class ExampleTool implements MetadataInterface, ToolExecutorInterface
811
{
9-
public function __invoke(string $format = 'Y-m-d H:i:s'): string
12+
public function call(ToolCall $input): ToolCallResult
1013
{
11-
return (new \DateTime('now', new \DateTimeZone('UTC')))->format($format);
14+
$format = $input->arguments['format'] ?? 'Y-m-d H:i:s';
15+
16+
return new ToolCallResult(
17+
(new \DateTime('now', new \DateTimeZone('UTC')))->format($format)
18+
);
1219
}
1320

1421
public function getName(): string

examples/cli/src/Manager/PromptManager.php

Lines changed: 0 additions & 53 deletions
This file was deleted.

examples/cli/src/Manager/ResourceManager.php

Lines changed: 0 additions & 46 deletions
This file was deleted.

examples/cli/src/Manager/ToolManager.php

Lines changed: 0 additions & 48 deletions
This file was deleted.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace PhpLlm\McpSdk\Capability\Prompt;
4+
5+
interface IdentifierInterface
6+
{
7+
public function getName(): string;
8+
}

src/Capability/Prompt/MetadataInterface.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@
44

55
namespace PhpLlm\McpSdk\Capability\Prompt;
66

7-
interface MetadataInterface
7+
interface MetadataInterface extends IdentifierInterface
88
{
9-
public function getName(): string;
10-
119
public function getDescription(): ?string;
1210

1311
/**

src/Capability/Prompt/PromptGetterInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ interface PromptGetterInterface
1111
* @throws PromptGetException if the prompt execution fails
1212
* @throws PromptNotFoundException if the prompt is not found
1313
*/
14-
public function get(PromptGet $request): PromptGetResult;
14+
public function get(PromptGet $input): PromptGetResult;
1515
}

src/Capability/PromptChain.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
namespace PhpLlm\McpSdk\Capability;
4+
5+
use PhpLlm\McpSdk\Capability\Prompt\CollectionInterface;
6+
use PhpLlm\McpSdk\Capability\Prompt\IdentifierInterface;
7+
use PhpLlm\McpSdk\Capability\Prompt\MetadataInterface;
8+
use PhpLlm\McpSdk\Capability\Prompt\PromptGet;
9+
use PhpLlm\McpSdk\Capability\Prompt\PromptGetResult;
10+
use PhpLlm\McpSdk\Capability\Prompt\PromptGetterInterface;
11+
use PhpLlm\McpSdk\Exception\PromptGetException;
12+
use PhpLlm\McpSdk\Exception\PromptNotFoundException;
13+
14+
/**
15+
* A collection of prompts. All prompts need to implement IdentifierInterface.
16+
*/
17+
class PromptChain implements PromptGetterInterface, CollectionInterface
18+
{
19+
public function __construct(
20+
/**
21+
* @var IdentifierInterface[]
22+
*/
23+
private readonly array $items,
24+
) {
25+
}
26+
27+
public function getMetadata(): array
28+
{
29+
return array_filter($this->items, fn ($item) => $item instanceof MetadataInterface);
30+
}
31+
32+
public function get(PromptGet $input): PromptGetResult
33+
{
34+
foreach ($this->items as $item) {
35+
if ($item instanceof PromptGetterInterface && $input->name === $item->getName()) {
36+
try {
37+
return $item->get($input);
38+
} catch (\Throwable $e) {
39+
throw new PromptGetException($input, $e);
40+
}
41+
}
42+
}
43+
44+
throw new PromptNotFoundException($input);
45+
}
46+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace PhpLlm\McpSdk\Capability\Resource;
4+
5+
interface IdentifierInterface
6+
{
7+
public function getUri(): string;
8+
}

src/Capability/Resource/MetadataInterface.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@
44

55
namespace PhpLlm\McpSdk\Capability\Resource;
66

7-
interface MetadataInterface
7+
interface MetadataInterface extends IdentifierInterface
88
{
9-
public function getUri(): string;
10-
119
public function getName(): string;
1210

1311
public function getDescription(): ?string;

src/Capability/Resource/ResourceReaderInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ interface ResourceReaderInterface
1111
* @throws ResourceReadException if the resource execution fails
1212
* @throws ResourceNotFoundException if the resource is not found
1313
*/
14-
public function read(ResourceRead $request): ResourceReadResult;
14+
public function read(ResourceRead $input): ResourceReadResult;
1515
}

0 commit comments

Comments
 (0)