Skip to content

Commit 2ff0f7d

Browse files
Merge pull request #2 from php-mcp/feature/enhanced-element-registration
feat: Add Manual Registration, Invokable Discovery, and Refactor DI
2 parents 1fa0246 + 05b9258 commit 2ff0f7d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1899
-1144
lines changed

.github/workflows/changelog.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: "Update Changelog"
2+
3+
on:
4+
release:
5+
types: [released]
6+
7+
permissions:
8+
contents: write
9+
10+
jobs:
11+
update:
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
with:
18+
ref: main
19+
20+
- name: Update Changelog
21+
uses: stefanzweifel/changelog-updater-action@v1
22+
with:
23+
latest-version: ${{ github.event.release.name }}
24+
release-notes: ${{ github.event.release.body }}
25+
26+
- name: Commit updated CHANGELOG
27+
uses: stefanzweifel/git-auto-commit-action@v5
28+
with:
29+
branch: main
30+
commit_message: Update CHANGELOG
31+
file_pattern: CHANGELOG.md

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,7 @@ workbench
6161
playground
6262

6363
# Log files
64-
*.log
64+
*.log
65+
66+
# Cache files
67+
cache

CHANGELOG.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Changelog
2+
3+
All notable changes to `php-mcp/server` will be documented in this file.
4+
5+
## Release v1.0.0 - Initial Release
6+
7+
🚀 **Initial release of PHP MCP SERVER!**
8+
9+
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.
10+
11+
### ✨ Key Features:
12+
13+
* **Attribute-Based Definitions:** Easily define MCP Tools (`#[McpTool]`), Resources (`#[McpResource]`, `#[McpResourceTemplate]`), and Prompts (`#[McpPrompt]`) using PHP 8 attributes directly on your methods.
14+
* **Automatic Metadata Inference:** Leverages method signatures (parameters, type hints) and DocBlocks (`@param`, `@return`, summaries) to automatically generate MCP schemas and descriptions, minimizing boilerplate.
15+
* **PSR Compliance:** Integrates seamlessly with standard PHP interfaces:
16+
* `PSR-3` (LoggerInterface) for flexible logging.
17+
* `PSR-11` (ContainerInterface) for dependency injection and class resolution.
18+
* `PSR-16` (SimpleCacheInterface) for caching discovered elements and transport state.
19+
* **Automatic Discovery:** Scans configured directories to find and register your annotated MCP elements.
20+
* **Flexible Configuration:** Uses a configuration repository (`ConfigurationRepositoryInterface`) for fine-grained control over server behaviour, capabilities, and caching.
21+
* **Multiple Transports:**
22+
* Built-in support for the `stdio` transport, ideal for command-line driven clients.
23+
* Includes `HttpTransportHandler` components for building standard `http` (HTTP+SSE) transports (requires integration into an HTTP server).
24+
* Provides `ReactPhpHttpTransportHandler` for seamless integration with asynchronous ReactPHP applications.
25+
* **Protocol Support:** Implements the `2024-11-05` version of the Model Context Protocol.
26+
* **Framework Agnostic:** Designed to work in vanilla PHP projects or integrated into any framework.
27+
28+
### 🚀 Getting Started
29+
30+
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.
31+
32+
### ⚠️ Important Notes
33+
34+
* 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).
35+
36+
### Future Plans
37+
38+
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.

README.md

Lines changed: 192 additions & 76 deletions
Large diffs are not rendered by default.

samples/php_http/server.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919

2020
// --- MCP Server Setup ---
2121
$logger = new StreamLogger(__DIR__.'/vanilla_server.log', 'debug');
22-
$server = Server::make()->withLogger($logger)->withBasePath(__DIR__)->discover();
23-
$processor = $server->getProcessor();
24-
$state = $server->getStateManager();
25-
$httpHandler = new HttpTransportHandler($processor, $state, $logger);
22+
$server = Server::make()
23+
->withLogger($logger)
24+
->withBasePath(__DIR__)
25+
->discover();
26+
27+
$httpHandler = new HttpTransportHandler($server);
2628

2729
// --- Basic Routing & Client ID ---
2830
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';

samples/php_stdio/server.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PhpMcp\Server\Defaults\StreamLogger;
66
use PhpMcp\Server\Server;
7+
use Test\SampleMcpElements;
78

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

