Skip to main content
Back to Blog

Understand Spring AI Tool Mechanism in 5 Minutes: From @Tool Annotation to MCP Tool Bridging Full Chain

Introduction

โ€œWhy isnโ€™t my @Tool method being recognized?โ€

โ€œHow do MCP Server tools bridge to my local ChatClient?โ€

โ€œWhatโ€™s the relationship between ToolCallback and ToolCallbackProvider?โ€

These are common confusions for developers new to Spring AIโ€™s Tool mechanism.

Official documentation teaches you how to use it, but rarely explains how it works under the hood. The result is not knowing where to start troubleshooting when problems arise.

In this article, Iโ€™ll use plain language to help you understand Spring AI Toolโ€™s underlying runtime mechanism. After reading, youโ€™ll understand:

  • How a @Tool annotation becomes an AI-callable tool
  • The responsibilities and use cases for each type of Provider
  • The complete chain from tool registration to LLM invocation

Version Note (as of 2026-03-22): Spring AIโ€™s latest stable version is 1.1.3, and latest preview version is 2.0.0-M3 (released on 2026-03-17). 1.1.2 is also a stable version, just not the latest stable version as of 2026-03-22. This article is primarily based on the current official Reference/API documentation; for 2.0.0-M3 changes, Iโ€™ll mark them separately to avoid mixing โ€œstable version statusโ€ with โ€œpreview version changesโ€.

If your current project uses spring-ai-alibaba:1.1.2.0, note that its transitive org.springframework.ai dependency is still 1.1.2, not 1.1.3. So APIs like AugmentedToolCallback that are visible in 1.1.3 may not appear in your IDE yet.


1. Core Interfaces: ToolCallback and ToolCallbackProvider

Bottom line first: ToolCallback is a single tool, ToolCallbackProvider is a provider of tool collections.

1.1 ToolCallback: Abstraction of a Single Tool

ToolCallback is the smallest unit in Spring AIโ€™s tool system, representing a tool that can be called by an AI model.

public interface ToolCallback {
    // Tool definition: name, description, JSON Schema for input parameters
    ToolDefinition getToolDefinition();

    // Tool metadata: e.g., returnDirect controls whether results are returned directly
    ToolMetadata getToolMetadata();

    // Execute the tool, input is a JSON string
    String call(String toolInput);

    // Execute with context
    String call(String toolInput, ToolContext toolContext);
}

Its responsibilities are simple:

  1. Tell the AI what this tool is called, what it does, and what parameters it needs
  2. Receive JSON parameters from the AI, execute logic, return results

Two most common local implementations:

  • MethodToolCallback โ€” Wraps Java methods (used with @Tool annotation)
  • FunctionToolCallback โ€” Wraps functional interfaces (Function, Supplier, Consumer, BiFunction, etc.)

1.2 ToolCallbackProvider: Tool Factory

ToolCallbackProvider is responsible for providing tools in batches.

public interface ToolCallbackProvider {
    // Return all tool callbacks
    ToolCallback[] getToolCallbacks();
}

Its responsibility: Collect tools from different sources and expose them uniformly for ChatClient registration.


2. Five Providers: Four Source Types + One Enhancer

In the current official API, ToolCallbackProvider has 5 known implementations. The first four handle โ€œwhere tools come fromโ€, and the last one handles โ€œwrapping existing tools with enhancementsโ€.

ProviderTool SourceCharacteristics
StaticToolCallbackProviderStatic arraySimplest, immutable after construction, manually create fixed tool sets
MethodToolCallbackProvider@Tool annotated methodsAutomatically scans objects for @Tool methods and generates ToolCallbacks
SyncMcpToolCallbackProviderMCP synchronous clientConnects to remote MCP Server, automatically discovers and bridges tools
AsyncMcpToolCallbackProviderMCP asynchronous clientSimilar to Sync but uses async client; also implements getToolCallbacks(), plus provides reactive helper capabilities
AugmentedToolCallbackProviderEnhancement wrapper for existing toolsAppends input Schema extension fields to existing tools, e.g., additional structured metadata

3. MethodToolCallbackProvider: Local Annotation Scanning

This is the most commonly used approach, automatically generating tools through @Tool annotations.

@Service
public class WeatherService {

    @Tool(name = "getWeather", description = "Get weather for a specified city")
    public String getWeather(@JsonProperty("city") String city) {
        return city + ": Sunny, 25\u00B0C";
    }

    @Tool(name = "query_weather_by_city_date", description = "Query weather by city and date")
    public String queryByCityAndDate(
            @JsonProperty("city") String city,
            @JsonProperty("date") String date) {
        return city + " on " + date + ": Cloudy, 22\u00B0C";
    }
}

