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
19 changes: 15 additions & 4 deletions USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,12 @@ Recipe runs support text output, `--json` / `--format json`, and
`--format issue-drafts`; `--list-recipes` supports text or JSON. Other search
export formats and `--json=array` are rejected for recipe modes because recipe
output is grouped by query or list metadata.
The MCP `search` tool exposes the same recipe surface with
`{"listRecipes":true}` for discovery and `{"recipe":"risky-code"}` for
execution. Set `CDIDX_SEARCH_RECIPE_PATHS` to one or more JSON files separated
by the platform path separator to add configured recipe sources; each file may
be a recipe array or `{ "recipes": [...] }`, and invalid sources are reported as
bounded `recipe_source_diagnostics`.
For triage automation, `--format issue-drafts` emits draft issue objects with
titles, labels, evidence paths, Markdown bodies, and duplicate-preflight
metadata. `--open-issues <path>` accepts an open-issue JSON list such as
Expand Down Expand Up @@ -2214,7 +2220,7 @@ For HTTP, `CDIDX_MCP_HTTP_TOKEN` is the preferred bearer secret. If it is
unset, HTTP falls back to `CDIDX_MCP_AUTH_TOKEN` as the bearer secret, and
clients still authenticate with `Authorization: Bearer <token>`.

Each HTTP `POST /` carries one JSON-RPC frame in the request body, the matching response is returned in the same HTTP body (`200 OK`, `application/json`), and notifications return `204 No Content`. `GET /events` opens a `text/event-stream` channel for server-to-client frames; the server emits no unsolicited JSON-RPC frames unless keep-alive notifications are opted in with `CDIDX_MCP_KEEP_ALIVE_INTERVAL_S`. Accepted keep-alive values are finite seconds from `1` to `300`; invalid or out-of-range values leave keep-alive disabled with a `stderr` warning. The stream is independent and does not block normal POST requests. Non-POST verbs on `/` return `405 Method Not Allowed` with `Allow: POST`. Request bodies are capped at 1,000,000 bytes by default and oversized requests return `413 Payload Too Large`; the pending POST queue and accepted handler tasks are capped at 64 by default, and concurrent `/events` streams are capped at 16. Full queues, handler pools, or stream slots return `429 Too Many Requests` with `Retry-After: 1`. Tune those positive-integer limits with `CDIDX_MCP_HTTP_MAX_REQUEST_BYTES`, `CDIDX_MCP_HTTP_MAX_QUEUE_DEPTH`, `CDIDX_MCP_HTTP_MAX_CONCURRENT_HANDLERS`, and `CDIDX_MCP_HTTP_MAX_EVENT_STREAMS`; accepted ranges are `1..16777216` bytes and `1..1024` for each count limit. Invalid non-positive or non-numeric values fall back to the defaults, while values above those maximums are rejected before the listener starts. Idle event streams receive minimal SSE comment heartbeats so disconnected clients release their stream slots. When the persistent lifecycle log is enabled, HTTP mode also writes one `mcp_http_request` record per request with method, path, status, duration, auth outcome, remote peer, correlation id, and JSON-RPC request id when available. Method, path, remote peer, and request id fields are capped at 256 characters with a `...<truncated>` marker. Request and response bodies are not logged.
Each HTTP `POST /` carries one JSON-RPC frame in the request body, the matching response is returned in the same HTTP body (`200 OK`, `application/json`), and notifications return `204 No Content`. `GET /events` opens a `text/event-stream` channel for server-to-client frames; multiple concurrent clients can hold `/events`, and server notifications are broadcast to every connected stream. Event responses include `X-Accel-Buffering: no` and a per-stream `X-Cdidx-Mcp-Event-Stream-Id`. The server emits no unsolicited JSON-RPC frames unless keep-alive notifications are opted in with `CDIDX_MCP_KEEP_ALIVE_INTERVAL_S`. Accepted keep-alive values are finite seconds from `1` to `300`; invalid or out-of-range values leave keep-alive disabled with a `stderr` warning. The stream is independent and does not block normal POST requests. Non-POST verbs on `/` return `405 Method Not Allowed` with `Allow: POST`. Request bodies are capped at 1,000,000 bytes by default and oversized requests return `413 Payload Too Large`; the pending POST queue and accepted handler tasks are capped at 64 by default, and concurrent `/events` streams are capped at 16. Full queues, handler pools, or stream slots return `429 Too Many Requests` with `Retry-After: 1`. Tune those positive-integer limits with `CDIDX_MCP_HTTP_MAX_REQUEST_BYTES`, `CDIDX_MCP_HTTP_MAX_QUEUE_DEPTH`, `CDIDX_MCP_HTTP_MAX_CONCURRENT_HANDLERS`, and `CDIDX_MCP_HTTP_MAX_EVENT_STREAMS`; accepted ranges are `1..16777216` bytes and `1..1024` for each count limit. Invalid non-positive or non-numeric values fall back to the defaults, while values above those maximums are rejected before the listener starts. `/healthz` includes `http_event_stream_count`, `http_event_stream_limit`, `http_max_concurrent_handlers`, and `http_queued_request_count` for transport diagnostics. Idle event streams receive minimal SSE comment heartbeats so disconnected clients release their stream slots. When the persistent lifecycle log is enabled, HTTP mode also writes one `mcp_http_request` record per request with method, path, status, duration, auth outcome, remote peer, correlation id, and JSON-RPC request id when available. Method, path, remote peer, and request id fields are capped at 256 characters with a `...<truncated>` marker. Request and response bodies are not logged.

