Skip to content

[Schema] Add title field to Prompt for MCP spec compliance#278

Merged
chr-hertel merged 1 commit intomainfrom
fix/prompt-title-field
Apr 14, 2026
Merged

[Schema] Add title field to Prompt for MCP spec compliance#278
chr-hertel merged 1 commit intomainfrom
fix/prompt-title-field

Conversation

@chr-hertel
Copy link
Copy Markdown
Member

Summary

  • Adds the optional title property to the Prompt schema class, McpPrompt attribute, Discoverer, ArrayLoader, and Server\Builder
  • The MCP 2025-11-25 spec defines title as a human-readable display name for prompts (distinct from the programmatic name identifier), but it was missing from the SDK
  • Fully backwards-compatible: title defaults to null everywhere

Closes #276

Test plan

  • All 600 unit tests pass
  • PHPStan static analysis passes
  • PHP CS Fixer reports no issues

🤖 Generated with Claude Code

@chr-hertel chr-hertel changed the title Add title field to Prompt for MCP spec compliance [Schema] Add title field to Prompt for MCP spec compliance Apr 11, 2026
@chr-hertel chr-hertel added Schema Issues & PRs related to the Schema component improves spec compliance Improves consistency with other SDKs such as TyepScript breaking change Breaking the Backwards Compatibility Promise labels Apr 11, 2026
@chr-hertel chr-hertel force-pushed the fix/prompt-title-field branch from 5aa8874 to d9affe9 Compare April 11, 2026 15:17
@chr-hertel chr-hertel added this to the 0.5.0 milestone Apr 11, 2026
soyuka
soyuka previously approved these changes Apr 14, 2026
The MCP 2025-11-25 specification defines an optional `title` property on
Prompt for human-readable display in UI contexts, distinct from the
programmatic `name` identifier. This was missing from the SDK.

BC Break: Builder::addPrompt() signature changed — $title parameter added
between $name and $description. Callers using positional arguments for
$description must switch to named arguments.

Closes #276

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@chr-hertel chr-hertel merged commit 7af5a34 into main Apr 14, 2026
18 of 19 checks passed
@chr-hertel chr-hertel deleted the fix/prompt-title-field branch April 14, 2026 08:04
e0ipso pushed a commit to e0ipso/php-sdk that referenced this pull request Apr 19, 2026
Mirror PR modelcontextprotocol#278's Prompt change for Tool:

- Add optional ?string $title to Mcp\Schema\Tool between $name
  and $inputSchema. fromArray() now reads $data['title'];
  jsonSerialize() emits 'title' right after 'name'. The
  @phpstan-type ToolData gains title?: string.
- Add ?string $title to the #[McpTool] attribute between $name
  and $description.
- Note ToolAnnotations::$title as deprecated-for-display in
  favor of Tool::$title per MCP spec 2025-06-18 (PHPDoc only,
  field retained for BC).

Phase 1 of plan 01--tool-title-spec-compliance. Later phases
update Discoverer, Builder::addTool(), ArrayLoader, and the
conformance fixture to match the new signature.
chr-hertel pushed a commit that referenced this pull request Apr 26, 2026
* feat(schema): add top-level title to Tool

Mirror PR #278's Prompt change for Tool:

- Add optional ?string $title to Mcp\Schema\Tool between $name
  and $inputSchema. fromArray() now reads $data['title'];
  jsonSerialize() emits 'title' right after 'name'. The
  @phpstan-type ToolData gains title?: string.
- Add ?string $title to the #[McpTool] attribute between $name
  and $description.
- Note ToolAnnotations::$title as deprecated-for-display in
  favor of Tool::$title per MCP spec 2025-06-18 (PHPDoc only,
  field retained for BC).

Phase 1 of plan 01--tool-title-spec-compliance. Later phases
update Discoverer, Builder::addTool(), ArrayLoader, and the
conformance fixture to match the new signature.

* feat(server): thread title through discovery

- Discoverer::processMethod() now propagates McpTool::$title
  into every discovered Tool via named arguments.
- Builder::addTool() accepts ?string $title between $name and
  $description. [BC Break] positional callers passing the old
  $description as 3rd positional argument must switch to named
  arguments, matching the precedent set for addPrompt() in
  0.5.0.
- tests/Conformance/server.php migrated to named-argument form
  for every addTool() call.

Phase 2 of plan 01--tool-title-spec-compliance.

* feat(loader): forward title in ArrayLoader

ArrayLoader now reads 'title' from each tool config entry and
passes it into the Tool constructor, completing the wiring
from Builder::addTool() through array-driven registration.

The $tools @param array-shape typedef gains title: ?string
between name and description.

Phase 3 of plan 01--tool-title-spec-compliance.

* test(schema): cover Tool.title end-to-end

- New tests/Unit/Schema/ToolTest.php: constructor round-trip,
  jsonSerialize key-order when title set vs null, fromArray
  tolerance.
- New tests/Unit/Capability/Discovery/DiscovererToolTitleTest
  plus a TitleFixture class verifying McpTool(title: ...)
  propagates through discovery into the registered Tool.
- New tests/Unit/Capability/Registry/Loader/ArrayLoader...
  test verifying array-driven title propagation.
- Extend McpToolTest for title named-arg and default-null.
- Extend BuilderTest with addTool(title: 't') propagation.
- Update tests/Unit/.../RegistryTest, CallToolHandlerTest,
  ListToolsHandlerTest and examples/.../server.php
  new Tool(...) call sites to pass title (named args) so
  they match the new constructor signature.
- CHANGELOG 0.6.0 section: feature bullet + [BC Break]
  note for addTool() signature, mirroring 0.5.0 Prompt
  entries.
- docs/server-builder.md: addTool() row and prose now
  list title? between name and description.

Phase 4 of plan 01--tool-title-spec-compliance. All 730
phpunit tests pass; remaining phpstan warnings are
pre-existing and unrelated to Tool.title.

* refactor(schema): make Tool.title non-BC-breaking

Move `title` to the end of the Tool, Builder::addTool, and McpTool
attribute constructors with a default of null. This preserves
positional-argument compatibility and removes the need for
`title: null` boilerplate at call sites. JSON serialization order
(name, title, inputSchema, ...) is unchanged.

Also tighten the new tests: parameterize ToolTest with data
providers, fold the Discoverer title fixture into the existing
DiscoverableToolHandler, and drop the reflection-heavy Builder
test that overlapped with ArrayLoaderToolTitleTest.

* fix: move title after name

---------

Co-authored-by: DDEV User <nobody@example.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change Breaking the Backwards Compatibility Promise improves spec compliance Improves consistency with other SDKs such as TyepScript Schema Issues & PRs related to the Schema component

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing title and arguments fields in Prompt definition (spec compliance)

3 participants