Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: "Update Changelog"

on:
release:
types: [released]

permissions:
contents: write

jobs:
update:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: main

- name: Update Changelog
uses: stefanzweifel/changelog-updater-action@v1
with:
latest-version: ${{ github.event.release.name }}
release-notes: ${{ github.event.release.body }}

- name: Commit updated CHANGELOG
uses: stefanzweifel/git-auto-commit-action@v5
with:
branch: main
commit_message: Update CHANGELOG
file_pattern: CHANGELOG.md
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,7 @@ workbench
playground

# Log files
*.log
*.log

# Cache files
cache
38 changes: 38 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Changelog

All notable changes to `php-mcp/server` will be documented in this file.

## Release v1.0.0 - Initial Release

🚀 **Initial release of PHP MCP SERVER!**

This release introduces the core implementation of the Model Context Protocol (MCP) server for PHP applications. The goal is to provide a robust, flexible, and developer-friendly way to expose parts of your PHP application as MCP Tools, Resources, and Prompts, enabling standardized communication with AI assistants like Claude, Cursor, and others.

### ✨ Key Features:

* **Attribute-Based Definitions:** Easily define MCP Tools (`#[McpTool]`), Resources (`#[McpResource]`, `#[McpResourceTemplate]`), and Prompts (`#[McpPrompt]`) using PHP 8 attributes directly on your methods.
* **Automatic Metadata Inference:** Leverages method signatures (parameters, type hints) and DocBlocks (`@param`, `@return`, summaries) to automatically generate MCP schemas and descriptions, minimizing boilerplate.
* **PSR Compliance:** Integrates seamlessly with standard PHP interfaces:
* `PSR-3` (LoggerInterface) for flexible logging.
* `PSR-11` (ContainerInterface) for dependency injection and class resolution.
* `PSR-16` (SimpleCacheInterface) for caching discovered elements and transport state.
* **Automatic Discovery:** Scans configured directories to find and register your annotated MCP elements.
* **Flexible Configuration:** Uses a configuration repository (`ConfigurationRepositoryInterface`) for fine-grained control over server behaviour, capabilities, and caching.
* **Multiple Transports:**
* Built-in support for the `stdio` transport, ideal for command-line driven clients.
* Includes `HttpTransportHandler` components for building standard `http` (HTTP+SSE) transports (requires integration into an HTTP server).
* Provides `ReactPhpHttpTransportHandler` for seamless integration with asynchronous ReactPHP applications.
* **Protocol Support:** Implements the `2024-11-05` version of the Model Context Protocol.
* **Framework Agnostic:** Designed to work in vanilla PHP projects or integrated into any framework.

### 🚀 Getting Started

Please refer to the [README.md](README.md) for detailed installation instructions, usage examples, and core concepts. Sample implementations for `stdio` and `reactphp` are available in the `samples/` directory.

### ⚠️ Important Notes

* When implementing the `http` transport using `HttpTransportHandler`, be aware of the critical server environment requirements detailed in the README regarding concurrent request handling for SSE. Standard synchronous PHP servers (like `php artisan serve` or basic Apache/Nginx setups) are generally **not suitable** without proper configuration for concurrency (e.g., PHP-FPM with multiple workers, Octane, Swoole, ReactPHP, RoadRunner, FrankenPHP).

### Future Plans

While this package focuses on the server implementation, future projects within the `php-mcp` organization may include client libraries and other utilities related to MCP in PHP.
268 changes: 192 additions & 76 deletions README.md

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions samples/php_http/server.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@

// --- MCP Server Setup ---
$logger = new StreamLogger(__DIR__.'/vanilla_server.log', 'debug');
$server = Server::make()->withLogger($logger)->withBasePath(__DIR__)->discover();
$processor = $server->getProcessor();
$state = $server->getStateManager();
$httpHandler = new HttpTransportHandler($processor, $state, $logger);
$server = Server::make()
->withLogger($logger)
->withBasePath(__DIR__)
->discover();

$httpHandler = new HttpTransportHandler($server);

// --- Basic Routing & Client ID ---
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
Expand Down
5 changes: 4 additions & 1 deletion samples/php_stdio/server.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use PhpMcp\Server\Defaults\StreamLogger;
use PhpMcp\Server\Server;
use Test\SampleMcpElements;