2627
$server = Server::make()
27-
->withLogger($logger)
2828
->withBasePath(__DIR__)
29+
->withLogger($logger)
30+
->withTool([SampleMcpElements::class, 'simpleTool'], 'greeter')
31+
->withResource([SampleMcpElements::class, 'getUserData'], 'user://data')
2932
->discover();
3033

3134
$exitCode = $server->run('stdio');

samples/reactphp_http/server.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use PhpMcp\Server\Transports\ReactPhpHttpTransportHandler;
88
use Psr\Http\Message\ResponseInterface;
99
use Psr\Http\Message\ServerRequestInterface;
10-
use React\EventLoop\Loop;
1110
use React\Http\HttpServer;
1211
use React\Http\Message\Response;
1312
use React\Promise\Promise;
@@ -34,10 +33,7 @@
3433
->withBasePath(__DIR__)
3534
->discover();
3635

37-
$processor = $server->getProcessor();
38-
$state = $server->getStateManager();
39-
40-
$transportHandler = new ReactPhpHttpTransportHandler($processor, $state, $logger, Loop::get());
36+
$transportHandler = new ReactPhpHttpTransportHandler($server);
4137

4238
// --- ReactPHP HTTP Server Setup ---
4339
$postEndpoint = '/mcp/message';

src/Attributes/McpPrompt.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Marks a PHP method as an MCP Prompt generator.
99
* The method should return the prompt messages, potentially using arguments for templating.
1010
*/
11-
#[Attribute(Attribute::TARGET_METHOD)]
11+
#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)]
1212
final class McpPrompt
1313
{
1414
/**
@@ -18,6 +18,5 @@ final class McpPrompt
1818
public function __construct(
1919
public ?string $name = null,
2020
public ?string $description = null,
21-
) {
22-
}
21+
) {}
2322
}

src/Attributes/McpResource.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Marks a PHP class as representing or handling a specific MCP Resource instance.
99
* Used primarily for the 'resources/list' discovery.
1010
*/
11-
#[Attribute(Attribute::TARGET_METHOD)]
11+
#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)]
1212
final class McpResource
1313
{
1414
/**
@@ -17,15 +17,14 @@ final class McpResource
1717
* @param ?string $description An optional description of the resource. Defaults to class DocBlock summary.
1818
* @param ?string $mimeType The MIME type, if known and constant for this resource.
1919
* @param ?int $size The size in bytes, if known and constant.
20-
* @param ?array<string, mixed> $annotations Optional annotations following the MCP spec (e.g., ['audience' => ['user'], 'priority' => 0.5]).
20+
* @param array<string, mixed> $annotations Optional annotations following the MCP spec (e.g., ['audience' => ['user'], 'priority' => 0.5]).
2121
*/
2222
public function __construct(
2323
public string $uri,
2424
public ?string $name = null,
2525
public ?string $description = null,
2626
public ?string $mimeType = null,
2727
public ?int $size = null,
28-
public ?array $annotations = null,
29-
) {
30-
}
28+
public array $annotations = [],
29+
) {}
3130
}

src/Attributes/McpResourceTemplate.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,21 @@
88
* Marks a PHP class definition as representing an MCP Resource Template.
99
* This is informational, used for 'resources/templates/list'.
1010
*/
11-
#[Attribute(Attribute::TARGET_METHOD)]
11+
#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)]
1212
final class McpResourceTemplate
1313
{
1414
/**
1515
* @param string $uriTemplate The URI template string (RFC 6570).
1616
* @param ?string $name A human-readable name for the template type. If null, a default might be generated from the method name.
1717
* @param ?string $description Optional description. Defaults to class DocBlock summary.
1818
* @param ?string $mimeType Optional default MIME type for matching resources.
19-
* @param ?array<string, mixed> $annotations Optional annotations following the MCP spec.
19+
* @param array<string, mixed> $annotations Optional annotations following the MCP spec.
2020
*/
2121
public function __construct(
2222
public string $uriTemplate,
2323
public ?string $name = null,
2424
public ?string $description = null,
2525
public ?string $mimeType = null,
26-
public ?array $annotations = null,
27-
) {
28-
}
26+
public array $annotations = [],
27+
) {}
2928
}

0 commit comments

Comments
 (0)