Skip to content

Commit 3003b65

Browse files
authored
Merge branch 'main' into feature/SEP-2243-Mcp-Name-in-header
2 parents f229279 + 301f8b0 commit 3003b65

64 files changed

Lines changed: 3969 additions & 942 deletions

File tree

Some content is hidden

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

.github/workflows/conformance.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ jobs:
9595
run: mvn clean install -DskipTests
9696

9797
- name: Run conformance test
98-
uses: modelcontextprotocol/conformance@v0.1.15
98+
uses: modelcontextprotocol/conformance@v0.1.16
9999
with:
100100
node-version: '22' # see https://github.com/modelcontextprotocol/conformance/pull/162
101101
mode: client

MIGRATION-2.0.md

Lines changed: 180 additions & 89 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,15 @@ npx @modelcontextprotocol/conformance server --url http://localhost:8080/mcp --s
6464
./mvnw clean package -DskipTests -pl conformance-tests/client-jdk-http-client -am
6565
for scenario in initialize tools_call elicitation-sep1034-client-defaults sse-retry; do
6666
npx @modelcontextprotocol/conformance client \
67-
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-2.0.0-SNAPSHOT.jar" \
67+
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-2.0.1-SNAPSHOT.jar" \
6868
--scenario $scenario
6969
done
7070

7171
# Auth conformance (Spring HTTP Client)
7272
./mvnw clean package -DskipTests -pl conformance-tests/client-spring-http-client -am
7373
npx @modelcontextprotocol/conformance@0.1.15 client \
7474
--spec-version 2025-11-25 \
75-
--command "java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-2.0.0-SNAPSHOT.jar" \
75+
--command "java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-2.0.1-SNAPSHOT.jar" \
7676
--suite auth
7777
```
7878

conformance-tests/client-jdk-http-client/README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ cd conformance-tests/client-jdk-http-client
5454

5555
This creates an executable JAR at:
5656
```
57-
target/client-jdk-http-client-1.1.0-SNAPSHOT.jar
57+
target/client-jdk-http-client-2.0.1-SNAPSHOT.jar
5858
```
5959

6060
## Running Tests
@@ -65,27 +65,27 @@ Run a single scenario:
6565

6666
```bash
6767
npx @modelcontextprotocol/conformance client \
68-
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.1.0-SNAPSHOT.jar" \
68+
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-2.0.1-SNAPSHOT.jar" \
6969
--scenario initialize
7070

7171
npx @modelcontextprotocol/conformance client \
72-
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.1.0-SNAPSHOT.jar" \
72+
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-2.0.1-SNAPSHOT.jar" \
7373
--scenario tools_call
7474

7575
npx @modelcontextprotocol/conformance client \
76-
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.1.0-SNAPSHOT.jar" \
76+
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-2.0.1-SNAPSHOT.jar" \
7777
--scenario elicitation-sep1034-client-defaults
7878