// --- Instructions ---
// 1. composer install
Expand All @@ -24,8 +25,10 @@
$logger = new StreamLogger(__DIR__.'/mcp.log', 'debug');

$server = Server::make()
->withLogger($logger)
->withBasePath(__DIR__)
->withLogger($logger)
->withTool([SampleMcpElements::class, 'simpleTool'], 'greeter')
->withResource([SampleMcpElements::class, 'getUserData'], 'user://data')
->discover();

$exitCode = $server->run('stdio');
Expand Down
6 changes: 1 addition & 5 deletions samples/reactphp_http/server.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use PhpMcp\Server\Transports\ReactPhpHttpTransportHandler;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use React\EventLoop\Loop;
use React\Http\HttpServer;
use React\Http\Message\Response;
use React\Promise\Promise;
Expand All @@ -34,10 +33,7 @@
->withBasePath(__DIR__)
->discover();

$processor = $server->getProcessor();
$state = $server->getStateManager();

$transportHandler = new ReactPhpHttpTransportHandler($processor, $state, $logger, Loop::get());
$transportHandler = new ReactPhpHttpTransportHandler($server);

// --- ReactPHP HTTP Server Setup ---
$postEndpoint = '/mcp/message';
Expand Down
5 changes: 2 additions & 3 deletions src/Attributes/McpPrompt.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* Marks a PHP method as an MCP Prompt generator.
* The method should return the prompt messages, potentially using arguments for templating.
*/
#[Attribute(Attribute::TARGET_METHOD)]
#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)]
final class McpPrompt
{
/**
Expand All @@ -18,6 +18,5 @@ final class McpPrompt
public function __construct(
public ?string $name = null,
public ?string $description = null,
) {
}
) {}
}
9 changes: 4 additions & 5 deletions src/Attributes/McpResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* Marks a PHP class as representing or handling a specific MCP Resource instance.
* Used primarily for the 'resources/list' discovery.
*/
#[Attribute(Attribute::TARGET_METHOD)]
#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)]
final class McpResource
{
/**
Expand All @@ -17,15 +17,14 @@ final class McpResource
* @param ?string $description An optional description of the resource. Defaults to class DocBlock summary.
* @param ?string $mimeType The MIME type, if known and constant for this resource.
* @param ?int $size The size in bytes, if known and constant.
* @param ?array<string, mixed> $annotations Optional annotations following the MCP spec (e.g., ['audience' => ['user'], 'priority' => 0.5]).
* @param array<string, mixed> $annotations Optional annotations following the MCP spec (e.g., ['audience' => ['user'], 'priority' => 0.5]).
*/
public function __construct(
public string $uri,
public ?string $name = null,
public ?string $description = null,
public ?string $mimeType = null,
public ?int $size = null,
public ?array $annotations = null,
) {
}
public array $annotations = [],
) {}
}
9 changes: 4 additions & 5 deletions src/Attributes/McpResourceTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,21 @@
* Marks a PHP class definition as representing an MCP Resource Template.
* This is informational, used for 'resources/templates/list'.
*/
#[Attribute(Attribute::TARGET_METHOD)]
#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)]
final class McpResourceTemplate
{
/**
* @param string $uriTemplate The URI template string (RFC 6570).
* @param ?string $name A human-readable name for the template type. If null, a default might be generated from the method name.
* @param ?string $description Optional description. Defaults to class DocBlock summary.
* @param ?string $mimeType Optional default MIME type for matching resources.
* @param ?array<string, mixed> $annotations Optional annotations following the MCP spec.
* @param array<string, mixed> $annotations Optional annotations following the MCP spec.
*/
public function __construct(
public string $uriTemplate,
public ?string $name = null,
public ?string $description = null,
public ?string $mimeType = null,
public ?array $annotations = null,
) {
}
public array $annotations = [],
) {}
}
5 changes: 2 additions & 3 deletions src/Attributes/McpTool.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use Attribute;

#[Attribute(Attribute::TARGET_METHOD)]
#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)]
class McpTool
{
/**
Expand All @@ -14,6 +14,5 @@ class McpTool
public function __construct(
public ?string $name = null,
public ?string $description = null,
) {
}
) {}
}
Loading