Security defaults:

Expand Down Expand Up @@ -2247,7 +2253,7 @@ Filter parsing also warns on `stderr` when an allow/deny variable is empty, cont

#### MCP roots and sampling

`cdidx mcp` advertises roots and sampling support during `initialize`. When the client supports roots, `index` refreshes `roots/list` and rejects paths outside the granted client roots. `suggest_improvement` uses `sampling/createMessage` to extract an optional one-line title and tag list before storing the raw suggestion. Sampling prompts are byte-bounded, long fields are clamped to one-line summaries, and `toolInvocationContext` is summarized without sending its raw content to the sampling client. Set `CDIDX_MCP_SAMPLING=0` (or `false` / `off`) to disable server-to-client sampling requests.
`cdidx mcp` advertises roots and sampling support during `initialize`. When the client supports roots, `index` refreshes `roots/list` and rejects paths outside the granted client roots. `suggest_improvement` only calls `sampling/createMessage` when the client advertises sampling and `CDIDX_MCP_SAMPLING` is explicitly opted in with `1`, `true`, `yes`, or `on`; unset, opt-out, and unrecognized values fail closed and return a bounded `sampling_diagnostic` in the tool result. When enabled, sampling extracts an optional one-line title and tag list before storing the raw suggestion. Sampling prompts are byte-bounded, long fields are clamped to one-line summaries, and `toolInvocationContext` is summarized without sending its raw content to the sampling client.

### Why cdidx over grep/ripgrep for AI workflows?

Expand Down Expand Up @@ -3276,6 +3282,11 @@ recipe run が対応する形式は text output、`--json` / `--format json`、
`--format issue-drafts` です。`--list-recipes` は text または JSON に対応します。
その他の search export format と `--json=array` は、recipe output が query または
list metadata ごとに grouped されるため usage error で拒否します。
MCP `search` tool では `{"listRecipes":true}` で recipe を発見し、
`{"recipe":"risky-code"}` で実行できます。`CDIDX_SEARCH_RECIPE_PATHS` に
platform path separator 区切りの JSON file を指定すると、設定済み recipe source を
追加できます。各 file は recipe array または `{ "recipes": [...] }` を受け付け、
不正な source は bounded な `recipe_source_diagnostics` として報告されます。
triage automation では `--format issue-drafts` を使うと、title、label、evidence path、
Markdown body、duplicate-preflight metadata を持つ issue draft object を出力します。
`--open-issues <path>` は `gh issue list --state open --json number,title,labels,url`
Expand Down Expand Up @@ -4555,7 +4566,7 @@ HTTP では `CDIDX_MCP_HTTP_TOKEN` が優先の bearer secret です。未設定
`CDIDX_MCP_AUTH_TOKEN` を bearer secret として fallback し、クライアントは引き続き
`Authorization: Bearer <token>` で認証します。

