Skip to content

temporal-spring-ai: discover MCP clients by type, not by bean name#2859

Open
donald-pinckney wants to merge 3 commits intomasterfrom
spring-ai/mcp-bean-lookup
Open

temporal-spring-ai: discover MCP clients by type, not by bean name#2859
donald-pinckney wants to merge 3 commits intomasterfrom
spring-ai/mcp-bean-lookup

Conversation

@donald-pinckney
Copy link
Copy Markdown
Contributor

What was changed

McpPlugin.getMcpClients() now calls ApplicationContext.getBeansOfType(McpSyncClient.class) instead of looking up the hard-coded bean name "mcpSyncClients". The unchecked cast from the old (List<McpSyncClient>) someObject path is gone; discovered bean names are logged alongside the count for easier debugging.

New McpPluginTest covers three cases via Mockito:

  • Two distinct McpSyncClient beans discovered by type both reach McpClientActivityImpl.
  • Zero beans leaves the worker queued for deferred registration; afterSingletonsInstantiated handles "still no beans" without crashing.
  • Beans that appear between initializeWorker and afterSingletonsInstantiated are picked up on the deferred attempt.

build.gradle gains spring-ai-mcp as a testImplementation so the tests can reference McpSyncClient directly for mocking. The main-scope dep stays compileOnly; nothing changes for users who don't use MCP.

Why?

The old bean-name lookup broke silently whenever Spring AI changed the name its MCP auto-configuration used (e.g. if mcpSyncClients ever got renamed, or if sync-vs-async support got refactored). It also ignored user-defined McpSyncClient beans declared outside Spring AI's auto-configuration. Type-based discovery is more robust, works with arbitrary user configuration, and removes an unchecked cast that could have misbehaved at runtime if someone had registered a differently-typed List bean at that name.

donald-pinckney and others added 2 commits April 21, 2026 15:56
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
McpPlugin.getMcpClients() now calls ApplicationContext.getBeansOfType(
McpSyncClient.class) instead of looking up the hard-coded bean name
"mcpSyncClients". The unchecked cast is removed; discovered bean names
are logged for easier debugging.

Tests: McpPluginTest exercises three cases via Mockito —
- two McpSyncClient beans discovered by type both reach
  McpClientActivityImpl;
- zero beans leaves the worker queued for deferred registration, and
  afterSingletonsInstantiated handles "still no beans" cleanly;
- beans that appear between initializeWorker and
  afterSingletonsInstantiated get picked up on the deferred attempt.

build.gradle: spring-ai-mcp added as a testImplementation so tests can
mock McpSyncClient directly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Planning scratchpad — not part of the shipped artifact. Removed before merge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@donald-pinckney donald-pinckney marked this pull request as ready for review April 22, 2026 19:52
@donald-pinckney donald-pinckney requested a review from a team as a code owner April 22, 2026 19:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant