Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions DEVELOPER_GUIDE.md

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions TESTING_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,7 @@ Use `docs/test-doc-maintenance-plan.md` before moving oversized suites or adding
MCP JSON-RPC behavior and tool outputs. Large server coverage is split into focused partial suites for tool calls, tool listing, protocol/session handling, and error handling while the root `McpServerTests` part keeps shared seeded fixture state. Request-timeout tests use signal-gated delay hooks instead of fixed sleeps: start the request, confirm the hook has begun, then await the timeout response with a bounded wait so they pay only the configured timeout while still proving in-flight actions drain after the timeout response.
The single-request timeout-lease regression uses an ID-specific dispatch signal, a one-second execution timeout for scheduler headroom, typed response-node assertions, and `TestDeterminism.AssertTaskRemainsBlockedAsync` for the queued request. Keep those checks together so full-suite load produces an actionable assertion instead of a null dereference (#4807).
The root seeded database/server fixture is initialized through a thread-safe `Lazy<T>` only when a test accesses its default fixture path. Static helpers and tests that build their own server or transport must not pay schema creation and seed cost; concurrent fixture access must still publish exactly one database/server pair.
Bounded MCP discovery coverage must keep the default 25-tool `tools/list` envelope at or below 64 KiB of serialized UTF-8 while preserving authoritative invocation-schema structure, deterministic ordering and opaque pagination, explicit-full reachability for output schemas/examples, legacy numeric-cursor compatibility, and section-level UTF-8 byte telemetry (including non-ASCII descriptions). Initialize coverage must keep `instructions` at or below 2 KiB and verify that extended guidance is discoverable through prompts.
High-volume discovery cursor coverage must consume `symbols`, `files`, and `validate` through the final page and assert authoritative totals, deterministic no-gap/no-duplicate enumeration, empty/final-page metadata, bounded opaque tokens, stateless reuse by concurrent server instances, and typed malformed, query-mismatch, and stale-generation failures. Keep an exact qualified Rust symbol query on the total-count path, and prove demoted issue readiness makes `validate` report a non-authoritative zero with explicit table/currentness signals. Seed only the rows needed by that focused partial suite and change the persisted generation before opening a fresh server for stale-token assertions.
`McpServerOutlinePaginationIssue4897Tests.cs` owns the standalone large-file `outline` contract. Keep its 175-row deep tree, empty file, projected aliases, stable source/name ordering, exact UTF-8 byte boundary, no-progress budget error, and stale-generation replay checks together. The suite intentionally uses an isolated database and the `SQLite pool sensitive` collection because it closes one server, mutates the persisted generation, and opens another to prove cursor invalidation.
Protocol negotiation coverage keeps `2025-06-18`, `2025-03-26`, and `2024-11-05` in one shared version-echo fixture and asserts the exact server-side capability keys for every version. The Codex compatibility regression separately uses the lifecycle-enforcing transport to send a `2025-06-18` initialize, `notifications/initialized`, and `tools/list`, because a direct handler assertion would not catch initialization-gate failures. Transport transcripts must also prove that a second initialize receives `duplicate_initialize` without mutating the session, and that `notifications/initialized` triggers `roots/list` only when the client advertised roots support. Signal-gated coverage must repeat initialized while the first roots response is blocked, prove only one client request starts and teardown drains it, and force both bounded drain deadlines to expire while a late roots write remains blocked to prove stdio resource disposal stays deferred. Release a timeout-delayed initialize worker after its frame cleanup to prove a corrected retry is accepted.
Expand Down Expand Up @@ -1603,6 +1604,7 @@ dotnet test --filter "FullyQualifiedName~GitHelperTests"
MCP の JSON-RPC 挙動とツール出力のテスト。大きな server coverage は tool call、tool listing、protocol/session handling、error handling ごとの focused partial suite に分割し、共有の seed 済み fixture 状態は root 側の `McpServerTests` に残します。request-timeout test は固定 sleep ではなく signal-gated delay hook を使います。request を開始し、hook が始まったことを確認してから timeout response を bounded wait で待つことで、timeout response 後に in-flight action が drain されることは保ったまま、設定した timeout 分だけを待つようにします。
single-request の timeout-lease 回帰テストでは、ID 別の dispatch signal、scheduler の余裕を確保する 1 秒の execution timeout、型付き response-node assertion、queue 待ち request に対する `TestDeterminism.AssertTaskRemainsBlockedAsync` を使います。full-suite 負荷でも null 参照ではなく対応可能な assertion を返すよう、これらの検証をまとめて維持してください(#4807)。
root の seed 済み database/server fixture は、test が既定 fixture path へアクセスした場合だけ thread-safe な `Lazy<T>` で初期化します。static helper や独自 server / transport を構築する test は未使用 schema の作成・seed cost を支払わず、並行 fixture access でも database/server pair を必ず1組だけ公開してください。
bounded MCP discovery の coverage では、既定の 25-tool `tools/list` envelope を serialized UTF-8 で 64 KiB 以下に保ちつつ、authoritative な呼び出し schema 構造、決定的な順序と opaque pagination、output schema / example への明示的 full 経路、legacy 数値 cursor の互換性、non-ASCII description を含む section ごとの UTF-8 byte telemetry を検証してください。initialize coverage は `instructions` を 2 KiB 以下に保ち、詳細 guidance を prompt から発見できることも確認してください。
大量 discovery 用 cursor の coverage では、`symbols`、`files`、`validate` を最終 page まで消費し、authoritative な total、gap・duplicate のない決定的列挙、空・最終 page metadata、上限内の opaque token、並行 server instance による stateless reuse、不正・query mismatch・stale generation の型付き failure を検証してください。total-count 経路には Rust の exact な完全修飾 symbol query も保持し、issue readiness を demote したときは `validate` が table/currentness signal とともに non-authoritative な 0 件を報告することも検証してください。focused partial suite に必要な row だけを seed し、stale token の assertion では永続化 generation を変更してから新しい server を開いてください。
`McpServerOutlinePaginationIssue4897Tests.cs` は独立した大規模 file の `outline` 契約を担当します。175 row の深い tree、空 file、projection alias、安定した source/name 順、正確な UTF-8 byte 境界、進捗不能 budget error、stale-generation replay の検証を同じ suite に維持してください。この suite は一方の server を閉じ、永続化 generation を変更して別の server で cursor invalidation を証明するため、独立 database と `SQLite pool sensitive` collection を意図的に使います。
protocol negotiation coverage は `2025-06-18`、`2025-03-26`、`2024-11-05` を共通の version-echo fixture にまとめ、全 version で server-side capability の正確な key を検証します。Codex 互換性の回帰テストでは別途 lifecycle を強制する transport を使い、`2025-06-18` の initialize、`notifications/initialized`、`tools/list` までを送ります。direct handler の assertion だけでは initialization gate の失敗を検出できないためです。transport transcript では、2回目の initialize が session を変更せず `duplicate_initialize` を返すことと、client が roots support を提示した場合だけ `notifications/initialized` の後に `roots/list` を送ることも検証してください。signal-gated coverage では最初の roots response を block したまま initialized を再送し、client request が1件だけ開始され teardown で drain されることを確認します。さらに、遅い roots write を block したまま両 bounded drain deadline を期限切れにし、stdio resource の dispose が引き続き defer されることを証明してください。また、frame cleanup 後に timeout で遅れた initialize worker を解放し、修正済み retry が受理されることを証明してください。
Expand Down
23 changes: 23 additions & 0 deletions changelog.d/unreleased/5059.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
category: fixed
issues:
- 5059
affected:
- src/CodeIndex/Mcp/McpServer.cs
- src/CodeIndex/Mcp/McpToolDefinitions.cs
- src/CodeIndex/Mcp/McpToolHandlers.Instructions.cs
- tests/CodeIndex.Tests/McpServerToolsListTests.cs
- tests/CodeIndex.Tests/McpServerProtocolTests.cs
- tests/CodeIndex.Tests/McpServerOutputSchemaTests.cs
- tests/CodeIndex.Tests/McpToolContractTests.cs
- DEVELOPER_GUIDE.md
- TESTING_GUIDE.md
---

## English

- **MCP discovery now fits an agent-safe bounded payload (#5059; follow-up to #4336)** — the default 25-tool `tools/list` response now stays within 64 KiB while retaining authoritative invocation schemas, safety-critical suggestion guidance, deterministic standard pagination, on-demand full definitions, and section-level UTF-8 size telemetry. Initialize guidance is also concise and points clients to compatible prompts for extended workflows.

## 日本語

- **MCP discovery を agent-safe な上限付き payload に収めました (#5059、#4336 の follow-up)** — 既定の 25-tool `tools/list` response を 64 KiB 以内に保ちながら、authoritative な呼び出し schema、安全上重要な提案 guidance、決定的な標準 pagination、完全定義の on-demand 取得、section ごとの UTF-8 size telemetry を維持します。initialize guidance も短縮し、詳細 workflow は互換性のある prompt へ誘導します。
2 changes: 2 additions & 0 deletions src/CodeIndex/Mcp/McpServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ public partial class McpServer : IDisposable
internal const int MaxResourceReadCursorCharacters = 128;
internal const int DefaultToolsListPageSize = 25;
internal const int MaxToolsListPageSize = 25;
internal const int DefaultToolsListResponseByteBudget = 64 * 1024;
internal const int DefaultInitializeInstructionsByteBudget = 2 * 1024;
internal const int MaxToolsListNameFilters = 24;
internal const int MaxToolsListNameCharacters = 128;
internal const int MaxToolsListCursorCharacters = 8_192;
Expand Down
Loading
Loading