php-sdk/examples/server
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Christopher Hertel cbceef06eb
[Server] Serve both protocol eras from one endpoint (#455)
* [Server] Serve both protocol eras from one endpoint

The two lifecycles share a transport, not a dispatcher. StreamableHttpTransport
classifies each request - a 2026-07-28 envelope, an initialize handshake, or a
session-bound follow-up - through InboundClassifier and routes it to the
dispatcher that owns it, so one URL answers a modern client and a handshake-era
one alike. Builder::build() carries both; withoutModernEra() opts out and
setModernVersions() narrows what the modern leg answers for.

InputRequiredShim lets a handler written for multi round-trip requests also
serve a handshake-era client, by turning each ask into the request/response
exchange that era has - so a handler is written once rather than twice.

The conformance fixture collapses into one server for the same reason: both
legs now hit the same URL.

* Trim redundant comments, fix stale in-memory claim in conformance fixture

* Drop stale json-schema-2020-12 baseline entries

The new fixture tool makes this scenario pass in both eras now.

* Reject handshake revisions in setModernVersions(), warn on unsafe custom middleware

Copilot review: setModernVersions() accepted revisions InboundClassifier
would never route to the modern leg. StreamableHttpTransport now warns
when a custom middleware list carries ProtocolVersionMiddleware, since
it runs before era classification and rejects modern-era traffic by
default. Also fixed a misleading docblock claim on the same middleware.
2026-08-19 01:36:56 +02:00
..
cached-discovery CS update after release of v3.95 (#282) 2026-04-26 12:39:27 +02:00
client-communication [Client][Server] Add Roots support (#395) 2026-08-14 23:04:25 +02:00
client-logging Move examples to server directory (#198) 2025-12-27 15:39:05 +01:00
combined-registration [Examples] Demo pre-built instance handlers + inspector coverage (#390) 2026-07-15 00:23:20 +02:00
complex-tool-schema Use SchemaValidator to validate tool input (#203) 2026-01-11 21:46:53 +01:00
custom-dependencies Update codestyle based on updated Symfony rules (#229) 2026-02-01 11:54:31 +01:00
custom-method-handlers [Schema][Server] Add top-level title to Tool (#288) 2026-04-26 15:37:40 +02:00
discovery-calculator Move examples to server directory (#198) 2025-12-27 15:39:05 +01:00
discovery-userprofile [Schema] Add resource_link content block (#400) 2026-08-14 23:20:56 +02:00
elicitation [Schema][Server] Add top-level title to Tool (#288) 2026-04-26 15:37:40 +02:00
env-variables Update codestyle based on updated Symfony rules (#229) 2026-02-01 11:54:31 +01:00
explicit-registration Move examples to server directory (#198) 2025-12-27 15:39:05 +01:00
mcp-apps [Examples][Tests] Make the MCP Apps example work over HTTP, and pin it (#439) 2026-08-18 14:51:34 +02:00
oauth-keycloak [Server] Compose StreamableHttpTransport security middleware via defaultMiddleware() factory (#307) 2026-05-25 13:49:43 +02:00
oauth-microsoft [Server] Compose StreamableHttpTransport security middleware via defaultMiddleware() factory (#307) 2026-05-25 13:49:43 +02:00
schema-showcase Update codestyle based on updated Symfony rules (#229) 2026-02-01 11:54:31 +01:00
bootstrap.php [Server] Serve both protocol eras from one endpoint (#455) 2026-08-19 01:36:56 +02:00
README.md [Client] Feat: Implement MCP client component (#192) 2026-03-10 17:22:40 +01:00

MCP SDK Examples

This directory contains various examples of how to use the PHP MCP SDK.

You can run the examples with the dependencies already installed in the root directory of the SDK. The bootstrapping of the example will choose the used transport based on the SAPI you use.

For running an example, you execute the server.php like this:

# For using the STDIO transport:
php examples/server/discovery-calculator/server.php

# For using the Streamable HTTP transport:
php -S localhost:8000 examples/server/discovery-userprofile/server.php

You will see debug outputs to help you understand what is happening.

Run with Inspector:

npx @modelcontextprotocol/inspector php examples/server/discovery-calculator/server.php

Debugging

You can enable debug output by setting the DEBUG environment variable to 1, and additionally log to a file by setting the FILE_LOG environment variable to 1 as well. A dev.log file gets written within the example's directory.

With the Inspector you can set the environment variables like this:

npx @modelcontextprotocol/inspector -e DEBUG=1 -e FILE_LOG=1 php examples/server/discovery-calculator/server.php