Skip to content

Commit 717ef9c

Browse files
author
虫洞
committed
refactor(mcp): update SQLite examples to use new MCP client API
- Replace deprecated StdioServerTransport with StdioClientTransport - Update SyncMcpToolCallbackProvider to use builder pattern with noPrefix generator - Change SQLite MCP-Server documentation links from GitHub to PyPI - Remove obsolete function callback documentation sections - Streamline MCP client initialization with new timeout configuration These changes align with the latest Spring AI MCP integration patterns and improve code maintainability across both simple and chatbot examples.
1 parent 316d0d7 commit 717ef9c

File tree

4 files changed

+28
-94
lines changed

4 files changed

+28
-94
lines changed

model-context-protocol/sqlite/chatbot/README.md

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
A demo application showcasing the integration of Spring AI with SQLite databases using the Model Context Protocol (MCP). This application enables natural language interactions with your SQLite database through a command-line interface.
44

5-
It uses the [SQLite MCP-Server](https://github.com/modelcontextprotocol/servers/tree/main/src/sqlite) to enable running SQL queries, analyzing business data, and automatically generating business insight memos.
5+
It uses the [SQLite MCP-Server](https://pypi.org/project/mcp-server-sqlite/) to enable running SQL queries, analyzing business data, and automatically generating business insight memos.
66

77
The demo starts a simple chatbot where your can ask qustions about the data stored in the database.
88

@@ -68,7 +68,7 @@ It has a `PRODUCTS` table and was created using the script `create-database.sh`
6868
Enables real-time conversation with your database:
6969

7070
```bash
71-
./mvnw spring-boot:run -Dspring-boot.run.profiles=chat
71+
./mvnw spring-boot:run
7272
```
7373

7474
## Architecture Overview
@@ -85,8 +85,8 @@ public McpSyncClient mcpClient() {
8585
.args("mcp-server-sqlite", "--db-path", getDbPath())
8686
.build();
8787

88-
var mcpClient = McpClient.sync(new StdioServerTransport(stdioParams),
89-
Duration.ofSeconds(10), new ObjectMapper());
88+
var mcpClient = McpClient.sync(new StdioClientTransport(stdioParams, McpJsonMapper.createDefault()))
89+
.requestTimeout(Duration.ofSeconds(10)).build();
9090

9191
var init = mcpClient.initialize();
9292

@@ -105,39 +105,6 @@ This configuration:
105105

106106
The `destroyMethod = "close"` annotation ensures proper cleanup when the application shuts down.
107107

108-
### Function Callbacks
109-
110-
The application registers MCP tools with Spring AI using function callbacks:
111-
112-
```java
113-
@Bean
114-
public List<McpFunctionCallback> functionCallbacks(McpSyncClient mcpClient) {
115-
return mcpClient.listTools(null)
116-
.tools()
117-
.stream()
118-
.map(tool -> new McpFunctionCallback(mcpClient, tool))
119-
.toList();
120-
}
121-
```
122-
123-
#### Purpose
124-
125-
This bean is responsible for:
126-
1. Discovering available MCP tools from the client
127-
2. Converting each tool into a Spring AI function callback
128-
3. Making these callbacks available for use with the ChatClient
129-
130-
131-
#### How It Works
132-
133-
1. `mcpClient.listTools(null)` queries the MCP server for all available tools
134-
- The `null` parameter represents a pagination cursor
135-
- When null, returns the first page of results
136-
- A cursor string can be provided to get results after that position
137-
2. `.tools()` extracts the tool list from the response
138-
3. Each tool is transformed into a `McpFunctionCallback` using `.map()`
139-
4. These callbacks are collected into an array using `.toArray(McpFunctionCallback[]::new)`
140-
141108
#### Usage
142109

143110
The registered callbacks enable the ChatClient to:

model-context-protocol/sqlite/chatbot/src/main/java/org/springframework/ai/mcp/samples/sqlite/Application.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.springframework.ai.chat.client.ChatClient;
1515
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
1616
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
17+
import org.springframework.ai.mcp.McpToolNamePrefixGenerator;
1718
import org.springframework.ai.mcp.SyncMcpToolCallbackProvider;
1819
import org.springframework.boot.CommandLineRunner;
1920
import org.springframework.boot.SpringApplication;
@@ -33,9 +34,11 @@ public CommandLineRunner interactiveChat(ChatClient.Builder chatClientBuilder,
3334
List<McpSyncClient> mcpClients,
3435
ConfigurableApplicationContext context) {
3536
return args -> {
36-
37-
var chatClient = chatClientBuilder
38-
.defaultToolCallbacks(new SyncMcpToolCallbackProvider(mcpClients))
37+
var toolCallbackProvider = SyncMcpToolCallbackProvider.builder()
38+
.mcpClients(mcpClients)
39+
.toolNamePrefixGenerator(McpToolNamePrefixGenerator.noPrefix())
40+
.build();
41+
var chatClient = chatClientBuilder.defaultToolCallbacks(toolCallbackProvider)
3942
.defaultAdvisors(MessageChatMemoryAdvisor.builder(MessageWindowChatMemory.builder().build()).build())
4043
.build();
4144

model-context-protocol/sqlite/simple/README.md

Lines changed: 12 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
A demo application showcasing the integration of Spring AI with SQLite databases using the Model Context Protocol (MCP). This application enables natural language interactions with your SQLite database through a command-line interface.
44

5-
It uses the [SQLite MCP-Server](https://github.com/modelcontextprotocol/servers/tree/main/src/sqlite) to enable running SQL queries, analyzing business data, and automatically generating business insight memos.
5+
It uses the [SQLite MCP-Server](https://pypi.org/project/mcp-server-sqlite/) to enable running SQL queries, analyzing business data, and automatically generating business insight memos.
66

77
## Features
88

@@ -67,13 +67,15 @@ The bean definitions are described below, starting with the `ChatClient`
6767

6868
```java
6969
@Bean
70-
@Profile("!chat")
7170
public CommandLineRunner predefinedQuestions(ChatClient.Builder chatClientBuilder,
72-
List<McpFunctionCallback> functionCallbacks,
73-
ConfigurableApplicationContext context) {
74-
return args -> {
75-
var chatClient = chatClientBuilder.defaultFunctions(functionCallbacks.toArray(new McpFunctionCallback[0]))
76-
.build();
71+
List<McpSyncClient> mcpClients, ConfigurableApplicationContext context) {
72+
73+
return args -> {
74+
var toolCallbackProvider = SyncMcpToolCallbackProvider.builder()
75+
.mcpClients(mcpClients)
76+
.toolNamePrefixGenerator(McpToolNamePrefixGenerator.noPrefix())
77+
.build();
78+
var chatClient = chatClientBuilder.defaultToolCallbacks(toolCallbackProvider).build();
7779
// Run Predefined Questions
7880
System.out.println(chatClient.prompt(
7981
"Can you connect to my SQLite database and tell me what products are available, and their prices?").call().content());
@@ -82,51 +84,10 @@ public CommandLineRunner predefinedQuestions(ChatClient.Builder chatClientBuilde
8284
}
8385
```
8486

85-
The chat client setup is remarkably simple - it just needs the function callbacks that were automatically created from the MCP tools. Spring's dependency injection handles all the wiring, making the integration seamless.
87+
The chat client setup is remarkably simple - it just needs the mcp clients. Spring's dependency injection handles all the wiring, making the integration seamless.
8688

8789
Now let's look at the other bean definitions in detail...
8890

89-
### Function Callbacks
90-
91-
The application registers MCP tools with Spring AI using function callbacks:
92-
93-
```java
94-
@Bean
95-
public List<McpFunctionCallback> functionCallbacks(McpSyncClient mcpClient) {
96-
return mcpClient.listTools(null)
97-
.tools()
98-
.stream()
99-
.map(tool -> new McpFunctionCallback(mcpClient, tool))
100-
.toList();
101-
}
102-
```
103-
104-
#### Purpose
105-
106-
This bean is responsible for:
107-
1. Discovering available MCP tools from the client
108-
2. Converting each tool into a Spring AI function callback
109-
3. Making these callbacks available for use with the ChatClient
110-
111-
112-
#### How It Works
113-
114-
1. `mcpClient.listTools(null)` queries the MCP server for all available tools
115-
- The `null` parameter represents a pagination cursor
116-
- When null, returns the first page of results
117-
- A cursor string can be provided to get results after that position
118-
2. `.tools()` extracts the tool list from the response
119-
3. Each tool is transformed into a `McpFunctionCallback` using `.map()`
120-
4. These callbacks are collected into an array using `.toArray(McpFunctionCallback[]::new)`
121-
122-
#### Usage
123-
124-
The registered callbacks enable the ChatClient to:
125-
- Access MCP tools during conversations
126-
- Handle function calls requested by the AI model
127-
- Execute tools against the MCP server (e.g., SQLite database)
128-
129-
13091
### MCP Client
13192

13293
The application uses a synchronous MCP client to communicate with the SQLite database:
@@ -138,8 +99,8 @@ public McpSyncClient mcpClient() {
13899
.args("mcp-server-sqlite", "--db-path", getDbPath())
139100
.build();
140101

141-
var mcpClient = McpClient.sync(new StdioServerTransport(stdioParams),
142-
Duration.ofSeconds(10), new ObjectMapper());
102+
var mcpClient = McpClient.sync(new StdioClientTransport(stdioParams, McpJsonMapper.createDefault()))
103+
.requestTimeout(Duration.ofSeconds(10)).build();
143104

144105
var init = mcpClient.initialize();
145106
System.out.println("MCP Initialized: " + init);

model-context-protocol/sqlite/simple/src/main/java/org/springframework/ai/mcp/samples/sqlite/Application.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import io.modelcontextprotocol.json.McpJsonMapper;
1212

1313
import org.springframework.ai.chat.client.ChatClient;
14+
import org.springframework.ai.mcp.McpToolNamePrefixGenerator;
1415
import org.springframework.ai.mcp.SyncMcpToolCallbackProvider;
1516
import org.springframework.boot.CommandLineRunner;
1617
import org.springframework.boot.SpringApplication;
@@ -30,9 +31,11 @@ public CommandLineRunner predefinedQuestions(ChatClient.Builder chatClientBuilde
3031
List<McpSyncClient> mcpClients, ConfigurableApplicationContext context) {
3132

3233
return args -> {
33-
var chatClient = chatClientBuilder
34-
.defaultToolCallbacks(new SyncMcpToolCallbackProvider(mcpClients))
35-
.build();
34+
var toolCallbackProvider = SyncMcpToolCallbackProvider.builder()
35+
.mcpClients(mcpClients)
36+
.toolNamePrefixGenerator(McpToolNamePrefixGenerator.noPrefix())
37+
.build();
38+
var chatClient = chatClientBuilder.defaultToolCallbacks(toolCallbackProvider).build();
3639
System.out.println("Running predefined questions with AI model responses:\n");
3740

3841
// Question 1

0 commit comments

Comments
 (0)