* feat: add MCP Apps extension (io.modelcontextprotocol/ui) support
Adds support for the MCP Apps protocol extension, which lets servers
expose interactive HTML UIs as resources rendered by spec-conforming
clients (e.g. Goose) in sandboxed iframes.
- Generic extension plumbing: ServerExtensionInterface and
Builder::enableExtension(), with extensions advertised under
capabilities.extensions during the initialize handshake.
ClientCapabilities/ServerCapabilities gain an extensions field.
- Schema DTOs under Mcp\Schema\Extension\Apps: the McpApps marker,
UiToolMeta, ToolVisibility enum, UiResourceContentMeta,
UiResourceCsp, and UiResourcePermissions (with empty-object
presence markers per spec).
- A worked weather example under examples/server/mcp-apps/ with a
minimal spec-conforming view (ui/initialize handshake, postMessage
JSONRPCMessage objects, and ResizeObserver-driven size reporting).
- docs/extensions.md guide with pointers from index.md and
examples.md to the ext-apps repository for the TypeScript SDK and
richer view-side patterns.
- Unit and inspector snapshot test coverage.
Spec: https://github.com/modelcontextprotocol/ext-apps
* Type UiToolMeta visibility as ToolVisibility enum
Also fix UiResourceContentMeta::jsonSerialize() return phpdoc.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Address review nitpicks for MCP Apps extension
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Apply PR review feedback for MCP Apps extension
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Add regression tests and CHANGELOG entry for capabilities extensions
- Pin the is_array() guards on extensions in ServerCapabilities and
ClientCapabilities::fromArray() with explicit non-array payload tests.
- Pin the isset()-rejects-null contract in UiResourcePermissions::fromArray().
- Surface the new extensions field on both capability classes in CHANGELOG.
- Inline the ?: idiom in Builder::build() to match the surrounding style.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Add optional namePatterns capability to discovery so that the default scan for `*.php` files can be overridden.
* add default to namePatterns docs
* add an error check if we manage to pass in an empty list of patterns
* add unit tests (and a static entry to classmap for composer.json so it autoloads from a non .php file for the test)
* run php-cs-fixer
* change how default namePatterns are set and make sure all the annotations are correct
* Fix bad whitespace
Co-authored-by: Christopher Hertel <mail@christopher-hertel.de>
* switch to a const default instead of nullable with a check in the function to convert null to a default
* make sure we handle empty arrays
* formatting fixes
* Apply suggestion from @chr-hertel
Co-authored-by: Christopher Hertel <mail@christopher-hertel.de>
* Add changelog entry
---------
Co-authored-by: Christopher Hertel <mail@christopher-hertel.de>
* feat(client): add complete MCP client SDK with STDIO and HTTP transports
Add Client, Builder, ClientProtocol, ClientSession, and transport
implementations for communicating with MCP servers. Supports tools, resources, prompts, and real-time progress/logging notifications.
* refactor(examples): reorganize examples into server/ and client/ folders
* feat: add SamplingRequestHandler for handling server sampling requests
* feat: add setLoggingLevel method to control server logging verbosity
* refactor: make progress token dependent on request ID
* docs: Update server IP in usage instructions and add notes on sampling server requirements.
* feat: add complete() method for completion/complete requests
* refactor: properly parse and type initialize result
* refactor: standardize method names
* fix: revert changes to server related components
* fix: revert changes to server related components
* refactor: Restructure client transports and handlers into dedicated namespaces.
* fix: cs and php-stan errors fixes(partial)
* feat: Refactor request handlers to return `Response` or `Error` objects directly, adding a `SamplingException` and error logging for sampling requests.
* feat: Replace `ClientTransportInterface` with `TransportInterface` and move response result deserialization to client methods.
* refactor: remove redundant timeout check for intialize on transports
The processFiber that executes per tick while fiber is suspended already handles timeouts while waiting
* feat: broaden symfony/http-client dependency to support Symfony 5.4 to 8.0
* Update examples/client/README.md
Co-authored-by: Christopher Hertel <mail@christopher-hertel.de>
* Update examples/client/README.md
Co-authored-by: Christopher Hertel <mail@christopher-hertel.de>
* refactor: remove outgoing message queue from session and simplify transport send method to directly dispatch messages.
* refactor: Replace ClientSession with ClientState for clearer intent on runtime state management
* refactor: rename connectAndInitialize to connect for consistency
* chore: cs fix
* chore: use SamplingCallbackInterface instead of a closure for sampling request handler
---------
Co-authored-by: Christopher Hertel <mail@christopher-hertel.de>
* Add Middleware handlers to StreamableHttpTransport
* OAuth Implementation based on middleware
* OAuth Implementation based on middleware
* Add Middleware handlers to StreamableHttpTransport
* OAuth Implementation based on middleware
* OAuth Implementation based on middleware
Signed-off-by: Volodymyr Panivko <sveneld300@gmail.com>
* Address PR review feedback for OAuth middleware
* Apply php-cs-fixer to satisfy QA
* Use Mcp exception classes in OAuth middleware
* Refactor OAuth HTTP stack and add Microsoft example policies
* Fix QA PHPStan findings in OAuth examples and auth middleware
* Require OIDC discovery in JWKS provider and refine OAuth proxy behavior
* Remove local development docker artifacts from VCS
* Revert .gitignore changes for local docker files
* Fix body retrieval in OAuthRequestMetaMiddleware for proper string conversion
Signed-off-by: Volodymyr Panivko <sveneld300@gmail.com>
* Address OAuth PR review feedback and align example configs
* Fix QA style issues and add authorization docs
* Fix PHPStan typing issues in OAuth middleware
* Remove duplicate Middleware namespace, consolidate under Http\Middleware
Remove old Mcp\Server\Transport\Middleware\ classes that were duplicated
in Mcp\Server\Transport\Http\Middleware\ and Http\OAuth\. Update docs
to reference the correct namespaces.
* Address PR review: replace Throwable catch with specific exceptions, add JSON_THROW_ON_ERROR
- JwtTokenValidator: replace catch(\Throwable) with explicit
\InvalidArgumentException|\UnexpectedValueException|\DomainException,
letting RuntimeException from JwksProvider propagate as infrastructure errors
- OAuthProxyMiddleware: add \JSON_THROW_ON_ERROR to json_encode for metadata response
- Update tests to expect RuntimeException for JWKS infrastructure failures
---------
Signed-off-by: Volodymyr Panivko <sveneld300@gmail.com>
Co-authored-by: Volodymyr Panivko <volodymyr.panivko@togethernetworks.com>
- Add ElicitAction enum (accept/decline/cancel)
- Add schema definitions for elicitation fields (string, number, boolean, enum)
- Add ElicitationSchema wrapper for requestedSchema
- Add ElicitRequest and ElicitResult for elicitation/create method
- Update ClientCapabilities to support elicitation capability
- Add elicit() method to ClientGateway
- Store client capabilities in session during initialization
- Add comprehensive unit tests
- Add elicitation example server with book_restaurant, confirm_action, and collect_feedback tools
* Add API documentation generation with phpDocumentor
- Add phpDocumentor configuration and `docs` Makefile target
- Generate docs during CI to catch errors before releases
- Set up GitHub Pages with Jekyll for hosting generated docs
- Add GitHub Actions workflow to deploy docs to GitHub Pages on releases
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix phpDocumentor errors in type annotations
Change class-string union types to use phpDocumentor-compatible syntax
and reorder docblock tags so class descriptions precede `@author` tags.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix CI: pin phar-io/composer-distributor ^1.0.2
phar-io/composer-distributor 1.0.0 has a bug where it uses the wrong
package version when determining the phpDocumentor download URL,
causing CI to fail with 404 errors when using --prefer-lowest.
Version 1.0.2 fixes this issue.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Integrate markdown guides into phpDocumentor output
Configure phpDocumentor to generate both API documentation and user
guides in a single unified site. This replaces the previous Jekyll-based
approach where API docs were copied into the docs folder.
- Add `<guide>` configuration to `phpdoc.dist.xml`
- Create custom template with "Guides" navigation link
- Replace `docs/index.html` redirect with `docs/index.md` guide index
- Update workflow to publish `build/docs` directly without Jekyll
- Track `.phpdoc/template/` while still ignoring `.phpdoc/cache/`
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fine-tuning for path, config, and layout
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Christopher Hertel <mail@christopher-hertel.de>
* feat(server): add bidirectional client communication support
* fix(server): use correct session ID string conversion method
* fix: clean up docblocks for request handler methods in Builder
* fix: merge artifacts
* feat: implement discovery caching with state-based approach
- Add DiscoveryState class to encapsulate discovered MCP capabilities
- Add exportDiscoveryState and importDiscoveryState methods to Registry
- Modify Discoverer to return DiscoveryState instead of void
- Create CachedDiscoverer decorator for caching discovery results
- Add importDiscoveryState method to ReferenceRegistryInterface
- Update ServerBuilder to use caching with withCache() method
- Update tests to work with new state-based approach
- Add example demonstrating cached discovery functionality
- Add PSR-16 SimpleCache and Symfony Cache dependencies
* docs: add comprehensive discovery caching documentation
- Add detailed documentation explaining discovery caching architecture
- Include usage examples for different cache implementations
- Document performance benefits and best practices
- Add troubleshooting guide and migration instructions
- Include complete API reference for all caching components
- Fix PHPStan issues by regenerating baseline
- Apply PHP CS Fixer formatting to all new files
* refactor: address reviewer feedback and clean up discovery caching
- Make DiscoveryState class final
- Cache DiscoveryState objects directly instead of arrays (no serialization needed)
- Rename exportDiscoveryState/importDiscoveryState to getDiscoveryState/setDiscoveryState
- Add getDiscoveryState method to ReferenceRegistryInterface
- Remove TTL parameter from CachedDiscoverer (no expiration by default)
- Remove unused methods from DiscoveryState (toArray, fromArray, merge)
- Simplify ServerBuilder to handle decoration internally
- Make Discoverer.applyDiscoveryState() internal (no longer public API)
- Simplify documentation to focus on user perspective
- Remove unnecessary development comments
- Update all tests to work with new architecture
- All tests pass, PHPStan clean, code formatting applied
* refactor: clean up comments and formatting in server.php example
* refactor: improve code formatting and consistency in discovery classes and example server
* Fix method names in cached discovery example
- Change withServerInfo() to setServerInfo()
- Change withDiscovery() to setDiscovery()
- Change withLogger() to setLogger()
- Fixes PHPStan static analysis errors
* refactor: update method names in ServerBuilder for consistency
- Change withCache() to setCache() in ServerBuilder
- Update example and documentation to reflect method name changes
- Ensure consistency across caching implementation in examples and documentation
* refactor: reorganize examples and fix PHPStan baseline
- Move cached discovery example from examples/10 to examples/09
- Update composer.json autoload-dev namespace mapping
- Fix PHPStan baseline by removing invalid entries for non-existent files
- Update server.php to follow proper example pattern with logging and lifecycle
* fix: correct formatting in server.php
* feat(server): Rework transport architecture and add StreamableHttpTransport
- `Server::connect()` no longer contains a processing loop.
- `TransportInterface` is updated with `setMessageHandler()` and `listen()`.
- `StdioTransport` is updated to implement the new interface.
- A new, minimal `StreamableHttpTransport` is added for stateless HTTP.
* refactor(server): use event-driven message handling
* feat(server): Introduce a formal session management system
* fix: ensure session elements are preserved when building server (regression from #46)
* refactor: consolidate HTTP example to use shared dependencies
* feat(server): Enhance message handling with session support
- Updated `TransportInterface` to use `onMessage` for handling incoming messages with session IDs.
- Refactored `Server`, `Handler`, and transport classes to accommodate session management using `Uuid`.
- Introduced methods for creating sessions with auto-generated and specific UUIDs in `SessionFactory` and `SessionFactoryInterface`.
* feat(server): Integrate session management in message handling
- Added session support to the `Server` and `Handler` classes, allowing for session data to be managed during message processing.
- Updated `TransportInterface` to include session context in the `send` method.
- Refactored various request handlers to utilize session information, ensuring proper session handling for incoming requests.
- Introduced a file-based session store for persistent session data management
* feat: Update session builder method to use set* instead of with*
* feat: Fix test compatibility with new session management architecture
* chore: apply code style fixes
* fix: remove deprecated SSE transport and resolve PHPStan issues
Remove symfony/dependency-injection and symfony/event-dispatcher
from require-dev as they are not used in the codebase. The project
uses psr/event-dispatcher interface instead of symfony's implementation.