PageSourceSearch

https://java2ai.com/assets/js/4522ed3f.2594946e.js

js java2ai.com collected 2026-10-03 21:35:00 UTC 31,775 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkspring_ai_alibaba_website=self.webpackChunkspring_ai_alibaba_website||[]).push([[3914],{27163:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>p,frontMatter:()=>c,metadata:()=>s,toc:()=>a});const s=JSON.parse('{"id":"mcps/mcp-streamable-http-server-boot-starter-docs","title":"mcp-streamable-http-server-boot-starter-docs","description":"Streamable-HTTP MCP Servers","source":"@site/integration/mcps/mcp-streamable-http-server-boot-starter-docs.md","sourceDirName":"mcps","slug":"/mcps/mcp-streamable-http-server-boot-starter-docs","permalink":"/integration/mcps/mcp-streamable-http-server-boot-starter-docs","draft":false,"unlisted":false,"editUrl":"https://github.com/spring-ai-alibaba/website/tree/main/integration/mcps/mcp-streamable-http-server-boot-starter-docs.md","tags":[],"version":"current","lastUpdatedBy":"Ken Liu","lastUpdatedAt":1768271906000,"frontMatter":{},"sidebar":"integrationSidebar","previous":{"title":"mcp-stdio-sse-server-boot-starter-docs","permalink":"/integration/mcps/mcp-stdio-sse-server-boot-starter-docs"},"next":{"title":"MCP Annotations","permalink":"/integration/mcps/annotations/mcp-annotations-overview"}}');var i=r(74848),t=r(28453);const c={},l=void 0,o={},a=[{value:"Streamable-HTTP MCP Servers",id:"streamable-http-mcp-servers",level:2},{value:"Streamable-HTTP WebMVC Server",id:"streamable-http-webmvc-server",level:3},{value:"Streamable-HTTP WebFlux Server",id:"streamable-http-webflux-server",level:3},{value:"Configuration Properties",id:"configuration-properties",level:2},{value:"Common Properties",id:"common-properties",level:3},{value:"MCP Annotations Properties",id:"mcp-annotations-properties",level:3},{value:"Streamable-HTTP Properties",id:"streamable-http-properties",level:3},{value:"Features and Capabilities",id:"features-and-capabilities",level:2},{value:"Tools",id:"tools",level:3},{value:"Tool Context Support",id:"tool-context-support",level:4},{value:"Resources",id:"resources",level:3},{value:"Prompts",id:"prompts",level:3},{value:"Completions",id:"completions",level:3},{value:"Logging",id:"logging",level:3},{value:"Progress",id:"progress",level:3},{value:"Root List Changes",id:"root-list-changes",level:3},{value:"Ping",id:"ping",level:3},{value:"Keep Alive",id:"keep-alive",level:3},{value:"Usage Examples",id:"usage-examples",level:2},{value:"Streamable HTTP Server Configuration",id:"streamable-http-server-configuration",level:3},{value:"Creating a Spring Boot Application with MCP Server",id:"creating-a-spring-boot-application-with-mcp-server",level:3}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"streamable-http-mcp-servers",children:"Streamable-HTTP MCP Servers"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#streamable-http",children:"Streamable HTTP transport"})," \u5141\u8bb8 MCP \u670d\u52a1\u5668\u4f5c\u4e3a\u72ec\u7acb\u8fdb\u7a0b\u8fd0\u884c\uff0c\u53ef\u4ee5\u4f7f\u7528 HTTP POST \u548c GET \u8bf7\u6c42\u5904\u7406\u591a\u4e2a\u5ba2\u6237\u7aef\u8fde\u63a5\uff0c\u5e76\u53ef\u9009\u5730\u4f7f\u7528 Server-Sent Events (SSE) \u6d41\u5f0f\u4f20\u8f93\u591a\u4e2a\u670d\u52a1\u5668\u6d88\u606f\u3002\u5b83\u53d6\u4ee3\u4e86 SSE \u4f20\u8f93\u3002"]}),"\n",(0,i.jsxs)(n.p,{children:["\u8fd9\u4e9b\u670d\u52a1\u5668\u968f\u89c4\u8303\u7248\u672c ",(0,i.jsx)(n.a,{href:"https://modelcontextprotocol.io/specification/2025-03-26",children:"2025-03-26"})," \u5f15\u5165\uff0c\u975e\u5e38\u9002\u5408\u9700\u8981\u901a\u77e5\u5ba2\u6237\u7aef\u6709\u5173\u5de5\u5177\u3001\u8d44\u6e90\u6216 prompts \u52a8\u6001\u66f4\u6539\u7684\u5e94\u7528\u7a0b\u5e8f\u3002"]}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"\u63d0\u793a\uff1a"})," \u8bbe\u7f6e ",(0,i.jsx)(n.code,{children:"spring.ai.mcp.server.protocol=STREAMABLE"})," \u5c5e\u6027"]}),"\n"]}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"\u63d0\u793a\uff1a"})," \u4f7f\u7528 ",(0,i.jsx)(n.a,{href:"mcp-client-boot-starter-docs#_streamable_http_transport_properties",children:"Streamable-HTTP clients"}
1)," \u8fde\u63a5\u5230 Streamable-HTTP \u670d\u52a1\u5668\u3002"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"streamable-http-webmvc-server",children:"Streamable-HTTP WebMVC Server"}),"\n",(0,i.jsxs)(n.p,{children:["\u4f7f\u7528 ",(0,i.jsx)(n.code,{children:"spring-ai-starter-mcp-server-webmvc"})," \u4f9d\u8d56\uff1a"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-xml",children:"<dependency>\n    <groupId>org.springframework.ai</groupId>\n    <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>\n</dependency>\n"})}),"\n",(0,i.jsxs)(n.p,{children:["\u5e76\u5c06 ",(0,i.jsx)(n.code,{children:"spring.ai.mcp.server.protocol"})," \u5c5e\u6027\u8bbe\u7f6e\u4e3a ",(0,i.jsx)(n.code,{children:"STREAMABLE"}),"\u3002"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\u5177\u6709 Spring MVC Streamable \u4f20\u8f93\u7684\u5b8c\u6574 MCP \u670d\u52a1\u5668\u529f\u80fd"}),"\n",(0,i.jsx)(n.li,{children:"\u652f\u6301\u5de5\u5177\u3001\u8d44\u6e90\u3001prompts\u3001completion\u3001logging\u3001progression\u3001ping\u3001root-changes \u529f\u80fd"}),"\n",(0,i.jsx)(n.li,{children:"\u6301\u4e45\u8fde\u63a5\u7ba1\u7406"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"streamable-http-webflux-server",children:"Streamable-HTTP WebFlux Server"}),"\n",(0,i.jsxs)(n.p,{children:["\u4f7f\u7528 ",(0,i.jsx)(n.code,{children:"spring-ai-starter-mcp-server-webflux"})," \u4f9d\u8d56\uff1a"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-xml",children:"<dependency>\n    <groupId>org.springframework.ai</groupId>\n    <artifactId>spring-ai-starter-mcp-server-webflux</artifactId>\n</dependency>\n"})}),"\n",(0,i.jsxs)(n.p,{children:["\u5e76\u5c06 ",(0,i.jsx)(n.code,{children:"spring.ai.mcp.server.protocol"})," \u5c5e\u6027\u8bbe\u7f6e\u4e3a ",(0,i.jsx)(n.code,{children:"STREAMABLE"}),"\u3002"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\u5177\u6709 WebFlux Streamable \u4f20\u8f93\u7684\u54cd\u5e94\u5f0f MCP \u670d\u52a1\u5668"}),"\n",(0,i.jsx)(n.li,{children:"\u652f\u6301\u5de5\u5177\u3001\u8d44\u6e90\u3001prompts\u3001completion\u3001logging\u3001progression\u3001ping\u3001root-changes \u529f\u80fd"}),"\n",(0,i.jsx)(n.li,{children:"\u975e\u963b\u585e\u3001\u6301\u4e45\u8fde\u63a5\u7ba1\u7406"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"configuration-properties",children:"Configuration Properties"}),"\n",(0,i.jsx)(n.h3,{id:"common-properties",children:"Common Properties"}),"\n",(0,i.jsxs)(n.p,{children:["\u6240\u6709\u901a\u7528\u5c5e\u6027\u4ee5 ",(0,i.jsx)(n.code,{children:"spring.ai.mcp.server"})," \u4e3a\u524d\u7f00\uff1a"]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Property"}),(0,i.jsx)(n.th,{children:"Description"}),(0,i.jsx)(n.th,{children:"Default"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"enabled"})}),(0,i.jsx)(n.td,{children:"Enable/disable the streamable MCP server"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"true"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"protocol"})}),(0,i.jsx)(n.td,{children:"MCP server protocol"}),(0,i.jsxs)(n.td,{children:["Must be set to ",(0,i.jsx)(n.code,{children:"STREAMABLE"})," to enable the streamable server"]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"tool-callback-converter"})}),(0,i.jsx)(n.td,{children:"Enable/disable the conversion of Spring AI ToolCallbacks into MCP Tool specs"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"true"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"name"})}),(0,i.jsx)(n.td,{children:"Server name for identification"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"mcp-server"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"version"})}),(0,i.jsx)(n.td,{children:"Server version"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"1.0.0"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"instructions"})}),(0,i.jsx)(n.td,{children:"Optional instructions for client interaction"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"null"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"type"})}),(0,i.jsx)(n.td,{children:"Server type (SYNC/ASYNC)"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"SYNC"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"capabilities.resource"})}),(0,i.jsx)(n.td,{children:"Enable/disable resource capabilities"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"true"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"capabilities.tool"})}),(0,i.jsx)(n.td,{children:"Enable/disable tool capabilities"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"true"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"capabilities.prompt"})}
1),(0,i.jsx)(n.td,{children:"Enable/disable prompt capabilities"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"true"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"capabilities.completion"})}),(0,i.jsx)(n.td,{children:"Enable/disable completion capabilities"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"true"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"resource-change-notification"})}),(0,i.jsx)(n.td,{children:"Enable resource change notifications"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"true"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"prompt-change-notification"})}),(0,i.jsx)(n.td,{children:"Enable prompt change notifications"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"true"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"tool-change-notification"})}),(0,i.jsx)(n.td,{children:"Enable tool change notifications"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"true"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"tool-response-mime-type"})}),(0,i.jsx)(n.td,{children:"Response MIME type per tool name"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"-"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"request-timeout"})}),(0,i.jsx)(n.td,{children:"Request timeout duration"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"20 seconds"})})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"mcp-annotations-properties",children:"MCP Annotations Properties"}),"\n",(0,i.jsx)(n.p,{children:"MCP Server Annotations \u63d0\u4f9b\u4e86\u4e00\u79cd\u4f7f\u7528 Java \u6ce8\u89e3\u5b9e\u73b0 MCP \u670d\u52a1\u5668\u5904\u7406\u5668\u7684\u58f0\u660e\u5f0f\u65b9\u6cd5\u3002"}),"\n",(0,i.jsxs)(n.p,{children:["\u670d\u52a1\u5668 mcp-annotations \u5c5e\u6027\u4ee5 ",(0,i.jsx)(n.code,{children:"spring.ai.mcp.server.annotation-scanner"})," \u4e3a\u524d\u7f00\uff1a"]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Property"}),(0,i.jsx)(n.th,{children:"Description"}),(0,i.jsx)(n.th,{children:"Default Value"})]})}),(0,i.jsx)(n.tbody,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"enabled"})}),(0,i.jsx)(n.td,{children:"Enable/disable the MCP server annotations auto-scanning"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"true"})})]})})]}),"\n",(0,i.jsx)(n.h3,{id:"streamable-http-properties",children:"Streamable-HTTP Properties"}),"\n",(0,i.jsxs)(n.p,{children:["\u6240\u6709 streamable-HTTP \u5c5e\u6027\u4ee5 ",(0,i.jsx)(n.code,{children:"spring.ai.mcp.server.streamable-http"})," \u4e3a\u524d\u7f00\uff1a"]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Property"}),(0,i.jsx)(n.th,{children:"Description"}),(0,i.jsx)(n.th,{children:"Default"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"mcp-endpoint"})}),(0,i.jsx)(n.td,{children:"Custom MCP endpoint path"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"/mcp"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"keep-alive-interval"})}),(0,i.jsx)(n.td,{children:"Connection keep-alive interval"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"null"})," (disabled)"]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"disallow-delete"})}),(0,i.jsx)(n.td,{children:"Disallow delete operations"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"false"})})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"features-and-capabilities",children:"Features and Capabilities"}),"\n",(0,i.jsx)(n.p,{children:"MCP \u670d\u52a1\u5668\u652f\u6301\u56db\u79cd\u4e3b\u8981\u529f\u80fd\u7c7b\u578b\uff0c\u53ef\u4ee5\u5355\u72ec\u542f\u7528\u6216\u7981\u7528\uff1a"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Tools"})," - \u4f7f\u7528 ",(0,i.jsx)(n.code,{children:"spring.ai.mcp.server.capabilities.tool=true|false"})," \u542f\u7528/\u7981\u7528\u5de5\u5177\u529f\u80fd"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Resources"})," - \u4f7f\u7528 ",(0,i.jsx)(n.code,{children:"spring.ai.mcp.server.capabilities.resource=true|false"})," \u542f\u7528/\u7981\u7528\u8d44\u6e90\u529f\u80fd"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Prompts"})," - \u4f7f\u7528 ",(0,i.jsx)(n.code,{children:"spring.ai.mcp.server.capabilities.prompt=true|false"})," \u542f\u7528/\u7981\u7528 prompt \u529f\u80fd"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Completions"})," - \u4f7f\u7528 ",(0,i.jsx)(n.code,{children:"spring.ai.mcp.server.capabilities.completion=true|false"})," \u542f\u7528/\u7981\u7528 completion \u529f\u80fd"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u6240\u6709\u529f\u80fd\u90fd\u5df2\u542f\u7528\u3002\u7981\u7528\u529f\u80fd\u5c06\u963b\u6b62\u670d\u52a1\u5668\u5411\u5ba2\u6237\u7aef\u6ce8\u518c\u548c\u66b4\u9732\u76f8\u5e94\u7684\u529f\u80fd\u3002"}),"\n",(0,i.jsx)(n.p,{children:"MCP Server Boot Starter \u5141\u8bb8\u670d\u52a1\u5668\u5411\u5ba2\u6237\u7aef\u66b4\u9732\u5de5\u5177\u3001\u8d44\u
16e90\u548c prompts\u3002\n\u5b83\u6839\u636e\u670d\u52a1\u5668\u7c7b\u578b\u81ea\u52a8\u5c06\u6ce8\u518c\u4e3a Spring beans \u7684\u81ea\u5b9a\u4e49\u529f\u80fd\u5904\u7406\u5668\u8f6c\u6362\u4e3a\u540c\u6b65/\u5f02\u6b65\u89c4\u8303\uff1a"}),"\n",(0,i.jsx)(n.h3,{id:"tools",children:(0,i.jsx)(n.a,{href:"https://modelcontextprotocol.io/specification/2025-03-26/server/tools",children:"Tools"})}),"\n",(0,i.jsx)(n.p,{children:"\u5141\u8bb8\u670d\u52a1\u5668\u66b4\u9732\u53ef\u7531\u8bed\u8a00\u6a21\u578b\u8c03\u7528\u7684\u5de5\u5177\u3002MCP Server Boot Starter \u63d0\u4f9b\uff1a"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\u53d8\u66f4\u901a\u77e5\u652f\u6301"}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"../toolcalls/tool-calls",children:"Spring AI Tools"})," \u6839\u636e\u670d\u52a1\u5668\u7c7b\u578b\u81ea\u52a8\u8f6c\u6362\u4e3a\u540c\u6b65/\u5f02\u6b65\u89c4\u8303"]}),"\n",(0,i.jsx)(n.li,{children:"\u901a\u8fc7 Spring beans \u81ea\u52a8\u5de5\u5177\u89c4\u8303\uff1a"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:"@Bean\npublic ToolCallbackProvider myTools(...) {\n    List<ToolCallback> tools = ...\n    return ToolCallbackProvider.from(tools);\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"\u6216\u4f7f\u7528\u4f4e\u7ea7 API\uff1a"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:"@Bean\npublic List<McpServerFeatures.SyncToolSpecification> myTools(...) {\n    List<McpServerFeatures.SyncToolSpecification> tools = ...\n    return tools;\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"\u81ea\u52a8\u914d\u7f6e\u5c06\u81ea\u52a8\u68c0\u6d4b\u5e76\u6ce8\u518c\u6765\u81ea\u4ee5\u4e0b\u5185\u5bb9\u7684\u6240\u6709\u5de5\u5177\u56de\u8c03\uff1a"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\u5355\u4e2a ",(0,i.jsx)(n.code,{children:"ToolCallback"})," beans"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"ToolCallback"})," beans \u5217\u8868"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"ToolCallbackProvider"})," beans"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"\u5de5\u5177\u6309\u540d\u79f0\u53bb\u91cd\uff0c\u4f7f\u7528\u6bcf\u4e2a\u5de5\u5177\u540d\u79f0\u7684\u7b2c\u4e00\u6b21\u51fa\u73b0\u3002"}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"\u63d0\u793a\uff1a"})," \u60a8\u53ef\u4ee5\u901a\u8fc7\u5c06 ",(0,i.jsx)(n.code,{children:"tool-callback-converter"})," \u8bbe\u7f6e\u4e3a ",(0,i.jsx)(n.code,{children:"false"})," \u6765\u7981\u7528\u6240\u6709\u5de5\u5177\u56de\u8c03\u7684\u81ea\u52a8\u68c0\u6d4b\u548c\u6ce8\u518c\u3002"]}),"\n"]}),"\n",(0,i.jsx)(n.h4,{id:"tool-context-support",children:"Tool Context Support"}),"\n",(0,i.jsxs)(n.p,{children:["\u652f\u6301 ",(0,i.jsx)(n.a,{href:"../toolcalls/tool-calls#_tool_context",children:"ToolContext"}),"\uff0c\u5141\u8bb8\u5c06\u4e0a\u4e0b\u6587\u4fe1\u606f\u4f20\u9012\u7ed9\u5de5\u5177\u8c03\u7528\u3002\u5b83\u5728 ",(0,i.jsx)(n.code,{children:"exchange"})," \u952e\u4e0b\u5305\u542b\u4e00\u4e2a ",(0,i.jsx)(n.code,{children:"McpSyncServerExchange"})," \u5b9e\u4f8b\uff0c\u53ef\u901a\u8fc7 ",(0,i.jsx)(n.code,{children:"McpToolUtils.getMcpExchange(toolContext)"})," \u8bbf\u95ee\u3002\u8bf7\u53c2\u9605\u6b64",(0,i.jsx)(n.a,{href:"https://github.com/spring-projects/spring-ai-examples/blob/3fab8483b8deddc241b1e16b8b049616604b7767/model-context-protocol/sampling/mcp-weather-webmvc-server/src/main/java/org/springframework/ai/mcp/sample/server/WeatherService.java#L59-L126",children:"\u793a\u4f8b"}),"\uff0c\u6f14\u793a ",(0,i.jsx)(n.code,{children:"exchange.loggingNotification(...)"})," \u548c ",(0,i.jsx)(n.code,{children:"exchange.createMessage(...)"}),"\u3002"]}),"\n",(0,i.jsx)(n.h3,{id:"resources",children:(0,i.jsx)(n.a,{href:"https://modelcontextprotocol.io/specification/2025-03-26/server/resources/",children:"Resources"})}),"\n",(0,i.jsx)(n.p,{children:"\u4e3a\u670d\u52a1\u5668\u5411\u5ba2\u6237\u7aef\u66b4\u9732\u8d44\u6e90\u63d0\u4f9b\u6807\u51c6\u5316\u65b9\u5f0f\u3002"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\u9759\u6001\u548c\u52a8\u6001\u8d44\u
16e90\u89c4\u8303"}),"\n",(0,i.jsx)(n.li,{children:"\u53ef\u9009\u7684\u53d8\u66f4\u901a\u77e5"}),"\n",(0,i.jsx)(n.li,{children:"\u652f\u6301\u8d44\u6e90\u6a21\u677f"}),"\n",(0,i.jsx)(n.li,{children:"\u540c\u6b65/\u5f02\u6b65\u8d44\u6e90\u89c4\u8303\u4e4b\u95f4\u7684\u81ea\u52a8\u8f6c\u6362"}),"\n",(0,i.jsx)(n.li,{children:"\u901a\u8fc7 Spring beans \u81ea\u52a8\u8d44\u6e90\u89c4\u8303\uff1a"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:'@Bean\npublic List<McpServerFeatures.SyncResourceSpecification> myResources(...) {\n    var systemInfoResource = new McpSchema.Resource(...);\n    var resourceSpecification = new McpServerFeatures.SyncResourceSpecification(systemInfoResource, (exchange, request) -> {\n        try {\n            var systemInfo = Map.of(...);\n            String jsonContent = new ObjectMapper().writeValueAsString(systemInfo);\n            return new McpSchema.ReadResourceResult(\n                    List.of(new McpSchema.TextResourceContents(request.uri(), "application/json", jsonContent)));\n        }\n        catch (Exception e) {\n            throw new RuntimeException("Failed to generate system info", e);\n        }\n    });\n\n    return List.of(resourceSpecification);\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"prompts",children:(0,i.jsx)(n.a,{href:"https://modelcontextprotocol.io/specification/2025-03-26/server/prompts/",children:"Prompts"})}),"\n",(0,i.jsx)(n.p,{children:"\u4e3a\u670d\u52a1\u5668\u5411\u5ba2\u6237\u7aef\u66b4\u9732 prompt \u6a21\u677f\u63d0\u4f9b\u6807\u51c6\u5316\u65b9\u5f0f\u3002"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\u53d8\u66f4\u901a\u77e5\u652f\u6301"}),"\n",(0,i.jsx)(n.li,{children:"\u6a21\u677f\u7248\u672c\u63a7\u5236"}),"\n",(0,i.jsx)(n.li,{children:"\u540c\u6b65/\u5f02\u6b65 prompt \u89c4\u8303\u4e4b\u95f4\u7684\u81ea\u52a8\u8f6c\u6362"}),"\n",(0,i.jsx)(n.li,{children:"\u901a\u8fc7 Spring beans \u81ea\u52a8 prompt \u89c4\u8303\uff1a"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:'@Bean\npublic List<McpServerFeatures.SyncPromptSpecification> myPrompts() {\n    var prompt = new McpSchema.Prompt("greeting", "A friendly greeting prompt",\n        List.of(new McpSchema.PromptArgument("name", "The name to greet", true)));\n\n    var promptSpecification = new McpServerFeatures.SyncPromptSpecification(prompt, (exchange, getPromptRequest) -> {\n        String nameArgument = (String) getPromptRequest.arguments().get("name");\n        if (nameArgument == null) { nameArgument = "friend"; }\n        var userMessage = new PromptMessage(Role.USER, new TextContent("Hello " + nameArgument + "! How can I assist you today?"));\n        return new GetPromptResult("A personalized greeting message", List.of(userMessage));\n    });\n\n    return List.of(promptSpecification);\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"completions",children:(0,i.jsx)(n.a,{href:"https://modelcontextprotocol.io/specification/2025-03-26/server/utilities/completion/",children:"Completions"})}),"\n",(0,i.jsx)(n.p,{children:"\u4e3a\u670d\u52a1\u5668\u5411\u5ba2\u6237\u7aef\u66b4\u9732 completion \u529f\u80fd\u63d0\u4f9b\u6807\u51c6\u5316\u65b9\u5f0f\u3002"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\u652f\u6301\u540c\u6b65\u548c\u5f02\u6b65 completion \u89c4\u8303"}),"\n",(0,i.jsx)(n.li,{children:"\u901a\u8fc7 Spring beans \u81ea\u52a8\u6ce8\u518c\uff1a"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:'@Bean\npublic List<McpServerFeatures.SyncCompletionSpecification> myCompletions() {\n    var completion = new McpServerFeatures.SyncCompletionSpecification(\n        new McpSchema.PromptReference(\n\t\t\t\t\t"ref/prompt", "code-completion", "Provides code completion suggestions"),\n        (exchange, request) -> {\n            // Implementation that returns completion suggestions\n            return new McpSchema.CompleteResult(List.of("python", "pytorch", "pyside"), 10, true);\n        }\n    );\n\n    return List.of(completion);\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"logging",children:(0,i.jsx)(n.a,{href:"https://modelcontextprotocol.io/specification/2025-03-26/server/utilities/logging/",children:"Logging"})}),"\n",(0,i.jsxs)(n.p,{children:["\u4e3a\u670d\u52a1\u5668\u5411\u5ba2\u6237\u7aef\u53d1\u9001\u7ed3\u6784\u5316\u65e5\u5fd7\u6d88\u606f\u63d0\u4f9b\u6807\u51c6\u5316\u65b9\u5f0f\u3002\n\u4ece\u5de5\u5177\u3001\u8d44\u
16e90\u3001prompt \u6216 completion \u8c03\u7528\u5904\u7406\u5668\u5185\u90e8\uff0c\u4f7f\u7528\u63d0\u4f9b\u7684 ",(0,i.jsx)(n.code,{children:"McpSyncServerExchange"}),"/",(0,i.jsx)(n.code,{children:"McpAsyncServerExchange"})," ",(0,i.jsx)(n.code,{children:"exchange"})," \u5bf9\u8c61\u53d1\u9001\u65e5\u5fd7\u6d88\u606f\uff1a"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:'(exchange, request) -> {\n        exchange.loggingNotification(LoggingMessageNotification.builder()\n            .level(LoggingLevel.INFO)\n            .logger("test-logger")\n            .data("This is a test log message")\n            .build());\n}\n'})}),"\n",(0,i.jsxs)(n.p,{children:["\u5728 MCP \u5ba2\u6237\u7aef\u4e0a\uff0c\u60a8\u53ef\u4ee5\u6ce8\u518c",(0,i.jsx)(n.a,{href:"mcp-client-boot-starter-docs#_customization_types",children:"\u65e5\u5fd7\u6d88\u8d39\u8005"}),"\u6765\u5904\u7406\u8fd9\u4e9b\u6d88\u606f\uff1a"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:"mcpClientSpec.loggingConsumer((McpSchema.LoggingMessageNotification log) -> {\n    // Handle log messages\n});\n"})}),"\n",(0,i.jsx)(n.h3,{id:"progress",children:(0,i.jsx)(n.a,{href:"https://modelcontextprotocol.io/specification/2025-03-26/basic/utilities/progress",children:"Progress"})}),"\n",(0,i.jsxs)(n.p,{children:["\u4e3a\u670d\u52a1\u5668\u5411\u5ba2\u6237\u7aef\u53d1\u9001\u8fdb\u5ea6\u66f4\u65b0\u63d0\u4f9b\u6807\u51c6\u5316\u65b9\u5f0f\u3002\n\u4ece\u5de5\u5177\u3001\u8d44\u6e90\u3001prompt \u6216 completion \u8c03\u7528\u5904\u7406\u5668\u5185\u90e8\uff0c\u4f7f\u7528\u63d0\u4f9b\u7684 ",(0,i.jsx)(n.code,{children:"McpSyncServerExchange"}),"/",(0,i.jsx)(n.code,{children:"McpAsyncServerExchange"})," ",(0,i.jsx)(n.code,{children:"exchange"})," \u5bf9\u8c61\u53d1\u9001\u8fdb\u5ea6\u901a\u77e5\uff1a"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:'(exchange, request) -> {\n        exchange.progressNotification(ProgressNotification.builder()\n            .progressToken("test-progress-token")\n            .progress(0.25)\n            .total(1.0)\n            .message("tool call in progress")\n            .build());\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:"MCP \u5ba2\u6237\u7aef\u53ef\u4ee5\u63a5\u6536\u8fdb\u5ea6\u901a\u77e5\u5e76\u76f8\u5e94\u5730\u66f4\u65b0\u5176 UI\u3002\n\u4e3a\u6b64\uff0c\u5b83\u9700\u8981\u6ce8\u518c\u4e00\u4e2a\u8fdb\u5ea6\u6d88\u8d39\u8005\u3002"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:"mcpClientSpec.progressConsumer((McpSchema.ProgressNotification progress) -> {\n    // Handle progress notifications\n});\n"})}),"\n",(0,i.jsx)(n.h3,{id:"root-list-changes",children:(0,i.jsx)(n.a,{href:"https://modelcontextprotocol.io/specification/2025-03-26/client/roots#root-list-changes",children:"Root List Changes"})}),"\n",(0,i.jsxs)(n.p,{children:["\u5f53 roots \u66f4\u6539\u65f6\uff0c\u652f\u6301 ",(0,i.jsx)(n.code,{children:"listChanged"})," \u7684\u5ba2\u6237\u7aef\u4f1a\u53d1\u9001 root \u53d8\u66f4\u901a\u77e5\u3002"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\u652f\u6301\u76d1\u63a7 root \u53d8\u66f4"}),"\n",(0,i.jsx)(n.li,{children:"\u81ea\u52a8\u8f6c\u6362\u4e3a\u54cd\u5e94\u5f0f\u5e94\u7528\u7a0b\u5e8f\u7684\u5f02\u6b65\u6d88\u8d39\u8005"}),"\n",(0,i.jsx)(n.li,{children:"\u901a\u8fc7 Spring beans \u53ef\u9009\u6ce8\u518c"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:'@Bean\npublic BiConsumer<McpSyncServerExchange, List<McpSchema.Root>> rootsChangeHandler() {\n    return (exchange, roots) -> {\n        logger.info("Registering root resources: {}", roots);\n    };\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"ping",children:(0,i.jsx)(n.a,{href:"https://modelcontextprotocol.io/specification/2025-03-26/basic/utilities/ping/",children:"Ping"})}),"\n",(0,i.jsxs)(n.p,{children:["\u670d\u52a1\u5668\u9a8c\u8bc1\u5176\u5ba2\u6237\u7aef\u662f\u5426\u4ecd\u7136\u5b58\u6d3b\u7684 ping \u673a\u5236\u3002\n\u4ece\u5de5\u5177\u3001\u8d44\u6e90\u3001prompt \u6216 completion \u8c03\u7528\u5904\u7406\u5668\u5185\u90e8\uff0c\u4f7f\u7528\u63d0\u4f9b\u7684 ",(0,i.jsx)(n.code,{children:"McpSyncServerExchange"}),"/",(0,i.jsx)(n.code,{children:"McpAsyncServerExchange"})," ",(0,i.jsx)(n.code,{children:"exchange"})," \u5bf9\u8c61\u53d1\u9001 ping \u6d88\u606f\uff1a"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:"(exchange, request) -> {\n        exchange.ping();\n}\n"})}),"\n",(0,i.jsx)(n.h3,{id:"keep-alive",children:"Keep Alive"}),"\n",(0,i.jsx)(n.p,{children:"\u670d\u52a1\u5668\u53ef\u4ee5\u53ef\u9009\u5730\u5b9a\u671f\u5411\u8fde\u63a5\u7684\u5ba2\u6237\u7aef\u53d1\u9001 ping \u4ee5\u9a8c\u8bc1\u8fde\u63a5\u5065\u5eb7\u3002"}),"\n",(0,i.jsxs)(n.p,{children:["\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0ckeep-alive \u88ab\u7981\u7528\u3002\n\u8981\u542f\u7528 keep-alive\uff0c\u8bf7\u5728\u914d\u7f6e\u4e2d\u8bbe\u7f6e ",(0,i.jsx)(n.code,{children:"keep-alive-interval"})," \u5c5e\u6027\uff1a"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"spring:\n  ai:\n    mcp:\n      server:\n        streamable-http:\n          keep-alive-interval: 30s\n"})}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"\u6ce8\u610f\uff1a"})," \u76ee\u524d\uff0c\u5bf9\u4e8e streamable-http \u670d\u52a1\u5668\uff0ckeep-alive \u673a\u5236\u4ec5\u9002\u7528\u4e8e ",(0,i.jsx)(n.a,{href:"https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#listening-for-messages-from-the-server",children:"Listening for Messages from the Server (SSE)"}
1)," \u8fde\u63a5\u3002"]}),"\n",(0,i.jsx)(n.h2,{id:"usage-examples",children:"Usage Examples"}),"\n",(0,i.jsx)(n.h3,{id:"streamable-http-server-configuration",children:"Streamable HTTP Server Configuration"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# Using spring-ai-starter-mcp-server-streamable-webmvc\nspring:\n  ai:\n    mcp:\n      server:\n        protocol: STREAMABLE\n        name: streamable-mcp-server\n        version: 1.0.0\n        type: SYNC\n        instructions: "This streamable server provides real-time notifications"\n        resource-change-notification: true\n        tool-change-notification: true\n        prompt-change-notification: true\n        streamable-http:\n          mcp-endpoint: /api/mcp\n          keep-alive-interval: 30s\n'})}),"\n",(0,i.jsx)(n.h3,{id:"creating-a-spring-boot-application-with-mcp-server",children:"Creating a Spring Boot Application with MCP Server"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:'@Service\npublic class WeatherService {\n\n    @Tool(description = "Get weather information by city name")\n    public String getWeather(String cityName) {\n        // Implementation\n    }\n}\n\n@SpringBootApplication\npublic class McpServerApplication {\n\n    private static final Logger logger = LoggerFactory.getLogger(McpServerApplication.class);\n\n    public static void main(String[] args) {\n        SpringApplication.run(McpServerApplication.class, args);\n    }\n\n\t@Bean\n\tpublic ToolCallbackProvider weatherTools(WeatherService weatherService) {\n\t\treturn MethodToolCallbackProvider.builder().toolObjects(weatherService).build();\n\t}\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:"\u81ea\u52a8\u914d\u7f6e\u5c06\u81ea\u52a8\u5c06\u5de5\u5177\u56de\u8c03\u6ce8\u518c\u4e3a MCP \u5de5\u5177\u3002\n\u60a8\u53ef\u4ee5\u6709\u591a\u4e2a\u4ea7\u751f ToolCallbacks \u7684 beans\uff0c\u81ea\u52a8\u914d\u7f6e\u4f1a\u5c06\u5b83\u4eec\u5408\u5e76\u3002"})]})}function p(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>c,x:()=>l});var s=r(96540);const i={},t=s.createContext(i);function c(e){const n=s.useContext(t);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.