Mirror of https://github.com/modelcontextprotocol/php-sdk — The official PHP SDK for Model Context Protocol servers and clients. Maintained in collaboration with The PHP Foundation.
  • PHP 99.8%
  • Makefile 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Jonathan Hefner 940eb90872
Add API documentation generation with phpDocumentor (#184)
* 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>
2026-02-01 16:22:40 +01:00
.github Add API documentation generation with phpDocumentor (#184) 2026-02-01 16:22:40 +01:00
.phpdoc/template Add API documentation generation with phpDocumentor (#184) 2026-02-01 16:22:40 +01:00
docs Add API documentation generation with phpDocumentor (#184) 2026-02-01 16:22:40 +01:00
examples/server Update codestyle based on updated Symfony rules (#229) 2026-02-01 11:54:31 +01:00
src Add API documentation generation with phpDocumentor (#184) 2026-02-01 16:22:40 +01:00
tests Switch pipeline to conformance baseline (#230) 2026-02-01 11:59:44 +01:00
.gitattributes Add Makefile to export-ignore in .gitattributes (#56) 2025-09-09 22:32:02 +02:00
.gitignore Add API documentation generation with phpDocumentor (#184) 2026-02-01 16:22:40 +01:00
.php-cs-fixer.dist.php House keeping in cs fixer config and makefile (#196) 2025-12-25 00:04:13 +01:00
CHANGELOG.md [Server] Use getDescription to get all descriptions. (#188) 2026-01-11 22:08:05 +01:00
composer.json Add API documentation generation with phpDocumentor (#184) 2026-02-01 16:22:40 +01:00
LICENSE chore: update licensing to Apache 2.0 for new contributions (#222) 2026-01-18 21:29:44 +01:00
Makefile Add API documentation generation with phpDocumentor (#184) 2026-02-01 16:22:40 +01:00
phpdoc.dist.xml Add API documentation generation with phpDocumentor (#184) 2026-02-01 16:22:40 +01:00
phpstan-baseline.neon Add $runnerControl parameter to StdioTransport constructor (#205) 2026-01-11 22:12:33 +01:00
phpstan.dist.neon Add tool name validation for SEP-986 (#140) 2025-11-13 21:42:30 +01:00
phpunit.xml.dist Split testsuite for unit and inspector based tests (#82) 2025-09-25 22:27:41 +01:00
README.md chore: update licensing to Apache 2.0 for new contributions (#222) 2026-01-18 21:29:44 +01:00

MCP PHP SDK

The official PHP SDK for Model Context Protocol (MCP). It provides a framework-agnostic API for implementing MCP servers and clients in PHP.

Important

This SDK is currently in active development with ongoing refinement of its architecture and features. While functional, the API may experience changes as we work toward stabilization.

If you want to help us stabilize the SDK, please see the issue tracker.

This project represents a collaboration between the PHP Foundation and the Symfony project. It adopts development practices and standards from the Symfony project, including Coding Standards and the Backward Compatibility Promise.

Until the first major release, this SDK is considered experimental.

Roadmap

Features

  • Stabilize server component with all needed handlers and functional tests
  • Extend documentation, including integration guides for popular frameworks
  • Implement Client component
  • Support multiple schema versions

Installation

composer require mcp/sdk

Quick Start

This example demonstrates the most common usage pattern - a STDIO server using attribute discovery.

1. Define Your MCP Elements

Create a class with MCP capabilities using attributes:

<?php

namespace App;

use Mcp\Capability\Attribute\McpTool;
use Mcp\Capability\Attribute\McpResource;

class CalculatorElements
{
    /**
     * Adds two numbers together.
     * 
     * @param int $a The first number
     * @param int $b The second number
     * @return int The sum of the two numbers
     */
    #[McpTool]
    public function add(int $a, int $b): int
    {
        return $a + $b;
    }

    /**
     * Performs basic arithmetic operations.
     */
    #[McpTool(name: 'calculate')]
    public function calculate(float $a, float $b, string $operation): float|string
    {
        return match($operation) {
            'add' => $a + $b,
            'subtract' => $a - $b,
            'multiply' => $a * $b,
            'divide' => $b != 0 ? $a / $b : 'Error: Division by zero',
            default => 'Error: Unknown operation'
        };
    }

    #[McpResource(
        uri: 'config://calculator/settings',
        name: 'calculator_config',
        mimeType: 'application/json'
    )]
    public function getSettings(): array
    {
        return ['precision' => 2, 'allow_negative' => true];
    }
}

2. Create the Server Script

Create your MCP server:

#!/usr/bin/env php
<?php

declare(strict_types=1);

require_once __DIR__ . '/vendor/autoload.php';

use Mcp\Server;
use Mcp\Server\Transport\StdioTransport;

$server = Server::builder()
    ->setServerInfo('Calculator Server', '1.0.0')
    ->setDiscovery(__DIR__, ['.'])
    ->build();

$transport = new StdioTransport();

$server->run($transport);

3. Configure Your MCP Client

Add to your client configuration (e.g., Claude Desktop's mcp.json):

{
    "mcpServers": {
        "php-calculator": {
            "command": "php",
            "args": ["/absolute/path/to/your/server.php"]
        }
    }
}

4. Test Your Server

# Test with MCP Inspector
npx @modelcontextprotocol/inspector php /path/to/server.php

# Your AI assistant can now call:
# - add: Add two integers
# - calculate: Perform arithmetic operations
# - Read config://calculator/settings resource

Key Features

Attribute-Based Discovery

Define MCP elements using PHP attributes with automatic discovery:

// Tool with automatic name and description from method
#[McpTool]
public function generateReport(): string { /* ... */ }

// Tool with custom name
#[McpTool(name: 'custom_name')]
public function myMethod(): string { /* ... */ }

// Resource with URI and metadata
#[McpResource(uri: 'config://app/settings', mimeType: 'application/json')]
public function getConfig(): array { /* ... */ }

Manual Registration

Register capabilities programmatically:

$server = Server::builder()
    ->addTool([MyClass::class, 'myMethod'], 'tool_name')
    ->addResource([MyClass::class, 'getData'], 'data://config')
    ->build();

Multiple Transport Options

STDIO Transport (Command-line integration):

$transport = new StdioTransport();
$server->run($transport);

HTTP Transport (Web-based communication):

$transport = new StreamableHttpTransport($request, $responseFactory, $streamFactory);
$response = $server->run($transport);
// Handle $response in your web application

Session Management

By default, the SDK uses in-memory sessions. You can configure different session stores:

use Mcp\Server\Session\FileSessionStore;
use Mcp\Server\Session\InMemorySessionStore;
use Mcp\Server\Session\Psr16StoreSession;
use Symfony\Component\Cache\Psr16Cache;
use Symfony\Component\Cache\Adapter\RedisAdapter;

// Use default in-memory sessions with custom TTL
$server = Server::builder()
    ->setSession(ttl: 7200) // 2 hours
    ->build();

// Override with file-based storage
$server = Server::builder()
    ->setSession(new FileSessionStore(__DIR__ . '/sessions'))
    ->build();

// Override with in-memory storage and custom TTL
$server = Server::builder()
    ->setSession(new InMemorySessionStore(3600))
    ->build();

// Override with PSR-16 cache-based storage
// Requires psr/simple-cache and symfony/cache (or any other PSR-16 implementation)
// composer require psr/simple-cache symfony/cache
$redisAdapter = new RedisAdapter(
    RedisAdapter::createConnection('redis://localhost:6379'),
    'mcp_sessions'
);

$server = Server::builder()
    ->setSession(new Psr16StoreSession(
        cache: new Psr16Cache($redisAdapter),
        prefix: 'mcp-',
        ttl: 3600
    ))
    ->build();

Discovery Caching

Use any PSR-16 cache implementation to cache discovery results and avoid running discovery on every server start:

use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Psr16Cache;

$cache = new Psr16Cache(new FilesystemAdapter('mcp-discovery'));

$server = Server::builder()
    ->setDiscovery(
        basePath: __DIR__,
        scanDirs: ['.', 'src'],      // Default: ['.', 'src']
        excludeDirs: ['vendor'],     // Default: ['vendor', 'node_modules']
        cache: $cache
    )
    ->build();

Documentation

Core Concepts:

Learning:

  • Examples - Comprehensive example walkthroughs

External Resources:

PHP Libraries Using the MCP SDK

Contributing

We are passionate about supporting contributors of all levels of experience and would love to see you get involved in the project. See the contributing guide to get started before you report issues and send pull requests.

Credits

The starting point for this SDK was the PHP-MCP project, initiated by Kyrian Obikwelu, and the Symfony AI initiative. We are grateful for the work done by both projects and their contributors, which created a solid foundation for this SDK.

License

This project is licensed under the Apache License, Version 2.0 for new contributions, with existing code under the MIT License - see the LICENSE file for details.