From 8821494fac4958de8c763c6f5371057c7db7fb7d Mon Sep 17 00:00:00 2001 From: Widthdom Date: Mon, 25 May 2026 12:28:32 +0900 Subject: [PATCH 1/5] Add MCP tool examples (#1810) --- changelog.d/unreleased/1810.added.md | 16 +++++++ src/CodeIndex/Mcp/McpServer.cs | 63 +++++++++++++++++++++++++++- 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 changelog.d/unreleased/1810.added.md diff --git a/changelog.d/unreleased/1810.added.md b/changelog.d/unreleased/1810.added.md new file mode 100644 index 0000000000..e5421185eb --- /dev/null +++ b/changelog.d/unreleased/1810.added.md @@ -0,0 +1,16 @@ +--- +category: added +issues: + - 1810 +affected: + - src/CodeIndex/Mcp/McpServer.cs + - tests/CodeIndex.Tests/McpServerTests.cs +--- + +## English + +- **MCP tools now publish inline call examples (#1810)** — every `tools/list` tool definition includes an `examples` array with a canonical `tools/call` request shape. + +## 日本語 + +- **MCP ツールが inline call example を公開するようになりました (#1810)** — `tools/list` の全ツール定義に、標準的な `tools/call` リクエスト形状を示す `examples` 配列を追加しました。 diff --git a/src/CodeIndex/Mcp/McpServer.cs b/src/CodeIndex/Mcp/McpServer.cs index b1681089d5..83f158b3b5 100644 --- a/src/CodeIndex/Mcp/McpServer.cs +++ b/src/CodeIndex/Mcp/McpServer.cs @@ -2480,13 +2480,74 @@ private static JsonObject CreateToolDefinition(string name, string description, { ["name"] = name, ["description"] = AppendLanguageSupportClause(name, description), - ["inputSchema"] = inputSchema + ["inputSchema"] = inputSchema, + ["examples"] = BuildToolExamples(name), }; if (annotations != null) def["annotations"] = annotations; return def; } + private static JsonArray BuildToolExamples(string name) + { + var args = name switch + { + "search" => new JsonObject { ["query"] = "Run", ["lang"] = "csharp", ["limit"] = 5 }, + "definition" => new JsonObject { ["query"] = "App", ["exactName"] = true }, + "references" => new JsonObject { ["query"] = "Run", ["kind"] = "call" }, + "callers" => new JsonObject { ["query"] = "Run", ["rankBy"] = "weighted" }, + "callees" => new JsonObject { ["query"] = "App.Run" }, + "symbols" => new JsonObject { ["query"] = "App", ["kind"] = "class" }, + "files" => new JsonObject { ["query"] = "app.cs", ["lang"] = "csharp" }, + "excerpt" => new JsonObject { ["path"] = "src/app.cs", ["startLine"] = 1, ["endLine"] = 5 }, + "find_in_file" => new JsonObject { ["path"] = "src/app.cs", ["query"] = "Run", ["before"] = 1, ["after"] = 1 }, + "map" => new JsonObject { ["limit"] = 5, ["excludeTests"] = true }, + "analyze_symbol" => new JsonObject { ["query"] = "Run", ["includeBody"] = true }, + "impact_analysis" => new JsonObject { ["query"] = "Run", ["maxHops"] = 2, ["withPaths"] = true }, + "status" => new JsonObject(), + "outline" => new JsonObject { ["path"] = "src/app.cs" }, + "deps" => new JsonObject { ["path"] = "src/", ["reverse"] = false, ["limit"] = 10 }, + "languages" => new JsonObject(), + "validate" => new JsonObject { ["kind"] = "line_too_long" }, + "ping" => new JsonObject(), + "batch_query" => new JsonObject + { + ["queries"] = new JsonArray + { + new JsonObject { ["tool"] = "search", ["arguments"] = new JsonObject { ["query"] = "Run", ["limit"] = 3 } }, + new JsonObject { ["tool"] = "definition", ["arguments"] = new JsonObject { ["query"] = "App", ["limit"] = 3 } }, + }, + }, + "index" => new JsonObject { ["path"] = ".", ["rebuild"] = false }, + "backfill_fold" => new JsonObject(), + "symbol_hotspots" => new JsonObject { ["lang"] = "csharp", ["limit"] = 10 }, + "unused_symbols" => new JsonObject { ["lang"] = "csharp", ["limit"] = 10 }, + "suggest_improvement" => new JsonObject + { + ["category"] = "output_format", + ["description"] = "The tool response should make truncation easier to detect.", + }, + _ => new JsonObject(), + }; + + return new JsonArray + { + new JsonObject + { + ["request"] = new JsonObject + { + ["method"] = "tools/call", + ["params"] = new JsonObject + { + ["name"] = name, + ["arguments"] = args, + }, + }, + ["response_excerpt"] = "A successful MCP tool result includes content and, when available, structuredContent.", + }, + }; + } + private static string AppendLanguageSupportClause(string name, string description) { var clause = name switch From 7eff74a73f81ec506280214eb1d6dc9d1a6bbc61 Mon Sep 17 00:00:00 2001 From: Widthdom Date: Mon, 25 May 2026 12:28:40 +0900 Subject: [PATCH 2/5] Add MCP response shape tests (#1820) --- changelog.d/unreleased/1820.internal.md | 15 +++++++ tests/CodeIndex.Tests/McpServerTests.cs | 57 +++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 changelog.d/unreleased/1820.internal.md diff --git a/changelog.d/unreleased/1820.internal.md b/changelog.d/unreleased/1820.internal.md new file mode 100644 index 0000000000..f6c2118e5c --- /dev/null +++ b/changelog.d/unreleased/1820.internal.md @@ -0,0 +1,15 @@ +--- +category: internal +issues: + - 1820 +affected: + - tests/CodeIndex.Tests/McpServerTests.cs +--- + +## English + +- **MCP response shape tests now cover tool schemas and examples (#1820)** — tests assert the shared `tools/list` schema/example contract and representative MCP result envelopes. + +## 日本語 + +- **MCP response shape テストが tool schema と example を確認するようになりました (#1820)** — `tools/list` の共通 schema/example 契約と代表的な MCP result envelope をテストで固定しました。 diff --git a/tests/CodeIndex.Tests/McpServerTests.cs b/tests/CodeIndex.Tests/McpServerTests.cs index a0c57a18f1..ce243d430b 100644 --- a/tests/CodeIndex.Tests/McpServerTests.cs +++ b/tests/CodeIndex.Tests/McpServerTests.cs @@ -617,6 +617,63 @@ public void Initialize_ReturnsToolsCapability() Assert.False(response["result"]!["capabilities"]!["tools"]!["listChanged"]!.GetValue()); } + [Fact] + public void ToolsList_EachToolPublishesSchemaAndExampleContract() + { + var request = JsonNode.Parse("""{"jsonrpc":"2.0","id":1,"method":"tools/list"}""")!; + var response = _server.HandleMessage(request)!; + + var tools = response["result"]!["tools"]!.AsArray(); + Assert.Equal(24, tools.Count); + foreach (var tool in tools) + { + Assert.False(string.IsNullOrWhiteSpace(tool!["name"]!.GetValue())); + Assert.False(string.IsNullOrWhiteSpace(tool["description"]!.GetValue())); + Assert.Equal("object", tool["inputSchema"]!["type"]!.GetValue()); + + var examples = tool["examples"]!.AsArray(); + Assert.NotEmpty(examples); + foreach (var example in examples) + { + Assert.Equal("tools/call", example!["request"]!["method"]!.GetValue()); + Assert.Equal(tool["name"]!.GetValue(), example["request"]!["params"]!["name"]!.GetValue()); + Assert.NotNull(example["request"]!["params"]!["arguments"]); + Assert.False(string.IsNullOrWhiteSpace(example["response_excerpt"]!.GetValue())); + } + } + } + + [Theory] + [InlineData("ping", """{}""")] + [InlineData("status", """{}""")] + [InlineData("search", """{"query":"Run","limit":5}""")] + public void ToolCall_ResponseShape_HasStableMcpResultEnvelope(string toolName, string argumentsJson) + { + var request = new JsonObject + { + ["jsonrpc"] = "2.0", + ["id"] = 1, + ["method"] = "tools/call", + ["params"] = new JsonObject + { + ["name"] = toolName, + ["arguments"] = JsonNode.Parse(argumentsJson), + }, + }; + var response = _server.HandleMessage(request)!; + + Assert.Equal("2.0", response["jsonrpc"]!.GetValue()); + Assert.Equal(1, response["id"]!.GetValue()); + Assert.Null(response["error"]); + + var result = response["result"]!; + Assert.NotNull(result["content"]); + Assert.Equal("text", result["content"]!.AsArray()[0]!["type"]!.GetValue()); + Assert.NotNull(result["structuredContent"]); + Assert.NotNull(result["_meta"]!["request_id"]); + Assert.NotNull(result["_meta"]!["correlation_id"]); + } + [Fact] public void Initialize_ReturnsInstructions() { From efbf472afaeee7a9bf306a728b6118f248671131 Mon Sep 17 00:00:00 2001 From: Widthdom Date: Mon, 25 May 2026 12:28:52 +0900 Subject: [PATCH 3/5] Document JSON and MCP stability contract (#1902) --- INTEGRATION_POLICY.md | 22 ++++++++++++++++++++++ changelog.d/unreleased/1902.docs.md | 15 +++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 changelog.d/unreleased/1902.docs.md diff --git a/INTEGRATION_POLICY.md b/INTEGRATION_POLICY.md index dde2179837..ae0d10e3d8 100644 --- a/INTEGRATION_POLICY.md +++ b/INTEGRATION_POLICY.md @@ -82,6 +82,28 @@ CLI payload can be substituted for an MCP payload without adaptation. Additive fields may appear on either surface in minor releases; consumers should ignore unknown fields and prefer documented fields over positional assumptions. +### JSON and MCP stability contract + +CodeIndex follows SemVer for the supported integration surfaces listed above. +Patch releases may fix incorrect values while preserving documented field names +and value types. Minor releases may add fields, tools, tool arguments, examples, +annotations, error `data` members, or enum values when existing consumers can +ignore them safely. Breaking removals, required-field additions, field renames, +or incompatible type changes require a major release unless the old shape was +explicitly documented as preview. + +Deprecations are announced in the changelog before removal. Stable fields keep a +minimum one-major-release compatibility window; preview fields may change in a +minor release, but the release notes must say so. Tool definitions can expose +additional metadata such as examples and annotations without changing the +meaning of existing `inputSchema` entries. + +Consumers should branch on documented structural fields, not prose. For MCP +errors, route on `error.code` and structured `error.data.category` when present; +do not parse `error.message`, which is diagnostic text and may be clarified in +minor or patch releases. For CLI automation, route on documented exit codes and +JSON fields rather than human output. + | Query surface | CLI `--json` shape | MCP response shape | Compatibility notes | |---|---|---|---| | `search` | One JSON object per result, with CLI query metadata such as `api_version`, `query`, path, line range, snippet, highlights, and truncation details. | Tool result content contains equivalent search-result objects using MCP serialization and tool-call framing. | Result semantics are shared, but the outer envelope and field casing follow the called surface. | diff --git a/changelog.d/unreleased/1902.docs.md b/changelog.d/unreleased/1902.docs.md new file mode 100644 index 0000000000..670f3c62e5 --- /dev/null +++ b/changelog.d/unreleased/1902.docs.md @@ -0,0 +1,15 @@ +--- +category: docs +issues: + - 1902 +affected: + - INTEGRATION_POLICY.md +--- + +## English + +- **Documented the JSON and MCP stability contract (#1902)** — the integration policy now describes SemVer expectations, additive changes, breaking changes, deprecation windows, and client routing guidance. + +## 日本語 + +- **JSON / MCP の安定性契約を文書化しました (#1902)** — integration policy に SemVer 期待値、additive change、breaking change、deprecation window、client routing guidance を追記しました。 From 90afb937b777f44948dd6a4b3fa5179432a0f4f9 Mon Sep 17 00:00:00 2001 From: Widthdom Date: Mon, 25 May 2026 12:29:40 +0900 Subject: [PATCH 4/5] Clarify MCP tool inventory docs (#1911) --- USER_GUIDE.md | 4 ++-- changelog.d/unreleased/1911.docs.md | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 changelog.d/unreleased/1911.docs.md diff --git a/USER_GUIDE.md b/USER_GUIDE.md index 66aacaff56..5b465c1d9a 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -30,7 +30,7 @@ cdidx suggestions list # Review local AI feedback history cdidx mcp # Start MCP server for AI tools ``` -78 languages supported. 24 MCP tools. Incremental updates. Zero config. +78 languages supported. 24 registered MCP tools. Incremental updates. Zero config. | Topic | Link | |---|---| @@ -1686,7 +1686,7 @@ OpenAI Codex CLI (`codex.json` or `~/.codex/config.json`): Once configured, the AI can directly call these tools: -The MCP `tools/list` descriptions include compact English/Japanese usage examples for the primary search and navigation tools, so AI clients can discover valid argument shapes directly from the server response. +The MCP `tools/list` response includes an `examples` array for every registered tool, so AI clients can discover valid `tools/call` argument shapes directly from the server response. | Tool | Description | |---|---| diff --git a/changelog.d/unreleased/1911.docs.md b/changelog.d/unreleased/1911.docs.md new file mode 100644 index 0000000000..a61968b22e --- /dev/null +++ b/changelog.d/unreleased/1911.docs.md @@ -0,0 +1,15 @@ +--- +category: docs +issues: + - 1911 +affected: + - USER_GUIDE.md +--- + +## English + +- **Clarified the MCP tool count and inventory wording (#1911)** — the user guide now describes the count as registered MCP tools and points clients to the authoritative `tools/list` response. + +## 日本語 + +- **MCP tool count と inventory の表現を明確化しました (#1911)** — USER_GUIDE で registered MCP tools として件数を表現し、権威情報が `tools/list` response であることを明示しました。 From 20f5887ea3c29142eefc2e1c44ac47242c14aee3 Mon Sep 17 00:00:00 2001 From: Widthdom Date: Mon, 25 May 2026 12:29:47 +0900 Subject: [PATCH 5/5] Document MCP error response handling (#1978) --- USER_GUIDE.md | 20 ++++++++++++++++++++ changelog.d/unreleased/1978.docs.md | 15 +++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 changelog.d/unreleased/1978.docs.md diff --git a/USER_GUIDE.md b/USER_GUIDE.md index 5b465c1d9a..c0d0ae3759 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -1731,6 +1731,26 @@ Graph-oriented MCP tools such as `references`, `callers`, and `callees` also ret All MCP tools include `annotations` (`readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`) so AI clients can auto-approve safe read-only queries without prompting the user. +#### MCP error responses + +MCP JSON-RPC failures use the standard `error` object. Clients should route on +`error.code` and, when present, `error.data.category`; do not parse +`error.message`, which is human-facing diagnostic text. + +| Code | Meaning | Client action | +|---|---|---| +| `-32700` | Parse error or frame too large | Fix the JSON/frame size before retrying | +| `-32600` | Invalid JSON-RPC request | Fix request shape before retrying | +| `-32601` | Method not found or disabled tool | Check server version and `tools/list` | +| `-32602` | Invalid params, unknown tool, or bad protocol version | Fix arguments or negotiate a supported version | +| `-32603` | Internal error | Surface the failure and inspect server stderr | +| `-32000` | Rate limited | Retry after the reported delay | +| `-32001` | Permission denied | Provide the configured auth token | +| `-32010` | Index missing | Run `cdidx index ` first | +| `-32011` | Index stale/schema mismatch | Rebuild or refresh the index | +| `-32012` | Index corrupted/unreadable | Rebuild the index from source | +| `-32015` | Request cancelled | Retry if the client still needs the result | + #### Optional HTTP transport By default `cdidx mcp` speaks JSON-RPC over stdin/stdout, which is what every config example above uses. AI clients that prefer to keep one warm server running across many requests — instead of paying subprocess-spawn cost per call — can switch the transport to HTTP: diff --git a/changelog.d/unreleased/1978.docs.md b/changelog.d/unreleased/1978.docs.md new file mode 100644 index 0000000000..59e963515c --- /dev/null +++ b/changelog.d/unreleased/1978.docs.md @@ -0,0 +1,15 @@ +--- +category: docs +issues: + - 1978 +affected: + - USER_GUIDE.md +--- + +## English + +- **Documented MCP error response handling in the user guide (#1978)** — the MCP section now lists JSON-RPC error codes, meanings, and recommended client actions. + +## 日本語 + +- **USER_GUIDE に MCP error response の扱いを文書化しました (#1978)** — MCP セクションに JSON-RPC error code、意味、推奨される client action の表を追加しました。