Skip to content

Commit 8ef5371

Browse files
Simplify pagination cursor to use only TaskId since UUID v7 is monotonically increasing
Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com>
1 parent a637ea2 commit 8ef5371

1 file changed

Lines changed: 8 additions & 18 deletions

File tree

src/ModelContextProtocol.Core/Server/InMemoryMcpTaskStore.cs

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -351,32 +351,22 @@ public Task<ListTasksResult> ListTasksAsync(
351351
string? sessionId = null,
352352
CancellationToken cancellationToken = default)
353353
{
354-
// Parse cursor: format is "CreatedAt|TaskId" for keyset pagination
355-
(DateTimeOffset, string)? parsedCursor = null;
356-
if (cursor != null)
357-
{
358-
var parts = cursor.Split('|');
359-
if (parts.Length == 2 &&
360-
DateTimeOffset.TryParse(parts[0], out var parsedDate))
361-
{
362-
parsedCursor = (parsedDate, parts[1]);
363-
}
364-
}
365-
366354
// Stream enumeration - filter by session, exclude expired, apply keyset pagination
367355
var query = _tasks.Values
368356
.Where(e => sessionId == null || e.SessionId == sessionId)
369357
.Where(e => !IsExpired(e));
370358

371-
// Apply keyset filter if cursor provided: (CreatedAt, TaskId) > cursor
372-
if (parsedCursor is { } parsedCursorValue)
359+
// Apply keyset filter if cursor provided: TaskId > cursor
360+
// UUID v7 task IDs are monotonically increasing and inherently time-ordered
361+
if (cursor != null)
373362
{
374-
query = query.Where(e => (e.CreatedAt, e.TaskId).CompareTo(parsedCursorValue) > 0);
363+
query = query.Where(e => string.CompareOrdinal(e.TaskId, cursor) > 0);
375364
}
376365

377-
// Order by (CreatedAt, TaskId) for stable, deterministic pagination
366+
// Order by TaskId for stable, deterministic pagination
367+
// UUID v7 task IDs sort chronologically due to embedded timestamp
378368
var page = query
379-
.OrderBy(e => (e.CreatedAt, e.TaskId))
369+
.OrderBy(e => e.TaskId, StringComparer.Ordinal)
380370
.Take(_pageSize + 1) // Take one extra to check if there's a next page
381371
.Select(e => e.ToMcpTask())
382372
.ToList();
@@ -386,7 +376,7 @@ public Task<ListTasksResult> ListTasksAsync(
386376
if (page.Count > _pageSize)
387377
{
388378
var lastItemInPage = page[_pageSize - 1]; // Last item we'll actually return
389-
nextCursor = $"{lastItemInPage.CreatedAt:O}|{lastItemInPage.TaskId}";
379+
nextCursor = lastItemInPage.TaskId;
390380
page.RemoveAt(_pageSize); // Remove the extra item
391381
}
392382
else

0 commit comments

Comments
 (0)