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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ All notable changes to `mcp/sdk` will be documented in this file.
* Add client component for building MCP clients
* Add `Builder::setReferenceHandler()` to allow custom `ReferenceHandlerInterface` implementations (e.g. authorization decorators)
* Add elicitation enum schema types per SEP-1330: `TitledEnumSchemaDefinition`, `MultiSelectEnumSchemaDefinition`, `TitledMultiSelectEnumSchemaDefinition`
* Add optional `title` field to `Prompt` and `McpPrompt` for MCP spec compliance
* **BC Break**: `Builder::addPrompt()` signature changed — `$title` parameter added between `$name` and `$description`. Callers using positional arguments for `$description` must switch to named arguments.

0.4.0
-----
Expand Down
1 change: 1 addition & 0 deletions docs/server-builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ $server = Server::builder()

- `handler` (callable|string): The prompt handler
- `name` (string|null): Optional prompt name
- `title` (string|null): Optional human-readable title for display in UI
- `description` (string|null): Optional prompt description
- `icons` (Icon[]|null): Optional array of icons for the prompt

Expand Down
2 changes: 2 additions & 0 deletions src/Capability/Attribute/McpPrompt.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ class McpPrompt
{
/**
* @param ?string $name overrides the prompt name (defaults to method name)
* @param ?string $title Optional human-readable title for display in UI
* @param ?string $description Optional description of the prompt. Defaults to method DocBlock summary.
* @param ?Icon[] $icons Optional list of icon URLs representing the prompt
* @param ?array<string, mixed> $meta Optional metadata
*/
public function __construct(
public ?string $name = null,
public ?string $title = null,
public ?string $description = null,
public ?array $icons = null,
public ?array $meta = null,
Expand Down
2 changes: 1 addition & 1 deletion src/Capability/Discovery/Discoverer.php
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ private function processMethod(\ReflectionMethod $method, array &$discoveredCoun
$paramTag = $paramTags['$'.$param->getName()] ?? null;
$arguments[] = new PromptArgument($param->getName(), $paramTag ? trim((string) $paramTag->getDescription()) : null, !$param->isOptional() && !$param->isDefaultValueAvailable());
}
$prompt = new Prompt($name, $description, $arguments, $instance->icons, $instance->meta);
$prompt = new Prompt($name, $instance->title, $description, $arguments, $instance->icons, $instance->meta);
$completionProviders = $this->getCompletionProviders($method);
$prompts[$name] = new PromptReference($prompt, [$className, $methodName], false, $completionProviders);
++$discoveredCount['prompts'];
Expand Down
1 change: 1 addition & 0 deletions src/Capability/Registry/Loader/ArrayLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ public function load(RegistryInterface $registry): void
}
$prompt = new Prompt(
name: $name,
title: $data['title'] ?? null,
description: $description,
arguments: $arguments,
icons: $data['icons'] ?? null,
Expand Down
8 changes: 8 additions & 0 deletions src/Schema/Prompt.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*
* @phpstan-type PromptData array{
* name: string,
* title?: string,
* description?: string,
* arguments?: PromptArgumentData[],
* icons?: IconData[],
Expand All @@ -33,13 +34,15 @@ class Prompt implements \JsonSerializable
{
/**
* @param string $name the name of the prompt or prompt template
* @param ?string $title Optional human-readable title for display in UI
* @param ?string $description an optional description of what this prompt provides
* @param ?PromptArgument[] $arguments A list of arguments for templating. Null if not a template.
* @param ?Icon[] $icons optional icons representing the prompt
* @param ?array<string, mixed> $meta Optional metadata
*/
public function __construct(
public readonly string $name,
public readonly ?string $title = null,
public readonly ?string $description = null,
public readonly ?array $arguments = null,
public readonly ?array $icons = null,
Expand Down Expand Up @@ -73,6 +76,7 @@ public static function fromArray(array $data): self

return new self(
name: $data['name'],
title: $data['title'] ?? null,
description: $data['description'] ?? null,
arguments: $arguments,
icons: isset($data['icons']) && \is_array($data['icons']) ? array_map(Icon::fromArray(...), $data['icons']) : null,
Expand All @@ -83,6 +87,7 @@ public static function fromArray(array $data): self
/**
* @return array{
* name: string,
* title?: string,
* description?: string,
* arguments?: array<PromptArgument>,
* icons?: Icon[],
Expand All @@ -92,6 +97,9 @@ public static function fromArray(array $data): self
public function jsonSerialize(): array
{
$data = ['name' => $this->name];
if (null !== $this->title) {
$data['title'] = $this->title;
}
if (null !== $this->description) {
$data['description'] = $this->description;
}
Expand Down
3 changes: 2 additions & 1 deletion src/Server/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -472,11 +472,12 @@ public function addResourceTemplate(
public function addPrompt(
\Closure|array|string $handler,
?string $name = null,
?string $title = null,
?string $description = null,
?array $icons = null,
?array $meta = null,
): self {
$this->prompts[] = compact('handler', 'name', 'description', 'icons', 'meta');
$this->prompts[] = compact('handler', 'name', 'title', 'description', 'icons', 'meta');

return $this;
}
Expand Down
8 changes: 4 additions & 4 deletions tests/Conformance/server.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@
->addResourceTemplate([Elements::class, 'resourceTemplate'], 'test://template/{id}/data', 'template', 'A resource template with parameter substitution', 'application/json')
->addResource(static fn () => 'Watched resource content', 'test://watched-resource', 'watched-resource', 'A resource that can be watched')
// Prompts
->addPrompt(static fn () => [['role' => 'user', 'content' => 'This is a simple prompt for testing.']], 'test_simple_prompt', 'A simple prompt without arguments')
->addPrompt([Elements::class, 'promptWithArguments'], 'test_prompt_with_arguments', 'A prompt with required arguments')
->addPrompt([Elements::class, 'promptWithEmbeddedResource'], 'test_prompt_with_embedded_resource', 'A prompt that includes an embedded resource')
->addPrompt([Elements::class, 'promptWithImage'], 'test_prompt_with_image', 'A prompt that includes image content')
->addPrompt(static fn () => [['role' => 'user', 'content' => 'This is a simple prompt for testing.']], name: 'test_simple_prompt', description: 'A simple prompt without arguments')
->addPrompt([Elements::class, 'promptWithArguments'], name: 'test_prompt_with_arguments', description: 'A prompt with required arguments')
->addPrompt([Elements::class, 'promptWithEmbeddedResource'], name: 'test_prompt_with_embedded_resource', description: 'A prompt that includes an embedded resource')
->addPrompt([Elements::class, 'promptWithImage'], name: 'test_prompt_with_image', description: 'A prompt that includes image content')
->build();

$response = $server->run($transport);
Expand Down
Loading