Hacktoberfest 2026:維護者為十月標記出來的 issue,仍然開放、適合新手。 瀏覽 Hacktoberfest issue

[BUG] Re-subscribing the Mono returned by listTools/listResources/listResourceTemplates/listPrompts/listRoots duplicates the results

已關閉 適合新手
#1,174 0 則留言 1 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 1 天內回覆

@kamisheng 已經在處理了。

開始於 2026年10月12日。

  • #1175 來自 @kamisheng —— 未關閉

評估

難度
2/5
預估耗時
1-3 小時
新手友好度
75/100
Issue 類型
缺陷
描述清晰度
描述清楚
活躍度
活躍
技術堆疊
java
領域
api, backend

研究方向

找出列出的五個方法:McpAsyncServerExchange#listRoots(),以及 McpAsyncClient#listTools()、listResources()、listResourceTemplates() 和 listPrompts()。閱讀它們對 reduce(seed, accumulator) 的呼叫,以及用於回傳兩個 roots 的模擬工作階段之現有測試 fixture;確認每次訂閱都回傳相同結果。完成標準是五個方法都為每次訂閱建立新的累加器,且測試涵蓋重複訂閱。

由索引模型根據 Issue 內容生成。

描述

Bug description

The Mono returned by these methods is not safe to subscribe more than once: each
subscription appends to the same mutable accumulator created when the method was called,
so the results grow on every subscription.

Mono<McpSchema.ListRootsResult> listRoots = exchange.listRoots();
listRoots.block().roots().size();   // 2
listRoots.block().roots().size();   // 4  <- duplicated
listRoots.block().roots().size();   // 6

Affected methods (all use reduce(seed, accumulator) with a seed created at assembly
time):

  • McpAsyncServerExchange#listRoots()
  • McpAsyncClient#listTools()
  • McpAsyncClient#listResources()
  • McpAsyncClient#listResourceTemplates()
  • McpAsyncClient#listPrompts()
Steps to reproduce

Using the existing test fixture (McpAsyncServerExchange with a mocked session that
returns a single page of 2 roots):

Mono<McpSchema.ListRootsResult> listRoots = exchange.listRoots();

System.out.println(listRoots.block().roots().size());   // 2
System.out.println(listRoots.block().roots().size());   // 4
System.out.println(listRoots.block().roots().size());   // 6
Expected behavior

Every subscription starts from an empty accumulator and returns the same result (2 / 2 /
2). Re-subscribing a Mono is a supported Reactor pattern (retry, repeat, cache, reusing
the Mono in several downstream branches), and concurrent subscriptions currently race on
the shared ArrayList too.

Suggested fix

Flux#reduceWith(Supplier, BiFunction) creates the seed per subscription:

.reduceWith(() -> McpSchema.ListRootsResult.builder(new ArrayList<>()).build(),
        (allRootsResult, result) -> { ... })

.reduceWith(ArrayList<McpSchema.Tool>::new, (accumulated, result) -> { ... })

Happy to open a PR with the five call sites updated and tests if you agree with the
approach.

主要語言
Java
星號
3.7k
分支
1.2k
平均合併
7 小時 6 分鐘
30 天內合併 PR
8

環境準備

  • 沒有 Dockerfile 或 Docker Compose 檔案
  • 沒有 Pull Request 範本
  • 閱讀貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

modelcontextprotocol/java-sdk 的其他 Issue

查看 modelcontextprotocol/java-sdk 的全部 Issue

相似的 Issue

更多 Java Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。