Registration method:

@Configuration
public class ToolConfig {

    @Bean
    public ToolCallbackProvider weatherTools(WeatherService weatherService) {
        return MethodToolCallbackProvider.builder()
                .toolObjects(weatherService)  // Pass the Service object
                .build();
    }
}

How it works:

MethodToolCallbackProvider uses reflection to scan all methods in weatherService, finds methods with @Tool annotation, and generates a MethodToolCallback for each method.

This example registers 2 tools:

  • getWeather โ€” Query weather by city
  • query_weather_by_city_date โ€” Query weather by city and date

4. How to Register Multiple Services?

toolObjects() accepts varargs, you can pass multiple objects:

@Bean
public ToolCallbackProvider allTools(
        WeatherService weatherService,
        OrderService orderService,
        TradeService tradeService,
        GoodsService goodsService) {

    return MethodToolCallbackProvider.builder()
            .toolObjects(weatherService, orderService, tradeService, goodsService)
            .build();
}

Method 2: Multiple Beans (Spring AI auto-merges)

@Bean
public ToolCallbackProvider weatherTools(WeatherService weatherService) {
    return MethodToolCallbackProvider.builder()
            .toolObjects(weatherService)
            .build();
}

@Bean
public ToolCallbackProvider orderTools(OrderService orderService) {
    return MethodToolCallbackProvider.builder()
            .toolObjects(orderService)
            .build();
}

If youโ€™re using Spring Bootโ€™s auto-configured MCP Server / MCP Client scenario, the framework collects these ToolCallbackProvider beans and merges them, achieving the same effect.

If youโ€™re manually building a ChatClient, you still need to explicitly pass the ToolCallback[] returned by these Providers to defaultToolCallbacks(...).


5. SyncMcpToolCallbackProvider: Remote Tool Bridging

This is the core of MCP development, wrapping remote MCP Server tools as local ToolCallbacks.

@Component
public class McpClientService {

    @Autowired
    private SyncMcpToolCallbackProvider toolCallbackProvider;

    @PostConstruct
    public void init() {
        // Get all tools from remote MCP servers
        ToolCallback[] toolCallbacks = toolCallbackProvider.getToolCallbacks();

        // Register to ChatClient
        this.chatClient = ChatClient.builder(chatModel)
                .defaultToolCallbacks(toolCallbacks)
                .build();
    }
}

What it does:

MCP servers configured in application.yml
         โ†“
Spring AI auto-configures SyncMcpToolCallbackProvider
         โ†“
Reads configuration, connects to each MCP Server (starts process or establishes HTTP connection)
         โ†“
Calls MCP's listTools API to get tool list
         โ†“
Wraps each remote tool as a local ToolCallback
         โ†“
Registers to ChatClient, LLM can call them

Result:

chatClient.prompt()
    .user("What's the weather in Beijing?")
    .call()
    .content();
// LLM automatically calls the remote mcp-server's getWeather tool
// Returns: "Beijing: Sunny, 25\u00B0C"

Sync vs Async:

  • SyncMcpToolCallbackProvider โ€” Uses McpSyncClient, getToolCallbacks() returns ToolCallback[]
  • AsyncMcpToolCallbackProvider โ€” Uses McpAsyncClient, also implements getToolCallbacks() returning ToolCallback[]; additionally provides asyncToolCallbacks(List<McpAsyncClient>) returning Flux<ToolCallback>

Note: Both can connect to multiple MCP Servers. Your choice depends on whether your application is synchronous or reactive. See Chapter 8 for details.


6. MCP Server vs Client: Each Has Its Role

Many beginners confuse this: Both MCP Server and Client use Providers, will they conflict?

The answer is no. They have a complementary relationship, each responsible for one side:

6.1 MCP Server Side: Two Main Paths Available Now

Path A: @McpTool annotation + annotation scanner
       โ†“
Directly exposed as MCP Tool (this is the approach currently recommended by the Boot Starter docs)

Path B: Spring AI ToolCallback path
@Service + @Tool method / ToolCallback Bean / ToolCallbackProvider Bean
       โ†“
Auto-converted to MCP Tool spec via tool-callback-converter
       โ†“
Exposed to clients via MCP protocol (stdio / SSE / Streamable-HTTP)

6.2 MCP Client Side: Consuming Tools

Connects to MCP Server
       โ†“
Gets tool list via MCP protocol (listTools)
       โ†“
SyncMcpToolCallbackProvider (remote tools โ†’ local ToolCallback)
       โ†“
Registers to ChatClient, enabling LLM to call them

