Files
myep/src/Chatbot/Mcp/Tool/SearchContentTool.php
T

48 lines
1.9 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Chatbot\Mcp\Tool;
use App\Chatbot\Mcp\Sites;
use App\Chatbot\Mcp\ToolCallRunner;
use App\Chatbot\Search\ContentSearch;
use Mcp\Capability\Attribute\McpTool;
use Mcp\Capability\Attribute\Schema;
use Mcp\Exception\ToolCallException;
use Mcp\Schema\Result\CallToolResult;
use Mcp\Schema\ToolAnnotations;
#[McpTool(
name: 'search_content',
description: "Search the websites' editorial content: destinations, hotels, travel information, FAQs, terms, blog articles, general company information. Use for questions that are not about specific dates or prices. Returns excerpts; use get_document for the full text of a hit.",
annotations: new ToolAnnotations(readOnlyHint: true, openWorldHint: false),
)]
final class SearchContentTool
{
public function __construct(
private readonly ContentSearch $search,
private readonly ToolCallRunner $runner,
) {
}
public function __invoke(
#[Schema(description: 'What to look for, in German keywords works best, e.g. "Gepäck Snowboard Bus".', minLength: 1)]
string $query,
#[Schema(description: 'Restrict to one kind of content. destination = region, country or town.', enum: ['page', 'product', 'hotel', 'destination', 'concept', 'news'])]
?string $type = null,
#[Schema(description: Sites::DESCRIPTION, enum: Sites::IDENTIFIERS)]
?string $site = null,
#[Schema(description: 'Number of hits, default 5, at most 8.', minimum: 1, maximum: 8)]
?int $limit = null,
): CallToolResult {
return $this->runner->run('search_content', get_defined_vars(), function () use ($query, $type, $site, $limit): array {
if ('' === trim($query)) {
throw new ToolCallException('query must not be empty.');
}
return ['results' => $this->search->search($query, $type, $site, max(1, min(8, $limit ?? 5)))];
});
}
}