agentic-community / agentic-community/mcp-gateway-registry

PATCH /api/servers/{path} fails and uses non-atomic full-card write on MongoDB CE

オープン
#1,716 コメント 1 件 リアクション 1 件 担当者 0 名 GitHub で見る
主要言語
Python
スター
912
フォーク
234
平均マージ
1日 11時間
マージ済み PR(30日)
62

説明

## Observed

On registry image version 1.29.0 / source revision `66d1945b6e91531512f44649e36a6bfc5c798af2`, an authenticated registry-admin M2M request to `PATCH /api/servers/{path}` returns HTTP 500 with `Failed to save server` for a description-only JSON merge patch. The card exists and is readable.

There is a second, independent correctness problem at that revision. `patch_server_endpoint` reads the complete card and merges the narrow client payload, then `server_service.update_server` reaches a Mongo repository update that performs an unconditional full-card `$set`. A concurrent egress OAuth, credential, or other card update can be overwritten even though the client omitted that field.

This blocks Git reconciliation of existing-card metadata and tool inventory. A full-card PUT has the same lost-update problem. A client-side `If-Match` check before the repository call is not race-proof unless the compare participates atomically in the repository write.

## Expected

A description-only PATCH returns 2xx and persists only that field. The same endpoint accepts `tool_list` / `num_tools` while preserving absent and concurrently updated auth, OAuth, egress, credential, and server-managed fields.

The persistence primitive must be either:

- an atomic field-scoped `$set` containing only fields present in the validated patch; or
- a repository-level compare-and-set whose version/revision predicate and write are one atomic database operation.

## Relevant source path

`registry/api/server_routes.py::patch_server_endpoint` reads and merges the card before `server_service.update_server(path, merged)`. The MongoDB CE repository then performs the write; the current route collapses a false return to the 500 and does not expose the underlying exception.

## Acceptance

- description-only PATCH succeeds as an admin identity
- tool-list growth succeeds
- the repository write is field-scoped or atomic-CAS, not read/merge plus unconditional full-card `$set`
- a concurrent update to an omitted credential/OAuth/egress field cannot be lost (persistence-level concurrency regression test)
- any `If-Match`/revision contract is enforced in the same repository operation as the write
- a repeated identical PATCH is harmless
- focused MongoDB CE route and repository regression coverage

コントリビューションガイド

コントリビューションガイドを開く

調査の方向性

Start at `registry/api/server_routes.py` in `patch_server_endpoint`, then follow `server_service.update_server` to the MongoDB CE repository write path doing unconditional full-card `$set`. Next inspect existing server PATCH/PUT tests and run the MongoCE route/repository regression tests for this flow. Done when tests confirm description-only `PATCH /api/servers/{path}` succeeds, writes only requested fields via field-scoped/CAS semantics, preserves concurrent updates to omitted credential/OAuth/egress fields, and repeated identical PATCH is harmless.

索引モデルが issue の本文から書いたものです。

評価

技術スタック
mongodb, python
領域
backend-api-design, databases
issue の種類
バグ
難易度
3/5
見積もり時間
1〜2日
活発さ
活発
明瞭さ
おおむね明確
初心者へのやさしさ
64/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。