Skip to content

[Client] Implement PHP MCP Client Component in php-sdk #185

@robertoperuzzo

Description

@robertoperuzzo

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:

  1. 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
  2. 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)
  3. 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
  4. Handle the complete client lifecycle

    • Connection initialization and MCP handshake
    • Capability negotiation
    • Session management
    • Graceful disconnection and cleanup
  5. 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
  6. Provide robust error handling

    • Specific exception types for different failure scenarios
    • Timeout management
    • Connection recovery strategies
  7. 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
    • Review the current modelcontextprotocol/php-sdk architecture 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
  • Phase 2: Architecture & Design

    • Design the src/Client namespace structure following the existing src/Server patterns
    • 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)
  • Phase 3: Core Implementation

    • Implement base Client class 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)
    • Implement notification handling system
  • 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

  1. 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
  2. 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
  3. Client as a separate Composer package

    • Create mcp/client as a sibling package to mcp/sdk
    • Pros: Clearer separation of concerns, independent versioning
    • Cons: May lead to code duplication with server component, harder to maintain shared abstractions initially
  4. 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


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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions