157 lines
5 KiB
ReStructuredText
157 lines
5 KiB
ReStructuredText
Model Context Protocol SDK
|
|
==========================
|
|
|
|
The PHP MCP SDK is the low level library that enables communication between a PHP application and an LLM model.
|
|
|
|
Installation
|
|
------------
|
|
|
|
Install the SDK using Composer:
|
|
|
|
.. code-block:: terminal
|
|
|
|
$ composer require mcp/sdk
|
|
|
|
Usage
|
|
-----
|
|
|
|
The `Model Context Protocol`_ is built on top of JSON-RPC. There two types of
|
|
messages. A Notification and Request. The Notification is just a status update
|
|
that something has happened. There is never a response to a Notification. A Request
|
|
is a message that expects a response. There are 3 concepts/capabilities that you
|
|
may use. These are::
|
|
|
|
1. **Resources**: File-like data that can be read by clients (like API responses or file contents)
|
|
1. **Tools**: Functions that can be called by the LLM (with user approval)
|
|
1. **Prompts**: Pre-written templates that help users accomplish specific tasks
|
|
|
|
The SDK comes with NotificationHandlers and RequestHandlers which are expected
|
|
to be wired up in your application.
|
|
|
|
JsonRpcHandler
|
|
..............
|
|
|
|
The ``Mcp\Server\JsonRpcHandler`` is the heart of the SDK. It is here
|
|
you inject the NotificationHandlers and RequestHandlers. It is recommended to use
|
|
the built-in handlers in ``Mcp\Server\NotificationHandlers\*`` and
|
|
``Mcp\Server\RequestHandlers\*``.
|
|
|
|
The ``Mcp\Server\JsonRpcHandler`` is started and kept running by
|
|
the ``Mcp\Server``
|
|
|
|
Transports
|
|
..........
|
|
|
|
The SDK supports multiple transports for sending and receiving messages. The
|
|
``Mcp\Server`` is using the transport to fetch a message, then
|
|
give it to the ``Mcp\Server\JsonRpcHandler`` and finally send the
|
|
response/error back to the transport. The SDK comes with a few transports::
|
|
|
|
1. **Symfony Console Transport**: Good for testing and for CLI applications
|
|
1. **Stream Transport**: It uses Server Side Events (SSE) and HTTP streaming
|
|
|
|
Capabilities
|
|
............
|
|
|
|
Any client would like to discover the capabilities of the server. Exactly what
|
|
the server supports is defined in the ``Mcp\Server\RequestHandler\InitializeHandler``.
|
|
When the client connects, it sees the capabilities and will ask the server to list
|
|
the tools/resource/prompts etc. When you want to add a new capability, example a
|
|
**Tool** that can tell the current time, you need to provide some metadata to the
|
|
``Mcp\Server\RequestHandler\ToolListHandler``::
|
|
|
|
namespace App;
|
|
|
|
use Mcp\Capability\Tool\MetadataInterface;
|
|
|
|
class CurrentTimeToolMetadata implements MetadataInterface
|
|
{
|
|
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' => [],
|
|
];
|
|
}
|
|
}
|
|
|
|
We would also need a class to actually execute the tool::
|
|
|
|
namespace App;
|
|
|
|
use Mcp\Capability\Tool\IdentifierInterface;
|
|
use Mcp\Capability\Tool\ToolCall;
|
|
use Mcp\Capability\Tool\ToolCallResult;
|
|
use Mcp\Capability\Tool\ToolExecutorInterface;
|
|
|
|
class CurrentTimeToolExecutor implements ToolExecutorInterface, IdentifierInterface
|
|
{
|
|
public function getName(): string
|
|
{
|
|
return 'Current time';
|
|
}
|
|
|
|
public function call(ToolCall $input): ToolCallResult
|
|
{
|
|
$format = $input->arguments['format'] ?? 'Y-m-d H:i:s';
|
|
|
|
return new ToolCallResult(
|
|
(new \DateTime('now', new \DateTimeZone('UTC')))->format($format)
|
|
);
|
|
}
|
|
}
|
|
|
|
If you have multiple tools, you can put them in a ToolChain::
|
|
|
|
$tools = new ToolChain([
|
|
new CurrentTimeToolMetadata(),
|
|
new CurrentTimeToolExecutor(),
|
|
]);
|
|
|
|
$jsonRpcHandler = new Mcp\Server\JsonRpcHandler(
|
|
new Mcp\Message\Factory(),
|
|
[
|
|
new ToolCallHandler($tools),
|
|
new ToolListHandler($tools),
|
|
// Other RequestHandlers ...
|
|
],
|
|
[
|
|
// Other NotificationHandlers ...
|
|
],
|
|
new NullLogger()
|
|
);
|
|
|
|
With this metadata and executor, the client can now call the tool.
|
|
|
|
Extending the SDK
|
|
-----------------
|
|
|
|
If you want to extend the SDK, you can create your own RequestHandlers and NotificationHandlers.
|
|
The provided one are very good defaults for most applications but they are not
|
|
a requirement.
|
|
|
|
If you do decide to use them, you get the benefit of having a well-defined interfaces
|
|
and value objects to work with. They will assure that you follow the `Model Context Protocol`_.
|
|
specification.
|
|
|
|
You also have the Transport abstraction that allows you to create your own transport
|
|
if non of the standard ones fit your needs.
|
|
|
|
.. _`Model Context Protocol`: https://modelcontextprotocol.io/
|