HTTP の `POST /` 1 件が JSON-RPC フレーム 1 件に対応し、応答は同じ HTTP レスポンスのボディに `200 OK` / `application/json` で返ります。通知は `204 No Content` です。`GET /events` はサーバー→クライアントフレーム用の `text/event-stream` channel を開きます。server-initiated JSON-RPC frame は `CDIDX_MCP_KEEP_ALIVE_INTERVAL_S` で keep-alive notification を opt-in した場合だけ送信されます。受理される値は有限な `1`〜`300` 秒で、不正値や範囲外の値では `stderr` に警告を出して keep-alive を無効のままにします。この stream は独立しており通常の POST リクエストを塞ぎません。`/` への POST 以外は `405 Method Not Allowed`(`Allow: POST` 付き)です。リクエスト本文は既定で 1,000,000 bytes までに制限され、超過時は `413 Payload Too Large` を返します。保留中 POST queue と受理済み handler task は既定で 64 件まで、同時 `/events` stream は既定で 16 件までに制限されます。queue、handler pool、stream slot が満杯の場合は `Retry-After: 1` 付きの `429 Too Many Requests` を返します。正の整数の `CDIDX_MCP_HTTP_MAX_REQUEST_BYTES`、`CDIDX_MCP_HTTP_MAX_QUEUE_DEPTH`、`CDIDX_MCP_HTTP_MAX_CONCURRENT_HANDLERS`、`CDIDX_MCP_HTTP_MAX_EVENT_STREAMS` で調整でき、受理範囲は本文が `1..16777216` bytes、各件数 limit が `1..1024` 件です。正でない値や数値でない値は既定にフォールバックし、最大値を超える値は listener 起動前に拒否されます。idle event stream には最小限の SSE comment heartbeat を送り、切断済み client の stream slot を解放します。永続 lifecycle log が有効な場合、HTTP mode はリクエストごとに `mcp_http_request` レコードも出力し、method、path、status、duration、auth outcome、remote peer、correlation id、利用可能な JSON-RPC request id を記録します。method、path、remote peer、request id は 256 文字を上限に `...<truncated>` marker 付きで切り詰めます。リクエスト/レスポンス本文は記録しません。
HTTP の `POST /` 1 件が JSON-RPC フレーム 1 件に対応し、応答は同じ HTTP レスポンスのボディに `200 OK` / `application/json` で返ります。通知は `204 No Content` です。`GET /events` はサーバー→クライアントフレーム用の `text/event-stream` channel を開きます。複数 client が同時に `/events` を保持でき、server notification は接続中の全 stream に broadcast されます。event response には `X-Accel-Buffering: no` と stream ごとの `X-Cdidx-Mcp-Event-Stream-Id` が付きます。server-initiated JSON-RPC frame は `CDIDX_MCP_KEEP_ALIVE_INTERVAL_S` で keep-alive notification を opt-in した場合だけ送信されます。受理される値は有限な `1`〜`300` 秒で、不正値や範囲外の値では `stderr` に警告を出して keep-alive を無効のままにします。この stream は独立しており通常の POST リクエストを塞ぎません。`/` への POST 以外は `405 Method Not Allowed`(`Allow: POST` 付き)です。リクエスト本文は既定で 1,000,000 bytes までに制限され、超過時は `413 Payload Too Large` を返します。保留中 POST queue と受理済み handler task は既定で 64 件まで、同時 `/events` stream は既定で 16 件までに制限されます。queue、handler pool、stream slot が満杯の場合は `Retry-After: 1` 付きの `429 Too Many Requests` を返します。正の整数の `CDIDX_MCP_HTTP_MAX_REQUEST_BYTES`、`CDIDX_MCP_HTTP_MAX_QUEUE_DEPTH`、`CDIDX_MCP_HTTP_MAX_CONCURRENT_HANDLERS`、`CDIDX_MCP_HTTP_MAX_EVENT_STREAMS` で調整でき、受理範囲は本文が `1..16777216` bytes、各件数 limit が `1..1024` 件です。正でない値や数値でない値は既定にフォールバックし、最大値を超える値は listener 起動前に拒否されます。`/healthz` は transport diagnostic として `http_event_stream_count`、`http_event_stream_limit`、`http_max_concurrent_handlers`、`http_queued_request_count` を含みます。idle event stream には最小限の SSE comment heartbeat を送り、切断済み client の stream slot を解放します。永続 lifecycle log が有効な場合、HTTP mode はリクエストごとに `mcp_http_request` レコードも出力し、method、path、status、duration、auth outcome、remote peer、correlation id、利用可能な JSON-RPC request id を記録します。method、path、remote peer、request id は 256 文字を上限に `...<truncated>` marker 付きで切り詰めます。リクエスト/レスポンス本文は記録しません。

セキュリティ既定:

Expand Down Expand Up @@ -4588,7 +4599,7 @@ filter 解析では、allow / deny 変数が空、CSV 内に空 entry がある

#### MCP roots と sampling

