diff --git a/.docs/README.md b/.docs/README.md deleted file mode 100644 index e304553..0000000 --- a/.docs/README.md +++ /dev/null @@ -1,717 +0,0 @@ -# Contributte MCP - -Integration of [Model Context Protocol (MCP)](https://modelcontextprotocol.io) for Nette Framework. - -## Content - -- [Installation](#installation) -- [Configuration](#configuration) - - [Minimal configuration](#minimal-configuration) - - [Advanced configuration](#advanced-configuration) - - [Server configuration](#server-configuration) - - [Discovery](#discovery) - - [Session management](#session-management) - - [Container integration](#container-integration) - - [Transport factories](#transport-factories) - - [Custom transport factories](#custom-transport-factories) -- [Tools, Resources, and Prompts](#tools-resources-and-prompts) -- [Usage](#usage) - - [Basic usage](#basic-usage) -- [Debugging](#debugging) -- [Examples](#examples) - -## Installation - -Install package using composer. - -```bash -composer require contributte/mcp -``` - -Register prepared [compiler extension](https://doc.nette.org/en/dependency-injection/nette-container) in your `config.neon` file. - -```neon -extensions: - mcp: Contributte\Mcp\DI\McpExtension -``` - -## Configuration - -### Minimal configuration - -The simplest configuration requires only a server name: - -```neon -mcp: - servers: - default: - name: My MCP Server - version: 1.0.0 -``` - -### Advanced configuration - -Here is the list of all available configuration options: - -```neon -mcp: - servers: - : - # Server information - name: # Server name (default: 'MCP') - version: # Server version (default: '1.0.0') - - # Discovery configuration - discovery: - enabled: # Enable auto-discovery (default: true) - basePath: # Base path for discovery (default: %appDir%) - scanDirs: > # Directories to scan relative to basePath (default: ['.']) - excludeDirs: > # Directories to exclude (default: []) - cache: # PSR-16 cache service for discovery results - - # Session configuration - session: - type: <'file'|'inmemory'|'psr16'> # Session type (default: 'file' if %tempDir% exists, otherwise 'inmemory') - path: # Path for file sessions - ttl: # Time to live in seconds (default: 3600) - prefix: # Session key prefix (default: 'mcp-') - cache: # PSR-16 cache service for sessions - - # Container integration - container: # PSR-11 container implementation (default: NetteContainer adapter) -``` - -### Server configuration - -Each server configuration defines an MCP server instance. You can define multiple servers with different names: - -```neon -mcp: - servers: - default: - name: Main MCP Server - version: 1.0.0 - - secondary: - name: Secondary MCP Server - version: 2.0.0 -``` - -Use `McpManager` to get server factories: - -```php -use Contributte\Mcp\McpManager; - -class MyService -{ - public function __construct( - private McpManager $mcpManager - ) { - } - - public function doMagic(): void - { - $server = $this->mcpManager - ->getServerFactory('secondary') - ->create(); - - // Do something with server - } -} -``` - -### Discovery - -Discovery is **enabled by default** and automatically scans your application for MCP tools, resources, and prompts using PHP attributes. - -```neon -mcp: - servers: - default: - name: My MCP Server - version: 1.0.0 - discovery: - enabled: true # Default: true - basePath: %appDir% # Default: %appDir% - scanDirs: - - src/Mcp # Directories relative to basePath - excludeDirs: - - vendor - - tests - cache: @cacheService # Optional: PSR-16 cache for discovery results -``` - -The discovery mechanism scans PHP files in the specified directories and automatically registers classes with MCP attributes (`#[McpTool]`, `#[McpResource]`, `#[McpPrompt]`, `#[McpResourceTemplate]`). - -> [!TIP] -> Use a PSR-16 cache service to improve performance in production environments, as discovery scanning can be expensive. - -### Session management - -MCP servers can maintain session state. Three session types are supported: - -**File-based sessions** (default): - -```neon -mcp: - servers: - default: - session: - type: file - path: %tempDir%/mcp-sessions - ttl: 3600 -``` - -**In-memory sessions**: - -```neon -mcp: - servers: - default: - session: - type: inmemory - ttl: 3600 -``` - -**PSR-16 cache sessions**: - -```neon -mcp: - servers: - default: - session: - type: psr16 - cache: @psr16CacheService - ttl: 3600 - prefix: mcp- -``` - -> [!NOTE] -> The `prefix` option only applies to PSR-16 cache sessions. It is ignored for file-based and in-memory sessions. - -### Container integration - -The extension automatically provides a `NetteContainer` adapter out-of-the-box, which enables dependency injection in MCP tools using the Nette DI container. No configuration is required. - -If you need to use a custom PSR-11 container implementation instead, you can override it: - -```neon -mcp: - servers: - default: - container: @myContainerService -``` - -### Transport factories - -The extension registers two transport factories by default: - -1. **`stdio`** - STDIN/STDOUT transport for command-line usage -2. **`streamable`** - HTTP streamable transport for web requests - -```php -// Get stdio transport factory -$stdioFactory = $mcpManager->getTransportFactory('stdio'); - -// Get streamable transport factory -$streamableFactory = $mcpManager->getTransportFactory('streamable'); -``` - -### Custom transport factories - -You can create custom transport factories by implementing `TransportFactoryInterface`: - -```php -getTransportFactory('custom'); -``` - -## Tools, Resources, and Prompts - -MCP capabilities (tools, resources, prompts) are **automatically discovered** using PHP attributes. There is no manual configuration needed - just create classes with the appropriate attributes and they will be registered automatically. - -### Tools - -Tools are methods that can be called by MCP clients. Use the `#[McpTool]` attribute: - -```php - 22, 'condition' => 'sunny']; - } -} -``` - -### Resources - -Resources provide data that MCP clients can read. Use the `#[McpResource]` attribute: - -```php - '1.0.0', 'env' => 'production']); - } - - #[McpResource(uri: 'file://readme', name: 'Readme', description: 'Project readme file', mimeType: 'text/markdown')] - public function getReadme(): string - { - return file_get_contents(__DIR__ . '/../../README.md'); - } -} -``` - -### Resource Templates - -Resource templates define URI patterns with placeholders. Use the `#[McpResourceTemplate]` attribute: - -```php -userRepository->find($id); - return json_encode($user); - } -} -``` - -### Prompts - -Prompts are predefined templates that MCP clients can use. Use the `#[McpPrompt]` attribute: - -```php -userRepository->findByEmail($email); - return $user ? $user->toArray() : []; - } -} -``` - -## Usage - -### Basic usage - -After configuration, you can use the MCP server in your application: - -#### Using in Nette Presenter - -```php -getParameter('server'); - $serverName = is_string($serverName) ? $serverName : 'default'; - - // Convert Nette request to PSR-7 request - $serverRequest = GuzzleBridge::fromNette($this->httpRequest); - - // Create server and transport - $server = $this->mcpManager->getServerFactory($serverName)->create(); - $transport = $this->mcpManager->getTransportFactory('streamable')->create($serverRequest); - - // Run server - $psr7Response = $server->run($transport); - assert($psr7Response instanceof ResponseInterface); - - return GuzzleBridge::toNette($psr7Response); - } - -} -``` - -#### Using in PSR-7 Controller - -```php -mcpManager->getServerFactory('default')->create(); - $transport = $this->mcpManager->getTransportFactory('streamable')->create($serverRequest); - - $response = $server->run($transport); - - return $response; - } -} -``` - -## Debugging - -When Tracy debugger is enabled, a debug panel is automatically registered showing all registered tools, resources, resource templates, and prompts along with their handlers. - -To inspect the MCP server configuration without processing actual MCP requests, add the `?debug=1` query parameter to your MCP endpoint URL: - -``` -https://your-app.com/mcp?debug=1 -``` - -This will return a simple text response and allow you to inspect the Tracy debug bar to see: -- Number of registered tools, resources, templates, and prompts -- Handler class and method for each registered item (e.g., `App\Mcp\CalculatorTool::add()`) -- Tool descriptions and input schemas -- Resource URIs and MIME types -- Prompt arguments - -![](./assets/panel.png) - -## Examples - -### Example 1: Basic MCP Server - -```neon -# config.neon -extensions: - mcp: Contributte\Mcp\DI\McpExtension - -mcp: - servers: - default: - name: My Application MCP Server - version: 1.0.0 - discovery: - scanDirs: - - src/Mcp -``` - -```php -getParameter('server'); - $serverName = is_string($serverName) ? $serverName : 'default'; - - // Convert Nette request to PSR-7 request - $serverRequest = GuzzleBridge::fromNette($this->httpRequest); - - // Create server and transport - $server = $this->mcpManager->getServerFactory($serverName)->create(); - $transport = $this->mcpManager->getTransportFactory('streamable')->create($serverRequest); - - // Run server - $psr7Response = $server->run($transport); - assert($psr7Response instanceof ResponseInterface); - - return GuzzleBridge::toNette($psr7Response); - } - -} -``` - -### Example 4: Using in PSR-7 Controller - -```php -mcpManager->getServerFactory('default')->create(); - $transport = $this->mcpManager->getTransportFactory('streamable')->create($request); - - // Run server and return PSR-7 response - return $server->run($transport); - } -} -``` - -### Example 5: Pure PHP CLI Script - -Create a standalone `mcp.php` script: - -```php -#!/usr/bin/env php -getByType(McpManager::class); - -// Create server -$server = $mcpManager->getServerFactory('default')->create(); - -// Create stdio transport -$transport = $mcpManager->getTransportFactory('stdio')->create(); - -// Run server -$server->run($transport); -``` - -Make it executable: - -```bash -chmod +x mcp.php -``` - -Run it: - -```bash -./mcp.php -``` - -### Example 6: Symfony Console Command - -The package provides a built-in Symfony console command `Contributte\Mcp\Console\McpCommand` for running MCP servers. - -Register it in your console configuration (if using [contributte/console](https://github.com/contributte/console)): - -```neon -services: - - Contributte\Mcp\Console\McpCommand -``` - -Run the command: - -```bash -php bin/console mcp:server --server=default -``` - -Or specify a different server: - -```bash -php bin/console mcp:server --server=secondary -``` - -> [!TIP] -> For more information about MCP, visit the [official MCP documentation](https://modelcontextprotocol.io). -> -> For information about the underlying PHP SDK, see the [MCP PHP SDK documentation](https://github.com/modelcontextprotocol/php-sdk). diff --git a/README.md b/README.md index d75e022..87b5721 100644 --- a/README.md +++ b/README.md @@ -17,23 +17,630 @@ Website 🚀 contributte.org | Contact 👨🏻‍💻 f3l1x.io | Twitter 🐦 @contributte

