Tools now return CallToolResult directly instead of Content arrays, preventing the MCP SDK from auto-generating structuredContent as a JSON array (which Claude Code rejects — expects a JSON object/record). Also adds Accept header to test helpers and SSE response parsing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
57 lines
1.6 KiB
PHP
57 lines
1.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Mcp\Tool\Machine;
|
|
|
|
use App\Mcp\Tool\McpToolHelper;
|
|
use App\Repository\MachineRepository;
|
|
use Mcp\Capability\Attribute\McpTool;
|
|
use Mcp\Schema\Result\CallToolResult;
|
|
|
|
#[McpTool(
|
|
name: 'list_machines',
|
|
description: 'List machines with pagination. Filterable by name or reference.',
|
|
)]
|
|
class ListMachinesTool
|
|
{
|
|
use McpToolHelper;
|
|
|
|
public function __construct(
|
|
private readonly MachineRepository $machines,
|
|
) {}
|
|
|
|
public function __invoke(int $page = 1, int $limit = 30, string $search = ''): CallToolResult
|
|
{
|
|
$p = $this->paginationParams($page, $limit);
|
|
|
|
$countQb = $this->machines->createQueryBuilder('m')
|
|
->select('COUNT(m.id)')
|
|
;
|
|
|
|
$qb = $this->machines->createQueryBuilder('m')
|
|
->select('m.id', 'm.name', 'm.reference', 'm.prix')
|
|
->orderBy('m.name', 'ASC')
|
|
;
|
|
|
|
if ('' !== $search) {
|
|
$countQb->andWhere('LOWER(m.name) LIKE LOWER(:search) OR LOWER(m.reference) LIKE LOWER(:search)')
|
|
->setParameter('search', "%{$search}%")
|
|
;
|
|
$qb->andWhere('LOWER(m.name) LIKE LOWER(:search) OR LOWER(m.reference) LIKE LOWER(:search)')
|
|
->setParameter('search', "%{$search}%")
|
|
;
|
|
}
|
|
|
|
$total = (int) $countQb->getQuery()->getSingleScalarResult();
|
|
|
|
$items = $qb->setFirstResult($p['offset'])
|
|
->setMaxResults($p['limit'])
|
|
->getQuery()
|
|
->getArrayResult()
|
|
;
|
|
|
|
return $this->paginatedResponse($items, $total, $p['page'], $p['limit']);
|
|
}
|
|
}
|