6.3 One Diagram to Understand Both Sides

6.4 Simple Analogy

RoleAnalogyClasses Used
MCP ServerRestaurant (exposes menu items)@McpTool or ToolCallbackProvider
MCP ClientFood delivery platform (aggregates restaurants)SyncMcpToolCallbackProvider
  • A restaurant can either directly use @McpTool to produce its menu, or first produce ToolCallbacks, then have the Server Starter auto-convert them to MCP Tools
  • The delivery platform uses SyncMcpToolCallbackProvider to turn each restaurantโ€™s โ€œmenuโ€ into โ€œorderable itemsโ€ (local ToolCallbacks) for users

6.5 What If Server Side Doesnโ€™t Use MethodToolCallbackProvider?

A prerequisite here: This question only applies when you choose the @Tool โ†’ MethodToolCallbackProvider โ†’ MCP Tool path.

// Without MethodToolCallbackProvider
public class WeatherService {
    @Tool(name = "getWeather", description = "...")
    public String getWeather(String city) { ... }
}

Result: The @Tool annotation alone wonโ€™t automatically become an MCP Tool. If you havenโ€™t configured MethodToolCallbackProvider, nor wrapped it as another ToolCallback Bean / ToolCallbackProvider Bean, the clientโ€™s listTools will return an empty list.

But if you take the @McpTool + annotation scanner path, you donโ€™t need MethodToolCallbackProvider.


7. Complete Call Chain: From Registration to Execution

The following flow diagram uses the @Tool / ToolCallback โ†’ ChatClient โ†’ tool calling path as the main thread, connecting all stages:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        Registration Phase                        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

@Service + @Tool annotated methods                application.yml MCP config
       โ”‚                                              โ”‚
       โ–ผ                                              โ–ผ
MethodToolCallbackProvider                   SyncMcpToolCallbackProvider
       โ”‚                                              โ”‚
       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                          โ–ผ
                  ToolCallback[]
                          โ”‚
                          โ–ผ
              ChatClient.builder()
                  .defaultToolCallbacks()
                          โ”‚
                          โ–ผ
                    ChatClient initialization complete

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                       Invocation Phase                           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

User: "What's the weather in Beijing?"
       โ”‚
       โ–ผ
ChatModel sends request (carrying tool definitions: name + description + inputSchema)
       โ”‚
       โ–ผ
AI model decides: needs to call getWeather tool
       โ”‚
       โ–ผ
AI returns tool call request (tool name + JSON parameters)
       โ”‚
       โ–ผ
ToolCallingManager receives
       โ”‚
       โ–ผ
ToolCallbackResolver finds the corresponding ToolCallback
       โ”‚
       โ–ผ
ToolCallback.call('{"city":"Beijing"}')
       โ”‚
       โ–ผ
Returns: "Beijing: Sunny, 25\u00B0C"
       โ”‚
       โ–ผ
ToolResponseMessage sent back to AI model
       โ”‚
       โ–ผ
AI generates final response: "The weather in Beijing today is sunny, temperature 25\u00B0C"

8. Five ToolCallback Types: Whatโ€™s Each For?

We covered Providers above; now letโ€™s look at how the ToolCallbacks they generate differ:

8.1 MethodToolCallback

Purpose: Wraps @Tool annotated Java methods

@Tool(name = "getWeather", description = "Get weather")
public String getWeather(String city) {
    return city + ": Sunny, 25\u00B0C";
}
// โ†“ Wrapped into
MethodToolCallback

On execution: Directly invokes Java method via reflection


8.2 FunctionToolCallback

Purpose: Encapsulates existing code functionality through functional interfaces

// Call an existing Service method
FunctionToolCallback.builder("calculatePrice", (Function<String, BigDecimal>) input -> {
        return orderService.calculatePrice(input);
    })
    .build();

On execution: Calls Function.apply()


8.3 SyncMcpToolCallback vs AsyncMcpToolCallback

This is the pair most easily confused.

Both are used for bridging remote MCP Server tools, the difference is only in the underlying MCP client type:

ComparisonSyncMcpToolCallbackAsyncMcpToolCallback
Underlying clientMcpSyncClientMcpAsyncClient
Sync entry point for callersgetToolCallbacks()getToolCallbacks()
Generated ProviderSyncMcpToolCallbackProviderAsyncMcpToolCallbackProvider
Multiple MCP Server supportYesYes
Additional reactive capabilityNoneasyncToolCallbacks(List<McpAsyncClient>) -> Flux<ToolCallback>

Key point: Both can connect to multiple MCP Servers โ€” you donโ€™t need to choose Async just for multi-Server support!

API Perspective

