-
Notifications
You must be signed in to change notification settings - Fork 102
Description
Is your feature request related to a problem? Please describe
The current PHP SDK focuses exclusively on server-side MCP implementation. However, the Model Context Protocol (MCP) specification defines both server and client sides, and a complete SDK should support both directions of communication. Without a client component, PHP applications cannot programmatically connect to and consume services from MCP servers, limiting the ecosystem's potential for integration and automation.
Currently, PHP developers looking to build MCP clients must either use standalone libraries (like php-mcp/client or swisnl/mcp-client) or implement their own solutions, fragmenting the ecosystem. This issue aims to bring a unified, officially supported client implementation into the modelcontextprotocol/php-sdk repository as a sub-component, following the same development practices and standards as the existing server component.
Describe the solution you'd like
Implement a src/Client sub-component within the php-sdk repository that provides a comprehensive, well-designed PHP client for interacting with MCP servers. The implementation should:
-
Follow the existing SDK architecture and patterns
- Align with the server component's code structure and conventions
- Adopt Symfony's coding standards and backward compatibility promise
- Use attribute-based configuration where appropriate
- Integrate with the existing transport layer concepts
-
Provide both synchronous and asynchronous APIs
- Simple, blocking methods for straightforward use cases (
$client->listTools(),$client->callTool()) - Promise-based async methods for advanced scenarios (
$client->listToolsAsync()) - Leverage existing async infrastructure (ReactPHP or consider php-runtime/runtime for transport agnosticism)
- Simple, blocking methods for straightforward use cases (
-
Support multiple transport mechanisms
- STDIO transport (for spawning and communicating with server processes)
- HTTP/SSE transport (for communicating with remote MCP servers)
- Extensible architecture for custom transports
-
Handle the complete client lifecycle
- Connection initialization and MCP handshake
- Capability negotiation
- Session management
- Graceful disconnection and cleanup
-
Implement core MCP client operations
- List and call tools (
tools/list,tools/call) - List and read resources (
resources/list,resources/read,resources/subscribe) - List and get prompts (
prompts/list,prompts/get) - Handle server notifications (e.g.,
resources/updated,tools/list_changed) - Support logging levels and progress notifications
- List and call tools (
-
Provide robust error handling
- Specific exception types for different failure scenarios
- Timeout management
- Connection recovery strategies
-
Integrate with PSR standards
- PSR-3 (LoggerInterface) for logging
- PSR-16 (SimpleCacheInterface) for optional caching
- PSR-14 (EventDispatcherInterface) for notification handling
Implementation Plan
-
Phase 1: Research & Analysis
- Analyze existing client implementations to identify best practices and patterns
- php-mcp/client - ReactPHP-based with dual sync/async API
- swisnl/mcp-client - Promise-based with tool annotations support
- Review the current
modelcontextprotocol/php-sdkarchitecture to identify:- Shared code that could be reused between client and server components
- Common abstractions (transports, JSON-RPC handling, schema definitions)
- Session management patterns
- Event/notification infrastructure
- Document findings and propose the client architecture that best aligns with existing patterns
- Analyze existing client implementations to identify best practices and patterns
-
Phase 2: Architecture & Design
- Design the
src/Clientnamespace structure following the existingsrc/Serverpatterns - Define client builder API similar to
Server::builder() - Specify transport abstraction layer (evaluate php-runtime/runtime vs. ReactPHP)
- Design configuration system (similar to ServerBuilder but for client capabilities)
- Plan integration points with existing shared code (JsonRpc, Schema, Capability)
- Design the
-
Phase 3: Core Implementation
- Implement base
Clientclass with builder pattern - Implement transport layer
- STDIO transport (for local server processes)
- HTTP/SSE transport (for remote servers)
- Implement connection lifecycle management
- Initialize and handshake
- Capability negotiation
- Session management
- Graceful disconnection
- Implement core MCP operations
- Tools operations (
list,call) - Resources operations (
list,read,subscribe,unsubscribe) - Prompts operations (
list,get)
- Tools operations (
- Implement notification handling system
- Implement base
-
Phase 4: API Refinement
- Implement synchronous API (blocking methods)
- Implement asynchronous API (Promise-based methods)
- Add PSR integration (Logger, Cache, EventDispatcher)
- Implement exception hierarchy for error handling
- Add timeout and retry mechanisms
-
Phase 5: Testing & Documentation
- Write unit tests for all client components
- Write integration tests with real MCP servers
- Create functional tests for transport mechanisms
- Write comprehensive documentation
- Client builder reference
- Transport configuration guide
- Usage examples (both sync and async)
- Integration guides (similar to server docs)
- Create example applications demonstrating client usage
-
Phase 6: Refinement & Stabilization
- Gather feedback from early adopters
- Optimize performance and resource usage
- Ensure backward compatibility with the existing server component
- Consider package split strategy for future releases (if needed)
- Update README and main documentation to reflect client availability
Describe alternatives you've considered
-
Maintain separate client libraries
- Keep php-mcp/client and swisnl/mcp-client as standalone packages
- Pros: No disruption to existing projects, maintains current maintenance structures
- Cons: Fragments the PHP MCP ecosystem, inconsistent APIs, duplicated effort, lack of unified standards
-
Recommend one existing library as "official"
- Endorse one of the existing client libraries without bringing it into php-sdk
- Pros: Quick solution, no implementation work needed
- Cons: Doesn't align with the goal of a unified SDK, may not meet all architectural requirements
-
Client as a separate Composer package
- Create
mcp/clientas a sibling package tomcp/sdk - Pros: Clearer separation of concerns, independent versioning
- Cons: May lead to code duplication with server component, harder to maintain shared abstractions initially
- Create
-
Adopt php-runtime/runtime for transport agnosticism
- Use php-runtime/runtime instead of directly depending on ReactPHP
- Pros: More flexible, allows users to choose their async runtime (ReactPHP, Amp, Swoole, etc.)
- Cons: Adds another abstraction layer, may complicate initial implementation
Additional context
- This proposal aligns with the SDK roadmap item: "Implement Client component"
- The work should build upon insights from php-mcp/client, which was initially developed by Kyrian Obikwelu (who also contributed to the server component)
- Chris (chr-hertel) suggested implementing this as a sub-component in
src/Client, with potential package splitting in future releases - The client should share common code with the server component where possible (JSON-RPC handling, schema definitions, capability models)
- Consider transport agnosticism using php-runtime/runtime to avoid tight coupling to ReactPHP
- The implementation should maintain the experimental status until stabilization, following Symfony's experimental component guidelines
Related Issues & References
- Closes [Client] (Re-)Implement Client component #15 (original client implementation request)
- Related to MCP Specification - Client
- Reference implementations: TypeScript SDK, Python SDK
Note for Contributors: If you're interested in working on any phase of this implementation, please comment below to coordinate efforts and avoid duplicate work. Let's discuss the architectural decisions together to ensure the client component integrates seamlessly with the existing SDK.