Hacktoberfest 2026: as issues que os mantenedores marcaram para outubro, abertas e boas para iniciantes. Ver issues do Hacktoberfest

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

Aberta Para iniciantes
#1,174 0 comentários 1 reação 0 responsáveis Ver no GitHub

Mantenedores costumam responder em até 2 dias

@kamisheng já está trabalhando nisso.

Desde 12/10/2026.

  • #1175 de @kamisheng — aberto

Avaliação

Dificuldade
2/5
Tempo estimado
1-3 horas
Facilidade para iniciantes
75/100
Tipo de issue
Bug
Clareza
Claramente especificada
Status de atividade
Ativa
Stack de tecnologia
java
Domínio
api, backend

Direção de pesquisa

Encontre os cinco métodos listados: McpAsyncServerExchange#listRoots() e McpAsyncClient#listTools(), listResources(), listResourceTemplates() e listPrompts(). Leia as chamadas a reduce(seed, accumulator) e o fixture de teste existente para uma sessão simulada que retorna duas roots; verifique se cada inscrição retorna os mesmos resultados. O trabalho estará concluído quando os cinco métodos criarem um novo acumulador por inscrição e os testes cobrirem inscrições repetidas.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

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.

Linguagem predominante
Java
Estrelas
3.7k
Forks
1.2k
Merge médio
3h 38min
PRs com merge (30d)
5

Preparar o ambiente

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de modelcontextprotocol/java-sdk

Todas as issues de modelcontextprotocol/java-sdk

Issues semelhantes

Mais issues de Java

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.