Skip to content

Commit adc6143

Browse files
RainYuYheliang666ssongxiaoshengwcy666103
authored
Dubbo MCP Integration (#15406)
* move dubbo-mcp-sdk to dubbo plugin * Added configuration options for MCP, switches, and SSE path ports, and optimized the port selection logic when configurations are not provided. * Edit error log,Let it print error code * Edit sessions as ExpiringCache. Add errorCode. Add unitTest * support @DubboService annotation for service control, optimize logging and refactor package structure * code format * Fix the log format and translate all Chinese comments into English. Optimize some code. * Add the @mcptool and @McpToolParam annotations to support customized exposure of MCP services. * support dynamic MCP tool registration and correct URL-based configuration parsing * fix:log format * add attribute = false * code format * fix move file path * add unit tests * fix unit tests * optimize error throw * optimize error throw * fix unit test * move the demo dic * update mcp-jdk version * update mcp-jdk version * base and update version * base and update version * provider * register streamable service * Change the response type from String to byte[] to avoid double serialization of JSON. * streamable 接入 * error code fix * fix npe * demo also need jdk 17 * demo also need jdk 17 * fix param name * remove netty class * add streamTest * transport provider init * fix logger problem. * fix logger problem. * feat:mcp expire config * Enable the capability of resuming transmission at breakpoints * change is to get * update mcp version * update mcp version * disable MCP service initialization by default * add change set --------- Co-authored-by: heliang <[email protected]> Co-authored-by: heliang666s <[email protected]> Co-authored-by: Stellar <[email protected]> Co-authored-by: xiaosheng <[email protected]> Co-authored-by: 王聪洋 <[email protected]>
1 parent f2d5ba9 commit adc6143

File tree

54 files changed

+6196
-0
lines changed

Some content is hidden

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

54 files changed

+6196
-0
lines changed

.artifacts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ dubbo-filter-cache
4141
dubbo-filter-validation
4242
dubbo-kubernetes
4343
dubbo-maven-plugin
44+
dubbo-mcp
4445
dubbo-metadata
4546
dubbo-metadata-api
4647
dubbo-metadata-definition-protobuf

dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,9 @@ public interface LoggerCodeConstants {
439439

440440
String QOS_PERMISSION_DENY_EXCEPTION = "7-7";
441441

442+
// MCP plugin
443+
String MCP_FAILED_START_SERVER = "8-1";
444+
442445
// Testing module (8[X], where [X] is number of the module to be tested.)
443446
String TESTING_REGISTRY_FAILED_TO_START_ZOOKEEPER = "81-1";
444447

dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboService.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,4 +354,11 @@
354354
* The configuration supports multiple, which are separated by commas.Such as:<code>fastjson2,fastjson,hessian2</code>
355355
*/
356356
String preferSerialization() default "";
357+
358+
/**
359+
* Whether to expose methods in this service as MCP tools, default value is false
360+
* This controls whether methods in this service class can be exposed as MCP tools.
361+
* Specific method-level configuration should be done via method annotations.
362+
*/
363+
boolean mcpEnabled() default false;
357364
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.dubbo.config.nested;
18+
19+
import org.apache.dubbo.config.support.Nested;
20+
21+
import java.io.Serializable;
22+
23+
public class McpConfig implements Serializable {
24+
25+
private static final long serialVersionUID = 6943417856234001947L;
26+
27+
/**
28+
* Whether to enable MCP Server support
29+
* <p>The default value is 'true'.
30+
*/
31+
private Boolean enabled;
32+
33+
/**
34+
* The port of MCP Server
35+
* <p>The default value is '0'.
36+
*/
37+
private Integer port;
38+
39+
/**
40+
* the path of mcp
41+
*/
42+
@Nested
43+
private MCPPath path;
44+
45+
/**
46+
* streamable or sse
47+
*/
48+
private String protocol;
49+
50+
/**
51+
* Session timeout in milliseconds for long connection
52+
* unit: seconds
53+
*/
54+
private Integer sessionTimeout;
55+
56+
public Boolean getEnabled() {
57+
return enabled;
58+
}
59+
60+
public void setEnabled(Boolean enabled) {
61+
this.enabled = enabled;
62+
}
63+
64+
public Integer getPort() {
65+
return port;
66+
}
67+
68+
public void setPort(Integer port) {
69+
this.port = port;
70+
}
71+
72+
public MCPPath getPath() {
73+
return path;
74+
}
75+
76+
public void setPath(MCPPath path) {
77+
this.path = path;
78+
}
79+
80+
public String getProtocol() {
81+
return protocol;
82+
}
83+
84+
public void setProtocol(String protocol) {
85+
this.protocol = protocol;
86+
}
87+
88+
public Integer getSessionTimeout() {
89+
return sessionTimeout;
90+
}
91+
92+
public void setSessionTimeout(Integer sessionTimeout) {
93+
this.sessionTimeout = sessionTimeout;
94+
}
95+
96+
public static class MCPPath implements Serializable {
97+
98+
private static final long serialVersionUID = 6943417856234837947L;
99+
100+
/**
101+
* The path of mcp message
102+
* <p>The default value is '/mcp/message'.
103+
*/
104+
private String message;
105+
106+
/**
107+
* The path of mcp sse
108+
* <p>The default value is '/mcp/sse'.
109+
*/
110+
private String sse;
111+
112+
public String getMessage() {
113+
return message;
114+
}
115+
116+
public void setMessage(String message) {
117+
this.message = message;
118+
}
119+
120+
public String getSse() {
121+
return sse;
122+
}
123+
124+
public void setSse(String sse) {
125+
this.sse = sse;
126+
}
127+
}
128+
}

dubbo-common/src/main/java/org/apache/dubbo/config/nested/RestConfig.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ public class RestConfig implements Serializable {
9797
@Nested
9898
private OpenAPIConfig openapi;
9999

100+
/**
101+
* The Mcp configuration.
102+
*/
103+
@Nested
104+
private McpConfig mcp;
105+
100106
/**
101107
* Multiple configurations for openapi.
102108
*/
@@ -212,6 +218,16 @@ public void setOpenapi(OpenAPIConfig openapi) {
212218
this.openapi = openapi;
213219
}
214220

221+
@Parameter(excluded = true)
222+
public McpConfig getMcp() {
223+
return mcp;
224+
}
225+
226+
@Parameter(attribute = false)
227+
public void setMcp(McpConfig mcp) {
228+
this.mcp = mcp;
229+
}
230+
215231
@Parameter(excluded = true)
216232
public Map<String, OpenAPIConfig> getOpenapis() {
217233
return openapis;

dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
163163

164164
private final List<ServiceListener> serviceListeners = new ArrayList<>();
165165

166+
/**
167+
* Whether to expose methods in this service as MCP tools, default value is false
168+
*/
169+
private boolean mcpEnabled = false;
170+
166171
public ServiceConfig() {}
167172

168173
public ServiceConfig(ModuleModel moduleModel) {
@@ -196,6 +201,15 @@ public boolean isUnexported() {
196201
return unexported;
197202
}
198203

204+
@Parameter(attribute = false, key = "mcp.enabled")
205+
public boolean isMcpEnabled() {
206+
return mcpEnabled;
207+
}
208+
209+
public void setMcpEnabled(boolean mcpEnabled) {
210+
this.mcpEnabled = mcpEnabled;
211+
}
212+
199213
@Override
200214
public synchronized void unexport() {
201215
if (!exported) {
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Licensed to the Apache Software Foundation (ASF) under one or more
4+
contributor license agreements. See the NOTICE file distributed with
5+
this work for additional information regarding copyright ownership.
6+
The ASF licenses this file to You under the Apache License, Version 2.0
7+
(the "License"); you may not use this file except in compliance with
8+
the License. You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
-->
18+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
19+
<modelVersion>4.0.0</modelVersion>
20+
<parent>
21+
<groupId>org.apache.dubbo</groupId>
22+
<artifactId>dubbo-parent</artifactId>
23+
<version>${revision}</version>
24+
<relativePath>../../pom.xml</relativePath>
25+
</parent>
26+
<artifactId>dubbo-demo-mcp-server</artifactId>
27+
28+
<properties>
29+
<spring-boot-maven-plugin.version>2.7.18</spring-boot-maven-plugin.version>
30+
</properties>
31+
32+
<dependencies>
33+
<dependency>
34+
<groupId>org.apache.dubbo</groupId>
35+
<artifactId>dubbo-registry-zookeeper</artifactId>
36+
<version>${project.version}</version>
37+
</dependency>
38+
<dependency>
39+
<groupId>org.apache.dubbo</groupId>
40+
<artifactId>dubbo-rpc-triple</artifactId>
41+
<version>${project.version}</version>
42+
<exclusions>
43+
<exclusion>
44+
<groupId>com.google.protobuf</groupId>
45+
<artifactId>protobuf-java-util</artifactId>
46+
</exclusion>
47+
<exclusion>
48+
<groupId>com.google.protobuf</groupId>
49+
<artifactId>protobuf-java</artifactId>
50+
</exclusion>
51+
</exclusions>
52+
</dependency>
53+
<dependency>
54+
<groupId>org.apache.dubbo</groupId>
55+
<artifactId>dubbo-triple-servlet</artifactId>
56+
<version>${project.version}</version>
57+
</dependency>
58+
<dependency>
59+
<groupId>org.apache.dubbo</groupId>
60+
<artifactId>dubbo-rest-openapi</artifactId>
61+
<version>${project.version}</version>
62+
</dependency>
63+
<dependency>
64+
<groupId>org.apache.dubbo</groupId>
65+
<artifactId>dubbo-serialization-hessian2</artifactId>
66+
<version>${project.version}</version>
67+
</dependency>
68+
<dependency>
69+
<groupId>org.apache.dubbo</groupId>
70+
<artifactId>dubbo-remoting-netty4</artifactId>
71+
<version>${project.version}</version>
72+
</dependency>
73+
<dependency>
74+
<groupId>org.apache.dubbo</groupId>
75+
<artifactId>dubbo-mcp</artifactId>
76+
<version>${project.version}</version>
77+
</dependency>
78+
<dependency>
79+
<groupId>org.apache.dubbo</groupId>
80+
<artifactId>dubbo-config-spring</artifactId>
81+
<version>${project.version}</version>
82+
</dependency>
83+
84+
<dependency>
85+
<groupId>org.apache.dubbo</groupId>
86+
<artifactId>dubbo-spring-boot-autoconfigure</artifactId>
87+
<version>${project.version}</version>
88+
<exclusions>
89+
<exclusion>
90+
<groupId>org.apache.dubbo</groupId>
91+
<artifactId>dubbo</artifactId>
92+
</exclusion>
93+
</exclusions>
94+
</dependency>
95+
<dependency>
96+
<groupId>org.springframework.boot</groupId>
97+
<artifactId>spring-boot-starter-log4j2</artifactId>
98+
</dependency>
99+
<dependency>
100+
<groupId>org.springframework.boot</groupId>
101+
<artifactId>spring-boot-starter</artifactId>
102+
<exclusions>
103+
<exclusion>
104+
<groupId>org.springframework.boot</groupId>
105+
<artifactId>spring-boot-starter-logging</artifactId>
106+
</exclusion>
107+
</exclusions>
108+
</dependency>
109+
110+
<!-- generate json format javadoc for openapi -->
111+
<dependency>
112+
<groupId>com.github.therapi</groupId>
113+
<artifactId>therapi-runtime-javadoc-scribe</artifactId>
114+
<version>0.15.0</version>
115+
<scope>provided</scope>
116+
</dependency>
117+
</dependencies>
118+
119+
<build>
120+
<plugins>
121+
<plugin>
122+
<groupId>org.springframework.boot</groupId>
123+
<artifactId>spring-boot-maven-plugin</artifactId>
124+
<version>${spring-boot-maven-plugin.version}</version>
125+
</plugin>
126+
<plugin>
127+
<groupId>org.apache.maven.plugins</groupId>
128+
<artifactId>maven-compiler-plugin</artifactId>
129+
<configuration>
130+
<compilerArgs>
131+
<compilerArg>-parameters</compilerArg>
132+
</compilerArgs>
133+
</configuration>
134+
</plugin>
135+
</plugins>
136+
</build>
137+
138+
<profiles>
139+
<profile>
140+
<id>jdk-version-ge-17</id>
141+
<activation>
142+
<jdk>[17,)</jdk>
143+
</activation>
144+
<dependencies>
145+
<dependency>
146+
<groupId>org.apache.dubbo</groupId>
147+
<artifactId>dubbo-spring-boot-3-autoconfigure</artifactId>
148+
<version>${project.version}</version>
149+
</dependency>
150+
</dependencies>
151+
</profile>
152+
</profiles>
153+
</project>

0 commit comments

Comments
 (0)