[Server] Allow overriding the default file name pattern for Discovery (#292)
* Add optional namePatterns capability to discovery so that the default scan for `*.php` files can be overridden. * add default to namePatterns docs * add an error check if we manage to pass in an empty list of patterns * add unit tests (and a static entry to classmap for composer.json so it autoloads from a non .php file for the test) * run php-cs-fixer * change how default namePatterns are set and make sure all the annotations are correct * Fix bad whitespace Co-authored-by: Christopher Hertel <mail@christopher-hertel.de> * switch to a const default instead of nullable with a check in the function to convert null to a default * make sure we handle empty arrays * formatting fixes * Apply suggestion from @chr-hertel Co-authored-by: Christopher Hertel <mail@christopher-hertel.de> * Add changelog entry --------- Co-authored-by: Christopher Hertel <mail@christopher-hertel.de>
This commit is contained in:
parent
fb2c8c2ee4
commit
86bd845924
1 changed files with 109 additions and 37 deletions
|
|
@ -99,8 +99,9 @@ $server = Server::builder()
|
|||
->setDiscovery(
|
||||
basePath: __DIR__,
|
||||
scanDirs: ['.', 'src', 'lib'], // Where to look for MCP attributes
|
||||
excludeDirs: ['vendor', 'tests'], // Where NOT to look
|
||||
cache: $cacheInstance // Optional: cache discovered elements
|
||||
excludeDirs: ['vendor', 'tests'], // Where NOT to look
|
||||
cache: $cacheInstance, // Optional: cache discovered elements
|
||||
namePatterns: ['*.php', '*.inc'], // Optional: list of filename patterns to match
|
||||
);
|
||||
```
|
||||
|
||||
|
|
@ -109,6 +110,7 @@ $server = Server::builder()
|
|||
- `$scanDirs` (array): Directories to recursively scan for `#[McpTool]`, `#[McpResource]`, etc. All subdirectories are included. (default: `['.', 'src']`)
|
||||
- `$excludeDirs` (array): Directory names to exclude **within** the scanned directories during recursive scanning
|
||||
- `$cache` (CacheInterface|null): Optional PSR-16 cache to store discovered elements for performance
|
||||
- `$namePatterns` (array): Optional list of patterns (regexp, glob, or string) for file names (default: `['*.php']`)
|
||||
|
||||
**Basic Discovery (scans current directory and `src/`):**
|
||||
```php
|
||||
|
|
@ -137,7 +139,7 @@ $server = Server::builder()
|
|||
|
||||
**How `excludeDirs` works:**
|
||||
- If scanning `src/` and there's `src/vendor/`, it will be excluded
|
||||
- If scanning `lib/` and there's `lib/tests/`, it will be excluded
|
||||
- If scanning `lib/` and there's `lib/tests/`, it will be excluded
|
||||
- But if `vendor/` and `tests/` are at the same level as `src/`, they're not scanned anyway (not in `scanDirs`)
|
||||
|
||||
> **Performance**: Always use a cache in production. The first run scans and caches all discovered MCP elements, making
|
||||
|
|
@ -255,19 +257,19 @@ $server = Server::builder()
|
|||
name: 'add_numbers',
|
||||
description: 'Adds two numbers together'
|
||||
)
|
||||
|
||||
|
||||
// Using class method pair
|
||||
->addTool(
|
||||
handler: [Calculator::class, 'multiply'],
|
||||
name: 'multiply_numbers'
|
||||
// name and description are optional - derived from method name and docblock
|
||||
)
|
||||
|
||||
|
||||
// Using instance method
|
||||
->addTool(
|
||||
handler: [$calculatorInstance, 'divide']
|
||||
)
|
||||
|
||||
|
||||
// Using invokable class
|
||||
->addTool(
|
||||
handler: InvokableCalculator::class
|
||||
|
|
@ -421,17 +423,17 @@ $server = Server::builder()
|
|||
individual JSON-RPC messages. They do not receive the builder's registry, container, or discovery output unless you pass
|
||||
those dependencies in yourself.
|
||||
|
||||
> **Warning**: Custom message handlers bypass discovery, manual capability registration, and container lookups (unless
|
||||
> **Warning**: Custom message handlers bypass discovery, manual capability registration, and container lookups (unless
|
||||
> you explicitly pass them). Tools, resources, and prompts you register elsewhere will not show up unless your handler
|
||||
> loads and executes them manually. Reach for this API only when you need that level of control and are comfortable
|
||||
> loads and executes them manually. Reach for this API only when you need that level of control and are comfortable
|
||||
> taking on the additional plumbing.
|
||||
|
||||
### Request Handlers
|
||||
|
||||
Handle JSON-RPC requests (messages with an `id` that expect a response). Request handlers **must** return either a
|
||||
Handle JSON-RPC requests (messages with an `id` that expect a response). Request handlers **must** return either a
|
||||
`Response` or an `Error` object.
|
||||
|
||||
Attach request handlers with `addRequestHandler()` (single) or `addRequestHandlers()` (multiple). You can call these
|
||||
Attach request handlers with `addRequestHandler()` (single) or `addRequestHandlers()` (multiple). You can call these
|
||||
methods as many times as needed; each call prepends the handlers so they execute before the defaults:
|
||||
|
||||
```php
|
||||
|
|
@ -508,7 +510,7 @@ interface NotificationHandlerInterface
|
|||
|
||||
### Example
|
||||
|
||||
Check out `examples/custom-method-handlers/server.php` for a complete example showing how to implement
|
||||
Check out `examples/custom-method-handlers/server.php` for a complete example showing how to implement
|
||||
custom `tools/list` and `tools/call` request handlers independently of the registry.
|
||||
|
||||
## Complete Example
|
||||
|
|
@ -540,25 +542,25 @@ $container->set(DatabaseService::class, new DatabaseService($container->get(\PDO
|
|||
$server = Server::builder()
|
||||
// Server identity
|
||||
->setServerInfo('Advanced Calculator', '2.1.0')
|
||||
|
||||
|
||||
// Performance and behavior
|
||||
->setPaginationLimit(100)
|
||||
->setInstructions('Use calculate tool for math operations. Check config resource for current settings.')
|
||||
|
||||
|
||||
// Discovery with caching
|
||||
->setDiscovery(__DIR__, ['src'], ['vendor', 'tests'], $cache)
|
||||
|
||||
|
||||
// Session management
|
||||
->setSession($sessionStore)
|
||||
|
||||
|
||||
// Services
|
||||
->setLogger($logger)
|
||||
->setContainer($container)
|
||||
|
||||
|
||||
// Manual capability registration
|
||||
->addTool([Calculator::class, 'advancedCalculation'], 'advanced_calc')
|
||||
->addResource([Config::class, 'getSettings'], 'config://app/settings', 'app_settings')
|
||||
|
||||
|
||||
// Build the server
|
||||
->build();
|
||||
```
|
||||
|
|
|
|||
Loading…
Reference in a new issue