Skip to content

Commit 9993e35

Browse files
committed
Fix MCP pagination review findings (#1727 #1729)
1 parent 2e6d071 commit 9993e35

3 files changed

Lines changed: 31 additions & 6 deletions

File tree

src/CodeIndex/Database/DbReader.References.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ public List<ReferenceResult> SearchReferences(string? query = null, int limit =
2525
return SearchReferencesCore(query, limit, lang, referenceKind, pathPatterns, excludePathPatterns, excludeTests, exact, offset, maxLineWidth, excludeSelfReferences);
2626

2727
var rawLimit = Math.Max(limit, CSharpUsingStaticReferenceFilterChunkSize);
28-
var rawOffset = Math.Max(0, offset);
28+
var rawOffset = 0;
29+
var acceptedBeforePage = Math.Max(0, offset);
30+
var accepted = 0;
2931
var filtered = new List<ReferenceResult>();
3032
while (filtered.Count < limit)
3133
{
@@ -38,6 +40,13 @@ public List<ReferenceResult> SearchReferences(string? query = null, int limit =
3840
if (ShouldSuppressCSharpUsingStaticConstantPatternReference(result))
3941
continue;
4042

43+
if (accepted < acceptedBeforePage)
44+
{
45+
accepted++;
46+
continue;
47+
}
48+
49+
accepted++;
4150
filtered.Add(result);
4251
if (filtered.Count >= limit)
4352
break;

src/CodeIndex/Mcp/McpToolDefinitions.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ private JsonNode HandleToolsList(JsonNode? id)
2727
["properties"] = new JsonObject
2828
{
2929
["query"] = new JsonObject { ["type"] = "string", ["description"] = "Search query text. Append `*` to a token to make that token a prefix phrase (`計算*` matches `計算する`)." },
30-
["limit"] = new JsonObject { ["type"] = "integer", ["description"] = "Max results (default: 20). Responses include `truncated`, `more_available`, and `next_offset` when more rows exist.", ["default"] = 20 },
31-
["offset"] = new JsonObject { ["type"] = "integer", ["description"] = "Zero-based result offset for pagination; use `next_offset` from a truncated response.", ["default"] = 0, ["minimum"] = 0 },
30+
["limit"] = new JsonObject { ["type"] = "integer", ["description"] = "Max results (default: 20). Responses include `truncated` and `more_available` when more rows exist.", ["default"] = 20 },
3231
["lang"] = new JsonObject { ["type"] = "string", ["description"] = "Filter by language (e.g. csharp, python, javascript)" },
3332
["snippetLines"] = new JsonObject { ["type"] = "integer", ["description"] = "Max snippet lines per result (default: 8, max: 20)", ["default"] = 8, ["minimum"] = 1, ["maximum"] = SearchSnippetFormatter.MaxSnippetLines },
3433
["maxLineWidth"] = new JsonObject { ["type"] = "integer", ["description"] = "Clamp very long single-line snippets per line (default: 512; 0 disables clamping). Match lines are clamped around the first match; non-match lines are clamped from the head. Each clamp inserts a `...(+N)...` marker showing how many chars were elided.", ["default"] = LineWidthFormatter.DefaultMaxLineWidth, ["minimum"] = 0, ["maximum"] = LineWidthFormatter.MaxAllowedLineWidth },

tests/CodeIndex.Tests/DbReaderTests.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10245,11 +10245,12 @@ class Demo
1024510245
// call site.
1024610246
const int suppressedReferenceCount = 64;
1024710247
const int callReferenceLine = suppressedReferenceCount + 10;
10248+
const int secondCallReferenceLine = callReferenceLine + 1;
1024810249

1024910250
using (var updateFileCmd = _db.Connection.CreateCommand())
1025010251
{
1025110252
updateFileCmd.CommandText = "UPDATE files SET lines = @lines WHERE path = 'src/Use.cs'";
10252-
updateFileCmd.Parameters.AddWithValue("@lines", callReferenceLine + 5);
10253+
updateFileCmd.Parameters.AddWithValue("@lines", secondCallReferenceLine + 5);
1025310254
updateFileCmd.ExecuteNonQuery();
1025410255
}
1025510256

@@ -10307,13 +10308,29 @@ LIMIT 1
1030710308
ContainerKind = "function",
1030810309
ContainerName = "Match",
1030910310
});
10311+
syntheticReferences.Add(new ReferenceRecord
10312+
{
10313+
FileId = useFileId,
10314+
SymbolName = "Red",
10315+
ReferenceKind = "call",
10316+
Line = secondCallReferenceLine,
10317+
Column = 9,
10318+
Context = " Red();",
10319+
ContainerKind = "function",
10320+
ContainerName = "Match",
10321+
});
1031010322
_writer.InsertReferences(syntheticReferences);
1031110323

1031210324
var result = Assert.Single(_reader.SearchReferences("Red", limit: 1, lang: "csharp", exact: true, pathPatterns: ["src/Use.cs"]));
1031310325
Assert.Equal("call", result.ReferenceKind);
1031410326
Assert.Equal(callReferenceLine, result.Line);
10315-
Assert.Equal(1, _reader.CountSearchReferences("Red", limit: 1, lang: "csharp", exact: true, pathPatterns: ["src/Use.cs"]));
10316-
Assert.Equal(new QueryCountResult(1, 1), _reader.CountSearchReferencesTotal("Red", lang: "csharp", exact: true, pathPatterns: ["src/Use.cs"]));
10327+
10328+
var nextPage = Assert.Single(_reader.SearchReferences("Red", limit: 1, lang: "csharp", exact: true, pathPatterns: ["src/Use.cs"], offset: 1));
10329+
Assert.Equal("call", nextPage.ReferenceKind);
10330+
Assert.Equal(secondCallReferenceLine, nextPage.Line);
10331+
10332+
Assert.Equal(2, _reader.CountSearchReferences("Red", limit: 2, lang: "csharp", exact: true, pathPatterns: ["src/Use.cs"]));
10333+
Assert.Equal(new QueryCountResult(2, 1), _reader.CountSearchReferencesTotal("Red", lang: "csharp", exact: true, pathPatterns: ["src/Use.cs"]));
1031710334
}
1031810335

1031910336
[Fact]

0 commit comments

Comments
 (0)