7979
npx @modelcontextprotocol/conformance client \
80-
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.1.0-SNAPSHOT.jar" \
80+
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-2.0.1-SNAPSHOT.jar" \
8181
--scenario sse-retry
8282
```
8383

8484
Run with verbose output:
8585

8686
```bash
8787
npx @modelcontextprotocol/conformance client \
88-
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.1.0-SNAPSHOT.jar" \
88+
--command "java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-2.0.1-SNAPSHOT.jar" \
8989
--scenario initialize \
9090
--verbose
9191
```
@@ -96,7 +96,7 @@ You can also run the client manually if you have a test server:
9696

9797
```bash
9898
export MCP_CONFORMANCE_SCENARIO=initialize
99-
java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-1.1.0-SNAPSHOT.jar http://localhost:3000/mcp
99+
java -jar conformance-tests/client-jdk-http-client/target/client-jdk-http-client-2.0.1-SNAPSHOT.jar http://localhost:3000/mcp
100100
```
101101

102102
## Test Results

conformance-tests/client-jdk-http-client/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>io.modelcontextprotocol.sdk</groupId>
88
<artifactId>conformance-tests</artifactId>
9-
<version>2.0.0-SNAPSHOT</version>
9+
<version>2.0.1-SNAPSHOT</version>
1010
</parent>
1111
<artifactId>client-jdk-http-client</artifactId>
1212
<packaging>jar</packaging>
@@ -28,7 +28,7 @@
2828
<dependency>
2929
<groupId>io.modelcontextprotocol.sdk</groupId>
3030
<artifactId>mcp</artifactId>
31-
<version>2.0.0-SNAPSHOT</version>
31+
<version>2.0.1-SNAPSHOT</version>
3232
</dependency>
3333

3434
<!-- Logging -->

conformance-tests/client-spring-http-client/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ cd conformance-tests/client-spring-http-client
6868

6969
This creates an executable JAR at:
7070
```
71-
target/client-spring-http-client-2.0.0-SNAPSHOT.jar
71+
target/client-spring-http-client-2.0.1-SNAPSHOT.jar
7272
```
7373

7474
## Running Tests
@@ -80,7 +80,7 @@ Run the full auth suite:
8080
```bash
8181
npx @modelcontextprotocol/conformance@0.1.15 client \
8282
--spec-version 2025-11-25 \
83-
--command "java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-2.0.0-SNAPSHOT.jar" \
83+
--command "java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-2.0.1-SNAPSHOT.jar" \
8484
--suite auth
8585
```
8686

@@ -89,7 +89,7 @@ Run a single scenario:
8989
```bash
9090
npx @modelcontextprotocol/conformance@0.1.15 client \
9191
--spec-version 2025-11-25 \
92-
--command "java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-2.0.0-SNAPSHOT.jar" \
92+
--command "java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-2.0.1-SNAPSHOT.jar" \
9393
--scenario auth/metadata-default
9494
```
9595

@@ -98,7 +98,7 @@ Run with verbose output:
9898
```bash
9999
npx @modelcontextprotocol/conformance@0.1.15 client \
100100
--spec-version 2025-11-25 \
101-
--command "java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-2.0.0-SNAPSHOT.jar" \
101+
--command "java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-2.0.1-SNAPSHOT.jar" \
102102
--scenario auth/metadata-default \
103103
--verbose
104104
```
@@ -109,7 +109,7 @@ You can also run the client manually if you have a test server:
109109

110110
```bash
111111
export MCP_CONFORMANCE_SCENARIO=auth/metadata-default
112-
java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-2.0.0-SNAPSHOT.jar http://localhost:3000/mcp
112+
java -jar conformance-tests/client-spring-http-client/target/client-spring-http-client-2.0.1-SNAPSHOT.jar http://localhost:3000/mcp
113113
```
114114

115115
## Known Issues

conformance-tests/client-spring-http-client/pom.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>io.modelcontextprotocol.sdk</groupId>
88
<artifactId>conformance-tests</artifactId>
9-
<version>2.0.0-SNAPSHOT</version>
9+
<version>2.0.1-SNAPSHOT</version>
1010
</parent>
1111
<artifactId>client-spring-http-client</artifactId>
1212
<packaging>jar</packaging>
@@ -22,9 +22,9 @@
2222

2323
<properties>
2424
<java.version>17</java.version>
25-
<spring-boot.version>4.0.5</spring-boot.version>
26-
<spring-ai.version>2.0.0-M6</spring-ai.version>
27-
<spring-ai-mcp-security.version>0.1.11</spring-ai-mcp-security.version>
25+
<spring-boot.version>4.1.0</spring-boot.version>
26+
<spring-ai.version>2.0.0</spring-ai.version>
27+
<spring-ai-mcp-security.version>0.1.13</spring-ai-mcp-security.version>
2828
<maven.deploy.skip>true</maven.deploy.skip>
2929
</properties>
3030

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2026-2026 the original author or authors.
3+
*/
4+
5+
package io.modelcontextprotocol.conformance.client.condition;
6+
7+
import java.lang.annotation.Documented;
8+
import java.lang.annotation.ElementType;
9+
import java.lang.annotation.Retention;
10+
import java.lang.annotation.RetentionPolicy;
11+
import java.lang.annotation.Target;
12+
13+
import org.springframework.context.annotation.Conditional;
14+
15+
/**
16+
* Condition to include beans only when certain scenarios are active / inactive. Checks
17+
* the value of the {@code MCP_CONFORMANCE_SCENARIO} environment variable and matches
18+
* against {@link #included()} and {@link #excluded()}. Exactly one of these attributes
19+
* must be defined.
20+
* <p>
21+
* Usage: <pre>
22+
*
23+
* &#64;Configuration
24+
* &#64;ConditionalOnScenario(excluded =
25+
* {
26+
* "auth/pre-registration",
27+
* "auth/client-credentials-basic"
28+
* }
29+
* )
30+
* public class DefaultConfiguration {
31+
* // ...
32+
* }
33+
* </pre>
34+
*
35+
* @author Daniel Garnier-Moiroux
36+
* @see OnScenarioCondition
37+
*/
38+
@Target({ ElementType.TYPE, ElementType.METHOD })
39+
@Retention(RetentionPolicy.RUNTIME)
40+
@Documented
41+
@Conditional(OnScenarioCondition.class)
42+
public @interface ConditionalOnScenario {
43+
44+
String[] included() default {};
45+
46+
String[] excluded() default {};
47+
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2026-2026 the original author or authors.
3+
*/
4+
5+
package io.modelcontextprotocol.conformance.client.condition;
6+
7+
import java.util.Arrays;
8+
import java.util.List;
9+
import java.util.Map;
10+
11+
import org.jspecify.annotations.Nullable;
12+
13+
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
14+
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
15+
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
16+
import org.springframework.context.annotation.ConditionContext;
17+
import org.springframework.core.type.AnnotatedTypeMetadata;
18+
import org.springframework.util.Assert;
19+
20+
/**
21+
* Condition implementation for {@link ConditionalOnScenario}.
22+
*
23+
* @author Daniel Garnier-Moiroux
24+
*/
25+
class OnScenarioCondition extends SpringBootCondition {
26+
27+
private static final String ENV_VAR = "MCP_CONFORMANCE_SCENARIO";
28+
29+
@Override
30+
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
31+
Map<String, @Nullable Object> attributes = metadata
32+
.getAnnotationAttributes(ConditionalOnScenario.class.getName());
33+
Assert.state(attributes != null, "'attributes' must not be null");
34+
35+
String[] included = (String[]) attributes.get("included");
36+
String[] excluded = (String[]) attributes.get("excluded");
37+
38+
boolean hasIncluded = included != null && included.length > 0;
39+
boolean hasExcluded = excluded != null && excluded.length > 0;
40+
41+
Assert.state(hasIncluded ^ hasExcluded,
42+
"@ConditionalOnScenario must have exactly one of 'included' or 'excluded' defined");
43+
44+
String scenario = System.getenv(ENV_VAR);
45+
46+
if (hasIncluded) {
47+
List<String> includedList = Arrays.asList(included);
48+
boolean matches = scenario != null && includedList.contains(scenario);
49+
ConditionMessage message = ConditionMessage.forCondition(ConditionalOnScenario.class)
50+
.because("scenario '" + scenario + "' " + (matches ? "is" : "is not") + " in included list "
51+
+ includedList);
52+
return matches ? ConditionOutcome.match(message) : ConditionOutcome.noMatch(message);
53+
}
54+
else {
55+
List<String> excludedList = Arrays.asList(excluded);
56+
boolean matches = scenario == null || !excludedList.contains(scenario);
57+
ConditionMessage message = ConditionMessage.forCondition(ConditionalOnScenario.class)
58+
.because("scenario '" + scenario + "' " + (matches ? "is not" : "is") + " in excluded list "
59+
+ excludedList);
60+
return matches ? ConditionOutcome.match(message) : ConditionOutcome.noMatch(message);
61+
}
62+
}
63+
64+
}

conformance-tests/client-spring-http-client/src/main/java/io/modelcontextprotocol/conformance/client/configuration/DefaultConfiguration.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package io.modelcontextprotocol.conformance.client.configuration;
66

77
import io.modelcontextprotocol.client.transport.HttpClientStreamableHttpTransport;
8+
import io.modelcontextprotocol.conformance.client.condition.ConditionalOnScenario;
89
import io.modelcontextprotocol.conformance.client.scenario.DefaultScenario;
910
import org.springaicommunity.mcp.security.client.sync.config.McpClientOAuth2Configurer;
1011
import org.springaicommunity.mcp.security.client.sync.oauth2.http.client.OAuth2CimdHttpClientTransportCustomizer;
@@ -16,7 +17,6 @@
1617

1718
import org.springframework.ai.mcp.customizer.McpClientCustomizer;
1819
import org.springframework.beans.factory.annotation.Value;
19-
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
2020
import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext;
2121
import org.springframework.context.annotation.Bean;
2222
import org.springframework.context.annotation.Configuration;
@@ -26,7 +26,7 @@
2626
import org.springframework.security.web.SecurityFilterChain;
2727

2828
@Configuration
29-
@ConditionalOnExpression("#{environment['MCP_CONFORMANCE_SCENARIO'] != 'auth/pre-registration'}")
29+
@ConditionalOnScenario(excluded = { "auth/pre-registration", "auth/client-credentials-basic" })
3030
public class DefaultConfiguration {
3131

3232
private final String TEST_CLIENT_ID_URL = "https://conformance-test.local/client-metadata.json";

0 commit comments

Comments
 (0)