Skip to content

Commit 4d0206b

Browse files
eddumelendezilayaperumalg
authored andcommitted
Add Testcontainers Service Connection support for docker/mcp-gateway
Signed-off-by: Eddú Meléndez <eddu.melendez@gmail.com>
1 parent 711414d commit 4d0206b

File tree

5 files changed

+136
-0
lines changed

5 files changed

+136
-0
lines changed

spring-ai-docs/src/main/antora/modules/ROOT/pages/api/testcontainers.adoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ The following service connection factories are provided in the `spring-ai-spring
3838
| `ChromaConnectionDetails`
3939
| Containers of type `ChromaDBContainer`
4040

41+
| `McpSseClientConnectionDetails`
42+
| Containers of type `DockerMcpGatewayContainer`
43+
4144
| `MilvusServiceClientConnectionDetails`
4245
| Containers of type `MilvusContainer`
4346

spring-ai-spring-boot-testcontainers/pom.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,20 @@
101101
<optional>true</optional>
102102
</dependency>
103103

104+
<dependency>
105+
<groupId>org.springframework.ai</groupId>
106+
<artifactId>spring-ai-autoconfigure-mcp-client-httpclient</artifactId>
107+
<version>${project.version}</version>
108+
<optional>true</optional>
109+
</dependency>
110+
111+
<dependency>
112+
<groupId>org.springframework.ai</groupId>
113+
<artifactId>spring-ai-autoconfigure-mcp-client-webflux</artifactId>
114+
<version>${project.version}</version>
115+
<optional>true</optional>
116+
</dependency>
117+
104118
<!-- production dependencies -->
105119

106120
<dependency>
@@ -239,6 +253,7 @@
239253
<dependency>
240254
<groupId>org.testcontainers</groupId>
241255
<artifactId>testcontainers</artifactId>
256+
<version>1.21.3</version>
242257
<optional>true</optional>
243258
</dependency>
244259

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 2023-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ai.testcontainers.service.connection.docker;
18+
19+
import java.util.Map;
20+
21+
import org.testcontainers.containers.DockerMcpGatewayContainer;
22+
23+
import org.springframework.ai.mcp.client.common.autoconfigure.McpSseClientConnectionDetails;
24+
import org.springframework.ai.mcp.client.common.autoconfigure.properties.McpSseClientProperties;
25+
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory;
26+
import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource;
27+
28+
/**
29+
* @author Eddú Meléndez
30+
*/
31+
class DockerMcpGatewayContainerConnectionDetailsFactory
32+
extends ContainerConnectionDetailsFactory<DockerMcpGatewayContainer, McpSseClientConnectionDetails> {
33+
34+
@Override
35+
public McpSseClientConnectionDetails getContainerConnectionDetails(
36+
ContainerConnectionSource<DockerMcpGatewayContainer> source) {
37+
return new DockerMcpGatewayContainerConnectionDetails(source);
38+
}
39+
40+
/**
41+
* {@link McpSseClientConnectionDetails} backed by a
42+
* {@link ContainerConnectionSource}.
43+
*/
44+
private static final class DockerMcpGatewayContainerConnectionDetails
45+
extends ContainerConnectionDetails<DockerMcpGatewayContainer> implements McpSseClientConnectionDetails {
46+
47+
private DockerMcpGatewayContainerConnectionDetails(
48+
ContainerConnectionSource<DockerMcpGatewayContainer> source) {
49+
super(source);
50+
}
51+
52+
@Override
53+
public Map<String, McpSseClientProperties.SseParameters> getConnections() {
54+
return Map.of("gateway", new McpSseClientProperties.SseParameters(getContainer().getEndpoint(), "/sse"));
55+
}
56+
57+
}
58+
59+
}

spring-ai-spring-boot-testcontainers/src/main/resources/META-INF/spring.factories

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#
1616
org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\
1717
org.springframework.ai.testcontainers.service.connection.chroma.ChromaContainerConnectionDetailsFactory,\
18+
org.springframework.ai.testcontainers.service.connection.docker.DockerMcpGatewayContainerConnectionDetailsFactory,\
1819
org.springframework.ai.testcontainers.service.connection.milvus.MilvusContainerConnectionDetailsFactory,\
1920
org.springframework.ai.testcontainers.service.connection.mongo.MongoDbAtlasLocalContainerConnectionDetailsFactory,\
2021
org.springframework.ai.testcontainers.service.connection.ollama.OllamaContainerConnectionDetailsFactory,\
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2023-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ai.testcontainers.service.connection.docker;
18+
19+
import org.junit.jupiter.api.Test;
20+
import org.testcontainers.containers.DockerMcpGatewayContainer;
21+
import org.testcontainers.junit.jupiter.Container;
22+
import org.testcontainers.junit.jupiter.Testcontainers;
23+
24+
import org.springframework.ai.mcp.client.common.autoconfigure.McpSseClientConnectionDetails;
25+
import org.springframework.ai.mcp.client.common.autoconfigure.properties.McpSseClientProperties;
26+
import org.springframework.ai.mcp.client.httpclient.autoconfigure.SseHttpClientTransportAutoConfiguration;
27+
import org.springframework.beans.factory.annotation.Autowired;
28+
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
29+
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
30+
import org.springframework.context.annotation.Configuration;
31+
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
32+
33+
import static org.assertj.core.api.Assertions.assertThat;
34+
35+
@SpringJUnitConfig
36+
@Testcontainers
37+
class DockerMcpGatewayContainerConnectionDetailsFactoryIT {
38+
39+
@Container
40+
@ServiceConnection
41+
private static final DockerMcpGatewayContainer MCP_GATEWAY = new DockerMcpGatewayContainer("docker/mcp-gateway:v2");
42+
43+
@Autowired
44+
private McpSseClientConnectionDetails connectionDetails;
45+
46+
@Test
47+
void test() {
48+
assertThat(this.connectionDetails.getConnections()).containsEntry("gateway",
49+
new McpSseClientProperties.SseParameters(MCP_GATEWAY.getEndpoint(), "/sse"));
50+
}
51+
52+
@Configuration(proxyBeanMethods = false)
53+
@ImportAutoConfiguration(SseHttpClientTransportAutoConfiguration.class)
54+
static class Config {
55+
56+
}
57+
58+
}

0 commit comments

Comments
 (0)