Skip to content

Commit eb63315

Browse files
authored
feat : mcp document (#249)
* feat : mcp document * fix * fix lint * fix lint * fix lint * fix lint * fix lint table-column-style
1 parent 92eb356 commit eb63315

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1947
-262
lines changed

.markdownlint.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"default": true,
3+
"MD003": false,
4+
"MD025": false,
5+
"MD013": false,
6+
"MD014": false,
7+
"MD024": false,
8+
"MD026": false,
9+
"MD029": false,
10+
"MD033": false,
11+
"MD034": false,
12+
"MD040": false,
13+
"MD041": false,
14+
"MD036": false,
15+
"MD037": false,
16+
"MD046": false,
17+
"MD022": false,
18+
"MD009": false,
19+
"MD005": false,
20+
"MD001": false,
21+
"MD060": false
22+
}

blog/spring-ai-mcp-desc.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ java版的MCP源码:https://github.com/modelcontextprotocol/java-sdk
1818

1919
## 理论部分
2020

21-
![Image](/img/blog/mcp-desc/overall.PNG)
22-
2321
### MCP调用链路(核心)
2422

2523
以client-webflux、server-webflux为例

docusaurus.config.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -325,9 +325,9 @@ const config: Config = {
325325
image: 'img/social-card.jpg',
326326
// Enhanced metadata for SEO
327327
metadata: [
328-
{name: 'keywords', content: 'Spring AI Alibaba, Agent Framework, ReactAgent, Graph, Multi-Agent, Java AI, 智能体, AI开发框架'},
329-
{name: 'twitter:card', content: 'summary_large_image'},
330-
{property: 'og:type', content: 'website'},
328+
{ name: 'keywords', content: 'Spring AI Alibaba, Agent Framework, ReactAgent, Graph, Multi-Agent, Java AI, 智能体, AI开发框架' },
329+
{ name: 'twitter:card', content: 'summary_large_image' },
330+
{ property: 'og:type', content: 'website' },
331331
],
332332
// Disable search functionality
333333
algolia: undefined,

ecosystem/spring-ai/reference/MCP.md

Lines changed: 0 additions & 114 deletions
This file was deleted.
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# MCP 服务认证
2+
3+
背景:MCP Server 服务,只为携带特定请求头 token 的提供服务
4+
5+
示例代码
6+
7+
- server:[https://github.com/spring-ai-alibaba/examples/tree/main/spring-ai-alibaba-mcp-example/spring-ai-alibaba-mcp-auth-example/server/mcp-auth-web-server](https://github.com/spring-ai-alibaba/examples/tree/main/spring-ai-alibaba-mcp-example/spring-ai-alibaba-mcp-auth-example/server/mcp-auth-web-server)
8+
- client:[https://github.com/spring-ai-alibaba/examples/tree/main/spring-ai-alibaba-mcp-example/spring-ai-alibaba-mcp-auth-example/client/mcp-auth-client](https://github.com/spring-ai-alibaba/examples/tree/main/spring-ai-alibaba-mcp-example/spring-ai-alibaba-mcp-auth-example/client/mcp-auth-client)
9+
10+
## server
11+
12+
### pom 依赖
13+
14+
```xml
15+
<dependencies>
16+
<dependency>
17+
<groupId>org.springframework.ai</groupId>
18+
<artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
19+
</dependency>
20+
</dependencies>
21+
```
22+
23+
### application 文件
24+
25+
```yaml
26+
server:
27+
port: 20000
28+
29+
spring:
30+
application:
31+
name: mcp-auth-web-server
32+
ai:
33+
mcp:
34+
server:
35+
name: streamable-mcp-server
36+
protocol: STREAMABLE # SSE、STREAMABLE、STATELESS
37+
version: 1.0.0
38+
type: ASYNC # Recommended for reactive applications
39+
instructions: "This reactive server provides time information tools and resources"
40+
request-timeout: 20s
41+
streamable-http:
42+
mcp-endpoint: /mcp
43+
keep-alive-interval: 30s
44+
disallow-delete: false
45+
```
46+
47+
### 过滤器链(核心)
48+
49+
```java
50+
@Component
51+
public class McpServerFilter implements WebFilter {
52+
53+
private static final String TOKENHEADER = "token-1";
54+
private static final String TOKENVALUE = "yingzi-1";
55+
56+
private static final Logger logger = LoggerFactory.getLogger(McpServerFilter.class);
57+
58+
@Override
59+
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
60+
// 获取请求头中的token值
61+
HttpHeaders headers = exchange.getRequest().getHeaders();
62+
// 打印所有请求头信息
63+
for (String headerName : headers.keySet()) {
64+
logger.info("Header {}: {}", headerName, headers.getFirst(headerName));
65+
}
66+
67+
String token = headers.getFirst(TOKENHEADER);
68+
// 检查token是否存在且值正确
69+
if (TOKENVALUE.equals(token)) {
70+
logger.info("preHandle: 验证通过");
71+
logger.info("preHandle: 请求的URL: {}", exchange.getRequest().getURI());
72+
logger.info("preHandle: 请求的TOKEN: {}", token);
73+
// token验证通过,继续处理请求
74+
return chain.filter(exchange);
75+
} else {
76+
// token验证失败,返回401未授权错误
77+
logger.warn("Token验证失败: 请求的URL: {}, 提供的TOKEN: {}", exchange.getRequest().getURI(), token);
78+
logger.warn("要求的token为:{}", TOKENVALUE);
79+
exchange.getResponse().setStatusCode(org.springframework.http.HttpStatus.UNAUTHORIZED);
80+
return exchange.getResponse().setComplete();
81+
}
82+
}
83+
}
84+
```
85+
86+
实现 WebFilter,只对存在请求头 token-1,且只为 yingzi-1 的连接放行。
87+
88+
## client
89+
90+
### pom 依赖
91+
92+
```xml
93+
<dependencies>
94+
95+
<dependency>
96+
<groupId>org.springframework.ai</groupId>
97+
<artifactId>spring-ai-starter-mcp-client</artifactId>
98+
</dependency>
99+
100+
<dependency>
101+
<groupId>com.alibaba.cloud.ai</groupId>
102+
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
103+
</dependency>
104+
105+
</dependencies>
106+
```
107+
108+
### application 文件
109+
110+
```yaml
111+
server:
112+
port: 19100
113+
114+
spring:
115+
application:
116+
name: mcp-auth-client
117+
main:
118+
web-application-type: none
119+
ai:
120+
dashscope:
121+
api-key: ${AIDASHSCOPEAPIKEY}
122+
123+
mcp:
124+
client:
125+
enabled: true
126+
name: my-mcp-client
127+
version: 1.0.0
128+
request-timeout: 600s
129+
type: ASYNC # or ASYNC for reactive applications
130+
streamable-http:
131+
connections:
132+
server1:
133+
url: http://localhost:20000
134+
endpoint: /mcp
135+
```
136+
137+
### HTTP 请求配置
138+
139+
自定义 McpSyncHttpClientRequestCustomizer 接口类,为 HttpRequest.Builder 配置请求头信息
140+
141+
```java
142+
public class HeaderSyncHttpRequestCustomizer implements McpSyncHttpClientRequestCustomizer {
143+
144+
private final Map<String, String> headers;
145+
146+
public HeaderSyncHttpRequestCustomizer(Map<String, String> headers) {
147+
this.headers = headers;
148+
}
149+
150+
@Override
151+
public void customize(HttpRequest.Builder builder, String method, URI endpoint, String body, McpTransportContext context) {
152+
headers.forEach(builder::header);
153+
}
154+
}
155+
156+
@Configuration
157+
public class HttpClientConfig {
158+
159+
@Bean
160+
public McpSyncHttpClientRequestCustomizer mcpAsyncHttpClientRequestCustomizer() {
161+
Map<String, String> headers = new HashMap<>();
162+
headers.put("token-1", "yingzi-1");
163+
headers.put("token-2", "yingzi-2");
164+
165+
return new HeaderSyncHttpRequestCustomizer(headers);
166+
}
167+
}
168+
```
169+
170+
## 验证
171+
172+
当 mcp client 侧携带对应请求头 kv 对`{token-1:yingzi-1}`时,通过,否则将不予连接
173+
![mcp-auth-1](/img/blog/base/mcp/mcp-auth-1.png)
174+
175+
![mcp-auth-2](/img/blog/base/mcp/mcp-auth-2.png)
File renamed without changes.

0 commit comments

Comments
 (0)