Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,26 @@

All notable changes to `mcp/sdk` will be documented in this file.

0.9.0
-----

* [BC Break] Split the root namespace into `Mcp\Schema`, `Mcp\Client` and `Mcp\Server` to prepare package slicing. `Mcp\Schema` depends on nothing, `Mcp\Client` and `Mcp\Server` depend on `Mcp\Schema` only — enforced by Deptrac (`make deptrac`).
* `Mcp\Server` => `Mcp\Server\Server`
* `Mcp\Client` => `Mcp\Client\Client`
* `Mcp\Capability\*` => `Mcp\Server\Capability\*` (`Attribute`, `Completion`, `Discovery`, `Formatter`, `Logger`, `Registry`, `Tool`, plus `Registry` and `RegistryInterface`)
* `Mcp\Event\*` => `Mcp\Server\Event\*`
* `Mcp\JsonRpc\MessageFactory` => `Mcp\Schema\MessageFactory`
* `Mcp\Server\Stateless\RequestMeta` => `Mcp\Schema\RequestMeta`
* [BC Break] Distribute `Mcp\Exception\*` across the three namespaces.
* `Mcp\Exception\{ExceptionInterface,InvalidArgumentException,LogicException,RuntimeException}` => the same names under `Mcp\Schema\Exception\`, `Mcp\Client\Exception\` and `Mcp\Server\Exception\` — pick the one matching the package you catch around
* `Mcp\Exception\Exception` => `Mcp\Client\Exception\Exception` and `Mcp\Server\Exception\Exception`
* `Mcp\Exception\{InvalidInputMessageException,MissingRequestMetaException}` => `Mcp\Schema\Exception\*`
* `Mcp\Exception\{ConnectionException,ElicitationException,RequestException,RootsException,SamplingException}` => `Mcp\Client\Exception\*`
* `Mcp\Exception\{BadMethodCallException,ClientException,ClientRegistrationException,ConfigurationException,ContainerException,InvalidCursorException,MissingRequiredClientCapabilityException,NotFoundExceptionInterface,PromptGetException,PromptNotFoundException,RegistryException,RequestStateException,ResourceNotFoundException,ResourceReadException,ServiceNotFoundException,ToolCallException,ToolNotFoundException}` => `Mcp\Server\Exception\*`
* `Mcp\Exception\TimeoutException` and `Mcp\Exception\HandlerNotFoundException` are removed; both were unused.
* `Mcp\Server\Exception\ExceptionInterface` and `Mcp\Client\Exception\ExceptionInterface` extend `Mcp\Schema\Exception\ExceptionInterface`, so catching the latter still catches any SDK exception.
* The named exceptions now extend their package's `RuntimeException`/`InvalidArgumentException` instead of the global ones, so `catch (Mcp\Server\Exception\RuntimeException)` reaches `ToolCallException`, `PromptGetException` and friends.

0.8.0
-----

Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ composer require mcp/sdk
A server is a plain PHP class plus three lines of wiring:

```php
use Mcp\Capability\Attribute\McpResource;
use Mcp\Capability\Attribute\McpTool;
use Mcp\Server;
use Mcp\Server\Capability\Attribute\McpResource;
use Mcp\Server\Capability\Attribute\McpTool;
use Mcp\Server\Server;
Comment thread
chr-hertel marked this conversation as resolved.
use Mcp\Server\Transport\StdioTransport;

class Calculator
Expand Down Expand Up @@ -72,7 +72,7 @@ The walkthrough in [First server](docs/get-started/first-server.md) explains eac
## Build a client

```php
use Mcp\Client;
use Mcp\Client\Client;
use Mcp\Client\Transport\StdioTransport;

$client = Client::builder()
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"Mcp\\Tests\\": "tests/"
},
"classmap": [
"tests/Unit/Capability/Discovery/Fixtures/AlternativeFileNameToolHandler.class.inc"
"tests/Unit/Server/Capability/Discovery/Fixtures/AlternativeFileNameToolHandler.class.inc"
]
},
"config": {
Expand Down
6 changes: 3 additions & 3 deletions docs/advanced/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ The MCP SDK provides a PSR-14 compatible event system that allows you to hook in
Configure an event dispatcher when building your server:

```php
use Mcp\Event\RequestEvent;
use Mcp\Server;
use Mcp\Server\Event\RequestEvent;
use Mcp\Server\Server;
use Symfony\Component\EventDispatcher\EventDispatcher;

