From 1d8b482eec3299d4edfcd715651bb80fe81c509d Mon Sep 17 00:00:00 2001 From: Christopher Hertel Date: Sun, 14 Sep 2025 17:37:39 +0200 Subject: [PATCH] Switch to set* and add* on ServerBuilder instead of with* --- README.md | 4 +- .../01-discovery-stdio-calculator/server.php | 8 +-- .../02-discovery-http-userprofile/server.php | 12 ++-- .../03-manual-registration-stdio/server.php | 14 ++-- .../04-combined-registration-http/server.php | 12 ++-- examples/05-stdio-env-variables/server.php | 6 +- .../06-custom-dependencies-stdio/server.php | 8 +-- .../07-complex-tool-schema-http/server.php | 8 +-- .../08-schema-showcase-streamable/server.php | 6 +- phpstan-baseline.neon | 46 ++++--------- src/Server/ServerBuilder.php | 66 +++++++++---------- 11 files changed, 83 insertions(+), 107 deletions(-) diff --git a/README.md b/README.md index 84db63ea..121d8dd4 100644 --- a/README.md +++ b/README.md @@ -98,8 +98,8 @@ use Mcp\Server; use Mcp\Server\Transport\StdioTransport; Server::make() - ->withServerInfo('Stdio Calculator', '1.1.0', 'Basic Calculator over STDIO transport.') - ->withDiscovery(__DIR__, ['.']) + ->setServerInfo('Stdio Calculator', '1.1.0', 'Basic Calculator over STDIO transport.') + ->setDiscovery(__DIR__, ['.']) ->build() ->connect(new StdioTransport()); ``` diff --git a/examples/01-discovery-stdio-calculator/server.php b/examples/01-discovery-stdio-calculator/server.php index b54b6e98..ce19dc0e 100644 --- a/examples/01-discovery-stdio-calculator/server.php +++ b/examples/01-discovery-stdio-calculator/server.php @@ -19,10 +19,10 @@ logger()->info('Starting MCP Stdio Calculator Server...'); Server::make() - ->withServerInfo('Stdio Calculator', '1.1.0', 'Basic Calculator over STDIO transport.') - ->withContainer(container()) - ->withLogger(logger()) - ->withDiscovery(__DIR__, ['.']) + ->setServerInfo('Stdio Calculator', '1.1.0', 'Basic Calculator over STDIO transport.') + ->setContainer(container()) + ->setLogger(logger()) + ->setDiscovery(__DIR__, ['.']) ->build() ->connect(new StdioTransport(logger: logger())); diff --git a/examples/02-discovery-http-userprofile/server.php b/examples/02-discovery-http-userprofile/server.php index 2a76580c..1d4ddc45 100644 --- a/examples/02-discovery-http-userprofile/server.php +++ b/examples/02-discovery-http-userprofile/server.php @@ -24,11 +24,11 @@ $container->set(LoggerInterface::class, logger()); Server::make() - ->withServerInfo('HTTP User Profiles', '1.0.0') - ->withLogger(logger()) - ->withContainer($container) - ->withDiscovery(__DIR__, ['.']) - ->withTool( + ->setServerInfo('HTTP User Profiles', '1.0.0') + ->setLogger(logger()) + ->setContainer($container) + ->setDiscovery(__DIR__, ['.']) + ->addTool( function (float $a, float $b, string $operation = 'add'): array { $result = match ($operation) { 'add' => $a + $b, @@ -47,7 +47,7 @@ function (float $a, float $b, string $operation = 'add'): array { name: 'calculator', description: 'Perform basic math operations (add, subtract, multiply, divide)' ) - ->withResource( + ->addResource( function (): array { $memoryUsage = memory_get_usage(true); $memoryPeak = memory_get_peak_usage(true); diff --git a/examples/03-manual-registration-stdio/server.php b/examples/03-manual-registration-stdio/server.php index cea4001c..8a4916fc 100644 --- a/examples/03-manual-registration-stdio/server.php +++ b/examples/03-manual-registration-stdio/server.php @@ -20,13 +20,13 @@ logger()->info('Starting MCP Manual Registration (Stdio) Server...'); Server::make() - ->withServerInfo('Manual Reg Server', '1.0.0') - ->withLogger(logger()) - ->withContainer(container()) - ->withTool([SimpleHandlers::class, 'echoText'], 'echo_text') - ->withResource([SimpleHandlers::class, 'getAppVersion'], 'app://version', 'application_version', mimeType: 'text/plain') - ->withPrompt([SimpleHandlers::class, 'greetingPrompt'], 'personalized_greeting') - ->withResourceTemplate([SimpleHandlers::class, 'getItemDetails'], 'item://{itemId}/details', 'get_item_details', mimeType: 'application/json') + ->setServerInfo('Manual Reg Server', '1.0.0') + ->setLogger(logger()) + ->setContainer(container()) + ->addTool([SimpleHandlers::class, 'echoText'], 'echo_text') + ->addResource([SimpleHandlers::class, 'getAppVersion'], 'app://version', 'application_version', mimeType: 'text/plain') + ->addPrompt([SimpleHandlers::class, 'greetingPrompt'], 'personalized_greeting') + ->addResourceTemplate([SimpleHandlers::class, 'getItemDetails'], 'item://{itemId}/details', 'get_item_details', mimeType: 'application/json') ->build() ->connect(new StdioTransport(logger: logger())); diff --git a/examples/04-combined-registration-http/server.php b/examples/04-combined-registration-http/server.php index 4f86c409..f3ea730d 100644 --- a/examples/04-combined-registration-http/server.php +++ b/examples/04-combined-registration-http/server.php @@ -20,12 +20,12 @@ logger()->info('Starting MCP Combined Registration (HTTP) Server...'); Server::make() - ->withServerInfo('Combined HTTP Server', '1.0.0') - ->withLogger(logger()) - ->withContainer(container()) - ->withDiscovery(__DIR__, ['.']) - ->withTool([ManualHandlers::class, 'manualGreeter']) - ->withResource( + ->setServerInfo('Combined HTTP Server', '1.0.0') + ->setLogger(logger()) + ->setContainer(container()) + ->setDiscovery(__DIR__, ['.']) + ->addTool([ManualHandlers::class, 'manualGreeter']) + ->addResource( [ManualHandlers::class, 'getPriorityConfigManual'], 'config://priority', 'priority_config_manual', diff --git a/examples/05-stdio-env-variables/server.php b/examples/05-stdio-env-variables/server.php index 134a1ae2..1cfaa13d 100644 --- a/examples/05-stdio-env-variables/server.php +++ b/examples/05-stdio-env-variables/server.php @@ -50,9 +50,9 @@ logger()->info('Starting MCP Stdio Environment Variable Example Server...'); Server::make() - ->withServerInfo('Env Var Server', '1.0.0') - ->withLogger(logger()) - ->withDiscovery(__DIR__, ['.']) + ->setServerInfo('Env Var Server', '1.0.0') + ->setLogger(logger()) + ->setDiscovery(__DIR__, ['.']) ->build() ->connect(new StdioTransport(logger: logger())); diff --git a/examples/06-custom-dependencies-stdio/server.php b/examples/06-custom-dependencies-stdio/server.php index a9fe46d2..653d7773 100644 --- a/examples/06-custom-dependencies-stdio/server.php +++ b/examples/06-custom-dependencies-stdio/server.php @@ -28,10 +28,10 @@ $container->set(Services\StatsServiceInterface::class, $statsService); Server::make() - ->withServerInfo('Task Manager Server', '1.0.0') - ->withLogger(logger()) - ->withContainer($container) - ->withDiscovery(__DIR__, ['.']) + ->setServerInfo('Task Manager Server', '1.0.0') + ->setLogger(logger()) + ->setContainer($container) + ->setDiscovery(__DIR__, ['.']) ->build() ->connect(new StdioTransport(logger: logger())); diff --git a/examples/07-complex-tool-schema-http/server.php b/examples/07-complex-tool-schema-http/server.php index bef31e56..44dbc45d 100644 --- a/examples/07-complex-tool-schema-http/server.php +++ b/examples/07-complex-tool-schema-http/server.php @@ -19,10 +19,10 @@ logger()->info('Starting MCP Complex Schema HTTP Server...'); Server::make() - ->withServerInfo('Event Scheduler Server', '1.0.0') - ->withLogger(logger()) - ->withContainer(container()) - ->withDiscovery(__DIR__, ['.']) + ->setServerInfo('Event Scheduler Server', '1.0.0') + ->setLogger(logger()) + ->setContainer(container()) + ->setDiscovery(__DIR__, ['.']) ->build() ->connect(new HttpServerTransport('127.0.0.1', 8082, 'mcp_scheduler')); diff --git a/examples/08-schema-showcase-streamable/server.php b/examples/08-schema-showcase-streamable/server.php index df348a5a..b77b6db8 100644 --- a/examples/08-schema-showcase-streamable/server.php +++ b/examples/08-schema-showcase-streamable/server.php @@ -19,9 +19,9 @@ logger()->info('Starting MCP Schema Showcase Server...'); Server::make() - ->withServerInfo('Schema Showcase', '1.0.0') - ->withLogger(logger()) - ->withDiscovery(__DIR__, ['.']) + ->setServerInfo('Schema Showcase', '1.0.0') + ->setLogger(logger()) + ->setDiscovery(__DIR__, ['.']) ->build() ->connect(new StreamableHttpServerTransport('127.0.0.1', 8080, 'mcp')); diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 1ac806b3..a9382bf3 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -463,43 +463,43 @@ parameters: path: src/Server/ServerBuilder.php - - message: '#^Method Mcp\\Server\\ServerBuilder\:\:withDiscovery\(\) has parameter \$excludeDirs with no value type specified in iterable type array\.$#' + message: '#^Method Mcp\\Server\\ServerBuilder\:\:setDiscovery\(\) has parameter \$excludeDirs with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 path: src/Server/ServerBuilder.php - - message: '#^Method Mcp\\Server\\ServerBuilder\:\:withDiscovery\(\) has parameter \$scanDirs with no value type specified in iterable type array\.$#' + message: '#^Method Mcp\\Server\\ServerBuilder\:\:setDiscovery\(\) has parameter \$scanDirs with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 path: src/Server/ServerBuilder.php - - message: '#^Method Mcp\\Server\\ServerBuilder\:\:withPrompt\(\) has parameter \$handler with no value type specified in iterable type array\.$#' + message: '#^Method Mcp\\Server\\ServerBuilder\:\:addPrompt\(\) has parameter \$handler with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 path: src/Server/ServerBuilder.php - - message: '#^Method Mcp\\Server\\ServerBuilder\:\:withResource\(\) has parameter \$handler with no value type specified in iterable type array\.$#' + message: '#^Method Mcp\\Server\\ServerBuilder\:\:addResource\(\) has parameter \$handler with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 path: src/Server/ServerBuilder.php - - message: '#^Method Mcp\\Server\\ServerBuilder\:\:withResourceTemplate\(\) has parameter \$handler with no value type specified in iterable type array\.$#' + message: '#^Method Mcp\\Server\\ServerBuilder\:\:addResourceTemplate\(\) has parameter \$handler with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 path: src/Server/ServerBuilder.php - - message: '#^Method Mcp\\Server\\ServerBuilder\:\:withTool\(\) has parameter \$handler with no value type specified in iterable type array\.$#' + message: '#^Method Mcp\\Server\\ServerBuilder\:\:addTool\(\) has parameter \$handler with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 path: src/Server/ServerBuilder.php - - message: '#^Method Mcp\\Server\\ServerBuilder\:\:withTool\(\) has parameter \$inputSchema with no value type specified in iterable type array\.$#' + message: '#^Method Mcp\\Server\\ServerBuilder\:\:addTool\(\) has parameter \$inputSchema with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 path: src/Server/ServerBuilder.php @@ -535,49 +535,25 @@ parameters: path: src/Server/ServerBuilder.php - - message: '#^Property Mcp\\Server\\ServerBuilder\:\:\$manualPrompts has unknown class Mcp\\Server\\Closure as its type\.$#' - identifier: class.notFound - count: 1 - path: src/Server/ServerBuilder.php - - - - message: '#^Property Mcp\\Server\\ServerBuilder\:\:\$manualPrompts type has no value type specified in iterable type array\.$#' + message: '#^Property Mcp\\Server\\ServerBuilder\:\:\$prompts type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 path: src/Server/ServerBuilder.php - - message: '#^Property Mcp\\Server\\ServerBuilder\:\:\$manualResourceTemplates has unknown class Mcp\\Server\\Closure as its type\.$#' - identifier: class.notFound - count: 1 - path: src/Server/ServerBuilder.php - - - - message: '#^Property Mcp\\Server\\ServerBuilder\:\:\$manualResourceTemplates type has no value type specified in iterable type array\.$#' + message: '#^Property Mcp\\Server\\ServerBuilder\:\:\$resourceTemplates type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 path: src/Server/ServerBuilder.php - - message: '#^Property Mcp\\Server\\ServerBuilder\:\:\$manualResources has unknown class Mcp\\Server\\Closure as its type\.$#' - identifier: class.notFound - count: 1 - path: src/Server/ServerBuilder.php - - - - message: '#^Property Mcp\\Server\\ServerBuilder\:\:\$manualResources type has no value type specified in iterable type array\.$#' + message: '#^Property Mcp\\Server\\ServerBuilder\:\:\$resources type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 path: src/Server/ServerBuilder.php - - message: '#^Property Mcp\\Server\\ServerBuilder\:\:\$manualTools has unknown class Mcp\\Server\\Closure as its type\.$#' - identifier: class.notFound - count: 1 - path: src/Server/ServerBuilder.php - - - - message: '#^Property Mcp\\Server\\ServerBuilder\:\:\$manualTools type has no value type specified in iterable type array\.$#' + message: '#^Property Mcp\\Server\\ServerBuilder\:\:\$tools type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 path: src/Server/ServerBuilder.php diff --git a/src/Server/ServerBuilder.php b/src/Server/ServerBuilder.php index ede6c77d..4075cdba 100644 --- a/src/Server/ServerBuilder.php +++ b/src/Server/ServerBuilder.php @@ -70,15 +70,15 @@ final class ServerBuilder private ?string $instructions = null; /** @var array< - * array{handler: array|string|Closure, + * array{handler: array|string|\Closure, * name: string|null, * description: string|null, * annotations: ToolAnnotations|null} * > */ - private array $manualTools = []; + private array $tools = []; /** @var array< - * array{handler: array|string|Closure, + * array{handler: array|string|\Closure, * uri: string, * name: string|null, * description: string|null, @@ -86,23 +86,23 @@ final class ServerBuilder * size: int|null, * annotations: Annotations|null} * > */ - private array $manualResources = []; + private array $resources = []; /** @var array< - * array{handler: array|string|Closure, + * array{handler: array|string|\Closure, * uriTemplate: string, * name: string|null, * description: string|null, * mimeType: string|null, * annotations: Annotations|null} * > */ - private array $manualResourceTemplates = []; + private array $resourceTemplates = []; /** @var array< - * array{handler: array|string|Closure, + * array{handler: array|string|\Closure, * name: string|null, * description: string|null} * > */ - private array $manualPrompts = []; + private array $prompts = []; private ?string $discoveryBasePath = null; /** * @var array|string[] @@ -113,7 +113,7 @@ final class ServerBuilder /** * Sets the server's identity. Required. */ - public function withServerInfo(string $name, string $version, ?string $description = null): self + public function setServerInfo(string $name, string $version, ?string $description = null): self { $this->serverInfo = new Implementation(trim($name), trim($version), $description); @@ -123,7 +123,7 @@ public function withServerInfo(string $name, string $version, ?string $descripti /** * Configures the server's pagination limit. */ - public function withPaginationLimit(int $paginationLimit): self + public function setPaginationLimit(int $paginationLimit): self { $this->paginationLimit = $paginationLimit; @@ -137,7 +137,7 @@ public function withPaginationLimit(int $paginationLimit): self * etc. It can be thought of like a "hint" to the model. For example, this information MAY * be added to the system prompt. */ - public function withInstructions(?string $instructions): self + public function setInstructions(?string $instructions): self { $this->instructions = $instructions; @@ -147,35 +147,35 @@ public function withInstructions(?string $instructions): self /** * Provides a PSR-3 logger instance. Defaults to NullLogger. */ - public function withLogger(LoggerInterface $logger): self + public function setLogger(LoggerInterface $logger): self { $this->logger = $logger; return $this; } - public function withEventDispatcher(EventDispatcherInterface $eventDispatcher): self + public function setEventDispatcher(EventDispatcherInterface $eventDispatcher): self { $this->eventDispatcher = $eventDispatcher; return $this; } - public function withToolCaller(ToolCallerInterface $toolCaller): self + public function setToolCaller(ToolCallerInterface $toolCaller): self { $this->toolCaller = $toolCaller; return $this; } - public function withResourceReader(ResourceReaderInterface $resourceReader): self + public function setResourceReader(ResourceReaderInterface $resourceReader): self { $this->resourceReader = $resourceReader; return $this; } - public function withPromptGetter(PromptGetterInterface $promptGetter): self + public function setPromptGetter(PromptGetterInterface $promptGetter): self { $this->promptGetter = $promptGetter; @@ -186,14 +186,14 @@ public function withPromptGetter(PromptGetterInterface $promptGetter): self * Provides a PSR-11 DI container, primarily for resolving user-defined handler classes. * Defaults to a basic internal container. */ - public function withContainer(ContainerInterface $container): self + public function setContainer(ContainerInterface $container): self { $this->container = $container; return $this; } - public function withDiscovery( + public function setDiscovery( string $basePath, array $scanDirs = ['.', 'src'], array $excludeDirs = [], @@ -208,14 +208,14 @@ public function withDiscovery( /** * Manually registers a tool handler. */ - public function withTool( + public function addTool( callable|array|string $handler, ?string $name = null, ?string $description = null, ?ToolAnnotations $annotations = null, ?array $inputSchema = null, ): self { - $this->manualTools[] = compact('handler', 'name', 'description', 'annotations', 'inputSchema'); + $this->tools[] = compact('handler', 'name', 'description', 'annotations', 'inputSchema'); return $this; } @@ -223,7 +223,7 @@ public function withTool( /** * Manually registers a resource handler. */ - public function withResource( + public function addResource( callable|array|string $handler, string $uri, ?string $name = null, @@ -232,7 +232,7 @@ public function withResource( ?int $size = null, ?Annotations $annotations = null, ): self { - $this->manualResources[] = compact('handler', 'uri', 'name', 'description', 'mimeType', 'size', 'annotations'); + $this->resources[] = compact('handler', 'uri', 'name', 'description', 'mimeType', 'size', 'annotations'); return $this; } @@ -240,7 +240,7 @@ public function withResource( /** * Manually registers a resource template handler. */ - public function withResourceTemplate( + public function addResourceTemplate( callable|array|string $handler, string $uriTemplate, ?string $name = null, @@ -248,7 +248,7 @@ public function withResourceTemplate( ?string $mimeType = null, ?Annotations $annotations = null, ): self { - $this->manualResourceTemplates[] = compact( + $this->resourceTemplates[] = compact( 'handler', 'uriTemplate', 'name', @@ -263,9 +263,9 @@ public function withResourceTemplate( /** * Manually registers a prompt handler. */ - public function withPrompt(callable|array|string $handler, ?string $name = null, ?string $description = null): self + public function addPrompt(callable|array|string $handler, ?string $name = null, ?string $description = null): self { - $this->manualPrompts[] = compact('handler', 'name', 'description'); + $this->prompts[] = compact('handler', 'name', 'description'); return $this; } @@ -285,7 +285,7 @@ public function build(): Server $resourceReader = $this->resourceReader ??= new ResourceReader($registry, $referenceHandler, $logger); $promptGetter = $this->promptGetter ??= new PromptGetter($registry, $referenceHandler, $logger); - $this->registerManualElements($registry, $logger); + $this->registerCapabilities($registry, $logger); if (null !== $this->discoveryBasePath) { $discovery = new Discoverer($registry, $logger); @@ -310,11 +310,11 @@ public function build(): Server * Helper to perform the actual registration based on stored data. * Moved into the builder. */ - private function registerManualElements( + private function registerCapabilities( Registry\ReferenceRegistryInterface $registry, LoggerInterface $logger = new NullLogger(), ): void { - if (empty($this->manualTools) && empty($this->manualResources) && empty($this->manualResourceTemplates) && empty($this->manualPrompts)) { + if (empty($this->tools) && empty($this->resources) && empty($this->resourceTemplates) && empty($this->prompts)) { return; } @@ -322,7 +322,7 @@ private function registerManualElements( $schemaGenerator = new SchemaGenerator($docBlockParser); // Register Tools - foreach ($this->manualTools as $data) { + foreach ($this->tools as $data) { try { $reflection = HandlerResolver::resolve($data['handler']); @@ -357,7 +357,7 @@ private function registerManualElements( } // Register Resources - foreach ($this->manualResources as $data) { + foreach ($this->resources as $data) { try { $reflection = HandlerResolver::resolve($data['handler']); @@ -395,7 +395,7 @@ private function registerManualElements( } // Register Templates - foreach ($this->manualResourceTemplates as $data) { + foreach ($this->resourceTemplates as $data) { try { $reflection = HandlerResolver::resolve($data['handler']); @@ -433,7 +433,7 @@ private function registerManualElements( } // Register Prompts - foreach ($this->manualPrompts as $data) { + foreach ($this->prompts as $data) { try { $reflection = HandlerResolver::resolve($data['handler']);