diff --git a/.gitattributes b/.gitattributes index b7b2a18d3..cd92b2325 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,6 +4,7 @@ /examples export-ignore /tests export-ignore /.php-cs-fixer.dist.php export-ignore +/deptrac.yaml export-ignore /Makefile export-ignore /mkdocs.yml export-ignore /requirements-docs.txt export-ignore diff --git a/.github/workflows/pipeline.yaml b/.github/workflows/pipeline.yaml index 3d0552897..184107cd2 100644 --- a/.github/workflows/pipeline.yaml +++ b/.github/workflows/pipeline.yaml @@ -338,6 +338,9 @@ jobs: - name: PHPStan run: vendor/bin/phpstan analyse + - name: Package boundaries + run: vendor/bin/deptrac analyse + # Only the phpDocumentor half: this job is PHP-only, and the Zensical # guides are built (strictly) by the Documentation workflow. - name: Documentation diff --git a/.gitignore b/.gitignore index d786517e4..6a681b6cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .phpunit.cache .php-cs-fixer.cache +.deptrac.cache composer.lock coverage vendor diff --git a/AGENTS.md b/AGENTS.md index 302b32e36..0a8f6bfbb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,9 +11,10 @@ It is a PHP Foundation × Symfony collaboration and follows Symfony's coding sta composer install npm ci --include=dev --prefix tests/Interop # once; without it the interop suite fails with setup noise -make ci # composer update --prefer-stable, cs, phpstan, all PHPUnit suites +make ci # composer update --prefer-stable, cs, phpstan, deptrac, all PHPUnit suites make cs # php-cs-fixer (auto-fixes; @Symfony + @Symfony:risky + file header) make phpstan # static analysis (phpstan.dist.neon + phpstan-baseline.neon) +make deptrac # package boundaries: Schema depends on nothing, Client and Server on Schema only make unit-tests # tests/Unit make integration-tests # tests/Integration — our client against our server make interop-tests # tests/Interop — needs Node; MCP Inspector + TS reference server @@ -73,13 +74,13 @@ by issuing real `elicitation/create`/`sampling/createMessage` requests and re-ru ### Capabilities (tools, resources, prompts) -- Elements are declared with attributes (`Capability\Attribute\McpTool`, `McpResource`, `McpPrompt`, …) or registered +- Elements are declared with attributes (`Server\Capability\Attribute\McpTool`, `McpResource`, `McpPrompt`, …) or registered explicitly on the builder. -- `Capability\Registry\Loader\*` populate the `Registry`: `DiscoveryLoader` scans directories (needs +- `Server\Capability\Registry\Loader\*` populate the `Registry`: `DiscoveryLoader` scans directories (needs `symfony/finder`), `ReflectedElementLoader` handles `addTool()` & co, `ExplicitElementLoader` handles `Builder::add()`, chained by `ChainLoader`. -- `Capability\Discovery\*` derives JSON schemas from signatures and docblocks; `Registry\ReferenceHandler` invokes the - element, injecting `RequestContext` and container services; `Capability\Formatter\*` turns return values into +- `Server\Capability\Discovery\*` derives JSON schemas from signatures and docblocks; `Registry\ReferenceHandler` invokes the + element, injecting `RequestContext` and container services; `Server\Capability\Formatter\*` turns return values into content. ### Client @@ -92,13 +93,14 @@ and reconnect policy). `Schema\*` holds the MCP types (requests, results, notifications, content, enums) as immutable value objects serialized via `jsonSerialize()`; requests and notifications extend `Schema\JsonRpc\Request`/`Notification` and -implement `getMethod()`, `fromParams()` and `getParams()`. `JsonRpc\*` parses and builds raw messages. `Schema\Extension\*` is the generic seam +implement `getMethod()`, `fromParams()` and `getParams()`. `Schema\MessageFactory` parses raw messages. `Schema\Extension\*` is the generic seam for protocol extensions (`ExtensionInterface`, e.g. `Apps`); core handlers, `RequestContext` and `Client` must not reference concrete extension types. ## Conventions -- Throw `Mcp\Exception\*` (all implement `ExceptionInterface`), never native SPL exceptions. +- Throw the `Exception\*` of the package you are in (`Mcp\Schema`, `Mcp\Client` or `Mcp\Server`; all implement + `Mcp\Schema\Exception\ExceptionInterface`), never native SPL exceptions. - No `suggest` in `composer.json`: code that needs an optional package or extension checks for it and throws an exception that names what to install. - Add an `@author` tag to newly introduced classes. diff --git a/CHANGELOG.md b/CHANGELOG.md index ec77cdb12..072035e50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,27 @@ All notable changes to `mcp/sdk` will be documented in this file. * [BC Break] Require PHP 8.2 or higher, as PHP 8.1 reached its end of life. +### Namespaces + +* [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,RequestCancelledException,RequestException,RootsException,SamplingException,TimeoutException}` => `Mcp\Client\Exception\*` + * `Mcp\Exception\{BadMethodCallException,ClientException,ConfigurationException,ContainerException,InvalidCursorException,MissingRequiredClientCapabilityException,NotFoundExceptionInterface,PromptGetException,PromptNotFoundException,RegistryException,RequestStateException,ResourceNotFoundException,ResourceReadException,ServiceNotFoundException,SessionLockException,SessionLockTimeoutException,SessionStoreException,ToolCallException,ToolNotFoundException}` => `Mcp\Server\Exception\*` + * `Mcp\Exception\HandlerNotFoundException` is removed; it was 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. + +* [BC Break] Move `ExtensionInterface::getRequestHandlers()` to the new `Mcp\Server\Extension\ServerExtensionInterface`, so `Mcp\Schema` does not reference `Mcp\Server`. `AbstractExtension` no longer defines it. An extension that serves its methods must implement the new interface, or `Builder::enableExtension()` does not register its handlers. + ### Server * [BC Break] Refuse an OAuth URL whose host is `0.0.0.0`, `::`, an IPv4 address within IPv6 or an IPv4 address in a non-standard form (e.g. `127.1`), or that holds percent-encoding or non-ASCII characters (an internationalized name must be given in punycode), for the issuer, the `jwks_uri` and the resource. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1160701cf..68dfaf6a5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,7 +31,7 @@ make ci ``` This runs, in order: `make deps-stable` (`composer update --prefer-stable`), `make cs` -(PHP CS Fixer, auto-fixes style), `make phpstan` (static analysis) and `make tests` (all PHPUnit +(PHP CS Fixer, auto-fixes style), `make phpstan` (static analysis), `make deptrac` (package boundaries) and `make tests` (all PHPUnit suites). All of them must pass. The interop suite runs against Node packages. Install them once before you run `make ci` or diff --git a/Makefile b/Makefile index c0234c7b2..b2816e564 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: deps-stable deps-low cs phpstan tests unit-tests integration-tests interop-tests e2e-tests coverage ci ci-stable ci-lowest conformance-tests conformance-server conformance-client conformance-client-extensions conformance-draft conformance-draft-server conformance-draft-client docs docs-guides docs-api docs-serve +.PHONY: deps-stable deps-low cs phpstan deptrac tests unit-tests integration-tests interop-tests e2e-tests coverage ci ci-stable ci-lowest conformance-tests conformance-server conformance-client conformance-client-extensions conformance-draft conformance-draft-server conformance-draft-client docs docs-guides docs-api docs-serve # The 2026-07-28 scenarios ship on the `alpha` dist-tag; `latest` (0.1.x) has # none of them. Pinned to the same version CI runs (see @@ -23,6 +23,9 @@ cs: phpstan: vendor/bin/phpstan --memory-limit=-1 +deptrac: + vendor/bin/deptrac analyse + tests: vendor/bin/phpunit @@ -83,9 +86,9 @@ coverage: ci: ci-stable -ci-stable: deps-stable cs phpstan tests +ci-stable: deps-stable cs phpstan deptrac tests -ci-lowest: deps-low cs phpstan tests +ci-lowest: deps-low cs phpstan deptrac tests # The published site is the guides (Zensical) with the phpDocumentor API # reference mounted at /api/. `zensical build` wipes site/, so it runs first. diff --git a/README.md b/README.md index 7918f2c4c..376ed1663 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,9 @@ A server is a plain PHP class plus a few lines of wiring: 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 @@ -84,7 +84,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() diff --git a/composer.json b/composer.json index fbeed9b94..50abc999c 100644 --- a/composer.json +++ b/composer.json @@ -39,6 +39,7 @@ "amphp/amp": "^3.0", "amphp/http-server": "^3.3", "composer/semver": "^3.0", + "deptrac/deptrac": "^3.0", "firebase/php-jwt": "^6.10 || ^7.0", "laminas/laminas-httphandlerrunner": "^2.12", "nyholm/psr7": "^1.8", @@ -92,7 +93,7 @@ "Mcp\\Tests\\": "tests/" }, "classmap": [ - "tests/Unit/Capability/Discovery/Fixtures/AlternativeFileNameToolHandler.class.inc" + "tests/Unit/Server/Capability/Discovery/Fixtures/AlternativeFileNameToolHandler.class.inc" ] }, "config": { diff --git a/deptrac.yaml b/deptrac.yaml new file mode 100644 index 000000000..a8c358cf4 --- /dev/null +++ b/deptrac.yaml @@ -0,0 +1,22 @@ +deptrac: + paths: + - ./src + layers: + - name: Schema + collectors: + - type: classLike + value: ^Mcp\\Schema\\.* + - name: Client + collectors: + - type: classLike + value: ^Mcp\\Client\\.* + - name: Server + collectors: + - type: classLike + value: ^Mcp\\Server\\.* + ruleset: + Schema: ~ + Client: + - Schema + Server: + - Schema diff --git a/docs/advanced/custom-handlers.md b/docs/advanced/custom-handlers.md index 4b846cd22..cd12704ce 100644 --- a/docs/advanced/custom-handlers.md +++ b/docs/advanced/custom-handlers.md @@ -25,7 +25,7 @@ built-in defaults: ```php use Mcp\Schema\ServerCapabilities; -use Mcp\Server; +use Mcp\Server\Server; $server = Server::builder() // the SDK detects capabilities from registered elements, so declare what your handlers serve @@ -65,7 +65,7 @@ return anything - they perform side effects only. Attach notification handlers with `addNotificationHandler()` (single) or `addNotificationHandlers()` (multiple): ```php -use Mcp\Server; +use Mcp\Server\Server; // Handlers are your own classes implementing NotificationHandlerInterface; // the SDK ships only its internal ones. diff --git a/docs/advanced/events.md b/docs/advanced/events.md index 23ac7ebe0..56f3fc670 100644 --- a/docs/advanced/events.md +++ b/docs/advanced/events.md @@ -8,8 +8,8 @@ Configure an event dispatcher when building your server. This example uses `symf implementation you can install with `composer require symfony/event-dispatcher`: ```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(); @@ -137,9 +137,9 @@ To change the lists at runtime and react to it, create the registry yourself and `setEventDispatcher()` doesn't reach a registry you pass with `setRegistry()`: ```php -use Mcp\Capability\Registry; -use Mcp\Event\ToolListChangedEvent; -use Mcp\Server; +use Mcp\Server\Capability\Registry; +use Mcp\Server\Event\ToolListChangedEvent; +use Mcp\Server\Server; use Psr\Log\LoggerInterface; use Symfony\Component\EventDispatcher\EventDispatcher; diff --git a/docs/advanced/extensions.md b/docs/advanced/extensions.md index 2a5d84c68..989926d76 100644 --- a/docs/advanced/extensions.md +++ b/docs/advanced/extensions.md @@ -7,7 +7,7 @@ A server opts in with `Builder::enableExtension()`. The SDK announces the extens ```php use Mcp\Schema\Extension\Apps\McpApps; -use Mcp\Server; +use Mcp\Server\Server; $server = Server::builder() ->setServerInfo('My Server', '1.0.0') @@ -82,10 +82,11 @@ Enable it with `Builder::enableExtension(new AuditExtension())`. A prefix whose second label is `modelcontextprotocol` or `mcp` (e.g. `io.modelcontextprotocol/`) is reserved for official extensions. The SDK doesn't refuse such an identifier, so choose a prefix of your own. -An extension that adds JSON-RPC methods also implements `getMessages()` and -`getRequestHandlers()`. `getMessages()` returns the request and notification classes of the -new methods, so the SDK can parse them. `getRequestHandlers()` returns the -[request handlers](custom-handlers.md) that answer them. If two enabled extensions define +An extension that adds JSON-RPC methods also implements `getMessages()`, which returns the +request and notification classes of the new methods, so the SDK can parse them. To answer +those methods on a server, it implements `Mcp\Server\Extension\ServerExtensionInterface`, +whose `getRequestHandlers()` returns the [request handlers](custom-handlers.md) that answer +them. If two enabled extensions define the same method, `enableExtension()` throws a `LogicException`. Extensions bring no notification handlers: add those with `Builder::addNotificationHandler()`. They [don't run on revision `2026-07-28`](custom-handlers.md#protocol-2026-07-28). @@ -111,7 +112,7 @@ use Mcp\Schema\Extension\Apps\UiResourceContentMeta; use Mcp\Schema\Extension\Apps\UiResourceCsp; use Mcp\Schema\Extension\Apps\UiResourcePermissions; use Mcp\Schema\Extension\Apps\UiToolMeta; -use Mcp\Server; +use Mcp\Server\Server; $server = Server::builder() ->enableExtension(new McpApps()) @@ -157,12 +158,12 @@ 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\Content\TextResourceContents; 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 { diff --git a/docs/client/authorization.md b/docs/client/authorization.md index f3a056c2e..6c566693d 100644 --- a/docs/client/authorization.md +++ b/docs/client/authorization.md @@ -3,7 +3,7 @@ A remote MCP server can require an OAuth access token. It answers a request without a token with `401 Unauthorized`. Pass an authenticator to the HTTP transport and the client gets a token and sends the request again: ```php -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Auth\OAuth; use Mcp\Client\Transport\HttpTransport; @@ -120,7 +120,7 @@ When the client needs a token, the handler throws an `AuthorizationPendingExcept ```php use Mcp\Client\Transport\HttpTransport; -use Mcp\Exception\AuthorizationPendingException; +use Mcp\Client\Exception\AuthorizationPendingException; try { $client->connect(new HttpTransport('https://mcp.example.com/mcp', auth: createAuthenticator())); @@ -307,8 +307,8 @@ A `resource` can name a parent path of the MCP server. All paths below it then b `connect()` reports a failed authorization as a `ConnectionException`. The cause is an `AuthorizationException`: ```php -use Mcp\Exception\AuthorizationException; -use Mcp\Exception\ConnectionException; +use Mcp\Client\Exception\AuthorizationException; +use Mcp\Client\Exception\ConnectionException; try { $client->connect($transport); diff --git a/docs/client/connecting.md b/docs/client/connecting.md index 7c7006448..8c1ab669e 100644 --- a/docs/client/connecting.md +++ b/docs/client/connecting.md @@ -12,7 +12,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') diff --git a/docs/client/errors.md b/docs/client/errors.md index 37a3c8cbc..4f2b4f732 100644 --- a/docs/client/errors.md +++ b/docs/client/errors.md @@ -1,9 +1,9 @@ # Error handling -Every exception `Client` throws implements `Mcp\Exception\ExceptionInterface`. Catch it to handle +Every exception `Client` throws implements `Mcp\Schema\Exception\ExceptionInterface`. Catch it to handle client errors in one place. Creating an `HttpTransport` is different: if no PSR-18 client or PSR-17 factory can be found, the constructor throws an exception from `php-http/discovery`. All classes below -live in the `Mcp\Exception` namespace: +live in the `Mcp\Client\Exception` namespace: | Exception | Thrown when | | --- | --- | @@ -21,7 +21,7 @@ wait for the request timeout. ## ConnectionException ```php -use Mcp\Exception\ConnectionException; +use Mcp\Client\Exception\ConnectionException; try { $client->connect($transport); @@ -31,14 +31,14 @@ try { ``` A malformed result during `connect()` also throws a `ConnectionException`. In this case, `$e->getPrevious()` -returns the `InvalidArgumentException`. +returns the `Mcp\Schema\Exception\InvalidArgumentException`. ## AuthorizationException This exception also reports a failed [authorization](authorization.md) flow. The message of a refused request contains the `WWW-Authenticate` header of the response, if the server sends one: ```php -use Mcp\Exception\AuthorizationException; +use Mcp\Client\Exception\AuthorizationException; try { $result = $client->callTool('get_weather', ['city' => 'Paris']); @@ -52,7 +52,7 @@ During `connect()`, the client doesn't retry the request. It throws a `Connectio ## RequestException ```php -use Mcp\Exception\RequestException; +use Mcp\Client\Exception\RequestException; try { $result = $client->callTool('unknown_tool', []); @@ -68,8 +68,8 @@ Thrown when the request timeout or the `timeoutSeconds` of a `callTool()` call r `RequestException`, so catch it first to tell a timeout from an error response: ```php -use Mcp\Exception\RequestException; -use Mcp\Exception\TimeoutException; +use Mcp\Client\Exception\RequestException; +use Mcp\Client\Exception\TimeoutException; try { $result = $client->callTool('slow_tool', []); @@ -102,7 +102,7 @@ This script connects to a `server.php` next to it, which provides a `process_dat require __DIR__.'/vendor/autoload.php'; -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Handler\Request\ElicitationCallbackInterface; use Mcp\Client\Handler\Request\ElicitationRequestHandler; use Mcp\Client\Transport\StdioTransport; diff --git a/docs/client/index.md b/docs/client/index.md index 2682c07d9..cfe761fe3 100644 --- a/docs/client/index.md +++ b/docs/client/index.md @@ -6,7 +6,7 @@ result or throws. A tool can report its own failure in the result, see [Tool errors](errors.md#tool-errors). ```php -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Transport\StdioTransport; // Build and configure the client diff --git a/docs/client/server-requests.md b/docs/client/server-requests.md index a2deac126..2ae57e384 100644 --- a/docs/client/server-requests.md +++ b/docs/client/server-requests.md @@ -18,10 +18,9 @@ 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; -use Mcp\Client\Handler\Request\ElicitationRequestHandler; +use Mcp\Client\Client; use Mcp\Client\Handler\Request\ElicitationCallbackInterface; -use Mcp\Exception\ElicitationException; +use Mcp\Client\Handler\Request\ElicitationRequestHandler; use Mcp\Schema\ClientCapabilities; use Mcp\Schema\Elicitation\AbstractSchemaDefinition; use Mcp\Schema\Elicitation\BooleanSchemaDefinition; @@ -145,15 +144,15 @@ elicitation demo server. Handle server requests for LLM completions: ```php -use Mcp\Client; -use Mcp\Client\Handler\Request\SamplingRequestHandler; +use Mcp\Client\Client; +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 { @@ -202,7 +201,7 @@ Clients that support tool-enabled sampling should advertise that capability and `ToolUseContent` blocks: ```php -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Handler\Request\SamplingRequestHandler; use Mcp\Schema\ClientCapabilities; use Mcp\Schema\Content\ToolUseContent; @@ -263,7 +262,7 @@ blocks in a user message. The client should pass those blocks back to the LLM pr Receive structured log messages from the server: ```php -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Handler\Notification\LoggingNotificationHandler; use Mcp\Schema\Enum\LoggingLevel; use Mcp\Schema\Notification\LoggingMessageNotification; @@ -302,7 +301,7 @@ is allowed to operate on. Advertise the `roots` capability and register a handle that answers server `roots/list` requests: ```php -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Handler\Request\ListRootsRequestHandler; use Mcp\Client\Handler\Request\RootsCallbackInterface; use Mcp\Schema\ClientCapabilities; diff --git a/docs/get-started/first-server.md b/docs/get-started/first-server.md index afb27103e..fce9010ff 100644 --- a/docs/get-started/first-server.md +++ b/docs/get-started/first-server.md @@ -8,9 +8,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 diff --git a/docs/get-started/inspector.md b/docs/get-started/inspector.md index 8d23f9df6..9b2c0e4b3 100644 --- a/docs/get-started/inspector.md +++ b/docs/get-started/inspector.md @@ -29,7 +29,7 @@ so it fails under `php -S`: ```php title="server.php (HTTP variant)" use Http\Discovery\Psr17Factory; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; use Mcp\Server\Transport\StreamableHttpTransport; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; diff --git a/docs/handlers/client-communication.md b/docs/handlers/client-communication.md index dc190a4a0..f893400e7 100644 --- a/docs/handlers/client-communication.md +++ b/docs/handlers/client-communication.md @@ -18,7 +18,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 diff --git a/docs/handlers/index.md b/docs/handlers/index.md index d15aa7949..059c0521d 100644 --- a/docs/handlers/index.md +++ b/docs/handlers/index.md @@ -5,9 +5,9 @@ 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\Elicitation\ElicitationSchema; use Mcp\Schema\Elicitation\StringSchemaDefinition; +use Mcp\Server\Capability\Attribute\McpTool; use Mcp\Server\RequestContext; #[McpTool] diff --git a/docs/handlers/logging.md b/docs/handlers/logging.md index 58e8589ed..712c154c4 100644 --- a/docs/handlers/logging.md +++ b/docs/handlers/logging.md @@ -25,7 +25,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] diff --git a/docs/index.md b/docs/index.md index 16e5acef5..8edb89e6c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -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 diff --git a/docs/protocol-versions.md b/docs/protocol-versions.md index ac9fb71bd..5b29d1473 100644 --- a/docs/protocol-versions.md +++ b/docs/protocol-versions.md @@ -113,7 +113,7 @@ A client speaks both eras out of the box. It prefers `2026-07-28`, and finds out depends on the answer. ```php -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Transport\HttpTransport; use Mcp\Schema\ClientCapabilities; diff --git a/docs/run/authorization.md b/docs/run/authorization.md index c88cc0d53..3c10e220b 100644 --- a/docs/run/authorization.md +++ b/docs/run/authorization.md @@ -56,7 +56,7 @@ composer require firebase/php-jwt symfony/cache symfony/http-client nyholm/psr7 ```php use Http\Discovery\Psr17Factory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Transport\Http\Middleware\AuthorizationMiddleware; use Mcp\Server\Transport\Http\Middleware\CorsMiddleware; use Mcp\Server\Transport\Http\Middleware\DnsRebindingProtectionMiddleware; @@ -325,7 +325,7 @@ The validated token reaches handlers through the `RequestContext`. It lives for arrived with only: it is never written to a session store. ```php -use Mcp\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\McpTool; use Mcp\Server\RequestContext; #[McpTool(name: 'whoami')] diff --git a/docs/run/framework-integration.md b/docs/run/framework-integration.md index 14d13af35..5dcf9c709 100644 --- a/docs/run/framework-integration.md +++ b/docs/run/framework-integration.md @@ -30,10 +30,10 @@ composer require nyholm/psr7 laminas/laminas-httphandlerrunner symfony/finder ```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(); @@ -69,13 +69,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 { @@ -111,11 +111,11 @@ Then create a controller that type-hints `ServerRequestInterface`: ```php // In a Laravel controller +use Mcp\Server\Server; +use Mcp\Server\Transport\StreamableHttpTransport; use Psr\Http\Message\ServerRequestInterface; use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory; use Symfony\Component\HttpFoundation\Response; -use Mcp\Server; -use Mcp\Server\Transport\StreamableHttpTransport; class McpController { @@ -153,10 +153,10 @@ composer require slim/slim slim/psr7 symfony/finder 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\Session\FileSessionStore; use Mcp\Server\Transport\StreamableHttpTransport; +use Slim\Factory\AppFactory; $app = AppFactory::create(); diff --git a/docs/run/index.md b/docs/run/index.md index 276e70741..d1d836905 100644 --- a/docs/run/index.md +++ b/docs/run/index.md @@ -5,7 +5,7 @@ answering. `StdioTransport`, `StreamableHttpTransport` and `InMemoryTransport` i `TransportInterface` and are used the same way: ```php -use Mcp\Server; +use Mcp\Server\Server; $server = Server::builder() ->setServerInfo('My Server', '1.0.0') diff --git a/docs/run/protocol-eras.md b/docs/run/protocol-eras.md index 9f6017b20..0cf66980f 100644 --- a/docs/run/protocol-eras.md +++ b/docs/run/protocol-eras.md @@ -8,7 +8,7 @@ which of them answers. You don't need to configure this. Handshake-era clients r ```php use Http\Discovery\Psr17Factory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Transport\StreamableHttpTransport; $request = (new Psr17Factory())->createServerRequestFromGlobals(); @@ -125,11 +125,11 @@ the member it wants to change. `server/discover` dispatches the same `RequestEve (`composer require symfony/event-dispatcher`): ```php -use Mcp\Event\ResponseEvent; +use Mcp\Server\Event\ResponseEvent; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\DiscoverRequest; use Mcp\Schema\Result\DiscoverResult; -use Mcp\Server; +use Mcp\Server\Server; use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); @@ -215,7 +215,7 @@ dispatcher on its own and mount it on `StatelessHttpTransport`: use Http\Discovery\Psr17Factory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; use Mcp\Schema\Enum\ProtocolVersion; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Transport\StatelessHttpTransport; $request = (new Psr17Factory())->createServerRequestFromGlobals(); diff --git a/docs/run/server-builder.md b/docs/run/server-builder.md index 6f6799082..56cfbdc34 100644 --- a/docs/run/server-builder.md +++ b/docs/run/server-builder.md @@ -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') @@ -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( @@ -112,7 +112,7 @@ required to serve either one. Each knob is covered in depth elsewhere: ```php use Mcp\Schema\Enum\CacheScope; use Mcp\Schema\Enum\ProtocolVersion; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Stateless\OriginatingRequestBinder; use Mcp\Server\Subscription\Psr16NotificationBus; use Mcp\Server\Wire\CachePolicy; @@ -162,7 +162,7 @@ it. See **Required when using MCP attributes.** If you're using PHP attributes (`#[McpTool]`, `#[McpResource]`, `#[McpResourceTemplate]`, `#[McpPrompt]`) to define your MCP elements, you **MUST** configure discovery to tell the server where to look for these attributes. ```php -use Mcp\Server; +use Mcp\Server\Server; $server = Server::builder() ->setDiscovery( @@ -202,7 +202,7 @@ $server = Server::builder() **Production Setup with Caching:** ```php -use Mcp\Server; +use Mcp\Server\Server; use Symfony\Component\Cache\Adapter\FilesystemAdapter; // Cache discovered elements to avoid filesystem scanning on every server start @@ -235,7 +235,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(); @@ -372,7 +372,7 @@ Some libraries keep their context per fiber. For example, OpenTelemetry raises a in a fiber it doesn't know. Set a fiber context to carry the context of the caller into the fiber of the handler: ```php -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Fiber\FiberContextInterface; use OpenTelemetry\Context\Context; @@ -427,13 +427,13 @@ Fibers that a handler starts itself (e.g. with `Amp\async()`) don't get the cont 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 Symfony\Component\Cache\Adapter\FilesystemAdapter; use Monolog\Handler\StreamHandler; use Monolog\Level; use Monolog\Logger; +use Symfony\Component\Cache\Adapter\FilesystemAdapter; // Setup dependencies $logger = new Logger('mcp-server'); diff --git a/docs/run/sessions.md b/docs/run/sessions.md index 06a134446..fa4c539b9 100644 --- a/docs/run/sessions.md +++ b/docs/run/sessions.md @@ -10,7 +10,7 @@ serves handshake-era clients [without sessions](#serving-without-sessions). Over session, which stays in memory unless `setSession()` names a store. Configure session storage and lifecycle: ```php -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; use Mcp\Server\Session\InMemorySessionStore; use Mcp\Server\Session\Psr16SessionStore; diff --git a/docs/run/stdio.md b/docs/run/stdio.md index 0af849f66..1a46f4e1a 100644 --- a/docs/run/stdio.md +++ b/docs/run/stdio.md @@ -34,7 +34,7 @@ connection uses, see [Serving both eras](protocol-eras.md#over-stdio). require __DIR__.'/vendor/autoload.php'; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Transport\StdioTransport; $server = Server::builder() diff --git a/docs/run/subscriptions.md b/docs/run/subscriptions.md index f04a86baa..2c5327b01 100644 --- a/docs/run/subscriptions.md +++ b/docs/run/subscriptions.md @@ -38,8 +38,8 @@ without an event dispatcher, unless you pass your own registry with `setRegistry it to the bus yourself, and the builder announces `listChanged` for it: ```php -use Mcp\Capability\Registry; -use Mcp\Server; +use Mcp\Server\Capability\Registry; +use Mcp\Server\Server; use Mcp\Server\Subscription\InMemoryNotificationBus; use Mcp\Server\Subscription\PublishingEventDispatcher; diff --git a/docs/run/web-servers.md b/docs/run/web-servers.md index e63d8f135..bff927654 100644 --- a/docs/run/web-servers.md +++ b/docs/run/web-servers.md @@ -24,7 +24,7 @@ the rest of the project outside of it: use Http\Discovery\Psr17Factory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionLock; use Mcp\Server\Session\FileSessionStore; use Mcp\Server\Transport\Http\Middleware\CorsMiddleware; diff --git a/docs/servers/completions.md b/docs/servers/completions.md index 013d1b68c..4024da783 100644 --- a/docs/servers/completions.md +++ b/docs/servers/completions.md @@ -9,8 +9,8 @@ Completion providers help MCP clients offer auto-completion suggestions. The pro Provide a static list of possible values: ```php -use Mcp\Capability\Attribute\CompletionProvider; -use Mcp\Capability\Attribute\McpPrompt; +use Mcp\Server\Capability\Attribute\CompletionProvider; +use Mcp\Server\Capability\Attribute\McpPrompt; #[McpPrompt] public function generateContent( @@ -32,8 +32,8 @@ public function generateContent( Use enum values for completion: ```php -use Mcp\Capability\Attribute\CompletionProvider; -use Mcp\Capability\Attribute\McpResourceTemplate; +use Mcp\Server\Capability\Attribute\CompletionProvider; +use Mcp\Server\Capability\Attribute\McpResourceTemplate; enum Priority: string { @@ -79,9 +79,9 @@ Type the parameter as `string` instead. For dynamic completion logic: ```php -use Mcp\Capability\Attribute\CompletionProvider; -use Mcp\Capability\Attribute\McpResourceTemplate; -use Mcp\Capability\Completion\ProviderInterface; +use Mcp\Server\Capability\Attribute\CompletionProvider; +use Mcp\Server\Capability\Attribute\McpResourceTemplate; +use Mcp\Server\Capability\Completion\ProviderInterface; class UserIdCompletionProvider implements ProviderInterface { @@ -124,7 +124,7 @@ For a `Prompt` or `ResourceTemplate` registered with `Builder::add()`, pass the keys are the argument or variable names: ```php -use Mcp\Capability\Completion\ListCompletionProvider; +use Mcp\Server\Capability\Completion\ListCompletionProvider; // $prompt is an Mcp\Schema\Prompt, ContentPromptHandler implements PromptHandlerInterface $builder->add($prompt, new ContentPromptHandler(), [ @@ -132,5 +132,5 @@ $builder->add($prompt, new ContentPromptHandler(), [ ]); ``` -`Builder::add()` throws an `Mcp\Exception\InvalidArgumentException` if you pass providers with a `Tool` or a +`Builder::add()` throws an `Mcp\Server\Exception\InvalidArgumentException` if you pass providers with a `Tool` or a `ResourceDefinition`. See [Explicit element registration](registration.md#explicit-element-registration). diff --git a/docs/servers/prompts.md b/docs/servers/prompts.md index ddaed67df..1e2bc6391 100644 --- a/docs/servers/prompts.md +++ b/docs/servers/prompts.md @@ -3,7 +3,7 @@ Prompts generate templates for AI interactions. ```php -use Mcp\Capability\Attribute\McpPrompt; +use Mcp\Server\Capability\Attribute\McpPrompt; class PromptGenerator { @@ -108,8 +108,8 @@ Prompt handlers can throw any exception, but the type determines how it's handle - **Any other exception you throw from your handler**: Converted to JSON-RPC error response, but with a generic error message ```php -use Mcp\Capability\Attribute\McpPrompt; -use Mcp\Exception\PromptGetException; +use Mcp\Server\Capability\Attribute\McpPrompt; +use Mcp\Server\Exception\PromptGetException; #[McpPrompt] public function generatePrompt(string $topic, string $style): array diff --git a/docs/servers/registration.md b/docs/servers/registration.md index 4c1b151b0..445114c31 100644 --- a/docs/servers/registration.md +++ b/docs/servers/registration.md @@ -17,7 +17,7 @@ registration with `Builder::add()`. **Example:** ```php -use Mcp\Server; +use Mcp\Server\Server; $server = Server::builder() ->setDiscovery(__DIR__, ['.'], excludeDirs: ['vendor']) // Automatic discovery @@ -61,7 +61,7 @@ an invokable object, fail when the elements load: 4. **Invokable class name**: `InvokableClass::class` - class must be constructable through the container and have `__invoke` method !!! note - A custom loader implements `Mcp\Capability\Registry\Loader\LoaderInterface` and is added with `Builder::addLoader()`. It can register an element with the id of a callable service from your container as the handler (e.g. `app.weather_handler`). + A custom loader implements `Mcp\Server\Capability\Registry\Loader\LoaderInterface` and is added with `Builder::addLoader()`. It can register an element with the id of a callable service from your container as the handler (e.g. `app.weather_handler`). `addTool()`, `addResource()`, `addResourceTemplate()` and `addPrompt()` don't accept service ids. A bad handler fails when the elements load, by default on the first registry read. The SDK logs a `ConfigurationException` and answers that request with `-32603` `Internal server error.`. With `setLazyLoading(false)`, `build()` throws the exception. @@ -212,9 +212,9 @@ resource template handlers receive the URI and the parsed template variables. ```php use Mcp\Schema\Tool; -use Mcp\Server; use Mcp\Server\ClientGateway; use Mcp\Server\Handler\ToolHandlerInterface; +use Mcp\Server\Server; final class WeatherHandler implements ToolHandlerInterface { @@ -242,7 +242,7 @@ $server = Server::builder() ``` `Builder::add()` validates the pairing at registration time. Pairing a `Tool` definition with, for example, a -`PromptHandlerInterface` raises `Mcp\Exception\InvalidArgumentException`. +`PromptHandlerInterface` raises `Mcp\Server\Exception\InvalidArgumentException`. The schema value objects validate some of their own input as well. `Tool` requires an object-typed input schema. `ResourceDefinition` and `ResourceTemplate` check the URI. diff --git a/docs/servers/resource-templates.md b/docs/servers/resource-templates.md index 10e004e7b..c6c552359 100644 --- a/docs/servers/resource-templates.md +++ b/docs/servers/resource-templates.md @@ -10,8 +10,8 @@ cannot contain `/`. The SDK doesn't reject a template that uses them: it lists t template, but no real URI matches it. ```php -use Mcp\Capability\Attribute\McpResourceTemplate; -use Mcp\Exception\ResourceNotFoundException; +use Mcp\Server\Capability\Attribute\McpResourceTemplate; +use Mcp\Server\Exception\ResourceNotFoundException; class UserProvider { diff --git a/docs/servers/resources.md b/docs/servers/resources.md index 603abc65e..b39d0cee1 100644 --- a/docs/servers/resources.md +++ b/docs/servers/resources.md @@ -3,7 +3,7 @@ Resources provide access to static data that clients can read. ```php -use Mcp\Capability\Attribute\McpResource; +use Mcp\Server\Capability\Attribute\McpResource; class ConfigProvider { @@ -132,9 +132,9 @@ Resource handlers can throw any exception, but the type determines how it's hand - **Any other exception you throw from your handler**: Converted to JSON-RPC error response, but with a generic error message ```php -use Mcp\Capability\Attribute\McpResourceTemplate; -use Mcp\Exception\ResourceNotFoundException; -use Mcp\Exception\ResourceReadException; +use Mcp\Server\Capability\Attribute\McpResourceTemplate; +use Mcp\Server\Exception\ResourceNotFoundException; +use Mcp\Server\Exception\ResourceReadException; // A URI with variables needs a template, and a variable matches one path segment #[McpResourceTemplate(uriTemplate: 'docs://{name}')] diff --git a/docs/servers/schemas.md b/docs/servers/schemas.md index a7f9ea22f..b77f49345 100644 --- a/docs/servers/schemas.md +++ b/docs/servers/schemas.md @@ -16,7 +16,7 @@ The server follows this order of precedence: ## Automatic Schema from PHP Types ```php -use Mcp\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\McpTool; #[McpTool] public function processUser( @@ -33,7 +33,7 @@ public function processUser( The generator also reads these parts of the signature: ```php -use Mcp\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\McpTool; use Mcp\Server\RequestContext; enum Unit: string @@ -67,8 +67,8 @@ In this example: Add validation rules to specific parameters: ```php -use Mcp\Capability\Attribute\McpTool; -use Mcp\Capability\Attribute\Schema; +use Mcp\Server\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\Schema; #[McpTool] public function validateUser( @@ -95,8 +95,8 @@ public function validateUser( Add validation for complex object structures: ```php -use Mcp\Capability\Attribute\McpTool; -use Mcp\Capability\Attribute\Schema; +use Mcp\Server\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\Schema; #[McpTool] #[Schema( @@ -125,8 +125,8 @@ public function createUser(array $userData): array **Use sparingly** - bypasses all automatic inference: ```php -use Mcp\Capability\Attribute\McpTool; -use Mcp\Capability\Attribute\Schema; +use Mcp\Server\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\Schema; #[McpTool] #[Schema(definition: [ @@ -156,8 +156,8 @@ To replace the schema of one parameter only, put `definition` on the parameter. still added: ```php -use Mcp\Capability\Attribute\McpTool; -use Mcp\Capability\Attribute\Schema; +use Mcp\Server\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\Schema; #[McpTool] public function getForecast( @@ -224,7 +224,7 @@ The SDK also validates structured tool output against the tool's `outputSchema`, The type of a parameter decides how your method receives a JSON object: ```php -use Mcp\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\McpTool; /** * @param array $filters @@ -263,8 +263,8 @@ The SDK validates with [opis/json-schema](https://opis.io/json-schema/). To conf external `$ref` schemas, pass your own `SchemaValidator` to `Builder::setSchemaValidator()`: ```php -use Mcp\Capability\Discovery\SchemaValidator; -use Mcp\Server; +use Mcp\Server\Capability\Discovery\SchemaValidator; +use Mcp\Server\Server; use Opis\JsonSchema\Validator; $validator = new Validator(); diff --git a/docs/servers/tools.md b/docs/servers/tools.md index 67d068003..ad87b8891 100644 --- a/docs/servers/tools.md +++ b/docs/servers/tools.md @@ -3,8 +3,8 @@ Tools are callable functions that perform actions and return results. ```php -use Mcp\Capability\Attribute\McpTool; -use Mcp\Exception\ToolCallException; +use Mcp\Server\Capability\Attribute\McpTool; +use Mcp\Server\Exception\ToolCallException; class Calculator { @@ -135,7 +135,7 @@ Besides the human-readable `content`, a tool result can carry a machine-readable shape with `outputSchema`, a JSON Schema. This example uses an object schema, which works with every revision: ```php -use Mcp\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\McpTool; #[McpTool( name: 'get_weather', @@ -181,7 +181,7 @@ conforming to it. The SDK picks the rule from the revision negotiated for the ca object shape to produce structured output everywhere. Wrap the list in a key for that: ```php -use Mcp\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\McpTool; // Structured content only from 2026-07-28 on: a bare list is not a JSON object public function listUsersFlat(): array @@ -261,7 +261,7 @@ By default, the SDK also JSON-encodes structured content into `content`. To send `CallToolResult` with an empty `content` list: ```php -use Mcp\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\McpTool; use Mcp\Schema\Result\CallToolResult; #[McpTool(outputSchema: [/* ... */])] @@ -291,8 +291,8 @@ Tool handlers can throw any exception, but the type determines how it's handled: - **Any other exception you throw from your handler**: Converted to JSON-RPC error response, but with a generic error message ```php -use Mcp\Capability\Attribute\McpTool; -use Mcp\Exception\ToolCallException; +use Mcp\Server\Capability\Attribute\McpTool; +use Mcp\Server\Exception\ToolCallException; #[McpTool] public function divideNumbers(float $a, float $b): float diff --git a/examples/client/http_client_communication.php b/examples/client/http_client_communication.php index 659879976..c38b2a536 100644 --- a/examples/client/http_client_communication.php +++ b/examples/client/http_client_communication.php @@ -24,7 +24,7 @@ require_once __DIR__.'/../../vendor/autoload.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; diff --git a/examples/client/http_discovery_calculator.php b/examples/client/http_discovery_calculator.php index 0e4e05b07..c1cfa9b5b 100644 --- a/examples/client/http_discovery_calculator.php +++ b/examples/client/http_discovery_calculator.php @@ -23,7 +23,7 @@ require_once __DIR__.'/../../vendor/autoload.php'; -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Transport\HttpTransport; $endpoint = getenv('MCP_SERVER_URL') ?: 'http://localhost:8000'; diff --git a/examples/client/oauth_client.php b/examples/client/oauth_client.php index 93cf6c042..21868907b 100644 --- a/examples/client/oauth_client.php +++ b/examples/client/oauth_client.php @@ -29,12 +29,12 @@ require_once __DIR__.'/../../vendor/autoload.php'; -use Mcp\Client; use Mcp\Client\Auth\FileCredentialStorage; use Mcp\Client\Auth\OAuth; +use Mcp\Client\Client; +use Mcp\Client\Exception\AuthorizationException; +use Mcp\Client\Exception\ConnectionException; use Mcp\Client\Transport\HttpTransport; -use Mcp\Exception\AuthorizationException; -use Mcp\Exception\ConnectionException; $endpoint = 'http://localhost:8000/mcp'; diff --git a/examples/client/stateless_lifecycle_client.php b/examples/client/stateless_lifecycle_client.php index e3c28b455..614b38687 100644 --- a/examples/client/stateless_lifecycle_client.php +++ b/examples/client/stateless_lifecycle_client.php @@ -37,7 +37,7 @@ require_once __DIR__.'/../../vendor/autoload.php'; -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Handler\Request\RequestHandlerInterface; use Mcp\Client\Transport\HttpTransport; use Mcp\Schema\ClientCapabilities; diff --git a/examples/client/stdio_client_communication.php b/examples/client/stdio_client_communication.php index 38f08b9b8..16820ea52 100644 --- a/examples/client/stdio_client_communication.php +++ b/examples/client/stdio_client_communication.php @@ -22,7 +22,7 @@ require_once __DIR__.'/../../vendor/autoload.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; diff --git a/examples/client/stdio_discovery_calculator.php b/examples/client/stdio_discovery_calculator.php index 5b560e64a..1e61340a3 100644 --- a/examples/client/stdio_discovery_calculator.php +++ b/examples/client/stdio_discovery_calculator.php @@ -20,7 +20,7 @@ require_once __DIR__.'/../../vendor/autoload.php'; -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Transport\StdioTransport; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Content\TextResourceContents; diff --git a/examples/client/stdio_elicitation.php b/examples/client/stdio_elicitation.php index 055646f33..71d6a45b7 100644 --- a/examples/client/stdio_elicitation.php +++ b/examples/client/stdio_elicitation.php @@ -23,7 +23,7 @@ require_once __DIR__.'/../../vendor/autoload.php'; -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Handler\Request\ElicitationCallbackInterface; use Mcp\Client\Handler\Request\ElicitationRequestHandler; use Mcp\Client\Transport\StdioTransport; diff --git a/examples/client/stdio_roots.php b/examples/client/stdio_roots.php index 9345eada5..10edc5d2d 100644 --- a/examples/client/stdio_roots.php +++ b/examples/client/stdio_roots.php @@ -26,7 +26,7 @@ require_once __DIR__.'/../../vendor/autoload.php'; -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Handler\Request\ListRootsRequestHandler; use Mcp\Client\Handler\Request\RootsCallbackInterface; use Mcp\Client\Transport\StdioTransport; diff --git a/examples/server/bootstrap.php b/examples/server/bootstrap.php index 1c61fba07..bd2d2df1b 100644 --- a/examples/server/bootstrap.php +++ b/examples/server/bootstrap.php @@ -11,7 +11,7 @@ use Http\Discovery\Psr17Factory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; -use Mcp\Capability\Registry\Container; +use Mcp\Server\Capability\Registry\Container; use Mcp\Server\Transport\StdioTransport; use Mcp\Server\Transport\StreamableHttpTransport; use Mcp\Server\Transport\TransportInterface; diff --git a/examples/server/cached-discovery/CachedCalculatorElements.php b/examples/server/cached-discovery/CachedCalculatorElements.php index 07e975204..0c7976d36 100644 --- a/examples/server/cached-discovery/CachedCalculatorElements.php +++ b/examples/server/cached-discovery/CachedCalculatorElements.php @@ -11,8 +11,8 @@ namespace Mcp\Example\Server\CachedDiscovery; -use Mcp\Capability\Attribute\McpTool; -use Mcp\Exception\ToolCallException; +use Mcp\Server\Capability\Attribute\McpTool; +use Mcp\Server\Exception\ToolCallException; /** * Example MCP elements for demonstrating cached discovery. diff --git a/examples/server/cached-discovery/server.php b/examples/server/cached-discovery/server.php index 27e147be4..b3b10ae0e 100644 --- a/examples/server/cached-discovery/server.php +++ b/examples/server/cached-discovery/server.php @@ -13,7 +13,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; chdir(__DIR__); -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; use Symfony\Component\Cache\Adapter\PhpFilesAdapter; use Symfony\Component\Cache\Psr16Cache; diff --git a/examples/server/client-communication/ClientAwareService.php b/examples/server/client-communication/ClientAwareService.php index 01cfc07dc..06e7d6ec3 100644 --- a/examples/server/client-communication/ClientAwareService.php +++ b/examples/server/client-communication/ClientAwareService.php @@ -11,7 +11,6 @@ namespace Mcp\Example\Server\ClientCommunication; -use Mcp\Capability\Attribute\McpTool; use Mcp\Schema\Content\SamplingMessage; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Enum\LoggingLevel; @@ -19,6 +18,7 @@ use Mcp\Schema\Request\CreateSamplingMessageRequest; use Mcp\Schema\Request\ListRootsRequest; use Mcp\Schema\Result\InputRequiredResult; +use Mcp\Server\Capability\Attribute\McpTool; use Mcp\Server\RequestContext; use Psr\Log\LoggerInterface; diff --git a/examples/server/client-communication/server.php b/examples/server/client-communication/server.php index 16b4bd566..2167db4a1 100644 --- a/examples/server/client-communication/server.php +++ b/examples/server/client-communication/server.php @@ -14,8 +14,8 @@ use Mcp\Schema\Enum\LoggingLevel; use Mcp\Schema\ServerCapabilities; -use Mcp\Server; use Mcp\Server\RequestContext; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; $server = Server::builder() diff --git a/examples/server/client-logging/LoggingShowcaseHandlers.php b/examples/server/client-logging/LoggingShowcaseHandlers.php index 422efaf15..132b6972c 100644 --- a/examples/server/client-logging/LoggingShowcaseHandlers.php +++ b/examples/server/client-logging/LoggingShowcaseHandlers.php @@ -11,8 +11,7 @@ namespace Mcp\Example\Server\ClientLogging; -use Mcp\Capability\Attribute\McpTool; -use Mcp\Capability\Logger\ClientLogger; +use Mcp\Server\Capability\Attribute\McpTool; use Mcp\Server\RequestContext; /** diff --git a/examples/server/client-logging/server.php b/examples/server/client-logging/server.php index c2421980b..46cf17865 100644 --- a/examples/server/client-logging/server.php +++ b/examples/server/client-logging/server.php @@ -13,7 +13,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; chdir(__DIR__); -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; $server = Server::builder() diff --git a/examples/server/combined-registration/DiscoveredElements.php b/examples/server/combined-registration/DiscoveredElements.php index c2f93ac3a..6727544da 100644 --- a/examples/server/combined-registration/DiscoveredElements.php +++ b/examples/server/combined-registration/DiscoveredElements.php @@ -11,8 +11,8 @@ namespace Mcp\Example\Server\CombinedRegistration; -use Mcp\Capability\Attribute\McpResource; -use Mcp\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\McpResource; +use Mcp\Server\Capability\Attribute\McpTool; final class DiscoveredElements { diff --git a/examples/server/combined-registration/server.php b/examples/server/combined-registration/server.php index 475ed4198..a9239cd6a 100644 --- a/examples/server/combined-registration/server.php +++ b/examples/server/combined-registration/server.php @@ -15,7 +15,7 @@ use Mcp\Example\Server\CombinedRegistration\ManualHandlers; use Mcp\Example\Server\CombinedRegistration\PreconfiguredGreeter; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; // Built here so its constructor dependencies (a scalar the container cannot diff --git a/examples/server/complex-tool-schema/McpEventScheduler.php b/examples/server/complex-tool-schema/McpEventScheduler.php index 0777b22bb..094a5d5d3 100644 --- a/examples/server/complex-tool-schema/McpEventScheduler.php +++ b/examples/server/complex-tool-schema/McpEventScheduler.php @@ -11,9 +11,9 @@ namespace Mcp\Example\Server\ComplexToolSchema; -use Mcp\Capability\Attribute\McpTool; use Mcp\Example\Server\ComplexToolSchema\Model\EventPriority; use Mcp\Example\Server\ComplexToolSchema\Model\EventType; +use Mcp\Server\Capability\Attribute\McpTool; use Psr\Log\LoggerInterface; final class McpEventScheduler diff --git a/examples/server/complex-tool-schema/server.php b/examples/server/complex-tool-schema/server.php index 92f80b617..460934504 100644 --- a/examples/server/complex-tool-schema/server.php +++ b/examples/server/complex-tool-schema/server.php @@ -13,7 +13,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; chdir(__DIR__); -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; $server = Server::builder() diff --git a/examples/server/custom-dependencies/McpTaskHandlers.php b/examples/server/custom-dependencies/McpTaskHandlers.php index affa2a7b6..9af12a201 100644 --- a/examples/server/custom-dependencies/McpTaskHandlers.php +++ b/examples/server/custom-dependencies/McpTaskHandlers.php @@ -11,10 +11,10 @@ namespace Mcp\Example\Server\CustomDependencies; -use Mcp\Capability\Attribute\McpResource; -use Mcp\Capability\Attribute\McpTool; use Mcp\Example\Server\CustomDependencies\Service\StatsServiceInterface; use Mcp\Example\Server\CustomDependencies\Service\TaskRepositoryInterface; +use Mcp\Server\Capability\Attribute\McpResource; +use Mcp\Server\Capability\Attribute\McpTool; use Psr\Log\LoggerInterface; /** diff --git a/examples/server/custom-dependencies/server.php b/examples/server/custom-dependencies/server.php index 835a84b7c..05982cc55 100644 --- a/examples/server/custom-dependencies/server.php +++ b/examples/server/custom-dependencies/server.php @@ -17,7 +17,7 @@ use Mcp\Example\Server\CustomDependencies\Service\StatsServiceInterface; use Mcp\Example\Server\CustomDependencies\Service\SystemStatsService; use Mcp\Example\Server\CustomDependencies\Service\TaskRepositoryInterface; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; logger()->info('Starting MCP Custom Dependencies Server...'); diff --git a/examples/server/custom-method-handlers/server.php b/examples/server/custom-method-handlers/server.php index 461d9d964..7c8327488 100644 --- a/examples/server/custom-method-handlers/server.php +++ b/examples/server/custom-method-handlers/server.php @@ -17,7 +17,7 @@ use Mcp\Example\Server\CustomMethodHandlers\ListToolsRequestHandler; use Mcp\Schema\ServerCapabilities; use Mcp\Schema\Tool; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; logger()->info('Starting MCP Custom Method Handlers Server...'); diff --git a/examples/server/discovery-calculator/McpElements.php b/examples/server/discovery-calculator/McpElements.php index cabd3101d..686fdeb3c 100644 --- a/examples/server/discovery-calculator/McpElements.php +++ b/examples/server/discovery-calculator/McpElements.php @@ -11,10 +11,10 @@ namespace Mcp\Example\Server\DiscoveryCalculator; -use Mcp\Capability\Attribute\McpResource; -use Mcp\Capability\Attribute\McpTool; -use Mcp\Exception\ToolCallException; use Mcp\Schema\Icon; +use Mcp\Server\Capability\Attribute\McpResource; +use Mcp\Server\Capability\Attribute\McpTool; +use Mcp\Server\Exception\ToolCallException; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; diff --git a/examples/server/discovery-calculator/server.php b/examples/server/discovery-calculator/server.php index e8b28ad68..eb14486b7 100644 --- a/examples/server/discovery-calculator/server.php +++ b/examples/server/discovery-calculator/server.php @@ -12,7 +12,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; chdir(__DIR__); -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; logger()->info('Starting MCP Calculator Server...'); diff --git a/examples/server/discovery-userprofile/McpElements.php b/examples/server/discovery-userprofile/McpElements.php index c85325448..46cf87d45 100644 --- a/examples/server/discovery-userprofile/McpElements.php +++ b/examples/server/discovery-userprofile/McpElements.php @@ -11,16 +11,16 @@ namespace Mcp\Example\Server\DiscoveryUserProfile; -use Mcp\Capability\Attribute\CompletionProvider; -use Mcp\Capability\Attribute\McpPrompt; -use Mcp\Capability\Attribute\McpResource; -use Mcp\Capability\Attribute\McpResourceTemplate; -use Mcp\Capability\Attribute\McpTool; -use Mcp\Exception\PromptGetException; -use Mcp\Exception\ResourceReadException; use Mcp\Schema\Content\Content; use Mcp\Schema\Content\ResourceLink; use Mcp\Schema\Content\TextContent; +use Mcp\Server\Capability\Attribute\CompletionProvider; +use Mcp\Server\Capability\Attribute\McpPrompt; +use Mcp\Server\Capability\Attribute\McpResource; +use Mcp\Server\Capability\Attribute\McpResourceTemplate; +use Mcp\Server\Capability\Attribute\McpTool; +use Mcp\Server\Exception\PromptGetException; +use Mcp\Server\Exception\ResourceReadException; use Psr\Log\LoggerInterface; /** diff --git a/examples/server/discovery-userprofile/UserIdCompletionProvider.php b/examples/server/discovery-userprofile/UserIdCompletionProvider.php index bee4ffa61..7d99f7582 100644 --- a/examples/server/discovery-userprofile/UserIdCompletionProvider.php +++ b/examples/server/discovery-userprofile/UserIdCompletionProvider.php @@ -11,7 +11,7 @@ namespace Mcp\Example\Server\DiscoveryUserProfile; -use Mcp\Capability\Completion\ProviderInterface; +use Mcp\Server\Capability\Completion\ProviderInterface; final class UserIdCompletionProvider implements ProviderInterface { diff --git a/examples/server/discovery-userprofile/server.php b/examples/server/discovery-userprofile/server.php index 25448188e..96c6b5749 100644 --- a/examples/server/discovery-userprofile/server.php +++ b/examples/server/discovery-userprofile/server.php @@ -13,7 +13,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; chdir(__DIR__); -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; $server = Server::builder() diff --git a/examples/server/elicitation/ElicitationHandlers.php b/examples/server/elicitation/ElicitationHandlers.php index 9ae87f95f..2686a6c18 100644 --- a/examples/server/elicitation/ElicitationHandlers.php +++ b/examples/server/elicitation/ElicitationHandlers.php @@ -11,13 +11,13 @@ namespace Mcp\Example\Server\Elicitation; -use Mcp\Capability\Attribute\McpTool; use Mcp\Schema\Elicitation\BooleanSchemaDefinition; use Mcp\Schema\Elicitation\ElicitationSchema; use Mcp\Schema\Elicitation\EnumSchemaDefinition; use Mcp\Schema\Elicitation\NumberSchemaDefinition; use Mcp\Schema\Elicitation\StringSchemaDefinition; use Mcp\Schema\Result\ElicitResult; +use Mcp\Server\Capability\Attribute\McpTool; use Mcp\Server\RequestContext; use Psr\Log\LoggerInterface; diff --git a/examples/server/elicitation/server.php b/examples/server/elicitation/server.php index ccb51bee7..b9268084b 100644 --- a/examples/server/elicitation/server.php +++ b/examples/server/elicitation/server.php @@ -21,7 +21,7 @@ chdir(__DIR__); use Mcp\Schema\ServerCapabilities; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; $server = Server::builder() diff --git a/examples/server/env-variables/EnvToolHandler.php b/examples/server/env-variables/EnvToolHandler.php index 0520a715a..c93539d59 100644 --- a/examples/server/env-variables/EnvToolHandler.php +++ b/examples/server/env-variables/EnvToolHandler.php @@ -11,7 +11,7 @@ namespace Mcp\Example\Server\EnvVariables; -use Mcp\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\McpTool; final class EnvToolHandler { diff --git a/examples/server/env-variables/server.php b/examples/server/env-variables/server.php index 7b7bbb4f5..356d25edf 100644 --- a/examples/server/env-variables/server.php +++ b/examples/server/env-variables/server.php @@ -13,7 +13,7 @@ require_once dirname(__DIR__).'/bootstrap.php'; chdir(__DIR__); -use Mcp\Server; +use Mcp\Server\Server; /* |-------------------------------------------------------------------------- diff --git a/examples/server/explicit-registration/server.php b/examples/server/explicit-registration/server.php index 977ee4390..617f3f396 100644 --- a/examples/server/explicit-registration/server.php +++ b/examples/server/explicit-registration/server.php @@ -15,7 +15,7 @@ use Mcp\Example\Server\ExplicitRegistration\SimpleHandlers; use Mcp\Schema\ServerCapabilities; -use Mcp\Server; +use Mcp\Server\Server; logger()->info('Starting MCP Manual Registration Server...'); diff --git a/examples/server/mcp-apps/server.php b/examples/server/mcp-apps/server.php index d61c15a0e..8e18d00ca 100644 --- a/examples/server/mcp-apps/server.php +++ b/examples/server/mcp-apps/server.php @@ -17,7 +17,7 @@ use Mcp\Schema\Extension\Apps\McpApps; use Mcp\Schema\Extension\Apps\ToolVisibility; use Mcp\Schema\Extension\Apps\UiToolMeta; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; logger()->info('Starting MCP Apps Example Server...'); diff --git a/examples/server/oauth-keycloak/McpElements.php b/examples/server/oauth-keycloak/McpElements.php index f17047dd1..ba9563035 100644 --- a/examples/server/oauth-keycloak/McpElements.php +++ b/examples/server/oauth-keycloak/McpElements.php @@ -11,9 +11,9 @@ namespace Mcp\Example\Server\OAuthKeycloak; -use Mcp\Capability\Attribute\McpPrompt; -use Mcp\Capability\Attribute\McpResource; -use Mcp\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\McpPrompt; +use Mcp\Server\Capability\Attribute\McpResource; +use Mcp\Server\Capability\Attribute\McpTool; use Mcp\Server\RequestContext; /** diff --git a/examples/server/oauth-keycloak/server.php b/examples/server/oauth-keycloak/server.php index 6d25e3605..ef94d84a0 100644 --- a/examples/server/oauth-keycloak/server.php +++ b/examples/server/oauth-keycloak/server.php @@ -15,7 +15,7 @@ use Http\Discovery\Psr17Factory; use Http\Discovery\Psr18ClientDiscovery; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; use Mcp\Server\Transport\Http\Middleware\AuthorizationMiddleware; use Mcp\Server\Transport\Http\Middleware\ProtectedResourceMetadataMiddleware; diff --git a/examples/server/oauth-microsoft/McpElements.php b/examples/server/oauth-microsoft/McpElements.php index 602797a36..870d13b4b 100644 --- a/examples/server/oauth-microsoft/McpElements.php +++ b/examples/server/oauth-microsoft/McpElements.php @@ -11,9 +11,9 @@ namespace Mcp\Example\Server\OAuthMicrosoft; -use Mcp\Capability\Attribute\McpPrompt; -use Mcp\Capability\Attribute\McpResource; -use Mcp\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\McpPrompt; +use Mcp\Server\Capability\Attribute\McpResource; +use Mcp\Server\Capability\Attribute\McpTool; use Mcp\Server\RequestContext; /** diff --git a/examples/server/oauth-microsoft/server.php b/examples/server/oauth-microsoft/server.php index a195a5dee..a0a279b28 100644 --- a/examples/server/oauth-microsoft/server.php +++ b/examples/server/oauth-microsoft/server.php @@ -13,7 +13,7 @@ use Http\Discovery\Psr17Factory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; use Mcp\Server\Transport\Http\Middleware\AuthorizationMiddleware; use Mcp\Server\Transport\Http\Middleware\ProtectedResourceMetadataMiddleware; diff --git a/examples/server/reactphp/server.php b/examples/server/reactphp/server.php index fe8ff7642..412aac834 100644 --- a/examples/server/reactphp/server.php +++ b/examples/server/reactphp/server.php @@ -15,7 +15,7 @@ use Http\Discovery\Psr17Factory; use Mcp\Example\Server\ReactPhp\ReactFiberScheduler; use Mcp\Example\Server\ReactPhp\SlowTools; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Subscription\InMemoryNotificationBus; use Mcp\Server\Transport\CallbackStream; use Mcp\Server\Transport\StreamableHttpTransport; diff --git a/examples/server/revolt/server.php b/examples/server/revolt/server.php index 3453a6b44..8f826ba2a 100644 --- a/examples/server/revolt/server.php +++ b/examples/server/revolt/server.php @@ -21,7 +21,7 @@ use Http\Discovery\Psr17Factory; use Mcp\Example\Server\Revolt\RevoltFiberScheduler; use Mcp\Example\Server\Revolt\SlowTools; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Subscription\InMemoryNotificationBus; use Mcp\Server\Transport\CallbackStream; use Mcp\Server\Transport\StreamableHttpTransport; diff --git a/examples/server/schema-showcase/SchemaShowcaseElements.php b/examples/server/schema-showcase/SchemaShowcaseElements.php index 294d9680b..d2acb91d4 100644 --- a/examples/server/schema-showcase/SchemaShowcaseElements.php +++ b/examples/server/schema-showcase/SchemaShowcaseElements.php @@ -11,8 +11,8 @@ namespace Mcp\Example\Server\SchemaShowcase; -use Mcp\Capability\Attribute\McpTool; -use Mcp\Capability\Attribute\Schema; +use Mcp\Server\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\Schema; use Psr\Log\LoggerInterface; final class SchemaShowcaseElements diff --git a/examples/server/schema-showcase/server.php b/examples/server/schema-showcase/server.php index 86c2bf774..7dbbc336d 100644 --- a/examples/server/schema-showcase/server.php +++ b/examples/server/schema-showcase/server.php @@ -14,7 +14,7 @@ chdir(__DIR__); use Mcp\Schema\Icon; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; $server = Server::builder() diff --git a/examples/server/stateless-lifecycle/server.php b/examples/server/stateless-lifecycle/server.php index e64751ef8..6f06ea103 100644 --- a/examples/server/stateless-lifecycle/server.php +++ b/examples/server/stateless-lifecycle/server.php @@ -21,8 +21,8 @@ use Mcp\Schema\Result\CallToolResult; use Mcp\Schema\Result\InputRequiredResult; use Mcp\Schema\ServerCapabilities; -use Mcp\Server; use Mcp\Server\RequestContext; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; use Mcp\Server\Subscription\InMemoryNotificationBus; use Mcp\Server\Wire\CachePolicy; diff --git a/phpstan.dist.neon b/phpstan.dist.neon index 0ff247199..0524c6120 100644 --- a/phpstan.dist.neon +++ b/phpstan.dist.neon @@ -9,8 +9,8 @@ parameters: - tests/ excludePaths: - examples/cli/vendor/* (?) - - tests/Unit/Capability/Discovery/Fixtures/ - - tests/Unit/Capability/Discovery/SchemaGeneratorFixture.php + - tests/Unit/Server/Capability/Discovery/Fixtures/ + - tests/Unit/Server/Capability/Discovery/SchemaGeneratorFixture.php treatPhpDocTypesAsCertain: false ignoreErrors: - @@ -20,5 +20,5 @@ parameters: # These errors should actually be fixed, but are ignored for now - identifier: missingType.iterableValue - path: src/Capability/Discovery/SchemaGenerator.php + path: src/Server/Capability/Discovery/SchemaGenerator.php count: 12 diff --git a/src/Client/Auth/AccessToken.php b/src/Client/Auth/AccessToken.php index dec3e2a2e..7277e5b16 100644 --- a/src/Client/Auth/AccessToken.php +++ b/src/Client/Auth/AccessToken.php @@ -11,7 +11,7 @@ namespace Mcp\Client\Auth; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Client\Exception\InvalidArgumentException; /** * An OAuth 2.1 token response: the access token plus everything needed to keep using it. diff --git a/src/Client/Auth/AuthenticatingHttpClient.php b/src/Client/Auth/AuthenticatingHttpClient.php index 5aadb7bed..ae2bb124f 100644 --- a/src/Client/Auth/AuthenticatingHttpClient.php +++ b/src/Client/Auth/AuthenticatingHttpClient.php @@ -11,9 +11,9 @@ namespace Mcp\Client\Auth; +use Mcp\Client\Exception\AuthorizationException; +use Mcp\Client\Exception\InvalidArgumentException; use Mcp\Client\Transport\NoRedirects; -use Mcp\Exception\AuthorizationException; -use Mcp\Exception\InvalidArgumentException; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; diff --git a/src/Client/Auth/AuthenticatorInterface.php b/src/Client/Auth/AuthenticatorInterface.php index 82ac85085..a65d87dea 100644 --- a/src/Client/Auth/AuthenticatorInterface.php +++ b/src/Client/Auth/AuthenticatorInterface.php @@ -11,7 +11,7 @@ namespace Mcp\Client\Auth; -use Mcp\Exception\AuthorizationException; +use Mcp\Client\Exception\AuthorizationException; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; diff --git a/src/Client/Auth/AuthorizationHandlerInterface.php b/src/Client/Auth/AuthorizationHandlerInterface.php index 1e8d1d67b..767283f36 100644 --- a/src/Client/Auth/AuthorizationHandlerInterface.php +++ b/src/Client/Auth/AuthorizationHandlerInterface.php @@ -23,8 +23,8 @@ interface AuthorizationHandlerInterface * * @return array the callback's query parameters * - * @throws \Mcp\Exception\AuthorizationException when the user could not be sent, or did not come back - * @throws \Mcp\Exception\AuthorizationPendingException to persist the flow and redirect from a web application + * @throws \Mcp\Client\Exception\AuthorizationException when the user could not be sent, or did not come back + * @throws \Mcp\Client\Exception\AuthorizationPendingException to persist the flow and redirect from a web application */ public function authorize(string $authorizationUrl, string $redirectUri): array; } diff --git a/src/Client/Auth/AuthorizationServerMetadata.php b/src/Client/Auth/AuthorizationServerMetadata.php index 0038e91db..04ce1da64 100644 --- a/src/Client/Auth/AuthorizationServerMetadata.php +++ b/src/Client/Auth/AuthorizationServerMetadata.php @@ -11,8 +11,7 @@ namespace Mcp\Client\Auth; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Server\Transport\Http\OAuth\SecureUrl; +use Mcp\Client\Exception\InvalidArgumentException; /** * An authorization server's metadata document (RFC 8414 or OpenID Connect discovery). diff --git a/src/Client/Auth/BearerToken.php b/src/Client/Auth/BearerToken.php index dbb276056..2874865d8 100644 --- a/src/Client/Auth/BearerToken.php +++ b/src/Client/Auth/BearerToken.php @@ -11,7 +11,7 @@ namespace Mcp\Client\Auth; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Client\Exception\InvalidArgumentException; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; diff --git a/src/Client/Auth/ClientRegistrar.php b/src/Client/Auth/ClientRegistrar.php index 8c0cd6c3c..55a25cb29 100644 --- a/src/Client/Auth/ClientRegistrar.php +++ b/src/Client/Auth/ClientRegistrar.php @@ -11,8 +11,8 @@ namespace Mcp\Client\Auth; -use Mcp\Exception\AuthorizationException; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Client\Exception\AuthorizationException; +use Mcp\Client\Exception\InvalidArgumentException; use Psr\Http\Client\ClientExceptionInterface; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; diff --git a/src/Client/Auth/ClientRegistration.php b/src/Client/Auth/ClientRegistration.php index 9c1779885..4c23200de 100644 --- a/src/Client/Auth/ClientRegistration.php +++ b/src/Client/Auth/ClientRegistration.php @@ -11,7 +11,7 @@ namespace Mcp\Client\Auth; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Client\Exception\InvalidArgumentException; /** * The client's identity at one authorization server. diff --git a/src/Client/Auth/ConsoleAuthorizationHandler.php b/src/Client/Auth/ConsoleAuthorizationHandler.php index 63b5a4b60..5a6446ff1 100644 --- a/src/Client/Auth/ConsoleAuthorizationHandler.php +++ b/src/Client/Auth/ConsoleAuthorizationHandler.php @@ -11,7 +11,7 @@ namespace Mcp\Client\Auth; -use Mcp\Exception\AuthorizationException; +use Mcp\Client\Exception\AuthorizationException; /** * Prints the authorization URL and reads the redirected URL back, for a shell without a browser. diff --git a/src/Client/Auth/CrossAppAccess.php b/src/Client/Auth/CrossAppAccess.php index 4eaa0d33b..2b91e7a41 100644 --- a/src/Client/Auth/CrossAppAccess.php +++ b/src/Client/Auth/CrossAppAccess.php @@ -11,8 +11,8 @@ namespace Mcp\Client\Auth; -use Mcp\Exception\AuthorizationException; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Client\Exception\AuthorizationException; +use Mcp\Client\Exception\InvalidArgumentException; /** * Reaches an MCP server through the identity a user already has at their company. diff --git a/src/Client/Auth/FileCredentialStorage.php b/src/Client/Auth/FileCredentialStorage.php index c01d7f195..5ed84933d 100644 --- a/src/Client/Auth/FileCredentialStorage.php +++ b/src/Client/Auth/FileCredentialStorage.php @@ -11,8 +11,8 @@ namespace Mcp\Client\Auth; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\RuntimeException; +use Mcp\Client\Exception\InvalidArgumentException; +use Mcp\Client\Exception\RuntimeException; /** * Persists credentials unencrypted in a JSON file with the mode 0600, in a directory with the mode 0700. diff --git a/src/Client/Auth/HeadlessAuthorizationHandler.php b/src/Client/Auth/HeadlessAuthorizationHandler.php index 1db2fd55b..519d35ddc 100644 --- a/src/Client/Auth/HeadlessAuthorizationHandler.php +++ b/src/Client/Auth/HeadlessAuthorizationHandler.php @@ -12,8 +12,8 @@ namespace Mcp\Client\Auth; use Http\Discovery\Psr17FactoryDiscovery; +use Mcp\Client\Exception\AuthorizationException; use Mcp\Client\Transport\NoRedirects; -use Mcp\Exception\AuthorizationException; use Psr\Http\Client\ClientExceptionInterface; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; diff --git a/src/Client/Auth/LoopbackAuthorizationHandler.php b/src/Client/Auth/LoopbackAuthorizationHandler.php index 6c7ec3a8f..bf6289748 100644 --- a/src/Client/Auth/LoopbackAuthorizationHandler.php +++ b/src/Client/Auth/LoopbackAuthorizationHandler.php @@ -11,7 +11,7 @@ namespace Mcp\Client\Auth; -use Mcp\Exception\AuthorizationException; +use Mcp\Client\Exception\AuthorizationException; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; diff --git a/src/Client/Auth/MetadataDiscovery.php b/src/Client/Auth/MetadataDiscovery.php index 084adeee9..2a995d7b7 100644 --- a/src/Client/Auth/MetadataDiscovery.php +++ b/src/Client/Auth/MetadataDiscovery.php @@ -11,8 +11,8 @@ namespace Mcp\Client\Auth; -use Mcp\Exception\AuthorizationException; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Client\Exception\AuthorizationException; +use Mcp\Client\Exception\InvalidArgumentException; use Psr\Http\Client\ClientExceptionInterface; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; diff --git a/src/Client/Auth/OAuth.php b/src/Client/Auth/OAuth.php index f25a423ab..eb1dd30e9 100644 --- a/src/Client/Auth/OAuth.php +++ b/src/Client/Auth/OAuth.php @@ -12,9 +12,8 @@ namespace Mcp\Client\Auth; use Http\Discovery\Psr17FactoryDiscovery; +use Mcp\Client\Exception\InvalidArgumentException; use Mcp\Client\Transport\NoRedirects; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Server\Transport\Http\OAuth\SecureUrl; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; use Psr\Http\Message\StreamFactoryInterface; diff --git a/src/Client/Auth/OAuthAuthenticator.php b/src/Client/Auth/OAuthAuthenticator.php index 5751292bf..0f80ec18c 100644 --- a/src/Client/Auth/OAuthAuthenticator.php +++ b/src/Client/Auth/OAuthAuthenticator.php @@ -11,12 +11,11 @@ namespace Mcp\Client\Auth; -use Mcp\Exception\AuthorizationException; -use Mcp\Exception\AuthorizationPendingException; -use Mcp\Exception\OAuthErrorException; -use Mcp\Exception\RuntimeException; -use Mcp\Exception\TokenEndpointUnavailableException; -use Mcp\Server\Transport\Http\OAuth\SecureUrl; +use Mcp\Client\Exception\AuthorizationException; +use Mcp\Client\Exception\AuthorizationPendingException; +use Mcp\Client\Exception\OAuthErrorException; +use Mcp\Client\Exception\RuntimeException; +use Mcp\Client\Exception\TokenEndpointUnavailableException; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Log\LoggerInterface; diff --git a/src/Client/Auth/OAuthConfiguration.php b/src/Client/Auth/OAuthConfiguration.php index b041146f0..d90c30269 100644 --- a/src/Client/Auth/OAuthConfiguration.php +++ b/src/Client/Auth/OAuthConfiguration.php @@ -11,7 +11,7 @@ namespace Mcp\Client\Auth; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Client\Exception\InvalidArgumentException; /** * What the application decided about authorization before the first request. diff --git a/src/Client/Auth/PendingAuthorization.php b/src/Client/Auth/PendingAuthorization.php index 3c1e5f82a..276c15748 100644 --- a/src/Client/Auth/PendingAuthorization.php +++ b/src/Client/Auth/PendingAuthorization.php @@ -11,7 +11,7 @@ namespace Mcp\Client\Auth; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Client\Exception\InvalidArgumentException; /** * @author bbdu3 diff --git a/src/Client/Auth/ProtectedResourceMetadata.php b/src/Client/Auth/ProtectedResourceMetadata.php index 3eddb1e1d..064ee6f9a 100644 --- a/src/Client/Auth/ProtectedResourceMetadata.php +++ b/src/Client/Auth/ProtectedResourceMetadata.php @@ -11,8 +11,7 @@ namespace Mcp\Client\Auth; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Server\Transport\Http\OAuth\SecureUrl; +use Mcp\Client\Exception\InvalidArgumentException; /** * What an MCP server publishes about itself as a protected resource (RFC 9728). diff --git a/src/Client/Auth/RedirectAuthorizationHandler.php b/src/Client/Auth/RedirectAuthorizationHandler.php index b511d63b6..b313fad54 100644 --- a/src/Client/Auth/RedirectAuthorizationHandler.php +++ b/src/Client/Auth/RedirectAuthorizationHandler.php @@ -11,7 +11,7 @@ namespace Mcp\Client\Auth; -use Mcp\Exception\AuthorizationPendingException; +use Mcp\Client\Exception\AuthorizationPendingException; /** * @author bbdu3 diff --git a/src/Client/Auth/SecureUrl.php b/src/Client/Auth/SecureUrl.php new file mode 100644 index 000000000..37099d059 --- /dev/null +++ b/src/Client/Auth/SecureUrl.php @@ -0,0 +1,48 @@ + + */ +final class SecureUrl +{ + /** + * @return array{scheme: string, host: string, port?: int, path?: string, query?: string, fragment?: string} + * + * @throws InvalidArgumentException + */ + public static function parse(mixed $url, string $label): array + { + try { + return SchemaSecureUrl::parse($url, $label); + } catch (SchemaInvalidArgumentException $e) { + throw new InvalidArgumentException($e->getMessage(), 0, $e); + } + } + + public static function isLoopback(string $url): bool + { + return SchemaSecureUrl::isLoopback($url); + } + + public static function isPrivateNetwork(string $url): bool + { + return SchemaSecureUrl::isPrivateNetwork($url); + } +} diff --git a/src/Client/Auth/TokenEndpoint.php b/src/Client/Auth/TokenEndpoint.php index 7c1f51e51..9f1e8e656 100644 --- a/src/Client/Auth/TokenEndpoint.php +++ b/src/Client/Auth/TokenEndpoint.php @@ -12,10 +12,10 @@ namespace Mcp\Client\Auth; use Firebase\JWT\JWT; -use Mcp\Exception\AuthorizationException; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\OAuthErrorException; -use Mcp\Exception\TokenEndpointUnavailableException; +use Mcp\Client\Exception\AuthorizationException; +use Mcp\Client\Exception\InvalidArgumentException; +use Mcp\Client\Exception\OAuthErrorException; +use Mcp\Client\Exception\TokenEndpointUnavailableException; use Psr\Http\Client\ClientExceptionInterface; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; diff --git a/src/Client/Builder.php b/src/Client/Builder.php index 290eda040..745070085 100644 --- a/src/Client/Builder.php +++ b/src/Client/Builder.php @@ -11,11 +11,10 @@ namespace Mcp\Client; -use Mcp\Client; +use Mcp\Client\Exception\InvalidArgumentException; +use Mcp\Client\Exception\LogicException; use Mcp\Client\Handler\Notification\NotificationHandlerInterface; use Mcp\Client\Handler\Request\RequestHandlerInterface; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\LogicException; use Mcp\Schema\ClientCapabilities; use Mcp\Schema\Enum\ProtocolVersion; use Mcp\Schema\Extension\ExtensionInterface; diff --git a/src/Client.php b/src/Client/Client.php similarity index 97% rename from src/Client.php rename to src/Client/Client.php index aad83954b..d6214a44b 100644 --- a/src/Client.php +++ b/src/Client/Client.php @@ -9,23 +9,19 @@ * file that was distributed with this source code. */ -namespace Mcp; - -use Mcp\Client\Builder; -use Mcp\Client\CancellationTokenInterface; -use Mcp\Client\Configuration; -use Mcp\Client\Protocol; +namespace Mcp\Client; + +use Mcp\Client\Exception\AuthorizationException; +use Mcp\Client\Exception\AuthorizationPendingException; +use Mcp\Client\Exception\ConnectionException; +use Mcp\Client\Exception\InvalidArgumentException; +use Mcp\Client\Exception\RequestCancelledException; +use Mcp\Client\Exception\RequestException; +use Mcp\Client\Exception\RuntimeException; use Mcp\Client\Transport\TransportInterface; -use Mcp\Exception\AuthorizationException; -use Mcp\Exception\AuthorizationPendingException; -use Mcp\Exception\ConnectionException; -use Mcp\Exception\ExceptionInterface; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\RequestCancelledException; -use Mcp\Exception\RequestException; -use Mcp\Exception\RuntimeException; use Mcp\Schema\Enum\LoggingLevel; use Mcp\Schema\Enum\ProtocolVersion; +use Mcp\Schema\Exception\ExceptionInterface; use Mcp\Schema\Implementation; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Request; diff --git a/src/Client/Configuration.php b/src/Client/Configuration.php index ac668c57d..47c2c9789 100644 --- a/src/Client/Configuration.php +++ b/src/Client/Configuration.php @@ -11,7 +11,7 @@ namespace Mcp\Client; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Client\Exception\InvalidArgumentException; use Mcp\Schema\ClientCapabilities; use Mcp\Schema\Enum\ProtocolVersion; use Mcp\Schema\Implementation; diff --git a/src/Exception/AuthorizationException.php b/src/Client/Exception/AuthorizationException.php similarity index 85% rename from src/Exception/AuthorizationException.php rename to src/Client/Exception/AuthorizationException.php index 6a101c7cf..45deca694 100644 --- a/src/Exception/AuthorizationException.php +++ b/src/Client/Exception/AuthorizationException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Client\Exception; use Psr\Http\Client\ClientExceptionInterface; @@ -18,7 +18,7 @@ * * @author Christopher Hertel */ -class AuthorizationException extends \RuntimeException implements ExceptionInterface, ClientExceptionInterface +class AuthorizationException extends RuntimeException implements ClientExceptionInterface { public function __construct(string $message = '', int $code = 0, ?\Throwable $previous = null) { diff --git a/src/Exception/AuthorizationPendingException.php b/src/Client/Exception/AuthorizationPendingException.php similarity index 94% rename from src/Exception/AuthorizationPendingException.php rename to src/Client/Exception/AuthorizationPendingException.php index 2c96beaa3..14c38108e 100644 --- a/src/Exception/AuthorizationPendingException.php +++ b/src/Client/Exception/AuthorizationPendingException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Client\Exception; /** * @author bbdu3 diff --git a/src/Exception/ConnectionException.php b/src/Client/Exception/ConnectionException.php similarity index 92% rename from src/Exception/ConnectionException.php rename to src/Client/Exception/ConnectionException.php index 4e4527f5e..dec5f9dbd 100644 --- a/src/Exception/ConnectionException.php +++ b/src/Client/Exception/ConnectionException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Client\Exception; /** * Exception for connection failures. diff --git a/src/Exception/ElicitationException.php b/src/Client/Exception/ElicitationException.php similarity index 81% rename from src/Exception/ElicitationException.php rename to src/Client/Exception/ElicitationException.php index 0ef784e10..e72f2768f 100644 --- a/src/Exception/ElicitationException.php +++ b/src/Client/Exception/ElicitationException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Client\Exception; /** * Exception thrown when an elicitation request fails. @@ -19,6 +19,6 @@ * * @author Johannes Wachter */ -final class ElicitationException extends \RuntimeException implements ExceptionInterface +final class ElicitationException extends RuntimeException { } diff --git a/src/Exception/Exception.php b/src/Client/Exception/Exception.php similarity index 92% rename from src/Exception/Exception.php rename to src/Client/Exception/Exception.php index 12ff5f014..402230694 100644 --- a/src/Exception/Exception.php +++ b/src/Client/Exception/Exception.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Client\Exception; /** * @author Christopher Hertel diff --git a/src/Client/Exception/ExceptionInterface.php b/src/Client/Exception/ExceptionInterface.php new file mode 100644 index 000000000..a98583fae --- /dev/null +++ b/src/Client/Exception/ExceptionInterface.php @@ -0,0 +1,21 @@ + + */ +interface ExceptionInterface extends SchemaExceptionInterface +{ +} diff --git a/src/Exception/InvalidArgumentException.php b/src/Client/Exception/InvalidArgumentException.php similarity index 92% rename from src/Exception/InvalidArgumentException.php rename to src/Client/Exception/InvalidArgumentException.php index 8c85a7c4e..91af3673a 100644 --- a/src/Exception/InvalidArgumentException.php +++ b/src/Client/Exception/InvalidArgumentException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Client\Exception; /** * @author Christopher Hertel diff --git a/src/Exception/LogicException.php b/src/Client/Exception/LogicException.php similarity index 92% rename from src/Exception/LogicException.php rename to src/Client/Exception/LogicException.php index 2ebe44c98..e3e2aa1ae 100644 --- a/src/Exception/LogicException.php +++ b/src/Client/Exception/LogicException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Client\Exception; /** * @author Christopher Hertel diff --git a/src/Exception/OAuthErrorException.php b/src/Client/Exception/OAuthErrorException.php similarity index 95% rename from src/Exception/OAuthErrorException.php rename to src/Client/Exception/OAuthErrorException.php index bec2926ff..45d15be20 100644 --- a/src/Exception/OAuthErrorException.php +++ b/src/Client/Exception/OAuthErrorException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Client\Exception; /** * Thrown when an authorization server answers with an OAuth error code. diff --git a/src/Exception/RequestCancelledException.php b/src/Client/Exception/RequestCancelledException.php similarity index 92% rename from src/Exception/RequestCancelledException.php rename to src/Client/Exception/RequestCancelledException.php index f1dd61554..a8ffe2110 100644 --- a/src/Exception/RequestCancelledException.php +++ b/src/Client/Exception/RequestCancelledException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Client\Exception; /** * The caller cancelled a request before the server responded. diff --git a/src/Exception/RequestException.php b/src/Client/Exception/RequestException.php similarity index 96% rename from src/Exception/RequestException.php rename to src/Client/Exception/RequestException.php index 44b8a91f7..3f9024ff5 100644 --- a/src/Exception/RequestException.php +++ b/src/Client/Exception/RequestException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Client\Exception; use Mcp\Schema\JsonRpc\Error; diff --git a/src/Exception/RootsException.php b/src/Client/Exception/RootsException.php similarity index 82% rename from src/Exception/RootsException.php rename to src/Client/Exception/RootsException.php index 8d12cb06c..dac1205fd 100644 --- a/src/Exception/RootsException.php +++ b/src/Client/Exception/RootsException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Client\Exception; /** * Exception thrown when listing roots fails. @@ -19,6 +19,6 @@ * * @author Johannes Wachter */ -final class RootsException extends \RuntimeException implements ExceptionInterface +final class RootsException extends RuntimeException { } diff --git a/src/Client/Exception/RuntimeException.php b/src/Client/Exception/RuntimeException.php new file mode 100644 index 000000000..34fb6315b --- /dev/null +++ b/src/Client/Exception/RuntimeException.php @@ -0,0 +1,19 @@ + + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/src/Exception/SamplingException.php b/src/Client/Exception/SamplingException.php similarity index 82% rename from src/Exception/SamplingException.php rename to src/Client/Exception/SamplingException.php index 17abcebc1..5b5d77092 100644 --- a/src/Exception/SamplingException.php +++ b/src/Client/Exception/SamplingException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Client\Exception; /** * Exception thrown when a sampling request fails. @@ -19,6 +19,6 @@ * * @author Kyrian Obikwelu */ -final class SamplingException extends \RuntimeException implements ExceptionInterface +final class SamplingException extends RuntimeException { } diff --git a/src/Exception/TimeoutException.php b/src/Client/Exception/TimeoutException.php similarity index 92% rename from src/Exception/TimeoutException.php rename to src/Client/Exception/TimeoutException.php index 160fb8ba7..2f7ae0c39 100644 --- a/src/Exception/TimeoutException.php +++ b/src/Client/Exception/TimeoutException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Client\Exception; /** * Exception for timeout conditions. diff --git a/src/Exception/TokenEndpointUnavailableException.php b/src/Client/Exception/TokenEndpointUnavailableException.php similarity index 94% rename from src/Exception/TokenEndpointUnavailableException.php rename to src/Client/Exception/TokenEndpointUnavailableException.php index fbee01bde..728a6afc8 100644 --- a/src/Exception/TokenEndpointUnavailableException.php +++ b/src/Client/Exception/TokenEndpointUnavailableException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Client\Exception; /** * Thrown when the token endpoint can't answer right now, which says nothing about the credentials sent to it. diff --git a/src/Client/Handler/Request/ElicitationRequestHandler.php b/src/Client/Handler/Request/ElicitationRequestHandler.php index 2fac53385..4936b0a57 100644 --- a/src/Client/Handler/Request/ElicitationRequestHandler.php +++ b/src/Client/Handler/Request/ElicitationRequestHandler.php @@ -11,7 +11,7 @@ namespace Mcp\Client\Handler\Request; -use Mcp\Exception\ElicitationException; +use Mcp\Client\Exception\ElicitationException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; diff --git a/src/Client/Handler/Request/ListRootsRequestHandler.php b/src/Client/Handler/Request/ListRootsRequestHandler.php index 50806c19e..addf075a7 100644 --- a/src/Client/Handler/Request/ListRootsRequestHandler.php +++ b/src/Client/Handler/Request/ListRootsRequestHandler.php @@ -11,7 +11,7 @@ namespace Mcp\Client\Handler\Request; -use Mcp\Exception\RootsException; +use Mcp\Client\Exception\RootsException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; diff --git a/src/Client/Handler/Request/SamplingRequestHandler.php b/src/Client/Handler/Request/SamplingRequestHandler.php index 3a7f862e2..e078b3e7e 100644 --- a/src/Client/Handler/Request/SamplingRequestHandler.php +++ b/src/Client/Handler/Request/SamplingRequestHandler.php @@ -11,8 +11,8 @@ namespace Mcp\Client\Handler\Request; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\SamplingException; +use Mcp\Client\Exception\SamplingException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; diff --git a/src/Client/Protocol.php b/src/Client/Protocol.php index 1d8cce902..7476ef68f 100644 --- a/src/Client/Protocol.php +++ b/src/Client/Protocol.php @@ -11,6 +11,9 @@ namespace Mcp\Client; +use Mcp\Client\Exception\InvalidArgumentException; +use Mcp\Client\Exception\RequestCancelledException; +use Mcp\Client\Exception\TimeoutException; use Mcp\Client\Handler\Notification\NotificationHandlerInterface; use Mcp\Client\Handler\Notification\ProgressNotificationHandler; use Mcp\Client\Handler\Request\RequestHandlerInterface; @@ -23,26 +26,23 @@ use Mcp\Client\Transport\HeaderAwareTransportInterface; use Mcp\Client\Transport\HttpTransport; use Mcp\Client\Transport\TransportInterface; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\InvalidInputMessageException; -use Mcp\Exception\RequestCancelledException; -use Mcp\Exception\TimeoutException; -use Mcp\JsonRpc\MessageFactory; use Mcp\Schema\Enum\LoggingLevel; use Mcp\Schema\Enum\ProtocolVersion; +use Mcp\Schema\Exception\InvalidInputMessageException; use Mcp\Schema\Implementation; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Notification; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; +use Mcp\Schema\MessageFactory; use Mcp\Schema\Notification\CancelledNotification; use Mcp\Schema\Notification\InitializedNotification; use Mcp\Schema\Notification\ProgressNotification; use Mcp\Schema\Request\DiscoverRequest; use Mcp\Schema\Request\InitializeRequest; +use Mcp\Schema\RequestMeta; use Mcp\Schema\Result\InitializeResult; use Mcp\Schema\ServerCapabilities; -use Mcp\Server\Stateless\RequestMeta; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; diff --git a/src/Client/Stateless/HeaderFactory.php b/src/Client/Stateless/HeaderFactory.php index 428e1c702..b341feaa5 100644 --- a/src/Client/Stateless/HeaderFactory.php +++ b/src/Client/Stateless/HeaderFactory.php @@ -12,8 +12,8 @@ namespace Mcp\Client\Stateless; use Mcp\Schema\Enum\ProtocolVersion; +use Mcp\Schema\RequestMeta; use Mcp\Schema\Wire\McpHeader; -use Mcp\Server\Stateless\RequestMeta; /** * The HTTP headers a modern-era client puts on every POST (SEP-2243, SEP-2575). diff --git a/src/Client/Stateless/InputRequestResolver.php b/src/Client/Stateless/InputRequestResolver.php index a592542d5..d8e547beb 100644 --- a/src/Client/Stateless/InputRequestResolver.php +++ b/src/Client/Stateless/InputRequestResolver.php @@ -11,8 +11,8 @@ namespace Mcp\Client\Stateless; +use Mcp\Client\Exception\RuntimeException; use Mcp\Client\Handler\Request\RequestHandlerInterface; -use Mcp\Exception\RuntimeException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; diff --git a/src/Client/Stateless/RequestEnvelope.php b/src/Client/Stateless/RequestEnvelope.php index ea42f5c9c..9c3f51d3b 100644 --- a/src/Client/Stateless/RequestEnvelope.php +++ b/src/Client/Stateless/RequestEnvelope.php @@ -15,7 +15,7 @@ use Mcp\Schema\Enum\LoggingLevel; use Mcp\Schema\Enum\ProtocolVersion; use Mcp\Schema\Implementation; -use Mcp\Server\Stateless\RequestMeta; +use Mcp\Schema\RequestMeta; /** * Stamps the per-request `_meta` that replaces the `initialize` handshake diff --git a/src/Client/Transport/BaseTransport.php b/src/Client/Transport/BaseTransport.php index a1fc19363..2a13e7534 100644 --- a/src/Client/Transport/BaseTransport.php +++ b/src/Client/Transport/BaseTransport.php @@ -11,8 +11,8 @@ namespace Mcp\Client\Transport; +use Mcp\Client\Exception\RuntimeException; use Mcp\Client\State\ClientStateInterface; -use Mcp\Exception\RuntimeException; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; diff --git a/src/Client/Transport/HttpTransport.php b/src/Client/Transport/HttpTransport.php index a3d777a15..9817742e0 100644 --- a/src/Client/Transport/HttpTransport.php +++ b/src/Client/Transport/HttpTransport.php @@ -14,14 +14,15 @@ use Http\Discovery\Psr17FactoryDiscovery; use Mcp\Client\Auth\AuthenticatingHttpClient; use Mcp\Client\Auth\AuthenticatorInterface; +use Mcp\Client\Exception\AuthorizationException; +use Mcp\Client\Exception\AuthorizationPendingException; +use Mcp\Client\Exception\ConnectionException; +use Mcp\Client\Exception\InvalidArgumentException; +use Mcp\Client\Exception\RequestCancelledException; +use Mcp\Client\Exception\RequestException; +use Mcp\Client\Exception\TimeoutException; use Mcp\Client\MonotonicClock; -use Mcp\Exception\AuthorizationException; -use Mcp\Exception\AuthorizationPendingException; -use Mcp\Exception\ConnectionException; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\RequestCancelledException; -use Mcp\Exception\RequestException; -use Mcp\Exception\TimeoutException; +use Mcp\Schema\Exception\InvalidArgumentException as SchemaInvalidArgumentException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Wire\McpHeader; @@ -531,7 +532,7 @@ private static function isWellFormedAnswer(array $answer): bool { try { \array_key_exists('error', $answer) ? Error::fromArray($answer) : Response::fromArray($answer); - } catch (InvalidArgumentException) { + } catch (SchemaInvalidArgumentException) { return false; } diff --git a/src/Client/Transport/ReconnectPolicy.php b/src/Client/Transport/ReconnectPolicy.php index e6b4cde7f..e72538833 100644 --- a/src/Client/Transport/ReconnectPolicy.php +++ b/src/Client/Transport/ReconnectPolicy.php @@ -11,7 +11,7 @@ namespace Mcp\Client\Transport; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Client\Exception\InvalidArgumentException; /** * How HttpTransport resumes an SSE stream that closed before its response arrived. diff --git a/src/Client/Transport/SseParser.php b/src/Client/Transport/SseParser.php index 095f86bcf..3de7281b7 100644 --- a/src/Client/Transport/SseParser.php +++ b/src/Client/Transport/SseParser.php @@ -11,7 +11,7 @@ namespace Mcp\Client\Transport; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Client\Exception\InvalidArgumentException; /** * Incremental parser for a text/event-stream body. diff --git a/src/Client/Transport/StdioTransport.php b/src/Client/Transport/StdioTransport.php index c0aa83639..03db08d6e 100644 --- a/src/Client/Transport/StdioTransport.php +++ b/src/Client/Transport/StdioTransport.php @@ -11,10 +11,10 @@ namespace Mcp\Client\Transport; -use Mcp\Exception\ConnectionException; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\RequestCancelledException; -use Mcp\Exception\TimeoutException; +use Mcp\Client\Exception\ConnectionException; +use Mcp\Client\Exception\InvalidArgumentException; +use Mcp\Client\Exception\RequestCancelledException; +use Mcp\Client\Exception\TimeoutException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Response; use Psr\Log\LoggerInterface; diff --git a/src/Client/Transport/TransportInterface.php b/src/Client/Transport/TransportInterface.php index 3a0b7291b..9bede24d3 100644 --- a/src/Client/Transport/TransportInterface.php +++ b/src/Client/Transport/TransportInterface.php @@ -11,6 +11,7 @@ namespace Mcp\Client\Transport; +use Mcp\Client\Exception\ConnectionException; use Mcp\Client\State\ClientStateInterface; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Response; @@ -52,7 +53,7 @@ interface TransportInterface * - Initialization completes successfully * - Connection fails (throws ConnectionException) * - * @throws \Mcp\Exception\ConnectionException + * @throws ConnectionException */ public function connect(): void; diff --git a/src/Schema/Annotations.php b/src/Schema/Annotations.php index ec64e7ab9..b7dcbffc6 100644 --- a/src/Schema/Annotations.php +++ b/src/Schema/Annotations.php @@ -11,8 +11,8 @@ namespace Mcp\Schema; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Enum\Role; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Optional annotations for the client. The client can use annotations diff --git a/src/Schema/Content/AudioContent.php b/src/Schema/Content/AudioContent.php index 8baa357b3..66ed48e27 100644 --- a/src/Schema/Content/AudioContent.php +++ b/src/Schema/Content/AudioContent.php @@ -11,9 +11,9 @@ namespace Mcp\Schema\Content; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\RuntimeException; use Mcp\Schema\Annotations; +use Mcp\Schema\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\RuntimeException; /** * Represents audio content in MCP. diff --git a/src/Schema/Content/BlobResourceContents.php b/src/Schema/Content/BlobResourceContents.php index d7ffa3fbd..6f57875b2 100644 --- a/src/Schema/Content/BlobResourceContents.php +++ b/src/Schema/Content/BlobResourceContents.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Content; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Represents blob resource contents in MCP. diff --git a/src/Schema/Content/EmbeddedResource.php b/src/Schema/Content/EmbeddedResource.php index 9eeefde85..b71ae2ca9 100644 --- a/src/Schema/Content/EmbeddedResource.php +++ b/src/Schema/Content/EmbeddedResource.php @@ -11,9 +11,9 @@ namespace Mcp\Schema\Content; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\RuntimeException; use Mcp\Schema\Annotations; +use Mcp\Schema\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\RuntimeException; /** * Represents embedded resource content within a message. diff --git a/src/Schema/Content/ImageContent.php b/src/Schema/Content/ImageContent.php index dc5dce1e7..a32d22bd8 100644 --- a/src/Schema/Content/ImageContent.php +++ b/src/Schema/Content/ImageContent.php @@ -11,8 +11,8 @@ namespace Mcp\Schema\Content; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Annotations; +use Mcp\Schema\Exception\InvalidArgumentException; /** * @phpstan-import-type AnnotationsData from Annotations diff --git a/src/Schema/Content/MimeType.php b/src/Schema/Content/MimeType.php index 9eb83e619..c0aec46bc 100644 --- a/src/Schema/Content/MimeType.php +++ b/src/Schema/Content/MimeType.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Content; -use Mcp\Exception\LogicException; +use Mcp\Schema\Exception\LogicException; /** * @internal diff --git a/src/Schema/Content/PromptMessage.php b/src/Schema/Content/PromptMessage.php index e54f65838..4fe563bd5 100644 --- a/src/Schema/Content/PromptMessage.php +++ b/src/Schema/Content/PromptMessage.php @@ -11,8 +11,8 @@ namespace Mcp\Schema\Content; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Enum\Role; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Describes a message returned as part of a prompt. diff --git a/src/Schema/Content/ResourceLink.php b/src/Schema/Content/ResourceLink.php index 6d8f07561..ae6c4bf7a 100644 --- a/src/Schema/Content/ResourceLink.php +++ b/src/Schema/Content/ResourceLink.php @@ -11,8 +11,8 @@ namespace Mcp\Schema\Content; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Annotations; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\Icon; /** diff --git a/src/Schema/Content/SamplingMessage.php b/src/Schema/Content/SamplingMessage.php index c4af551cd..17e0cf5fb 100644 --- a/src/Schema/Content/SamplingMessage.php +++ b/src/Schema/Content/SamplingMessage.php @@ -11,8 +11,8 @@ namespace Mcp\Schema\Content; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Enum\Role; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Describes a message issued to or received from an LLM API during sampling. diff --git a/src/Schema/Content/TextContent.php b/src/Schema/Content/TextContent.php index 73a83b415..7e0c1d49f 100644 --- a/src/Schema/Content/TextContent.php +++ b/src/Schema/Content/TextContent.php @@ -11,8 +11,8 @@ namespace Mcp\Schema\Content; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Annotations; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Represents text content in MCP. diff --git a/src/Schema/Content/TextResourceContents.php b/src/Schema/Content/TextResourceContents.php index 614933386..e4c338abc 100644 --- a/src/Schema/Content/TextResourceContents.php +++ b/src/Schema/Content/TextResourceContents.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Content; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Represents text resource contents in MCP. diff --git a/src/Schema/Content/ToolResultContent.php b/src/Schema/Content/ToolResultContent.php index 87f46a293..203f4d340 100644 --- a/src/Schema/Content/ToolResultContent.php +++ b/src/Schema/Content/ToolResultContent.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Content; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * The result of a tool use, provided by the user back to the assistant. diff --git a/src/Schema/Content/ToolUseContent.php b/src/Schema/Content/ToolUseContent.php index d04011112..c890e3368 100644 --- a/src/Schema/Content/ToolUseContent.php +++ b/src/Schema/Content/ToolUseContent.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Content; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * A request from the assistant to call a tool. diff --git a/src/Schema/Elicitation/AbstractSchemaDefinition.php b/src/Schema/Elicitation/AbstractSchemaDefinition.php index f6698b2c1..db75a5309 100644 --- a/src/Schema/Elicitation/AbstractSchemaDefinition.php +++ b/src/Schema/Elicitation/AbstractSchemaDefinition.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Elicitation; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Base class for schema definitions in elicitation requests. diff --git a/src/Schema/Elicitation/ElicitationSchema.php b/src/Schema/Elicitation/ElicitationSchema.php index 720c0ca37..a3abfa25f 100644 --- a/src/Schema/Elicitation/ElicitationSchema.php +++ b/src/Schema/Elicitation/ElicitationSchema.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Elicitation; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Schema wrapper for elicitation requestedSchema (JSON Schema object type). diff --git a/src/Schema/Elicitation/EnumSchemaDefinition.php b/src/Schema/Elicitation/EnumSchemaDefinition.php index 6127fd997..aeab51dbe 100644 --- a/src/Schema/Elicitation/EnumSchemaDefinition.php +++ b/src/Schema/Elicitation/EnumSchemaDefinition.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Elicitation; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Schema definition for string enum fields in elicitation requests. diff --git a/src/Schema/Elicitation/MultiSelectEnumSchemaDefinition.php b/src/Schema/Elicitation/MultiSelectEnumSchemaDefinition.php index 996eced90..b44e0e986 100644 --- a/src/Schema/Elicitation/MultiSelectEnumSchemaDefinition.php +++ b/src/Schema/Elicitation/MultiSelectEnumSchemaDefinition.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Elicitation; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Schema definition for multi-select enum fields without titles (SEP-1330). diff --git a/src/Schema/Elicitation/NumberSchemaDefinition.php b/src/Schema/Elicitation/NumberSchemaDefinition.php index 18ddfc38c..e1c57d765 100644 --- a/src/Schema/Elicitation/NumberSchemaDefinition.php +++ b/src/Schema/Elicitation/NumberSchemaDefinition.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Elicitation; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Schema definition for number/integer fields in elicitation requests. diff --git a/src/Schema/Elicitation/StringSchemaDefinition.php b/src/Schema/Elicitation/StringSchemaDefinition.php index e04f5c4d2..676bd0885 100644 --- a/src/Schema/Elicitation/StringSchemaDefinition.php +++ b/src/Schema/Elicitation/StringSchemaDefinition.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Elicitation; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Schema definition for string fields in elicitation requests. diff --git a/src/Schema/Elicitation/TitledEnumSchemaDefinition.php b/src/Schema/Elicitation/TitledEnumSchemaDefinition.php index 334e0bcdf..6e9e6caf9 100644 --- a/src/Schema/Elicitation/TitledEnumSchemaDefinition.php +++ b/src/Schema/Elicitation/TitledEnumSchemaDefinition.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Elicitation; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Schema definition for single-select enum fields with titled options (SEP-1330). diff --git a/src/Schema/Elicitation/TitledMultiSelectEnumSchemaDefinition.php b/src/Schema/Elicitation/TitledMultiSelectEnumSchemaDefinition.php index ee7241d19..944cc5c65 100644 --- a/src/Schema/Elicitation/TitledMultiSelectEnumSchemaDefinition.php +++ b/src/Schema/Elicitation/TitledMultiSelectEnumSchemaDefinition.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Elicitation; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Schema definition for multi-select enum fields with titled options (SEP-1330). diff --git a/src/Schema/Enum/ProtocolVersion.php b/src/Schema/Enum/ProtocolVersion.php index 700aebf9b..7812d9fea 100644 --- a/src/Schema/Enum/ProtocolVersion.php +++ b/src/Schema/Enum/ProtocolVersion.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Enum; -use Mcp\Exception\LogicException; +use Mcp\Schema\Exception\LogicException; /** * Registry of the MCP protocol revisions this SDK knows about. diff --git a/src/Exception/ExceptionInterface.php b/src/Schema/Exception/ExceptionInterface.php similarity index 92% rename from src/Exception/ExceptionInterface.php rename to src/Schema/Exception/ExceptionInterface.php index 634493059..f95979806 100644 --- a/src/Exception/ExceptionInterface.php +++ b/src/Schema/Exception/ExceptionInterface.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Schema\Exception; /** * @author Tobias Nyholm diff --git a/src/Schema/Exception/InvalidArgumentException.php b/src/Schema/Exception/InvalidArgumentException.php new file mode 100644 index 000000000..a1abda4d8 --- /dev/null +++ b/src/Schema/Exception/InvalidArgumentException.php @@ -0,0 +1,19 @@ + + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/src/Exception/InvalidInputMessageException.php b/src/Schema/Exception/InvalidInputMessageException.php similarity index 90% rename from src/Exception/InvalidInputMessageException.php rename to src/Schema/Exception/InvalidInputMessageException.php index 97d5d4365..735fdc3d9 100644 --- a/src/Exception/InvalidInputMessageException.php +++ b/src/Schema/Exception/InvalidInputMessageException.php @@ -9,12 +9,12 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Schema\Exception; /** * @author Tobias Nyholm */ -class InvalidInputMessageException extends \InvalidArgumentException implements ExceptionInterface +class InvalidInputMessageException extends InvalidArgumentException { private string|int|null $requestId = null; diff --git a/src/Exception/InvalidParamsException.php b/src/Schema/Exception/InvalidParamsException.php similarity index 94% rename from src/Exception/InvalidParamsException.php rename to src/Schema/Exception/InvalidParamsException.php index 9e5809015..d6545e369 100644 --- a/src/Exception/InvalidParamsException.php +++ b/src/Schema/Exception/InvalidParamsException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Schema\Exception; /** * The params of a request do not fit the method, e.g. a required one is missing. diff --git a/src/Schema/Exception/LogicException.php b/src/Schema/Exception/LogicException.php new file mode 100644 index 000000000..3f2d12c90 --- /dev/null +++ b/src/Schema/Exception/LogicException.php @@ -0,0 +1,19 @@ + + */ +final class LogicException extends \LogicException implements ExceptionInterface +{ +} diff --git a/src/Exception/MissingRequestMetaException.php b/src/Schema/Exception/MissingRequestMetaException.php similarity index 94% rename from src/Exception/MissingRequestMetaException.php rename to src/Schema/Exception/MissingRequestMetaException.php index 1499205f2..93fe01f06 100644 --- a/src/Exception/MissingRequestMetaException.php +++ b/src/Schema/Exception/MissingRequestMetaException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Schema\Exception; /** * A modern-era request omitted the protocol version or client capabilities. diff --git a/src/Exception/RuntimeException.php b/src/Schema/Exception/RuntimeException.php similarity index 92% rename from src/Exception/RuntimeException.php rename to src/Schema/Exception/RuntimeException.php index b68a1bf42..15e594989 100644 --- a/src/Exception/RuntimeException.php +++ b/src/Schema/Exception/RuntimeException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Schema\Exception; /** * @author Christopher Hertel diff --git a/src/Exception/UnknownMethodException.php b/src/Schema/Exception/UnknownMethodException.php similarity index 92% rename from src/Exception/UnknownMethodException.php rename to src/Schema/Exception/UnknownMethodException.php index 16163a6b5..4517a0307 100644 --- a/src/Exception/UnknownMethodException.php +++ b/src/Schema/Exception/UnknownMethodException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Schema\Exception; /** * @author Christopher Hertel diff --git a/src/Schema/Extension/AbstractExtension.php b/src/Schema/Extension/AbstractExtension.php index a449c8a4c..70ffb91a2 100644 --- a/src/Schema/Extension/AbstractExtension.php +++ b/src/Schema/Extension/AbstractExtension.php @@ -24,9 +24,4 @@ public function getMessages(): array { return []; } - - public function getRequestHandlers(): iterable - { - return []; - } } diff --git a/src/Schema/Extension/Apps/UiResourceContentMeta.php b/src/Schema/Extension/Apps/UiResourceContentMeta.php index 666a7e995..137d080bb 100644 --- a/src/Schema/Extension/Apps/UiResourceContentMeta.php +++ b/src/Schema/Extension/Apps/UiResourceContentMeta.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Extension\Apps; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Metadata for the _meta.ui field on resource content in a resources/read response. diff --git a/src/Schema/Extension/Apps/UiResourceCsp.php b/src/Schema/Extension/Apps/UiResourceCsp.php index e3550a675..ba08ecf1c 100644 --- a/src/Schema/Extension/Apps/UiResourceCsp.php +++ b/src/Schema/Extension/Apps/UiResourceCsp.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Extension\Apps; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Content Security Policy configuration for MCP App resources. diff --git a/src/Schema/Extension/Apps/UiToolMeta.php b/src/Schema/Extension/Apps/UiToolMeta.php index 39edd8f3f..8cc988508 100644 --- a/src/Schema/Extension/Apps/UiToolMeta.php +++ b/src/Schema/Extension/Apps/UiToolMeta.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Extension\Apps; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Metadata for the _meta.ui field on a Tool, linking it to a UI resource. diff --git a/src/Schema/Extension/ExtensionIdentifier.php b/src/Schema/Extension/ExtensionIdentifier.php index 2d714d6ee..595cc9307 100644 --- a/src/Schema/Extension/ExtensionIdentifier.php +++ b/src/Schema/Extension/ExtensionIdentifier.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Extension; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * An extension identifier (SEP-2133): a `_meta` key with a mandatory vendor diff --git a/src/Schema/Extension/ExtensionInterface.php b/src/Schema/Extension/ExtensionInterface.php index a66352546..f28cb7f72 100644 --- a/src/Schema/Extension/ExtensionInterface.php +++ b/src/Schema/Extension/ExtensionInterface.php @@ -13,8 +13,6 @@ use Mcp\Schema\JsonRpc\Notification; use Mcp\Schema\JsonRpc\Request; -use Mcp\Schema\JsonRpc\ResultInterface; -use Mcp\Server\Handler\Request\RequestHandlerInterface; /** * An MCP protocol extension advertised during capability negotiation. @@ -25,8 +23,7 @@ * (initialize request); the side that enables it decides which. * * An extension that only announces a capability, without adding RPC methods of its - * own, can extend {@see AbstractExtension} and skip {@see self::getMessages()} and - * {@see self::getRequestHandlers()} entirely. + * own, can extend {@see AbstractExtension} and skip {@see self::getMessages()}. * * @author Christopher Hertel */ @@ -51,7 +48,7 @@ public function getCapabilities(): array; /** * Every message class this extension defines. * - * These are registered with the {@see \Mcp\JsonRpc\MessageFactory}, without + * These are registered with the {@see \Mcp\Schema\MessageFactory}, without * which an extension's method cannot be decoded off the wire at all, and * their method names are what let a server distinguish an extension it does * not serve from a method that does not exist. An extension with no methods @@ -60,11 +57,4 @@ public function getCapabilities(): array; * @return list|class-string> */ public function getMessages(): array; - - /** - * The handlers serving those methods. - * - * @return iterable> - */ - public function getRequestHandlers(): iterable; } diff --git a/src/Schema/Icon.php b/src/Schema/Icon.php index 71bddfd74..cfb56d15d 100644 --- a/src/Schema/Icon.php +++ b/src/Schema/Icon.php @@ -11,8 +11,8 @@ namespace Mcp\Schema; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Enum\IconTheme; +use Mcp\Schema\Exception\InvalidArgumentException; /** * A url pointing to an icon URL or a base64-encoded data URI. diff --git a/src/Schema/Implementation.php b/src/Schema/Implementation.php index c8b755234..8dd60c3be 100644 --- a/src/Schema/Implementation.php +++ b/src/Schema/Implementation.php @@ -11,7 +11,7 @@ namespace Mcp\Schema; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Describes the name and version of an MCP implementation. diff --git a/src/JsonRpc/Json.php b/src/Schema/Json.php similarity index 97% rename from src/JsonRpc/Json.php rename to src/Schema/Json.php index a9341343f..207d7961e 100644 --- a/src/JsonRpc/Json.php +++ b/src/Schema/Json.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\JsonRpc; +namespace Mcp\Schema; /** * @internal diff --git a/src/Schema/JsonRpc/Error.php b/src/Schema/JsonRpc/Error.php index 3636f89fa..183bb1a27 100644 --- a/src/Schema/JsonRpc/Error.php +++ b/src/Schema/JsonRpc/Error.php @@ -11,9 +11,9 @@ namespace Mcp\Schema\JsonRpc; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\ClientCapabilities; use Mcp\Schema\Enum\ProtocolVersion; +use Mcp\Schema\Exception\InvalidArgumentException; /** * A response to a request that indicates an error occurred. diff --git a/src/Schema/JsonRpc/Notification.php b/src/Schema/JsonRpc/Notification.php index 789678bb4..ddf8e876d 100644 --- a/src/Schema/JsonRpc/Notification.php +++ b/src/Schema/JsonRpc/Notification.php @@ -11,8 +11,8 @@ namespace Mcp\Schema\JsonRpc; -use Mcp\Exception\InvalidArgumentException; -use Mcp\JsonRpc\Json; +use Mcp\Schema\Exception\InvalidArgumentException; +use Mcp\Schema\Json; /** * @phpstan-type NotificationData array{ diff --git a/src/Schema/JsonRpc/Request.php b/src/Schema/JsonRpc/Request.php index eeb927e11..5d58b654e 100644 --- a/src/Schema/JsonRpc/Request.php +++ b/src/Schema/JsonRpc/Request.php @@ -11,9 +11,9 @@ namespace Mcp\Schema\JsonRpc; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\InvalidParamsException; -use Mcp\JsonRpc\Json; +use Mcp\Schema\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidParamsException; +use Mcp\Schema\Json; /** * @phpstan-type RequestData array{ diff --git a/src/Schema/JsonRpc/Response.php b/src/Schema/JsonRpc/Response.php index c3bcbdbcd..f4fe9af48 100644 --- a/src/Schema/JsonRpc/Response.php +++ b/src/Schema/JsonRpc/Response.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\JsonRpc; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Covariant because a Response only hands its result out, never consumes it, diff --git a/src/JsonRpc/MessageFactory.php b/src/Schema/MessageFactory.php similarity index 95% rename from src/JsonRpc/MessageFactory.php rename to src/Schema/MessageFactory.php index c6a82cbd7..ce9377730 100644 --- a/src/JsonRpc/MessageFactory.php +++ b/src/Schema/MessageFactory.php @@ -9,13 +9,13 @@ * file that was distributed with this source code. */ -namespace Mcp\JsonRpc; +namespace Mcp\Schema; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\InvalidInputMessageException; -use Mcp\Exception\InvalidParamsException; -use Mcp\Exception\UnknownMethodException; use Mcp\Schema; +use Mcp\Schema\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidInputMessageException; +use Mcp\Schema\Exception\InvalidParamsException; +use Mcp\Schema\Exception\UnknownMethodException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\MessageInterface; use Mcp\Schema\JsonRpc\Notification; @@ -172,6 +172,8 @@ private function createMessage(\stdClass|array $message): MessageInterface return $messageClass::fromArray($data); } catch (InvalidParamsException $e) { throw InvalidInputMessageException::forInvalidParams($e->getMessage(), $data['method'], $e); + } catch (InvalidInputMessageException $e) { + throw $e; } catch (InvalidArgumentException $e) { throw new InvalidInputMessageException($e->getMessage(), 0, $e); } diff --git a/src/Schema/ModelPreferences.php b/src/Schema/ModelPreferences.php index e66842900..cf223c2c6 100644 --- a/src/Schema/ModelPreferences.php +++ b/src/Schema/ModelPreferences.php @@ -11,7 +11,7 @@ namespace Mcp\Schema; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * The server's preferences for model selection, requested of the client during sampling. diff --git a/src/Schema/Notification/CancelledNotification.php b/src/Schema/Notification/CancelledNotification.php index 4ae325765..e86a33d33 100644 --- a/src/Schema/Notification/CancelledNotification.php +++ b/src/Schema/Notification/CancelledNotification.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Notification; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Notification; /** diff --git a/src/Schema/Notification/LoggingMessageNotification.php b/src/Schema/Notification/LoggingMessageNotification.php index 17cbd70ce..ad18f6802 100644 --- a/src/Schema/Notification/LoggingMessageNotification.php +++ b/src/Schema/Notification/LoggingMessageNotification.php @@ -11,8 +11,8 @@ namespace Mcp\Schema\Notification; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Enum\LoggingLevel; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Notification; /** diff --git a/src/Schema/Notification/ProgressNotification.php b/src/Schema/Notification/ProgressNotification.php index 15fc50ac9..341da7303 100644 --- a/src/Schema/Notification/ProgressNotification.php +++ b/src/Schema/Notification/ProgressNotification.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Notification; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Notification; /** diff --git a/src/Schema/Notification/ResourceUpdatedNotification.php b/src/Schema/Notification/ResourceUpdatedNotification.php index 946d500ec..2a07fb399 100644 --- a/src/Schema/Notification/ResourceUpdatedNotification.php +++ b/src/Schema/Notification/ResourceUpdatedNotification.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Notification; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Notification; /** diff --git a/src/Schema/Prompt.php b/src/Schema/Prompt.php index 1f33e410d..e49be3cf9 100644 --- a/src/Schema/Prompt.php +++ b/src/Schema/Prompt.php @@ -11,7 +11,7 @@ namespace Mcp\Schema; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * A prompt or prompt template that the server offers. diff --git a/src/Schema/PromptArgument.php b/src/Schema/PromptArgument.php index 38fe3dc0a..88f3262ed 100644 --- a/src/Schema/PromptArgument.php +++ b/src/Schema/PromptArgument.php @@ -11,7 +11,7 @@ namespace Mcp\Schema; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Describes an argument that a prompt can accept. diff --git a/src/Schema/Request/CallToolRequest.php b/src/Schema/Request/CallToolRequest.php index 3d8e970b3..a60ffa7d3 100644 --- a/src/Schema/Request/CallToolRequest.php +++ b/src/Schema/Request/CallToolRequest.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Request; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Request; /** diff --git a/src/Schema/Request/CompletionCompleteRequest.php b/src/Schema/Request/CompletionCompleteRequest.php index ee362a21f..bcbf04608 100644 --- a/src/Schema/Request/CompletionCompleteRequest.php +++ b/src/Schema/Request/CompletionCompleteRequest.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Request; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\PromptReference; use Mcp\Schema\ResourceReference; diff --git a/src/Schema/Request/CreateSamplingMessageRequest.php b/src/Schema/Request/CreateSamplingMessageRequest.php index 12e030924..0e65941ed 100644 --- a/src/Schema/Request/CreateSamplingMessageRequest.php +++ b/src/Schema/Request/CreateSamplingMessageRequest.php @@ -11,12 +11,12 @@ namespace Mcp\Schema\Request; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Content\SamplingMessage; use Mcp\Schema\Content\ToolResultContent; use Mcp\Schema\Content\ToolUseContent; use Mcp\Schema\Enum\Role; use Mcp\Schema\Enum\SamplingContext; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\ModelPreferences; use Mcp\Schema\Tool; diff --git a/src/Schema/Request/ElicitRequest.php b/src/Schema/Request/ElicitRequest.php index ae540064a..a80d22e9f 100644 --- a/src/Schema/Request/ElicitRequest.php +++ b/src/Schema/Request/ElicitRequest.php @@ -11,10 +11,10 @@ namespace Mcp\Schema\Request; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\LogicException; use Mcp\Schema\Elicitation\ElicitationSchema; use Mcp\Schema\Enum\ElicitationMode; +use Mcp\Schema\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\LogicException; use Mcp\Schema\JsonRpc\Request; /** diff --git a/src/Schema/Request/GetPromptRequest.php b/src/Schema/Request/GetPromptRequest.php index a75d71c33..0bcd6a9a0 100644 --- a/src/Schema/Request/GetPromptRequest.php +++ b/src/Schema/Request/GetPromptRequest.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Request; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Request; /** diff --git a/src/Schema/Request/InitializeRequest.php b/src/Schema/Request/InitializeRequest.php index f7b746013..b8a19a07d 100644 --- a/src/Schema/Request/InitializeRequest.php +++ b/src/Schema/Request/InitializeRequest.php @@ -11,8 +11,8 @@ namespace Mcp\Schema\Request; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\ClientCapabilities; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\Implementation; use Mcp\Schema\JsonRpc\Request; diff --git a/src/Schema/Request/ListPromptsRequest.php b/src/Schema/Request/ListPromptsRequest.php index 3f1cff0e5..d1d794771 100644 --- a/src/Schema/Request/ListPromptsRequest.php +++ b/src/Schema/Request/ListPromptsRequest.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Request; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Request; /** diff --git a/src/Schema/Request/ListResourceTemplatesRequest.php b/src/Schema/Request/ListResourceTemplatesRequest.php index 1822c57e0..dc66eb98b 100644 --- a/src/Schema/Request/ListResourceTemplatesRequest.php +++ b/src/Schema/Request/ListResourceTemplatesRequest.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Request; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Request; /** diff --git a/src/Schema/Request/ListResourcesRequest.php b/src/Schema/Request/ListResourcesRequest.php index a8fe7727e..b9a68699b 100644 --- a/src/Schema/Request/ListResourcesRequest.php +++ b/src/Schema/Request/ListResourcesRequest.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Request; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Request; /** diff --git a/src/Schema/Request/ListToolsRequest.php b/src/Schema/Request/ListToolsRequest.php index 83cf88755..1bdfbdc73 100644 --- a/src/Schema/Request/ListToolsRequest.php +++ b/src/Schema/Request/ListToolsRequest.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Request; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Request; /** diff --git a/src/Schema/Request/ReadResourceRequest.php b/src/Schema/Request/ReadResourceRequest.php index 69523eff3..c671f7350 100644 --- a/src/Schema/Request/ReadResourceRequest.php +++ b/src/Schema/Request/ReadResourceRequest.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Request; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Request; /** diff --git a/src/Schema/Request/ResourceSubscribeRequest.php b/src/Schema/Request/ResourceSubscribeRequest.php index 036785a21..98a1b0539 100644 --- a/src/Schema/Request/ResourceSubscribeRequest.php +++ b/src/Schema/Request/ResourceSubscribeRequest.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Request; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Request; /** diff --git a/src/Schema/Request/ResourceUnsubscribeRequest.php b/src/Schema/Request/ResourceUnsubscribeRequest.php index fd93727b6..04f08884e 100644 --- a/src/Schema/Request/ResourceUnsubscribeRequest.php +++ b/src/Schema/Request/ResourceUnsubscribeRequest.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Request; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Request; /** diff --git a/src/Schema/Request/SetLogLevelRequest.php b/src/Schema/Request/SetLogLevelRequest.php index f781ca513..88435d8a1 100644 --- a/src/Schema/Request/SetLogLevelRequest.php +++ b/src/Schema/Request/SetLogLevelRequest.php @@ -11,8 +11,8 @@ namespace Mcp\Schema\Request; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Enum\LoggingLevel; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Request; /** diff --git a/src/Server/Stateless/RequestMeta.php b/src/Schema/RequestMeta.php similarity index 94% rename from src/Server/Stateless/RequestMeta.php rename to src/Schema/RequestMeta.php index 3744d92c3..47466070b 100644 --- a/src/Server/Stateless/RequestMeta.php +++ b/src/Schema/RequestMeta.php @@ -9,13 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Server\Stateless; +namespace Mcp\Schema; -use Mcp\Exception\MissingRequestMetaException; -use Mcp\Schema\ClientCapabilities; use Mcp\Schema\Enum\LoggingLevel; -use Mcp\Schema\Implementation; -use Mcp\Server\Wire\InboundClassifier; +use Mcp\Schema\Exception\MissingRequestMetaException; +use Mcp\Schema\Wire\McpHeader; /** * The per-request metadata that replaces the `initialize` handshake in the @@ -123,7 +121,7 @@ private static function parseTraceContext(array $meta, array $headers): array foreach (self::TRACE_KEYS as $key) { if (\is_string($meta[$key] ?? null)) { $context[$key] = $meta[$key]; - } elseif (null !== $header = InboundClassifier::header($headers, $key)) { + } elseif (null !== $header = McpHeader::lookup($headers, $key)) { $context[$key] = $header; } } diff --git a/src/Schema/ResourceDefinition.php b/src/Schema/ResourceDefinition.php index 1d2a11058..1985e565c 100644 --- a/src/Schema/ResourceDefinition.php +++ b/src/Schema/ResourceDefinition.php @@ -11,7 +11,7 @@ namespace Mcp\Schema; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * A known resource that the server is capable of reading. diff --git a/src/Schema/ResourceTemplate.php b/src/Schema/ResourceTemplate.php index 2b7c6abb8..c89d04906 100644 --- a/src/Schema/ResourceTemplate.php +++ b/src/Schema/ResourceTemplate.php @@ -11,7 +11,7 @@ namespace Mcp\Schema; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * A template description for resources available on the server. diff --git a/src/Schema/Result/CallToolResult.php b/src/Schema/Result/CallToolResult.php index 1582f7953..f00c4fdad 100644 --- a/src/Schema/Result/CallToolResult.php +++ b/src/Schema/Result/CallToolResult.php @@ -11,7 +11,6 @@ namespace Mcp\Schema\Result; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Content\AudioContent; use Mcp\Schema\Content\Content; use Mcp\Schema\Content\EmbeddedResource; @@ -19,6 +18,7 @@ use Mcp\Schema\Content\ResourceLink; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Enum\StructuredContent; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\ResultInterface; /** diff --git a/src/Schema/Result/CompletionCompleteResult.php b/src/Schema/Result/CompletionCompleteResult.php index 43c9fed4c..02e4b708c 100644 --- a/src/Schema/Result/CompletionCompleteResult.php +++ b/src/Schema/Result/CompletionCompleteResult.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Result; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\ResultInterface; /** diff --git a/src/Schema/Result/CreateSamplingMessageResult.php b/src/Schema/Result/CreateSamplingMessageResult.php index a325ed942..a434064af 100644 --- a/src/Schema/Result/CreateSamplingMessageResult.php +++ b/src/Schema/Result/CreateSamplingMessageResult.php @@ -11,12 +11,12 @@ namespace Mcp\Schema\Result; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Content\AudioContent; use Mcp\Schema\Content\ImageContent; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Content\ToolUseContent; use Mcp\Schema\Enum\Role; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\ResultInterface; /** diff --git a/src/Schema/Result/DiscoverResult.php b/src/Schema/Result/DiscoverResult.php index 22222e973..524bf9121 100644 --- a/src/Schema/Result/DiscoverResult.php +++ b/src/Schema/Result/DiscoverResult.php @@ -11,9 +11,8 @@ namespace Mcp\Schema\Result; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Enum\ProtocolVersion; -use Mcp\Schema\Enum\ResultType; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\ResultInterface; use Mcp\Schema\ServerCapabilities; diff --git a/src/Schema/Result/ElicitResult.php b/src/Schema/Result/ElicitResult.php index 371ae4cd7..4c3de1ead 100644 --- a/src/Schema/Result/ElicitResult.php +++ b/src/Schema/Result/ElicitResult.php @@ -11,9 +11,9 @@ namespace Mcp\Schema\Result; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Enum\ElicitAction; use Mcp\Schema\Enum\ElicitationMode; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\ResultInterface; /** diff --git a/src/Schema/Result/GetPromptResult.php b/src/Schema/Result/GetPromptResult.php index ffc7ff3ea..c9d4acb5e 100644 --- a/src/Schema/Result/GetPromptResult.php +++ b/src/Schema/Result/GetPromptResult.php @@ -11,8 +11,8 @@ namespace Mcp\Schema\Result; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Content\PromptMessage; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\ResultInterface; /** diff --git a/src/Schema/Result/InitializeResult.php b/src/Schema/Result/InitializeResult.php index 05c0f5024..78c386850 100644 --- a/src/Schema/Result/InitializeResult.php +++ b/src/Schema/Result/InitializeResult.php @@ -11,10 +11,9 @@ namespace Mcp\Schema\Result; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Enum\ProtocolVersion; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\Implementation; -use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\JsonRpc\ResultInterface; use Mcp\Schema\ServerCapabilities; diff --git a/src/Schema/Result/InputRequiredResult.php b/src/Schema/Result/InputRequiredResult.php index a0fca5e61..4525535ec 100644 --- a/src/Schema/Result/InputRequiredResult.php +++ b/src/Schema/Result/InputRequiredResult.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Result; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\ResultInterface; use Mcp\Schema\Request\CreateSamplingMessageRequest; use Mcp\Schema\Request\ElicitRequest; diff --git a/src/Schema/Result/ListPromptsResult.php b/src/Schema/Result/ListPromptsResult.php index fd164c454..7e8d2e1dc 100644 --- a/src/Schema/Result/ListPromptsResult.php +++ b/src/Schema/Result/ListPromptsResult.php @@ -11,8 +11,7 @@ namespace Mcp\Schema\Result; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Schema\JsonRpc\Response; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\ResultInterface; use Mcp\Schema\Prompt; diff --git a/src/Schema/Result/ListResourceTemplatesResult.php b/src/Schema/Result/ListResourceTemplatesResult.php index e0b711461..cc475eb64 100644 --- a/src/Schema/Result/ListResourceTemplatesResult.php +++ b/src/Schema/Result/ListResourceTemplatesResult.php @@ -11,8 +11,7 @@ namespace Mcp\Schema\Result; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Schema\JsonRpc\Response; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\ResultInterface; use Mcp\Schema\ResourceTemplate; diff --git a/src/Schema/Result/ListResourcesResult.php b/src/Schema/Result/ListResourcesResult.php index 63066b064..e312a7f67 100644 --- a/src/Schema/Result/ListResourcesResult.php +++ b/src/Schema/Result/ListResourcesResult.php @@ -11,8 +11,7 @@ namespace Mcp\Schema\Result; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Schema\JsonRpc\Response; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\ResultInterface; use Mcp\Schema\ResourceDefinition; diff --git a/src/Schema/Result/ListRootsResult.php b/src/Schema/Result/ListRootsResult.php index 9a6d29041..4e453f25b 100644 --- a/src/Schema/Result/ListRootsResult.php +++ b/src/Schema/Result/ListRootsResult.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Result; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\ResultInterface; use Mcp\Schema\Root; diff --git a/src/Schema/Result/ListToolsResult.php b/src/Schema/Result/ListToolsResult.php index c6ba6c846..6f027b318 100644 --- a/src/Schema/Result/ListToolsResult.php +++ b/src/Schema/Result/ListToolsResult.php @@ -11,8 +11,7 @@ namespace Mcp\Schema\Result; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Schema\JsonRpc\Response; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\ResultInterface; use Mcp\Schema\Tool; diff --git a/src/Schema/Result/ReadResourceResult.php b/src/Schema/Result/ReadResourceResult.php index e97e3e077..7d4f5301f 100644 --- a/src/Schema/Result/ReadResourceResult.php +++ b/src/Schema/Result/ReadResourceResult.php @@ -11,11 +11,11 @@ namespace Mcp\Schema\Result; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Content\BlobResourceContents; use Mcp\Schema\Content\ResourceContents; use Mcp\Schema\Content\TextResourceContents; use Mcp\Schema\Enum\CacheScope; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\ResultInterface; /** diff --git a/src/Schema/Root.php b/src/Schema/Root.php index cad18f705..fae13da38 100644 --- a/src/Schema/Root.php +++ b/src/Schema/Root.php @@ -11,7 +11,7 @@ namespace Mcp\Schema; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Represents a root directory or file that the server can operate on. diff --git a/src/Schema/SecureUrl.php b/src/Schema/SecureUrl.php new file mode 100644 index 000000000..fe31a5dce --- /dev/null +++ b/src/Schema/SecureUrl.php @@ -0,0 +1,177 @@ + + */ +final class SecureUrl +{ + /** @var list */ + private const PRIVATE_IPV4 = [['10.0.0.0', 8], ['172.16.0.0', 12], ['192.168.0.0', 16], ['169.254.0.0', 16], ['100.64.0.0', 10]]; + + /** + * @return array{scheme: string, host: string, port?: int, path?: string, query?: string, fragment?: string} + * + * @throws InvalidArgumentException + */ + public static function parse(mixed $url, string $label): array + { + // parse_url() reads a host differently than browsers do around a backslash, and turns control characters into underscores. + $parts = \is_string($url) && 1 !== preg_match('/[\x00-\x20\x7f\\\\]/', $url) ? parse_url($url) : false; + + if (false === $parts || !isset($parts['scheme'], $parts['host'])) { + throw new InvalidArgumentException(\sprintf('The %s must be an absolute URL.', $label)); + } + + // Browsers and IDNA decode these into another host, e.g. "%31%32%37.1" or "127.0.0.1" into a loopback address. + if (1 === preg_match('/[%\x80-\xff]/', $parts['host'])) { + throw new InvalidArgumentException(\sprintf('The %s "%s" must write its host in ASCII without percent-encoding, an internationalized name in punycode.', $label, $url)); + } + + $scheme = strtolower($parts['scheme']); + if ('https' !== $scheme && ('http' !== $scheme || !self::isLoopbackHost($parts['host']))) { + throw new InvalidArgumentException(\sprintf('The %s "%s" must use https; plain http is only accepted for loopback hosts.', $label, $url)); + } + + if (self::hidesItsAddress($parts['host'])) { + throw new InvalidArgumentException(\sprintf('The %s "%s" must use a host name or an IP address in standard form; unspecified addresses and IPv4 within IPv6 are refused.', $label, $url)); + } + + return $parts; + } + + /** + * Whether a URL points at the machine it is requested from, on any scheme. + */ + public static function isLoopback(string $url): bool + { + $host = parse_url($url, \PHP_URL_HOST); + + return \is_string($host) && self::isLoopbackHost($host); + } + + /** + * Whether a URL names an address of a private or link-local network as an IP literal; a name is not resolved. + */ + public static function isPrivateNetwork(string $url): bool + { + $host = parse_url($url, \PHP_URL_HOST); + $host = \is_string($host) ? trim($host, '[]') : ''; + + if (false === filter_var($host, \FILTER_VALIDATE_IP)) { + return false; + } + + $address = (string) inet_pton($host); + + if (4 === \strlen($address)) { + return self::isWithin($address, self::PRIVATE_IPV4); + } + + if (self::isWithin($address, [['64:ff9b:1::', 48]])) { + return true; + } + + // NAT64 (RFC 6052) and 6to4 (RFC 3056) addresses reach the IPv4 address they carry, loopback included. + $embedded = match (true) { + self::isWithin($address, [['64:ff9b::', 96]]) => substr($address, 12), + self::isWithin($address, [['2002::', 16]]) => substr($address, 2, 4), + default => null, + }; + + if (null !== $embedded) { + return self::isWithin($embedded, [...self::PRIVATE_IPV4, ['127.0.0.0', 8], ['0.0.0.0', 8]]); + } + + return self::isWithin($address, [['fc00::', 7], ['fe80::', 10], ['fec0::', 10]]); + } + + /** + * @param list $ranges + */ + private static function isWithin(string $address, array $ranges): bool + { + foreach ($ranges as [$network, $bits]) { + $prefix = (string) inet_pton($network); + + if (\strlen($prefix) !== \strlen($address)) { + continue; + } + + $bytes = intdiv($bits, 8); + $mask = 0xFF << (8 - $bits % 8) & 0xFF; + + if (0 === substr_compare($address, $prefix, 0, $bytes) && (0 === $bits % 8 || (\ord($address[$bytes]) & $mask) === \ord($prefix[$bytes]))) { + return true; + } + } + + return false; + } + + // Each of these can reach this machine or a private network without looking like it. + private static function hidesItsAddress(string $host): bool + { + $host = self::normalizeHost($host); + + if (false !== filter_var($host, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) { + return '0.0.0.0' === $host; + } + + if (false !== filter_var($host, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) { + $bytes = (string) inet_pton($host); + + return '::1' !== $host && str_starts_with($bytes, str_repeat("\0", 10)) && \in_array(substr($bytes, 10, 2), ["\0\0", "\xff\xff"], true); + } + + return 1 === preg_match('/^(?:0x[0-9a-f]*|[0-9]+)(?:\.(?:0x[0-9a-f]*|[0-9]+)){0,3}\.?$/', $host); + } + + private static function isLoopbackHost(string $host): bool + { + $host = self::normalizeHost($host); + if ('::1' === $host) { + return true; + } + + if (false !== filter_var($host, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) { + return str_starts_with($host, '127.'); + } + + if (str_ends_with($host, '.')) { + $host = substr($host, 0, -1); + } + + return 1 === preg_match('/^(?:[a-z0-9_-]+\.)*localhost$/', $host); + } + + private static function normalizeHost(string $host): string + { + $host = strtolower(trim($host, '[]')); + + if (false !== filter_var($host, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) { + return (string) inet_ntop((string) inet_pton($host)); + } + + return $host; + } +} diff --git a/src/Schema/Tool.php b/src/Schema/Tool.php index 977988345..5cdd60bac 100644 --- a/src/Schema/Tool.php +++ b/src/Schema/Tool.php @@ -11,7 +11,7 @@ namespace Mcp\Schema; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\Wire\McpHeader; /** diff --git a/src/Schema/ToolAnnotations.php b/src/Schema/ToolAnnotations.php index c4f27746e..8943cef42 100644 --- a/src/Schema/ToolAnnotations.php +++ b/src/Schema/ToolAnnotations.php @@ -11,7 +11,7 @@ namespace Mcp\Schema; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Additional properties describing a Tool to clients. diff --git a/src/Schema/ToolChoice.php b/src/Schema/ToolChoice.php index 5c0f2bac6..978140338 100644 --- a/src/Schema/ToolChoice.php +++ b/src/Schema/ToolChoice.php @@ -11,8 +11,8 @@ namespace Mcp\Schema; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Enum\ToolChoiceMode; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Controls how the model uses tools during sampling. diff --git a/src/Schema/ToolExecution.php b/src/Schema/ToolExecution.php index 27edc8473..932704edc 100644 --- a/src/Schema/ToolExecution.php +++ b/src/Schema/ToolExecution.php @@ -11,8 +11,8 @@ namespace Mcp\Schema; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Enum\TaskSupport; +use Mcp\Schema\Exception\InvalidArgumentException; /** * Execution-related properties of a Tool. diff --git a/src/Schema/Wire/McpHeader.php b/src/Schema/Wire/McpHeader.php index 1e0f37a99..e95da645e 100644 --- a/src/Schema/Wire/McpHeader.php +++ b/src/Schema/Wire/McpHeader.php @@ -11,7 +11,7 @@ namespace Mcp\Schema\Wire; -use Mcp\JsonRpc\Json; +use Mcp\Schema\Json; /** * The HTTP header vocabulary that mirrors a request's JSON-RPC body (SEP-2243). @@ -250,6 +250,22 @@ private static function findUnreachable(array $schema, string $path, bool $reach return null; } + /** + * Case-insensitive header lookup, since PSR-7 preserves the sender's casing. + * + * @param array $headers + */ + public static function lookup(array $headers, string $name): ?string + { + foreach ($headers as $key => $value) { + if (0 === strcasecmp($key, $name)) { + return '' === $value ? null : $value; + } + } + + return null; + } + private static function wrap(string $value): string { return self::BASE64_PREFIX.base64_encode($value).self::BASE64_SUFFIX; diff --git a/src/Server/Builder.php b/src/Server/Builder.php index 701f9f03a..aa8a850da 100644 --- a/src/Server/Builder.php +++ b/src/Server/Builder.php @@ -11,32 +11,13 @@ namespace Mcp\Server; -use Mcp\Capability\Completion\ProviderInterface; -use Mcp\Capability\Discovery\CachedDiscoverer; -use Mcp\Capability\Discovery\Discoverer; -use Mcp\Capability\Discovery\DiscovererInterface; -use Mcp\Capability\Discovery\SchemaGeneratorInterface; -use Mcp\Capability\Discovery\SchemaValidator; -use Mcp\Capability\Registry; -use Mcp\Capability\Registry\Container; -use Mcp\Capability\Registry\ElementReference; -use Mcp\Capability\Registry\Loader\ChainLoader; -use Mcp\Capability\Registry\Loader\DiscoveryLoader; -use Mcp\Capability\Registry\Loader\ExplicitElementLoader; -use Mcp\Capability\Registry\Loader\LoaderInterface; -use Mcp\Capability\Registry\Loader\ReflectedElementLoader; -use Mcp\Capability\Registry\ReferenceHandler; -use Mcp\Capability\Registry\ReferenceHandlerInterface; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\LogicException; -use Mcp\JsonRpc\MessageFactory; use Mcp\Schema\Annotations; use Mcp\Schema\Enum\ProtocolVersion; use Mcp\Schema\Extension\AbstractExtension; use Mcp\Schema\Extension\ExtensionInterface; use Mcp\Schema\Icon; use Mcp\Schema\Implementation; +use Mcp\Schema\MessageFactory; use Mcp\Schema\Prompt; use Mcp\Schema\Request\DiscoverRequest; use Mcp\Schema\ResourceDefinition; @@ -44,7 +25,26 @@ use Mcp\Schema\ServerCapabilities; use Mcp\Schema\Tool; use Mcp\Schema\ToolAnnotations; -use Mcp\Server; +use Mcp\Server\Capability\Completion\ProviderInterface; +use Mcp\Server\Capability\Discovery\CachedDiscoverer; +use Mcp\Server\Capability\Discovery\Discoverer; +use Mcp\Server\Capability\Discovery\DiscovererInterface; +use Mcp\Server\Capability\Discovery\SchemaGeneratorInterface; +use Mcp\Server\Capability\Discovery\SchemaValidator; +use Mcp\Server\Capability\Registry; +use Mcp\Server\Capability\Registry\Container; +use Mcp\Server\Capability\Registry\ElementReference; +use Mcp\Server\Capability\Registry\Loader\ChainLoader; +use Mcp\Server\Capability\Registry\Loader\DiscoveryLoader; +use Mcp\Server\Capability\Registry\Loader\ExplicitElementLoader; +use Mcp\Server\Capability\Registry\Loader\LoaderInterface; +use Mcp\Server\Capability\Registry\Loader\ReflectedElementLoader; +use Mcp\Server\Capability\Registry\ReferenceHandler; +use Mcp\Server\Capability\Registry\ReferenceHandlerInterface; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\InvalidArgumentException; +use Mcp\Server\Exception\LogicException; +use Mcp\Server\Extension\ServerExtensionInterface; use Mcp\Server\Fiber\FiberContextInterface; use Mcp\Server\Fiber\FiberSchedulerInterface; use Mcp\Server\Handler\ElementHandlerInterface; @@ -487,8 +487,8 @@ public function setCapabilities(ServerCapabilities $serverCapabilities): self * `capabilities.extensions` during the initialize handshake. * * An extension also contributes the message classes its methods decode - * into and the handlers serving them, if any — see {@see AbstractExtension} - * for extensions that only announce a capability. + * into, and a {@see ServerExtensionInterface} the handlers serving them — see + * {@see AbstractExtension} for extensions that only announce a capability. * * @throws InvalidArgumentException if the identifier is not a valid `_meta` prefix * @throws LogicException if the same extension is enabled more than once, or @@ -523,8 +523,10 @@ public function enableExtension(ExtensionInterface ...$extensions): self $this->extensionMethods[$method] = $id; } - foreach ($extension->getRequestHandlers() as $handler) { - $this->requestHandlers[] = $handler; + if ($extension instanceof ServerExtensionInterface) { + foreach ($extension->getRequestHandlers() as $handler) { + $this->requestHandlers[] = $handler; + } } } @@ -886,7 +888,7 @@ public function addPrompt( * reflection of the handler. * * Mismatched pairings (e.g. a `Tool` with a `PromptHandlerInterface`) raise - * `Mcp\Exception\InvalidArgumentException`. Completion providers are only supported on + * `Mcp\Server\Exception\InvalidArgumentException`. Completion providers are only supported on * `Prompt` and `ResourceTemplate` definitions; supplying them with `Tool` or * `ResourceDefinition` raises the same exception. * diff --git a/src/Capability/Attribute/CompletionProvider.php b/src/Server/Capability/Attribute/CompletionProvider.php similarity index 89% rename from src/Capability/Attribute/CompletionProvider.php rename to src/Server/Capability/Attribute/CompletionProvider.php index a21963c95..7512ad19e 100644 --- a/src/Capability/Attribute/CompletionProvider.php +++ b/src/Server/Capability/Attribute/CompletionProvider.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Attribute; +namespace Mcp\Server\Capability\Attribute; -use Mcp\Capability\Completion\ProviderInterface; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Server\Capability\Completion\ProviderInterface; +use Mcp\Server\Exception\InvalidArgumentException; /** * @author Kyrian Obikwelu diff --git a/src/Capability/Attribute/McpPrompt.php b/src/Server/Capability/Attribute/McpPrompt.php similarity index 96% rename from src/Capability/Attribute/McpPrompt.php rename to src/Server/Capability/Attribute/McpPrompt.php index cd47fe2cc..da4c5e556 100644 --- a/src/Capability/Attribute/McpPrompt.php +++ b/src/Server/Capability/Attribute/McpPrompt.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Attribute; +namespace Mcp\Server\Capability\Attribute; use Mcp\Schema\Icon; diff --git a/src/Capability/Attribute/McpResource.php b/src/Server/Capability/Attribute/McpResource.php similarity index 97% rename from src/Capability/Attribute/McpResource.php rename to src/Server/Capability/Attribute/McpResource.php index 0f516576d..eff97ac73 100644 --- a/src/Capability/Attribute/McpResource.php +++ b/src/Server/Capability/Attribute/McpResource.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Attribute; +namespace Mcp\Server\Capability\Attribute; use Mcp\Schema\Annotations; use Mcp\Schema\Icon; diff --git a/src/Capability/Attribute/McpResourceTemplate.php b/src/Server/Capability/Attribute/McpResourceTemplate.php similarity index 97% rename from src/Capability/Attribute/McpResourceTemplate.php rename to src/Server/Capability/Attribute/McpResourceTemplate.php index 6a2044d83..f4d802e1b 100644 --- a/src/Capability/Attribute/McpResourceTemplate.php +++ b/src/Server/Capability/Attribute/McpResourceTemplate.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Attribute; +namespace Mcp\Server\Capability\Attribute; use Mcp\Schema\Annotations; diff --git a/src/Capability/Attribute/McpTool.php b/src/Server/Capability/Attribute/McpTool.php similarity index 97% rename from src/Capability/Attribute/McpTool.php rename to src/Server/Capability/Attribute/McpTool.php index 1c71e2cd3..2ac171ad4 100644 --- a/src/Capability/Attribute/McpTool.php +++ b/src/Server/Capability/Attribute/McpTool.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Attribute; +namespace Mcp\Server\Capability\Attribute; use Mcp\Schema\Icon; use Mcp\Schema\ToolAnnotations; diff --git a/src/Capability/Attribute/Schema.php b/src/Server/Capability/Attribute/Schema.php similarity index 99% rename from src/Capability/Attribute/Schema.php rename to src/Server/Capability/Attribute/Schema.php index 8a375e15c..15120a282 100644 --- a/src/Capability/Attribute/Schema.php +++ b/src/Server/Capability/Attribute/Schema.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Attribute; +namespace Mcp\Server\Capability\Attribute; /** * Defines a JSON Schema for a method's input or an individual parameter. diff --git a/src/Capability/Completion/EnumCompletionProvider.php b/src/Server/Capability/Completion/EnumCompletionProvider.php similarity index 93% rename from src/Capability/Completion/EnumCompletionProvider.php rename to src/Server/Capability/Completion/EnumCompletionProvider.php index f98161932..0fe30a72d 100644 --- a/src/Capability/Completion/EnumCompletionProvider.php +++ b/src/Server/Capability/Completion/EnumCompletionProvider.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Completion; +namespace Mcp\Server\Capability\Completion; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Server\Exception\InvalidArgumentException; /** * @author Kyrian Obikwelu diff --git a/src/Capability/Completion/ListCompletionProvider.php b/src/Server/Capability/Completion/ListCompletionProvider.php similarity index 95% rename from src/Capability/Completion/ListCompletionProvider.php rename to src/Server/Capability/Completion/ListCompletionProvider.php index ce5eff8f7..f18fa480b 100644 --- a/src/Capability/Completion/ListCompletionProvider.php +++ b/src/Server/Capability/Completion/ListCompletionProvider.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Completion; +namespace Mcp\Server\Capability\Completion; /** * @author Kyrian Obikwelu diff --git a/src/Capability/Completion/ProviderInterface.php b/src/Server/Capability/Completion/ProviderInterface.php similarity index 93% rename from src/Capability/Completion/ProviderInterface.php rename to src/Server/Capability/Completion/ProviderInterface.php index 84f3f2344..792933b1d 100644 --- a/src/Capability/Completion/ProviderInterface.php +++ b/src/Server/Capability/Completion/ProviderInterface.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Completion; +namespace Mcp\Server\Capability\Completion; /** * @author Kyrian Obikwelu diff --git a/src/Capability/Discovery/CachedDiscoverer.php b/src/Server/Capability/Discovery/CachedDiscoverer.php similarity index 94% rename from src/Capability/Discovery/CachedDiscoverer.php rename to src/Server/Capability/Discovery/CachedDiscoverer.php index c9ff1e121..404521152 100644 --- a/src/Capability/Discovery/CachedDiscoverer.php +++ b/src/Server/Capability/Discovery/CachedDiscoverer.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Discovery; +namespace Mcp\Server\Capability\Discovery; use Psr\Cache\CacheItemPoolInterface; use Psr\Log\LoggerInterface; @@ -27,7 +27,8 @@ */ final class CachedDiscoverer implements DiscovererInterface { - private const CACHE_PREFIX = 'mcp_discovery_'; + // Versioned, since an entry holds serialized SDK classes that a release can rename. + private const CACHE_PREFIX = 'mcp_discovery_v2_'; private const GENERATION_KEY = self::CACHE_PREFIX.'generation'; public function __construct( @@ -51,7 +52,7 @@ public function discover(string $basePath, array $directories, array $excludeDir $cachedResult = $this->read($cacheKey); - if (null !== $cachedResult) { + if ($cachedResult instanceof DiscoveryState) { $this->logger->debug('Using cached discovery results', [ 'cache_key' => $cacheKey, 'base_path' => $basePath, diff --git a/src/Capability/Discovery/Discoverer.php b/src/Server/Capability/Discovery/Discoverer.php similarity index 95% rename from src/Capability/Discovery/Discoverer.php rename to src/Server/Capability/Discovery/Discoverer.php index c9080bfec..5e9955ced 100644 --- a/src/Capability/Discovery/Discoverer.php +++ b/src/Server/Capability/Discovery/Discoverer.php @@ -9,27 +9,27 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Discovery; - -use Mcp\Capability\Attribute\CompletionProvider; -use Mcp\Capability\Attribute\McpPrompt; -use Mcp\Capability\Attribute\McpResource; -use Mcp\Capability\Attribute\McpResourceTemplate; -use Mcp\Capability\Attribute\McpTool; -use Mcp\Capability\Completion\EnumCompletionProvider; -use Mcp\Capability\Completion\ListCompletionProvider; -use Mcp\Capability\Completion\ProviderInterface; -use Mcp\Capability\Registry\PromptReference; -use Mcp\Capability\Registry\ResourceReference; -use Mcp\Capability\Registry\ResourceTemplateReference; -use Mcp\Capability\Registry\ToolReference; -use Mcp\Exception\ExceptionInterface; -use Mcp\Exception\RuntimeException; +namespace Mcp\Server\Capability\Discovery; + +use Mcp\Schema\Exception\ExceptionInterface; use Mcp\Schema\Prompt; use Mcp\Schema\PromptArgument; use Mcp\Schema\ResourceDefinition; use Mcp\Schema\ResourceTemplate; use Mcp\Schema\Tool; +use Mcp\Server\Capability\Attribute\CompletionProvider; +use Mcp\Server\Capability\Attribute\McpPrompt; +use Mcp\Server\Capability\Attribute\McpResource; +use Mcp\Server\Capability\Attribute\McpResourceTemplate; +use Mcp\Server\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Completion\EnumCompletionProvider; +use Mcp\Server\Capability\Completion\ListCompletionProvider; +use Mcp\Server\Capability\Completion\ProviderInterface; +use Mcp\Server\Capability\Registry\PromptReference; +use Mcp\Server\Capability\Registry\ResourceReference; +use Mcp\Server\Capability\Registry\ResourceTemplateReference; +use Mcp\Server\Capability\Registry\ToolReference; +use Mcp\Server\Exception\RuntimeException; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; use Symfony\Component\Finder\Finder; @@ -287,6 +287,8 @@ private function processMethod(\ReflectionMethod $method, array &$discoveredCoun ++$discoveredCount['resourceTemplates']; } } catch (ExceptionInterface $e) { + // Schema's root, not the Server one: the value objects built above + // validate their own input and throw from the Schema package. $this->logger->error("Failed to process MCP attribute on {$className}::{$methodName}", [ 'attribute' => $attributeClassName, 'exception' => $e, diff --git a/src/Capability/Discovery/DiscovererInterface.php b/src/Server/Capability/Discovery/DiscovererInterface.php similarity index 96% rename from src/Capability/Discovery/DiscovererInterface.php rename to src/Server/Capability/Discovery/DiscovererInterface.php index 2df69f35a..8bf12ecb3 100644 --- a/src/Capability/Discovery/DiscovererInterface.php +++ b/src/Server/Capability/Discovery/DiscovererInterface.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Discovery; +namespace Mcp\Server\Capability\Discovery; /** * Discovers MCP elements (tools, resources, prompts, resource templates) in directories. diff --git a/src/Capability/Discovery/DiscoveryState.php b/src/Server/Capability/Discovery/DiscoveryState.php similarity index 92% rename from src/Capability/Discovery/DiscoveryState.php rename to src/Server/Capability/Discovery/DiscoveryState.php index 59a73ec8e..5f4f78eae 100644 --- a/src/Capability/Discovery/DiscoveryState.php +++ b/src/Server/Capability/Discovery/DiscoveryState.php @@ -9,12 +9,12 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Discovery; +namespace Mcp\Server\Capability\Discovery; -use Mcp\Capability\Registry\PromptReference; -use Mcp\Capability\Registry\ResourceReference; -use Mcp\Capability\Registry\ResourceTemplateReference; -use Mcp\Capability\Registry\ToolReference; +use Mcp\Server\Capability\Registry\PromptReference; +use Mcp\Server\Capability\Registry\ResourceReference; +use Mcp\Server\Capability\Registry\ResourceTemplateReference; +use Mcp\Server\Capability\Registry\ToolReference; /** * Represents the state of discovered MCP capabilities. diff --git a/src/Capability/Discovery/DocBlockParser.php b/src/Server/Capability/Discovery/DocBlockParser.php similarity index 98% rename from src/Capability/Discovery/DocBlockParser.php rename to src/Server/Capability/Discovery/DocBlockParser.php index cee952b52..2a9c643a1 100644 --- a/src/Capability/Discovery/DocBlockParser.php +++ b/src/Server/Capability/Discovery/DocBlockParser.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Discovery; +namespace Mcp\Server\Capability\Discovery; use phpDocumentor\Reflection\DocBlock; use phpDocumentor\Reflection\DocBlock\Tags\Param; diff --git a/src/Capability/Discovery/ElementMetadataResolver.php b/src/Server/Capability/Discovery/ElementMetadataResolver.php similarity index 96% rename from src/Capability/Discovery/ElementMetadataResolver.php rename to src/Server/Capability/Discovery/ElementMetadataResolver.php index eaa1d8c6d..af6aa8f63 100644 --- a/src/Capability/Discovery/ElementMetadataResolver.php +++ b/src/Server/Capability/Discovery/ElementMetadataResolver.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Discovery; +namespace Mcp\Server\Capability\Discovery; /** * Derives an element's name and description from its handler method, used by diff --git a/src/Capability/Discovery/HandlerResolver.php b/src/Server/Capability/Discovery/HandlerResolver.php similarity index 96% rename from src/Capability/Discovery/HandlerResolver.php rename to src/Server/Capability/Discovery/HandlerResolver.php index 8cadcd3c1..b145480b7 100644 --- a/src/Capability/Discovery/HandlerResolver.php +++ b/src/Server/Capability/Discovery/HandlerResolver.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Discovery; +namespace Mcp\Server\Capability\Discovery; -use Mcp\Capability\Registry\ElementReference; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Server\Capability\Registry\ElementReference; +use Mcp\Server\Exception\InvalidArgumentException; /** * Utility class to validate and resolve MCP element handlers. diff --git a/src/Capability/Discovery/SchemaGenerator.php b/src/Server/Capability/Discovery/SchemaGenerator.php similarity index 99% rename from src/Capability/Discovery/SchemaGenerator.php rename to src/Server/Capability/Discovery/SchemaGenerator.php index 14231f53b..4b26e7a1d 100644 --- a/src/Capability/Discovery/SchemaGenerator.php +++ b/src/Server/Capability/Discovery/SchemaGenerator.php @@ -9,13 +9,13 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Discovery; +namespace Mcp\Server\Capability\Discovery; -use Mcp\Capability\Attribute\McpTool; -use Mcp\Capability\Attribute\Schema; -use Mcp\Capability\Registry\InjectableParameters; -use Mcp\Exception\BadMethodCallException; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Server\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\Schema; +use Mcp\Server\Capability\Registry\InjectableParameters; +use Mcp\Server\Exception\BadMethodCallException; +use Mcp\Server\Exception\InvalidArgumentException; use phpDocumentor\Reflection\DocBlock\Tags\Param; /** diff --git a/src/Capability/Discovery/SchemaGeneratorInterface.php b/src/Server/Capability/Discovery/SchemaGeneratorInterface.php similarity index 95% rename from src/Capability/Discovery/SchemaGeneratorInterface.php rename to src/Server/Capability/Discovery/SchemaGeneratorInterface.php index 4ee27f86f..4f8bc3760 100644 --- a/src/Capability/Discovery/SchemaGeneratorInterface.php +++ b/src/Server/Capability/Discovery/SchemaGeneratorInterface.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Discovery; +namespace Mcp\Server\Capability\Discovery; use Mcp\Schema\Tool; diff --git a/src/Capability/Discovery/SchemaValidator.php b/src/Server/Capability/Discovery/SchemaValidator.php similarity index 99% rename from src/Capability/Discovery/SchemaValidator.php rename to src/Server/Capability/Discovery/SchemaValidator.php index 5be96bd75..9350fc838 100644 --- a/src/Capability/Discovery/SchemaValidator.php +++ b/src/Server/Capability/Discovery/SchemaValidator.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Discovery; +namespace Mcp\Server\Capability\Discovery; use Opis\JsonSchema\Errors\ValidationError; use Opis\JsonSchema\Validator; diff --git a/src/Capability/Formatter/PromptResultFormatter.php b/src/Server/Capability/Formatter/PromptResultFormatter.php similarity index 96% rename from src/Capability/Formatter/PromptResultFormatter.php rename to src/Server/Capability/Formatter/PromptResultFormatter.php index 76bd5328c..261df0b5f 100644 --- a/src/Capability/Formatter/PromptResultFormatter.php +++ b/src/Server/Capability/Formatter/PromptResultFormatter.php @@ -9,10 +9,8 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Formatter; +namespace Mcp\Server\Capability\Formatter; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\RuntimeException; use Mcp\Schema\Content\AudioContent; use Mcp\Schema\Content\Content; use Mcp\Schema\Content\EmbeddedResource; @@ -21,6 +19,8 @@ use Mcp\Schema\Content\ResourceLink; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Enum\Role; +use Mcp\Schema\Exception\InvalidArgumentException; +use Mcp\Server\Exception\RuntimeException; /** * @author Kyrian Obikwelu @@ -35,8 +35,8 @@ final class PromptResultFormatter * * @return PromptMessage[] array of PromptMessage objects * - * @throws \RuntimeException if the result cannot be formatted - * @throws \JsonException if JSON encoding fails + * @throws RuntimeException if the result cannot be formatted + * @throws \JsonException if JSON encoding fails */ public function format(mixed $promptGenerationResult): array { @@ -70,7 +70,7 @@ public function format(mixed $promptGenerationResult): array if ($hasPromptMessages) { $result = []; - foreach ($promptGenerationResult as $index => $item) { + foreach ($promptGenerationResult as $item) { if ($item instanceof PromptMessage) { $result[] = $item; } else { diff --git a/src/Capability/Formatter/ResourceResultFormatter.php b/src/Server/Capability/Formatter/ResourceResultFormatter.php similarity index 98% rename from src/Capability/Formatter/ResourceResultFormatter.php rename to src/Server/Capability/Formatter/ResourceResultFormatter.php index 21bc4e84e..79b2e6ccd 100644 --- a/src/Capability/Formatter/ResourceResultFormatter.php +++ b/src/Server/Capability/Formatter/ResourceResultFormatter.php @@ -9,13 +9,13 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Formatter; +namespace Mcp\Server\Capability\Formatter; -use Mcp\Exception\RuntimeException; use Mcp\Schema\Content\BlobResourceContents; use Mcp\Schema\Content\EmbeddedResource; use Mcp\Schema\Content\ResourceContents; use Mcp\Schema\Content\TextResourceContents; +use Mcp\Server\Exception\RuntimeException; /** * Formats the raw result of a resource read operation into MCP ResourceContent items. diff --git a/src/Capability/Formatter/ToolResultFormatter.php b/src/Server/Capability/Formatter/ToolResultFormatter.php similarity index 98% rename from src/Capability/Formatter/ToolResultFormatter.php rename to src/Server/Capability/Formatter/ToolResultFormatter.php index e8aa92773..5e27e4d96 100644 --- a/src/Capability/Formatter/ToolResultFormatter.php +++ b/src/Server/Capability/Formatter/ToolResultFormatter.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Formatter; +namespace Mcp\Server\Capability\Formatter; use Mcp\Schema\Content\Content; use Mcp\Schema\Content\TextContent; diff --git a/src/Capability/Logger/ClientLogger.php b/src/Server/Capability/Logger/ClientLogger.php similarity index 98% rename from src/Capability/Logger/ClientLogger.php rename to src/Server/Capability/Logger/ClientLogger.php index 2cd6b9894..94ca154aa 100644 --- a/src/Capability/Logger/ClientLogger.php +++ b/src/Server/Capability/Logger/ClientLogger.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Logger; +namespace Mcp\Server\Capability\Logger; use Mcp\Schema\Enum\LoggingLevel; use Mcp\Server\ClientGateway; diff --git a/src/Capability/Registry.php b/src/Server/Capability/Registry.php similarity index 94% rename from src/Capability/Registry.php rename to src/Server/Capability/Registry.php index 620f7863d..f518d29bb 100644 --- a/src/Capability/Registry.php +++ b/src/Server/Capability/Registry.php @@ -9,27 +9,27 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability; - -use Mcp\Capability\Registry\Loader\LoaderInterface; -use Mcp\Capability\Registry\PromptReference; -use Mcp\Capability\Registry\ResourceReference; -use Mcp\Capability\Registry\ResourceTemplateReference; -use Mcp\Capability\Registry\ToolReference; -use Mcp\Capability\Tool\NameValidator; -use Mcp\Event\PromptListChangedEvent; -use Mcp\Event\ResourceListChangedEvent; -use Mcp\Event\ResourceTemplateListChangedEvent; -use Mcp\Event\ToolListChangedEvent; -use Mcp\Exception\InvalidCursorException; -use Mcp\Exception\PromptNotFoundException; -use Mcp\Exception\ResourceNotFoundException; -use Mcp\Exception\ToolNotFoundException; +namespace Mcp\Server\Capability; + use Mcp\Schema\Page; use Mcp\Schema\Prompt; use Mcp\Schema\ResourceDefinition; use Mcp\Schema\ResourceTemplate; use Mcp\Schema\Tool; +use Mcp\Server\Capability\Registry\Loader\LoaderInterface; +use Mcp\Server\Capability\Registry\PromptReference; +use Mcp\Server\Capability\Registry\ResourceReference; +use Mcp\Server\Capability\Registry\ResourceTemplateReference; +use Mcp\Server\Capability\Registry\ToolReference; +use Mcp\Server\Capability\Tool\NameValidator; +use Mcp\Server\Event\PromptListChangedEvent; +use Mcp\Server\Event\ResourceListChangedEvent; +use Mcp\Server\Event\ResourceTemplateListChangedEvent; +use Mcp\Server\Event\ToolListChangedEvent; +use Mcp\Server\Exception\InvalidCursorException; +use Mcp\Server\Exception\PromptNotFoundException; +use Mcp\Server\Exception\ResourceNotFoundException; +use Mcp\Server\Exception\ToolNotFoundException; use Mcp\Server\Subscription\PublishingEventDispatcher; use Psr\EventDispatcher\EventDispatcherInterface; use Psr\Log\LoggerInterface; diff --git a/src/Capability/Registry/Container.php b/src/Server/Capability/Registry/Container.php similarity index 98% rename from src/Capability/Registry/Container.php rename to src/Server/Capability/Registry/Container.php index 92c4a908e..32f4392d6 100644 --- a/src/Capability/Registry/Container.php +++ b/src/Server/Capability/Registry/Container.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Registry; +namespace Mcp\Server\Capability\Registry; -use Mcp\Exception\ContainerException; -use Mcp\Exception\ServiceNotFoundException; +use Mcp\Server\Exception\ContainerException; +use Mcp\Server\Exception\ServiceNotFoundException; use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; use Psr\Container\NotFoundExceptionInterface; diff --git a/src/Capability/Registry/ElementReference.php b/src/Server/Capability/Registry/ElementReference.php similarity index 93% rename from src/Capability/Registry/ElementReference.php rename to src/Server/Capability/Registry/ElementReference.php index a49b2eb3d..38d92d635 100644 --- a/src/Capability/Registry/ElementReference.php +++ b/src/Server/Capability/Registry/ElementReference.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Registry; +namespace Mcp\Server\Capability\Registry; /** * @phpstan-type Handler \Closure|array{0: object|string, 1: string}|string diff --git a/src/Capability/Registry/InjectableParameters.php b/src/Server/Capability/Registry/InjectableParameters.php similarity index 97% rename from src/Capability/Registry/InjectableParameters.php rename to src/Server/Capability/Registry/InjectableParameters.php index b2fd19f3b..84eee18f3 100644 --- a/src/Capability/Registry/InjectableParameters.php +++ b/src/Server/Capability/Registry/InjectableParameters.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Registry; +namespace Mcp\Server\Capability\Registry; use Mcp\Server\ClientGateway; use Mcp\Server\RequestContext; diff --git a/src/Capability/Registry/Loader/ChainLoader.php b/src/Server/Capability/Registry/Loader/ChainLoader.php similarity index 90% rename from src/Capability/Registry/Loader/ChainLoader.php rename to src/Server/Capability/Registry/Loader/ChainLoader.php index 6c30a1606..cb37a4869 100644 --- a/src/Capability/Registry/Loader/ChainLoader.php +++ b/src/Server/Capability/Registry/Loader/ChainLoader.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Registry\Loader; +namespace Mcp\Server\Capability\Registry\Loader; -use Mcp\Capability\RegistryInterface; +use Mcp\Server\Capability\RegistryInterface; /** * Composes multiple loaders into a single one. Child loaders run in the order they were given; diff --git a/src/Capability/Registry/Loader/DiscoveryLoader.php b/src/Server/Capability/Registry/Loader/DiscoveryLoader.php similarity index 96% rename from src/Capability/Registry/Loader/DiscoveryLoader.php rename to src/Server/Capability/Registry/Loader/DiscoveryLoader.php index d2b953845..bec367204 100644 --- a/src/Capability/Registry/Loader/DiscoveryLoader.php +++ b/src/Server/Capability/Registry/Loader/DiscoveryLoader.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Registry\Loader; +namespace Mcp\Server\Capability\Registry\Loader; -use Mcp\Capability\Discovery\DiscovererInterface; -use Mcp\Capability\Discovery\DiscoveryState; -use Mcp\Capability\RegistryInterface; +use Mcp\Server\Capability\Discovery\DiscovererInterface; +use Mcp\Server\Capability\Discovery\DiscoveryState; +use Mcp\Server\Capability\RegistryInterface; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; diff --git a/src/Capability/Registry/Loader/ExplicitElementLoader.php b/src/Server/Capability/Registry/Loader/ExplicitElementLoader.php similarity index 95% rename from src/Capability/Registry/Loader/ExplicitElementLoader.php rename to src/Server/Capability/Registry/Loader/ExplicitElementLoader.php index ce7b66b15..82299024b 100644 --- a/src/Capability/Registry/Loader/ExplicitElementLoader.php +++ b/src/Server/Capability/Registry/Loader/ExplicitElementLoader.php @@ -9,15 +9,15 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Registry\Loader; +namespace Mcp\Server\Capability\Registry\Loader; -use Mcp\Capability\Completion\ProviderInterface; -use Mcp\Capability\Registry\ReferenceHandler; -use Mcp\Capability\RegistryInterface; use Mcp\Schema\Prompt; use Mcp\Schema\ResourceDefinition; use Mcp\Schema\ResourceTemplate; use Mcp\Schema\Tool; +use Mcp\Server\Capability\Completion\ProviderInterface; +use Mcp\Server\Capability\Registry\ReferenceHandler; +use Mcp\Server\Capability\RegistryInterface; use Mcp\Server\ClientGateway; use Mcp\Server\Handler\PromptHandlerInterface; use Mcp\Server\Handler\ResourceHandlerInterface; diff --git a/src/Capability/Registry/Loader/LoaderInterface.php b/src/Server/Capability/Registry/Loader/LoaderInterface.php similarity index 81% rename from src/Capability/Registry/Loader/LoaderInterface.php rename to src/Server/Capability/Registry/Loader/LoaderInterface.php index a7ad87ce4..aa24dcc77 100644 --- a/src/Capability/Registry/Loader/LoaderInterface.php +++ b/src/Server/Capability/Registry/Loader/LoaderInterface.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Registry\Loader; +namespace Mcp\Server\Capability\Registry\Loader; -use Mcp\Capability\RegistryInterface; +use Mcp\Server\Capability\RegistryInterface; /** * @author Antoine Bluchet diff --git a/src/Capability/Registry/Loader/ReflectedElementLoader.php b/src/Server/Capability/Registry/Loader/ReflectedElementLoader.php similarity index 94% rename from src/Capability/Registry/Loader/ReflectedElementLoader.php rename to src/Server/Capability/Registry/Loader/ReflectedElementLoader.php index 618e9a718..60fff503e 100644 --- a/src/Capability/Registry/Loader/ReflectedElementLoader.php +++ b/src/Server/Capability/Registry/Loader/ReflectedElementLoader.php @@ -9,20 +9,8 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Registry\Loader; - -use Mcp\Capability\Attribute\CompletionProvider; -use Mcp\Capability\Completion\EnumCompletionProvider; -use Mcp\Capability\Completion\ListCompletionProvider; -use Mcp\Capability\Completion\ProviderInterface; -use Mcp\Capability\Discovery\DocBlockParser; -use Mcp\Capability\Discovery\ElementMetadataResolver; -use Mcp\Capability\Discovery\HandlerResolver; -use Mcp\Capability\Discovery\SchemaGenerator; -use Mcp\Capability\Discovery\SchemaGeneratorInterface; -use Mcp\Capability\Registry\ElementReference; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\ConfigurationException; +namespace Mcp\Server\Capability\Registry\Loader; + use Mcp\Schema\Annotations; use Mcp\Schema\Icon; use Mcp\Schema\Prompt; @@ -31,6 +19,18 @@ use Mcp\Schema\ResourceTemplate; use Mcp\Schema\Tool; use Mcp\Schema\ToolAnnotations; +use Mcp\Server\Capability\Attribute\CompletionProvider; +use Mcp\Server\Capability\Completion\EnumCompletionProvider; +use Mcp\Server\Capability\Completion\ListCompletionProvider; +use Mcp\Server\Capability\Completion\ProviderInterface; +use Mcp\Server\Capability\Discovery\DocBlockParser; +use Mcp\Server\Capability\Discovery\ElementMetadataResolver; +use Mcp\Server\Capability\Discovery\HandlerResolver; +use Mcp\Server\Capability\Discovery\SchemaGenerator; +use Mcp\Server\Capability\Discovery\SchemaGeneratorInterface; +use Mcp\Server\Capability\Registry\ElementReference; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\ConfigurationException; use Mcp\Server\Handler; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; diff --git a/src/Capability/Registry/PromptReference.php b/src/Server/Capability/Registry/PromptReference.php similarity index 93% rename from src/Capability/Registry/PromptReference.php rename to src/Server/Capability/Registry/PromptReference.php index ec7d0219c..ab1f4c192 100644 --- a/src/Capability/Registry/PromptReference.php +++ b/src/Server/Capability/Registry/PromptReference.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Registry; +namespace Mcp\Server\Capability\Registry; -use Mcp\Capability\Formatter\PromptResultFormatter; use Mcp\Schema\Content\PromptMessage; use Mcp\Schema\Prompt; +use Mcp\Server\Capability\Formatter\PromptResultFormatter; /** * @phpstan-import-type Handler from ElementReference diff --git a/src/Capability/Registry/ReferenceHandler.php b/src/Server/Capability/Registry/ReferenceHandler.php similarity index 98% rename from src/Capability/Registry/ReferenceHandler.php rename to src/Server/Capability/Registry/ReferenceHandler.php index 0befe0910..a3121bf8b 100644 --- a/src/Capability/Registry/ReferenceHandler.php +++ b/src/Server/Capability/Registry/ReferenceHandler.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Registry; +namespace Mcp\Server\Capability\Registry; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\RegistryException; -use Mcp\JsonRpc\Json; +use Mcp\Schema\Json; +use Mcp\Server\Exception\InvalidArgumentException; +use Mcp\Server\Exception\RegistryException; use Mcp\Server\Session\SessionInterface; use Psr\Container\ContainerInterface; diff --git a/src/Capability/Registry/ReferenceHandlerInterface.php b/src/Server/Capability/Registry/ReferenceHandlerInterface.php similarity index 87% rename from src/Capability/Registry/ReferenceHandlerInterface.php rename to src/Server/Capability/Registry/ReferenceHandlerInterface.php index c4e52f104..b6dc40577 100644 --- a/src/Capability/Registry/ReferenceHandlerInterface.php +++ b/src/Server/Capability/Registry/ReferenceHandlerInterface.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Registry; +namespace Mcp\Server\Capability\Registry; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\RegistryException; +use Mcp\Server\Exception\InvalidArgumentException; +use Mcp\Server\Exception\RegistryException; /** * Interface for handling execution of MCP elements. diff --git a/src/Capability/Registry/ResourceReference.php b/src/Server/Capability/Registry/ResourceReference.php similarity index 95% rename from src/Capability/Registry/ResourceReference.php rename to src/Server/Capability/Registry/ResourceReference.php index 10d783776..8a50ab339 100644 --- a/src/Capability/Registry/ResourceReference.php +++ b/src/Server/Capability/Registry/ResourceReference.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Registry; +namespace Mcp\Server\Capability\Registry; -use Mcp\Capability\Formatter\ResourceResultFormatter; use Mcp\Schema\Content\ResourceContents; use Mcp\Schema\ResourceDefinition; +use Mcp\Server\Capability\Formatter\ResourceResultFormatter; /** * @phpstan-import-type Handler from ElementReference diff --git a/src/Capability/Registry/ResourceTemplateReference.php b/src/Server/Capability/Registry/ResourceTemplateReference.php similarity index 96% rename from src/Capability/Registry/ResourceTemplateReference.php rename to src/Server/Capability/Registry/ResourceTemplateReference.php index 925550f58..25df99142 100644 --- a/src/Capability/Registry/ResourceTemplateReference.php +++ b/src/Server/Capability/Registry/ResourceTemplateReference.php @@ -9,12 +9,12 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Registry; +namespace Mcp\Server\Capability\Registry; -use Mcp\Capability\Formatter\ResourceResultFormatter; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Content\ResourceContents; use Mcp\Schema\ResourceTemplate; +use Mcp\Server\Capability\Formatter\ResourceResultFormatter; +use Mcp\Server\Exception\InvalidArgumentException; /** * @phpstan-import-type Handler from ElementReference diff --git a/src/Capability/Registry/ToolReference.php b/src/Server/Capability/Registry/ToolReference.php similarity index 98% rename from src/Capability/Registry/ToolReference.php rename to src/Server/Capability/Registry/ToolReference.php index 5f35e08a2..71052f9fa 100644 --- a/src/Capability/Registry/ToolReference.php +++ b/src/Server/Capability/Registry/ToolReference.php @@ -9,13 +9,13 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Registry; +namespace Mcp\Server\Capability\Registry; -use Mcp\Capability\Formatter\ToolResultFormatter; use Mcp\Schema\Content\Content; use Mcp\Schema\Enum\ProtocolVersion; use Mcp\Schema\Enum\StructuredContent; use Mcp\Schema\Tool; +use Mcp\Server\Capability\Formatter\ToolResultFormatter; /** * @phpstan-import-type Handler from ElementReference diff --git a/src/Capability/RegistryInterface.php b/src/Server/Capability/RegistryInterface.php similarity index 91% rename from src/Capability/RegistryInterface.php rename to src/Server/Capability/RegistryInterface.php index e7c110bef..af34b4315 100644 --- a/src/Capability/RegistryInterface.php +++ b/src/Server/Capability/RegistryInterface.php @@ -9,22 +9,22 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability; - -use Mcp\Capability\Registry\ElementReference; -use Mcp\Capability\Registry\PromptReference; -use Mcp\Capability\Registry\ResourceReference; -use Mcp\Capability\Registry\ResourceTemplateReference; -use Mcp\Capability\Registry\ToolReference; -use Mcp\Exception\ConfigurationException; -use Mcp\Exception\PromptNotFoundException; -use Mcp\Exception\ResourceNotFoundException; -use Mcp\Exception\ToolNotFoundException; +namespace Mcp\Server\Capability; + use Mcp\Schema\Page; use Mcp\Schema\Prompt; use Mcp\Schema\ResourceDefinition; use Mcp\Schema\ResourceTemplate; use Mcp\Schema\Tool; +use Mcp\Server\Capability\Registry\ElementReference; +use Mcp\Server\Capability\Registry\PromptReference; +use Mcp\Server\Capability\Registry\ResourceReference; +use Mcp\Server\Capability\Registry\ResourceTemplateReference; +use Mcp\Server\Capability\Registry\ToolReference; +use Mcp\Server\Exception\ConfigurationException; +use Mcp\Server\Exception\PromptNotFoundException; +use Mcp\Server\Exception\ResourceNotFoundException; +use Mcp\Server\Exception\ToolNotFoundException; use Mcp\Server\Subscription\PublishingEventDispatcher; /** diff --git a/src/Capability/Tool/NameValidator.php b/src/Server/Capability/Tool/NameValidator.php similarity index 91% rename from src/Capability/Tool/NameValidator.php rename to src/Server/Capability/Tool/NameValidator.php index 231675fd3..dfaec1bf1 100644 --- a/src/Capability/Tool/NameValidator.php +++ b/src/Server/Capability/Tool/NameValidator.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Capability\Tool; +namespace Mcp\Server\Capability\Tool; final class NameValidator { diff --git a/src/Server/ClientGateway.php b/src/Server/ClientGateway.php index 5a19dd3c8..86bcb1d84 100644 --- a/src/Server/ClientGateway.php +++ b/src/Server/ClientGateway.php @@ -11,10 +11,6 @@ namespace Mcp\Server; -use Mcp\Exception\ClientException; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\RuntimeException; -use Mcp\Exception\SessionRequiredException; use Mcp\Schema\Content\AudioContent; use Mcp\Schema\Content\Content; use Mcp\Schema\Content\ImageContent; @@ -40,6 +36,10 @@ use Mcp\Schema\Result\ListRootsResult; use Mcp\Schema\Tool; use Mcp\Schema\ToolChoice; +use Mcp\Server\Exception\ClientException; +use Mcp\Server\Exception\InvalidArgumentException; +use Mcp\Server\Exception\RuntimeException; +use Mcp\Server\Exception\SessionRequiredException; use Mcp\Server\Fiber\HandlerFibers; use Mcp\Server\Session\EphemeralSessionInterface; use Mcp\Server\Session\SessionInterface; diff --git a/src/Event/ClientResponseEvent.php b/src/Server/Event/ClientResponseEvent.php similarity index 97% rename from src/Event/ClientResponseEvent.php rename to src/Server/Event/ClientResponseEvent.php index 54d586c70..90e805a17 100644 --- a/src/Event/ClientResponseEvent.php +++ b/src/Server/Event/ClientResponseEvent.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Event; +namespace Mcp\Server\Event; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Response; diff --git a/src/Event/ErrorEvent.php b/src/Server/Event/ErrorEvent.php similarity index 97% rename from src/Event/ErrorEvent.php rename to src/Server/Event/ErrorEvent.php index 65ce650d6..8521e9fd1 100644 --- a/src/Event/ErrorEvent.php +++ b/src/Server/Event/ErrorEvent.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Event; +namespace Mcp\Server\Event; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Request; diff --git a/src/Event/NotificationEvent.php b/src/Server/Event/NotificationEvent.php similarity index 97% rename from src/Event/NotificationEvent.php rename to src/Server/Event/NotificationEvent.php index 579d877da..b021ae315 100644 --- a/src/Event/NotificationEvent.php +++ b/src/Server/Event/NotificationEvent.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Event; +namespace Mcp\Server\Event; use Mcp\Schema\JsonRpc\Notification; use Mcp\Server\Session\SessionInterface; diff --git a/src/Event/PromptListChangedEvent.php b/src/Server/Event/PromptListChangedEvent.php similarity index 92% rename from src/Event/PromptListChangedEvent.php rename to src/Server/Event/PromptListChangedEvent.php index 2e8691816..3da1352b6 100644 --- a/src/Event/PromptListChangedEvent.php +++ b/src/Server/Event/PromptListChangedEvent.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Event; +namespace Mcp\Server\Event; /** * @author Christopher Hertel diff --git a/src/Event/RequestEvent.php b/src/Server/Event/RequestEvent.php similarity index 97% rename from src/Event/RequestEvent.php rename to src/Server/Event/RequestEvent.php index 3a7de08ee..465a1ac92 100644 --- a/src/Event/RequestEvent.php +++ b/src/Server/Event/RequestEvent.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Event; +namespace Mcp\Server\Event; use Mcp\Schema\JsonRpc\Request; use Mcp\Server\Session\SessionInterface; diff --git a/src/Event/ResourceListChangedEvent.php b/src/Server/Event/ResourceListChangedEvent.php similarity index 92% rename from src/Event/ResourceListChangedEvent.php rename to src/Server/Event/ResourceListChangedEvent.php index 83120d68f..3a4bdb10e 100644 --- a/src/Event/ResourceListChangedEvent.php +++ b/src/Server/Event/ResourceListChangedEvent.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Event; +namespace Mcp\Server\Event; /** * @author Christopher Hertel diff --git a/src/Event/ResourceTemplateListChangedEvent.php b/src/Server/Event/ResourceTemplateListChangedEvent.php similarity index 93% rename from src/Event/ResourceTemplateListChangedEvent.php rename to src/Server/Event/ResourceTemplateListChangedEvent.php index 0c13f654d..f888a9d0a 100644 --- a/src/Event/ResourceTemplateListChangedEvent.php +++ b/src/Server/Event/ResourceTemplateListChangedEvent.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Event; +namespace Mcp\Server\Event; /** * @author Christopher Hertel diff --git a/src/Event/ResponseEvent.php b/src/Server/Event/ResponseEvent.php similarity index 98% rename from src/Event/ResponseEvent.php rename to src/Server/Event/ResponseEvent.php index 94b9a907d..9eec7c008 100644 --- a/src/Event/ResponseEvent.php +++ b/src/Server/Event/ResponseEvent.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Event; +namespace Mcp\Server\Event; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; diff --git a/src/Event/ServerRequestEvent.php b/src/Server/Event/ServerRequestEvent.php similarity index 97% rename from src/Event/ServerRequestEvent.php rename to src/Server/Event/ServerRequestEvent.php index 5bbcc86bd..d0d65a14b 100644 --- a/src/Event/ServerRequestEvent.php +++ b/src/Server/Event/ServerRequestEvent.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Event; +namespace Mcp\Server\Event; use Mcp\Schema\JsonRpc\Request; use Mcp\Server\Session\SessionInterface; diff --git a/src/Event/ToolListChangedEvent.php b/src/Server/Event/ToolListChangedEvent.php similarity index 92% rename from src/Event/ToolListChangedEvent.php rename to src/Server/Event/ToolListChangedEvent.php index 84d175a25..672eba026 100644 --- a/src/Event/ToolListChangedEvent.php +++ b/src/Server/Event/ToolListChangedEvent.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Event; +namespace Mcp\Server\Event; /** * @author Christopher Hertel diff --git a/src/Exception/BadMethodCallException.php b/src/Server/Exception/BadMethodCallException.php similarity index 92% rename from src/Exception/BadMethodCallException.php rename to src/Server/Exception/BadMethodCallException.php index d7c00c149..641b36819 100644 --- a/src/Exception/BadMethodCallException.php +++ b/src/Server/Exception/BadMethodCallException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; /** * @author Antoine Bluchet diff --git a/src/Exception/ClientException.php b/src/Server/Exception/ClientException.php similarity index 95% rename from src/Exception/ClientException.php rename to src/Server/Exception/ClientException.php index 33e36680c..9dd00e5a7 100644 --- a/src/Exception/ClientException.php +++ b/src/Server/Exception/ClientException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; use Mcp\Schema\JsonRpc\Error; diff --git a/src/Exception/ConfigurationException.php b/src/Server/Exception/ConfigurationException.php similarity index 92% rename from src/Exception/ConfigurationException.php rename to src/Server/Exception/ConfigurationException.php index b53333e01..ac530b0cf 100644 --- a/src/Exception/ConfigurationException.php +++ b/src/Server/Exception/ConfigurationException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; /** * @author Oskar Stark diff --git a/src/Exception/ContainerException.php b/src/Server/Exception/ContainerException.php similarity index 92% rename from src/Exception/ContainerException.php rename to src/Server/Exception/ContainerException.php index 0a56987d9..842297a01 100644 --- a/src/Exception/ContainerException.php +++ b/src/Server/Exception/ContainerException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; use Psr\Container\ContainerExceptionInterface; diff --git a/src/Server/Exception/Exception.php b/src/Server/Exception/Exception.php new file mode 100644 index 000000000..eeed34be3 --- /dev/null +++ b/src/Server/Exception/Exception.php @@ -0,0 +1,19 @@ + + */ +class Exception extends \Exception implements ExceptionInterface +{ +} diff --git a/src/Exception/HandlerNotFoundException.php b/src/Server/Exception/ExceptionInterface.php similarity index 65% rename from src/Exception/HandlerNotFoundException.php rename to src/Server/Exception/ExceptionInterface.php index ef222eda3..9e4b44342 100644 --- a/src/Exception/HandlerNotFoundException.php +++ b/src/Server/Exception/ExceptionInterface.php @@ -9,11 +9,13 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; + +use Mcp\Schema\Exception\ExceptionInterface as SchemaExceptionInterface; /** * @author Tobias Nyholm */ -class HandlerNotFoundException extends \InvalidArgumentException implements NotFoundExceptionInterface +interface ExceptionInterface extends SchemaExceptionInterface { } diff --git a/src/Server/Exception/InvalidArgumentException.php b/src/Server/Exception/InvalidArgumentException.php new file mode 100644 index 000000000..30bcdc854 --- /dev/null +++ b/src/Server/Exception/InvalidArgumentException.php @@ -0,0 +1,19 @@ + + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/src/Exception/InvalidCursorException.php b/src/Server/Exception/InvalidCursorException.php similarity index 80% rename from src/Exception/InvalidCursorException.php rename to src/Server/Exception/InvalidCursorException.php index 5b08743ab..ddb151245 100644 --- a/src/Exception/InvalidCursorException.php +++ b/src/Server/Exception/InvalidCursorException.php @@ -9,12 +9,12 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; /** * @author Tobias Nyholm */ -final class InvalidCursorException extends \InvalidArgumentException implements ExceptionInterface +final class InvalidCursorException extends InvalidArgumentException { public function __construct( public readonly string $cursor, diff --git a/src/Exception/JwksRefreshRateLimitException.php b/src/Server/Exception/JwksRefreshRateLimitException.php similarity index 76% rename from src/Exception/JwksRefreshRateLimitException.php rename to src/Server/Exception/JwksRefreshRateLimitException.php index 51a769201..d7280e3f3 100644 --- a/src/Exception/JwksRefreshRateLimitException.php +++ b/src/Server/Exception/JwksRefreshRateLimitException.php @@ -9,14 +9,14 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; use Psr\Http\Client\ClientExceptionInterface; /** * @author Erik Thiart */ -final class JwksRefreshRateLimitException extends \RuntimeException implements ExceptionInterface, ClientExceptionInterface +final class JwksRefreshRateLimitException extends RuntimeException implements ClientExceptionInterface { public function __construct( public readonly int $retryAfter, diff --git a/src/Server/Exception/LogicException.php b/src/Server/Exception/LogicException.php new file mode 100644 index 000000000..1b5359a69 --- /dev/null +++ b/src/Server/Exception/LogicException.php @@ -0,0 +1,19 @@ + + */ +final class LogicException extends \LogicException implements ExceptionInterface +{ +} diff --git a/src/Exception/MissingRequiredClientCapabilityException.php b/src/Server/Exception/MissingRequiredClientCapabilityException.php similarity index 87% rename from src/Exception/MissingRequiredClientCapabilityException.php rename to src/Server/Exception/MissingRequiredClientCapabilityException.php index aa8b03158..836879732 100644 --- a/src/Exception/MissingRequiredClientCapabilityException.php +++ b/src/Server/Exception/MissingRequiredClientCapabilityException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; use Mcp\Schema\ClientCapabilities; @@ -22,7 +22,7 @@ * * @author Christopher Hertel */ -class MissingRequiredClientCapabilityException extends \RuntimeException implements ExceptionInterface +class MissingRequiredClientCapabilityException extends RuntimeException { public function __construct( public readonly ClientCapabilities $requiredCapabilities, diff --git a/src/Exception/NotFoundExceptionInterface.php b/src/Server/Exception/NotFoundExceptionInterface.php similarity index 92% rename from src/Exception/NotFoundExceptionInterface.php rename to src/Server/Exception/NotFoundExceptionInterface.php index faecad679..5b629bdab 100644 --- a/src/Exception/NotFoundExceptionInterface.php +++ b/src/Server/Exception/NotFoundExceptionInterface.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; /** * @author Tobias Nyholm diff --git a/src/Exception/PromptGetException.php b/src/Server/Exception/PromptGetException.php similarity index 74% rename from src/Exception/PromptGetException.php rename to src/Server/Exception/PromptGetException.php index 7eec0dafa..1a803c225 100644 --- a/src/Exception/PromptGetException.php +++ b/src/Server/Exception/PromptGetException.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; /** * @author Tobias Nyholm */ -final class PromptGetException extends \RuntimeException implements ExceptionInterface +final class PromptGetException extends RuntimeException { } diff --git a/src/Exception/PromptNotFoundException.php b/src/Server/Exception/PromptNotFoundException.php similarity index 78% rename from src/Exception/PromptNotFoundException.php rename to src/Server/Exception/PromptNotFoundException.php index 81b7c6e54..b316c0793 100644 --- a/src/Exception/PromptNotFoundException.php +++ b/src/Server/Exception/PromptNotFoundException.php @@ -9,12 +9,12 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; /** * @author Tobias Nyholm */ -final class PromptNotFoundException extends \RuntimeException implements NotFoundExceptionInterface +final class PromptNotFoundException extends RuntimeException implements NotFoundExceptionInterface { public function __construct( public readonly string $name, diff --git a/src/Exception/RegistryException.php b/src/Server/Exception/RegistryException.php similarity index 90% rename from src/Exception/RegistryException.php rename to src/Server/Exception/RegistryException.php index d2f57463d..7c30b219c 100644 --- a/src/Exception/RegistryException.php +++ b/src/Server/Exception/RegistryException.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; use Mcp\Schema\JsonRpc\Error; -final class RegistryException extends \Exception implements ExceptionInterface +final class RegistryException extends Exception { public static function invalidParams(string $message = 'Invalid params', ?\Throwable $previous = null): self { diff --git a/src/Exception/RequestStateException.php b/src/Server/Exception/RequestStateException.php similarity index 94% rename from src/Exception/RequestStateException.php rename to src/Server/Exception/RequestStateException.php index 2dde880b4..5ee65fc1a 100644 --- a/src/Exception/RequestStateException.php +++ b/src/Server/Exception/RequestStateException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; /** * An echoed `requestState` failed verification. diff --git a/src/Exception/ResourceNotFoundException.php b/src/Server/Exception/ResourceNotFoundException.php similarity index 78% rename from src/Exception/ResourceNotFoundException.php rename to src/Server/Exception/ResourceNotFoundException.php index 420ac1a83..847716a26 100644 --- a/src/Exception/ResourceNotFoundException.php +++ b/src/Server/Exception/ResourceNotFoundException.php @@ -9,12 +9,12 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; /** * @author Tobias Nyholm */ -final class ResourceNotFoundException extends \RuntimeException implements NotFoundExceptionInterface +final class ResourceNotFoundException extends RuntimeException implements NotFoundExceptionInterface { public function __construct( public readonly string $uri, diff --git a/src/Exception/ResourceReadException.php b/src/Server/Exception/ResourceReadException.php similarity index 73% rename from src/Exception/ResourceReadException.php rename to src/Server/Exception/ResourceReadException.php index a89dec8ed..c4ac7975e 100644 --- a/src/Exception/ResourceReadException.php +++ b/src/Server/Exception/ResourceReadException.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; /** * @author Tobias Nyholm */ -final class ResourceReadException extends \RuntimeException implements ExceptionInterface +final class ResourceReadException extends RuntimeException { } diff --git a/src/Server/Exception/RuntimeException.php b/src/Server/Exception/RuntimeException.php new file mode 100644 index 000000000..65194ef11 --- /dev/null +++ b/src/Server/Exception/RuntimeException.php @@ -0,0 +1,19 @@ + + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/src/Exception/ServiceNotFoundException.php b/src/Server/Exception/ServiceNotFoundException.php similarity index 92% rename from src/Exception/ServiceNotFoundException.php rename to src/Server/Exception/ServiceNotFoundException.php index 2d22708a3..f34aad1a9 100644 --- a/src/Exception/ServiceNotFoundException.php +++ b/src/Server/Exception/ServiceNotFoundException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; use Psr\Container\NotFoundExceptionInterface; diff --git a/src/Exception/SessionLockException.php b/src/Server/Exception/SessionLockException.php similarity index 77% rename from src/Exception/SessionLockException.php rename to src/Server/Exception/SessionLockException.php index 06e91af3a..5c4c62a3f 100644 --- a/src/Exception/SessionLockException.php +++ b/src/Server/Exception/SessionLockException.php @@ -9,13 +9,13 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; /** * A session lock could not be acquired or released. * * @author Vitalii Cherepanov */ -class SessionLockException extends \RuntimeException implements ExceptionInterface +class SessionLockException extends RuntimeException { } diff --git a/src/Exception/SessionLockTimeoutException.php b/src/Server/Exception/SessionLockTimeoutException.php similarity index 94% rename from src/Exception/SessionLockTimeoutException.php rename to src/Server/Exception/SessionLockTimeoutException.php index c88630680..4ed9cc5ba 100644 --- a/src/Exception/SessionLockTimeoutException.php +++ b/src/Server/Exception/SessionLockTimeoutException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; /** * Another request held the session lock for longer than the timeout. diff --git a/src/Exception/SessionRequiredException.php b/src/Server/Exception/SessionRequiredException.php similarity index 94% rename from src/Exception/SessionRequiredException.php rename to src/Server/Exception/SessionRequiredException.php index 7bc022b91..d6512eb2e 100644 --- a/src/Exception/SessionRequiredException.php +++ b/src/Server/Exception/SessionRequiredException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; /** * A handler needs a session on a server built without {@see \Mcp\Server\Builder::setSession()}; the protocol answers `-32603` with this message. diff --git a/src/Exception/SessionStoreException.php b/src/Server/Exception/SessionStoreException.php similarity index 93% rename from src/Exception/SessionStoreException.php rename to src/Server/Exception/SessionStoreException.php index f5b0d92ab..e4cf595a2 100644 --- a/src/Exception/SessionStoreException.php +++ b/src/Server/Exception/SessionStoreException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; /** * The session store could not be reached, so whether a session exists is unknown. diff --git a/src/Exception/ToolCallException.php b/src/Server/Exception/ToolCallException.php similarity index 74% rename from src/Exception/ToolCallException.php rename to src/Server/Exception/ToolCallException.php index 01ba9f45a..64bedafce 100644 --- a/src/Exception/ToolCallException.php +++ b/src/Server/Exception/ToolCallException.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; /** * @author Tobias Nyholm */ -final class ToolCallException extends \RuntimeException implements ExceptionInterface +final class ToolCallException extends RuntimeException { } diff --git a/src/Exception/ToolNotFoundException.php b/src/Server/Exception/ToolNotFoundException.php similarity index 78% rename from src/Exception/ToolNotFoundException.php rename to src/Server/Exception/ToolNotFoundException.php index 0a864e753..e61752f2d 100644 --- a/src/Exception/ToolNotFoundException.php +++ b/src/Server/Exception/ToolNotFoundException.php @@ -9,12 +9,12 @@ * file that was distributed with this source code. */ -namespace Mcp\Exception; +namespace Mcp\Server\Exception; /** * @author Tobias Nyholm */ -final class ToolNotFoundException extends \RuntimeException implements NotFoundExceptionInterface +final class ToolNotFoundException extends RuntimeException implements NotFoundExceptionInterface { public function __construct( public readonly string $name, diff --git a/src/Server/Extension/ServerExtensionInterface.php b/src/Server/Extension/ServerExtensionInterface.php new file mode 100644 index 000000000..e0140a2ff --- /dev/null +++ b/src/Server/Extension/ServerExtensionInterface.php @@ -0,0 +1,31 @@ + + */ +interface ServerExtensionInterface extends ExtensionInterface +{ + /** + * The handlers serving the methods of {@see self::getMessages()}. + * + * @return iterable> + */ + public function getRequestHandlers(): iterable; +} diff --git a/src/Server/Fiber/HandlerFiberState.php b/src/Server/Fiber/HandlerFiberState.php index f935f29d8..3774b3f6c 100644 --- a/src/Server/Fiber/HandlerFiberState.php +++ b/src/Server/Fiber/HandlerFiberState.php @@ -11,8 +11,8 @@ namespace Mcp\Server\Fiber; -use Mcp\Exception\LogicException; use Mcp\Schema\JsonRpc\Error; +use Mcp\Server\Exception\LogicException; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; diff --git a/src/Server/Fiber/HandlerFibers.php b/src/Server/Fiber/HandlerFibers.php index 99c9636f7..c83eb62aa 100644 --- a/src/Server/Fiber/HandlerFibers.php +++ b/src/Server/Fiber/HandlerFibers.php @@ -11,8 +11,8 @@ namespace Mcp\Server\Fiber; -use Mcp\Exception\LogicException; use Mcp\Schema\JsonRpc\Error; +use Mcp\Server\Exception\LogicException; use Mcp\Server\Suspension\NotificationSuspension; use Mcp\Server\Suspension\RequestSuspension; use Psr\Log\LoggerInterface; diff --git a/src/Server/Handler/Request/CallToolHandler.php b/src/Server/Handler/Request/CallToolHandler.php index 0d8a90b4a..e4d4ad5aa 100644 --- a/src/Server/Handler/Request/CallToolHandler.php +++ b/src/Server/Handler/Request/CallToolHandler.php @@ -11,14 +11,6 @@ namespace Mcp\Server\Handler\Request; -use Mcp\Capability\Discovery\SchemaValidator; -use Mcp\Capability\Registry\ReferenceHandlerInterface; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\MissingRequiredClientCapabilityException; -use Mcp\Exception\RegistryException; -use Mcp\Exception\SessionRequiredException; -use Mcp\Exception\ToolCallException; -use Mcp\Exception\ToolNotFoundException; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Enum\StructuredContent; use Mcp\Schema\JsonRpc\Error; @@ -28,6 +20,14 @@ use Mcp\Schema\Result\CallToolResult; use Mcp\Schema\Result\InputRequiredResult; use Mcp\Schema\Tool; +use Mcp\Server\Capability\Discovery\SchemaValidator; +use Mcp\Server\Capability\Registry\ReferenceHandlerInterface; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\MissingRequiredClientCapabilityException; +use Mcp\Server\Exception\RegistryException; +use Mcp\Server\Exception\SessionRequiredException; +use Mcp\Server\Exception\ToolCallException; +use Mcp\Server\Exception\ToolNotFoundException; use Mcp\Server\RequestContext; use Mcp\Server\Session\SessionInterface; use Psr\Log\LoggerInterface; diff --git a/src/Server/Handler/Request/CompletionCompleteHandler.php b/src/Server/Handler/Request/CompletionCompleteHandler.php index 704116da3..aa708703b 100644 --- a/src/Server/Handler/Request/CompletionCompleteHandler.php +++ b/src/Server/Handler/Request/CompletionCompleteHandler.php @@ -11,11 +11,6 @@ namespace Mcp\Server\Handler\Request; -use Mcp\Capability\Completion\ProviderInterface; -use Mcp\Capability\Registry\ResourceTemplateReference; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\PromptNotFoundException; -use Mcp\Exception\ResourceNotFoundException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; @@ -23,6 +18,11 @@ use Mcp\Schema\Request\CompletionCompleteRequest; use Mcp\Schema\ResourceReference; use Mcp\Schema\Result\CompletionCompleteResult; +use Mcp\Server\Capability\Completion\ProviderInterface; +use Mcp\Server\Capability\Registry\ResourceTemplateReference; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\PromptNotFoundException; +use Mcp\Server\Exception\ResourceNotFoundException; use Mcp\Server\Session\SessionInterface; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; diff --git a/src/Server/Handler/Request/GetPromptHandler.php b/src/Server/Handler/Request/GetPromptHandler.php index 4ddc25f89..c1cc10aa6 100644 --- a/src/Server/Handler/Request/GetPromptHandler.php +++ b/src/Server/Handler/Request/GetPromptHandler.php @@ -11,19 +11,19 @@ namespace Mcp\Server\Handler\Request; -use Mcp\Capability\Registry\ReferenceHandlerInterface; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\MissingRequiredClientCapabilityException; -use Mcp\Exception\PromptGetException; -use Mcp\Exception\PromptNotFoundException; -use Mcp\Exception\RegistryException; -use Mcp\Exception\SessionRequiredException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\GetPromptRequest; use Mcp\Schema\Result\GetPromptResult; use Mcp\Schema\Result\InputRequiredResult; +use Mcp\Server\Capability\Registry\ReferenceHandlerInterface; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\MissingRequiredClientCapabilityException; +use Mcp\Server\Exception\PromptGetException; +use Mcp\Server\Exception\PromptNotFoundException; +use Mcp\Server\Exception\RegistryException; +use Mcp\Server\Exception\SessionRequiredException; use Mcp\Server\Session\SessionInterface; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; diff --git a/src/Server/Handler/Request/ListPromptsHandler.php b/src/Server/Handler/Request/ListPromptsHandler.php index ee287560f..5f45f9f04 100644 --- a/src/Server/Handler/Request/ListPromptsHandler.php +++ b/src/Server/Handler/Request/ListPromptsHandler.php @@ -11,12 +11,12 @@ namespace Mcp\Server\Handler\Request; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\InvalidCursorException; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\ListPromptsRequest; use Mcp\Schema\Result\ListPromptsResult; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\InvalidCursorException; use Mcp\Server\Session\SessionInterface; /** diff --git a/src/Server/Handler/Request/ListResourceTemplatesHandler.php b/src/Server/Handler/Request/ListResourceTemplatesHandler.php index 5360f75ed..a211eeed7 100644 --- a/src/Server/Handler/Request/ListResourceTemplatesHandler.php +++ b/src/Server/Handler/Request/ListResourceTemplatesHandler.php @@ -11,12 +11,12 @@ namespace Mcp\Server\Handler\Request; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\InvalidCursorException; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\ListResourceTemplatesRequest; use Mcp\Schema\Result\ListResourceTemplatesResult; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\InvalidCursorException; use Mcp\Server\Session\SessionInterface; /** diff --git a/src/Server/Handler/Request/ListResourcesHandler.php b/src/Server/Handler/Request/ListResourcesHandler.php index d1d683079..e5c3c1b9c 100644 --- a/src/Server/Handler/Request/ListResourcesHandler.php +++ b/src/Server/Handler/Request/ListResourcesHandler.php @@ -11,12 +11,12 @@ namespace Mcp\Server\Handler\Request; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\InvalidCursorException; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\ListResourcesRequest; use Mcp\Schema\Result\ListResourcesResult; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\InvalidCursorException; use Mcp\Server\Session\SessionInterface; /** diff --git a/src/Server/Handler/Request/ListToolsHandler.php b/src/Server/Handler/Request/ListToolsHandler.php index 007bdd507..775a31ff1 100644 --- a/src/Server/Handler/Request/ListToolsHandler.php +++ b/src/Server/Handler/Request/ListToolsHandler.php @@ -11,12 +11,12 @@ namespace Mcp\Server\Handler\Request; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\InvalidCursorException; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\ListToolsRequest; use Mcp\Schema\Result\ListToolsResult; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\InvalidCursorException; use Mcp\Server\Session\SessionInterface; /** diff --git a/src/Server/Handler/Request/ReadResourceHandler.php b/src/Server/Handler/Request/ReadResourceHandler.php index 961dc68ec..def85079f 100644 --- a/src/Server/Handler/Request/ReadResourceHandler.php +++ b/src/Server/Handler/Request/ReadResourceHandler.php @@ -11,20 +11,20 @@ namespace Mcp\Server\Handler\Request; -use Mcp\Capability\Registry\ReferenceHandlerInterface; -use Mcp\Capability\Registry\ResourceTemplateReference; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\MissingRequiredClientCapabilityException; -use Mcp\Exception\RegistryException; -use Mcp\Exception\ResourceNotFoundException; -use Mcp\Exception\ResourceReadException; -use Mcp\Exception\SessionRequiredException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\ReadResourceRequest; use Mcp\Schema\Result\InputRequiredResult; use Mcp\Schema\Result\ReadResourceResult; +use Mcp\Server\Capability\Registry\ReferenceHandlerInterface; +use Mcp\Server\Capability\Registry\ResourceTemplateReference; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\MissingRequiredClientCapabilityException; +use Mcp\Server\Exception\RegistryException; +use Mcp\Server\Exception\ResourceNotFoundException; +use Mcp\Server\Exception\ResourceReadException; +use Mcp\Server\Exception\SessionRequiredException; use Mcp\Server\RequestContext; use Mcp\Server\Session\SessionInterface; use Psr\Log\LoggerInterface; diff --git a/src/Server/Handler/Request/ResourceSubscribeHandler.php b/src/Server/Handler/Request/ResourceSubscribeHandler.php index 1e8147b02..96acdbd45 100644 --- a/src/Server/Handler/Request/ResourceSubscribeHandler.php +++ b/src/Server/Handler/Request/ResourceSubscribeHandler.php @@ -11,13 +11,13 @@ namespace Mcp\Server\Handler\Request; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\ResourceNotFoundException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\ResourceSubscribeRequest; use Mcp\Schema\Result\EmptyResult; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\ResourceNotFoundException; use Mcp\Server\RequestContext; use Mcp\Server\Resource\SubscriptionManagerInterface; use Mcp\Server\Session\SessionInterface; diff --git a/src/Server/Handler/Request/ResourceUnsubscribeHandler.php b/src/Server/Handler/Request/ResourceUnsubscribeHandler.php index 522c51289..a0bdfef34 100644 --- a/src/Server/Handler/Request/ResourceUnsubscribeHandler.php +++ b/src/Server/Handler/Request/ResourceUnsubscribeHandler.php @@ -11,13 +11,13 @@ namespace Mcp\Server\Handler\Request; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\ResourceNotFoundException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\ResourceUnsubscribeRequest; use Mcp\Schema\Result\EmptyResult; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\ResourceNotFoundException; use Mcp\Server\RequestContext; use Mcp\Server\Resource\SubscriptionManagerInterface; use Mcp\Server\Session\SessionInterface; diff --git a/src/Server/InputRequiredShim.php b/src/Server/InputRequiredShim.php index abce28056..89af4c620 100644 --- a/src/Server/InputRequiredShim.php +++ b/src/Server/InputRequiredShim.php @@ -11,13 +11,13 @@ namespace Mcp\Server; -use Mcp\Exception\RequestStateException; use Mcp\Schema\ClientCapabilities; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\JsonRpc\ResultInterface; use Mcp\Schema\Result\InputRequiredResult; +use Mcp\Server\Exception\RequestStateException; use Mcp\Server\Handler\Request\RequestHandlerInterface; use Mcp\Server\Session\EphemeralSessionInterface; use Mcp\Server\Session\SessionInterface; diff --git a/src/Server/Protocol.php b/src/Server/Protocol.php index 2ebaeb3e2..90c40e81a 100644 --- a/src/Server/Protocol.php +++ b/src/Server/Protocol.php @@ -11,31 +11,31 @@ namespace Mcp\Server; -use Mcp\Event\ClientResponseEvent; -use Mcp\Event\ErrorEvent; -use Mcp\Event\NotificationEvent; -use Mcp\Event\RequestEvent; -use Mcp\Event\ResponseEvent; -use Mcp\Event\ServerRequestEvent; -use Mcp\Exception\ConfigurationException; -use Mcp\Exception\InvalidInputMessageException; -use Mcp\Exception\RuntimeException; -use Mcp\Exception\SessionLockException; -use Mcp\Exception\SessionLockTimeoutException; -use Mcp\Exception\SessionRequiredException; -use Mcp\Exception\SessionStoreException; -use Mcp\JsonRpc\MessageFactory; +use Mcp\Schema\Exception\InvalidInputMessageException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\MessageInterface; use Mcp\Schema\JsonRpc\Notification; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\JsonRpc\ResultInterface; +use Mcp\Schema\MessageFactory; use Mcp\Schema\Request\InitializeRequest; use Mcp\Schema\Request\ResourceSubscribeRequest; use Mcp\Schema\Request\ResourceUnsubscribeRequest; use Mcp\Schema\Request\SetLogLevelRequest; use Mcp\Server\Authorization\AccessToken; +use Mcp\Server\Event\ClientResponseEvent; +use Mcp\Server\Event\ErrorEvent; +use Mcp\Server\Event\NotificationEvent; +use Mcp\Server\Event\RequestEvent; +use Mcp\Server\Event\ResponseEvent; +use Mcp\Server\Event\ServerRequestEvent; +use Mcp\Server\Exception\ConfigurationException; +use Mcp\Server\Exception\RuntimeException; +use Mcp\Server\Exception\SessionLockException; +use Mcp\Server\Exception\SessionLockTimeoutException; +use Mcp\Server\Exception\SessionRequiredException; +use Mcp\Server\Exception\SessionStoreException; use Mcp\Server\Fiber\EventLoopSessionLock; use Mcp\Server\Fiber\FiberContextInterface; use Mcp\Server\Fiber\FiberSchedulerInterface; diff --git a/src/Server/RequestContext.php b/src/Server/RequestContext.php index 51e31d9be..74bde076d 100644 --- a/src/Server/RequestContext.php +++ b/src/Server/RequestContext.php @@ -11,15 +11,15 @@ namespace Mcp\Server; -use Mcp\Capability\Logger\ClientLogger; -use Mcp\Exception\LogicException; use Mcp\Schema\ClientCapabilities; use Mcp\Schema\Enum\ProtocolVersion; use Mcp\Schema\JsonRpc\Request; +use Mcp\Schema\RequestMeta; use Mcp\Server\Authorization\AccessToken; +use Mcp\Server\Capability\Logger\ClientLogger; +use Mcp\Server\Exception\LogicException; use Mcp\Server\Session\SessionInterface; use Mcp\Server\Stateless\InputContext; -use Mcp\Server\Stateless\RequestMeta; use Mcp\Server\Stateless\RequestStateCodec; /** diff --git a/src/Server.php b/src/Server/Server.php similarity index 97% rename from src/Server.php rename to src/Server/Server.php index f623d86f4..d6368c443 100644 --- a/src/Server.php +++ b/src/Server/Server.php @@ -9,11 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp; +namespace Mcp\Server; use Mcp\Schema\Enum\ProtocolVersion; -use Mcp\Server\Builder; -use Mcp\Server\Protocol; use Mcp\Server\Stateless\StatelessProtocol; use Mcp\Server\Transport\StatelessAwareTransportInterface; use Mcp\Server\Transport\TransportInterface; diff --git a/src/Server/Session/EphemeralSession.php b/src/Server/Session/EphemeralSession.php index 448dc0e4e..e253fe9d5 100644 --- a/src/Server/Session/EphemeralSession.php +++ b/src/Server/Session/EphemeralSession.php @@ -11,7 +11,7 @@ namespace Mcp\Server\Session; -use Mcp\Exception\SessionRequiredException; +use Mcp\Server\Exception\SessionRequiredException; /** * The session of one request on a server built without {@see \Mcp\Server\Builder::setSession()}. diff --git a/src/Server/Session/FileSessionLock.php b/src/Server/Session/FileSessionLock.php index 38c04af7a..72b3dd8bc 100644 --- a/src/Server/Session/FileSessionLock.php +++ b/src/Server/Session/FileSessionLock.php @@ -11,10 +11,10 @@ namespace Mcp\Server\Session; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\RuntimeException; -use Mcp\Exception\SessionLockException; -use Mcp\Exception\SessionLockTimeoutException; +use Mcp\Server\Exception\InvalidArgumentException; +use Mcp\Server\Exception\RuntimeException; +use Mcp\Server\Exception\SessionLockException; +use Mcp\Server\Exception\SessionLockTimeoutException; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; use Symfony\Component\Uid\Uuid; diff --git a/src/Server/Session/FileSessionStore.php b/src/Server/Session/FileSessionStore.php index 02cc32430..eefe13534 100644 --- a/src/Server/Session/FileSessionStore.php +++ b/src/Server/Session/FileSessionStore.php @@ -11,7 +11,7 @@ namespace Mcp\Server\Session; -use Mcp\Exception\RuntimeException; +use Mcp\Server\Exception\RuntimeException; use Mcp\Server\NativeClock; use Psr\Clock\ClockInterface; use Psr\Log\LoggerInterface; diff --git a/src/Server/Session/Psr16SessionStore.php b/src/Server/Session/Psr16SessionStore.php index 08ab0e3cb..f6c3b2903 100644 --- a/src/Server/Session/Psr16SessionStore.php +++ b/src/Server/Session/Psr16SessionStore.php @@ -11,7 +11,7 @@ namespace Mcp\Server\Session; -use Mcp\Exception\SessionStoreException; +use Mcp\Server\Exception\SessionStoreException; use Psr\SimpleCache\CacheInterface; use Symfony\Component\Uid\Uuid; diff --git a/src/Server/Session/SessionInterface.php b/src/Server/Session/SessionInterface.php index 5ae93ad76..f2f5dce1f 100644 --- a/src/Server/Session/SessionInterface.php +++ b/src/Server/Session/SessionInterface.php @@ -11,7 +11,7 @@ namespace Mcp\Server\Session; -use Mcp\Exception\SessionStoreException; +use Mcp\Server\Exception\SessionStoreException; use Symfony\Component\Uid\Uuid; /** diff --git a/src/Server/Session/SessionLockInterface.php b/src/Server/Session/SessionLockInterface.php index ceb150c0f..e81e8ef59 100644 --- a/src/Server/Session/SessionLockInterface.php +++ b/src/Server/Session/SessionLockInterface.php @@ -11,8 +11,8 @@ namespace Mcp\Server\Session; -use Mcp\Exception\SessionLockException; -use Mcp\Exception\SessionLockTimeoutException; +use Mcp\Server\Exception\SessionLockException; +use Mcp\Server\Exception\SessionLockTimeoutException; use Symfony\Component\Uid\Uuid; /** diff --git a/src/Server/Session/SessionManager.php b/src/Server/Session/SessionManager.php index 2a08f7ee9..21535359f 100644 --- a/src/Server/Session/SessionManager.php +++ b/src/Server/Session/SessionManager.php @@ -11,7 +11,7 @@ namespace Mcp\Server\Session; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Server\Exception\InvalidArgumentException; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; use Symfony\Component\Uid\Uuid; diff --git a/src/Server/Session/SessionStoreInterface.php b/src/Server/Session/SessionStoreInterface.php index 88fe60375..cb4c7f0a7 100644 --- a/src/Server/Session/SessionStoreInterface.php +++ b/src/Server/Session/SessionStoreInterface.php @@ -11,7 +11,7 @@ namespace Mcp\Server\Session; -use Mcp\Exception\SessionStoreException; +use Mcp\Server\Exception\SessionStoreException; use Symfony\Component\Uid\Uuid; /** diff --git a/src/Server/Session/SymfonyLockSessionLock.php b/src/Server/Session/SymfonyLockSessionLock.php index e065d2dc7..5a0ca1cd8 100644 --- a/src/Server/Session/SymfonyLockSessionLock.php +++ b/src/Server/Session/SymfonyLockSessionLock.php @@ -11,9 +11,9 @@ namespace Mcp\Server\Session; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\SessionLockException; -use Mcp\Exception\SessionLockTimeoutException; +use Mcp\Server\Exception\InvalidArgumentException; +use Mcp\Server\Exception\SessionLockException; +use Mcp\Server\Exception\SessionLockTimeoutException; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; use Symfony\Component\Lock\Exception\ExceptionInterface as LockExceptionInterface; diff --git a/src/Server/Stateless/ElicitationReplay.php b/src/Server/Stateless/ElicitationReplay.php index fe936277a..6d66349d5 100644 --- a/src/Server/Stateless/ElicitationReplay.php +++ b/src/Server/Stateless/ElicitationReplay.php @@ -11,11 +11,11 @@ namespace Mcp\Server\Stateless; -use Mcp\Exception\LogicException; use Mcp\Schema\Enum\ElicitationMode; use Mcp\Schema\Request\ElicitRequest; use Mcp\Schema\Result\ElicitResult; use Mcp\Schema\Result\InputRequiredResult; +use Mcp\Server\Exception\LogicException; /** * Answers a handler's {@see \Mcp\Server\ClientGateway::elicit()} on a lifecycle diff --git a/src/Server/Stateless/OriginatingRequestBinder.php b/src/Server/Stateless/OriginatingRequestBinder.php index af2db2100..c4051af77 100644 --- a/src/Server/Stateless/OriginatingRequestBinder.php +++ b/src/Server/Stateless/OriginatingRequestBinder.php @@ -11,12 +11,12 @@ namespace Mcp\Server\Stateless; -use Mcp\Exception\RuntimeException; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\Request\CallToolRequest; use Mcp\Schema\Request\GetPromptRequest; use Mcp\Schema\Request\ReadResourceRequest; use Mcp\Server\Authorization\AccessToken; +use Mcp\Server\Exception\RuntimeException; /** * Binds a `requestState` to what the specification recommends: the diff --git a/src/Server/Stateless/RequestStateCodec.php b/src/Server/Stateless/RequestStateCodec.php index 6b81fab1c..cc30db4c1 100644 --- a/src/Server/Stateless/RequestStateCodec.php +++ b/src/Server/Stateless/RequestStateCodec.php @@ -11,8 +11,8 @@ namespace Mcp\Server\Stateless; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\RequestStateException; +use Mcp\Server\Exception\InvalidArgumentException; +use Mcp\Server\Exception\RequestStateException; /** * Seals and verifies the opaque `requestState` carried across the rounds of a diff --git a/src/Server/Stateless/StandardHeaderValidator.php b/src/Server/Stateless/StandardHeaderValidator.php index 7e956aa05..e18c84fa8 100644 --- a/src/Server/Stateless/StandardHeaderValidator.php +++ b/src/Server/Stateless/StandardHeaderValidator.php @@ -11,11 +11,11 @@ namespace Mcp\Server\Stateless; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\ConfigurationException; -use Mcp\Exception\ToolNotFoundException; -use Mcp\JsonRpc\Json; +use Mcp\Schema\Json; use Mcp\Schema\Wire\McpHeader; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\ConfigurationException; +use Mcp\Server\Exception\ToolNotFoundException; /** * Checks that a request's HTTP headers agree with its JSON-RPC body (SEP-2243). diff --git a/src/Server/Stateless/StatelessProtocol.php b/src/Server/Stateless/StatelessProtocol.php index 0eccf548b..4437e8ac2 100644 --- a/src/Server/Stateless/StatelessProtocol.php +++ b/src/Server/Stateless/StatelessProtocol.php @@ -11,29 +11,31 @@ namespace Mcp\Server\Stateless; -use Mcp\Event\ErrorEvent; -use Mcp\Event\RequestEvent; -use Mcp\Event\ResponseEvent; -use Mcp\Exception\ConfigurationException; -use Mcp\Exception\InvalidInputMessageException; -use Mcp\Exception\LogicException; -use Mcp\Exception\MissingRequestMetaException; -use Mcp\Exception\MissingRequiredClientCapabilityException; -use Mcp\Exception\RequestStateException; -use Mcp\Exception\UnknownMethodException; -use Mcp\JsonRpc\MessageFactory; use Mcp\Schema\Enum\ProtocolVersion; +use Mcp\Schema\Exception\InvalidInputMessageException; +use Mcp\Schema\Exception\MissingRequestMetaException; +use Mcp\Schema\Exception\UnknownMethodException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\MessageInterface; use Mcp\Schema\JsonRpc\Notification; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\JsonRpc\ResultInterface; +use Mcp\Schema\MessageFactory; use Mcp\Schema\Notification\LoggingMessageNotification; use Mcp\Schema\Request\ElicitRequest; +use Mcp\Schema\RequestMeta; use Mcp\Schema\Result\InputRequiredResult; +use Mcp\Schema\Wire\McpHeader; use Mcp\Server\Authorization\AccessToken; use Mcp\Server\Configuration; +use Mcp\Server\Event\ErrorEvent; +use Mcp\Server\Event\RequestEvent; +use Mcp\Server\Event\ResponseEvent; +use Mcp\Server\Exception\ConfigurationException; +use Mcp\Server\Exception\LogicException; +use Mcp\Server\Exception\MissingRequiredClientCapabilityException; +use Mcp\Server\Exception\RequestStateException; use Mcp\Server\Fiber\FiberContextInterface; use Mcp\Server\Fiber\FiberSchedulerInterface; use Mcp\Server\Fiber\HandlerFibers; @@ -312,7 +314,7 @@ private function acknowledge(string $method): StatelessResult */ private function checkVersion(RequestMeta $meta, array $headers, string|int|null $id, bool $headerLayer = true): ?StatelessResult { - $headerVersion = $this->header($headers, 'MCP-Protocol-Version'); + $headerVersion = McpHeader::lookup($headers, 'MCP-Protocol-Version'); // REQUIRED on every POST. The 2025-03-26 fallback for a header-less // request exists only for servers choosing to serve pre-2025-06-18 @@ -987,12 +989,4 @@ private static function acceptsEventStream(array $headers): bool return false; } - - /** - * @param array $headers - */ - private function header(array $headers, string $name): ?string - { - return InboundClassifier::header($headers, $name); - } } diff --git a/src/Server/Subscription/InMemoryNotificationBus.php b/src/Server/Subscription/InMemoryNotificationBus.php index 9a8029ca1..77f2a9dc1 100644 --- a/src/Server/Subscription/InMemoryNotificationBus.php +++ b/src/Server/Subscription/InMemoryNotificationBus.php @@ -11,8 +11,8 @@ namespace Mcp\Server\Subscription; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Notification; +use Mcp\Server\Exception\InvalidArgumentException; /** * A notification bus held in one process's memory. diff --git a/src/Server/Subscription/Psr16NotificationBus.php b/src/Server/Subscription/Psr16NotificationBus.php index 4a96fafd4..5a6f0fd70 100644 --- a/src/Server/Subscription/Psr16NotificationBus.php +++ b/src/Server/Subscription/Psr16NotificationBus.php @@ -11,9 +11,9 @@ namespace Mcp\Server\Subscription; -use Mcp\Exception\InvalidArgumentException; -use Mcp\JsonRpc\MessageFactory; use Mcp\Schema\JsonRpc\Notification; +use Mcp\Schema\MessageFactory; +use Mcp\Server\Exception\InvalidArgumentException; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; use Psr\SimpleCache\CacheInterface; diff --git a/src/Server/Subscription/Psr6NotificationBus.php b/src/Server/Subscription/Psr6NotificationBus.php index 0125bc1a2..5a8fa237f 100644 --- a/src/Server/Subscription/Psr6NotificationBus.php +++ b/src/Server/Subscription/Psr6NotificationBus.php @@ -11,9 +11,9 @@ namespace Mcp\Server\Subscription; -use Mcp\Exception\InvalidArgumentException; -use Mcp\JsonRpc\MessageFactory; use Mcp\Schema\JsonRpc\Notification; +use Mcp\Schema\MessageFactory; +use Mcp\Server\Exception\InvalidArgumentException; use Psr\Cache\CacheItemPoolInterface; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; diff --git a/src/Server/Subscription/RegistryChangePublisher.php b/src/Server/Subscription/RegistryChangePublisher.php index 363a2aea9..631bfafc3 100644 --- a/src/Server/Subscription/RegistryChangePublisher.php +++ b/src/Server/Subscription/RegistryChangePublisher.php @@ -11,13 +11,13 @@ namespace Mcp\Server\Subscription; -use Mcp\Event\PromptListChangedEvent; -use Mcp\Event\ResourceListChangedEvent; -use Mcp\Event\ResourceTemplateListChangedEvent; -use Mcp\Event\ToolListChangedEvent; use Mcp\Schema\Notification\PromptListChangedNotification; use Mcp\Schema\Notification\ResourceListChangedNotification; use Mcp\Schema\Notification\ToolListChangedNotification; +use Mcp\Server\Event\PromptListChangedEvent; +use Mcp\Server\Event\ResourceListChangedEvent; +use Mcp\Server\Event\ResourceTemplateListChangedEvent; +use Mcp\Server\Event\ToolListChangedEvent; /** * Turns the registry's own change events into the notifications a diff --git a/src/Server/Transport/BaseTransport.php b/src/Server/Transport/BaseTransport.php index 7b3da98df..868654aa5 100644 --- a/src/Server/Transport/BaseTransport.php +++ b/src/Server/Transport/BaseTransport.php @@ -11,10 +11,10 @@ namespace Mcp\Server\Transport; -use Mcp\Exception\SessionStoreException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Response; use Mcp\Server\Authorization\AccessToken; +use Mcp\Server\Exception\SessionStoreException; use Mcp\Server\Fiber\HandlerFibers; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; diff --git a/src/Server/Transport/CallbackStream.php b/src/Server/Transport/CallbackStream.php index 3439e9417..57761a88d 100644 --- a/src/Server/Transport/CallbackStream.php +++ b/src/Server/Transport/CallbackStream.php @@ -11,8 +11,8 @@ namespace Mcp\Server\Transport; -use Mcp\Exception\LogicException; -use Mcp\Exception\RuntimeException; +use Mcp\Server\Exception\LogicException; +use Mcp\Server\Exception\RuntimeException; use Psr\Http\Message\StreamInterface; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; diff --git a/src/Server/Transport/Http/Middleware/CorsMiddleware.php b/src/Server/Transport/Http/Middleware/CorsMiddleware.php index fd7690e47..65807c29f 100644 --- a/src/Server/Transport/Http/Middleware/CorsMiddleware.php +++ b/src/Server/Transport/Http/Middleware/CorsMiddleware.php @@ -11,8 +11,8 @@ namespace Mcp\Server\Transport\Http\Middleware; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Wire\McpHeader; +use Mcp\Server\Exception\InvalidArgumentException; use Mcp\Server\Transport\StreamableHttpTransport; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; diff --git a/src/Server/Transport/Http/OAuth/AuthorizationResult.php b/src/Server/Transport/Http/OAuth/AuthorizationResult.php index 973d74b11..f6043a391 100644 --- a/src/Server/Transport/Http/OAuth/AuthorizationResult.php +++ b/src/Server/Transport/Http/OAuth/AuthorizationResult.php @@ -11,8 +11,8 @@ namespace Mcp\Server\Transport\Http\OAuth; -use Mcp\Exception\InvalidArgumentException; use Mcp\Server\Authorization\AccessToken; +use Mcp\Server\Exception\InvalidArgumentException; /** * Describes the outcome of an authorization decision. diff --git a/src/Server/Transport/Http/OAuth/JwtTokenValidator.php b/src/Server/Transport/Http/OAuth/JwtTokenValidator.php index 8c7c5efd4..f53b8f073 100644 --- a/src/Server/Transport/Http/OAuth/JwtTokenValidator.php +++ b/src/Server/Transport/Http/OAuth/JwtTokenValidator.php @@ -19,10 +19,10 @@ use Firebase\JWT\SignatureInvalidException; use Http\Discovery\Psr17FactoryDiscovery; use Http\Discovery\Psr18ClientDiscovery; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\JwksRefreshRateLimitException; -use Mcp\Exception\RuntimeException; use Mcp\Server\Authorization\AccessToken; +use Mcp\Server\Exception\InvalidArgumentException; +use Mcp\Server\Exception\JwksRefreshRateLimitException; +use Mcp\Server\Exception\RuntimeException; use Psr\Cache\CacheItemPoolInterface; use Psr\Http\Client\ClientExceptionInterface; use Psr\Http\Client\ClientInterface; diff --git a/src/Server/Transport/Http/OAuth/OidcDiscovery.php b/src/Server/Transport/Http/OAuth/OidcDiscovery.php index 3da5e3f4a..552068840 100644 --- a/src/Server/Transport/Http/OAuth/OidcDiscovery.php +++ b/src/Server/Transport/Http/OAuth/OidcDiscovery.php @@ -13,8 +13,8 @@ use Http\Discovery\Psr17FactoryDiscovery; use Http\Discovery\Psr18ClientDiscovery; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\RuntimeException; +use Mcp\Server\Exception\InvalidArgumentException; +use Mcp\Server\Exception\RuntimeException; use Psr\Cache\CacheItemPoolInterface; use Psr\Http\Client\ClientExceptionInterface; use Psr\Http\Client\ClientInterface; diff --git a/src/Server/Transport/Http/OAuth/ProtectedResourceMetadata.php b/src/Server/Transport/Http/OAuth/ProtectedResourceMetadata.php index 9102a80bc..dfae2dbf6 100644 --- a/src/Server/Transport/Http/OAuth/ProtectedResourceMetadata.php +++ b/src/Server/Transport/Http/OAuth/ProtectedResourceMetadata.php @@ -11,7 +11,7 @@ namespace Mcp\Server\Transport\Http\OAuth; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Server\Exception\InvalidArgumentException; /** * OAuth 2.0 Protected Resource Metadata (RFC 9728). diff --git a/src/Server/Transport/Http/OAuth/RateLimitedJwksClient.php b/src/Server/Transport/Http/OAuth/RateLimitedJwksClient.php index 68200c55d..5ab3718d8 100644 --- a/src/Server/Transport/Http/OAuth/RateLimitedJwksClient.php +++ b/src/Server/Transport/Http/OAuth/RateLimitedJwksClient.php @@ -11,7 +11,7 @@ namespace Mcp\Server\Transport\Http\OAuth; -use Mcp\Exception\JwksRefreshRateLimitException; +use Mcp\Server\Exception\JwksRefreshRateLimitException; use Psr\Cache\CacheItemPoolInterface; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestInterface; diff --git a/src/Server/Transport/Http/OAuth/ScopePolicy.php b/src/Server/Transport/Http/OAuth/ScopePolicy.php index e86261e09..41c1ae80c 100644 --- a/src/Server/Transport/Http/OAuth/ScopePolicy.php +++ b/src/Server/Transport/Http/OAuth/ScopePolicy.php @@ -11,7 +11,7 @@ namespace Mcp\Server\Transport\Http\OAuth; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Server\Exception\InvalidArgumentException; /** * Declares which scopes a request needs, enforced by diff --git a/src/Server/Transport/Http/OAuth/Scopes.php b/src/Server/Transport/Http/OAuth/Scopes.php index 2eebe067a..7e7b7719e 100644 --- a/src/Server/Transport/Http/OAuth/Scopes.php +++ b/src/Server/Transport/Http/OAuth/Scopes.php @@ -11,7 +11,7 @@ namespace Mcp\Server\Transport\Http\OAuth; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Server\Exception\InvalidArgumentException; /** * Validates and dedupes a list of OAuth scopes. diff --git a/src/Server/Transport/Http/OAuth/SecureUrl.php b/src/Server/Transport/Http/OAuth/SecureUrl.php index bfd7949b0..3b352c207 100644 --- a/src/Server/Transport/Http/OAuth/SecureUrl.php +++ b/src/Server/Transport/Http/OAuth/SecureUrl.php @@ -11,23 +11,17 @@ namespace Mcp\Server\Transport\Http\OAuth; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException as SchemaInvalidArgumentException; +use Mcp\Schema\SecureUrl as SchemaSecureUrl; +use Mcp\Server\Exception\InvalidArgumentException; /** - * Parses an absolute URL that must use https, accepting plain http for loopback hosts only. - * - * Loopback hosts are `localhost`, names under the `.localhost` TLD (RFC 6761, section 6.3), - * `127.0.0.0/8` and `::1`. - * * @internal * * @author Christopher Hertel */ final class SecureUrl { - /** @var list */ - private const PRIVATE_IPV4 = [['10.0.0.0', 8], ['172.16.0.0', 12], ['192.168.0.0', 16], ['169.254.0.0', 16], ['100.64.0.0', 10]]; - /** * @return array{scheme: string, host: string, port?: int, path?: string, query?: string, fragment?: string} * @@ -35,143 +29,10 @@ final class SecureUrl */ public static function parse(mixed $url, string $label): array { - // parse_url() reads a host differently than browsers do around a backslash, and turns control characters into underscores. - $parts = \is_string($url) && 1 !== preg_match('/[\x00-\x20\x7f\\\\]/', $url) ? parse_url($url) : false; - - if (false === $parts || !isset($parts['scheme'], $parts['host'])) { - throw new InvalidArgumentException(\sprintf('The %s must be an absolute URL.', $label)); - } - - // Browsers and IDNA decode these into another host, e.g. "%31%32%37.1" or "127.0.0.1" into a loopback address. - if (1 === preg_match('/[%\x80-\xff]/', $parts['host'])) { - throw new InvalidArgumentException(\sprintf('The %s "%s" must write its host in ASCII without percent-encoding, an internationalized name in punycode.', $label, $url)); - } - - $scheme = strtolower($parts['scheme']); - if ('https' !== $scheme && ('http' !== $scheme || !self::isLoopbackHost($parts['host']))) { - throw new InvalidArgumentException(\sprintf('The %s "%s" must use https; plain http is only accepted for loopback hosts.', $label, $url)); - } - - if (self::hidesItsAddress($parts['host'])) { - throw new InvalidArgumentException(\sprintf('The %s "%s" must use a host name or an IP address in standard form; unspecified addresses and IPv4 within IPv6 are refused.', $label, $url)); - } - - return $parts; - } - - /** - * Whether a URL points at the machine it is requested from, on any scheme. - */ - public static function isLoopback(string $url): bool - { - $host = parse_url($url, \PHP_URL_HOST); - - return \is_string($host) && self::isLoopbackHost($host); - } - - /** - * Whether a URL names an address of a private or link-local network as an IP literal; a name is not resolved. - */ - public static function isPrivateNetwork(string $url): bool - { - $host = parse_url($url, \PHP_URL_HOST); - $host = \is_string($host) ? trim($host, '[]') : ''; - - if (false === filter_var($host, \FILTER_VALIDATE_IP)) { - return false; + try { + return SchemaSecureUrl::parse($url, $label); + } catch (SchemaInvalidArgumentException $e) { + throw new InvalidArgumentException($e->getMessage(), 0, $e); } - - $address = (string) inet_pton($host); - - if (4 === \strlen($address)) { - return self::isWithin($address, self::PRIVATE_IPV4); - } - - if (self::isWithin($address, [['64:ff9b:1::', 48]])) { - return true; - } - - // NAT64 (RFC 6052) and 6to4 (RFC 3056) addresses reach the IPv4 address they carry, loopback included. - $embedded = match (true) { - self::isWithin($address, [['64:ff9b::', 96]]) => substr($address, 12), - self::isWithin($address, [['2002::', 16]]) => substr($address, 2, 4), - default => null, - }; - - if (null !== $embedded) { - return self::isWithin($embedded, [...self::PRIVATE_IPV4, ['127.0.0.0', 8], ['0.0.0.0', 8]]); - } - - return self::isWithin($address, [['fc00::', 7], ['fe80::', 10], ['fec0::', 10]]); - } - - /** - * @param list $ranges - */ - private static function isWithin(string $address, array $ranges): bool - { - foreach ($ranges as [$network, $bits]) { - $prefix = (string) inet_pton($network); - - if (\strlen($prefix) !== \strlen($address)) { - continue; - } - - $bytes = intdiv($bits, 8); - $mask = 0xFF << (8 - $bits % 8) & 0xFF; - - if (0 === substr_compare($address, $prefix, 0, $bytes) && (0 === $bits % 8 || (\ord($address[$bytes]) & $mask) === \ord($prefix[$bytes]))) { - return true; - } - } - - return false; - } - - // Each of these can reach this machine or a private network without looking like it. - private static function hidesItsAddress(string $host): bool - { - $host = self::normalizeHost($host); - - if (false !== filter_var($host, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) { - return '0.0.0.0' === $host; - } - - if (false !== filter_var($host, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) { - $bytes = (string) inet_pton($host); - - return '::1' !== $host && str_starts_with($bytes, str_repeat("\0", 10)) && \in_array(substr($bytes, 10, 2), ["\0\0", "\xff\xff"], true); - } - - return 1 === preg_match('/^(?:0x[0-9a-f]*|[0-9]+)(?:\.(?:0x[0-9a-f]*|[0-9]+)){0,3}\.?$/', $host); - } - - private static function isLoopbackHost(string $host): bool - { - $host = self::normalizeHost($host); - if ('::1' === $host) { - return true; - } - - if (false !== filter_var($host, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) { - return str_starts_with($host, '127.'); - } - - if (str_ends_with($host, '.')) { - $host = substr($host, 0, -1); - } - - return 1 === preg_match('/^(?:[a-z0-9_-]+\.)*localhost$/', $host); - } - - private static function normalizeHost(string $host): string - { - $host = strtolower(trim($host, '[]')); - - if (false !== filter_var($host, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) { - return (string) inet_ntop((string) inet_pton($host)); - } - - return $host; } } diff --git a/src/Server/Transport/StatelessAwareTransportInterface.php b/src/Server/Transport/StatelessAwareTransportInterface.php index 966ca13d7..01586a59c 100644 --- a/src/Server/Transport/StatelessAwareTransportInterface.php +++ b/src/Server/Transport/StatelessAwareTransportInterface.php @@ -18,7 +18,7 @@ * A transport that can carry the modern (SEP-2575) lifecycle as well as the * handshake one. * - * {@see \Mcp\Server::run()} hands such a transport both dispatchers; deciding + * {@see \Mcp\Server\Server::run()} hands such a transport both dispatchers; deciding * which of them answers is the transport's job, because the evidence is in the * request it just read. * diff --git a/src/Server/Transport/StdioTransport.php b/src/Server/Transport/StdioTransport.php index 275cdb834..e556cc73d 100644 --- a/src/Server/Transport/StdioTransport.php +++ b/src/Server/Transport/StdioTransport.php @@ -11,13 +11,13 @@ namespace Mcp\Server\Transport; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\InvalidInputMessageException; -use Mcp\JsonRpc\MessageFactory; use Mcp\Schema\Enum\ProtocolVersion; +use Mcp\Schema\Exception\InvalidInputMessageException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\MessageInterface; +use Mcp\Schema\MessageFactory; use Mcp\Schema\Notification\CancelledNotification; +use Mcp\Server\Exception\InvalidArgumentException; use Mcp\Server\Stateless\StatelessProtocol; use Mcp\Server\Stateless\StatelessResult; use Mcp\Server\Transport\Stdio\RunnerControl; diff --git a/src/Server/Transport/StreamableHttpTransport.php b/src/Server/Transport/StreamableHttpTransport.php index cfc37bf02..2f94f142b 100644 --- a/src/Server/Transport/StreamableHttpTransport.php +++ b/src/Server/Transport/StreamableHttpTransport.php @@ -12,11 +12,11 @@ namespace Mcp\Server\Transport; use Http\Discovery\Psr17FactoryDiscovery; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\SessionStoreException; use Mcp\Schema\Enum\ProtocolVersion; use Mcp\Schema\JsonRpc\Error; use Mcp\Server\Authorization\AccessToken; +use Mcp\Server\Exception\InvalidArgumentException; +use Mcp\Server\Exception\SessionStoreException; use Mcp\Server\Stateless\StatelessProtocol; use Mcp\Server\Transport\Http\Middleware\CorsMiddleware; use Mcp\Server\Transport\Http\Middleware\DnsRebindingProtectionMiddleware; diff --git a/src/Server/Transport/TransportInterface.php b/src/Server/Transport/TransportInterface.php index 3f1f231b4..76f0431e4 100644 --- a/src/Server/Transport/TransportInterface.php +++ b/src/Server/Transport/TransportInterface.php @@ -83,7 +83,7 @@ public function onMessage(callable $listener): void; * * The transport calls this when a client disconnects or explicitly ends their session. * The principal identifies who ended it, if the transport authenticates requests. - * The listener throws a {@see \Mcp\Exception\SessionStoreException} when it cannot tell who opened the session. + * The listener throws a {@see \Mcp\Server\Exception\SessionStoreException} when it cannot tell who opened the session. * * @param callable(Uuid $sessionId, ?string $principal): bool $listener The callback function to execute when destroying a session, returning false when the session does not exist */ diff --git a/src/Server/Wire/CachePolicy.php b/src/Server/Wire/CachePolicy.php index e22fb2129..a74e393b0 100644 --- a/src/Server/Wire/CachePolicy.php +++ b/src/Server/Wire/CachePolicy.php @@ -11,8 +11,8 @@ namespace Mcp\Server\Wire; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Enum\CacheScope; +use Mcp\Server\Exception\InvalidArgumentException; /** * How long, and to whom, a server's answers may be cached (SEP-2549). diff --git a/src/Server/Wire/InboundClassifier.php b/src/Server/Wire/InboundClassifier.php index 19cf21b9b..3482220d7 100644 --- a/src/Server/Wire/InboundClassifier.php +++ b/src/Server/Wire/InboundClassifier.php @@ -13,7 +13,8 @@ use Mcp\Schema\Enum\ProtocolVersion; use Mcp\Schema\JsonRpc\Error; -use Mcp\Server\Stateless\RequestMeta; +use Mcp\Schema\RequestMeta; +use Mcp\Schema\Wire\McpHeader; /** * Decides which protocol era one inbound HTTP request belongs to. @@ -78,7 +79,7 @@ public function classify(string $httpMethod, ?string $body, array $headers = []) } /* @var array $decoded */ - return $this->classifyMessage($decoded, self::header($headers, self::PROTOCOL_VERSION_HEADER)); + return $this->classifyMessage($decoded, McpHeader::lookup($headers, self::PROTOCOL_VERSION_HEADER)); } /** @@ -98,22 +99,6 @@ public static function crossCheckVersion(?string $headerVersion, string $claimed return \sprintf('MCP-Protocol-Version header "%s" contradicts the "%s" declared in _meta.', $headerVersion, $claimedVersion); } - /** - * Case-insensitive header lookup, since PSR-7 preserves the sender's casing. - * - * @param array $headers - */ - public static function header(array $headers, string $name): ?string - { - foreach ($headers as $key => $value) { - if (0 === strcasecmp($key, $name)) { - return '' === $value ? null : $value; - } - } - - return null; - } - /** * @param array $message */ diff --git a/src/Server/Wire/Rev2026Codec.php b/src/Server/Wire/Rev2026Codec.php index 32db243d3..76305108b 100644 --- a/src/Server/Wire/Rev2026Codec.php +++ b/src/Server/Wire/Rev2026Codec.php @@ -14,7 +14,7 @@ use Mcp\Schema\Enum\CacheScope; use Mcp\Schema\Enum\ResultType; use Mcp\Schema\Implementation; -use Mcp\Server\Stateless\RequestMeta; +use Mcp\Schema\RequestMeta; /** * The wire codec for 2026-07-28: stamps `resultType`, then the SEP-2549 caching diff --git a/tests/Conformance/client.php b/tests/Conformance/client.php index c9ae646ad..24d4f4343 100644 --- a/tests/Conformance/client.php +++ b/tests/Conformance/client.php @@ -13,15 +13,14 @@ use Http\Discovery\Psr17FactoryDiscovery; use Http\Discovery\Psr18ClientDiscovery; -use Mcp\Client; use Mcp\Client\Auth\AuthenticatorInterface; use Mcp\Client\Auth\CrossAppAccess; use Mcp\Client\Auth\HeadlessAuthorizationHandler; use Mcp\Client\Auth\MetadataDiscovery; use Mcp\Client\Auth\OAuth; +use Mcp\Client\Client; use Mcp\Client\Handler\Request\RequestHandlerInterface; use Mcp\Client\Transport\HttpTransport; -use Mcp\Exception\RuntimeException; use Mcp\Schema\ClientCapabilities; use Mcp\Schema\Enum\ElicitAction; use Mcp\Schema\Enum\ProtocolVersion; @@ -29,6 +28,7 @@ use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\ElicitRequest; use Mcp\Schema\Result\ElicitResult; +use Mcp\Server\Exception\RuntimeException; use Mcp\Tests\Conformance\FileLogger; $url = $argv[1] ?? null; diff --git a/tests/Conformance/server.php b/tests/Conformance/server.php index b233d49b1..f1556e515 100644 --- a/tests/Conformance/server.php +++ b/tests/Conformance/server.php @@ -26,8 +26,6 @@ use Http\Discovery\Psr17Factory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; -use Mcp\Capability\Registry; -use Mcp\Exception\MissingRequiredClientCapabilityException; use Mcp\Schema\ClientCapabilities; use Mcp\Schema\Content\AudioContent; use Mcp\Schema\Content\EmbeddedResource; @@ -41,7 +39,9 @@ use Mcp\Schema\Result\CallToolResult; use Mcp\Schema\Result\InputRequiredResult; use Mcp\Schema\Tool; -use Mcp\Server; +use Mcp\Server\Capability\Registry; +use Mcp\Server\Exception\MissingRequiredClientCapabilityException; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; use Mcp\Server\Subscription\Psr16NotificationBus; use Mcp\Server\Subscription\PublishingEventDispatcher; diff --git a/tests/E2E/BrowserAuthorizationHandler.php b/tests/E2E/BrowserAuthorizationHandler.php index ae4f7154b..2e3ff0f2d 100644 --- a/tests/E2E/BrowserAuthorizationHandler.php +++ b/tests/E2E/BrowserAuthorizationHandler.php @@ -12,7 +12,7 @@ namespace Mcp\Tests\E2E; use Mcp\Client\Auth\AuthorizationHandlerInterface; -use Mcp\Exception\AuthorizationException; +use Mcp\Client\Exception\AuthorizationException; use Symfony\Component\HttpClient\HttpClient; use Symfony\Contracts\HttpClient\HttpClientInterface; diff --git a/tests/E2E/KeycloakAdmin.php b/tests/E2E/KeycloakAdmin.php index b3d2c17e0..4c8b9cfba 100644 --- a/tests/E2E/KeycloakAdmin.php +++ b/tests/E2E/KeycloakAdmin.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\E2E; -use Mcp\Exception\RuntimeException; +use Mcp\Server\Exception\RuntimeException; use Symfony\Component\HttpClient\HttpClient; use Symfony\Contracts\HttpClient\HttpClientInterface; diff --git a/tests/E2E/client.php b/tests/E2E/client.php index 127e439f1..c80415e35 100644 --- a/tests/E2E/client.php +++ b/tests/E2E/client.php @@ -27,13 +27,13 @@ require_once dirname(__DIR__, 2).'/vendor/autoload.php'; -use Mcp\Client; use Mcp\Client\Auth\FileCredentialStorage; use Mcp\Client\Auth\OAuth; +use Mcp\Client\Client; +use Mcp\Client\Exception\AuthorizationException; +use Mcp\Client\Exception\ConnectionException; use Mcp\Client\Transport\HttpTransport; -use Mcp\Exception\AuthorizationException; -use Mcp\Exception\ConnectionException; -use Mcp\Exception\RuntimeException; +use Mcp\Server\Exception\RuntimeException; use Mcp\Tests\E2E\BrowserAuthorizationHandler; use Mcp\Tests\E2E\KeycloakAdmin; diff --git a/tests/E2E/server.php b/tests/E2E/server.php index 63491e8eb..7a0f5dfef 100644 --- a/tests/E2E/server.php +++ b/tests/E2E/server.php @@ -22,7 +22,7 @@ use Firebase\JWT\JWK; use Http\Discovery\Psr17Factory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; use Mcp\Server\Transport\Http\Middleware\AuthorizationMiddleware; use Mcp\Server\Transport\Http\Middleware\ProtectedResourceMetadataMiddleware; diff --git a/tests/Integration/CancellationTest.php b/tests/Integration/CancellationTest.php index 2cb3b9687..7aaa4ea26 100644 --- a/tests/Integration/CancellationTest.php +++ b/tests/Integration/CancellationTest.php @@ -12,8 +12,8 @@ namespace Mcp\Tests\Integration; use Mcp\Client\CancellationTokenInterface; -use Mcp\Exception\RequestCancelledException; -use Mcp\Exception\TimeoutException; +use Mcp\Client\Exception\RequestCancelledException; +use Mcp\Client\Exception\TimeoutException; use PHPUnit\Framework\Attributes\TestDox; final class CancellationTest extends IntegrationTestCase diff --git a/tests/Integration/ClientOAuthTest.php b/tests/Integration/ClientOAuthTest.php index f77fdac4c..82f378ab3 100644 --- a/tests/Integration/ClientOAuthTest.php +++ b/tests/Integration/ClientOAuthTest.php @@ -11,16 +11,16 @@ namespace Mcp\Tests\Integration; -use Mcp\Client; use Mcp\Client\Auth\FileCredentialStorage; use Mcp\Client\Auth\HeadlessAuthorizationHandler; use Mcp\Client\Auth\InMemoryCredentialStorage; use Mcp\Client\Auth\OAuth; use Mcp\Client\Auth\RedirectAuthorizationHandler; +use Mcp\Client\Client; +use Mcp\Client\Exception\AuthorizationException; +use Mcp\Client\Exception\AuthorizationPendingException; +use Mcp\Client\Exception\ConnectionException; use Mcp\Client\Transport\HttpTransport; -use Mcp\Exception\AuthorizationException; -use Mcp\Exception\AuthorizationPendingException; -use Mcp\Exception\ConnectionException; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\TestCase; use Symfony\Component\Process\Process; diff --git a/tests/Integration/DeadServerTest.php b/tests/Integration/DeadServerTest.php index 54f98916a..f2d5044ae 100644 --- a/tests/Integration/DeadServerTest.php +++ b/tests/Integration/DeadServerTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Integration; -use Mcp\Exception\ConnectionException; -use Mcp\Exception\ExceptionInterface; +use Mcp\Client\Exception\ConnectionException; +use Mcp\Client\Exception\ExceptionInterface; use Mcp\Schema\Enum\ProtocolVersion; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; diff --git a/tests/Integration/DualEraExampleTestCase.php b/tests/Integration/DualEraExampleTestCase.php index 002cd6225..9c8deb7ae 100644 --- a/tests/Integration/DualEraExampleTestCase.php +++ b/tests/Integration/DualEraExampleTestCase.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Integration; -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Handler\Request\RequestHandlerInterface; use Mcp\Client\Transport\HttpTransport; use Mcp\Schema\ClientCapabilities; diff --git a/tests/Integration/ElicitationTest.php b/tests/Integration/ElicitationTest.php index b679068e4..bbedff8d5 100644 --- a/tests/Integration/ElicitationTest.php +++ b/tests/Integration/ElicitationTest.php @@ -12,9 +12,9 @@ namespace Mcp\Tests\Integration; use Mcp\Client\Builder as ClientBuilder; +use Mcp\Client\Exception\RuntimeException; use Mcp\Client\Handler\Request\ElicitationCallbackInterface; use Mcp\Client\Handler\Request\ElicitationRequestHandler; -use Mcp\Exception\RuntimeException; use Mcp\Schema\ClientCapabilities; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Enum\ElicitAction; diff --git a/tests/Integration/Fixture/Completion/BookingElements.php b/tests/Integration/Fixture/Completion/BookingElements.php index 2a64e5d40..cc0ac622e 100644 --- a/tests/Integration/Fixture/Completion/BookingElements.php +++ b/tests/Integration/Fixture/Completion/BookingElements.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Integration\Fixture\Completion; -use Mcp\Capability\Attribute\CompletionProvider; -use Mcp\Capability\Attribute\McpPrompt; +use Mcp\Server\Capability\Attribute\CompletionProvider; +use Mcp\Server\Capability\Attribute\McpPrompt; /** * @author Christopher Hertel diff --git a/tests/Integration/Fixture/Completion/SeatCompletionProvider.php b/tests/Integration/Fixture/Completion/SeatCompletionProvider.php index a749fcf7b..c118134d5 100644 --- a/tests/Integration/Fixture/Completion/SeatCompletionProvider.php +++ b/tests/Integration/Fixture/Completion/SeatCompletionProvider.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Integration\Fixture\Completion; -use Mcp\Capability\Completion\ProviderInterface; +use Mcp\Server\Capability\Completion\ProviderInterface; /** * A provider that cannot be built without its seat map. diff --git a/tests/Integration/Fixture/completion.php b/tests/Integration/Fixture/completion.php index f33e95111..c076b5fb5 100644 --- a/tests/Integration/Fixture/completion.php +++ b/tests/Integration/Fixture/completion.php @@ -13,8 +13,8 @@ * Server for {@see \Mcp\Tests\Integration\CompletionTest}. */ -use Mcp\Capability\Registry\Container; -use Mcp\Server; +use Mcp\Server\Capability\Registry\Container; +use Mcp\Server\Server; use Mcp\Server\Transport\StdioTransport; use Mcp\Tests\Integration\Fixture\Completion\SeatCompletionProvider; diff --git a/tests/Integration/Fixture/dead_server.php b/tests/Integration/Fixture/dead_server.php index fcb9f0d50..e0ba4a3dd 100644 --- a/tests/Integration/Fixture/dead_server.php +++ b/tests/Integration/Fixture/dead_server.php @@ -13,7 +13,7 @@ * Server for {@see \Mcp\Tests\Integration\DeadServerTest}. */ -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Transport\StdioTransport; require_once dirname(__DIR__, 3).'/vendor/autoload.php'; diff --git a/tests/Integration/Fixture/elicitation.php b/tests/Integration/Fixture/elicitation.php index ad588a94d..411683b87 100644 --- a/tests/Integration/Fixture/elicitation.php +++ b/tests/Integration/Fixture/elicitation.php @@ -13,11 +13,11 @@ * Server for {@see \Mcp\Tests\Integration\ElicitationTest}. */ -use Mcp\Exception\ClientException; use Mcp\Schema\Elicitation\ElicitationSchema; use Mcp\Schema\Elicitation\StringSchemaDefinition; -use Mcp\Server; +use Mcp\Server\Exception\ClientException; use Mcp\Server\RequestContext; +use Mcp\Server\Server; use Mcp\Server\Transport\StdioTransport; require_once dirname(__DIR__, 3).'/vendor/autoload.php'; diff --git a/tests/Integration/Fixture/handshake.php b/tests/Integration/Fixture/handshake.php index 0760289b9..3cf90e192 100644 --- a/tests/Integration/Fixture/handshake.php +++ b/tests/Integration/Fixture/handshake.php @@ -17,7 +17,7 @@ */ use Mcp\Schema\Enum\ProtocolVersion; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Transport\StdioTransport; require_once dirname(__DIR__, 3).'/vendor/autoload.php'; diff --git a/tests/Integration/Fixture/http.php b/tests/Integration/Fixture/http.php index 4871f3903..b2c645c4c 100644 --- a/tests/Integration/Fixture/http.php +++ b/tests/Integration/Fixture/http.php @@ -13,7 +13,7 @@ use Http\Discovery\Psr17Factory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; use Mcp\Server\Transport\StatelessHttpTransport; use Mcp\Server\Transport\StreamableHttpTransport; diff --git a/tests/Integration/Fixture/int_arguments.php b/tests/Integration/Fixture/int_arguments.php index d90704cf9..a772cca58 100644 --- a/tests/Integration/Fixture/int_arguments.php +++ b/tests/Integration/Fixture/int_arguments.php @@ -9,8 +9,8 @@ * file that was distributed with this source code. */ -use Mcp\Capability\Attribute\Schema; -use Mcp\Server; +use Mcp\Server\Capability\Attribute\Schema; +use Mcp\Server\Server; use Mcp\Server\Transport\StdioTransport; use Mcp\Tests\Unit\Fixtures\Enum\BackedIntEnum; diff --git a/tests/Integration/Fixture/notification.php b/tests/Integration/Fixture/notification.php index 166e84c6b..c2c5c503c 100644 --- a/tests/Integration/Fixture/notification.php +++ b/tests/Integration/Fixture/notification.php @@ -14,8 +14,8 @@ */ use Mcp\Schema\Enum\LoggingLevel; -use Mcp\Server; use Mcp\Server\RequestContext; +use Mcp\Server\Server; use Mcp\Server\Transport\StdioTransport; require_once dirname(__DIR__, 3).'/vendor/autoload.php'; diff --git a/tests/Integration/Fixture/oauth/resource-server.php b/tests/Integration/Fixture/oauth/resource-server.php index cfc119a68..a07d4c9ba 100644 --- a/tests/Integration/Fixture/oauth/resource-server.php +++ b/tests/Integration/Fixture/oauth/resource-server.php @@ -22,7 +22,7 @@ use Http\Discovery\Psr17Factory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; use Mcp\Server\Transport\StreamableHttpTransport; diff --git a/tests/Integration/Fixture/request_state.php b/tests/Integration/Fixture/request_state.php index 187a9ec69..976603e94 100644 --- a/tests/Integration/Fixture/request_state.php +++ b/tests/Integration/Fixture/request_state.php @@ -26,9 +26,9 @@ use Mcp\Schema\Request\ElicitRequest; use Mcp\Schema\Result\CallToolResult; use Mcp\Schema\Result\InputRequiredResult; -use Mcp\Server; use Mcp\Server\Authorization\AccessToken; use Mcp\Server\RequestContext; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; use Mcp\Server\Stateless\OriginatingRequestBinder; use Mcp\Server\Transport\Http\Middleware\AuthorizationMiddleware; diff --git a/tests/Integration/Fixture/request_timeout.php b/tests/Integration/Fixture/request_timeout.php index fb3697c6f..55fe6c113 100644 --- a/tests/Integration/Fixture/request_timeout.php +++ b/tests/Integration/Fixture/request_timeout.php @@ -17,7 +17,7 @@ * given up on once. */ -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Transport\StdioTransport; require_once dirname(__DIR__, 3).'/vendor/autoload.php'; diff --git a/tests/Integration/Fixture/retry.php b/tests/Integration/Fixture/retry.php index 9bd25ee32..83f195ef7 100644 --- a/tests/Integration/Fixture/retry.php +++ b/tests/Integration/Fixture/retry.php @@ -17,7 +17,7 @@ * actually started. */ -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Transport\StdioTransport; require_once dirname(__DIR__, 3).'/vendor/autoload.php'; diff --git a/tests/Integration/Fixture/roots.php b/tests/Integration/Fixture/roots.php index 244f9eb8c..0507c7e7a 100644 --- a/tests/Integration/Fixture/roots.php +++ b/tests/Integration/Fixture/roots.php @@ -15,8 +15,8 @@ use Mcp\Schema\Request\ListRootsRequest; use Mcp\Schema\Result\InputRequiredResult; -use Mcp\Server; use Mcp\Server\RequestContext; +use Mcp\Server\Server; use Mcp\Server\Transport\StdioTransport; require_once dirname(__DIR__, 3).'/vendor/autoload.php'; diff --git a/tests/Integration/Fixture/sampling.php b/tests/Integration/Fixture/sampling.php index 59a651c78..80ad8cb6d 100644 --- a/tests/Integration/Fixture/sampling.php +++ b/tests/Integration/Fixture/sampling.php @@ -13,15 +13,15 @@ * Server for {@see \Mcp\Tests\Integration\SamplingTest}. */ -use Mcp\Exception\ClientException; use Mcp\Schema\Content\SamplingMessage; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Enum\Role; use Mcp\Schema\Request\CreateSamplingMessageRequest; use Mcp\Schema\Result\InputRequiredResult; -use Mcp\Server; use Mcp\Server\ClientGateway; +use Mcp\Server\Exception\ClientException; use Mcp\Server\RequestContext; +use Mcp\Server\Server; use Mcp\Server\Transport\StdioTransport; require_once dirname(__DIR__, 3).'/vendor/autoload.php'; diff --git a/tests/Integration/Fixture/sampling_tools.php b/tests/Integration/Fixture/sampling_tools.php index 94cd5612d..102a07e01 100644 --- a/tests/Integration/Fixture/sampling_tools.php +++ b/tests/Integration/Fixture/sampling_tools.php @@ -19,8 +19,8 @@ use Mcp\Schema\Content\ToolUseContent; use Mcp\Schema\Enum\Role; use Mcp\Schema\Tool; -use Mcp\Server; use Mcp\Server\RequestContext; +use Mcp\Server\Server; use Mcp\Server\Transport\StdioTransport; require_once dirname(__DIR__, 3).'/vendor/autoload.php'; diff --git a/tests/Integration/Fixture/structured_null.php b/tests/Integration/Fixture/structured_null.php index ea7bd7d0f..877b5f4f4 100644 --- a/tests/Integration/Fixture/structured_null.php +++ b/tests/Integration/Fixture/structured_null.php @@ -11,7 +11,7 @@ use Mcp\Schema\Content\TextContent; use Mcp\Schema\Result\CallToolResult; -use Mcp\Server; +use Mcp\Server\Server; use Mcp\Server\Transport\StdioTransport; require_once dirname(__DIR__, 3).'/vendor/autoload.php'; diff --git a/tests/Integration/HandshakeTest.php b/tests/Integration/HandshakeTest.php index 9f21dbb31..ff0a72577 100644 --- a/tests/Integration/HandshakeTest.php +++ b/tests/Integration/HandshakeTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Integration; -use Mcp\Exception\ConnectionException; +use Mcp\Client\Exception\ConnectionException; use Mcp\Schema\Enum\ProtocolVersion; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; diff --git a/tests/Integration/HeaderAgreementTest.php b/tests/Integration/HeaderAgreementTest.php new file mode 100644 index 000000000..f4e3389fc --- /dev/null +++ b/tests/Integration/HeaderAgreementTest.php @@ -0,0 +1,58 @@ +}}> + */ + public static function providePayloads(): iterable + { + yield 'a subject' => [['method' => 'tools/call', 'params' => ['name' => 'search', 'arguments' => new \stdClass()]]]; + yield 'a subject that is not header-safe' => [['method' => 'resources/read', 'params' => ['uri' => 'file:///café.txt']]]; + yield 'mirrored arguments' => [['method' => 'tools/call', 'params' => ['name' => 'search', 'arguments' => ['region' => ' padded ', 'priority' => 7]]]]; + } + + /** + * @param array{method: string, params: array} $payload + */ + #[DataProvider('providePayloads')] + public function testServerAcceptsWhatTheClientEmits(array $payload): void + { + $catalog = new ToolCatalog(); + $catalog->record([[ + 'name' => 'search', + 'inputSchema' => [ + 'type' => 'object', + 'properties' => [ + 'region' => ['type' => 'string', 'x-mcp-header' => 'Region'], + 'priority' => ['type' => 'integer', 'x-mcp-header' => 'Priority'], + ], + ], + ]]); + + $headers = (new HeaderFactory($catalog))->forMessage($payload, ProtocolVersion::V2026_07_28); + + $this->assertNull((new StandardHeaderValidator())->validate($payload['method'], $payload['params'], $headers)); + } +} diff --git a/tests/Integration/HttpNegotiationTest.php b/tests/Integration/HttpNegotiationTest.php index 847229e90..88b7d44ff 100644 --- a/tests/Integration/HttpNegotiationTest.php +++ b/tests/Integration/HttpNegotiationTest.php @@ -11,10 +11,10 @@ namespace Mcp\Tests\Integration; -use Mcp\Client; use Mcp\Client\Builder as ClientBuilder; +use Mcp\Client\Client; +use Mcp\Client\Exception\ConnectionException; use Mcp\Client\Transport\HttpTransport; -use Mcp\Exception\ConnectionException; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Enum\ProtocolVersion; use Mcp\Tests\Support\ServerProcess; diff --git a/tests/Integration/HttpRedirectTest.php b/tests/Integration/HttpRedirectTest.php index cfafa52ad..7119425a1 100644 --- a/tests/Integration/HttpRedirectTest.php +++ b/tests/Integration/HttpRedirectTest.php @@ -12,9 +12,9 @@ namespace Mcp\Tests\Integration; use Http\Discovery\Psr18ClientDiscovery; -use Mcp\Client; +use Mcp\Client\Client; +use Mcp\Client\Exception\RequestException; use Mcp\Client\Transport\HttpTransport; -use Mcp\Exception\RequestException; use Mcp\Tests\Support\ServerProcess; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\TestDox; diff --git a/tests/Integration/IntArgumentTest.php b/tests/Integration/IntArgumentTest.php index bd7aa85bf..d38fa73b4 100644 --- a/tests/Integration/IntArgumentTest.php +++ b/tests/Integration/IntArgumentTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Integration; -use Mcp\Client; -use Mcp\Exception\RequestException; +use Mcp\Client\Client; +use Mcp\Client\Exception\RequestException; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Content\TextResourceContents; use Mcp\Schema\Enum\ProtocolVersion; diff --git a/tests/Integration/IntegrationTestCase.php b/tests/Integration/IntegrationTestCase.php index 09ddfcd3f..f74a586e6 100644 --- a/tests/Integration/IntegrationTestCase.php +++ b/tests/Integration/IntegrationTestCase.php @@ -11,10 +11,10 @@ namespace Mcp\Tests\Integration; -use Mcp\Client; use Mcp\Client\Builder as ClientBuilder; +use Mcp\Client\Client; +use Mcp\Client\Exception\ConnectionException; use Mcp\Client\Transport\StdioTransport; -use Mcp\Exception\ConnectionException; use Mcp\Schema\Enum\ProtocolVersion; use PHPUnit\Framework\TestCase; diff --git a/tests/Integration/RequestStateBindingTest.php b/tests/Integration/RequestStateBindingTest.php index d6c6de2e6..68cbd87e8 100644 --- a/tests/Integration/RequestStateBindingTest.php +++ b/tests/Integration/RequestStateBindingTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Integration; -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Handler\Request\RequestHandlerInterface; use Mcp\Client\Transport\StdioTransport; use Mcp\Schema\ClientCapabilities; diff --git a/tests/Integration/RequestStateTestCase.php b/tests/Integration/RequestStateTestCase.php index d4eab4ac2..2ed78a599 100644 --- a/tests/Integration/RequestStateTestCase.php +++ b/tests/Integration/RequestStateTestCase.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Integration; -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Handler\Request\RequestHandlerInterface; use Mcp\Client\Transport\HttpTransport; use Mcp\Schema\ClientCapabilities; diff --git a/tests/Integration/RequestTimeoutTest.php b/tests/Integration/RequestTimeoutTest.php index 21227b141..ff1c73127 100644 --- a/tests/Integration/RequestTimeoutTest.php +++ b/tests/Integration/RequestTimeoutTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Integration; -use Mcp\Exception\RequestException; +use Mcp\Client\Exception\RequestException; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\TestDox; diff --git a/tests/Integration/RetryTest.php b/tests/Integration/RetryTest.php index 7fc974c71..d8bb70c87 100644 --- a/tests/Integration/RetryTest.php +++ b/tests/Integration/RetryTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Integration; -use Mcp\Exception\ConnectionException; +use Mcp\Client\Exception\ConnectionException; use PHPUnit\Framework\Attributes\TestDox; /** diff --git a/tests/Integration/SamplingTest.php b/tests/Integration/SamplingTest.php index 5dc917f85..46f76df68 100644 --- a/tests/Integration/SamplingTest.php +++ b/tests/Integration/SamplingTest.php @@ -12,9 +12,9 @@ namespace Mcp\Tests\Integration; use Mcp\Client\Builder as ClientBuilder; +use Mcp\Client\Exception\RequestException; use Mcp\Client\Handler\Request\SamplingCallbackInterface; use Mcp\Client\Handler\Request\SamplingRequestHandler; -use Mcp\Exception\RequestException; use Mcp\Schema\ClientCapabilities; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Enum\ProtocolVersion; diff --git a/tests/Integration/SessionlessHttpTest.php b/tests/Integration/SessionlessHttpTest.php index bb8164706..8cf2da0a3 100644 --- a/tests/Integration/SessionlessHttpTest.php +++ b/tests/Integration/SessionlessHttpTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Integration; -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Transport\HttpTransport; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Enum\ProtocolVersion; diff --git a/tests/Integration/StatelessClientTest.php b/tests/Integration/StatelessClientTest.php index 3879ee844..75112ce16 100644 --- a/tests/Integration/StatelessClientTest.php +++ b/tests/Integration/StatelessClientTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Integration; -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Handler\Request\RequestHandlerInterface; use Mcp\Client\Transport\HttpTransport; use Mcp\Schema\ClientCapabilities; diff --git a/tests/Interop/Client/EverythingServerTestCase.php b/tests/Interop/Client/EverythingServerTestCase.php index 8cc4d5e1f..3ad404c4b 100644 --- a/tests/Interop/Client/EverythingServerTestCase.php +++ b/tests/Interop/Client/EverythingServerTestCase.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Interop\Client; -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Handler\Request\ElicitationCallbackInterface; use Mcp\Client\Handler\Request\ElicitationRequestHandler; use Mcp\Client\Handler\Request\ListRootsRequestHandler; diff --git a/tests/Interop/Server/Http/HttpReactPhpTest.php b/tests/Interop/Server/Http/HttpReactPhpTest.php index 9e7942209..535678b32 100644 --- a/tests/Interop/Server/Http/HttpReactPhpTest.php +++ b/tests/Interop/Server/Http/HttpReactPhpTest.php @@ -12,7 +12,7 @@ namespace Mcp\Tests\Interop\Server\Http; use Mcp\Schema\Enum\ProtocolVersion; -use Mcp\Server\Stateless\RequestMeta; +use Mcp\Schema\RequestMeta; use PHPUnit\Framework\Attributes\TestDox; final class HttpReactPhpTest extends HttpInspectorSnapshotTestCase diff --git a/tests/Interop/Server/Http/HttpRevoltTest.php b/tests/Interop/Server/Http/HttpRevoltTest.php index 427f1af0c..34f8dad12 100644 --- a/tests/Interop/Server/Http/HttpRevoltTest.php +++ b/tests/Interop/Server/Http/HttpRevoltTest.php @@ -12,7 +12,7 @@ namespace Mcp\Tests\Interop\Server\Http; use Mcp\Schema\Enum\ProtocolVersion; -use Mcp\Server\Stateless\RequestMeta; +use Mcp\Schema\RequestMeta; use PHPUnit\Framework\Attributes\TestDox; final class HttpRevoltTest extends HttpInspectorSnapshotTestCase diff --git a/tests/Unit/Client/Auth/AccessTokenTest.php b/tests/Unit/Client/Auth/AccessTokenTest.php index 412171cd8..ccf91b6f1 100644 --- a/tests/Unit/Client/Auth/AccessTokenTest.php +++ b/tests/Unit/Client/Auth/AccessTokenTest.php @@ -12,7 +12,7 @@ namespace Mcp\Tests\Unit\Client\Auth; use Mcp\Client\Auth\AccessToken; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Client\Exception\InvalidArgumentException; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Client/Auth/AuthenticatingHttpClientTest.php b/tests/Unit/Client/Auth/AuthenticatingHttpClientTest.php index 25a0d9f1a..6c46abb8d 100644 --- a/tests/Unit/Client/Auth/AuthenticatingHttpClientTest.php +++ b/tests/Unit/Client/Auth/AuthenticatingHttpClientTest.php @@ -14,8 +14,8 @@ use Mcp\Client\Auth\AuthenticatingHttpClient; use Mcp\Client\Auth\AuthenticatorInterface; use Mcp\Client\Auth\BearerToken; -use Mcp\Exception\AuthorizationException; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Client\Exception\AuthorizationException; +use Mcp\Client\Exception\InvalidArgumentException; use Nyholm\Psr7\Factory\Psr17Factory; use Nyholm\Psr7\Response; use PHPUnit\Framework\Attributes\TestDox; diff --git a/tests/Unit/Client/Auth/AuthorizationHandlerTest.php b/tests/Unit/Client/Auth/AuthorizationHandlerTest.php index 560e13697..983a793f8 100644 --- a/tests/Unit/Client/Auth/AuthorizationHandlerTest.php +++ b/tests/Unit/Client/Auth/AuthorizationHandlerTest.php @@ -14,7 +14,7 @@ use Mcp\Client\Auth\ConsoleAuthorizationHandler; use Mcp\Client\Auth\HeadlessAuthorizationHandler; use Mcp\Client\Auth\LoopbackAuthorizationHandler; -use Mcp\Exception\AuthorizationException; +use Mcp\Client\Exception\AuthorizationException; use Nyholm\Psr7\Response; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\Attributes\TestWith; diff --git a/tests/Unit/Client/Auth/AuthorizationServerMetadataTest.php b/tests/Unit/Client/Auth/AuthorizationServerMetadataTest.php index dfd14a191..ac777a22c 100644 --- a/tests/Unit/Client/Auth/AuthorizationServerMetadataTest.php +++ b/tests/Unit/Client/Auth/AuthorizationServerMetadataTest.php @@ -12,7 +12,7 @@ namespace Mcp\Tests\Unit\Client\Auth; use Mcp\Client\Auth\AuthorizationServerMetadata; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Client\Exception\InvalidArgumentException; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\Attributes\TestWith; diff --git a/tests/Unit/Client/Auth/ClientRegistrationTest.php b/tests/Unit/Client/Auth/ClientRegistrationTest.php index 06cca8713..bb5bee67e 100644 --- a/tests/Unit/Client/Auth/ClientRegistrationTest.php +++ b/tests/Unit/Client/Auth/ClientRegistrationTest.php @@ -16,8 +16,8 @@ use Mcp\Client\Auth\ClientRegistrar; use Mcp\Client\Auth\ClientRegistration; use Mcp\Client\Auth\TokenEndpointAuthMethod; -use Mcp\Exception\AuthorizationException; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Client\Exception\AuthorizationException; +use Mcp\Client\Exception\InvalidArgumentException; use Nyholm\Psr7\Factory\Psr17Factory; use Nyholm\Psr7\Response; use PHPUnit\Framework\Attributes\TestDox; diff --git a/tests/Unit/Client/Auth/MetadataDiscoveryTest.php b/tests/Unit/Client/Auth/MetadataDiscoveryTest.php index 1781a5781..fbe3b4738 100644 --- a/tests/Unit/Client/Auth/MetadataDiscoveryTest.php +++ b/tests/Unit/Client/Auth/MetadataDiscoveryTest.php @@ -12,7 +12,7 @@ namespace Mcp\Tests\Unit\Client\Auth; use Mcp\Client\Auth\MetadataDiscovery; -use Mcp\Exception\AuthorizationException; +use Mcp\Client\Exception\AuthorizationException; use Nyholm\Psr7\Factory\Psr17Factory; use Nyholm\Psr7\Response; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/tests/Unit/Client/Auth/OAuthAuthenticatorTest.php b/tests/Unit/Client/Auth/OAuthAuthenticatorTest.php index 1043f1d2c..f13887890 100644 --- a/tests/Unit/Client/Auth/OAuthAuthenticatorTest.php +++ b/tests/Unit/Client/Auth/OAuthAuthenticatorTest.php @@ -28,10 +28,10 @@ use Mcp\Client\Auth\RedirectAuthorizationHandler; use Mcp\Client\Auth\TokenEndpoint; use Mcp\Client\Auth\TokenEndpointAuthMethod; -use Mcp\Exception\AuthorizationException; -use Mcp\Exception\AuthorizationPendingException; -use Mcp\Exception\OAuthErrorException; -use Mcp\Exception\RuntimeException; +use Mcp\Client\Exception\AuthorizationException; +use Mcp\Client\Exception\AuthorizationPendingException; +use Mcp\Client\Exception\OAuthErrorException; +use Mcp\Client\Exception\RuntimeException; use Nyholm\Psr7\Factory\Psr17Factory; use Nyholm\Psr7\Response; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/tests/Unit/Client/Auth/OAuthTest.php b/tests/Unit/Client/Auth/OAuthTest.php index dcd64dab5..f4220e4be 100644 --- a/tests/Unit/Client/Auth/OAuthTest.php +++ b/tests/Unit/Client/Auth/OAuthTest.php @@ -21,8 +21,8 @@ use Mcp\Client\Auth\OAuthConfiguration; use Mcp\Client\Auth\RedirectAuthorizationHandler; use Mcp\Client\Auth\TokenEndpointAuthMethod; -use Mcp\Exception\AuthorizationException; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Client\Exception\AuthorizationException; +use Mcp\Client\Exception\InvalidArgumentException; use Nyholm\Psr7\Factory\Psr17Factory; use Nyholm\Psr7\Response; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/tests/Unit/Client/Auth/ProtectedResourceMetadataTest.php b/tests/Unit/Client/Auth/ProtectedResourceMetadataTest.php index 280130f64..e01415596 100644 --- a/tests/Unit/Client/Auth/ProtectedResourceMetadataTest.php +++ b/tests/Unit/Client/Auth/ProtectedResourceMetadataTest.php @@ -12,7 +12,7 @@ namespace Mcp\Tests\Unit\Client\Auth; use Mcp\Client\Auth\ProtectedResourceMetadata; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Client\Exception\InvalidArgumentException; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Client/Auth/ResponseBodyTest.php b/tests/Unit/Client/Auth/ResponseBodyTest.php index 76d8f0e47..c90dd5083 100644 --- a/tests/Unit/Client/Auth/ResponseBodyTest.php +++ b/tests/Unit/Client/Auth/ResponseBodyTest.php @@ -19,7 +19,7 @@ use Mcp\Client\Auth\ResponseBody; use Mcp\Client\Auth\TokenEndpoint; use Mcp\Client\Auth\TokenEndpointAuthMethod; -use Mcp\Exception\AuthorizationException; +use Mcp\Client\Exception\AuthorizationException; use Nyholm\Psr7\Factory\Psr17Factory; use Nyholm\Psr7\Response; use PHPUnit\Framework\Attributes\TestDox; diff --git a/tests/Unit/Client/Auth/TokenEndpointTest.php b/tests/Unit/Client/Auth/TokenEndpointTest.php index 87bb68dcf..0ce60eeb1 100644 --- a/tests/Unit/Client/Auth/TokenEndpointTest.php +++ b/tests/Unit/Client/Auth/TokenEndpointTest.php @@ -17,7 +17,7 @@ use Mcp\Client\Auth\ClientRegistration; use Mcp\Client\Auth\TokenEndpoint; use Mcp\Client\Auth\TokenEndpointAuthMethod; -use Mcp\Exception\AuthorizationException; +use Mcp\Client\Exception\AuthorizationException; use Nyholm\Psr7\Factory\Psr17Factory; use Nyholm\Psr7\Response; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/tests/Unit/Client/BuilderTest.php b/tests/Unit/Client/BuilderTest.php index b462b9bb6..682e6a586 100644 --- a/tests/Unit/Client/BuilderTest.php +++ b/tests/Unit/Client/BuilderTest.php @@ -11,9 +11,9 @@ namespace Mcp\Tests\Unit\Client; -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Configuration; -use Mcp\Exception\LogicException; +use Mcp\Client\Exception\LogicException; use Mcp\Schema\ClientCapabilities; use Mcp\Schema\Extension\Apps\McpApps; use PHPUnit\Framework\Attributes\TestDox; diff --git a/tests/Unit/Client/ClientTest.php b/tests/Unit/Client/ClientTest.php index 3c6da9a2a..96b669d55 100644 --- a/tests/Unit/Client/ClientTest.php +++ b/tests/Unit/Client/ClientTest.php @@ -11,12 +11,21 @@ namespace Mcp\Tests\Unit\Client; -use Mcp\Client; +use Mcp\Client\Builder; +use Mcp\Client\Client; +use Mcp\Client\Exception\ConnectionException; +use Mcp\Client\Exception\InvalidArgumentException; +use Mcp\Client\Exception\RuntimeException; use Mcp\Client\State\ClientStateInterface; +use Mcp\Client\Transport\BaseTransport; use Mcp\Client\Transport\TransportInterface; -use Mcp\Exception\ConnectionException; -use Mcp\Exception\RuntimeException; use Mcp\Schema\ClientCapabilities; +use Mcp\Schema\Enum\LoggingLevel; +use Mcp\Schema\Enum\ProtocolVersion; +use Mcp\Schema\Exception\InvalidArgumentException as SchemaInvalidArgumentException; +use Mcp\Schema\JsonRpc\Error; +use Mcp\Schema\JsonRpc\Response; +use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\TestCase; final class ClientTest extends TestCase @@ -44,6 +53,169 @@ public function testReconnectClosesPreviousTransport(): void $client->disconnect(); } + #[TestDox('builder() returns a Builder instance')] + public function testBuilderReturnsBuilderInstance(): void + { + $this->assertInstanceOf(Builder::class, Client::builder()); + } + + #[TestDox('readResource() refuses an empty URI before it reaches the wire')] + public function testReadResourceRejectsAnEmptyUri(): void + { + $client = Client::builder()->build(); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Resource URI must not be empty.'); + + $client->readResource(''); + } + + #[TestDox('connect() succeeds on the first attempt without retrying')] + public function testConnectSucceedsWithoutRetrying(): void + { + $transport = new FakeTransport([FakeTransport::ACCEPT]); + + $client = Client::builder()->build(); + $client->connect($transport); + + $this->assertSame(1, $transport->connectCalls); + $this->assertSame(0, $transport->closeCalls); + $this->assertTrue($client->isConnected()); + } + + #[TestDox('setting the log level after disconnecting a modern connection fails like any other call')] + public function testSetLoggingLevelRequiresAConnection(): void + { + $client = Client::builder()->setProtocolVersion(ProtocolVersion::V2026_07_28)->build(); + $client->connect(new FakeTransport([FakeTransport::ACCEPT_MODERN])); + $this->assertSame(ProtocolVersion::V2026_07_28, $client->getProtocolVersion()); + $client->disconnect(); + + $this->expectException(ConnectionException::class); + + $client->setLoggingLevel(LoggingLevel::Info); + } + + #[TestDox('connect() retries a failed attempt and succeeds on a later one')] + public function testConnectRetriesUntilItSucceeds(): void + { + $transport = new FakeTransport([FakeTransport::REJECT, FakeTransport::REJECT, FakeTransport::ACCEPT]); + + $client = Client::builder()->setMaxRetries(3)->build(); + $client->connect($transport); + + $this->assertSame(3, $transport->connectCalls); + $this->assertTrue($client->isConnected()); + $this->assertSame('Test Server', $client->getServerInfo()?->name); + } + + #[TestDox('connect() closes the transport between two attempts')] + public function testConnectClosesTransportBetweenAttempts(): void + { + $transport = new FakeTransport([FakeTransport::REJECT, FakeTransport::ACCEPT]); + + $client = Client::builder()->setMaxRetries(1)->build(); + $client->connect($transport); + + $this->assertSame(2, $transport->connectCalls); + $this->assertSame(1, $transport->closeCalls, 'the failed attempt must be cleaned up before the retry'); + } + + #[TestDox('connect() rethrows once the retries are exhausted')] + public function testConnectThrowsWhenRetriesAreExhausted(): void + { + $transport = new FakeTransport([FakeTransport::REJECT, FakeTransport::REJECT, FakeTransport::REJECT]); + + $client = Client::builder()->setMaxRetries(2)->build(); + + try { + $client->connect($transport); + $this->fail(\sprintf('Expected a "%s" to be thrown.', ConnectionException::class)); + } catch (ConnectionException) { + // Expected. + } + + $this->assertSame(3, $transport->connectCalls, 'one initial attempt plus two retries'); + $this->assertSame(3, $transport->closeCalls, 'the last attempt must be cleaned up as well'); + $this->assertFalse($client->isConnected()); + } + + #[TestDox('setMaxRetries(0) disables retrying')] + public function testZeroRetriesAttemptsToConnectOnce(): void + { + $transport = new FakeTransport([FakeTransport::REJECT, FakeTransport::ACCEPT]); + + $client = Client::builder()->setMaxRetries(0)->build(); + + $this->expectException(ConnectionException::class); + + try { + $client->connect($transport); + } finally { + $this->assertSame(1, $transport->connectCalls); + } + } + + #[TestDox('a negative retry count is rejected')] + public function testNegativeRetryCountIsRejected(): void + { + $builder = Client::builder()->setMaxRetries(-1); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('The maximum number of retries must be zero or greater, got -1.'); + + $builder->build(); + } + + #[TestDox('a connection breaking after the handshake result does not leave the client connected')] + public function testFailureAfterHandshakeResultDoesNotLeaveClientConnected(): void + { + $transport = new FakeTransport([FakeTransport::BREAK_AFTER_ACCEPT]); + + $client = Client::builder()->setMaxRetries(0)->build(); + + try { + $client->connect($transport); + $this->fail(\sprintf('Expected a "%s" to be thrown.', ConnectionException::class)); + } catch (ConnectionException) { + // Expected. + } + + $this->assertFalse($client->isConnected()); + } + + #[TestDox('a malformed handshake result fails with a ConnectionException and closes the transport')] + public function testMalformedHandshakeResultClosesTheTransport(): void + { + $transport = new FakeTransport([FakeTransport::MALFORMED]); + + $client = Client::builder()->setMaxRetries(2)->build(); + + try { + $client->connect($transport); + $this->fail(\sprintf('Expected a "%s" to be thrown.', ConnectionException::class)); + } catch (ConnectionException $e) { + $this->assertInstanceOf(SchemaInvalidArgumentException::class, $e->getPrevious()); + } + + $this->assertSame(1, $transport->connectCalls, 'a malformed result is not retried'); + $this->assertSame(1, $transport->closeCalls); + $this->assertFalse($client->isConnected()); + } + + #[TestDox('a timed out attempt does not leave state behind that fails the retry')] + public function testTimedOutAttemptDoesNotPoisonTheRetry(): void + { + // The shortest allowed init timeout, so this waits out about a second. + $transport = new FakeTransport([FakeTransport::IGNORE, FakeTransport::ACCEPT]); + + $client = Client::builder()->setInitTimeout(1)->setMaxRetries(1)->build(); + $client->connect($transport); + + $this->assertSame(2, $transport->connectCalls); + $this->assertTrue($client->isConnected()); + } + public function testSendRootsListChangedSendsNotificationWhenCapabilityDeclared(): void { $sent = []; @@ -100,3 +272,157 @@ public function testSendRootsListChangedThrowsWhenNotConnected(): void $client->sendRootsListChanged(); } } + +/** + * Transport whose connection attempts succeed or fail on command. + * + * Requests are answered from the polling loop rather than from send(), the way + * a stdio transport does, with each connect() call answering according to the + * next configured outcome. + * + * @phpstan-import-type McpFiber from TransportInterface + */ +final class FakeTransport extends BaseTransport +{ + /** The initialize request is answered with a result. */ + public const ACCEPT = 'accept'; + + /** The `server/discover` probe is answered as a modern server would, settling the connection on 2026-07-28. */ + public const ACCEPT_MODERN = 'accept_modern'; + + /** The initialize request is answered with a JSON-RPC error. */ + public const REJECT = 'reject'; + + /** The initialize request is not answered at all and has to time out. */ + public const IGNORE = 'ignore'; + + /** The initialize request is answered, but the connection breaks right after. */ + public const BREAK_AFTER_ACCEPT = 'break_after_accept'; + + /** The initialize request is answered with a result lacking `serverInfo.version`. */ + public const MALFORMED = 'malformed'; + + public int $connectCalls = 0; + public int $closeCalls = 0; + + private string $outcome = self::ACCEPT; + + /** @var list Answers not yet delivered to the client */ + private array $outbox = []; + + /** + * @param list $attempts How each successive connect() call behaves + */ + public function __construct(private array $attempts = [self::ACCEPT]) + { + parent::__construct(); + } + + public function connect(): void + { + ++$this->connectCalls; + $this->outcome = array_shift($this->attempts) ?? self::ACCEPT; + + $result = $this->runRequest(new \Fiber(fn () => $this->handleInitialize())); + + if ($result instanceof Error) { + throw new ConnectionException('Initialization failed: '.$result->message); + } + } + + public function send(string $data): void + { + if (self::IGNORE === $this->outcome) { + return; + } + + $message = json_decode($data, true, 512, \JSON_THROW_ON_ERROR); + + if (!isset($message['id'])) { + if (self::BREAK_AFTER_ACCEPT === $this->outcome) { + throw new ConnectionException('Connection lost'); + } + + return; // A notification, nothing to answer. + } + + if (self::ACCEPT_MODERN === $this->outcome && 'server/discover' === ($message['method'] ?? null)) { + $this->outbox[] = json_encode(['jsonrpc' => '2.0', 'id' => $message['id'], 'result' => [ + 'resultType' => 'complete', + 'supportedVersions' => [ProtocolVersion::V2026_07_28->value], + 'capabilities' => [], + ]], \JSON_THROW_ON_ERROR); + + return; + } + + $answer = self::REJECT === $this->outcome + ? ['error' => ['code' => Error::INTERNAL_ERROR, 'message' => 'Server unavailable']] + : ['result' => [ + 'protocolVersion' => ProtocolVersion::V2025_11_25->value, + 'capabilities' => [], + 'serverInfo' => self::MALFORMED === $this->outcome + ? ['name' => 'Test Server'] + : ['name' => 'Test Server', 'version' => '1.0.0'], + ]]; + + $this->outbox[] = json_encode(['jsonrpc' => '2.0', 'id' => $message['id']] + $answer, \JSON_THROW_ON_ERROR); + } + + public function runRequest(\Fiber $fiber, ?callable $onProgress = null): Response|Error + { + $fiber->start(); + + // Polls at the same 1ms interval as the real transports, so a request + // left unanswered runs into its timeout in real time. + for ($poll = 0; !$fiber->isTerminated(); ++$poll) { + if ($poll > 5000) { + throw new \LogicException('The fiber never terminated, no pending request became resolvable.'); + } + + foreach ($this->outbox as $answer) { + $this->handleMessage($answer); + } + $this->outbox = []; + + $this->resumeFiber($fiber); + + usleep(1000); + } + + return $fiber->getReturn(); + } + + public function close(): void + { + ++$this->closeCalls; + + $this->handleClose('Transport closed'); + } + + /** + * @param McpFiber $fiber + */ + private function resumeFiber(\Fiber $fiber): void + { + if (!$fiber->isSuspended() || null === $this->state) { + return; + } + + foreach ($this->state->getPendingRequests() as $pending) { + $response = $this->state->consumeResponse($pending['request_id']); + + if (null !== $response) { + $fiber->resume($response); + + return; + } + + if (time() - $pending['timestamp'] >= $pending['timeout']) { + $fiber->resume(Error::forInternalError('Request timed out', $pending['request_id'])); + + return; + } + } + } +} diff --git a/tests/Unit/Client/ConfigurationTest.php b/tests/Unit/Client/ConfigurationTest.php index 24146b819..a0dda632f 100644 --- a/tests/Unit/Client/ConfigurationTest.php +++ b/tests/Unit/Client/ConfigurationTest.php @@ -11,9 +11,9 @@ namespace Mcp\Tests\Unit\Client; -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Configuration; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Client\Exception\InvalidArgumentException; use Mcp\Schema\ClientCapabilities; use Mcp\Schema\Enum\ProtocolVersion; use Mcp\Schema\Implementation; diff --git a/tests/Unit/Exception/AuthorizationExceptionTest.php b/tests/Unit/Client/Exception/AuthorizationExceptionTest.php similarity index 93% rename from tests/Unit/Exception/AuthorizationExceptionTest.php rename to tests/Unit/Client/Exception/AuthorizationExceptionTest.php index 2cdd62f05..bc80cacae 100644 --- a/tests/Unit/Exception/AuthorizationExceptionTest.php +++ b/tests/Unit/Client/Exception/AuthorizationExceptionTest.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Exception; +namespace Mcp\Tests\Unit\Client\Exception; -use Mcp\Exception\AuthorizationException; +use Mcp\Client\Exception\AuthorizationException; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Client/Handler/Request/ElicitationRequestHandlerTest.php b/tests/Unit/Client/Handler/Request/ElicitationRequestHandlerTest.php index 67358717d..038432804 100644 --- a/tests/Unit/Client/Handler/Request/ElicitationRequestHandlerTest.php +++ b/tests/Unit/Client/Handler/Request/ElicitationRequestHandlerTest.php @@ -11,9 +11,9 @@ namespace Mcp\Tests\Unit\Client\Handler\Request; +use Mcp\Client\Exception\ElicitationException; use Mcp\Client\Handler\Request\ElicitationCallbackInterface; use Mcp\Client\Handler\Request\ElicitationRequestHandler; -use Mcp\Exception\ElicitationException; use Mcp\Schema\Enum\ElicitAction; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Response; diff --git a/tests/Unit/Client/Handler/Request/ListRootsRequestHandlerTest.php b/tests/Unit/Client/Handler/Request/ListRootsRequestHandlerTest.php index c101b168a..9bac2e613 100644 --- a/tests/Unit/Client/Handler/Request/ListRootsRequestHandlerTest.php +++ b/tests/Unit/Client/Handler/Request/ListRootsRequestHandlerTest.php @@ -11,9 +11,9 @@ namespace Mcp\Tests\Unit\Client\Handler\Request; +use Mcp\Client\Exception\RootsException; use Mcp\Client\Handler\Request\ListRootsRequestHandler; use Mcp\Client\Handler\Request\RootsCallbackInterface; -use Mcp\Exception\RootsException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\ListRootsRequest; diff --git a/tests/Unit/Client/ProtocolTest.php b/tests/Unit/Client/ProtocolTest.php index 559d82907..5ebc8dcd5 100644 --- a/tests/Unit/Client/ProtocolTest.php +++ b/tests/Unit/Client/ProtocolTest.php @@ -13,15 +13,15 @@ use Mcp\Client\CancellationTokenInterface; use Mcp\Client\Configuration; +use Mcp\Client\Exception\ConnectionException; +use Mcp\Client\Exception\InvalidArgumentException; +use Mcp\Client\Exception\LogicException; +use Mcp\Client\Exception\RequestCancelledException; +use Mcp\Client\Exception\TimeoutException; use Mcp\Client\Handler\Request\RequestHandlerInterface; use Mcp\Client\Protocol; use Mcp\Client\State\ClientStateInterface; use Mcp\Client\Transport\TransportInterface; -use Mcp\Exception\ConnectionException; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\LogicException; -use Mcp\Exception\RequestCancelledException; -use Mcp\Exception\TimeoutException; use Mcp\Schema\ClientCapabilities; use Mcp\Schema\Enum\LoggingLevel; use Mcp\Schema\Enum\ProtocolVersion; @@ -32,8 +32,8 @@ use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\CallToolRequest; use Mcp\Schema\Request\PingRequest; +use Mcp\Schema\RequestMeta; use Mcp\Schema\Result\CallToolResult; -use Mcp\Server\Stateless\RequestMeta; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Client/Stateless/HeaderFactoryTest.php b/tests/Unit/Client/Stateless/HeaderFactoryTest.php index 4aae8071c..6ca35b68a 100644 --- a/tests/Unit/Client/Stateless/HeaderFactoryTest.php +++ b/tests/Unit/Client/Stateless/HeaderFactoryTest.php @@ -14,17 +14,9 @@ use Mcp\Client\Stateless\HeaderFactory; use Mcp\Client\Stateless\ToolCatalog; use Mcp\Schema\Enum\ProtocolVersion; -use Mcp\Server\Stateless\StandardHeaderValidator; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\TestCase; -/** - * What the client puts on the wire, checked against the server that reads it. - * - * Every case asserts the emitted headers and then feeds them straight to - * {@see StandardHeaderValidator}: agreeing with a hand-written expectation is - * not the point, agreeing with the other side is. - */ final class HeaderFactoryTest extends TestCase { #[TestDox('declares the revision and the method on every request')] @@ -43,19 +35,17 @@ public function testNameHeader(): void $payload = ['method' => 'tools/call', 'params' => ['name' => 'search', 'arguments' => new \stdClass()]]; $this->assertSame('search', $this->headersFor($payload)['Mcp-Name']); - $this->assertNull($this->validate($payload)); } - #[TestDox('wraps a subject that is not header-safe, and the server unwraps it')] + #[TestDox('wraps a subject that is not header-safe')] public function testUnsafeNameRoundTrips(): void { $payload = ['method' => 'resources/read', 'params' => ['uri' => 'file:///café.txt']]; $this->assertSame('=?base64?ZmlsZTovLy9jYWbDqS50eHQ=?=', $this->headersFor($payload)['Mcp-Name']); - $this->assertNull($this->validate($payload)); } - #[TestDox('mirrors annotated tool arguments the server can verify')] + #[TestDox('mirrors annotated tool arguments')] public function testMirroredArguments(): void { $payload = [ @@ -70,7 +60,6 @@ public function testMirroredArguments(): void $this->assertSame('=?base64?IHBhZGRlZCA=?=', $headers['Mcp-Param-Region']); $this->assertSame('7', $headers['Mcp-Param-Priority']); - $this->assertNull($this->validate($payload)); } #[TestDox('a response carries the revision but nothing to mirror')] @@ -130,20 +119,6 @@ private function headersFor(array $payload): array return (new HeaderFactory($this->catalog()))->forMessage($payload, ProtocolVersion::V2026_07_28); } - /** - * @param array $payload - * - * @return string|null the server's reason to reject, or null when it agrees - */ - private function validate(array $payload): ?string - { - return (new StandardHeaderValidator())->validate( - $payload['method'], - $payload['params'] ?? null, - $this->headersFor($payload), - ); - } - private function catalog(): ToolCatalog { $catalog = new ToolCatalog(); diff --git a/tests/Unit/Client/Stateless/InputRequestResolverTest.php b/tests/Unit/Client/Stateless/InputRequestResolverTest.php index 536aa312a..7329b66fe 100644 --- a/tests/Unit/Client/Stateless/InputRequestResolverTest.php +++ b/tests/Unit/Client/Stateless/InputRequestResolverTest.php @@ -11,9 +11,9 @@ namespace Mcp\Tests\Unit\Client\Stateless; +use Mcp\Client\Exception\RuntimeException; use Mcp\Client\Handler\Request\RequestHandlerInterface; use Mcp\Client\Stateless\InputRequestResolver; -use Mcp\Exception\RuntimeException; use Mcp\Schema\Enum\ElicitAction; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; diff --git a/tests/Unit/Client/Transport/HttpTransportListenTest.php b/tests/Unit/Client/Transport/HttpTransportListenTest.php index 3172ff964..5bafd1614 100644 --- a/tests/Unit/Client/Transport/HttpTransportListenTest.php +++ b/tests/Unit/Client/Transport/HttpTransportListenTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Client\Transport; -use Mcp\Client; use Mcp\Client\Auth\AuthenticatorInterface; +use Mcp\Client\Client; use Mcp\Client\Handler\Notification\NotificationHandlerInterface; use Mcp\Client\Handler\Request\ListRootsRequestHandler; use Mcp\Client\Handler\Request\RootsCallbackInterface; diff --git a/tests/Unit/Client/Transport/HttpTransportTest.php b/tests/Unit/Client/Transport/HttpTransportTest.php index 96c34458e..3411cdc5f 100644 --- a/tests/Unit/Client/Transport/HttpTransportTest.php +++ b/tests/Unit/Client/Transport/HttpTransportTest.php @@ -13,23 +13,23 @@ use Http\Discovery\Psr18ClientDiscovery; use Http\Discovery\Strategy\DiscoveryStrategy; -use Mcp\Client; use Mcp\Client\Auth\AuthenticatorInterface; use Mcp\Client\Auth\BearerToken; use Mcp\Client\CancellationTokenInterface; +use Mcp\Client\Client; use Mcp\Client\Configuration; +use Mcp\Client\Exception\AuthorizationException; +use Mcp\Client\Exception\AuthorizationPendingException; +use Mcp\Client\Exception\ConnectionException; +use Mcp\Client\Exception\InvalidArgumentException; +use Mcp\Client\Exception\RequestCancelledException; +use Mcp\Client\Exception\RequestException; +use Mcp\Client\Exception\TimeoutException; use Mcp\Client\Handler\Notification\LoggingNotificationHandler; use Mcp\Client\Protocol; use Mcp\Client\State\ClientState; use Mcp\Client\Transport\HttpTransport; use Mcp\Client\Transport\TransportInterface; -use Mcp\Exception\AuthorizationException; -use Mcp\Exception\AuthorizationPendingException; -use Mcp\Exception\ConnectionException; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\RequestCancelledException; -use Mcp\Exception\RequestException; -use Mcp\Exception\TimeoutException; use Mcp\Schema\ClientCapabilities; use Mcp\Schema\Enum\ProtocolVersion; use Mcp\Schema\Implementation; diff --git a/tests/Unit/Client/Transport/ReconnectPolicyTest.php b/tests/Unit/Client/Transport/ReconnectPolicyTest.php index 8d9b15504..d461b8078 100644 --- a/tests/Unit/Client/Transport/ReconnectPolicyTest.php +++ b/tests/Unit/Client/Transport/ReconnectPolicyTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Client\Transport; +use Mcp\Client\Exception\InvalidArgumentException; use Mcp\Client\Transport\ReconnectPolicy; -use Mcp\Exception\InvalidArgumentException; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Client/Transport/SseParserTest.php b/tests/Unit/Client/Transport/SseParserTest.php index 206a860c0..c11ecdbb2 100644 --- a/tests/Unit/Client/Transport/SseParserTest.php +++ b/tests/Unit/Client/Transport/SseParserTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Client\Transport; +use Mcp\Client\Exception\InvalidArgumentException; use Mcp\Client\Transport\SseParser; -use Mcp\Exception\InvalidArgumentException; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Client/Transport/StdioTransportTest.php b/tests/Unit/Client/Transport/StdioTransportTest.php index cc2631950..6f45789db 100644 --- a/tests/Unit/Client/Transport/StdioTransportTest.php +++ b/tests/Unit/Client/Transport/StdioTransportTest.php @@ -11,15 +11,15 @@ namespace Mcp\Tests\Unit\Client\Transport; -use Mcp\Client; +use Mcp\Client\Client; use Mcp\Client\Configuration; +use Mcp\Client\Exception\ConnectionException; +use Mcp\Client\Exception\InvalidArgumentException; use Mcp\Client\Handler\Notification\LoggingNotificationHandler; use Mcp\Client\Protocol; use Mcp\Client\State\ClientState; use Mcp\Client\Transport\StdioTransport; use Mcp\Client\Transport\TransportInterface; -use Mcp\Exception\ConnectionException; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\ClientCapabilities; use Mcp\Schema\Implementation; use Mcp\Schema\JsonRpc\Error; diff --git a/tests/Unit/ClientTest.php b/tests/Unit/ClientTest.php deleted file mode 100644 index 58bce5fba..000000000 --- a/tests/Unit/ClientTest.php +++ /dev/null @@ -1,345 +0,0 @@ -assertInstanceOf(Builder::class, Client::builder()); - } - - #[TestDox('readResource() refuses an empty URI before it reaches the wire')] - public function testReadResourceRejectsAnEmptyUri(): void - { - $client = Client::builder()->build(); - - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Resource URI must not be empty.'); - - $client->readResource(''); - } - - #[TestDox('connect() succeeds on the first attempt without retrying')] - public function testConnectSucceedsWithoutRetrying(): void - { - $transport = new FakeTransport([FakeTransport::ACCEPT]); - - $client = Client::builder()->build(); - $client->connect($transport); - - $this->assertSame(1, $transport->connectCalls); - $this->assertSame(0, $transport->closeCalls); - $this->assertTrue($client->isConnected()); - } - - #[TestDox('setting the log level after disconnecting a modern connection fails like any other call')] - public function testSetLoggingLevelRequiresAConnection(): void - { - $client = Client::builder()->setProtocolVersion(ProtocolVersion::V2026_07_28)->build(); - $client->connect(new FakeTransport([FakeTransport::ACCEPT_MODERN])); - $this->assertSame(ProtocolVersion::V2026_07_28, $client->getProtocolVersion()); - $client->disconnect(); - - $this->expectException(ConnectionException::class); - - $client->setLoggingLevel(LoggingLevel::Info); - } - - #[TestDox('connect() retries a failed attempt and succeeds on a later one')] - public function testConnectRetriesUntilItSucceeds(): void - { - $transport = new FakeTransport([FakeTransport::REJECT, FakeTransport::REJECT, FakeTransport::ACCEPT]); - - $client = Client::builder()->setMaxRetries(3)->build(); - $client->connect($transport); - - $this->assertSame(3, $transport->connectCalls); - $this->assertTrue($client->isConnected()); - $this->assertSame('Test Server', $client->getServerInfo()?->name); - } - - #[TestDox('connect() closes the transport between two attempts')] - public function testConnectClosesTransportBetweenAttempts(): void - { - $transport = new FakeTransport([FakeTransport::REJECT, FakeTransport::ACCEPT]); - - $client = Client::builder()->setMaxRetries(1)->build(); - $client->connect($transport); - - $this->assertSame(2, $transport->connectCalls); - $this->assertSame(1, $transport->closeCalls, 'the failed attempt must be cleaned up before the retry'); - } - - #[TestDox('connect() rethrows once the retries are exhausted')] - public function testConnectThrowsWhenRetriesAreExhausted(): void - { - $transport = new FakeTransport([FakeTransport::REJECT, FakeTransport::REJECT, FakeTransport::REJECT]); - - $client = Client::builder()->setMaxRetries(2)->build(); - - try { - $client->connect($transport); - $this->fail(\sprintf('Expected a "%s" to be thrown.', ConnectionException::class)); - } catch (ConnectionException) { - // Expected. - } - - $this->assertSame(3, $transport->connectCalls, 'one initial attempt plus two retries'); - $this->assertSame(3, $transport->closeCalls, 'the last attempt must be cleaned up as well'); - $this->assertFalse($client->isConnected()); - } - - #[TestDox('setMaxRetries(0) disables retrying')] - public function testZeroRetriesAttemptsToConnectOnce(): void - { - $transport = new FakeTransport([FakeTransport::REJECT, FakeTransport::ACCEPT]); - - $client = Client::builder()->setMaxRetries(0)->build(); - - $this->expectException(ConnectionException::class); - - try { - $client->connect($transport); - } finally { - $this->assertSame(1, $transport->connectCalls); - } - } - - #[TestDox('a negative retry count is rejected')] - public function testNegativeRetryCountIsRejected(): void - { - $builder = Client::builder()->setMaxRetries(-1); - - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('The maximum number of retries must be zero or greater, got -1.'); - - $builder->build(); - } - - #[TestDox('a connection breaking after the handshake result does not leave the client connected')] - public function testFailureAfterHandshakeResultDoesNotLeaveClientConnected(): void - { - $transport = new FakeTransport([FakeTransport::BREAK_AFTER_ACCEPT]); - - $client = Client::builder()->setMaxRetries(0)->build(); - - try { - $client->connect($transport); - $this->fail(\sprintf('Expected a "%s" to be thrown.', ConnectionException::class)); - } catch (ConnectionException) { - // Expected. - } - - $this->assertFalse($client->isConnected()); - } - - #[TestDox('a malformed handshake result fails with a ConnectionException and closes the transport')] - public function testMalformedHandshakeResultClosesTheTransport(): void - { - $transport = new FakeTransport([FakeTransport::MALFORMED]); - - $client = Client::builder()->setMaxRetries(2)->build(); - - try { - $client->connect($transport); - $this->fail(\sprintf('Expected a "%s" to be thrown.', ConnectionException::class)); - } catch (ConnectionException $e) { - $this->assertInstanceOf(InvalidArgumentException::class, $e->getPrevious()); - } - - $this->assertSame(1, $transport->connectCalls, 'a malformed result is not retried'); - $this->assertSame(1, $transport->closeCalls); - $this->assertFalse($client->isConnected()); - } - - #[TestDox('a timed out attempt does not leave state behind that fails the retry')] - public function testTimedOutAttemptDoesNotPoisonTheRetry(): void - { - // The shortest allowed init timeout, so this waits out about a second. - $transport = new FakeTransport([FakeTransport::IGNORE, FakeTransport::ACCEPT]); - - $client = Client::builder()->setInitTimeout(1)->setMaxRetries(1)->build(); - $client->connect($transport); - - $this->assertSame(2, $transport->connectCalls); - $this->assertTrue($client->isConnected()); - } -} - -/** - * Transport whose connection attempts succeed or fail on command. - * - * Requests are answered from the polling loop rather than from send(), the way - * a stdio transport does, with each connect() call answering according to the - * next configured outcome. - * - * @phpstan-import-type McpFiber from TransportInterface - */ -final class FakeTransport extends BaseTransport -{ - /** The initialize request is answered with a result. */ - public const ACCEPT = 'accept'; - - /** The `server/discover` probe is answered as a modern server would, settling the connection on 2026-07-28. */ - public const ACCEPT_MODERN = 'accept_modern'; - - /** The initialize request is answered with a JSON-RPC error. */ - public const REJECT = 'reject'; - - /** The initialize request is not answered at all and has to time out. */ - public const IGNORE = 'ignore'; - - /** The initialize request is answered, but the connection breaks right after. */ - public const BREAK_AFTER_ACCEPT = 'break_after_accept'; - - /** The initialize request is answered with a result lacking `serverInfo.version`. */ - public const MALFORMED = 'malformed'; - - public int $connectCalls = 0; - public int $closeCalls = 0; - - private string $outcome = self::ACCEPT; - - /** @var list Answers not yet delivered to the client */ - private array $outbox = []; - - /** - * @param list $attempts How each successive connect() call behaves - */ - public function __construct(private array $attempts = [self::ACCEPT]) - { - parent::__construct(); - } - - public function connect(): void - { - ++$this->connectCalls; - $this->outcome = array_shift($this->attempts) ?? self::ACCEPT; - - $result = $this->runRequest(new \Fiber(fn () => $this->handleInitialize())); - - if ($result instanceof Error) { - throw new ConnectionException('Initialization failed: '.$result->message); - } - } - - public function send(string $data): void - { - if (self::IGNORE === $this->outcome) { - return; - } - - $message = json_decode($data, true, 512, \JSON_THROW_ON_ERROR); - - if (!isset($message['id'])) { - if (self::BREAK_AFTER_ACCEPT === $this->outcome) { - throw new ConnectionException('Connection lost'); - } - - return; // A notification, nothing to answer. - } - - if (self::ACCEPT_MODERN === $this->outcome && 'server/discover' === ($message['method'] ?? null)) { - $this->outbox[] = json_encode(['jsonrpc' => '2.0', 'id' => $message['id'], 'result' => [ - 'resultType' => 'complete', - 'supportedVersions' => [ProtocolVersion::V2026_07_28->value], - 'capabilities' => [], - ]], \JSON_THROW_ON_ERROR); - - return; - } - - $answer = self::REJECT === $this->outcome - ? ['error' => ['code' => Error::INTERNAL_ERROR, 'message' => 'Server unavailable']] - : ['result' => [ - 'protocolVersion' => ProtocolVersion::V2025_11_25->value, - 'capabilities' => [], - 'serverInfo' => self::MALFORMED === $this->outcome - ? ['name' => 'Test Server'] - : ['name' => 'Test Server', 'version' => '1.0.0'], - ]]; - - $this->outbox[] = json_encode(['jsonrpc' => '2.0', 'id' => $message['id']] + $answer, \JSON_THROW_ON_ERROR); - } - - public function runRequest(\Fiber $fiber, ?callable $onProgress = null): Response|Error - { - $fiber->start(); - - // Polls at the same 1ms interval as the real transports, so a request - // left unanswered runs into its timeout in real time. - for ($poll = 0; !$fiber->isTerminated(); ++$poll) { - if ($poll > 5000) { - throw new \LogicException('The fiber never terminated, no pending request became resolvable.'); - } - - foreach ($this->outbox as $answer) { - $this->handleMessage($answer); - } - $this->outbox = []; - - $this->resumeFiber($fiber); - - usleep(1000); - } - - return $fiber->getReturn(); - } - - public function close(): void - { - ++$this->closeCalls; - - $this->handleClose('Transport closed'); - } - - /** - * @param McpFiber $fiber - */ - private function resumeFiber(\Fiber $fiber): void - { - if (!$fiber->isSuspended() || null === $this->state) { - return; - } - - foreach ($this->state->getPendingRequests() as $pending) { - $response = $this->state->consumeResponse($pending['request_id']); - - if (null !== $response) { - $fiber->resume($response); - - return; - } - - if (time() - $pending['timestamp'] >= $pending['timeout']) { - $fiber->resume(Error::forInternalError('Request timed out', $pending['request_id'])); - - return; - } - } - } -} diff --git a/tests/Unit/Fixtures/RecordingFiberContext.php b/tests/Unit/Fixtures/RecordingFiberContext.php index 9e2d1fb06..f65562462 100644 --- a/tests/Unit/Fixtures/RecordingFiberContext.php +++ b/tests/Unit/Fixtures/RecordingFiberContext.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Fixtures; -use Mcp\Exception\LogicException; +use Mcp\Server\Exception\LogicException; use Mcp\Server\Fiber\FiberContextInterface; /** diff --git a/tests/Unit/Schema/Content/PromptMessageTest.php b/tests/Unit/Schema/Content/PromptMessageTest.php index 46a416578..c813ad759 100644 --- a/tests/Unit/Schema/Content/PromptMessageTest.php +++ b/tests/Unit/Schema/Content/PromptMessageTest.php @@ -11,10 +11,10 @@ namespace Mcp\Tests\Unit\Schema\Content; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Content\PromptMessage; use Mcp\Schema\Content\ResourceLink; use Mcp\Schema\Enum\Role; +use Mcp\Schema\Exception\InvalidArgumentException; use PHPUnit\Framework\TestCase; final class PromptMessageTest extends TestCase diff --git a/tests/Unit/Schema/Content/ResourceLinkTest.php b/tests/Unit/Schema/Content/ResourceLinkTest.php index 4283a8081..b110135ec 100644 --- a/tests/Unit/Schema/Content/ResourceLinkTest.php +++ b/tests/Unit/Schema/Content/ResourceLinkTest.php @@ -11,10 +11,10 @@ namespace Mcp\Tests\Unit\Schema\Content; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Annotations; use Mcp\Schema\Content\ResourceLink; use Mcp\Schema\Enum\Role; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\Icon; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Schema/Content/SamplingMessageTest.php b/tests/Unit/Schema/Content/SamplingMessageTest.php index e3e1b2e3f..71c928fad 100644 --- a/tests/Unit/Schema/Content/SamplingMessageTest.php +++ b/tests/Unit/Schema/Content/SamplingMessageTest.php @@ -11,12 +11,12 @@ namespace Mcp\Tests\Unit\Schema\Content; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Content\SamplingMessage; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Content\ToolResultContent; use Mcp\Schema\Content\ToolUseContent; use Mcp\Schema\Enum\Role; +use Mcp\Schema\Exception\InvalidArgumentException; use PHPUnit\Framework\TestCase; final class SamplingMessageTest extends TestCase diff --git a/tests/Unit/Schema/Content/ToolResultContentTest.php b/tests/Unit/Schema/Content/ToolResultContentTest.php index 51348730b..1f849a0bd 100644 --- a/tests/Unit/Schema/Content/ToolResultContentTest.php +++ b/tests/Unit/Schema/Content/ToolResultContentTest.php @@ -11,13 +11,13 @@ namespace Mcp\Tests\Unit\Schema\Content; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Content\EmbeddedResource; use Mcp\Schema\Content\ResourceLink; use Mcp\Schema\Content\SamplingMessage; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Content\ToolResultContent; use Mcp\Schema\Enum\Role; +use Mcp\Schema\Exception\InvalidArgumentException; use PHPUnit\Framework\TestCase; final class ToolResultContentTest extends TestCase diff --git a/tests/Unit/Schema/Content/ToolUseContentTest.php b/tests/Unit/Schema/Content/ToolUseContentTest.php index f40d36c7b..84870bc31 100644 --- a/tests/Unit/Schema/Content/ToolUseContentTest.php +++ b/tests/Unit/Schema/Content/ToolUseContentTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Schema\Content; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Content\ToolUseContent; +use Mcp\Schema\Exception\InvalidArgumentException; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Schema/Elicitation/BooleanSchemaDefinitionTest.php b/tests/Unit/Schema/Elicitation/BooleanSchemaDefinitionTest.php index 71aa4d998..347ff20b6 100644 --- a/tests/Unit/Schema/Elicitation/BooleanSchemaDefinitionTest.php +++ b/tests/Unit/Schema/Elicitation/BooleanSchemaDefinitionTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Schema\Elicitation; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Elicitation\BooleanSchemaDefinition; +use Mcp\Schema\Exception\InvalidArgumentException; use PHPUnit\Framework\TestCase; final class BooleanSchemaDefinitionTest extends TestCase diff --git a/tests/Unit/Schema/Elicitation/ElicitationSchemaTest.php b/tests/Unit/Schema/Elicitation/ElicitationSchemaTest.php index 5ee2fec50..daab03260 100644 --- a/tests/Unit/Schema/Elicitation/ElicitationSchemaTest.php +++ b/tests/Unit/Schema/Elicitation/ElicitationSchemaTest.php @@ -11,7 +11,6 @@ namespace Mcp\Tests\Unit\Schema\Elicitation; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Elicitation\BooleanSchemaDefinition; use Mcp\Schema\Elicitation\ElicitationSchema; use Mcp\Schema\Elicitation\EnumSchemaDefinition; @@ -20,6 +19,7 @@ use Mcp\Schema\Elicitation\StringSchemaDefinition; use Mcp\Schema\Elicitation\TitledEnumSchemaDefinition; use Mcp\Schema\Elicitation\TitledMultiSelectEnumSchemaDefinition; +use Mcp\Schema\Exception\InvalidArgumentException; use PHPUnit\Framework\TestCase; final class ElicitationSchemaTest extends TestCase diff --git a/tests/Unit/Schema/Elicitation/EnumSchemaDefinitionTest.php b/tests/Unit/Schema/Elicitation/EnumSchemaDefinitionTest.php index 2ae7046d0..9bccfe1b5 100644 --- a/tests/Unit/Schema/Elicitation/EnumSchemaDefinitionTest.php +++ b/tests/Unit/Schema/Elicitation/EnumSchemaDefinitionTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Schema\Elicitation; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Elicitation\EnumSchemaDefinition; +use Mcp\Schema\Exception\InvalidArgumentException; use PHPUnit\Framework\TestCase; final class EnumSchemaDefinitionTest extends TestCase diff --git a/tests/Unit/Schema/Elicitation/MultiSelectEnumSchemaDefinitionTest.php b/tests/Unit/Schema/Elicitation/MultiSelectEnumSchemaDefinitionTest.php index a36de82f1..4ba51835f 100644 --- a/tests/Unit/Schema/Elicitation/MultiSelectEnumSchemaDefinitionTest.php +++ b/tests/Unit/Schema/Elicitation/MultiSelectEnumSchemaDefinitionTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Schema\Elicitation; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Elicitation\MultiSelectEnumSchemaDefinition; +use Mcp\Schema\Exception\InvalidArgumentException; use PHPUnit\Framework\TestCase; final class MultiSelectEnumSchemaDefinitionTest extends TestCase diff --git a/tests/Unit/Schema/Elicitation/NumberSchemaDefinitionTest.php b/tests/Unit/Schema/Elicitation/NumberSchemaDefinitionTest.php index 6398da5ce..808ca77f1 100644 --- a/tests/Unit/Schema/Elicitation/NumberSchemaDefinitionTest.php +++ b/tests/Unit/Schema/Elicitation/NumberSchemaDefinitionTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Schema\Elicitation; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Elicitation\NumberSchemaDefinition; +use Mcp\Schema\Exception\InvalidArgumentException; use PHPUnit\Framework\TestCase; final class NumberSchemaDefinitionTest extends TestCase diff --git a/tests/Unit/Schema/Elicitation/StringSchemaDefinitionTest.php b/tests/Unit/Schema/Elicitation/StringSchemaDefinitionTest.php index 524f458ab..efeb3524a 100644 --- a/tests/Unit/Schema/Elicitation/StringSchemaDefinitionTest.php +++ b/tests/Unit/Schema/Elicitation/StringSchemaDefinitionTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Schema\Elicitation; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Elicitation\StringSchemaDefinition; +use Mcp\Schema\Exception\InvalidArgumentException; use PHPUnit\Framework\TestCase; final class StringSchemaDefinitionTest extends TestCase diff --git a/tests/Unit/Schema/Elicitation/TitledEnumSchemaDefinitionTest.php b/tests/Unit/Schema/Elicitation/TitledEnumSchemaDefinitionTest.php index f7f3347e8..f0c816ae1 100644 --- a/tests/Unit/Schema/Elicitation/TitledEnumSchemaDefinitionTest.php +++ b/tests/Unit/Schema/Elicitation/TitledEnumSchemaDefinitionTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Schema\Elicitation; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Elicitation\TitledEnumSchemaDefinition; +use Mcp\Schema\Exception\InvalidArgumentException; use PHPUnit\Framework\TestCase; final class TitledEnumSchemaDefinitionTest extends TestCase diff --git a/tests/Unit/Schema/Elicitation/TitledMultiSelectEnumSchemaDefinitionTest.php b/tests/Unit/Schema/Elicitation/TitledMultiSelectEnumSchemaDefinitionTest.php index 6bf1853cc..8ce303d91 100644 --- a/tests/Unit/Schema/Elicitation/TitledMultiSelectEnumSchemaDefinitionTest.php +++ b/tests/Unit/Schema/Elicitation/TitledMultiSelectEnumSchemaDefinitionTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Schema\Elicitation; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Elicitation\TitledMultiSelectEnumSchemaDefinition; +use Mcp\Schema\Exception\InvalidArgumentException; use PHPUnit\Framework\TestCase; final class TitledMultiSelectEnumSchemaDefinitionTest extends TestCase diff --git a/tests/Unit/Schema/ElicitationModeTest.php b/tests/Unit/Schema/ElicitationModeTest.php index 1502e1e0e..92aac79bd 100644 --- a/tests/Unit/Schema/ElicitationModeTest.php +++ b/tests/Unit/Schema/ElicitationModeTest.php @@ -11,10 +11,10 @@ namespace Mcp\Tests\Unit\Schema; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Elicitation\ElicitationSchema; use Mcp\Schema\Elicitation\StringSchemaDefinition; use Mcp\Schema\Enum\ElicitationMode; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\MessageInterface; use Mcp\Schema\Request\ElicitRequest; use PHPUnit\Framework\Attributes\TestDox; diff --git a/tests/Unit/Schema/Extension/AbstractExtensionTest.php b/tests/Unit/Schema/Extension/AbstractExtensionTest.php index 9ae06abd9..2f4426095 100644 --- a/tests/Unit/Schema/Extension/AbstractExtensionTest.php +++ b/tests/Unit/Schema/Extension/AbstractExtensionTest.php @@ -18,8 +18,8 @@ class AbstractExtensionTest extends TestCase { - #[TestDox('An extension that only announces a capability need not declare messages or handlers')] - public function testDefaultsToNoMessagesOrHandlers(): void + #[TestDox('An extension that only announces a capability need not declare messages')] + public function testDefaultsToNoMessages(): void { $extension = new class extends AbstractExtension { public function getId(): ExtensionIdentifier @@ -34,6 +34,5 @@ public function getCapabilities(): array }; $this->assertSame([], $extension->getMessages()); - $this->assertSame([], $extension->getRequestHandlers()); } } diff --git a/tests/Unit/Schema/Extension/ExtensionIdentifierTest.php b/tests/Unit/Schema/Extension/ExtensionIdentifierTest.php index 96ff22d24..58ef1c8c2 100644 --- a/tests/Unit/Schema/Extension/ExtensionIdentifierTest.php +++ b/tests/Unit/Schema/Extension/ExtensionIdentifierTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Schema\Extension; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\Extension\ExtensionIdentifier; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\TestDox; diff --git a/tests/Unit/Schema/IconTest.php b/tests/Unit/Schema/IconTest.php index 4f7f15372..b03ef3660 100644 --- a/tests/Unit/Schema/IconTest.php +++ b/tests/Unit/Schema/IconTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Schema; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Enum\IconTheme; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\Icon; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Schema/ImplementationTest.php b/tests/Unit/Schema/ImplementationTest.php index 3667cd57e..c7ceefdaf 100644 --- a/tests/Unit/Schema/ImplementationTest.php +++ b/tests/Unit/Schema/ImplementationTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Schema; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\Implementation; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/JsonRpc/MalformedInputTest.php b/tests/Unit/Schema/MalformedInputTest.php similarity index 97% rename from tests/Unit/JsonRpc/MalformedInputTest.php rename to tests/Unit/Schema/MalformedInputTest.php index 7609ecd0f..1994b5524 100644 --- a/tests/Unit/JsonRpc/MalformedInputTest.php +++ b/tests/Unit/Schema/MalformedInputTest.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\JsonRpc; +namespace Mcp\Tests\Unit\Schema; -use Mcp\Exception\InvalidInputMessageException; -use Mcp\JsonRpc\MessageFactory; +use Mcp\Schema\Exception\InvalidInputMessageException; +use Mcp\Schema\MessageFactory; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/JsonRpc/MessageFactoryTest.php b/tests/Unit/Schema/MessageFactoryTest.php similarity index 99% rename from tests/Unit/JsonRpc/MessageFactoryTest.php rename to tests/Unit/Schema/MessageFactoryTest.php index b01bff336..2c92eb17e 100644 --- a/tests/Unit/JsonRpc/MessageFactoryTest.php +++ b/tests/Unit/Schema/MessageFactoryTest.php @@ -9,13 +9,13 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\JsonRpc; +namespace Mcp\Tests\Unit\Schema; -use Mcp\Exception\InvalidInputMessageException; -use Mcp\Exception\UnknownMethodException; -use Mcp\JsonRpc\MessageFactory; +use Mcp\Schema\Exception\InvalidInputMessageException; +use Mcp\Schema\Exception\UnknownMethodException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Response; +use Mcp\Schema\MessageFactory; use Mcp\Schema\Notification\CancelledNotification; use Mcp\Schema\Notification\InitializedNotification; use Mcp\Schema\Request\CallToolRequest; diff --git a/tests/Unit/Schema/NonObjectOutputSchemaTest.php b/tests/Unit/Schema/NonObjectOutputSchemaTest.php index c84420ef0..4fd265758 100644 --- a/tests/Unit/Schema/NonObjectOutputSchemaTest.php +++ b/tests/Unit/Schema/NonObjectOutputSchemaTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Schema; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Content\TextContent; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\Result\CallToolResult; use Mcp\Schema\Tool; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/tests/Unit/Schema/Request/CallToolRequestTest.php b/tests/Unit/Schema/Request/CallToolRequestTest.php index 795adf43f..c8c54e18b 100644 --- a/tests/Unit/Schema/Request/CallToolRequestTest.php +++ b/tests/Unit/Schema/Request/CallToolRequestTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Schema\Request; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\Request\CallToolRequest; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Schema/Request/CompletionCompleteRequestTest.php b/tests/Unit/Schema/Request/CompletionCompleteRequestTest.php index 6aaf01447..5000ec36c 100644 --- a/tests/Unit/Schema/Request/CompletionCompleteRequestTest.php +++ b/tests/Unit/Schema/Request/CompletionCompleteRequestTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Schema\Request; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\PromptReference; use Mcp\Schema\Request\CompletionCompleteRequest; use Mcp\Schema\ResourceReference; diff --git a/tests/Unit/Schema/Request/CreateSamplingMessageRequestTest.php b/tests/Unit/Schema/Request/CreateSamplingMessageRequestTest.php index ddc227173..476176774 100644 --- a/tests/Unit/Schema/Request/CreateSamplingMessageRequestTest.php +++ b/tests/Unit/Schema/Request/CreateSamplingMessageRequestTest.php @@ -11,13 +11,13 @@ namespace Mcp\Tests\Unit\Schema\Request; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Content\SamplingMessage; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Content\ToolResultContent; use Mcp\Schema\Content\ToolUseContent; use Mcp\Schema\Enum\Role; use Mcp\Schema\Enum\ToolChoiceMode; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\Request\CreateSamplingMessageRequest; use Mcp\Schema\Tool; use Mcp\Schema\ToolChoice; diff --git a/tests/Unit/Schema/ResourceDefinitionTest.php b/tests/Unit/Schema/ResourceDefinitionTest.php index 65241c890..1bae2e47c 100644 --- a/tests/Unit/Schema/ResourceDefinitionTest.php +++ b/tests/Unit/Schema/ResourceDefinitionTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Schema; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\ResourceDefinition; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Schema/ResourceTemplateTest.php b/tests/Unit/Schema/ResourceTemplateTest.php index 70adde4d7..4c6edfa1e 100644 --- a/tests/Unit/Schema/ResourceTemplateTest.php +++ b/tests/Unit/Schema/ResourceTemplateTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Schema; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\ResourceTemplate; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Schema/Result/CallToolResultTest.php b/tests/Unit/Schema/Result/CallToolResultTest.php index 7f7885f11..c22a63b10 100644 --- a/tests/Unit/Schema/Result/CallToolResultTest.php +++ b/tests/Unit/Schema/Result/CallToolResultTest.php @@ -11,13 +11,13 @@ namespace Mcp\Tests\Unit\Schema\Result; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Content\AudioContent; use Mcp\Schema\Content\EmbeddedResource; use Mcp\Schema\Content\ImageContent; use Mcp\Schema\Content\ResourceLink; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Enum\StructuredContent; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\Result\CallToolResult; use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Schema/Result/CreateSamplingMessageResultTest.php b/tests/Unit/Schema/Result/CreateSamplingMessageResultTest.php index a65f6b6b1..92803e29e 100644 --- a/tests/Unit/Schema/Result/CreateSamplingMessageResultTest.php +++ b/tests/Unit/Schema/Result/CreateSamplingMessageResultTest.php @@ -11,10 +11,10 @@ namespace Mcp\Tests\Unit\Schema\Result; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Content\ToolUseContent; use Mcp\Schema\Enum\Role; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\Result\CreateSamplingMessageResult; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Schema/Result/ElicitResultTest.php b/tests/Unit/Schema/Result/ElicitResultTest.php index 574203a09..fae8d654e 100644 --- a/tests/Unit/Schema/Result/ElicitResultTest.php +++ b/tests/Unit/Schema/Result/ElicitResultTest.php @@ -11,9 +11,9 @@ namespace Mcp\Tests\Unit\Schema\Result; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Enum\ElicitAction; use Mcp\Schema\Enum\ElicitationMode; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\Result\ElicitResult; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Schema/Result/ListRootsResultTest.php b/tests/Unit/Schema/Result/ListRootsResultTest.php index c3cfaf109..27f4819a3 100644 --- a/tests/Unit/Schema/Result/ListRootsResultTest.php +++ b/tests/Unit/Schema/Result/ListRootsResultTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Schema\Result; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\Result\ListRootsResult; use Mcp\Schema\Root; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Server/Transport/Http/OAuth/SecureUrlTest.php b/tests/Unit/Schema/SecureUrlTest.php similarity index 98% rename from tests/Unit/Server/Transport/Http/OAuth/SecureUrlTest.php rename to tests/Unit/Schema/SecureUrlTest.php index b357210d2..fe24cae06 100644 --- a/tests/Unit/Server/Transport/Http/OAuth/SecureUrlTest.php +++ b/tests/Unit/Schema/SecureUrlTest.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Server\Transport\Http\OAuth; +namespace Mcp\Tests\Unit\Schema; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Server\Transport\Http\OAuth\SecureUrl; +use Mcp\Schema\Exception\InvalidArgumentException; +use Mcp\Schema\SecureUrl; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Schema/ToolChoiceTest.php b/tests/Unit/Schema/ToolChoiceTest.php index 0b19fd3b1..4bea72f2d 100644 --- a/tests/Unit/Schema/ToolChoiceTest.php +++ b/tests/Unit/Schema/ToolChoiceTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Schema; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Enum\ToolChoiceMode; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\ToolChoice; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Schema/ToolHeaderAnnotationTest.php b/tests/Unit/Schema/ToolHeaderAnnotationTest.php index 03488940e..a1a873577 100644 --- a/tests/Unit/Schema/ToolHeaderAnnotationTest.php +++ b/tests/Unit/Schema/ToolHeaderAnnotationTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Schema; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\Tool; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\TestDox; diff --git a/tests/Unit/Schema/ToolTest.php b/tests/Unit/Schema/ToolTest.php index 30dcfa3bb..a6d79e779 100644 --- a/tests/Unit/Schema/ToolTest.php +++ b/tests/Unit/Schema/ToolTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Schema; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Enum\TaskSupport; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\Tool; use Mcp\Schema\ToolExecution; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/tests/Unit/Server/BuilderTest.php b/tests/Unit/Server/BuilderTest.php index 5f2dc3de3..32acdf3a1 100644 --- a/tests/Unit/Server/BuilderTest.php +++ b/tests/Unit/Server/BuilderTest.php @@ -12,28 +12,29 @@ namespace Mcp\Tests\Unit\Server; use Composer\Autoload\ClassLoader; -use Mcp\Capability\Discovery\DiscovererInterface; -use Mcp\Capability\Registry; -use Mcp\Capability\Registry\ElementReference; -use Mcp\Capability\Registry\Loader\LoaderInterface; -use Mcp\Capability\Registry\ReferenceHandlerInterface; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\LogicException; -use Mcp\Exception\RuntimeException; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Enum\ProtocolVersion; +use Mcp\Schema\Exception\InvalidArgumentException as SchemaInvalidArgumentException; use Mcp\Schema\Extension\Apps\McpApps; use Mcp\Schema\Implementation; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\CallToolRequest; use Mcp\Schema\ServerCapabilities; use Mcp\Schema\Tool; -use Mcp\Server; use Mcp\Server\Builder; +use Mcp\Server\Capability\Discovery\DiscovererInterface; +use Mcp\Server\Capability\Registry; +use Mcp\Server\Capability\Registry\ElementReference; +use Mcp\Server\Capability\Registry\Loader\LoaderInterface; +use Mcp\Server\Capability\Registry\ReferenceHandlerInterface; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\InvalidArgumentException as ServerInvalidArgumentException; +use Mcp\Server\Exception\LogicException; +use Mcp\Server\Exception\RuntimeException; use Mcp\Server\Handler\Request\CallToolHandler; use Mcp\Server\Handler\Request\InitializeHandler; use Mcp\Server\Protocol; +use Mcp\Server\Server; use Mcp\Server\Session\SessionInterface; use Mcp\Server\Stateless\StatelessProtocol; use Mcp\Server\Subscription\InMemoryNotificationBus; @@ -132,7 +133,7 @@ public function testCustomReferenceHandlerIsUsedForToolCalls(): void #[TestDox('Custom SchemaValidator is used when calling a tool')] public function testCustomSchemaValidatorIsUsedForToolCalls(): void { - $schemaValidator = $this->createMock(\Mcp\Capability\Discovery\SchemaValidator::class); + $schemaValidator = $this->createMock(\Mcp\Server\Capability\Discovery\SchemaValidator::class); $schemaValidator->expects($this->once()) ->method('validateAgainstJsonSchema') ->willReturn([]); @@ -406,7 +407,7 @@ public function testSetModernVersions(): void #[TestDox('setModernVersions() rejects a handshake-era revision, which the classifier would never route there')] public function testSetModernVersionsRejectsHandshakeRevision(): void { - $this->expectException(InvalidArgumentException::class); + $this->expectException(ServerInvalidArgumentException::class); $this->expectExceptionMessage(ProtocolVersion::V2025_11_25->value); Server::builder()->setModernVersions([ProtocolVersion::V2025_11_25]); @@ -422,7 +423,7 @@ private static function statelessProtocol(Server $server): ?StatelessProtocol #[TestDox('An extension identifier must be a valid _meta prefix')] public function testEnableExtensionRejectsUnprefixedIdentifier(): void { - $this->expectException(InvalidArgumentException::class); + $this->expectException(SchemaInvalidArgumentException::class); $this->expectExceptionMessage('has no prefix'); Server::builder()->enableExtension(new ThingExtension('things')); diff --git a/tests/Unit/Capability/Attribute/CompletionProviderFixture.php b/tests/Unit/Server/Capability/Attribute/CompletionProviderFixture.php similarity index 86% rename from tests/Unit/Capability/Attribute/CompletionProviderFixture.php rename to tests/Unit/Server/Capability/Attribute/CompletionProviderFixture.php index 1f4f649ed..22860418d 100644 --- a/tests/Unit/Capability/Attribute/CompletionProviderFixture.php +++ b/tests/Unit/Server/Capability/Attribute/CompletionProviderFixture.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Attribute; +namespace Mcp\Tests\Unit\Server\Capability\Attribute; -use Mcp\Capability\Completion\ProviderInterface; +use Mcp\Server\Capability\Completion\ProviderInterface; class CompletionProviderFixture implements ProviderInterface { diff --git a/tests/Unit/Capability/Attribute/CompletionProviderTest.php b/tests/Unit/Server/Capability/Attribute/CompletionProviderTest.php similarity index 96% rename from tests/Unit/Capability/Attribute/CompletionProviderTest.php rename to tests/Unit/Server/Capability/Attribute/CompletionProviderTest.php index 4b5269d3c..bea973706 100644 --- a/tests/Unit/Capability/Attribute/CompletionProviderTest.php +++ b/tests/Unit/Server/Capability/Attribute/CompletionProviderTest.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Attribute; +namespace Mcp\Tests\Unit\Server\Capability\Attribute; -use Mcp\Capability\Attribute\CompletionProvider; +use Mcp\Server\Capability\Attribute\CompletionProvider; use Mcp\Tests\Unit\Fixtures\Enum\StatusEnum; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Capability/Attribute/McpPromptTest.php b/tests/Unit/Server/Capability/Attribute/McpPromptTest.php similarity index 93% rename from tests/Unit/Capability/Attribute/McpPromptTest.php rename to tests/Unit/Server/Capability/Attribute/McpPromptTest.php index d74cbcfe1..42f1bfd62 100644 --- a/tests/Unit/Capability/Attribute/McpPromptTest.php +++ b/tests/Unit/Server/Capability/Attribute/McpPromptTest.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Attribute; +namespace Mcp\Tests\Unit\Server\Capability\Attribute; -use Mcp\Capability\Attribute\McpPrompt; +use Mcp\Server\Capability\Attribute\McpPrompt; use PHPUnit\Framework\TestCase; class McpPromptTest extends TestCase diff --git a/tests/Unit/Capability/Attribute/McpResourceTemplateTest.php b/tests/Unit/Server/Capability/Attribute/McpResourceTemplateTest.php similarity index 95% rename from tests/Unit/Capability/Attribute/McpResourceTemplateTest.php rename to tests/Unit/Server/Capability/Attribute/McpResourceTemplateTest.php index 3bbccb882..571a066fa 100644 --- a/tests/Unit/Capability/Attribute/McpResourceTemplateTest.php +++ b/tests/Unit/Server/Capability/Attribute/McpResourceTemplateTest.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Attribute; +namespace Mcp\Tests\Unit\Server\Capability\Attribute; -use Mcp\Capability\Attribute\McpResourceTemplate; +use Mcp\Server\Capability\Attribute\McpResourceTemplate; use PHPUnit\Framework\TestCase; class McpResourceTemplateTest extends TestCase diff --git a/tests/Unit/Capability/Attribute/McpResourceTest.php b/tests/Unit/Server/Capability/Attribute/McpResourceTest.php similarity index 95% rename from tests/Unit/Capability/Attribute/McpResourceTest.php rename to tests/Unit/Server/Capability/Attribute/McpResourceTest.php index 423a4122c..32855af3a 100644 --- a/tests/Unit/Capability/Attribute/McpResourceTest.php +++ b/tests/Unit/Server/Capability/Attribute/McpResourceTest.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Attribute; +namespace Mcp\Tests\Unit\Server\Capability\Attribute; -use Mcp\Capability\Attribute\McpResource; +use Mcp\Server\Capability\Attribute\McpResource; use PHPUnit\Framework\TestCase; class McpResourceTest extends TestCase diff --git a/tests/Unit/Capability/Attribute/McpToolTest.php b/tests/Unit/Server/Capability/Attribute/McpToolTest.php similarity index 96% rename from tests/Unit/Capability/Attribute/McpToolTest.php rename to tests/Unit/Server/Capability/Attribute/McpToolTest.php index e6314581b..63587bd0f 100644 --- a/tests/Unit/Capability/Attribute/McpToolTest.php +++ b/tests/Unit/Server/Capability/Attribute/McpToolTest.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Attribute; +namespace Mcp\Tests\Unit\Server\Capability\Attribute; -use Mcp\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\McpTool; use PHPUnit\Framework\TestCase; class McpToolTest extends TestCase diff --git a/tests/Unit/Capability/Completion/EnumCompletionProviderTest.php b/tests/Unit/Server/Capability/Completion/EnumCompletionProviderTest.php similarity index 91% rename from tests/Unit/Capability/Completion/EnumCompletionProviderTest.php rename to tests/Unit/Server/Capability/Completion/EnumCompletionProviderTest.php index 4bbc292ad..bfd75b22f 100644 --- a/tests/Unit/Capability/Completion/EnumCompletionProviderTest.php +++ b/tests/Unit/Server/Capability/Completion/EnumCompletionProviderTest.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Completion; +namespace Mcp\Tests\Unit\Server\Capability\Completion; -use Mcp\Capability\Completion\EnumCompletionProvider; +use Mcp\Server\Capability\Completion\EnumCompletionProvider; use PHPUnit\Framework\TestCase; enum CompletionFixture: string diff --git a/tests/Unit/Capability/Completion/ListCompletionProviderTest.php b/tests/Unit/Server/Capability/Completion/ListCompletionProviderTest.php similarity index 94% rename from tests/Unit/Capability/Completion/ListCompletionProviderTest.php rename to tests/Unit/Server/Capability/Completion/ListCompletionProviderTest.php index 729dd2bce..41c9d1a26 100644 --- a/tests/Unit/Capability/Completion/ListCompletionProviderTest.php +++ b/tests/Unit/Server/Capability/Completion/ListCompletionProviderTest.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Completion; +namespace Mcp\Tests\Unit\Server\Capability\Completion; -use Mcp\Capability\Completion\ListCompletionProvider; +use Mcp\Server\Capability\Completion\ListCompletionProvider; use PHPUnit\Framework\TestCase; final class ListCompletionProviderTest extends TestCase diff --git a/tests/Unit/Capability/Discovery/CachedDiscovererTest.php b/tests/Unit/Server/Capability/Discovery/CachedDiscovererTest.php similarity index 88% rename from tests/Unit/Capability/Discovery/CachedDiscovererTest.php rename to tests/Unit/Server/Capability/Discovery/CachedDiscovererTest.php index e4e923f37..3b45d8bb4 100644 --- a/tests/Unit/Capability/Discovery/CachedDiscovererTest.php +++ b/tests/Unit/Server/Capability/Discovery/CachedDiscovererTest.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery; +namespace Mcp\Tests\Unit\Server\Capability\Discovery; -use Mcp\Capability\Discovery\CachedDiscoverer; -use Mcp\Capability\Discovery\DiscovererInterface; -use Mcp\Capability\Discovery\DiscoveryState; +use Mcp\Server\Capability\Discovery\CachedDiscoverer; +use Mcp\Server\Capability\Discovery\DiscovererInterface; +use Mcp\Server\Capability\Discovery\DiscoveryState; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Psr\Cache\CacheItemPoolInterface; @@ -100,10 +100,22 @@ public function testEvictedGenerationDoesNotServeStaleEntries(): void $cachedDiscoverer = new CachedDiscoverer($this->discoverer(2), $pool, new NullLogger()); $cachedDiscoverer->discover('/test/path', ['.']); - $pool->deleteItem('mcp_discovery_generation'); + $pool->deleteItem('mcp_discovery_v2_generation'); $cachedDiscoverer->discover('/test/path', ['.']); } + public function testEntryOfARenamedClassIsDiscoveredAgain(): void + { + $cache = $this->createStub(CacheInterface::class); + $cache->method('get')->willReturnCallback(static fn (string $key): mixed => 'mcp_discovery_v2_generation' === $key + ? 'generation' + : unserialize('O:39:"Mcp\Capability\Discovery\DiscoveryState":0:{}')); + + $cachedDiscoverer = new CachedDiscoverer($this->discoverer(1), $cache, new NullLogger()); + + $this->assertInstanceOf(DiscoveryState::class, $cachedDiscoverer->discover('/test/path', ['.'])); + } + public function testDiscoveryRunningDuringClearCacheIsNotServedAfterwards(): void { $pool = new ArrayAdapter(); diff --git a/tests/Unit/Capability/Discovery/DiscovererToolTitleTest.php b/tests/Unit/Server/Capability/Discovery/DiscovererToolTitleTest.php similarity index 84% rename from tests/Unit/Capability/Discovery/DiscovererToolTitleTest.php rename to tests/Unit/Server/Capability/Discovery/DiscovererToolTitleTest.php index 937542562..a12617ed1 100644 --- a/tests/Unit/Capability/Discovery/DiscovererToolTitleTest.php +++ b/tests/Unit/Server/Capability/Discovery/DiscovererToolTitleTest.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery; +namespace Mcp\Tests\Unit\Server\Capability\Discovery; -use Mcp\Capability\Discovery\Discoverer; -use Mcp\Capability\Registry\ToolReference; +use Mcp\Server\Capability\Discovery\Discoverer; +use Mcp\Server\Capability\Registry\ToolReference; use PHPUnit\Framework\TestCase; class DiscovererToolTitleTest extends TestCase diff --git a/tests/Unit/Capability/Discovery/DiscoveryStateTest.php b/tests/Unit/Server/Capability/Discovery/DiscoveryStateTest.php similarity index 94% rename from tests/Unit/Capability/Discovery/DiscoveryStateTest.php rename to tests/Unit/Server/Capability/Discovery/DiscoveryStateTest.php index e40c722dd..48e18549d 100644 --- a/tests/Unit/Capability/Discovery/DiscoveryStateTest.php +++ b/tests/Unit/Server/Capability/Discovery/DiscoveryStateTest.php @@ -9,17 +9,17 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery; +namespace Mcp\Tests\Unit\Server\Capability\Discovery; -use Mcp\Capability\Discovery\DiscoveryState; -use Mcp\Capability\Registry\PromptReference; -use Mcp\Capability\Registry\ResourceReference; -use Mcp\Capability\Registry\ResourceTemplateReference; -use Mcp\Capability\Registry\ToolReference; use Mcp\Schema\Prompt; use Mcp\Schema\ResourceDefinition; use Mcp\Schema\ResourceTemplate; use Mcp\Schema\Tool; +use Mcp\Server\Capability\Discovery\DiscoveryState; +use Mcp\Server\Capability\Registry\PromptReference; +use Mcp\Server\Capability\Registry\ResourceReference; +use Mcp\Server\Capability\Registry\ResourceTemplateReference; +use Mcp\Server\Capability\Registry\ToolReference; use PHPUnit\Framework\TestCase; class DiscoveryStateTest extends TestCase diff --git a/tests/Unit/Capability/Discovery/DiscoveryTest.php b/tests/Unit/Server/Capability/Discovery/DiscoveryTest.php similarity index 91% rename from tests/Unit/Capability/Discovery/DiscoveryTest.php rename to tests/Unit/Server/Capability/Discovery/DiscoveryTest.php index 7a9a9c549..b5987d812 100644 --- a/tests/Unit/Capability/Discovery/DiscoveryTest.php +++ b/tests/Unit/Server/Capability/Discovery/DiscoveryTest.php @@ -9,21 +9,21 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery; +namespace Mcp\Tests\Unit\Server\Capability\Discovery; -use Mcp\Capability\Completion\EnumCompletionProvider; -use Mcp\Capability\Completion\ListCompletionProvider; -use Mcp\Capability\Discovery\Discoverer; -use Mcp\Capability\Registry\ToolReference; use Mcp\Schema\Extension\Apps\McpApps; -use Mcp\Tests\Unit\Capability\Attribute\CompletionProviderFixture; -use Mcp\Tests\Unit\Capability\Discovery\Fixtures\AlternativeFileNameToolHandler; -use Mcp\Tests\Unit\Capability\Discovery\Fixtures\DiscoverableToolHandler; -use Mcp\Tests\Unit\Capability\Discovery\Fixtures\InvocablePromptFixture; -use Mcp\Tests\Unit\Capability\Discovery\Fixtures\InvocableResourceFixture; -use Mcp\Tests\Unit\Capability\Discovery\Fixtures\InvocableResourceTemplateFixture; -use Mcp\Tests\Unit\Capability\Discovery\Fixtures\InvocableToolFixture; -use Mcp\Tests\Unit\Capability\Discovery\LeadingEnumFixtures\LeadingEnumToolHandler; +use Mcp\Server\Capability\Completion\EnumCompletionProvider; +use Mcp\Server\Capability\Completion\ListCompletionProvider; +use Mcp\Server\Capability\Discovery\Discoverer; +use Mcp\Server\Capability\Registry\ToolReference; +use Mcp\Tests\Unit\Server\Capability\Attribute\CompletionProviderFixture; +use Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures\AlternativeFileNameToolHandler; +use Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures\DiscoverableToolHandler; +use Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures\InvocablePromptFixture; +use Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures\InvocableResourceFixture; +use Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures\InvocableResourceTemplateFixture; +use Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures\InvocableToolFixture; +use Mcp\Tests\Unit\Server\Capability\Discovery\LeadingEnumFixtures\LeadingEnumToolHandler; use PHPUnit\Framework\TestCase; class DiscoveryTest extends TestCase diff --git a/tests/Unit/Capability/Discovery/DocBlockParserTest.php b/tests/Unit/Server/Capability/Discovery/DocBlockParserTest.php similarity index 98% rename from tests/Unit/Capability/Discovery/DocBlockParserTest.php rename to tests/Unit/Server/Capability/Discovery/DocBlockParserTest.php index 26b5c4212..8998abfcb 100644 --- a/tests/Unit/Capability/Discovery/DocBlockParserTest.php +++ b/tests/Unit/Server/Capability/Discovery/DocBlockParserTest.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery; +namespace Mcp\Tests\Unit\Server\Capability\Discovery; use Composer\InstalledVersions; use Composer\Semver\VersionParser; -use Mcp\Capability\Discovery\DocBlockParser; +use Mcp\Server\Capability\Discovery\DocBlockParser; use phpDocumentor\Reflection\DocBlock; use phpDocumentor\Reflection\DocBlock\Tags\Deprecated; use phpDocumentor\Reflection\DocBlock\Tags\Param; diff --git a/tests/Unit/Capability/Discovery/DocBlockTestFixture.php b/tests/Unit/Server/Capability/Discovery/DocBlockTestFixture.php similarity index 97% rename from tests/Unit/Capability/Discovery/DocBlockTestFixture.php rename to tests/Unit/Server/Capability/Discovery/DocBlockTestFixture.php index 7a753ddf5..2adaebca0 100644 --- a/tests/Unit/Capability/Discovery/DocBlockTestFixture.php +++ b/tests/Unit/Server/Capability/Discovery/DocBlockTestFixture.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery; +namespace Mcp\Tests\Unit\Server\Capability\Discovery; use Mcp\Tests\Capability\Discovery\Missing; diff --git a/tests/Unit/Capability/Discovery/Fixtures/AlternativeFileNameToolHandler.class.inc b/tests/Unit/Server/Capability/Discovery/Fixtures/AlternativeFileNameToolHandler.class.inc similarity index 78% rename from tests/Unit/Capability/Discovery/Fixtures/AlternativeFileNameToolHandler.class.inc rename to tests/Unit/Server/Capability/Discovery/Fixtures/AlternativeFileNameToolHandler.class.inc index 67c78eb00..c11d2e9bc 100644 --- a/tests/Unit/Capability/Discovery/Fixtures/AlternativeFileNameToolHandler.class.inc +++ b/tests/Unit/Server/Capability/Discovery/Fixtures/AlternativeFileNameToolHandler.class.inc @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery\Fixtures; +namespace Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures; -use Mcp\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\McpTool; class AlternativeFileNameToolHandler { diff --git a/tests/Unit/Capability/Discovery/Fixtures/DiscoverablePromptHandler.php b/tests/Unit/Server/Capability/Discovery/Fixtures/DiscoverablePromptHandler.php similarity index 83% rename from tests/Unit/Capability/Discovery/Fixtures/DiscoverablePromptHandler.php rename to tests/Unit/Server/Capability/Discovery/Fixtures/DiscoverablePromptHandler.php index b4a8ac6d0..1fa22b550 100644 --- a/tests/Unit/Capability/Discovery/Fixtures/DiscoverablePromptHandler.php +++ b/tests/Unit/Server/Capability/Discovery/Fixtures/DiscoverablePromptHandler.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery\Fixtures; +namespace Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures; -use Mcp\Capability\Attribute\CompletionProvider; -use Mcp\Capability\Attribute\McpPrompt; -use Mcp\Tests\Unit\Capability\Attribute\CompletionProviderFixture; +use Mcp\Server\Capability\Attribute\CompletionProvider; +use Mcp\Server\Capability\Attribute\McpPrompt; +use Mcp\Tests\Unit\Server\Capability\Attribute\CompletionProviderFixture; class DiscoverablePromptHandler { diff --git a/tests/Unit/Capability/Discovery/Fixtures/DiscoverableResourceHandler.php b/tests/Unit/Server/Capability/Discovery/Fixtures/DiscoverableResourceHandler.php similarity index 90% rename from tests/Unit/Capability/Discovery/Fixtures/DiscoverableResourceHandler.php rename to tests/Unit/Server/Capability/Discovery/Fixtures/DiscoverableResourceHandler.php index 1dfd9368c..b25172f90 100644 --- a/tests/Unit/Capability/Discovery/Fixtures/DiscoverableResourceHandler.php +++ b/tests/Unit/Server/Capability/Discovery/Fixtures/DiscoverableResourceHandler.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery\Fixtures; +namespace Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures; -use Mcp\Capability\Attribute\McpResource; use Mcp\Schema\Annotations; +use Mcp\Server\Capability\Attribute\McpResource; class DiscoverableResourceHandler { diff --git a/tests/Unit/Capability/Discovery/Fixtures/DiscoverableTemplateHandler.php b/tests/Unit/Server/Capability/Discovery/Fixtures/DiscoverableTemplateHandler.php similarity index 84% rename from tests/Unit/Capability/Discovery/Fixtures/DiscoverableTemplateHandler.php rename to tests/Unit/Server/Capability/Discovery/Fixtures/DiscoverableTemplateHandler.php index f5d266b93..2b84d91a9 100644 --- a/tests/Unit/Capability/Discovery/Fixtures/DiscoverableTemplateHandler.php +++ b/tests/Unit/Server/Capability/Discovery/Fixtures/DiscoverableTemplateHandler.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery\Fixtures; +namespace Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures; -use Mcp\Capability\Attribute\CompletionProvider; -use Mcp\Capability\Attribute\McpResourceTemplate; -use Mcp\Tests\Unit\Capability\Attribute\CompletionProviderFixture; +use Mcp\Server\Capability\Attribute\CompletionProvider; +use Mcp\Server\Capability\Attribute\McpResourceTemplate; +use Mcp\Tests\Unit\Server\Capability\Attribute\CompletionProviderFixture; class DiscoverableTemplateHandler { diff --git a/tests/Unit/Capability/Discovery/Fixtures/DiscoverableToolHandler.php b/tests/Unit/Server/Capability/Discovery/Fixtures/DiscoverableToolHandler.php similarity index 94% rename from tests/Unit/Capability/Discovery/Fixtures/DiscoverableToolHandler.php rename to tests/Unit/Server/Capability/Discovery/Fixtures/DiscoverableToolHandler.php index f20cda582..f828541cd 100644 --- a/tests/Unit/Capability/Discovery/Fixtures/DiscoverableToolHandler.php +++ b/tests/Unit/Server/Capability/Discovery/Fixtures/DiscoverableToolHandler.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery\Fixtures; +namespace Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures; -use Mcp\Capability\Attribute\McpTool; use Mcp\Schema\ToolAnnotations; +use Mcp\Server\Capability\Attribute\McpTool; use Mcp\Tests\Unit\Fixtures\Enum\BackedStringEnum; class DiscoverableToolHandler diff --git a/tests/Unit/Capability/Discovery/Fixtures/DiscoverableUiHandler.php b/tests/Unit/Server/Capability/Discovery/Fixtures/DiscoverableUiHandler.php similarity index 90% rename from tests/Unit/Capability/Discovery/Fixtures/DiscoverableUiHandler.php rename to tests/Unit/Server/Capability/Discovery/Fixtures/DiscoverableUiHandler.php index f5d03ed33..99693f621 100644 --- a/tests/Unit/Capability/Discovery/Fixtures/DiscoverableUiHandler.php +++ b/tests/Unit/Server/Capability/Discovery/Fixtures/DiscoverableUiHandler.php @@ -9,16 +9,16 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery\Fixtures; +namespace Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures; -use Mcp\Capability\Attribute\McpResource; -use Mcp\Capability\Attribute\McpTool; use Mcp\Schema\Content\TextResourceContents; use Mcp\Schema\Extension\Apps\McpApps; use Mcp\Schema\Extension\Apps\ToolVisibility; use Mcp\Schema\Extension\Apps\UiResourceContentMeta; use Mcp\Schema\Extension\Apps\UiResourceCsp; use Mcp\Schema\Extension\Apps\UiToolMeta; +use Mcp\Server\Capability\Attribute\McpResource; +use Mcp\Server\Capability\Attribute\McpTool; /** * An MCP App declared purely through attributes: a `ui://` resource flagged with the diff --git a/tests/Unit/Capability/Discovery/Fixtures/EnhancedCompletionHandler.php b/tests/Unit/Server/Capability/Discovery/Fixtures/EnhancedCompletionHandler.php similarity index 84% rename from tests/Unit/Capability/Discovery/Fixtures/EnhancedCompletionHandler.php rename to tests/Unit/Server/Capability/Discovery/Fixtures/EnhancedCompletionHandler.php index 9975f9a6f..c0df41142 100644 --- a/tests/Unit/Capability/Discovery/Fixtures/EnhancedCompletionHandler.php +++ b/tests/Unit/Server/Capability/Discovery/Fixtures/EnhancedCompletionHandler.php @@ -9,14 +9,14 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery\Fixtures; +namespace Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures; -use Mcp\Capability\Attribute\CompletionProvider; -use Mcp\Capability\Attribute\McpPrompt; -use Mcp\Capability\Attribute\McpResourceTemplate; -use Mcp\Tests\Unit\Capability\Attribute\CompletionProviderFixture; +use Mcp\Server\Capability\Attribute\CompletionProvider; +use Mcp\Server\Capability\Attribute\McpPrompt; +use Mcp\Server\Capability\Attribute\McpResourceTemplate; use Mcp\Tests\Unit\Fixtures\Enum\PriorityEnum; use Mcp\Tests\Unit\Fixtures\Enum\StatusEnum; +use Mcp\Tests\Unit\Server\Capability\Attribute\CompletionProviderFixture; class EnhancedCompletionHandler { diff --git a/tests/Unit/Capability/Discovery/Fixtures/InvocablePromptFixture.php b/tests/Unit/Server/Capability/Discovery/Fixtures/InvocablePromptFixture.php similarity index 82% rename from tests/Unit/Capability/Discovery/Fixtures/InvocablePromptFixture.php rename to tests/Unit/Server/Capability/Discovery/Fixtures/InvocablePromptFixture.php index ab94e742b..ccdcd6fa6 100644 --- a/tests/Unit/Capability/Discovery/Fixtures/InvocablePromptFixture.php +++ b/tests/Unit/Server/Capability/Discovery/Fixtures/InvocablePromptFixture.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery\Fixtures; +namespace Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures; -use Mcp\Capability\Attribute\McpPrompt; +use Mcp\Server\Capability\Attribute\McpPrompt; #[McpPrompt(name: 'InvokableGreeterPrompt')] class InvocablePromptFixture diff --git a/tests/Unit/Capability/Discovery/Fixtures/InvocableResourceFixture.php b/tests/Unit/Server/Capability/Discovery/Fixtures/InvocableResourceFixture.php similarity index 81% rename from tests/Unit/Capability/Discovery/Fixtures/InvocableResourceFixture.php rename to tests/Unit/Server/Capability/Discovery/Fixtures/InvocableResourceFixture.php index 8af2d2141..5f3519ee5 100644 --- a/tests/Unit/Capability/Discovery/Fixtures/InvocableResourceFixture.php +++ b/tests/Unit/Server/Capability/Discovery/Fixtures/InvocableResourceFixture.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery\Fixtures; +namespace Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures; -use Mcp\Capability\Attribute\McpResource; +use Mcp\Server\Capability\Attribute\McpResource; #[McpResource(uri: 'invokable://config/status', name: 'invokable_app_status')] class InvocableResourceFixture diff --git a/tests/Unit/Capability/Discovery/Fixtures/InvocableResourceTemplateFixture.php b/tests/Unit/Server/Capability/Discovery/Fixtures/InvocableResourceTemplateFixture.php similarity index 81% rename from tests/Unit/Capability/Discovery/Fixtures/InvocableResourceTemplateFixture.php rename to tests/Unit/Server/Capability/Discovery/Fixtures/InvocableResourceTemplateFixture.php index 9f95e2e81..4385b1318 100644 --- a/tests/Unit/Capability/Discovery/Fixtures/InvocableResourceTemplateFixture.php +++ b/tests/Unit/Server/Capability/Discovery/Fixtures/InvocableResourceTemplateFixture.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery\Fixtures; +namespace Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures; -use Mcp\Capability\Attribute\McpResourceTemplate; +use Mcp\Server\Capability\Attribute\McpResourceTemplate; #[McpResourceTemplate(uriTemplate: 'invokable://user-profile/{userId}')] class InvocableResourceTemplateFixture diff --git a/tests/Unit/Capability/Discovery/Fixtures/InvocableToolFixture.php b/tests/Unit/Server/Capability/Discovery/Fixtures/InvocableToolFixture.php similarity index 82% rename from tests/Unit/Capability/Discovery/Fixtures/InvocableToolFixture.php rename to tests/Unit/Server/Capability/Discovery/Fixtures/InvocableToolFixture.php index 7fa86568d..d57f8db30 100644 --- a/tests/Unit/Capability/Discovery/Fixtures/InvocableToolFixture.php +++ b/tests/Unit/Server/Capability/Discovery/Fixtures/InvocableToolFixture.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery\Fixtures; +namespace Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures; -use Mcp\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\McpTool; #[McpTool(name: 'InvokableCalculator', description: 'An invokable calculator tool.')] class InvocableToolFixture diff --git a/tests/Unit/Capability/Discovery/Fixtures/NonDiscoverableClass.php b/tests/Unit/Server/Capability/Discovery/Fixtures/NonDiscoverableClass.php similarity index 89% rename from tests/Unit/Capability/Discovery/Fixtures/NonDiscoverableClass.php rename to tests/Unit/Server/Capability/Discovery/Fixtures/NonDiscoverableClass.php index eb42d0a70..fbb3ca873 100644 --- a/tests/Unit/Capability/Discovery/Fixtures/NonDiscoverableClass.php +++ b/tests/Unit/Server/Capability/Discovery/Fixtures/NonDiscoverableClass.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery\Fixtures; +namespace Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures; class NonDiscoverableClass { diff --git a/tests/Unit/Capability/Discovery/Fixtures/SubDir/HiddenTool.php b/tests/Unit/Server/Capability/Discovery/Fixtures/SubDir/HiddenTool.php similarity index 76% rename from tests/Unit/Capability/Discovery/Fixtures/SubDir/HiddenTool.php rename to tests/Unit/Server/Capability/Discovery/Fixtures/SubDir/HiddenTool.php index 8053aa6e3..b5bf274f2 100644 --- a/tests/Unit/Capability/Discovery/Fixtures/SubDir/HiddenTool.php +++ b/tests/Unit/Server/Capability/Discovery/Fixtures/SubDir/HiddenTool.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery\Fixtures\SubDir; +namespace Mcp\Tests\Unit\Server\Capability\Discovery\Fixtures\SubDir; -use Mcp\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\McpTool; class HiddenTool { diff --git a/tests/Unit/Capability/Discovery/HandlerResolverTest.php b/tests/Unit/Server/Capability/Discovery/HandlerResolverTest.php similarity index 95% rename from tests/Unit/Capability/Discovery/HandlerResolverTest.php rename to tests/Unit/Server/Capability/Discovery/HandlerResolverTest.php index 9076a7e5c..1c2eee104 100644 --- a/tests/Unit/Capability/Discovery/HandlerResolverTest.php +++ b/tests/Unit/Server/Capability/Discovery/HandlerResolverTest.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery; +namespace Mcp\Tests\Unit\Server\Capability\Discovery; -use Mcp\Capability\Discovery\HandlerResolver; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Server\Capability\Discovery\HandlerResolver; +use Mcp\Server\Exception\InvalidArgumentException; use PHPUnit\Framework\TestCase; class HandlerResolverTest extends TestCase @@ -110,7 +110,7 @@ public function testThrowsForNonExistentClassInStringHandler(): void public function testThrowsForNonInvokableClassStringHandler(): void { $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Invokable handler class "Mcp\Tests\Unit\Capability\Discovery\NonInvokableClass" must have a public "__invoke" method.'); + $this->expectExceptionMessage('Invokable handler class "Mcp\Tests\Unit\Server\Capability\Discovery\NonInvokableClass" must have a public "__invoke" method.'); HandlerResolver::resolve(NonInvokableClass::class); } @@ -145,7 +145,7 @@ public function testThrowsForDestructorAsHandler(): void public function testThrowsForAbstractMethodHandler(): void { $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Handler method "Mcp\Tests\Unit\Capability\Discovery\AbstractHandlerClass::abstractMethod" must not be abstract.'); + $this->expectExceptionMessage('Handler method "Mcp\Tests\Unit\Server\Capability\Discovery\AbstractHandlerClass::abstractMethod" must not be abstract.'); HandlerResolver::resolve([AbstractHandlerClass::class, 'abstractMethod']); } diff --git a/tests/Unit/Capability/Discovery/LeadingEnumFixtures/LeadingEnumToolHandler.php b/tests/Unit/Server/Capability/Discovery/LeadingEnumFixtures/LeadingEnumToolHandler.php similarity index 80% rename from tests/Unit/Capability/Discovery/LeadingEnumFixtures/LeadingEnumToolHandler.php rename to tests/Unit/Server/Capability/Discovery/LeadingEnumFixtures/LeadingEnumToolHandler.php index 23174ed67..52e5673a6 100644 --- a/tests/Unit/Capability/Discovery/LeadingEnumFixtures/LeadingEnumToolHandler.php +++ b/tests/Unit/Server/Capability/Discovery/LeadingEnumFixtures/LeadingEnumToolHandler.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery\LeadingEnumFixtures; +namespace Mcp\Tests\Unit\Server\Capability\Discovery\LeadingEnumFixtures; -use Mcp\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\McpTool; enum LeadingEnumMode: string { diff --git a/tests/Unit/Capability/Discovery/NullableMemberFixture.php b/tests/Unit/Server/Capability/Discovery/NullableMemberFixture.php similarity index 95% rename from tests/Unit/Capability/Discovery/NullableMemberFixture.php rename to tests/Unit/Server/Capability/Discovery/NullableMemberFixture.php index a83f1fdf8..5711d7d84 100644 --- a/tests/Unit/Capability/Discovery/NullableMemberFixture.php +++ b/tests/Unit/Server/Capability/Discovery/NullableMemberFixture.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery; +namespace Mcp\Tests\Unit\Server\Capability\Discovery; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; diff --git a/tests/Unit/Capability/Discovery/SchemaGeneratorFixture.php b/tests/Unit/Server/Capability/Discovery/SchemaGeneratorFixture.php similarity index 99% rename from tests/Unit/Capability/Discovery/SchemaGeneratorFixture.php rename to tests/Unit/Server/Capability/Discovery/SchemaGeneratorFixture.php index 2d529e5a4..14f105c39 100644 --- a/tests/Unit/Capability/Discovery/SchemaGeneratorFixture.php +++ b/tests/Unit/Server/Capability/Discovery/SchemaGeneratorFixture.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery; +namespace Mcp\Tests\Unit\Server\Capability\Discovery; -use Mcp\Capability\Attribute\McpTool; -use Mcp\Capability\Attribute\Schema; +use Mcp\Server\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\Schema; use Mcp\Server\ClientGateway; use Mcp\Server\RequestContext; use Mcp\Tests\Unit\Fixtures\Enum\BackedIntEnum; diff --git a/tests/Unit/Capability/Discovery/SchemaGeneratorNullableMemberTest.php b/tests/Unit/Server/Capability/Discovery/SchemaGeneratorNullableMemberTest.php similarity index 92% rename from tests/Unit/Capability/Discovery/SchemaGeneratorNullableMemberTest.php rename to tests/Unit/Server/Capability/Discovery/SchemaGeneratorNullableMemberTest.php index 83a2d02b7..205922e31 100644 --- a/tests/Unit/Capability/Discovery/SchemaGeneratorNullableMemberTest.php +++ b/tests/Unit/Server/Capability/Discovery/SchemaGeneratorNullableMemberTest.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery; +namespace Mcp\Tests\Unit\Server\Capability\Discovery; -use Mcp\Capability\Discovery\DocBlockParser; -use Mcp\Capability\Discovery\SchemaGenerator; -use Mcp\Capability\Discovery\SchemaValidator; +use Mcp\Server\Capability\Discovery\DocBlockParser; +use Mcp\Server\Capability\Discovery\SchemaGenerator; +use Mcp\Server\Capability\Discovery\SchemaValidator; use PHPUnit\Framework\TestCase; final class SchemaGeneratorNullableMemberTest extends TestCase diff --git a/tests/Unit/Capability/Discovery/SchemaGeneratorTest.php b/tests/Unit/Server/Capability/Discovery/SchemaGeneratorTest.php similarity index 99% rename from tests/Unit/Capability/Discovery/SchemaGeneratorTest.php rename to tests/Unit/Server/Capability/Discovery/SchemaGeneratorTest.php index 97bb6f2db..90e57d149 100644 --- a/tests/Unit/Capability/Discovery/SchemaGeneratorTest.php +++ b/tests/Unit/Server/Capability/Discovery/SchemaGeneratorTest.php @@ -9,13 +9,13 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery; +namespace Mcp\Tests\Unit\Server\Capability\Discovery; -use Mcp\Capability\Attribute\Schema; -use Mcp\Capability\Discovery\DocBlockParser; -use Mcp\Capability\Discovery\SchemaGenerator; -use Mcp\Capability\Discovery\SchemaValidator; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Server\Capability\Attribute\Schema; +use Mcp\Server\Capability\Discovery\DocBlockParser; +use Mcp\Server\Capability\Discovery\SchemaGenerator; +use Mcp\Server\Capability\Discovery\SchemaValidator; +use Mcp\Server\Exception\InvalidArgumentException; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Capability/Discovery/SchemaGeneratorUnionTest.php b/tests/Unit/Server/Capability/Discovery/SchemaGeneratorUnionTest.php similarity index 96% rename from tests/Unit/Capability/Discovery/SchemaGeneratorUnionTest.php rename to tests/Unit/Server/Capability/Discovery/SchemaGeneratorUnionTest.php index eb5672bde..859f2b034 100644 --- a/tests/Unit/Capability/Discovery/SchemaGeneratorUnionTest.php +++ b/tests/Unit/Server/Capability/Discovery/SchemaGeneratorUnionTest.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery; +namespace Mcp\Tests\Unit\Server\Capability\Discovery; -use Mcp\Capability\Discovery\DocBlockParser; -use Mcp\Capability\Discovery\SchemaGenerator; -use Mcp\Capability\Discovery\SchemaValidator; +use Mcp\Server\Capability\Discovery\DocBlockParser; +use Mcp\Server\Capability\Discovery\SchemaGenerator; +use Mcp\Server\Capability\Discovery\SchemaValidator; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Capability/Discovery/SchemaValidatorTest.php b/tests/Unit/Server/Capability/Discovery/SchemaValidatorTest.php similarity index 99% rename from tests/Unit/Capability/Discovery/SchemaValidatorTest.php rename to tests/Unit/Server/Capability/Discovery/SchemaValidatorTest.php index 199fce297..d62a9311c 100644 --- a/tests/Unit/Capability/Discovery/SchemaValidatorTest.php +++ b/tests/Unit/Server/Capability/Discovery/SchemaValidatorTest.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery; +namespace Mcp\Tests\Unit\Server\Capability\Discovery; -use Mcp\Capability\Attribute\Schema; -use Mcp\Capability\Discovery\SchemaValidator; +use Mcp\Server\Capability\Attribute\Schema; +use Mcp\Server\Capability\Discovery\SchemaValidator; use Opis\JsonSchema\SchemaLoader; use Opis\JsonSchema\Validator; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/tests/Unit/Capability/Discovery/UnionFixture.php b/tests/Unit/Server/Capability/Discovery/UnionFixture.php similarity index 94% rename from tests/Unit/Capability/Discovery/UnionFixture.php rename to tests/Unit/Server/Capability/Discovery/UnionFixture.php index b6d400d0d..022bb3194 100644 --- a/tests/Unit/Capability/Discovery/UnionFixture.php +++ b/tests/Unit/Server/Capability/Discovery/UnionFixture.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Discovery; +namespace Mcp\Tests\Unit\Server\Capability\Discovery; class UnionFixture { diff --git a/tests/Unit/Capability/Discovery/UnloadableFixtures/OrphanedHandler.php b/tests/Unit/Server/Capability/Discovery/UnloadableFixtures/OrphanedHandler.php similarity index 74% rename from tests/Unit/Capability/Discovery/UnloadableFixtures/OrphanedHandler.php rename to tests/Unit/Server/Capability/Discovery/UnloadableFixtures/OrphanedHandler.php index 81a8ea346..4fe84b23a 100644 --- a/tests/Unit/Capability/Discovery/UnloadableFixtures/OrphanedHandler.php +++ b/tests/Unit/Server/Capability/Discovery/UnloadableFixtures/OrphanedHandler.php @@ -12,12 +12,12 @@ /* * The namespace deliberately does not match this file's path, so PSR-4 cannot * autoload the class and discovery has to skip the file. See - * {@see \Mcp\Tests\Unit\Capability\Discovery\DiscoveryTest}. + * {@see \Mcp\Tests\Unit\Server\Capability\Discovery\DiscoveryTest}. */ -namespace Mcp\Tests\Unit\Capability\Discovery\NotWhereThisFileLives; +namespace Mcp\Tests\Unit\Server\Capability\Discovery\NotWhereThisFileLives; -use Mcp\Capability\Attribute\McpTool; +use Mcp\Server\Capability\Attribute\McpTool; final class OrphanedHandler { diff --git a/tests/Unit/Capability/Formatter/PromptResultFormatterTest.php b/tests/Unit/Server/Capability/Formatter/PromptResultFormatterTest.php similarity index 98% rename from tests/Unit/Capability/Formatter/PromptResultFormatterTest.php rename to tests/Unit/Server/Capability/Formatter/PromptResultFormatterTest.php index b89c5eaea..14c146075 100644 --- a/tests/Unit/Capability/Formatter/PromptResultFormatterTest.php +++ b/tests/Unit/Server/Capability/Formatter/PromptResultFormatterTest.php @@ -9,10 +9,8 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Formatter; +namespace Mcp\Tests\Unit\Server\Capability\Formatter; -use Mcp\Capability\Formatter\PromptResultFormatter; -use Mcp\Exception\RuntimeException; use Mcp\Schema\Content\AudioContent; use Mcp\Schema\Content\EmbeddedResource; use Mcp\Schema\Content\ImageContent; @@ -20,6 +18,8 @@ use Mcp\Schema\Content\ResourceLink; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Enum\Role; +use Mcp\Server\Capability\Formatter\PromptResultFormatter; +use Mcp\Server\Exception\RuntimeException; use PHPUnit\Framework\TestCase; class PromptResultFormatterTest extends TestCase diff --git a/tests/Unit/Capability/Formatter/ResourceResultFormatterTest.php b/tests/Unit/Server/Capability/Formatter/ResourceResultFormatterTest.php similarity index 97% rename from tests/Unit/Capability/Formatter/ResourceResultFormatterTest.php rename to tests/Unit/Server/Capability/Formatter/ResourceResultFormatterTest.php index c16468392..6676c54a4 100644 --- a/tests/Unit/Capability/Formatter/ResourceResultFormatterTest.php +++ b/tests/Unit/Server/Capability/Formatter/ResourceResultFormatterTest.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Formatter; +namespace Mcp\Tests\Unit\Server\Capability\Formatter; -use Mcp\Capability\Formatter\ResourceResultFormatter; use Mcp\Schema\Content\BlobResourceContents; use Mcp\Schema\Content\TextResourceContents; +use Mcp\Server\Capability\Formatter\ResourceResultFormatter; use PHPUnit\Framework\TestCase; class ResourceResultFormatterTest extends TestCase diff --git a/tests/Unit/Capability/Formatter/ToolResultFormatterTest.php b/tests/Unit/Server/Capability/Formatter/ToolResultFormatterTest.php similarity index 95% rename from tests/Unit/Capability/Formatter/ToolResultFormatterTest.php rename to tests/Unit/Server/Capability/Formatter/ToolResultFormatterTest.php index 5efac21cc..50086a177 100644 --- a/tests/Unit/Capability/Formatter/ToolResultFormatterTest.php +++ b/tests/Unit/Server/Capability/Formatter/ToolResultFormatterTest.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Formatter; +namespace Mcp\Tests\Unit\Server\Capability\Formatter; -use Mcp\Capability\Formatter\ToolResultFormatter; use Mcp\Schema\Content\TextContent; +use Mcp\Server\Capability\Formatter\ToolResultFormatter; use PHPUnit\Framework\TestCase; class ToolResultFormatterTest extends TestCase diff --git a/tests/Unit/Capability/Logger/ClientLoggerTest.php b/tests/Unit/Server/Capability/Logger/ClientLoggerTest.php similarity index 92% rename from tests/Unit/Capability/Logger/ClientLoggerTest.php rename to tests/Unit/Server/Capability/Logger/ClientLoggerTest.php index 13010ce8e..99ecc1e84 100644 --- a/tests/Unit/Capability/Logger/ClientLoggerTest.php +++ b/tests/Unit/Server/Capability/Logger/ClientLoggerTest.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Logger; +namespace Mcp\Tests\Unit\Server\Capability\Logger; -use Mcp\Capability\Logger\ClientLogger; use Mcp\Schema\Enum\LoggingLevel; +use Mcp\Server\Capability\Logger\ClientLogger; use Mcp\Server\ClientGateway; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Capability/Registry/Loader/ChainLoaderTest.php b/tests/Unit/Server/Capability/Registry/Loader/ChainLoaderTest.php similarity index 83% rename from tests/Unit/Capability/Registry/Loader/ChainLoaderTest.php rename to tests/Unit/Server/Capability/Registry/Loader/ChainLoaderTest.php index e2c68d459..8aebbb678 100644 --- a/tests/Unit/Capability/Registry/Loader/ChainLoaderTest.php +++ b/tests/Unit/Server/Capability/Registry/Loader/ChainLoaderTest.php @@ -9,12 +9,12 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Registry\Loader; +namespace Mcp\Tests\Unit\Server\Capability\Registry\Loader; -use Mcp\Capability\Registry; -use Mcp\Capability\Registry\Loader\ChainLoader; -use Mcp\Tests\Unit\Capability\Registry\Loader\Stub\RecordingLoader; -use Mcp\Tests\Unit\Capability\Registry\Loader\Stub\ToolWriterLoader; +use Mcp\Server\Capability\Registry; +use Mcp\Server\Capability\Registry\Loader\ChainLoader; +use Mcp\Tests\Unit\Server\Capability\Registry\Loader\Stub\RecordingLoader; +use Mcp\Tests\Unit\Server\Capability\Registry\Loader\Stub\ToolWriterLoader; use PHPUnit\Framework\TestCase; class ChainLoaderTest extends TestCase diff --git a/tests/Unit/Capability/Registry/Loader/DiscoveryLoaderTest.php b/tests/Unit/Server/Capability/Registry/Loader/DiscoveryLoaderTest.php similarity index 94% rename from tests/Unit/Capability/Registry/Loader/DiscoveryLoaderTest.php rename to tests/Unit/Server/Capability/Registry/Loader/DiscoveryLoaderTest.php index 25279a9f8..0eb18b4e3 100644 --- a/tests/Unit/Capability/Registry/Loader/DiscoveryLoaderTest.php +++ b/tests/Unit/Server/Capability/Registry/Loader/DiscoveryLoaderTest.php @@ -9,25 +9,25 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Registry\Loader; - -use Mcp\Capability\Completion\EnumCompletionProvider; -use Mcp\Capability\Completion\ListCompletionProvider; -use Mcp\Capability\Discovery\DiscoveryState; -use Mcp\Capability\Registry; -use Mcp\Capability\Registry\Loader\DiscoveryLoader; -use Mcp\Capability\Registry\PromptReference; -use Mcp\Capability\Registry\ResourceReference; -use Mcp\Capability\Registry\ResourceTemplateReference; -use Mcp\Capability\Registry\ToolReference; -use Mcp\Exception\PromptNotFoundException; -use Mcp\Exception\ResourceNotFoundException; -use Mcp\Exception\ToolNotFoundException; +namespace Mcp\Tests\Unit\Server\Capability\Registry\Loader; + use Mcp\Schema\Prompt; use Mcp\Schema\ResourceDefinition; use Mcp\Schema\ResourceTemplate; use Mcp\Schema\Tool; -use Mcp\Tests\Unit\Capability\Registry\Loader\Stub\MutableDiscoverer; +use Mcp\Server\Capability\Completion\EnumCompletionProvider; +use Mcp\Server\Capability\Completion\ListCompletionProvider; +use Mcp\Server\Capability\Discovery\DiscoveryState; +use Mcp\Server\Capability\Registry; +use Mcp\Server\Capability\Registry\Loader\DiscoveryLoader; +use Mcp\Server\Capability\Registry\PromptReference; +use Mcp\Server\Capability\Registry\ResourceReference; +use Mcp\Server\Capability\Registry\ResourceTemplateReference; +use Mcp\Server\Capability\Registry\ToolReference; +use Mcp\Server\Exception\PromptNotFoundException; +use Mcp\Server\Exception\ResourceNotFoundException; +use Mcp\Server\Exception\ToolNotFoundException; +use Mcp\Tests\Unit\Server\Capability\Registry\Loader\Stub\MutableDiscoverer; use PHPUnit\Framework\TestCase; class DiscoveryLoaderTest extends TestCase diff --git a/tests/Unit/Capability/Registry/Loader/ExplicitElementLoaderTest.php b/tests/Unit/Server/Capability/Registry/Loader/ExplicitElementLoaderTest.php similarity index 91% rename from tests/Unit/Capability/Registry/Loader/ExplicitElementLoaderTest.php rename to tests/Unit/Server/Capability/Registry/Loader/ExplicitElementLoaderTest.php index 4abb75040..4d4c49c5e 100644 --- a/tests/Unit/Capability/Registry/Loader/ExplicitElementLoaderTest.php +++ b/tests/Unit/Server/Capability/Registry/Loader/ExplicitElementLoaderTest.php @@ -9,25 +9,26 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Registry\Loader; - -use Mcp\Capability\Completion\ProviderInterface; -use Mcp\Capability\Registry; -use Mcp\Capability\Registry\ReferenceHandler; -use Mcp\Capability\Registry\ResourceReference; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\InvalidArgumentException; +namespace Mcp\Tests\Unit\Server\Capability\Registry\Loader; + use Mcp\Schema\Prompt; use Mcp\Schema\Request\PingRequest; use Mcp\Schema\ResourceDefinition; use Mcp\Schema\ResourceTemplate; use Mcp\Schema\Tool; -use Mcp\Server; +use Mcp\Server\Builder; +use Mcp\Server\Capability\Completion\ProviderInterface; +use Mcp\Server\Capability\Registry; +use Mcp\Server\Capability\Registry\ReferenceHandler; +use Mcp\Server\Capability\Registry\ResourceReference; +use Mcp\Server\Capability\RegistryInterface; use Mcp\Server\ClientGateway; +use Mcp\Server\Exception\InvalidArgumentException; use Mcp\Server\Handler\PromptHandlerInterface; use Mcp\Server\Handler\ResourceHandlerInterface; use Mcp\Server\Handler\ResourceTemplateHandlerInterface; use Mcp\Server\Handler\ToolHandlerInterface; +use Mcp\Server\Server; use Mcp\Server\Session\SessionInterface; use PHPUnit\Framework\TestCase; use Symfony\Component\Uid\Uuid; @@ -57,7 +58,7 @@ public function execute(array $arguments, ClientGateway $gateway): mixed } }; - $registry = $this->buildAndGetRegistry(static fn (Server\Builder $b) => $b->add($tool, $handler)); + $registry = $this->buildAndGetRegistry(static fn (Builder $b) => $b->add($tool, $handler)); $reference = $registry->getTool('demo'); $this->assertSame('demo', $reference->tool->name); @@ -99,7 +100,7 @@ public function read(string $uri, ClientGateway $gateway): mixed } }; - $registry = $this->buildAndGetRegistry(static fn (Server\Builder $b) => $b->add($resource, $handler)); + $registry = $this->buildAndGetRegistry(static fn (Builder $b) => $b->add($resource, $handler)); $reference = $registry->getResource('config://demo', false); $this->assertInstanceOf(ResourceReference::class, $reference); @@ -144,7 +145,7 @@ public function read(string $uri, array $variables, ClientGateway $gateway): mix } }; - $registry = $this->buildAndGetRegistry(static fn (Server\Builder $b) => $b->add($template, $handler)); + $registry = $this->buildAndGetRegistry(static fn (Builder $b) => $b->add($template, $handler)); $reference = $registry->getResourceTemplate('config://{key}'); $this->assertSame('config://{key}', $reference->resourceTemplate->uriTemplate); @@ -187,7 +188,7 @@ public function get(array $arguments, ClientGateway $gateway): mixed } }; - $registry = $this->buildAndGetRegistry(static fn (Server\Builder $b) => $b->add($prompt, $handler)); + $registry = $this->buildAndGetRegistry(static fn (Builder $b) => $b->add($prompt, $handler)); $reference = $registry->getPrompt('demo_prompt'); $this->assertSame('demo_prompt', $reference->prompt->name); @@ -223,7 +224,7 @@ public function getCompletions(string $currentValue): array } }; - $registry = $this->buildAndGetRegistry(static fn (Server\Builder $b) => $b->add( + $registry = $this->buildAndGetRegistry(static fn (Builder $b) => $b->add( $prompt, $handler, ['name' => $provider], @@ -253,7 +254,7 @@ public function getCompletions(string $currentValue): array } }; - $registry = $this->buildAndGetRegistry(static fn (Server\Builder $b) => $b->add( + $registry = $this->buildAndGetRegistry(static fn (Builder $b) => $b->add( $template, $handler, ['key' => $provider], @@ -273,7 +274,7 @@ public function get(array $arguments, ClientGateway $gateway): mixed } }; - $registry = $this->buildAndGetRegistry(static fn (Server\Builder $b) => $b->add($prompt, $handler)); + $registry = $this->buildAndGetRegistry(static fn (Builder $b) => $b->add($prompt, $handler)); $this->assertSame([], $registry->getPrompt('no_completion')->completionProviders); } @@ -365,14 +366,14 @@ public function execute(array $arguments, ClientGateway $gateway): mixed } }; - $registry = $this->buildAndGetRegistry(static fn (Server\Builder $b) => $b->add($tool, $handler)); + $registry = $this->buildAndGetRegistry(static fn (Builder $b) => $b->add($tool, $handler)); $reference = $registry->getTool('closure_check'); $this->assertInstanceOf(\Closure::class, $reference->handler); } /** - * @param callable(Server\Builder): Server\Builder $configure + * @param callable(Builder): Builder $configure */ private function buildAndGetRegistry(callable $configure): RegistryInterface { diff --git a/tests/Unit/Capability/Registry/Loader/ReflectedElementLoaderResourceTitleTest.php b/tests/Unit/Server/Capability/Registry/Loader/ReflectedElementLoaderResourceTitleTest.php similarity index 90% rename from tests/Unit/Capability/Registry/Loader/ReflectedElementLoaderResourceTitleTest.php rename to tests/Unit/Server/Capability/Registry/Loader/ReflectedElementLoaderResourceTitleTest.php index a8308a12b..2d280bf29 100644 --- a/tests/Unit/Capability/Registry/Loader/ReflectedElementLoaderResourceTitleTest.php +++ b/tests/Unit/Server/Capability/Registry/Loader/ReflectedElementLoaderResourceTitleTest.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Registry\Loader; +namespace Mcp\Tests\Unit\Server\Capability\Registry\Loader; -use Mcp\Capability\Registry; -use Mcp\Capability\Registry\Loader\ReflectedElementLoader; -use Mcp\Capability\Registry\ResourceReference; +use Mcp\Server\Capability\Registry; +use Mcp\Server\Capability\Registry\Loader\ReflectedElementLoader; +use Mcp\Server\Capability\Registry\ResourceReference; use PHPUnit\Framework\TestCase; class ReflectedElementLoaderResourceTitleTest extends TestCase diff --git a/tests/Unit/Capability/Registry/Loader/ReflectedElementLoaderToolTitleTest.php b/tests/Unit/Server/Capability/Registry/Loader/ReflectedElementLoaderToolTitleTest.php similarity index 88% rename from tests/Unit/Capability/Registry/Loader/ReflectedElementLoaderToolTitleTest.php rename to tests/Unit/Server/Capability/Registry/Loader/ReflectedElementLoaderToolTitleTest.php index 8537fcc86..6c97e57ab 100644 --- a/tests/Unit/Capability/Registry/Loader/ReflectedElementLoaderToolTitleTest.php +++ b/tests/Unit/Server/Capability/Registry/Loader/ReflectedElementLoaderToolTitleTest.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Registry\Loader; +namespace Mcp\Tests\Unit\Server\Capability\Registry\Loader; -use Mcp\Capability\Registry; -use Mcp\Capability\Registry\Loader\ReflectedElementLoader; +use Mcp\Server\Capability\Registry; +use Mcp\Server\Capability\Registry\Loader\ReflectedElementLoader; use PHPUnit\Framework\TestCase; class ReflectedElementLoaderToolTitleTest extends TestCase diff --git a/tests/Unit/Capability/Registry/Loader/Stub/MutableDiscoverer.php b/tests/Unit/Server/Capability/Registry/Loader/Stub/MutableDiscoverer.php similarity index 77% rename from tests/Unit/Capability/Registry/Loader/Stub/MutableDiscoverer.php rename to tests/Unit/Server/Capability/Registry/Loader/Stub/MutableDiscoverer.php index 0b5b298b0..16812a322 100644 --- a/tests/Unit/Capability/Registry/Loader/Stub/MutableDiscoverer.php +++ b/tests/Unit/Server/Capability/Registry/Loader/Stub/MutableDiscoverer.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Registry\Loader\Stub; +namespace Mcp\Tests\Unit\Server\Capability\Registry\Loader\Stub; -use Mcp\Capability\Discovery\DiscovererInterface; -use Mcp\Capability\Discovery\DiscoveryState; +use Mcp\Server\Capability\Discovery\DiscovererInterface; +use Mcp\Server\Capability\Discovery\DiscoveryState; final class MutableDiscoverer implements DiscovererInterface { diff --git a/tests/Unit/Capability/Registry/Loader/Stub/RecordingLoader.php b/tests/Unit/Server/Capability/Registry/Loader/Stub/RecordingLoader.php similarity index 77% rename from tests/Unit/Capability/Registry/Loader/Stub/RecordingLoader.php rename to tests/Unit/Server/Capability/Registry/Loader/Stub/RecordingLoader.php index a1eccae1c..21fbeb4fe 100644 --- a/tests/Unit/Capability/Registry/Loader/Stub/RecordingLoader.php +++ b/tests/Unit/Server/Capability/Registry/Loader/Stub/RecordingLoader.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Registry\Loader\Stub; +namespace Mcp\Tests\Unit\Server\Capability\Registry\Loader\Stub; -use Mcp\Capability\Registry\Loader\LoaderInterface; -use Mcp\Capability\RegistryInterface; +use Mcp\Server\Capability\Registry\Loader\LoaderInterface; +use Mcp\Server\Capability\RegistryInterface; final class RecordingLoader implements LoaderInterface { diff --git a/tests/Unit/Capability/Registry/Loader/Stub/ToolWriterLoader.php b/tests/Unit/Server/Capability/Registry/Loader/Stub/ToolWriterLoader.php similarity index 83% rename from tests/Unit/Capability/Registry/Loader/Stub/ToolWriterLoader.php rename to tests/Unit/Server/Capability/Registry/Loader/Stub/ToolWriterLoader.php index d8ae3f13b..ee204963c 100644 --- a/tests/Unit/Capability/Registry/Loader/Stub/ToolWriterLoader.php +++ b/tests/Unit/Server/Capability/Registry/Loader/Stub/ToolWriterLoader.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Registry\Loader\Stub; +namespace Mcp\Tests\Unit\Server\Capability\Registry\Loader\Stub; -use Mcp\Capability\Registry\Loader\LoaderInterface; -use Mcp\Capability\RegistryInterface; use Mcp\Schema\Tool; +use Mcp\Server\Capability\Registry\Loader\LoaderInterface; +use Mcp\Server\Capability\RegistryInterface; final class ToolWriterLoader implements LoaderInterface { diff --git a/tests/Unit/Capability/Registry/ReferenceHandlerTest.php b/tests/Unit/Server/Capability/Registry/ReferenceHandlerTest.php similarity index 98% rename from tests/Unit/Capability/Registry/ReferenceHandlerTest.php rename to tests/Unit/Server/Capability/Registry/ReferenceHandlerTest.php index 83b60ea17..b1ad60b7e 100644 --- a/tests/Unit/Capability/Registry/ReferenceHandlerTest.php +++ b/tests/Unit/Server/Capability/Registry/ReferenceHandlerTest.php @@ -9,16 +9,16 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Registry; +namespace Mcp\Tests\Unit\Server\Capability\Registry; -use Mcp\Capability\Registry\Container; -use Mcp\Capability\Registry\ElementReference; -use Mcp\Capability\Registry\ReferenceHandler; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\RegistryException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\Request\PingRequest; +use Mcp\Server\Capability\Registry\Container; +use Mcp\Server\Capability\Registry\ElementReference; +use Mcp\Server\Capability\Registry\ReferenceHandler; use Mcp\Server\ClientGateway; +use Mcp\Server\Exception\InvalidArgumentException; +use Mcp\Server\Exception\RegistryException; use Mcp\Server\Handler\ResourceHandlerInterface; use Mcp\Server\Handler\ToolHandlerInterface; use Mcp\Server\Session\SessionInterface; diff --git a/tests/Unit/Capability/RegistryTest.php b/tests/Unit/Server/Capability/RegistryTest.php similarity index 98% rename from tests/Unit/Capability/RegistryTest.php rename to tests/Unit/Server/Capability/RegistryTest.php index caeba9f11..62c2ee985 100644 --- a/tests/Unit/Capability/RegistryTest.php +++ b/tests/Unit/Server/Capability/RegistryTest.php @@ -9,20 +9,8 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability; - -use Mcp\Capability\Completion\EnumCompletionProvider; -use Mcp\Capability\Registry; -use Mcp\Capability\Registry\Loader\LoaderInterface; -use Mcp\Capability\Registry\PromptReference; -use Mcp\Capability\Registry\ResourceReference; -use Mcp\Capability\Registry\ResourceTemplateReference; -use Mcp\Capability\Registry\ToolReference; -use Mcp\Capability\RegistryInterface; -use Mcp\Event\ToolListChangedEvent; -use Mcp\Exception\PromptNotFoundException; -use Mcp\Exception\ResourceNotFoundException; -use Mcp\Exception\ToolNotFoundException; +namespace Mcp\Tests\Unit\Server\Capability; + use Mcp\Schema\Content\ResourceLink; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Enum\ProtocolVersion; @@ -32,6 +20,18 @@ use Mcp\Schema\ResourceTemplate; use Mcp\Schema\Result\CallToolResult; use Mcp\Schema\Tool; +use Mcp\Server\Capability\Completion\EnumCompletionProvider; +use Mcp\Server\Capability\Registry; +use Mcp\Server\Capability\Registry\Loader\LoaderInterface; +use Mcp\Server\Capability\Registry\PromptReference; +use Mcp\Server\Capability\Registry\ResourceReference; +use Mcp\Server\Capability\Registry\ResourceTemplateReference; +use Mcp\Server\Capability\Registry\ToolReference; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Event\ToolListChangedEvent; +use Mcp\Server\Exception\PromptNotFoundException; +use Mcp\Server\Exception\ResourceNotFoundException; +use Mcp\Server\Exception\ToolNotFoundException; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\EventDispatcher\EventDispatcherInterface; diff --git a/tests/Unit/Capability/Tool/NameValidatorTest.php b/tests/Unit/Server/Capability/Tool/NameValidatorTest.php similarity index 93% rename from tests/Unit/Capability/Tool/NameValidatorTest.php rename to tests/Unit/Server/Capability/Tool/NameValidatorTest.php index 26b32c166..6417488bf 100644 --- a/tests/Unit/Capability/Tool/NameValidatorTest.php +++ b/tests/Unit/Server/Capability/Tool/NameValidatorTest.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit\Capability\Tool; +namespace Mcp\Tests\Unit\Server\Capability\Tool; -use Mcp\Capability\Tool\NameValidator; +use Mcp\Server\Capability\Tool\NameValidator; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Server/ClientGatewayTest.php b/tests/Unit/Server/ClientGatewayTest.php index a85dc8458..3d4453d94 100644 --- a/tests/Unit/Server/ClientGatewayTest.php +++ b/tests/Unit/Server/ClientGatewayTest.php @@ -11,8 +11,6 @@ namespace Mcp\Tests\Unit\Server; -use Mcp\Exception\ClientException; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\ClientCapabilities; use Mcp\Schema\Elicitation\ElicitationSchema; use Mcp\Schema\Elicitation\StringSchemaDefinition; @@ -31,6 +29,8 @@ use Mcp\Schema\Result\ElicitResult; use Mcp\Schema\Result\ListRootsResult; use Mcp\Server\ClientGateway; +use Mcp\Server\Exception\ClientException; +use Mcp\Server\Exception\InvalidArgumentException; use Mcp\Server\Protocol; use Mcp\Server\Session\SessionInterface; use Mcp\Server\Suspension\NotificationSuspension; diff --git a/tests/Unit/Server/Extension/ThingExtension.php b/tests/Unit/Server/Extension/ThingExtension.php index 88d862df6..102a6f09e 100644 --- a/tests/Unit/Server/Extension/ThingExtension.php +++ b/tests/Unit/Server/Extension/ThingExtension.php @@ -12,13 +12,13 @@ namespace Mcp\Tests\Unit\Server\Extension; use Mcp\Schema\Extension\ExtensionIdentifier; -use Mcp\Schema\Extension\ExtensionInterface; +use Mcp\Server\Extension\ServerExtensionInterface; /** * A minimal extension: an identifier, a capability payload, and one method it * defines and serves. */ -final class ThingExtension implements ExtensionInterface +final class ThingExtension implements ServerExtensionInterface { public function __construct( private readonly string $id = 'com.example/things', diff --git a/tests/Unit/Server/Extension/UnservedThingExtension.php b/tests/Unit/Server/Extension/UnservedThingExtension.php index 43a92076a..994746a34 100644 --- a/tests/Unit/Server/Extension/UnservedThingExtension.php +++ b/tests/Unit/Server/Extension/UnservedThingExtension.php @@ -34,9 +34,4 @@ public function getMessages(): array { return [ThingListRequest::class]; } - - public function getRequestHandlers(): iterable - { - return []; - } } diff --git a/tests/Unit/Server/Fiber/EventLoopSessionLockTest.php b/tests/Unit/Server/Fiber/EventLoopSessionLockTest.php index 89f1eac96..6f0300eb8 100644 --- a/tests/Unit/Server/Fiber/EventLoopSessionLockTest.php +++ b/tests/Unit/Server/Fiber/EventLoopSessionLockTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Server\Fiber; -use Mcp\Exception\SessionLockException; +use Mcp\Server\Exception\SessionLockException; use Mcp\Server\Fiber\EventLoopSessionLock; use Mcp\Server\Fiber\FiberSchedulerInterface; use Mcp\Server\Fiber\FiberSettlement; diff --git a/tests/Unit/Server/Fiber/EventLoopToolCallTest.php b/tests/Unit/Server/Fiber/EventLoopToolCallTest.php index 1f383b304..4fedc8d38 100644 --- a/tests/Unit/Server/Fiber/EventLoopToolCallTest.php +++ b/tests/Unit/Server/Fiber/EventLoopToolCallTest.php @@ -11,19 +11,19 @@ namespace Mcp\Tests\Unit\Server\Fiber; -use Mcp\Event\ErrorEvent; -use Mcp\Event\ResponseEvent; use Mcp\Schema\Enum\ProtocolVersion; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Notification\ToolListChangedNotification; use Mcp\Schema\Request\CallToolRequest; -use Mcp\Server; +use Mcp\Schema\RequestMeta; +use Mcp\Server\Event\ErrorEvent; +use Mcp\Server\Event\ResponseEvent; use Mcp\Server\Handler\Request\RequestHandlerInterface; use Mcp\Server\RequestContext; +use Mcp\Server\Server; use Mcp\Server\Session\SessionInterface; -use Mcp\Server\Stateless\RequestMeta; use Mcp\Server\Transport\StdioTransport; use Mcp\Server\Transport\StreamableHttpTransport; use Nyholm\Psr7\Factory\Psr17Factory; diff --git a/tests/Unit/Server/Fiber/FiberContextTest.php b/tests/Unit/Server/Fiber/FiberContextTest.php index 6307e86ec..215547b46 100644 --- a/tests/Unit/Server/Fiber/FiberContextTest.php +++ b/tests/Unit/Server/Fiber/FiberContextTest.php @@ -11,13 +11,13 @@ namespace Mcp\Tests\Unit\Server\Fiber; -use Mcp\Exception\RuntimeException; use Mcp\Schema\Elicitation\ElicitationSchema; use Mcp\Schema\Elicitation\StringSchemaDefinition; -use Mcp\Server; +use Mcp\Schema\RequestMeta; use Mcp\Server\Builder; +use Mcp\Server\Exception\RuntimeException; use Mcp\Server\RequestContext; -use Mcp\Server\Stateless\RequestMeta; +use Mcp\Server\Server; use Mcp\Server\Stateless\StatelessProtocol; use Mcp\Server\Transport\StatelessHttpTransport; use Mcp\Server\Transport\StdioTransport; diff --git a/tests/Unit/Server/Fiber/HandlerFibersTest.php b/tests/Unit/Server/Fiber/HandlerFibersTest.php index 00edf2b2a..9856f5d4e 100644 --- a/tests/Unit/Server/Fiber/HandlerFibersTest.php +++ b/tests/Unit/Server/Fiber/HandlerFibersTest.php @@ -11,10 +11,10 @@ namespace Mcp\Tests\Unit\Server\Fiber; -use Mcp\Exception\LogicException; use Mcp\Schema\Enum\LoggingLevel; use Mcp\Schema\Notification\ToolListChangedNotification; use Mcp\Schema\Request\PingRequest; +use Mcp\Server\Exception\LogicException; use Mcp\Server\Fiber\FiberSchedulerInterface; use Mcp\Server\Fiber\FiberSettlement; use Mcp\Server\Fiber\HandlerFibers; diff --git a/tests/Unit/Server/Fiber/RealEventLoopTest.php b/tests/Unit/Server/Fiber/RealEventLoopTest.php index f2b165812..a5ab076cc 100644 --- a/tests/Unit/Server/Fiber/RealEventLoopTest.php +++ b/tests/Unit/Server/Fiber/RealEventLoopTest.php @@ -17,13 +17,13 @@ use Mcp\Schema\Elicitation\StringSchemaDefinition; use Mcp\Schema\Enum\ProtocolVersion; use Mcp\Schema\Notification\ToolListChangedNotification; -use Mcp\Server; +use Mcp\Schema\RequestMeta; use Mcp\Server\Builder; use Mcp\Server\Fiber\FiberSchedulerInterface; use Mcp\Server\RequestContext; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionLock; use Mcp\Server\Session\InMemorySessionStore; -use Mcp\Server\Stateless\RequestMeta; use Mcp\Server\Transport\CallbackStream; use Mcp\Server\Transport\StreamableHttpTransport; use Mcp\Tests\Unit\Fixtures\RecordingFiberContext; diff --git a/tests/Unit/Server/Handler/Request/CallToolHandlerTest.php b/tests/Unit/Server/Handler/Request/CallToolHandlerTest.php index 2101144a4..e19ac9339 100644 --- a/tests/Unit/Server/Handler/Request/CallToolHandlerTest.php +++ b/tests/Unit/Server/Handler/Request/CallToolHandlerTest.php @@ -11,12 +11,6 @@ namespace Mcp\Tests\Unit\Server\Handler\Request; -use Mcp\Capability\Registry\ReferenceHandlerInterface; -use Mcp\Capability\Registry\ToolReference; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\RegistryException; -use Mcp\Exception\ToolCallException; -use Mcp\Exception\ToolNotFoundException; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Enum\ProtocolVersion; use Mcp\Schema\JsonRpc\Error; @@ -24,6 +18,12 @@ use Mcp\Schema\Request\CallToolRequest; use Mcp\Schema\Result\CallToolResult; use Mcp\Schema\Tool; +use Mcp\Server\Capability\Registry\ReferenceHandlerInterface; +use Mcp\Server\Capability\Registry\ToolReference; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\RegistryException; +use Mcp\Server\Exception\ToolCallException; +use Mcp\Server\Exception\ToolNotFoundException; use Mcp\Server\Handler\Request\CallToolHandler; use Mcp\Server\Session\SessionInterface; use PHPUnit\Framework\MockObject\MockObject; diff --git a/tests/Unit/Server/Handler/Request/CompletionCompleteHandlerTest.php b/tests/Unit/Server/Handler/Request/CompletionCompleteHandlerTest.php index b35347a92..69f923744 100644 --- a/tests/Unit/Server/Handler/Request/CompletionCompleteHandlerTest.php +++ b/tests/Unit/Server/Handler/Request/CompletionCompleteHandlerTest.php @@ -11,18 +11,18 @@ namespace Mcp\Tests\Unit\Server\Handler\Request; -use Mcp\Capability\Completion\ProviderInterface; -use Mcp\Capability\Registry\ResourceReference; -use Mcp\Capability\Registry\ResourceTemplateReference; -use Mcp\Capability\RegistryInterface; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\CompletionCompleteRequest; use Mcp\Schema\ResourceTemplate; use Mcp\Schema\Result\CompletionCompleteResult; +use Mcp\Server\Capability\Completion\ProviderInterface; +use Mcp\Server\Capability\Registry\ResourceReference; +use Mcp\Server\Capability\Registry\ResourceTemplateReference; +use Mcp\Server\Capability\RegistryInterface; use Mcp\Server\Handler\Request\CompletionCompleteHandler; use Mcp\Server\Session\SessionInterface; -use Mcp\Tests\Unit\Capability\Attribute\CompletionProviderFixture; +use Mcp\Tests\Unit\Server\Capability\Attribute\CompletionProviderFixture; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; diff --git a/tests/Unit/Server/Handler/Request/GetPromptHandlerTest.php b/tests/Unit/Server/Handler/Request/GetPromptHandlerTest.php index 8e2304eb4..4a7452f2b 100644 --- a/tests/Unit/Server/Handler/Request/GetPromptHandlerTest.php +++ b/tests/Unit/Server/Handler/Request/GetPromptHandlerTest.php @@ -11,12 +11,6 @@ namespace Mcp\Tests\Unit\Server\Handler\Request; -use Mcp\Capability\Registry\PromptReference; -use Mcp\Capability\Registry\ReferenceHandlerInterface; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\PromptGetException; -use Mcp\Exception\PromptNotFoundException; -use Mcp\Exception\RegistryException; use Mcp\Schema\Content\PromptMessage; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Enum\Role; @@ -24,6 +18,12 @@ use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\GetPromptRequest; use Mcp\Schema\Result\GetPromptResult; +use Mcp\Server\Capability\Registry\PromptReference; +use Mcp\Server\Capability\Registry\ReferenceHandlerInterface; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\PromptGetException; +use Mcp\Server\Exception\PromptNotFoundException; +use Mcp\Server\Exception\RegistryException; use Mcp\Server\Handler\Request\GetPromptHandler; use Mcp\Server\Session\SessionInterface; use PHPUnit\Framework\MockObject\MockObject; diff --git a/tests/Unit/Server/Handler/Request/ListPromptsHandlerTest.php b/tests/Unit/Server/Handler/Request/ListPromptsHandlerTest.php index e2fb610d3..2cbec612b 100644 --- a/tests/Unit/Server/Handler/Request/ListPromptsHandlerTest.php +++ b/tests/Unit/Server/Handler/Request/ListPromptsHandlerTest.php @@ -11,11 +11,11 @@ namespace Mcp\Tests\Unit\Server\Handler\Request; -use Mcp\Capability\Registry; -use Mcp\Exception\InvalidCursorException; use Mcp\Schema\Prompt; use Mcp\Schema\Request\ListPromptsRequest; use Mcp\Schema\Result\ListPromptsResult; +use Mcp\Server\Capability\Registry; +use Mcp\Server\Exception\InvalidCursorException; use Mcp\Server\Handler\Request\ListPromptsHandler; use Mcp\Server\Session\InMemorySessionStore; use Mcp\Server\Session\Session; diff --git a/tests/Unit/Server/Handler/Request/ListResourceTemplatesHandlerTest.php b/tests/Unit/Server/Handler/Request/ListResourceTemplatesHandlerTest.php index ede74cbc9..397aa329f 100644 --- a/tests/Unit/Server/Handler/Request/ListResourceTemplatesHandlerTest.php +++ b/tests/Unit/Server/Handler/Request/ListResourceTemplatesHandlerTest.php @@ -11,11 +11,11 @@ namespace Mcp\Tests\Unit\Server\Handler\Request; -use Mcp\Capability\Registry; -use Mcp\Exception\InvalidCursorException; use Mcp\Schema\Request\ListResourceTemplatesRequest; use Mcp\Schema\ResourceTemplate; use Mcp\Schema\Result\ListResourceTemplatesResult; +use Mcp\Server\Capability\Registry; +use Mcp\Server\Exception\InvalidCursorException; use Mcp\Server\Handler\Request\ListResourceTemplatesHandler; use Mcp\Server\Session\InMemorySessionStore; use Mcp\Server\Session\Session; diff --git a/tests/Unit/Server/Handler/Request/ListResourcesHandlerTest.php b/tests/Unit/Server/Handler/Request/ListResourcesHandlerTest.php index 3e385fefe..bee581e0c 100644 --- a/tests/Unit/Server/Handler/Request/ListResourcesHandlerTest.php +++ b/tests/Unit/Server/Handler/Request/ListResourcesHandlerTest.php @@ -11,11 +11,11 @@ namespace Mcp\Tests\Unit\Server\Handler\Request; -use Mcp\Capability\Registry; -use Mcp\Exception\InvalidCursorException; use Mcp\Schema\Request\ListResourcesRequest; use Mcp\Schema\ResourceDefinition; use Mcp\Schema\Result\ListResourcesResult; +use Mcp\Server\Capability\Registry; +use Mcp\Server\Exception\InvalidCursorException; use Mcp\Server\Handler\Request\ListResourcesHandler; use Mcp\Server\Session\InMemorySessionStore; use Mcp\Server\Session\Session; diff --git a/tests/Unit/Server/Handler/Request/ListToolsHandlerTest.php b/tests/Unit/Server/Handler/Request/ListToolsHandlerTest.php index b97185adb..ebc588e90 100644 --- a/tests/Unit/Server/Handler/Request/ListToolsHandlerTest.php +++ b/tests/Unit/Server/Handler/Request/ListToolsHandlerTest.php @@ -11,11 +11,11 @@ namespace Mcp\Tests\Unit\Server\Handler\Request; -use Mcp\Capability\Registry; -use Mcp\Exception\InvalidCursorException; use Mcp\Schema\Request\ListToolsRequest; use Mcp\Schema\Result\ListToolsResult; use Mcp\Schema\Tool; +use Mcp\Server\Capability\Registry; +use Mcp\Server\Exception\InvalidCursorException; use Mcp\Server\Handler\Request\ListToolsHandler; use Mcp\Server\Session\InMemorySessionStore; use Mcp\Server\Session\Session; diff --git a/tests/Unit/Server/Handler/Request/ReadResourceHandlerTest.php b/tests/Unit/Server/Handler/Request/ReadResourceHandlerTest.php index 7135e7cff..965c6625d 100644 --- a/tests/Unit/Server/Handler/Request/ReadResourceHandlerTest.php +++ b/tests/Unit/Server/Handler/Request/ReadResourceHandlerTest.php @@ -11,12 +11,6 @@ namespace Mcp\Tests\Unit\Server\Handler\Request; -use Mcp\Capability\Registry\ReferenceHandlerInterface; -use Mcp\Capability\Registry\ResourceReference; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\RegistryException; -use Mcp\Exception\ResourceNotFoundException; -use Mcp\Exception\ResourceReadException; use Mcp\Schema\Content\BlobResourceContents; use Mcp\Schema\Content\TextResourceContents; use Mcp\Schema\Enum\CacheScope; @@ -26,6 +20,12 @@ use Mcp\Schema\Request\ReadResourceRequest; use Mcp\Schema\ResourceDefinition; use Mcp\Schema\Result\ReadResourceResult; +use Mcp\Server\Capability\Registry\ReferenceHandlerInterface; +use Mcp\Server\Capability\Registry\ResourceReference; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\RegistryException; +use Mcp\Server\Exception\ResourceNotFoundException; +use Mcp\Server\Exception\ResourceReadException; use Mcp\Server\Handler\Request\ReadResourceHandler; use Mcp\Server\Session\SessionInterface; use PHPUnit\Framework\MockObject\MockObject; diff --git a/tests/Unit/Server/Handler/Request/ResourceSubscribeHandlerTest.php b/tests/Unit/Server/Handler/Request/ResourceSubscribeHandlerTest.php index d16519eca..8d4fba1de 100644 --- a/tests/Unit/Server/Handler/Request/ResourceSubscribeHandlerTest.php +++ b/tests/Unit/Server/Handler/Request/ResourceSubscribeHandlerTest.php @@ -11,12 +11,12 @@ namespace Mcp\Tests\Unit\Server\Handler\Request; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\ResourceNotFoundException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\ResourceSubscribeRequest; use Mcp\Schema\Result\EmptyResult; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\ResourceNotFoundException; use Mcp\Server\Handler\Request\ResourceSubscribeHandler; use Mcp\Server\Resource\SubscriptionManagerInterface; use Mcp\Server\Session\SessionInterface; @@ -58,7 +58,7 @@ public function testHandleSuccessfulSubscribe(): void ->expects($this->once()) ->method('getResource') ->with($uri) - ->willReturn($this->createMock(\Mcp\Capability\Registry\ResourceReference::class)); + ->willReturn($this->createMock(\Mcp\Server\Capability\Registry\ResourceReference::class)); $this->subscriptionManager ->expects($this->once()) diff --git a/tests/Unit/Server/Handler/Request/ResourceSubscribeTest.php b/tests/Unit/Server/Handler/Request/ResourceSubscribeTest.php index b7d491b5b..5145a7b3e 100644 --- a/tests/Unit/Server/Handler/Request/ResourceSubscribeTest.php +++ b/tests/Unit/Server/Handler/Request/ResourceSubscribeTest.php @@ -11,15 +11,15 @@ namespace Mcp\Tests\Unit\Server\Handler\Request; -use Mcp\Capability\Registry\ResourceReference; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\ResourceNotFoundException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\ResourceSubscribeRequest; use Mcp\Schema\ResourceDefinition; use Mcp\Schema\Result\EmptyResult; +use Mcp\Server\Capability\Registry\ResourceReference; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\ResourceNotFoundException; use Mcp\Server\Handler\Request\ResourceSubscribeHandler; use Mcp\Server\Resource\SubscriptionManagerInterface; use Mcp\Server\Session\SessionInterface; diff --git a/tests/Unit/Server/Handler/Request/ResourceUnsubscribeHandlerTest.php b/tests/Unit/Server/Handler/Request/ResourceUnsubscribeHandlerTest.php index daa82f522..040e77037 100644 --- a/tests/Unit/Server/Handler/Request/ResourceUnsubscribeHandlerTest.php +++ b/tests/Unit/Server/Handler/Request/ResourceUnsubscribeHandlerTest.php @@ -11,12 +11,12 @@ namespace Mcp\Tests\Unit\Server\Handler\Request; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\ResourceNotFoundException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\ResourceUnsubscribeRequest; use Mcp\Schema\Result\EmptyResult; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\ResourceNotFoundException; use Mcp\Server\Handler\Request\ResourceUnsubscribeHandler; use Mcp\Server\Resource\SubscriptionManagerInterface; use Mcp\Server\Session\SessionInterface; @@ -58,7 +58,7 @@ public function testHandleSuccessfulUnsubscribe(): void ->expects($this->once()) ->method('getResource') ->with($uri) - ->willReturn($this->createMock(\Mcp\Capability\Registry\ResourceReference::class)); + ->willReturn($this->createMock(\Mcp\Server\Capability\Registry\ResourceReference::class)); $this->subscriptionManager ->expects($this->once()) diff --git a/tests/Unit/Server/Handler/Request/ResourceUnsubscribeTest.php b/tests/Unit/Server/Handler/Request/ResourceUnsubscribeTest.php index 5586d0555..5a0c50b82 100644 --- a/tests/Unit/Server/Handler/Request/ResourceUnsubscribeTest.php +++ b/tests/Unit/Server/Handler/Request/ResourceUnsubscribeTest.php @@ -11,15 +11,15 @@ namespace Mcp\Tests\Unit\Server\Handler\Request; -use Mcp\Capability\Registry\ResourceReference; -use Mcp\Capability\RegistryInterface; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\ResourceNotFoundException; +use Mcp\Schema\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Request\ResourceUnsubscribeRequest; use Mcp\Schema\ResourceDefinition; use Mcp\Schema\Result\EmptyResult; +use Mcp\Server\Capability\Registry\ResourceReference; +use Mcp\Server\Capability\RegistryInterface; +use Mcp\Server\Exception\ResourceNotFoundException; use Mcp\Server\Handler\Request\ResourceUnsubscribeHandler; use Mcp\Server\Resource\SubscriptionManagerInterface; use Mcp\Server\Session\SessionInterface; diff --git a/tests/Unit/Server/ProtocolSessionLockTest.php b/tests/Unit/Server/ProtocolSessionLockTest.php index fa2084c0b..c32522117 100644 --- a/tests/Unit/Server/ProtocolSessionLockTest.php +++ b/tests/Unit/Server/ProtocolSessionLockTest.php @@ -11,12 +11,12 @@ namespace Mcp\Tests\Unit\Server; -use Mcp\Exception\SessionLockException; -use Mcp\JsonRpc\MessageFactory; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; +use Mcp\Schema\MessageFactory; use Mcp\Schema\Request\PingRequest; +use Mcp\Server\Exception\SessionLockException; use Mcp\Server\Handler\Request\PingHandler; use Mcp\Server\Handler\Request\RequestHandlerInterface; use Mcp\Server\Protocol; diff --git a/tests/Unit/Server/ProtocolSessionRaceTest.php b/tests/Unit/Server/ProtocolSessionRaceTest.php index e13912f6a..b5a4a8308 100644 --- a/tests/Unit/Server/ProtocolSessionRaceTest.php +++ b/tests/Unit/Server/ProtocolSessionRaceTest.php @@ -11,9 +11,9 @@ namespace Mcp\Tests\Unit\Server; -use Mcp\JsonRpc\MessageFactory; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Response; +use Mcp\Schema\MessageFactory; use Mcp\Server\Protocol; use Mcp\Server\Session\SessionManager; use Mcp\Server\Transport\TransportInterface; diff --git a/tests/Unit/Server/ProtocolTest.php b/tests/Unit/Server/ProtocolTest.php index d400dbe0a..292d9acc6 100644 --- a/tests/Unit/Server/ProtocolTest.php +++ b/tests/Unit/Server/ProtocolTest.php @@ -11,24 +11,24 @@ namespace Mcp\Tests\Unit\Server; -use Mcp\Event\ClientResponseEvent; -use Mcp\Event\ErrorEvent; -use Mcp\Event\NotificationEvent; -use Mcp\Event\RequestEvent; -use Mcp\Event\ResponseEvent; -use Mcp\Event\ServerRequestEvent; -use Mcp\Exception\RuntimeException; -use Mcp\Exception\SessionRequiredException; -use Mcp\JsonRpc\MessageFactory; use Mcp\Schema\Enum\LoggingLevel; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; +use Mcp\Schema\MessageFactory; use Mcp\Schema\Notification\LoggingMessageNotification; use Mcp\Schema\Notification\ProgressNotification; use Mcp\Schema\Request\CallToolRequest; use Mcp\Schema\Request\PingRequest; use Mcp\Server\ClientGateway; +use Mcp\Server\Event\ClientResponseEvent; +use Mcp\Server\Event\ErrorEvent; +use Mcp\Server\Event\NotificationEvent; +use Mcp\Server\Event\RequestEvent; +use Mcp\Server\Event\ResponseEvent; +use Mcp\Server\Event\ServerRequestEvent; +use Mcp\Server\Exception\RuntimeException; +use Mcp\Server\Exception\SessionRequiredException; use Mcp\Server\Handler\Notification\NotificationHandlerInterface; use Mcp\Server\Handler\Request\RequestHandlerInterface; use Mcp\Server\Protocol; diff --git a/tests/Unit/ServerTest.php b/tests/Unit/Server/ServerTest.php similarity index 98% rename from tests/Unit/ServerTest.php rename to tests/Unit/Server/ServerTest.php index 373af4a38..5390b138c 100644 --- a/tests/Unit/ServerTest.php +++ b/tests/Unit/Server/ServerTest.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Mcp\Tests\Unit; +namespace Mcp\Tests\Unit\Server; -use Mcp\Server; use Mcp\Server\Builder; use Mcp\Server\Protocol; +use Mcp\Server\Server; use Mcp\Server\Transport\TransportInterface; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\MockObject\MockObject; diff --git a/tests/Unit/Server/Session/EphemeralSessionTest.php b/tests/Unit/Server/Session/EphemeralSessionTest.php index e65f30721..44298dbb6 100644 --- a/tests/Unit/Server/Session/EphemeralSessionTest.php +++ b/tests/Unit/Server/Session/EphemeralSessionTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Server\Session; -use Mcp\Exception\SessionRequiredException; +use Mcp\Server\Exception\SessionRequiredException; use Mcp\Server\Session\EphemeralSession; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Server/Session/FileSessionLockTest.php b/tests/Unit/Server/Session/FileSessionLockTest.php index a328473eb..6f33b3865 100644 --- a/tests/Unit/Server/Session/FileSessionLockTest.php +++ b/tests/Unit/Server/Session/FileSessionLockTest.php @@ -11,10 +11,10 @@ namespace Mcp\Tests\Unit\Server\Session; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\RuntimeException; -use Mcp\Exception\SessionLockException; -use Mcp\Exception\SessionLockTimeoutException; +use Mcp\Server\Exception\InvalidArgumentException; +use Mcp\Server\Exception\RuntimeException; +use Mcp\Server\Exception\SessionLockException; +use Mcp\Server\Exception\SessionLockTimeoutException; use Mcp\Server\Session\FileSessionLock; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Server/Session/FileSessionStoreTest.php b/tests/Unit/Server/Session/FileSessionStoreTest.php index 87f13e7e8..5378a9934 100644 --- a/tests/Unit/Server/Session/FileSessionStoreTest.php +++ b/tests/Unit/Server/Session/FileSessionStoreTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Server\Session; -use Mcp\Exception\ExceptionInterface; -use Mcp\Exception\RuntimeException; +use Mcp\Server\Exception\ExceptionInterface; +use Mcp\Server\Exception\RuntimeException; use Mcp\Server\Session\FileSessionLock; use Mcp\Server\Session\FileSessionStore; use PHPUnit\Framework\Attributes\TestDox; diff --git a/tests/Unit/Server/Session/Fixture/HeldElsewhereSessionLock.php b/tests/Unit/Server/Session/Fixture/HeldElsewhereSessionLock.php index 3781ef74c..d7ab2e67f 100644 --- a/tests/Unit/Server/Session/Fixture/HeldElsewhereSessionLock.php +++ b/tests/Unit/Server/Session/Fixture/HeldElsewhereSessionLock.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Server\Session\Fixture; -use Mcp\Exception\SessionLockTimeoutException; +use Mcp\Server\Exception\SessionLockTimeoutException; use Mcp\Server\Session\SessionLockInterface; use Symfony\Component\Uid\Uuid; diff --git a/tests/Unit/Server/Session/Fixture/RecordingSessionLock.php b/tests/Unit/Server/Session/Fixture/RecordingSessionLock.php index 75a0baeab..3725c59d5 100644 --- a/tests/Unit/Server/Session/Fixture/RecordingSessionLock.php +++ b/tests/Unit/Server/Session/Fixture/RecordingSessionLock.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Server\Session\Fixture; -use Mcp\Exception\SessionLockException; -use Mcp\Exception\SessionLockTimeoutException; +use Mcp\Server\Exception\SessionLockException; +use Mcp\Server\Exception\SessionLockTimeoutException; use Mcp\Server\Session\SessionLockInterface; use Symfony\Component\Uid\Uuid; diff --git a/tests/Unit/Server/Session/Psr16SessionStoreTest.php b/tests/Unit/Server/Session/Psr16SessionStoreTest.php index f0a44ccbf..bf961e0c6 100644 --- a/tests/Unit/Server/Session/Psr16SessionStoreTest.php +++ b/tests/Unit/Server/Session/Psr16SessionStoreTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Server\Session; -use Mcp\Exception\SessionStoreException; +use Mcp\Server\Exception\SessionStoreException; use Mcp\Server\Session\Psr16SessionStore; use PHPUnit\Framework\TestCase; use Psr\SimpleCache\CacheInterface; diff --git a/tests/Unit/Server/Session/SessionManagerTest.php b/tests/Unit/Server/Session/SessionManagerTest.php index e145292bd..c46e8ede3 100644 --- a/tests/Unit/Server/Session/SessionManagerTest.php +++ b/tests/Unit/Server/Session/SessionManagerTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Server\Session; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Server\Exception\InvalidArgumentException; use Mcp\Server\Session\InMemorySessionStore; use Mcp\Server\Session\SessionManager; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Server/Session/SymfonyLockSessionLockTest.php b/tests/Unit/Server/Session/SymfonyLockSessionLockTest.php index 6922afea0..c5d10f490 100644 --- a/tests/Unit/Server/Session/SymfonyLockSessionLockTest.php +++ b/tests/Unit/Server/Session/SymfonyLockSessionLockTest.php @@ -11,9 +11,9 @@ namespace Mcp\Tests\Unit\Server\Session; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\SessionLockException; -use Mcp\Exception\SessionLockTimeoutException; +use Mcp\Server\Exception\InvalidArgumentException; +use Mcp\Server\Exception\SessionLockException; +use Mcp\Server\Exception\SessionLockTimeoutException; use Mcp\Server\Session\SymfonyLockSessionLock; use Mcp\Tests\Unit\Server\Session\Fixture\RecordingLogger; use PHPUnit\Framework\Attributes\TestDox; diff --git a/tests/Unit/Server/Stateless/ElicitationReplayTest.php b/tests/Unit/Server/Stateless/ElicitationReplayTest.php index 83cc710f0..668aae474 100644 --- a/tests/Unit/Server/Stateless/ElicitationReplayTest.php +++ b/tests/Unit/Server/Stateless/ElicitationReplayTest.php @@ -11,11 +11,11 @@ namespace Mcp\Tests\Unit\Server\Stateless; -use Mcp\Exception\LogicException; use Mcp\Schema\Elicitation\ElicitationSchema; use Mcp\Schema\Elicitation\StringSchemaDefinition; use Mcp\Schema\Enum\ElicitationMode; use Mcp\Schema\Request\ElicitRequest; +use Mcp\Server\Exception\LogicException; use Mcp\Server\Stateless\ElicitationReplay; use Mcp\Server\Stateless\InputContext; use Mcp\Server\Stateless\RequestStateCodec; diff --git a/tests/Unit/Server/Stateless/OriginatingRequestBinderTest.php b/tests/Unit/Server/Stateless/OriginatingRequestBinderTest.php index bef91d029..57c1c361e 100644 --- a/tests/Unit/Server/Stateless/OriginatingRequestBinderTest.php +++ b/tests/Unit/Server/Stateless/OriginatingRequestBinderTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Server\Stateless; -use Mcp\JsonRpc\MessageFactory; use Mcp\Schema\JsonRpc\Request; +use Mcp\Schema\MessageFactory; use Mcp\Schema\Request\CallToolRequest; use Mcp\Schema\Request\GetPromptRequest; use Mcp\Schema\Request\ListToolsRequest; diff --git a/tests/Unit/Server/Stateless/RequestStateCodecTest.php b/tests/Unit/Server/Stateless/RequestStateCodecTest.php index 9cd205ea0..a844fbb07 100644 --- a/tests/Unit/Server/Stateless/RequestStateCodecTest.php +++ b/tests/Unit/Server/Stateless/RequestStateCodecTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Server\Stateless; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\RequestStateException; +use Mcp\Server\Exception\InvalidArgumentException; +use Mcp\Server\Exception\RequestStateException; use Mcp\Server\Stateless\RequestStateCodec; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\TestDox; diff --git a/tests/Unit/Server/Stateless/StandardHeaderValidatorTest.php b/tests/Unit/Server/Stateless/StandardHeaderValidatorTest.php index 60e090e1f..e6faef3dc 100644 --- a/tests/Unit/Server/Stateless/StandardHeaderValidatorTest.php +++ b/tests/Unit/Server/Stateless/StandardHeaderValidatorTest.php @@ -11,9 +11,9 @@ namespace Mcp\Tests\Unit\Server\Stateless; -use Mcp\Capability\Registry; -use Mcp\Capability\RegistryInterface; use Mcp\Schema\Tool; +use Mcp\Server\Capability\Registry; +use Mcp\Server\Capability\RegistryInterface; use Mcp\Server\Stateless\StandardHeaderValidator; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\TestDox; diff --git a/tests/Unit/Server/Stateless/StatelessProtocolTest.php b/tests/Unit/Server/Stateless/StatelessProtocolTest.php index b362d2556..17f5c0841 100644 --- a/tests/Unit/Server/Stateless/StatelessProtocolTest.php +++ b/tests/Unit/Server/Stateless/StatelessProtocolTest.php @@ -11,12 +11,6 @@ namespace Mcp\Tests\Unit\Server\Stateless; -use Mcp\Event\ErrorEvent; -use Mcp\Event\RequestEvent; -use Mcp\Event\ResponseEvent; -use Mcp\Exception\MissingRequiredClientCapabilityException; -use Mcp\Exception\ResourceReadException; -use Mcp\JsonRpc\MessageFactory; use Mcp\Schema\ClientCapabilities; use Mcp\Schema\Content\TextContent; use Mcp\Schema\Content\TextResourceContents; @@ -29,6 +23,7 @@ use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\JsonRpc\Request; use Mcp\Schema\JsonRpc\Response; +use Mcp\Schema\MessageFactory; use Mcp\Schema\Notification\PromptListChangedNotification; use Mcp\Schema\Notification\ResourceUpdatedNotification; use Mcp\Schema\Notification\ToolListChangedNotification; @@ -36,20 +31,25 @@ use Mcp\Schema\Request\DiscoverRequest; use Mcp\Schema\Request\ElicitRequest; use Mcp\Schema\Request\ListRootsRequest; +use Mcp\Schema\RequestMeta; use Mcp\Schema\Result\CallToolResult; use Mcp\Schema\Result\DiscoverResult; use Mcp\Schema\Result\InputRequiredResult; use Mcp\Schema\Result\ReadResourceResult; use Mcp\Schema\ServerCapabilities; -use Mcp\Server; use Mcp\Server\Authorization\AccessToken; use Mcp\Server\ClientGateway; use Mcp\Server\Configuration; +use Mcp\Server\Event\ErrorEvent; +use Mcp\Server\Event\RequestEvent; +use Mcp\Server\Event\ResponseEvent; +use Mcp\Server\Exception\MissingRequiredClientCapabilityException; +use Mcp\Server\Exception\ResourceReadException; use Mcp\Server\Handler\Request\RequestHandlerInterface; use Mcp\Server\RequestContext; +use Mcp\Server\Server; use Mcp\Server\Session\SessionInterface; use Mcp\Server\Stateless\OriginatingRequestBinder; -use Mcp\Server\Stateless\RequestMeta; use Mcp\Server\Stateless\RequestStateBinderInterface; use Mcp\Server\Stateless\StatelessProtocol; use Mcp\Server\Stateless\StatelessResult; diff --git a/tests/Unit/Server/Subscription/NotificationBusTest.php b/tests/Unit/Server/Subscription/NotificationBusTest.php index 3ff94214d..7da44d9ee 100644 --- a/tests/Unit/Server/Subscription/NotificationBusTest.php +++ b/tests/Unit/Server/Subscription/NotificationBusTest.php @@ -11,11 +11,11 @@ namespace Mcp\Tests\Unit\Server\Subscription; -use Mcp\Event\ToolListChangedEvent; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Notification\PromptListChangedNotification; use Mcp\Schema\Notification\ResourceUpdatedNotification; use Mcp\Schema\Notification\ToolListChangedNotification; +use Mcp\Server\Event\ToolListChangedEvent; +use Mcp\Server\Exception\InvalidArgumentException; use Mcp\Server\Subscription\InMemoryNotificationBus; use Mcp\Server\Subscription\NotificationBusInterface; use Mcp\Server\Subscription\Psr16NotificationBus; diff --git a/tests/Unit/Server/Transport/AccessTokenFlowTest.php b/tests/Unit/Server/Transport/AccessTokenFlowTest.php index fe092d764..521a1a15e 100644 --- a/tests/Unit/Server/Transport/AccessTokenFlowTest.php +++ b/tests/Unit/Server/Transport/AccessTokenFlowTest.php @@ -12,10 +12,10 @@ namespace Mcp\Tests\Unit\Server\Transport; use Mcp\Schema\Enum\ProtocolVersion; -use Mcp\Server; +use Mcp\Schema\RequestMeta; use Mcp\Server\Authorization\AccessToken; use Mcp\Server\RequestContext; -use Mcp\Server\Stateless\RequestMeta; +use Mcp\Server\Server; use Mcp\Server\Transport\Http\Middleware\AuthorizationMiddleware; use Mcp\Server\Transport\Http\OAuth\AuthorizationResult; use Mcp\Server\Transport\Http\OAuth\AuthorizationTokenValidatorInterface; diff --git a/tests/Unit/Server/Transport/CallbackStreamTest.php b/tests/Unit/Server/Transport/CallbackStreamTest.php index 6d471b320..92c5ee045 100644 --- a/tests/Unit/Server/Transport/CallbackStreamTest.php +++ b/tests/Unit/Server/Transport/CallbackStreamTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Server\Transport; -use Mcp\Exception\LogicException; +use Mcp\Server\Exception\LogicException; use Mcp\Server\Transport\CallbackStream; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Server/Transport/DualEraRoutingTest.php b/tests/Unit/Server/Transport/DualEraRoutingTest.php index edfe1316c..8775e5ea4 100644 --- a/tests/Unit/Server/Transport/DualEraRoutingTest.php +++ b/tests/Unit/Server/Transport/DualEraRoutingTest.php @@ -12,9 +12,9 @@ namespace Mcp\Tests\Unit\Server\Transport; use Mcp\Schema\Enum\ProtocolVersion; -use Mcp\Server; +use Mcp\Schema\RequestMeta; +use Mcp\Server\Server; use Mcp\Server\Session\InMemorySessionStore; -use Mcp\Server\Stateless\RequestMeta; use Mcp\Server\Transport\StreamableHttpTransport; use Nyholm\Psr7\Factory\Psr17Factory; use PHPUnit\Framework\Attributes\TestDox; diff --git a/tests/Unit/Server/Transport/Http/Middleware/CorsMiddlewareTest.php b/tests/Unit/Server/Transport/Http/Middleware/CorsMiddlewareTest.php index 1efaeb1af..ca422a7f5 100644 --- a/tests/Unit/Server/Transport/Http/Middleware/CorsMiddlewareTest.php +++ b/tests/Unit/Server/Transport/Http/Middleware/CorsMiddlewareTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Server\Transport\Http\Middleware; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Server\Exception\InvalidArgumentException; use Mcp\Server\Transport\Http\Middleware\CorsMiddleware; use PHPUnit\Framework\Attributes\TestDox; use Psr\Http\Message\ServerRequestInterface; diff --git a/tests/Unit/Server/Transport/Http/OAuth/AuthorizationResultTest.php b/tests/Unit/Server/Transport/Http/OAuth/AuthorizationResultTest.php index 47eed832d..281785a53 100644 --- a/tests/Unit/Server/Transport/Http/OAuth/AuthorizationResultTest.php +++ b/tests/Unit/Server/Transport/Http/OAuth/AuthorizationResultTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Server\Transport\Http\OAuth; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Server\Exception\InvalidArgumentException; use Mcp\Server\Transport\Http\OAuth\AuthorizationResult; use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Server/Transport/Http/OAuth/JwtTokenValidatorTest.php b/tests/Unit/Server/Transport/Http/OAuth/JwtTokenValidatorTest.php index 8cd118ad4..b3709de4f 100644 --- a/tests/Unit/Server/Transport/Http/OAuth/JwtTokenValidatorTest.php +++ b/tests/Unit/Server/Transport/Http/OAuth/JwtTokenValidatorTest.php @@ -14,7 +14,7 @@ use Firebase\JWT\CachedKeySet; use Firebase\JWT\JWT; use Firebase\JWT\Key; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Server\Exception\InvalidArgumentException; use Mcp\Server\Transport\Http\Middleware\AuthorizationMiddleware; use Mcp\Server\Transport\Http\OAuth\JwtTokenValidator; use Mcp\Server\Transport\Http\OAuth\ProtectedResourceMetadata; diff --git a/tests/Unit/Server/Transport/Http/OAuth/OidcDiscoveryTest.php b/tests/Unit/Server/Transport/Http/OAuth/OidcDiscoveryTest.php index 13ba3f84d..c0ab45701 100644 --- a/tests/Unit/Server/Transport/Http/OAuth/OidcDiscoveryTest.php +++ b/tests/Unit/Server/Transport/Http/OAuth/OidcDiscoveryTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Server\Transport\Http\OAuth; -use Mcp\Exception\InvalidArgumentException; -use Mcp\Exception\RuntimeException; +use Mcp\Server\Exception\InvalidArgumentException; +use Mcp\Server\Exception\RuntimeException; use Mcp\Server\Transport\Http\OAuth\OidcDiscovery; use Nyholm\Psr7\Factory\Psr17Factory; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/tests/Unit/Server/Transport/Http/OAuth/ProtectedResourceMetadataTest.php b/tests/Unit/Server/Transport/Http/OAuth/ProtectedResourceMetadataTest.php index 338060763..cfb33fd15 100644 --- a/tests/Unit/Server/Transport/Http/OAuth/ProtectedResourceMetadataTest.php +++ b/tests/Unit/Server/Transport/Http/OAuth/ProtectedResourceMetadataTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Server\Transport\Http\OAuth; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Server\Exception\InvalidArgumentException; use Mcp\Server\Transport\Http\OAuth\ProtectedResourceMetadata; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Server/Transport/Http/OAuth/RateLimitedJwksClientTest.php b/tests/Unit/Server/Transport/Http/OAuth/RateLimitedJwksClientTest.php index e736277d0..8cb7f5024 100644 --- a/tests/Unit/Server/Transport/Http/OAuth/RateLimitedJwksClientTest.php +++ b/tests/Unit/Server/Transport/Http/OAuth/RateLimitedJwksClientTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Server\Transport\Http\OAuth; -use Mcp\Exception\JwksRefreshRateLimitException; +use Mcp\Server\Exception\JwksRefreshRateLimitException; use Mcp\Server\Transport\Http\OAuth\RateLimitedJwksClient; use Nyholm\Psr7\Factory\Psr17Factory; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Server/Transport/Http/OAuth/ScopePolicyTest.php b/tests/Unit/Server/Transport/Http/OAuth/ScopePolicyTest.php index bee3ff3cd..a3f50ab76 100644 --- a/tests/Unit/Server/Transport/Http/OAuth/ScopePolicyTest.php +++ b/tests/Unit/Server/Transport/Http/OAuth/ScopePolicyTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Server\Transport\Http\OAuth; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Server\Exception\InvalidArgumentException; use Mcp\Server\Transport\Http\OAuth\ScopePolicy; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Server/Transport/Http/OAuth/ScopesTest.php b/tests/Unit/Server/Transport/Http/OAuth/ScopesTest.php index 7c7b49ead..a274ea9e7 100644 --- a/tests/Unit/Server/Transport/Http/OAuth/ScopesTest.php +++ b/tests/Unit/Server/Transport/Http/OAuth/ScopesTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Server\Transport\Http\OAuth; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Server\Exception\InvalidArgumentException; use Mcp\Server\Transport\Http\OAuth\Scopes; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Server/Transport/SessionBindingTest.php b/tests/Unit/Server/Transport/SessionBindingTest.php index dd0a7167d..e2858424a 100644 --- a/tests/Unit/Server/Transport/SessionBindingTest.php +++ b/tests/Unit/Server/Transport/SessionBindingTest.php @@ -11,15 +11,15 @@ namespace Mcp\Tests\Unit\Server\Transport; -use Mcp\Exception\SessionStoreException; -use Mcp\JsonRpc\MessageFactory; use Mcp\Schema\Enum\ProtocolVersion; +use Mcp\Schema\MessageFactory; use Mcp\Schema\Notification\ResourceUpdatedNotification; -use Mcp\Server; use Mcp\Server\Authorization\AccessToken; +use Mcp\Server\Exception\SessionStoreException; use Mcp\Server\Handler\Request\PingHandler; use Mcp\Server\Protocol; use Mcp\Server\RequestContext; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionStore; use Mcp\Server\Session\InMemorySessionStore; use Mcp\Server\Session\Session; diff --git a/tests/Unit/Server/Transport/SessionlessHttpTest.php b/tests/Unit/Server/Transport/SessionlessHttpTest.php index 14e2087d6..6f1df26af 100644 --- a/tests/Unit/Server/Transport/SessionlessHttpTest.php +++ b/tests/Unit/Server/Transport/SessionlessHttpTest.php @@ -19,11 +19,11 @@ use Mcp\Schema\Notification\ProgressNotification; use Mcp\Schema\Request\ElicitRequest; use Mcp\Schema\Request\PingRequest; +use Mcp\Schema\RequestMeta; use Mcp\Schema\Result\InputRequiredResult; -use Mcp\Server; use Mcp\Server\RequestContext; +use Mcp\Server\Server; use Mcp\Server\Session\InMemorySessionStore; -use Mcp\Server\Stateless\RequestMeta; use Mcp\Server\Suspension\RequestSuspension; use Mcp\Server\Transport\StreamableHttpTransport; use Nyholm\Psr7\Factory\Psr17Factory; diff --git a/tests/Unit/Server/Transport/StatelessHttpTransportTest.php b/tests/Unit/Server/Transport/StatelessHttpTransportTest.php index 45744ab5b..98c0237a3 100644 --- a/tests/Unit/Server/Transport/StatelessHttpTransportTest.php +++ b/tests/Unit/Server/Transport/StatelessHttpTransportTest.php @@ -12,8 +12,8 @@ namespace Mcp\Tests\Unit\Server\Transport; use Mcp\Schema\Enum\ProtocolVersion; -use Mcp\Server; -use Mcp\Server\Stateless\RequestMeta; +use Mcp\Schema\RequestMeta; +use Mcp\Server\Server; use Mcp\Server\Stateless\StatelessProtocol; use Mcp\Server\Transport\Http\Middleware\DnsRebindingProtectionMiddleware; use Mcp\Server\Transport\StatelessHttpTransport; diff --git a/tests/Unit/Server/Transport/StdioDualEraTest.php b/tests/Unit/Server/Transport/StdioDualEraTest.php index f49ab7f13..61907ca4d 100644 --- a/tests/Unit/Server/Transport/StdioDualEraTest.php +++ b/tests/Unit/Server/Transport/StdioDualEraTest.php @@ -17,14 +17,14 @@ use Mcp\Schema\JsonRpc\Response; use Mcp\Schema\Notification\ToolListChangedNotification; use Mcp\Schema\Request\DiscoverRequest; +use Mcp\Schema\RequestMeta; use Mcp\Schema\Result\DiscoverResult; use Mcp\Schema\ServerCapabilities; -use Mcp\Server; use Mcp\Server\Builder; use Mcp\Server\Handler\Request\RequestHandlerInterface; use Mcp\Server\RequestContext; +use Mcp\Server\Server; use Mcp\Server\Session\SessionInterface; -use Mcp\Server\Stateless\RequestMeta; use Mcp\Server\Subscription\InMemoryNotificationBus; use Mcp\Server\Transport\StdioTransport; use PHPUnit\Framework\Attributes\DataProvider; diff --git a/tests/Unit/Server/Transport/StdioSuspendedFibersTest.php b/tests/Unit/Server/Transport/StdioSuspendedFibersTest.php index 8d6962493..dd9c28f81 100644 --- a/tests/Unit/Server/Transport/StdioSuspendedFibersTest.php +++ b/tests/Unit/Server/Transport/StdioSuspendedFibersTest.php @@ -11,14 +11,14 @@ namespace Mcp\Tests\Unit\Server\Transport; -use Mcp\Event\ServerRequestEvent; use Mcp\Schema\Elicitation\ElicitationSchema; use Mcp\Schema\Elicitation\StringSchemaDefinition; use Mcp\Schema\Enum\LoggingLevel; use Mcp\Schema\Enum\ProtocolVersion; use Mcp\Schema\Notification\LoggingMessageNotification; -use Mcp\Server; +use Mcp\Server\Event\ServerRequestEvent; use Mcp\Server\RequestContext; +use Mcp\Server\Server; use Mcp\Server\Transport\StdioTransport; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Server/Transport/StdioTransportTest.php b/tests/Unit/Server/Transport/StdioTransportTest.php index 3843f1034..40ab6d889 100644 --- a/tests/Unit/Server/Transport/StdioTransportTest.php +++ b/tests/Unit/Server/Transport/StdioTransportTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Server\Transport; -use Mcp\Exception\InvalidArgumentException; +use Mcp\Server\Exception\InvalidArgumentException; use Mcp\Server\Transport\StdioTransport; use Mcp\Server\Transport\TransportInterface; use PHPUnit\Framework\Attributes\TestDox; diff --git a/tests/Unit/Server/Transport/StreamableHttpTransportTest.php b/tests/Unit/Server/Transport/StreamableHttpTransportTest.php index 9e9bcc623..978552a0e 100644 --- a/tests/Unit/Server/Transport/StreamableHttpTransportTest.php +++ b/tests/Unit/Server/Transport/StreamableHttpTransportTest.php @@ -11,13 +11,13 @@ namespace Mcp\Tests\Unit\Server\Transport; -use Mcp\Exception\ClientException; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\JsonRpc\Error; use Mcp\Schema\Notification\ProgressNotification; use Mcp\Schema\Request\PingRequest; -use Mcp\Server; +use Mcp\Server\Exception\ClientException; +use Mcp\Server\Exception\InvalidArgumentException; use Mcp\Server\RequestContext; +use Mcp\Server\Server; use Mcp\Server\Session\FileSessionLock; use Mcp\Server\Session\InMemorySessionStore; use Mcp\Server\Session\Session; diff --git a/tests/Unit/Server/Transport/TransportShutdownTest.php b/tests/Unit/Server/Transport/TransportShutdownTest.php index 873e5fd54..04cd26e90 100644 --- a/tests/Unit/Server/Transport/TransportShutdownTest.php +++ b/tests/Unit/Server/Transport/TransportShutdownTest.php @@ -11,7 +11,7 @@ namespace Mcp\Tests\Unit\Server\Transport; -use Mcp\Exception\SessionStoreException; +use Mcp\Server\Exception\SessionStoreException; use Mcp\Server\Transport\InMemoryTransport; use Mcp\Server\Transport\StdioTransport; use Mcp\Server\Transport\TransportInterface; diff --git a/tests/Unit/Server/Wire/CachePolicyTest.php b/tests/Unit/Server/Wire/CachePolicyTest.php index de81ff19c..b2dd7cf7e 100644 --- a/tests/Unit/Server/Wire/CachePolicyTest.php +++ b/tests/Unit/Server/Wire/CachePolicyTest.php @@ -11,8 +11,8 @@ namespace Mcp\Tests\Unit\Server\Wire; -use Mcp\Exception\InvalidArgumentException; use Mcp\Schema\Enum\CacheScope; +use Mcp\Server\Exception\InvalidArgumentException; use Mcp\Server\Wire\CachePolicy; use Mcp\Server\Wire\Rev2026Codec; use PHPUnit\Framework\Attributes\TestDox; diff --git a/tests/Unit/Server/Wire/InboundClassifierTest.php b/tests/Unit/Server/Wire/InboundClassifierTest.php index 49160e8fa..ab2e77cf4 100644 --- a/tests/Unit/Server/Wire/InboundClassifierTest.php +++ b/tests/Unit/Server/Wire/InboundClassifierTest.php @@ -12,7 +12,7 @@ namespace Mcp\Tests\Unit\Server\Wire; use Mcp\Schema\Enum\ProtocolVersion; -use Mcp\Server\Stateless\RequestMeta; +use Mcp\Schema\RequestMeta; use Mcp\Server\Wire\InboundClassifier; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\TestDox;