$dispatcher = new EventDispatcher();
Expand Down Expand Up @@ -86,7 +86,7 @@ These events are dispatched when the lists of available capabilities change:
These events carry no data and are used to notify clients that they should refresh their capability lists.

```php
use Mcp\Event\ToolListChangedEvent;
use Mcp\Server\Event\ToolListChangedEvent;

$dispatcher->addListener(ToolListChangedEvent::class, function (ToolListChangedEvent $event) {
$logger->info('Tool list has changed, clients should refresh');
Expand Down
6 changes: 3 additions & 3 deletions docs/advanced/extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ the SDK places the advertisement correctly for whichever era the client speaks:

```php
use Mcp\Schema\Extension\Apps\McpApps;
use Mcp\Server;
use Mcp\Server\Server;

$server = Server::builder()
->setServerInfo('My Server', '1.0.0')
Expand Down Expand Up @@ -112,11 +112,11 @@ descriptor marker: `McpApps::resourceMarker()` is a method call and cannot appea
in an attribute, so spell it as `new \stdClass()` there.

```php
use Mcp\Capability\Attribute\McpResource;
use Mcp\Capability\Attribute\McpTool;
use Mcp\Schema\Extension\Apps\McpApps;
use Mcp\Schema\Extension\Apps\ToolVisibility;
use Mcp\Schema\Extension\Apps\UiToolMeta;
use Mcp\Server\Capability\Attribute\McpResource;
use Mcp\Server\Capability\Attribute\McpTool;

final class WeatherApp
{
Expand Down
2 changes: 1 addition & 1 deletion docs/client/connecting.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The `Client\Builder` provides fluent configuration of client instances.
### Basic Configuration

```php
use Mcp\Client;
use Mcp\Client\Client;

$client = Client::builder()
->setClientInfo('My Application', '1.0.0', 'Description of my client')
Expand Down
8 changes: 4 additions & 4 deletions docs/client/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ The client throws exceptions for various error conditions:
Thrown when connection or initialization fails:

```php
use Mcp\Exception\ConnectionException;
use Mcp\Client\Exception\ConnectionException;

try {
$client->connect($transport);
Expand All @@ -21,7 +21,7 @@ try {
Thrown when a request returns an error response:

```php
use Mcp\Exception\RequestException;
use Mcp\Client\Exception\RequestException;

