├── .gitattributes ├── .gitignore ├── README.md ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── example │ │ ├── DataInitializer.java │ │ ├── DemoApplication.java │ │ ├── config │ │ ├── ChatClientConfig.java │ │ └── ProxyConfig.java │ │ ├── controller │ │ ├── BookController.java │ │ └── ChatController.java │ │ ├── entity │ │ └── Book.java │ │ ├── mcp │ │ ├── config │ │ │ └── McpServerConfig.java │ │ └── service │ │ │ └── BookQueryService.java │ │ ├── model │ │ ├── ChatRequest.java │ │ └── ChatResponse.java │ │ ├── repository │ │ └── BookRepository.java │ │ └── service │ │ ├── BookService.java │ │ └── impl │ │ └── BookServiceImpl.java └── resources │ └── application.properties └── test └── java └── com └── example └── demo └── DemoApplicationTests.java /.gitattributes: -------------------------------------------------------------------------------- 1 | /mvnw text eol=lf 2 | *.cmd text eol=crlf 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 2025-05-12 最新说明 2 | 3 | spring官方文档已更新,依赖名称发生变化,目前该demo中的依赖已经拉取不到,请大家查阅最新文档自行做整合! 4 | 5 | # 说明 6 | 7 | 有读者反馈想要源码自己实践下,就搞个仓库传上来。 8 | 9 | 10 | 项目结构和代码不是很规范,当时写文章重在跑通上,还请大家不要学,看实践就好! 11 | 12 | 13 | 原文来自以下平台: 14 | 15 | https://juejin.cn/post/7483454392979570700 16 | 17 | https://blog.csdn.net/m0_60925013/article/details/146393912?spm=1001.2014.3001.5501 18 | 19 | https://cloud.tencent.com.cn/developer/article/2506434 20 | 21 | https://developer.aliyun.com/article/1657752?spm=a2c6h.13262185.profile.12.68bb606c9YqAqv 22 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.4.3 9 | 10 | 11 | com.pitaya 12 | demo 13 | 0.0.1-SNAPSHOT 14 | demo 15 | demo 16 | 17 | 18 | 19 | 17 20 | 21 | 22 | 23 | 24 | 25 | 26 | org.springframework.ai 27 | spring-ai-bom 28 | 1.0.0-SNAPSHOT 29 | pom 30 | import 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-data-jpa 40 | 41 | 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-starter-web 46 | 47 | 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-starter-validation 52 | 53 | 54 | 55 | 56 | com.h2database 57 | h2 58 | runtime 59 | 60 | 61 | 62 | 63 | org.projectlombok 64 | lombok 65 | true 66 | 67 | 68 | 69 | 70 | org.springframework.boot 71 | spring-boot-starter-test 72 | test 73 | 74 | 75 | 76 | 77 | com.fasterxml.jackson.core 78 | jackson-databind 79 | 80 | 81 | 82 | 83 | org.springframework.ai 84 | spring-ai-core 85 | 86 | 87 | 88 | 89 | org.springframework.ai 90 | spring-ai-anthropic-spring-boot-starter 91 | 92 | 93 | 94 | 95 | org.springframework.ai 96 | spring-ai-mcp-server-webmvc-spring-boot-starter 97 | 98 | 99 | 100 | org.json 101 | json 102 | 20240303 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | spring-milestones 111 | Spring Milestones 112 | https://repo.spring.io/milestone 113 | 114 | false 115 | 116 | 117 | 118 | spring-snapshots 119 | Spring Snapshots 120 | https://repo.spring.io/snapshot 121 | 122 | false 123 | 124 | 125 | 126 | Central Portal Snapshots 127 | central-portal-snapshots 128 | https://central.sonatype.com/repository/maven-snapshots/ 129 | 130 | false 131 | 132 | 133 | true 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | org.apache.maven.plugins 143 | maven-compiler-plugin 144 | 145 | 146 | 147 | org.projectlombok 148 | lombok 149 | 150 | 151 | 152 | 153 | 154 | org.springframework.boot 155 | spring-boot-maven-plugin 156 | 157 | 158 | 159 | org.projectlombok 160 | lombok 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /src/main/java/com/example/DataInitializer.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | 4 | import com.example.entity.Book; 5 | import com.example.repository.BookRepository; 6 | import jakarta.annotation.Resource; 7 | import lombok.RequiredArgsConstructor; 8 | import org.springframework.boot.CommandLineRunner; 9 | import org.springframework.stereotype.Component; 10 | 11 | import java.time.LocalDate; 12 | import java.util.Arrays; 13 | import java.util.List; 14 | 15 | @Component 16 | @RequiredArgsConstructor 17 | public class DataInitializer implements CommandLineRunner { 18 | 19 | @Resource 20 | private BookRepository bookRepository; 21 | 22 | @Override 23 | public void run(String... args) throws Exception { 24 | // 准备示例数据 25 | List sampleBooks = Arrays.asList( 26 | new Book(null, "Spring实战(第6版)", "编程", "Craig Walls", 27 | LocalDate.of(2022, 1, 15), "9787115582247"), 28 | new Book(null, "深入理解Java虚拟机", "编程", "周志明", 29 | LocalDate.of(2019, 12, 1), "9787111641247"), 30 | new Book(null, "Java编程思想(第4版)", "编程", "Bruce Eckel", 31 | LocalDate.of(2007, 6, 1), "9787111213826"), 32 | new Book(null, "算法(第4版)", "计算机科学", "Robert Sedgewick", 33 | LocalDate.of(2012, 10, 1), "9787115293800"), 34 | new Book(null, "云原生架构", "架构设计", "张三", 35 | LocalDate.of(2023, 3, 15), "9781234567890"), 36 | new Book(null, "微服务设计模式", "架构设计", "张三", 37 | LocalDate.of(2021, 8, 20), "9789876543210"), 38 | new Book(null, "领域驱动设计", "架构设计", "Eric Evans", 39 | LocalDate.of(2010, 4, 10), "9787111214748"), 40 | new Book(null, "高性能MySQL", "数据库", "Baron Schwartz", 41 | LocalDate.of(2013, 5, 25), "9787111464747"), 42 | new Book(null, "Redis实战", "数据库", "Josiah L. Carlson", 43 | LocalDate.of(2015, 9, 30), "9787115419378"), 44 | new Book(null, "深入浅出Docker", "容器技术", "李四", 45 | LocalDate.of(2022, 11, 20), "9787123456789") 46 | ); 47 | 48 | // 保存示例数据 49 | bookRepository.saveAll(sampleBooks); 50 | 51 | System.out.println("数据初始化完成,共加载 " + sampleBooks.size() + " 本图书"); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/example/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/example/config/ChatClientConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.config; 2 | 3 | 4 | 5 | 6 | import org.springframework.ai.chat.client.ChatClient; 7 | import org.springframework.ai.tool.ToolCallbackProvider; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | 12 | 13 | /** 14 | * 聊天客户端配置类 15 | */ 16 | @Configuration 17 | public class ChatClientConfig { 18 | 19 | 20 | @Autowired 21 | private ToolCallbackProvider toolCallbackProvider; 22 | 23 | /** 24 | * 配置ChatClient,注册系统指令和工具函数 25 | */ 26 | @Bean 27 | public ChatClient chatClient(ChatClient.Builder builder) { 28 | return builder 29 | .defaultSystem("你是一个图书管理助手,可以帮助用户查询图书信息。" + 30 | "你可以根据书名模糊查询、根据作者查询和根据分类查询图书。" + 31 | "回复时,请使用简洁友好的语言,并将图书信息整理为易读的格式。") 32 | // 注册工具方法 33 | .defaultTools(toolCallbackProvider) 34 | .build(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/example/config/ProxyConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.config; 2 | 3 | import jakarta.annotation.PostConstruct; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | 7 | @Configuration 8 | public class ProxyConfig { 9 | 10 | // 代理设置 11 | private final String PROXY_HOST = "127.0.0.1"; 12 | private final int PROXY_PORT = 10080; 13 | 14 | @PostConstruct 15 | public void setSystemProxy() { 16 | // 设置系统代理属性,这会影响Spring Boot自动配置的HTTP客户端 17 | System.setProperty("http.proxyHost", PROXY_HOST); 18 | System.setProperty("http.proxyPort", String.valueOf(PROXY_PORT)); 19 | System.setProperty("https.proxyHost", PROXY_HOST); 20 | System.setProperty("https.proxyPort", String.valueOf(PROXY_PORT)); 21 | 22 | System.out.println("System proxy configured: http://" + PROXY_HOST + ":" + PROXY_PORT); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/example/controller/BookController.java: -------------------------------------------------------------------------------- 1 | package com.example.controller; 2 | 3 | import com.example.entity.Book; 4 | import com.example.service.BookService; 5 | import jakarta.annotation.Resource; 6 | import lombok.RequiredArgsConstructor; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.web.bind.annotation.*; 9 | 10 | import java.util.List; 11 | 12 | @RestController 13 | @RequestMapping("/api/books") 14 | @RequiredArgsConstructor 15 | public class BookController { 16 | 17 | @Resource 18 | private BookService bookService; 19 | 20 | @GetMapping("/search/title") 21 | public ResponseEntity> searchBooksByTitle(@RequestParam String title) { 22 | List books = bookService.findBooksByTitle(title); 23 | return ResponseEntity.ok(books); 24 | } 25 | 26 | @GetMapping("/search/author") 27 | public ResponseEntity> searchBooksByAuthor(@RequestParam String author) { 28 | List books = bookService.findBooksByAuthor(author); 29 | return ResponseEntity.ok(books); 30 | } 31 | 32 | @GetMapping("/search/category") 33 | public ResponseEntity> searchBooksByCategory(@RequestParam String category) { 34 | List books = bookService.findBooksByCategory(category); 35 | return ResponseEntity.ok(books); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/example/controller/ChatController.java: -------------------------------------------------------------------------------- 1 | package com.example.controller; 2 | 3 | 4 | import com.example.model.ChatRequest; 5 | import com.example.model.ChatResponse; 6 | import jakarta.annotation.Resource; 7 | import org.springframework.ai.chat.client.ChatClient; 8 | import org.springframework.http.ResponseEntity; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | /** 12 | * 聊天控制器,处理AI聊天请求 13 | */ 14 | @RestController 15 | @RequestMapping("/api/chat") 16 | public class ChatController { 17 | 18 | 19 | @Resource 20 | private ChatClient chatClient; 21 | 22 | 23 | /** 24 | * 处理聊天请求,使用AI和MCP工具进行响应 25 | * 26 | * @param request 聊天请求 27 | * @return 包含AI回复的响应 28 | */ 29 | @PostMapping 30 | public ResponseEntity chat(@RequestBody ChatRequest request) { 31 | try { 32 | // 创建用户消息 33 | String userMessage = request.getMessage(); 34 | 35 | // 使用流式API调用聊天 36 | String content = chatClient.prompt() 37 | .user(userMessage) 38 | .call() 39 | .content(); 40 | 41 | return ResponseEntity.ok(new ChatResponse(content)); 42 | } catch (Exception e) { 43 | e.printStackTrace(); 44 | return ResponseEntity.ok(new ChatResponse("处理请求时出错: " + e.getMessage())); 45 | } 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/example/entity/Book.java: -------------------------------------------------------------------------------- 1 | package com.example.entity; 2 | 3 | import jakarta.persistence.*; 4 | import jakarta.validation.constraints.NotBlank; 5 | import jakarta.validation.constraints.NotNull; 6 | import jakarta.validation.constraints.PastOrPresent; 7 | import lombok.AllArgsConstructor; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | 11 | 12 | import java.time.LocalDate; 13 | 14 | @Entity 15 | @Table(name = "books") 16 | @Data 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | public class Book { 20 | 21 | @Id 22 | @GeneratedValue(strategy = GenerationType.IDENTITY) 23 | private Long id; 24 | 25 | @NotBlank(message = "书名不能为空") 26 | @Column(nullable = false) 27 | private String title; 28 | 29 | @NotBlank(message = "分类不能为空") 30 | @Column(nullable = false) 31 | private String category; 32 | 33 | @NotBlank(message = "作者不能为空") 34 | @Column(nullable = false) 35 | private String author; 36 | 37 | @NotNull(message = "出版日期不能为空") 38 | @PastOrPresent(message = "出版日期不能是未来日期") 39 | @Column(nullable = false) 40 | private LocalDate publicationDate; 41 | 42 | @NotBlank(message = "ISBN编码不能为空") 43 | @Column(nullable = false, unique = true) 44 | private String isbn; 45 | 46 | public Long getId() { 47 | return id; 48 | } 49 | 50 | public void setId(Long id) { 51 | this.id = id; 52 | } 53 | 54 | public @NotBlank(message = "书名不能为空") String getTitle() { 55 | return title; 56 | } 57 | 58 | public void setTitle(@NotBlank(message = "书名不能为空") String title) { 59 | this.title = title; 60 | } 61 | 62 | public @NotBlank(message = "分类不能为空") String getCategory() { 63 | return category; 64 | } 65 | 66 | public void setCategory(@NotBlank(message = "分类不能为空") String category) { 67 | this.category = category; 68 | } 69 | 70 | public @NotBlank(message = "作者不能为空") String getAuthor() { 71 | return author; 72 | } 73 | 74 | public void setAuthor(@NotBlank(message = "作者不能为空") String author) { 75 | this.author = author; 76 | } 77 | 78 | public @NotNull(message = "出版日期不能为空") @PastOrPresent(message = "出版日期不能是未来日期") LocalDate getPublicationDate() { 79 | return publicationDate; 80 | } 81 | 82 | public void setPublicationDate(@NotNull(message = "出版日期不能为空") @PastOrPresent(message = "出版日期不能是未来日期") LocalDate publicationDate) { 83 | this.publicationDate = publicationDate; 84 | } 85 | 86 | public @NotBlank(message = "ISBN编码不能为空") String getIsbn() { 87 | return isbn; 88 | } 89 | 90 | public void setIsbn(@NotBlank(message = "ISBN编码不能为空") String isbn) { 91 | this.isbn = isbn; 92 | } 93 | 94 | public Book() { 95 | } 96 | 97 | public Book(Long id, String title, String category, String author, LocalDate publicationDate, String isbn) { 98 | this.id = id; 99 | this.title = title; 100 | this.category = category; 101 | this.author = author; 102 | this.publicationDate = publicationDate; 103 | this.isbn = isbn; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/com/example/mcp/config/McpServerConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.mcp.config; 2 | 3 | 4 | import com.example.service.BookService; 5 | import org.springframework.ai.tool.ToolCallbackProvider; 6 | import org.springframework.ai.tool.method.MethodToolCallbackProvider; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | /** 11 | * MCP服务器配置类,负责注册MCP工具 12 | */ 13 | @Configuration 14 | public class McpServerConfig { 15 | 16 | /** 17 | * 注册工具回调提供者,将BookQueryService中的@Tool方法暴露为MCP工具 18 | * 19 | * @param bookService 图书服务 20 | * @return 工具回调提供者 21 | */ 22 | @Bean 23 | public ToolCallbackProvider bookToolCallbackProvider(BookService bookService) { 24 | return MethodToolCallbackProvider.builder() 25 | .toolObjects(bookService) 26 | .build(); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/example/mcp/service/BookQueryService.java: -------------------------------------------------------------------------------- 1 | package com.example.mcp.service; 2 | 3 | 4 | import com.example.entity.Book; 5 | import com.example.service.BookService; 6 | import jakarta.annotation.Resource; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.stereotype.Service; 9 | 10 | import java.util.List; 11 | import java.util.function.Function; 12 | 13 | /** 14 | * 图书查询服务,将查询方法作为函数Bean导出 15 | */ 16 | @Service 17 | public class BookQueryService { 18 | 19 | @Resource 20 | private BookService bookService; 21 | 22 | /** 23 | * 根据书名查询图书的函数Bean 24 | */ 25 | @Bean 26 | public Function> findBooksByTitle() { 27 | return title -> bookService.findBooksByTitle(title); 28 | } 29 | 30 | /** 31 | * 根据作者查询图书的函数Bean 32 | */ 33 | @Bean 34 | public Function> findBooksByAuthor() { 35 | return author -> bookService.findBooksByAuthor(author); 36 | } 37 | 38 | /** 39 | * 根据分类查询图书的函数Bean 40 | */ 41 | @Bean 42 | public Function> findBooksByCategory() { 43 | return category -> bookService.findBooksByCategory(category); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/example/model/ChatRequest.java: -------------------------------------------------------------------------------- 1 | package com.example.model; 2 | 3 | import lombok.Data; 4 | import lombok.Getter; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | * 聊天请求模型,包含用户发送的消息 10 | */ 11 | @Data 12 | public class ChatRequest implements Serializable { 13 | 14 | private String message; 15 | 16 | public void setMessage(String message) { 17 | this.message = message; 18 | } 19 | 20 | public String getMessage() { 21 | return message; 22 | } 23 | 24 | public ChatRequest() { 25 | } 26 | 27 | public ChatRequest(String message) { 28 | this.message = message; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/example/model/ChatResponse.java: -------------------------------------------------------------------------------- 1 | package com.example.model; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 聊天响应模型,包含AI返回的内容 7 | */ 8 | @Data 9 | public class ChatResponse { 10 | 11 | private String content; 12 | 13 | public String getContent() { 14 | return content; 15 | } 16 | 17 | public void setContent(String content) { 18 | this.content = content; 19 | } 20 | 21 | public ChatResponse() { 22 | } 23 | 24 | public ChatResponse(String content) { 25 | this.content = content; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/example/repository/BookRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.repository; 2 | 3 | 4 | 5 | import com.example.entity.Book; 6 | import org.springframework.data.jpa.repository.JpaRepository; 7 | import org.springframework.data.jpa.repository.Query; 8 | import org.springframework.data.repository.query.Param; 9 | import org.springframework.stereotype.Repository; 10 | 11 | import java.util.List; 12 | 13 | @Repository 14 | public interface BookRepository extends JpaRepository { 15 | 16 | // 根据书名模糊查询 17 | @Query("SELECT b FROM Book b WHERE LOWER(b.title) LIKE LOWER(CONCAT('%', :title, '%'))") 18 | List findByTitleContaining(@Param("title") String title); 19 | 20 | // 根据作者查询 21 | List findByAuthor(String author); 22 | 23 | // 根据分类查询 24 | List findByCategory(String category); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/example/service/BookService.java: -------------------------------------------------------------------------------- 1 | package com.example.service; 2 | 3 | import com.example.entity.Book; 4 | 5 | import java.util.List; 6 | 7 | public interface BookService { 8 | 9 | // 根据书名模糊查询 10 | List findBooksByTitle(String title); 11 | 12 | // 根据作者查询 13 | List findBooksByAuthor(String author); 14 | 15 | // 根据分类查询 16 | List findBooksByCategory(String category); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/example/service/impl/BookServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.example.service.impl; 2 | 3 | 4 | 5 | import com.example.entity.Book; 6 | import com.example.repository.BookRepository; 7 | import com.example.service.BookService; 8 | import jakarta.annotation.Resource; 9 | import lombok.RequiredArgsConstructor; 10 | import org.springframework.ai.tool.annotation.Tool; 11 | import org.springframework.ai.tool.annotation.ToolParam; 12 | import org.springframework.stereotype.Service; 13 | 14 | import java.util.List; 15 | 16 | @Service 17 | @RequiredArgsConstructor 18 | public class BookServiceImpl implements BookService { 19 | 20 | @Resource 21 | private BookRepository bookRepository; 22 | 23 | 24 | @Override 25 | @Tool(name = "findBooksByTitle", description = "根据书名模糊查询图书,支持部分标题匹配") 26 | public List findBooksByTitle(@ToolParam(description = "书名关键词") String title) { 27 | return bookRepository.findByTitleContaining(title); 28 | } 29 | 30 | @Override 31 | @Tool(name = "findBooksByAuthor", description = "根据作者精确查询图书") 32 | public List findBooksByAuthor(@ToolParam(description = "作者姓名") String author) { 33 | return bookRepository.findByAuthor(author); 34 | } 35 | 36 | @Override 37 | @Tool(name = "findBooksByCategory", description = "根据图书分类精确查询图书") 38 | public List findBooksByCategory(@ToolParam(description = "图书分类")String category) { 39 | return bookRepository.findByCategory(category); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=book-management 2 | 3 | 4 | spring.datasource.url=jdbc:h2:mem:bookdb 5 | spring.datasource.driverClassName=org.h2.Driver 6 | spring.datasource.username=sa 7 | spring.datasource.password=password 8 | spring.h2.console.enabled=true 9 | spring.h2.console.path=/h2-console 10 | 11 | 12 | spring.jpa.database-platform=org.hibernate.dialect.H2Dialect 13 | spring.jpa.hibernate.ddl-auto=update 14 | spring.jpa.show-sql=true 15 | spring.jpa.properties.hibernate.format_sql=true 16 | 17 | 18 | server.port=8080 19 | 20 | 21 | spring.ai.anthropic.api-key=${????key} 22 | 23 | 24 | spring.ai.mcp.server.enabled=true 25 | 26 | 27 | spring.ai.mcp.server.name=book-management-server 28 | spring.ai.mcp.server.version=1.0.0 29 | spring.ai.mcp.server.type=SYNC 30 | spring.ai.mcp.server.sse-message-endpoint=/mcp/message 31 | -------------------------------------------------------------------------------- /src/test/java/com/example/demo/DemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class DemoApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | --------------------------------------------------------------------------------