Skip to content

Commit 52a2de8

Browse files
author
larry.sulebalogun
committed
10 - Added the registry logic
1 parent ac3e1e1 commit 52a2de8

File tree

1 file changed

+117
-9
lines changed

1 file changed

+117
-9
lines changed

src/Capability/Registry.php

Lines changed: 117 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Mcp\Event\ResourceTemplateListChangedEvent;
2323
use Mcp\Event\ToolListChangedEvent;
2424
use Mcp\Exception\InvalidArgumentException;
25+
use Mcp\Exception\InvalidCursorException;
2526
use Mcp\Schema\Content\PromptMessage;
2627
use Mcp\Schema\Content\ResourceContents;
2728
use Mcp\Schema\Prompt;
@@ -306,30 +307,137 @@ public function getPrompt(string $name): ?PromptReference
306307
/**
307308
* @return array<string, Tool>
308309
*/
309-
public function getTools(): array
310+
public function getTools(?int $limit = null, ?string $cursor = null): array
310311
{
311-
return array_map(fn (ToolReference $tool) => $tool->tool, $this->tools);
312+
$tools = [];
313+
foreach ($this->tools as $toolReference) {
314+
$tools[] = $toolReference->tool;
315+
}
316+
317+
if ($limit === null) {
318+
return $tools;
319+
}
320+
321+
return $this->paginateResults($tools, $limit, $cursor);
312322
}
313323

314324
/**
315325
* @return array<string, resource>
316326
*/
317-
public function getResources(): array
327+
public function getResources(?int $limit = null, ?string $cursor = null): array
318328
{
319-
return array_map(fn (ResourceReference $resource) => $resource->schema, $this->resources);
329+
$resources = [];
330+
foreach ($this->resources as $resource) {
331+
$resources[] = $resource->schema;
332+
}
333+
334+
if ($limit === null) {
335+
return $resources;
336+
}
337+
338+
return $this->paginateResults($resources, $limit, $cursor);
320339
}
321340

322341
/**
323342
* @return array<string, Prompt>
324343
*/
325-
public function getPrompts(): array
344+
public function getPrompts(?int $limit = null, ?string $cursor = null): array
345+
{
346+
$prompts = [];
347+
foreach ($this->prompts as $promptReference) {
348+
$prompts[] = $promptReference->prompt;
349+
}
350+
351+
if ($limit === null) {
352+
return $prompts;
353+
}
354+
355+
return $this->paginateResults($prompts, $limit, $cursor);
356+
}
357+
358+
/**
359+
* Get total count of tools.
360+
*/
361+
public function getToolsCount(): int
326362
{
327-
return array_map(fn (PromptReference $prompt) => $prompt->prompt, $this->prompts);
363+
return count($this->tools);
328364
}
329365

330-
/** @return array<string, ResourceTemplate> */
331-
public function getResourceTemplates(): array
366+
/**
367+
* Get total count of prompts.
368+
*/
369+
public function getPromptsCount(): int
370+
{
371+
return count($this->prompts);
372+
}
373+
374+
/**
375+
* Get total count of resources.
376+
*/
377+
public function getResourcesCount(): int
378+
{
379+
return count($this->resources);
380+
}
381+
382+
/**
383+
* @return array<string, ResourceTemplate>
384+
*/
385+
public function getResourceTemplates(?int $limit = null, ?string $cursor = null): array
332386
{
333-
return array_map(fn ($template) => $template->resourceTemplate, $this->resourceTemplates);
387+
$templates = array_map(fn ($template) => $template->resourceTemplate, $this->resourceTemplates);
388+
389+
if ($limit === null) {
390+
return $templates;
391+
}
392+
393+
return $this->paginateResults($templates, $limit, $cursor);
394+
}
395+
396+
/**
397+
* @throws InvalidCursorException
398+
*/
399+
private function paginateResults(array $items, int $limit, ?string $cursor = null): array
400+
{
401+
$offset = 0;
402+
if ($cursor !== null) {
403+
$decodedCursor = base64_decode($cursor, true);
404+
405+
if ($decodedCursor === false || !is_numeric($decodedCursor)) {
406+
throw new InvalidCursorException($cursor);
407+
}
408+
409+
$offset = $decodedCursor;
410+
411+
// Validate offset is within reasonable bounds
412+
if ($offset < 0 || $offset > count($items)) {
413+
throw new InvalidCursorException($cursor);
414+
}
415+
}
416+
417+
return array_slice($items, $offset, $limit);
418+
}
419+
420+
/**
421+
* Calculate next cursor for pagination.
422+
*/
423+
public function calculateNextCursor(int $totalCount, ?string $currentCursor, int $returnedCount): ?string
424+
{
425+
$currentOffset = 0;
426+
427+
if ($currentCursor !== null) {
428+
$decodedCursor = base64_decode($currentCursor, true);
429+
if ($decodedCursor !== false && is_numeric($decodedCursor)) {
430+
$currentOffset = $decodedCursor;
431+
}
432+
}
433+
434+
$nextOffset = $currentOffset + $returnedCount;
435+
436+
// If we have more items available, return next cursor
437+
if ($nextOffset < $totalCount) {
438+
return base64_encode((string) $nextOffset);
439+
}
440+
441+
return null;
334442
}
335443
}

0 commit comments

Comments
 (0)