62 lines
2.0 KiB
PHP
62 lines
2.0 KiB
PHP
<?php
|
|
|
|
use App\Mcp\Servers\WhisperMoneyServer;
|
|
use Laravel\Mcp\Server\Tool;
|
|
|
|
/**
|
|
* The ChatGPT app directory submission declares these hints per tool, so the
|
|
* served annotations must keep matching chatgpt-app-submission.json.
|
|
*/
|
|
$readOnly = [
|
|
'search_transactions',
|
|
'spending_by_category',
|
|
'get_cashflow',
|
|
'get_net_worth',
|
|
'list_accounts',
|
|
'list_categories',
|
|
'list_labels',
|
|
'list_spaces',
|
|
];
|
|
|
|
$destructive = [
|
|
'delete_transaction',
|
|
'delete_category',
|
|
'delete_label',
|
|
'delete_automation_rule',
|
|
];
|
|
|
|
/**
|
|
* The ChatGPT submission portal caps each tool description at 200 characters,
|
|
* so a longer one cannot be entered in the form. Detail that does not fit
|
|
* belongs in the server instructions or a schema field description.
|
|
*/
|
|
it('keeps every tool description within the submission form limit', function () {
|
|
/** @var array<int, class-string<Tool>> $tools */
|
|
$tools = (new ReflectionClass(WhisperMoneyServer::class))->getDefaultProperties()['tools'];
|
|
|
|
foreach ($tools as $class) {
|
|
$tool = new $class;
|
|
|
|
expect(mb_strlen((string) $tool->description()))
|
|
->toBeLessThanOrEqual(200, "description for {$tool->name()}");
|
|
}
|
|
});
|
|
|
|
it('declares all three MCP hints on every tool', function () use ($readOnly, $destructive) {
|
|
/** @var array<int, class-string<Tool>> $tools */
|
|
$tools = (new ReflectionClass(WhisperMoneyServer::class))->getDefaultProperties()['tools'];
|
|
|
|
expect($tools)->toHaveCount(count($readOnly) + 15);
|
|
|
|
foreach ($tools as $class) {
|
|
$tool = new $class;
|
|
$annotations = $tool->annotations();
|
|
$name = $tool->name();
|
|
|
|
expect($annotations)->toHaveKeys(['readOnlyHint', 'destructiveHint', 'openWorldHint'])
|
|
->and($annotations['openWorldHint'])->toBeFalse()
|
|
->and($annotations['readOnlyHint'])->toBe(in_array($name, $readOnly, true), "readOnlyHint for {$name}")
|
|
->and($annotations['destructiveHint'])->toBe(in_array($name, $destructive, true), "destructiveHint for {$name}");
|
|
}
|
|
});
|