feat : add collaborators to all MCP task tools
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -51,6 +51,7 @@ class CreateTaskTool
|
||||
?int $assigneeId = null,
|
||||
?int $groupId = null,
|
||||
?array $tagIds = null,
|
||||
?array $collaboratorIds = null,
|
||||
?string $scheduledStart = null,
|
||||
?string $scheduledEnd = null,
|
||||
?string $deadline = null,
|
||||
@@ -116,6 +117,18 @@ class CreateTaskTool
|
||||
$task->addTag($tag);
|
||||
}
|
||||
}
|
||||
if (null !== $collaboratorIds) {
|
||||
foreach ($collaboratorIds as $collaboratorId) {
|
||||
$collaborator = $this->userRepository->find($collaboratorId);
|
||||
if (null === $collaborator) {
|
||||
throw new InvalidArgumentException(sprintf('User with ID %d not found.', $collaboratorId));
|
||||
}
|
||||
if (null !== $assigneeId && $collaboratorId === $assigneeId) {
|
||||
throw new InvalidArgumentException('A collaborator cannot be the assignee.');
|
||||
}
|
||||
$task->addCollaborator($collaborator);
|
||||
}
|
||||
}
|
||||
if (null !== $scheduledStart) {
|
||||
$task->setScheduledStart(new DateTimeImmutable($scheduledStart));
|
||||
}
|
||||
@@ -147,6 +160,7 @@ class CreateTaskTool
|
||||
'priority' => Serializer::priority($task->getPriority()),
|
||||
'effort' => Serializer::effort($task->getEffort()),
|
||||
'assignee' => Serializer::user($task->getAssignee()),
|
||||
'collaborators' => Serializer::users($task->getCollaborators()),
|
||||
'group' => Serializer::groupRef($task->getGroup()),
|
||||
'project' => Serializer::projectRef($project),
|
||||
'tags' => Serializer::tags($task->getTags()),
|
||||
|
||||
@@ -34,19 +34,20 @@ class GetTaskTool
|
||||
}
|
||||
|
||||
return json_encode([
|
||||
'id' => $task->getId(),
|
||||
'number' => $task->getNumber(),
|
||||
'title' => $task->getTitle(),
|
||||
'description' => $task->getDescription(),
|
||||
'status' => Serializer::statusFull($task->getStatus()),
|
||||
'priority' => Serializer::priority($task->getPriority()),
|
||||
'effort' => Serializer::effort($task->getEffort()),
|
||||
'assignee' => Serializer::user($task->getAssignee()),
|
||||
'group' => Serializer::group($task->getGroup()),
|
||||
'project' => Serializer::projectRef($task->getProject()),
|
||||
'tags' => Serializer::tagsWithColor($task->getTags()),
|
||||
'documents' => Serializer::documents($task->getDocuments()),
|
||||
'archived' => $task->isArchived(),
|
||||
'id' => $task->getId(),
|
||||
'number' => $task->getNumber(),
|
||||
'title' => $task->getTitle(),
|
||||
'description' => $task->getDescription(),
|
||||
'status' => Serializer::statusFull($task->getStatus()),
|
||||
'priority' => Serializer::priority($task->getPriority()),
|
||||
'effort' => Serializer::effort($task->getEffort()),
|
||||
'assignee' => Serializer::user($task->getAssignee()),
|
||||
'collaborators' => Serializer::users($task->getCollaborators()),
|
||||
'group' => Serializer::group($task->getGroup()),
|
||||
'project' => Serializer::projectRef($task->getProject()),
|
||||
'tags' => Serializer::tagsWithColor($task->getTags()),
|
||||
'documents' => Serializer::documents($task->getDocuments()),
|
||||
'archived' => $task->isArchived(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use Mcp\Capability\Attribute\McpTool;
|
||||
use Symfony\Bundle\SecurityBundle\Security;
|
||||
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
||||
|
||||
#[McpTool(name: 'list-tasks', description: 'List tasks with optional filters by project, status, assignee, priority, group, tags, and archive state. Returns max 100 results by default, use filters to narrow down.')]
|
||||
#[McpTool(name: 'list-tasks', description: 'List tasks with optional filters by project, status, assignee, collaborator, priority, group, tags, and archive state. Returns max 100 results by default, use filters to narrow down.')]
|
||||
class ListTasksTool
|
||||
{
|
||||
public function __construct(
|
||||
@@ -22,6 +22,7 @@ class ListTasksTool
|
||||
?int $projectId = null,
|
||||
?int $statusId = null,
|
||||
?int $assigneeId = null,
|
||||
?int $collaboratorId = null,
|
||||
?int $priorityId = null,
|
||||
?int $groupId = null,
|
||||
?array $tagIds = null,
|
||||
@@ -38,6 +39,7 @@ class ListTasksTool
|
||||
->leftJoin('t.status', 's')->addSelect('s')
|
||||
->leftJoin('t.priority', 'p')->addSelect('p')
|
||||
->leftJoin('t.assignee', 'a')->addSelect('a')
|
||||
->leftJoin('t.collaborators', 'collab')->addSelect('collab')
|
||||
->leftJoin('t.project', 'pr')->addSelect('pr')
|
||||
->leftJoin('t.effort', 'e')->addSelect('e')
|
||||
->leftJoin('t.group', 'g')->addSelect('g')
|
||||
@@ -57,6 +59,9 @@ class ListTasksTool
|
||||
if (null !== $assigneeId) {
|
||||
$qb->andWhere('a.id = :assigneeId')->setParameter('assigneeId', $assigneeId);
|
||||
}
|
||||
if (null !== $collaboratorId) {
|
||||
$qb->andWhere('collab.id = :collaboratorId')->setParameter('collaboratorId', $collaboratorId);
|
||||
}
|
||||
if (null !== $priorityId) {
|
||||
$qb->andWhere('p.id = :priorityId')->setParameter('priorityId', $priorityId);
|
||||
}
|
||||
@@ -75,17 +80,18 @@ class ListTasksTool
|
||||
}
|
||||
|
||||
return json_encode(array_map(fn ($task) => [
|
||||
'id' => $task->getId(),
|
||||
'number' => $task->getNumber(),
|
||||
'title' => $task->getTitle(),
|
||||
'status' => Serializer::status($task->getStatus()),
|
||||
'priority' => Serializer::priority($task->getPriority()),
|
||||
'assignee' => Serializer::user($task->getAssignee()),
|
||||
'effort' => Serializer::effort($task->getEffort()),
|
||||
'group' => Serializer::groupRef($task->getGroup()),
|
||||
'project' => Serializer::projectRef($task->getProject()),
|
||||
'tags' => Serializer::tags($task->getTags()),
|
||||
'archived' => $task->isArchived(),
|
||||
'id' => $task->getId(),
|
||||
'number' => $task->getNumber(),
|
||||
'title' => $task->getTitle(),
|
||||
'status' => Serializer::status($task->getStatus()),
|
||||
'priority' => Serializer::priority($task->getPriority()),
|
||||
'assignee' => Serializer::user($task->getAssignee()),
|
||||
'collaborators' => Serializer::users($task->getCollaborators()),
|
||||
'effort' => Serializer::effort($task->getEffort()),
|
||||
'group' => Serializer::groupRef($task->getGroup()),
|
||||
'project' => Serializer::projectRef($task->getProject()),
|
||||
'tags' => Serializer::tags($task->getTags()),
|
||||
'archived' => $task->isArchived(),
|
||||
], array_values($tasks)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ class UpdateTaskTool
|
||||
?int $assigneeId = null,
|
||||
?int $groupId = null,
|
||||
?array $tagIds = null,
|
||||
?array $collaboratorIds = null,
|
||||
?bool $archived = null,
|
||||
?string $scheduledStart = null,
|
||||
?string $scheduledEnd = null,
|
||||
@@ -118,6 +119,22 @@ class UpdateTaskTool
|
||||
$task->addTag($tag);
|
||||
}
|
||||
}
|
||||
if (null !== $collaboratorIds) {
|
||||
foreach ($task->getCollaborators()->toArray() as $existing) {
|
||||
$task->removeCollaborator($existing);
|
||||
}
|
||||
$assignee = $task->getAssignee();
|
||||
foreach ($collaboratorIds as $collaboratorId) {
|
||||
$collaborator = $this->userRepository->find($collaboratorId);
|
||||
if (null === $collaborator) {
|
||||
throw new InvalidArgumentException(sprintf('User with ID %d not found.', $collaboratorId));
|
||||
}
|
||||
if (null !== $assignee && $collaborator->getId() === $assignee->getId()) {
|
||||
throw new InvalidArgumentException('A collaborator cannot be the assignee.');
|
||||
}
|
||||
$task->addCollaborator($collaborator);
|
||||
}
|
||||
}
|
||||
if (null !== $archived) {
|
||||
$task->setArchived($archived);
|
||||
}
|
||||
@@ -147,6 +164,7 @@ class UpdateTaskTool
|
||||
'priority' => Serializer::priority($task->getPriority()),
|
||||
'effort' => Serializer::effort($task->getEffort()),
|
||||
'assignee' => Serializer::user($task->getAssignee()),
|
||||
'collaborators' => Serializer::users($task->getCollaborators()),
|
||||
'group' => Serializer::groupRef($task->getGroup()),
|
||||
'project' => Serializer::projectRef($task->getProject()),
|
||||
'tags' => Serializer::tags($task->getTags()),
|
||||
|
||||
Reference in New Issue
Block a user