-## Usage +Integration of [Model Context Protocol (MCP)](https://modelcontextprotocol.io) for Nette Framework. + +## Versions + +| State | Version | Branch | Nette | PHP | +|-------------|---------|----------|--------|---------| +| dev | `^0.1` | `master` | `3.2+` | `>=8.4` | -To install latest version of `contributte/mcp` use [Composer](https://getcomposer.org). +## Installation + +Install package using composer. ```bash composer require contributte/mcp ``` -## Documentation +Register prepared [compiler extension](https://doc.nette.org/en/dependency-injection/nette-container) in your `config.neon` file. -For details on how to use this package, check out our [documentation](.docs). +```neon +extensions: + mcp: Contributte\Mcp\DI\McpExtension +``` -## Versions +## Configuration -| State | Version | Branch | Nette | PHP | -|-------------|---------|----------|--------|---------| -| dev | `^0.1` | `master` | `3.2+` | `>=8.4` | +### Minimal configuration + +The simplest configuration requires only a server name: + +```neon +mcp: + servers: + default: + name: My MCP Server + version: 1.0.0 +``` + +### Advanced configuration + +Here is the list of all available configuration options: + +```neon +mcp: + servers: + : + # Server information + name: # Server name (default: 'MCP') + version: # Server version (default: '1.0.0') + + # Discovery configuration + discovery: + enabled: # Enable auto-discovery (default: true) + basePath: # Base path for discovery (default: %appDir%) + scanDirs: > # Directories to scan relative to basePath (default: ['.']) + excludeDirs: > # Directories to exclude (default: []) + cache: # PSR-16 cache service for discovery results + + # Session configuration + session: + type: <'file'|'inmemory'|'psr16'> # Session type (default: 'file' if %tempDir% exists, otherwise 'inmemory') + path: # Path for file sessions + ttl: # Time to live in seconds (default: 3600) + prefix: # Session key prefix (default: 'mcp-') + cache: # PSR-16 cache service for sessions + + # Container integration + container: # PSR-11 container implementation (default: NetteContainer adapter) +``` + +### Server configuration + +Each server configuration defines an MCP server instance. You can define multiple servers with different names: + +```neon +mcp: + servers: + default: + name: Main MCP Server + version: 1.0.0 + + secondary: + name: Secondary MCP Server + version: 2.0.0 +``` + +Use `McpManager` to get server factories: + +```php +use Contributte\Mcp\McpManager; + +class MyService +{ + public function __construct( + private McpManager $mcpManager + ) { + } + + public function doMagic(): void + { + $server = $this->mcpManager + ->getServerFactory('secondary') + ->create(); + + // Do something with server + } +} +``` + +### Discovery + +Discovery is **enabled by default** and automatically scans your application for MCP tools, resources, and prompts using PHP attributes. + +```neon +mcp: + servers: + default: + name: My MCP Server + version: 1.0.0 + discovery: + enabled: true # Default: true + basePath: %appDir% # Default: %appDir% + scanDirs: + - src/Mcp # Directories relative to basePath + excludeDirs: + - vendor + - tests + cache: @cacheService # Optional: PSR-16 cache for discovery results +``` + +The discovery mechanism scans PHP files in the specified directories and automatically registers classes with MCP attributes (`#[McpTool]`, `#[McpResource]`, `#[McpPrompt]`, `#[McpResourceTemplate]`). + +> [!TIP] +> Use a PSR-16 cache service to improve performance in production environments, as discovery scanning can be expensive. + +### Session management + +MCP servers can maintain session state. Three session types are supported: + +**File-based sessions** (default): + +```neon +mcp: + servers: + default: + session: + type: file + path: %tempDir%/mcp-sessions + ttl: 3600 +``` + +**In-memory sessions**: + +```neon +mcp: + servers: + default: + session: + type: inmemory + ttl: 3600 +``` + +**PSR-16 cache sessions**: + +```neon +mcp: + servers: + default: + session: + type: psr16 + cache: @psr16CacheService + ttl: 3600 + prefix: mcp- +``` + +> [!NOTE] +> The `prefix` option only applies to PSR-16 cache sessions. It is ignored for file-based and in-memory sessions. + +### Container integration + +The extension automatically provides a `NetteContainer` adapter out-of-the-box, which enables dependency injection in MCP tools using the Nette DI container. No configuration is required. + +If you need to use a custom PSR-11 container implementation instead, you can override it: + +```neon +mcp: + servers: + default: + container: @myContainerService +``` + +### Transport factories + +The extension registers two transport factories by default: + +1. **`stdio`** - STDIN/STDOUT transport for command-line usage +2. **`streamable`** - HTTP streamable transport for web requests + +```php +// Get stdio transport factory +$stdioFactory = $mcpManager->getTransportFactory('stdio'); + +// Get streamable transport factory +$streamableFactory = $mcpManager->getTransportFactory('streamable'); +``` + +### Custom transport factories + +You can create custom transport factories by implementing `TransportFactoryInterface`: + +```php +getTransportFactory('custom')`. + +## Tools, Resources, and Prompts + +MCP capabilities (tools, resources, prompts) are **automatically discovered** using PHP attributes. There is no manual configuration needed - just create classes with the appropriate attributes and they will be registered automatically. + +### Tools + +Tools are methods that can be called by MCP clients. Use the `#[McpTool]` attribute: + +```php + 22, 'condition' => 'sunny']; + } +} +``` + +### Resources + +Resources provide data that MCP clients can read. Use the `#[McpResource]` attribute: + +```php + '1.0.0', 'env' => 'production']); + } + + #[McpResource(uri: 'file://readme', name: 'Readme', description: 'Project readme file', mimeType: 'text/markdown')] + public function getReadme(): string + { + return file_get_contents(__DIR__ . '/../../README.md'); + } +} +``` + +### Resource Templates + +Resource templates define URI patterns with placeholders. Use the `#[McpResourceTemplate]` attribute: + +```php +userRepository->find($id); + return json_encode($user); + } +} +``` + +### Prompts + +Prompts are predefined templates that MCP clients can use. Use the `#[McpPrompt]` attribute: + +```php +userRepository->findByEmail($email); + return $user ? $user->toArray() : []; + } +} +``` + +## Usage + +### Basic usage + +After configuration, you can use the MCP server in your application: + +#### Using in Nette Presenter + +```php +getParameter('server'); + $serverName = is_string($serverName) ? $serverName : 'default'; + + // Convert Nette request to PSR-7 request + $serverRequest = GuzzleBridge::fromNette($this->httpRequest); + + // Create server and transport + $server = $this->mcpManager->getServerFactory($serverName)->create(); + $transport = $this->mcpManager->getTransportFactory('streamable')->create($serverRequest); + + // Run server + $psr7Response = $server->run($transport); + assert($psr7Response instanceof ResponseInterface); + + return GuzzleBridge::toNette($psr7Response); + } + +} +``` + +#### Using in PSR-7 Controller + +```php +mcpManager->getServerFactory('default')->create(); + $transport = $this->mcpManager->getTransportFactory('streamable')->create($serverRequest); + + $response = $server->run($transport); + + return $response; + } +} +``` + +## Debugging + +When Tracy debugger is enabled, a debug panel is automatically registered showing all registered tools, resources, resource templates, and prompts along with their handlers. + +To inspect the MCP server configuration without processing actual MCP requests, add the `?debug=1` query parameter to your MCP endpoint URL: + +``` +https://your-app.com/mcp?debug=1 +``` + +This will return a simple text response and allow you to inspect the Tracy debug bar to see: +- Number of registered tools, resources, templates, and prompts +- Handler class and method for each registered item (e.g., `App\Mcp\CalculatorTool::add()`) +- Tool descriptions and input schemas +- Resource URIs and MIME types +- Prompt arguments + +![](.docs/assets/panel.png) + +## Examples + +### Example 1: Basic MCP Server + +```neon +# config.neon +extensions: + mcp: Contributte\Mcp\DI\McpExtension + +mcp: + servers: + default: + name: My Application MCP Server + version: 1.0.0 + discovery: + scanDirs: + - src/Mcp +``` + +```php +getByType(McpManager::class); + +// Create server +$server = $mcpManager->getServerFactory('default')->create(); + +// Create stdio transport +$transport = $mcpManager->getTransportFactory('stdio')->create(); + +// Run server +$server->run($transport); +``` + +Make it executable: + +```bash +chmod +x mcp.php +``` + +Run it: + +```bash +./mcp.php +``` + +### Example 4: Symfony Console Command + +The package provides a built-in Symfony console command `Contributte\Mcp\Console\McpCommand` for running MCP servers. + +Register it in your console configuration (if using [contributte/console](https://github.com/contributte/console)): + +```neon +services: + - Contributte\Mcp\Console\McpCommand +``` + +Run the command: + +```bash +php bin/console mcp:server --server=default +``` + +Or specify a different server: + +```bash +php bin/console mcp:server --server=secondary +``` + +> [!TIP] +> For more information about MCP, visit the [official MCP documentation](https://modelcontextprotocol.io). +> +> For information about the underlying PHP SDK, see the [MCP PHP SDK documentation](https://github.com/modelcontextprotocol/php-sdk). ## Development @@ -45,5 +652,5 @@ See [how to contribute](https://contributte.org) to this package. This package i ----- -Consider to [support](https://contributte.com/partners) **contributte** development team. +Consider to [support](https://contributte.org/partners) **contributte** development team. Also thank you for using this package.