SyncMcpToolCallbackProvider:

public ToolCallback[] getToolCallbacks()

AsyncMcpToolCallbackProvider:

public ToolCallback[] getToolCallbacks()

public static Flux<ToolCallback> asyncToolCallbacks(List<McpAsyncClient> mcpClients)

In other words: The unified interface exposed externally is still ToolCallback[]; the Async version just additionally provides reactive streaming assembly capability.


8.4 AugmentedToolCallback

This is an implementation that has appeared in the current 1.1.3 API docs but many articles havenโ€™t covered yet.

Note: If your project is still on 1.1.0 or 1.1.2, you likely wonโ€™t see AugmentedToolCallback / AugmentedToolCallbackProvider in your IDE. Iโ€™ve personally checked the Maven cache: these classes appear in spring-ai-model:1.1.3, but not in 1.1.0 / 1.1.2.

Purpose: Appends input Schema extension fields to existing tools without changing the original tool method signature.

Typical scenarios:

  • Adding structured metadata fields to tools
  • Uniformly recording extra parameters during tool calls
  • Extending the tool protocol without modifying original tool input parameters

The corresponding Provider at the underlying level is AugmentedToolCallbackProvider, with the related low-level tool being ToolInputSchemaAugmenter.


8.5 Which One Should I Use?

ScenarioRecommendation
Spring MVC + standard scenariosSyncMcpToolCallbackProvider
WebFlux reactive applicationsAsyncMcpToolCallbackProvider
Need to connect to multiple MCP ServersEither works
Need to append structured fields to existing toolsAugmentedToolCallbackProvider

Conclusion: If youโ€™re using Spring MVC, just go with SyncMcpToolCallbackProvider โ€” no need to switch architectures.


8.6 FunctionCallback Is Deprecated, How to Migrate?

Spring AI previously used FunctionCallback, later unified to the ToolCallback API. FunctionCallback is deprecated; migration is recommended.

Why was it deprecated?

Early on, different AI vendors used inconsistent naming. Later it was unified to โ€œtool callingโ€:

  • OpenAI: function calling โ†’ tool calling
  • Anthropic: tool use โ†’ tool calling

Spring AI aligned with this and deprecated FunctionCallback, unifying on ToolCallback.


Old code (FunctionCallback):

@Component
public class WeatherFunction {

    public String getWeather(String city) {
        return city + ": Sunny, 25\u00B0C";
    }
}

// Registration
FunctionCallback callback = FunctionCallback.builder()
    .function("getWeather", weatherFunction)
    .description("Get weather for a specified city")
    .inputType(WeatherRequest.class)
    .build();

New code (@Tool annotation):

@Service
public class WeatherService {

    @Tool(name = "getWeather", description = "Get weather for a specified city")
    public String getWeather(@JsonProperty("city") String city) {
        return city + ": Sunny, 25\u00B0C";
    }
}

// Registration - auto scanning
@Bean
public ToolCallbackProvider weatherTools(WeatherService weatherService) {
    return MethodToolCallbackProvider.builder()
            .toolObjects(weatherService)
            .build();
}

Migration Method 2: FunctionToolCallback (Wrapping Existing Interfaces)

If you donโ€™t want to modify existing code, use the wrapping approach:

// Existing Service, no changes needed
@Service
public class OrderService {
    public BigDecimal calculatePrice(String orderId) {
        // Original logic
        return new BigDecimal("99.99");
    }
}

// Wrap with FunctionToolCallback
@Configuration
public class ToolConfig {

    @Bean
    public ToolCallback orderPriceTool(OrderService orderService) {
        return FunctionToolCallback.builder("calculatePrice", orderService::calculatePrice)
            .description("Calculate price based on order ID")
            .inputType(String.class)
            .build();
    }
}

API Migration Reference

Old APINew API
FunctionCallbackToolCallback
FunctionCallback.builder().function()FunctionToolCallback.builder(name, function)
FunctionCallback.builder().method()MethodToolCallback.builder()
FunctionCallingOptionsToolCallingChatOptions
ChatClient.builder().defaultFunctions()ChatClient.builder().defaultTools()
FunctionCallingOptions.builder().functionCallbacks()ToolCallingChatOptions.builder().toolCallbacks()

9. Class Relationship Diagram Cheat Sheet

ToolCallbackProvider (interface)
    โ”‚
    โ”œโ”€โ”€ StaticToolCallbackProvider       โ† Static tool array
    โ”‚
    โ”œโ”€โ”€ MethodToolCallbackProvider       โ† Local @Tool annotated methods
    โ”‚
    โ”œโ”€โ”€ SyncMcpToolCallbackProvider      โ† MCP synchronous client
    โ”‚
    โ”œโ”€โ”€ AsyncMcpToolCallbackProvider     โ† MCP asynchronous client
    โ”‚
    โ””โ”€โ”€ AugmentedToolCallbackProvider    โ† Existing tool enhancer

