feat(mcp) : add Slots, Machine Links, Structure, and Clone tools

- list_slots + update_slots for composant/piece slots
- list/add/update/remove machine links (component, piece, product)
- get_machine_structure with full hierarchy
- clone_machine with all links and custom fields
- 52 MCP tests pass total

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matthieu
2026-03-16 14:49:55 +01:00
parent 2f173e766d
commit bd7259ed05
11 changed files with 1724 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
namespace App\Mcp\Tool\Machine;
use App\Mcp\Tool\McpToolHelper;
use App\Repository\MachineComponentLinkRepository;
use App\Repository\MachinePieceLinkRepository;
use App\Repository\MachineProductLinkRepository;
use Doctrine\ORM\EntityManagerInterface;
use Mcp\Capability\Attribute\McpTool;
use Symfony\Bundle\SecurityBundle\Security;
#[McpTool(
name: 'remove_machine_link',
description: 'Remove a machine link by id and type (composant, piece, or product). Requires ROLE_GESTIONNAIRE.',
)]
class RemoveMachineLinkTool
{
use McpToolHelper;
public function __construct(
private readonly EntityManagerInterface $em,
private readonly Security $security,
private readonly MachineComponentLinkRepository $componentLinks,
private readonly MachinePieceLinkRepository $pieceLinks,
private readonly MachineProductLinkRepository $productLinks,
) {}
public function __invoke(string $linkId, string $linkType): array
{
$this->requireRole($this->security, 'ROLE_GESTIONNAIRE');
$link = match ($linkType) {
'composant' => $this->componentLinks->find($linkId),
'piece' => $this->pieceLinks->find($linkId),
'product' => $this->productLinks->find($linkId),
default => $this->mcpError('Validation', "Unknown link type '{$linkType}'. Expected composant, piece, or product."),
};
if (null === $link) {
$this->mcpError('NotFound', "Link {$linkId} of type {$linkType} not found.");
}
$this->em->remove($link);
$this->em->flush();
return $this->jsonResponse(['deleted' => true, 'id' => $linkId, 'type' => $linkType]);
}
}