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 $assigneeId = null,
|
||||||
?int $groupId = null,
|
?int $groupId = null,
|
||||||
?array $tagIds = null,
|
?array $tagIds = null,
|
||||||
|
?array $collaboratorIds = null,
|
||||||
?string $scheduledStart = null,
|
?string $scheduledStart = null,
|
||||||
?string $scheduledEnd = null,
|
?string $scheduledEnd = null,
|
||||||
?string $deadline = null,
|
?string $deadline = null,
|
||||||
@@ -116,6 +117,18 @@ class CreateTaskTool
|
|||||||
$task->addTag($tag);
|
$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) {
|
if (null !== $scheduledStart) {
|
||||||
$task->setScheduledStart(new DateTimeImmutable($scheduledStart));
|
$task->setScheduledStart(new DateTimeImmutable($scheduledStart));
|
||||||
}
|
}
|
||||||
@@ -147,6 +160,7 @@ class CreateTaskTool
|
|||||||
'priority' => Serializer::priority($task->getPriority()),
|
'priority' => Serializer::priority($task->getPriority()),
|
||||||
'effort' => Serializer::effort($task->getEffort()),
|
'effort' => Serializer::effort($task->getEffort()),
|
||||||
'assignee' => Serializer::user($task->getAssignee()),
|
'assignee' => Serializer::user($task->getAssignee()),
|
||||||
|
'collaborators' => Serializer::users($task->getCollaborators()),
|
||||||
'group' => Serializer::groupRef($task->getGroup()),
|
'group' => Serializer::groupRef($task->getGroup()),
|
||||||
'project' => Serializer::projectRef($project),
|
'project' => Serializer::projectRef($project),
|
||||||
'tags' => Serializer::tags($task->getTags()),
|
'tags' => Serializer::tags($task->getTags()),
|
||||||
|
|||||||
@@ -34,19 +34,20 @@ class GetTaskTool
|
|||||||
}
|
}
|
||||||
|
|
||||||
return json_encode([
|
return json_encode([
|
||||||
'id' => $task->getId(),
|
'id' => $task->getId(),
|
||||||
'number' => $task->getNumber(),
|
'number' => $task->getNumber(),
|
||||||
'title' => $task->getTitle(),
|
'title' => $task->getTitle(),
|
||||||
'description' => $task->getDescription(),
|
'description' => $task->getDescription(),
|
||||||
'status' => Serializer::statusFull($task->getStatus()),
|
'status' => Serializer::statusFull($task->getStatus()),
|
||||||
'priority' => Serializer::priority($task->getPriority()),
|
'priority' => Serializer::priority($task->getPriority()),
|
||||||
'effort' => Serializer::effort($task->getEffort()),
|
'effort' => Serializer::effort($task->getEffort()),
|
||||||
'assignee' => Serializer::user($task->getAssignee()),
|
'assignee' => Serializer::user($task->getAssignee()),
|
||||||
'group' => Serializer::group($task->getGroup()),
|
'collaborators' => Serializer::users($task->getCollaborators()),
|
||||||
'project' => Serializer::projectRef($task->getProject()),
|
'group' => Serializer::group($task->getGroup()),
|
||||||
'tags' => Serializer::tagsWithColor($task->getTags()),
|
'project' => Serializer::projectRef($task->getProject()),
|
||||||
'documents' => Serializer::documents($task->getDocuments()),
|
'tags' => Serializer::tagsWithColor($task->getTags()),
|
||||||
'archived' => $task->isArchived(),
|
'documents' => Serializer::documents($task->getDocuments()),
|
||||||
|
'archived' => $task->isArchived(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use Mcp\Capability\Attribute\McpTool;
|
|||||||
use Symfony\Bundle\SecurityBundle\Security;
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
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
|
class ListTasksTool
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
@@ -22,6 +22,7 @@ class ListTasksTool
|
|||||||
?int $projectId = null,
|
?int $projectId = null,
|
||||||
?int $statusId = null,
|
?int $statusId = null,
|
||||||
?int $assigneeId = null,
|
?int $assigneeId = null,
|
||||||
|
?int $collaboratorId = null,
|
||||||
?int $priorityId = null,
|
?int $priorityId = null,
|
||||||
?int $groupId = null,
|
?int $groupId = null,
|
||||||
?array $tagIds = null,
|
?array $tagIds = null,
|
||||||
@@ -38,6 +39,7 @@ class ListTasksTool
|
|||||||
->leftJoin('t.status', 's')->addSelect('s')
|
->leftJoin('t.status', 's')->addSelect('s')
|
||||||
->leftJoin('t.priority', 'p')->addSelect('p')
|
->leftJoin('t.priority', 'p')->addSelect('p')
|
||||||
->leftJoin('t.assignee', 'a')->addSelect('a')
|
->leftJoin('t.assignee', 'a')->addSelect('a')
|
||||||
|
->leftJoin('t.collaborators', 'collab')->addSelect('collab')
|
||||||
->leftJoin('t.project', 'pr')->addSelect('pr')
|
->leftJoin('t.project', 'pr')->addSelect('pr')
|
||||||
->leftJoin('t.effort', 'e')->addSelect('e')
|
->leftJoin('t.effort', 'e')->addSelect('e')
|
||||||
->leftJoin('t.group', 'g')->addSelect('g')
|
->leftJoin('t.group', 'g')->addSelect('g')
|
||||||
@@ -57,6 +59,9 @@ class ListTasksTool
|
|||||||
if (null !== $assigneeId) {
|
if (null !== $assigneeId) {
|
||||||
$qb->andWhere('a.id = :assigneeId')->setParameter('assigneeId', $assigneeId);
|
$qb->andWhere('a.id = :assigneeId')->setParameter('assigneeId', $assigneeId);
|
||||||
}
|
}
|
||||||
|
if (null !== $collaboratorId) {
|
||||||
|
$qb->andWhere('collab.id = :collaboratorId')->setParameter('collaboratorId', $collaboratorId);
|
||||||
|
}
|
||||||
if (null !== $priorityId) {
|
if (null !== $priorityId) {
|
||||||
$qb->andWhere('p.id = :priorityId')->setParameter('priorityId', $priorityId);
|
$qb->andWhere('p.id = :priorityId')->setParameter('priorityId', $priorityId);
|
||||||
}
|
}
|
||||||
@@ -75,17 +80,18 @@ class ListTasksTool
|
|||||||
}
|
}
|
||||||
|
|
||||||
return json_encode(array_map(fn ($task) => [
|
return json_encode(array_map(fn ($task) => [
|
||||||
'id' => $task->getId(),
|
'id' => $task->getId(),
|
||||||
'number' => $task->getNumber(),
|
'number' => $task->getNumber(),
|
||||||
'title' => $task->getTitle(),
|
'title' => $task->getTitle(),
|
||||||
'status' => Serializer::status($task->getStatus()),
|
'status' => Serializer::status($task->getStatus()),
|
||||||
'priority' => Serializer::priority($task->getPriority()),
|
'priority' => Serializer::priority($task->getPriority()),
|
||||||
'assignee' => Serializer::user($task->getAssignee()),
|
'assignee' => Serializer::user($task->getAssignee()),
|
||||||
'effort' => Serializer::effort($task->getEffort()),
|
'collaborators' => Serializer::users($task->getCollaborators()),
|
||||||
'group' => Serializer::groupRef($task->getGroup()),
|
'effort' => Serializer::effort($task->getEffort()),
|
||||||
'project' => Serializer::projectRef($task->getProject()),
|
'group' => Serializer::groupRef($task->getGroup()),
|
||||||
'tags' => Serializer::tags($task->getTags()),
|
'project' => Serializer::projectRef($task->getProject()),
|
||||||
'archived' => $task->isArchived(),
|
'tags' => Serializer::tags($task->getTags()),
|
||||||
|
'archived' => $task->isArchived(),
|
||||||
], array_values($tasks)));
|
], array_values($tasks)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ class UpdateTaskTool
|
|||||||
?int $assigneeId = null,
|
?int $assigneeId = null,
|
||||||
?int $groupId = null,
|
?int $groupId = null,
|
||||||
?array $tagIds = null,
|
?array $tagIds = null,
|
||||||
|
?array $collaboratorIds = null,
|
||||||
?bool $archived = null,
|
?bool $archived = null,
|
||||||
?string $scheduledStart = null,
|
?string $scheduledStart = null,
|
||||||
?string $scheduledEnd = null,
|
?string $scheduledEnd = null,
|
||||||
@@ -118,6 +119,22 @@ class UpdateTaskTool
|
|||||||
$task->addTag($tag);
|
$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) {
|
if (null !== $archived) {
|
||||||
$task->setArchived($archived);
|
$task->setArchived($archived);
|
||||||
}
|
}
|
||||||
@@ -147,6 +164,7 @@ class UpdateTaskTool
|
|||||||
'priority' => Serializer::priority($task->getPriority()),
|
'priority' => Serializer::priority($task->getPriority()),
|
||||||
'effort' => Serializer::effort($task->getEffort()),
|
'effort' => Serializer::effort($task->getEffort()),
|
||||||
'assignee' => Serializer::user($task->getAssignee()),
|
'assignee' => Serializer::user($task->getAssignee()),
|
||||||
|
'collaborators' => Serializer::users($task->getCollaborators()),
|
||||||
'group' => Serializer::groupRef($task->getGroup()),
|
'group' => Serializer::groupRef($task->getGroup()),
|
||||||
'project' => Serializer::projectRef($task->getProject()),
|
'project' => Serializer::projectRef($task->getProject()),
|
||||||
'tags' => Serializer::tags($task->getTags()),
|
'tags' => Serializer::tags($task->getTags()),
|
||||||
|
|||||||
Reference in New Issue
Block a user