ToolCallback (interface)
    โ”‚
    โ”œโ”€โ”€ MethodToolCallback               โ† Wraps Java method
    โ”‚
    โ”œโ”€โ”€ FunctionToolCallback             โ† Wraps functional interface
    โ”‚
    โ”œโ”€โ”€ SyncMcpToolCallback              โ† Wraps MCP sync tool
    โ”‚
    โ”œโ”€โ”€ AsyncMcpToolCallback             โ† Wraps MCP async tool
    โ”‚
    โ””โ”€โ”€ AugmentedToolCallback            โ† Wraps enhanced tool

10. Common Questions

Q1: Does the Bean method name (like weatherTools) matter?

A: No, this is just the Spring Bean name. What actually matters is the name in @Tool(name = "getWeather"), thatโ€™s the tool name exposed to the LLM.

Q2: Will tools with the same name conflict?

A: By default, usually not. The current MCP Client Boot Starter defaults to using DefaultMcpToolNamePrefixGenerator, which automatically adds prefixes when duplicate names appear across connections, ensuring unique tool names.

Only when you explicitly disable prefix generation (e.g., using McpToolNamePrefixGenerator.noPrefix()) AND multiple MCP Servers expose tools with the same name will an IllegalStateException be thrown due to naming conflicts.

Q3: What happens when tool execution throws an exception?

A: Default configuration spring.ai.tools.throw-exception-on-error=false, exceptions are returned to the model as error messages; setting to true will throw exceptions directly.


11. Current Version Status (as of 2026-03-22)

11.1 First Distinguish โ€œStableโ€ from โ€œPreviewโ€

  1. Latest Stable Version: 1.1.3

  2. Latest Preview Version: 2.0.0-M3 Release date is 2026-03-17. If youโ€™re writing about production environments, I recommend primarily following the 1.1.3 official Reference; if youโ€™re evaluating Spring Boot 4 / Jackson 3 / Spring AI 2.x, then supplement with M3 changes separately.

11.2 These Are โ€œCurrently Still Validโ€ Directions

  1. FunctionCallback โ†’ ToolCallback migration is still the official recommended path But this isnโ€™t a change added in 2.0.0-M3, itโ€™s a unified migration direction that started earlier. Official now maintains a separate migration guide.

  2. Tool Argument Augmentation has entered current tools documentation The official naming in current docs is Tool Argument Augmentation. If youโ€™re using 1.1.3, the core classes are:

    • AugmentedToolCallbackProvider
    • AugmentedToolCallback
    • ToolInputSchemaAugmenter
  3. Dynamic Tool Discovery has official guide ToolSearchToolCallAdvisor can indeed do dynamic tool discovery, and the official guide provides 34% - 64% token savings data. But note: it comes from org.springaicommunity:tool-search-tool, not a core module built into Spring AI core itself.

11.3 2.0.0-M3 Breaking Changes Worth Noting

  1. MCP Annotations migrated into Spring AI core Package name moved from org.springaicommunity.mcp to org.springframework.ai.mcp.annotation.

  2. Spring-specific MCP transport implementation moved into Spring AI project The Spring transport implementation originally in MCP Java SDK moved to org.springframework.ai.mcp related modules.

  3. Jackson 2 โ†’ Jackson 3 This is a real breaking change, especially affecting dependencies and package names.

  4. ToolContext no longer automatically includes conversation history This is a breaking change explicitly called out in the M3 release notes, pay special attention when upgrading.

11.4 This Articleโ€™s Verification Sources

  • Spring AI Reference 1.1.3
  • Spring AI current API Javadoc
  • Spring AI 2.0.0-M3 release notes
  • Spring AI 2.0 Dynamic Tool Search guide

Summary

In one sentence:

ToolCallback is the wrapper for a single tool, ToolCallbackProvider is the factory for tool collections. MethodToolCallbackProvider handles local @Tool methods, Sync/AsyncMcpToolCallbackProvider bridges remote MCP tools, AugmentedToolCallbackProvider handles enhancement of existing tools; and on the MCP Server side, you can currently still use the @McpTool annotation route directly.

Understanding this mechanism enables you to:

  • Clearly know why your tools arenโ€™t being recognized
  • Understand how MCP tools are integrated
  • Know which part of the chain to troubleshoot when problems occur

Welcome to follow the WeChat Official Account FishTech Notes for more discussions!