`cdidx mcp` は `initialize` で roots と sampling support を広告します。クライアントが roots をサポートする場合、`index` は `roots/list` を更新し、許可された client root の外にある path を拒否します。`suggest_improvement` は raw suggestion を保存する前に `sampling/createMessage` で任意の 1 行タイトルとタグ一覧を抽出します。sampling prompt は byte 上限内に収められ、長い field は 1 行 summary に切り詰められ、`toolInvocationContext` は raw 内容を sampling client に送らず summary 化されます。server-to-client sampling request を無効化するには `CDIDX_MCP_SAMPLING=0`(または `false` / `off`)を設定してください
`cdidx mcp` は `initialize` で roots と sampling support を広告します。クライアントが roots をサポートする場合、`index` は `roots/list` を更新し、許可された client root の外にある path を拒否します。`suggest_improvement` は、クライアントが sampling を広告し、かつ `CDIDX_MCP_SAMPLING` が `1`、`true`、`yes`、`on` のいずれかで明示 opt-in された場合だけ `sampling/createMessage` を呼びます。未設定、opt-out、不明な値は fail closed になり、tool result に bounded な `sampling_diagnostic` を返します。有効な場合は raw suggestion を保存する前に任意の 1 行タイトルとタグ一覧を抽出します。sampling prompt は byte 上限内に収められ、長い field は 1 行 summary に切り詰められ、`toolInvocationContext` は raw 内容を sampling client に送らず summary 化されます。

### AIワークフローで grep/ripgrep より cdidx が優れる理由

Expand Down
16 changes: 16 additions & 0 deletions changelog.d/unreleased/3382.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
category: changed
issues:
- 3382
affected:
- src/CodeIndex/Mcp/McpToolArgumentContracts.cs
- src/CodeIndex/Mcp/McpToolHandlers.cs
---

## English

- **MCP tool argument contracts now live in a focused module (#3382)** — The server keeps tool-name and argument allow-list validation separate from handler execution so the MCP surface is easier to review and maintain.

## 日本語

- **MCP tool argument contract を専用 module に分離しました (#3382)** — tool name と argument allow-list の検証を handler 実行から分け、MCP surface を確認・保守しやすくしました。
17 changes: 17 additions & 0 deletions changelog.d/unreleased/3405.security.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
category: security
issues:
- 3405
affected:
- src/CodeIndex/Mcp/McpToolHandlers.cs
- tests/CodeIndex.Tests/McpServerTests.cs
- USER_GUIDE.md
---

## English

- **MCP suggestion sampling now requires explicit opt-in (#3405)** — `suggest_improvement` only sends `sampling/createMessage` when `CDIDX_MCP_SAMPLING` is set to an affirmative value, and disabled or invalid settings return bounded sampling diagnostics instead of calling the client.

## 日本語

- **MCP suggestion sampling が明示 opt-in 必須になりました (#3405)** — `suggest_improvement` は `CDIDX_MCP_SAMPLING` が有効値の場合だけ `sampling/createMessage` を送信し、無効または不正な設定では client を呼ばず bounded な sampling diagnostic を返します。
18 changes: 18 additions & 0 deletions changelog.d/unreleased/3522.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
category: added
issues:
- 3522
affected:
- src/CodeIndex/Mcp/HttpMcpTransport.cs
- src/CodeIndex/Mcp/McpServer.cs
- tests/CodeIndex.Tests/HttpMcpTransportTests.cs
- USER_GUIDE.md
---

## English

- **HTTP MCP multi-client SSE fan-out is now observable (#3522)** — event streams include proxy buffering and per-stream id headers, `/healthz` reports HTTP transport counters, and regression coverage verifies progress notifications reach multiple concurrent `/events` clients.

## 日本語

- **HTTP MCP multi-client SSE fan-out を確認しやすくしました (#3522)** — event stream に proxy buffering と stream id header を追加し、`/healthz` が HTTP transport counter を返し、progress notification が複数の同時 `/events` client に届くことを regression test で検証します。
20 changes: 20 additions & 0 deletions changelog.d/unreleased/3545.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
category: added
issues:
- 3545
affected:
- src/CodeIndex/Cli/SearchAuditRecipes.cs
- src/CodeIndex/Mcp/McpToolArgumentContracts.cs
- src/CodeIndex/Mcp/McpToolDefinitions.cs
- src/CodeIndex/Mcp/McpToolHandlers.cs
- tests/CodeIndex.Tests/McpServerTests.cs
- USER_GUIDE.md
---

## English

- **MCP search can list and run audit recipes (#3545)** — `search` now accepts `listRecipes:true` and `recipe:"name"`, and `CDIDX_SEARCH_RECIPE_PATHS` adds bounded JSON recipe sources with diagnostics for invalid files.

## 日本語

- **MCP search が audit recipe の一覧・実行に対応しました (#3545)** — `search` は `listRecipes:true` と `recipe:"name"` を受け付け、`CDIDX_SEARCH_RECIPE_PATHS` で bounded な JSON recipe source を追加し、不正 file の diagnostic を返せます。
Loading
Loading