try {
$result = $client->callTool('unknown_tool', []);
Expand All @@ -38,12 +38,12 @@ Here's a comprehensive example demonstrating client usage:
```php-file
<?php

use Mcp\Client;
use Mcp\Client\Client;
use Mcp\Client\Handler\Notification\LoggingNotificationHandler;
use Mcp\Client\Handler\Request\SamplingCallbackInterface;
use Mcp\Client\Handler\Request\SamplingRequestHandler;
use Mcp\Client\Transport\StdioTransport;
use Mcp\Exception\SamplingException;
use Mcp\Client\Exception\SamplingException;
use Mcp\Schema\ClientCapabilities;
use Mcp\Schema\Content\TextContent;
use Mcp\Schema\Enum\LoggingLevel;
Expand Down
2 changes: 1 addition & 1 deletion docs/client/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ discover what it offers, and call it. The API is synchronous — every method re
result or throws.

```php
use Mcp\Client;
use Mcp\Client\Client;
use Mcp\Client\Transport\StdioTransport;

// Build and configure the client
Expand Down
11 changes: 5 additions & 6 deletions docs/client/server-requests.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ needs; your callback presents them to the user and returns an `ElicitResult` wit
three actions — accept (with the collected content), decline, or cancel:

```php
use Mcp\Client\Handler\Request\ElicitationRequestHandler;
use Mcp\Client\Handler\Request\ElicitationCallbackInterface;
use Mcp\Exception\ElicitationException;
use Mcp\Client\Handler\Request\ElicitationRequestHandler;
use Mcp\Schema\ClientCapabilities;
use Mcp\Schema\Enum\ElicitAction;
use Mcp\Schema\Enum\ElicitationMode;
Expand Down Expand Up @@ -84,14 +83,14 @@ elicitation demo server.
Handle server requests for LLM completions:

```php
use Mcp\Client\Handler\Request\SamplingRequestHandler;
use Mcp\Client\Exception\SamplingException;
use Mcp\Client\Handler\Request\SamplingCallbackInterface;
use Mcp\Exception\SamplingException;
use Mcp\Client\Handler\Request\SamplingRequestHandler;
use Mcp\Schema\ClientCapabilities;
use Mcp\Schema\Request\CreateSamplingMessageRequest;
use Mcp\Schema\Result\CreateSamplingMessageResult;
use Mcp\Schema\Content\TextContent;
use Mcp\Schema\Enum\Role;
use Mcp\Schema\Request\CreateSamplingMessageRequest;
use Mcp\Schema\Result\CreateSamplingMessageResult;

class LlmSamplingCallback implements SamplingCallbackInterface
{
Expand Down
6 changes: 3 additions & 3 deletions docs/get-started/first-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ your `vendor/` directory:

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

use Mcp\Capability\Attribute\McpResource;
use Mcp\Capability\Attribute\McpTool;
use Mcp\Server;
use Mcp\Server\Capability\Attribute\McpResource;
use Mcp\Server\Capability\Attribute\McpTool;
use Mcp\Server\Server;
use Mcp\Server\Transport\StdioTransport;

class Calculator
Expand Down
2 changes: 1 addition & 1 deletion docs/handlers/client-communication.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Every reference of a MCP element, that translates to an actual method call, can
`RequestContext` and the SDK will take care to include the gateway in the arguments of the method call:

```php
use Mcp\Capability\Attribute\McpTool;
use Mcp\Server\Capability\Attribute\McpTool;
use Mcp\Server\RequestContext;

class MyService
Expand Down
2 changes: 1 addition & 1 deletion docs/handlers/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ protocol. Type-hint a `Mcp\Server\RequestContext` argument anywhere in the signa
the SDK passes it in — that object is the way back to the client mid-request.

```php
use Mcp\Capability\Attribute\McpTool;
use Mcp\Schema\Content\TextContent;
use Mcp\Server\Capability\Attribute\McpTool;
use Mcp\Server\RequestContext;

#[McpTool]
Expand Down
2 changes: 1 addition & 1 deletion docs/handlers/logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Level **warning** is the default level, so anything below it is dropped until th
The SDK automatically injects a `RequestContext` instance into handlers. This can be used to create a `ClientLogger`.

```php
use Mcp\Capability\Attribute\McpTool;
use Mcp\Server\Capability\Attribute\McpTool;
use Mcp\Server\RequestContext;

#[McpTool]
Expand Down
6 changes: 3 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ Create a file `server.php`:

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

use Mcp\Capability\Attribute\McpResource;
use Mcp\Capability\Attribute\McpTool;
use Mcp\Server;
use Mcp\Server\Capability\Attribute\McpResource;
use Mcp\Server\Capability\Attribute\McpTool;
use Mcp\Server\Server;
use Mcp\Server\Transport\StdioTransport;

class Calculator
Expand Down
2 changes: 1 addition & 1 deletion docs/run/authorization.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Authorization in MCP is implemented at the transport level using PSR-15 middlewa
## Quick Start

```php
use Mcp\Server;
use Mcp\Server\Server;
use Mcp\Server\Transport\Http\Middleware\AuthorizationMiddleware;
use Mcp\Server\Transport\Http\Middleware\OAuthRequestMetaMiddleware;
use Mcp\Server\Transport\Http\Middleware\ProtectedResourceMetadataMiddleware;
Expand Down
24 changes: 12 additions & 12 deletions docs/run/framework-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ Here's a simplified example using PSR-17 discovery and Laminas emitter:

```php
use Http\Discovery\Psr17Factory;
use Mcp\Server;
use Mcp\Server\Transport\StreamableHttpTransport;
use Mcp\Server\Session\FileSessionStore;
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
use Mcp\Server\Server;
use Mcp\Server\Session\FileSessionStore;
use Mcp\Server\Transport\StreamableHttpTransport;

$psr17Factory = new Psr17Factory();
$request = $psr17Factory->createServerRequestFromGlobals();
Expand Down Expand Up @@ -57,13 +57,13 @@ Then create a controller that uses Symfony's PSR-7 bridge:

```php
// In a Symfony controller
use Mcp\Server\Server;
use Mcp\Server\Transport\StreamableHttpTransport;
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
use Mcp\Server;
use Mcp\Server\Transport\StreamableHttpTransport;

class McpController
{
Expand Down Expand Up @@ -99,10 +99,10 @@ Then create a controller that type-hints `ServerRequestInterface`:

```php
// In a Laravel controller
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Mcp\Server;
use Mcp\Server\Server;
use Mcp\Server\Transport\StreamableHttpTransport;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class McpController
{
Expand All @@ -128,9 +128,9 @@ Slim Framework works natively with PSR-7.
Create a route handler using Slim's built-in factories and container:

```php
use Slim\Factory\AppFactory;
use Mcp\Server;
use Mcp\Server\Server;
use Mcp\Server\Transport\StreamableHttpTransport;
use Slim\Factory\AppFactory;

$app = AppFactory::create();

Expand Down
2 changes: 1 addition & 1 deletion docs/run/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ exhaust memory. A value below `1` throws `InvalidArgumentException`.

A JSON-RPC batch (top-level array) is capped at 100 messages. Oversized batches are rejected before any
message is constructed, so a single small request cannot amplify into arbitrarily many operations. The cap
lives on `Mcp\JsonRpc\MessageFactory` and is not currently configurable through the builder — a server built
lives on `Mcp\Schema\MessageFactory` and is not currently configurable through the builder — a server built
with `Server::builder()` always uses the default of 100.

Single-message vs batch is determined from the decoded JSON type — a JSON object is a single message, a JSON array
Expand Down
2 changes: 1 addition & 1 deletion docs/run/protocol-eras.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
which of them answers. There is nothing to configure:

```php
use Mcp\Server;
use Mcp\Server\Server;
use Mcp\Server\Transport\StreamableHttpTransport;

$server = Server::builder()
Expand Down
14 changes: 7 additions & 7 deletions docs/run/server-builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ There are two ways to obtain a server builder instance:
### Method 1: Static Builder Method (Recommended)

```php
use Mcp\Server;
use Mcp\Server\Server;

$server = Server::builder()
->setServerInfo('My MCP Server', '1.0.0')
Expand Down Expand Up @@ -41,7 +41,7 @@ Set the server's identity with name, version, and optional description:

```php
use Mcp\Schema\Icon;
use Mcp\Server;
use Mcp\Server\Server;

$server = Server::builder()
->setServerInfo(
Expand Down Expand Up @@ -204,7 +204,7 @@ The container is used to resolve handlers and their dependencies when handlers i
The SDK includes a basic container with simple auto-wiring capabilities.

```php
use Mcp\Capability\Registry\Container;
use Mcp\Server\Capability\Registry\Container;

// Use the default basic container
$container = new Container();
Expand Down Expand Up @@ -254,13 +254,13 @@ $server = Server::builder()
Here's a comprehensive example showing all major configuration options:

```php
use Mcp\Server;
use Mcp\Server\Capability\Registry\Container;
use Mcp\Server\Server;
use Mcp\Server\Session\FileSessionStore;
use Mcp\Capability\Registry\Container;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Psr16Cache;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

// Setup dependencies
$logger = new Logger('mcp-server');
Expand Down
2 changes: 1 addition & 1 deletion docs/run/stdio.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ declare(strict_types=1);

require_once __DIR__ . '/vendor/autoload.php';

use Mcp\Server;
use Mcp\Server\Server;
use Mcp\Server\Transport\StdioTransport;

$server = Server::builder()
Expand Down
4 changes: 2 additions & 2 deletions docs/servers/completions.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Completion providers help MCP clients offer auto-completion suggestions for Reso
Provide a static list of possible values:

```php
use Mcp\Capability\Attribute\CompletionProvider;
use Mcp\Server\Capability\Attribute\CompletionProvider;

#[McpPrompt]
public function generateContent(
Expand Down Expand Up @@ -63,7 +63,7 @@ public function getTask(
For dynamic completion logic:

```php
use Mcp\Capability\Completion\ProviderInterface;
use Mcp\Server\Capability\Completion\ProviderInterface;

class UserIdCompletionProvider implements ProviderInterface
{
Expand Down
Loading