47 lines
2.0 KiB
PHP
47 lines
2.0 KiB
PHP
<?php
|
|
|
|
namespace App\Mcp\Tools;
|
|
|
|
use App\Actions\Permissions\PermissionService;
|
|
use App\Mcp\Support\KanbanGitMcp;
|
|
use App\Models\Project;
|
|
use Illuminate\Contracts\JsonSchema\JsonSchema;
|
|
use Illuminate\JsonSchema\Types\Type;
|
|
use Laravel\Mcp\Request;
|
|
use Laravel\Mcp\Response;
|
|
use Laravel\Mcp\ResponseFactory;
|
|
use Laravel\Mcp\Server\Attributes\Description;
|
|
use Laravel\Mcp\Server\Attributes\Name;
|
|
use Laravel\Mcp\Server\Tool;
|
|
use Laravel\Mcp\Server\Tools\Annotations\IsReadOnly;
|
|
|
|
#[Name('list_projects')]
|
|
#[Description('List visible projects independently of assigned tickets. Returns only ID, key and name, ordered by ID, with bounded pagination. page starts at 1; per_page defaults to 25 and may not exceed 100.')]
|
|
#[IsReadOnly]
|
|
class ListProjects extends Tool
|
|
{
|
|
public function __construct(private readonly KanbanGitMcp $kanbanGitMcp, private readonly PermissionService $permissionService) {}
|
|
|
|
public function handle(Request $request): Response|ResponseFactory
|
|
{
|
|
$input = $request->validate(['page' => ['sometimes', 'integer', 'min:1'], 'per_page' => ['sometimes', 'integer', 'min:1', 'max:100']]);
|
|
$user = $this->kanbanGitMcp->user($request);
|
|
$projects = Project::query()->whereIn('id', $this->permissionService->viewableProjectIds($user))
|
|
->orderBy('id')->paginate($input['per_page'] ?? 25, ['id', 'key', 'name'], 'page', $input['page'] ?? 1);
|
|
|
|
return Response::structured([
|
|
'data' => $projects->getCollection()->map(fn (Project $project): array => ['id' => $project->id, 'key' => $project->key, 'name' => $project->name])->all(),
|
|
'meta' => $this->kanbanGitMcp->paginationPayload($projects),
|
|
]);
|
|
}
|
|
|
|
/** @return array<string, Type> */
|
|
public function schema(JsonSchema $schema): array
|
|
{
|
|
return [
|
|
'page' => $schema->integer()->min(1)->description('Page number, defaults to 1.'),
|
|
'per_page' => $schema->integer()->min(1)->max(100)->description('Page size, defaults to 25; maximum 100.'),
|
|
];
|
|
}
|
|
}
|