diff --git a/conformance-tests/client-spring-http-client/src/main/java/io/modelcontextprotocol/conformance/client/condition/ConditionalOnScenario.java b/conformance-tests/client-spring-http-client/src/main/java/io/modelcontextprotocol/conformance/client/condition/ConditionalOnScenario.java
new file mode 100644
index 000000000..fe3136419
--- /dev/null
+++ b/conformance-tests/client-spring-http-client/src/main/java/io/modelcontextprotocol/conformance/client/condition/ConditionalOnScenario.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2026-2026 the original author or authors.
+ */
+
+package io.modelcontextprotocol.conformance.client.condition;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.context.annotation.Conditional;
+
+/**
+ * Condition to include beans only when certain scenarios are active / inactive. Checks
+ * the value of the {@code MCP_CONFORMANCE_SCENARIO} environment variable and matches
+ * against {@link #included()} and {@link #excluded()}. Exactly one of these attributes
+ * must be defined.
+ *
+ * Usage:
+ *
+ * @Configuration
+ * @ConditionalOnScenario(excluded =
+ * {
+ * "auth/pre-registration",
+ * "auth/client-credentials-basic"
+ * }
+ * )
+ * public class DefaultConfiguration {
+ * // ...
+ * }
+ *
+ *
+ * @author Daniel Garnier-Moiroux
+ * @see OnScenarioCondition
+ */
+@Target({ ElementType.TYPE, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Conditional(OnScenarioCondition.class)
+public @interface ConditionalOnScenario {
+
+ String[] included() default {};
+
+ String[] excluded() default {};
+
+}
diff --git a/conformance-tests/client-spring-http-client/src/main/java/io/modelcontextprotocol/conformance/client/condition/OnScenarioCondition.java b/conformance-tests/client-spring-http-client/src/main/java/io/modelcontextprotocol/conformance/client/condition/OnScenarioCondition.java
new file mode 100644
index 000000000..2d35f254b
--- /dev/null
+++ b/conformance-tests/client-spring-http-client/src/main/java/io/modelcontextprotocol/conformance/client/condition/OnScenarioCondition.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2026-2026 the original author or authors.
+ */
+
+package io.modelcontextprotocol.conformance.client.condition;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.jspecify.annotations.Nullable;
+
+import org.springframework.boot.autoconfigure.condition.ConditionMessage;
+import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
+import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.core.type.AnnotatedTypeMetadata;
+import org.springframework.util.Assert;
+
+/**
+ * Condition implementation for {@link ConditionalOnScenario}.
+ *
+ * @author Daniel Garnier-Moiroux
+ */
+class OnScenarioCondition extends SpringBootCondition {
+
+ private static final String ENV_VAR = "MCP_CONFORMANCE_SCENARIO";
+
+ @Override
+ public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
+ Map attributes = metadata
+ .getAnnotationAttributes(ConditionalOnScenario.class.getName());
+ Assert.state(attributes != null, "'attributes' must not be null");
+
+ String[] included = (String[]) attributes.get("included");
+ String[] excluded = (String[]) attributes.get("excluded");
+
+ boolean hasIncluded = included != null && included.length > 0;
+ boolean hasExcluded = excluded != null && excluded.length > 0;
+
+ Assert.state(hasIncluded ^ hasExcluded,
+ "@ConditionalOnScenario must have exactly one of 'included' or 'excluded' defined");
+
+ String scenario = System.getenv(ENV_VAR);
+
+ if (hasIncluded) {
+ List includedList = Arrays.asList(included);
+ boolean matches = scenario != null && includedList.contains(scenario);
+ ConditionMessage message = ConditionMessage.forCondition(ConditionalOnScenario.class)
+ .because("scenario '" + scenario + "' " + (matches ? "is" : "is not") + " in included list "
+ + includedList);
+ return matches ? ConditionOutcome.match(message) : ConditionOutcome.noMatch(message);
+ }
+ else {
+ List excludedList = Arrays.asList(excluded);
+ boolean matches = scenario == null || !excludedList.contains(scenario);
+ ConditionMessage message = ConditionMessage.forCondition(ConditionalOnScenario.class)
+ .because("scenario '" + scenario + "' " + (matches ? "is not" : "is") + " in excluded list "
+ + excludedList);
+ return matches ? ConditionOutcome.match(message) : ConditionOutcome.noMatch(message);
+ }
+ }
+
+}
diff --git a/conformance-tests/client-spring-http-client/src/main/java/io/modelcontextprotocol/conformance/client/configuration/DefaultConfiguration.java b/conformance-tests/client-spring-http-client/src/main/java/io/modelcontextprotocol/conformance/client/configuration/DefaultConfiguration.java
index 2fd70569d..3629e3a56 100644
--- a/conformance-tests/client-spring-http-client/src/main/java/io/modelcontextprotocol/conformance/client/configuration/DefaultConfiguration.java
+++ b/conformance-tests/client-spring-http-client/src/main/java/io/modelcontextprotocol/conformance/client/configuration/DefaultConfiguration.java
@@ -5,6 +5,7 @@
package io.modelcontextprotocol.conformance.client.configuration;
import io.modelcontextprotocol.client.transport.HttpClientStreamableHttpTransport;
+import io.modelcontextprotocol.conformance.client.condition.ConditionalOnScenario;
import io.modelcontextprotocol.conformance.client.scenario.DefaultScenario;
import org.springaicommunity.mcp.security.client.sync.config.McpClientOAuth2Configurer;
import org.springaicommunity.mcp.security.client.sync.oauth2.http.client.OAuth2CimdHttpClientTransportCustomizer;
@@ -16,7 +17,6 @@
import org.springframework.ai.mcp.customizer.McpClientCustomizer;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -26,7 +26,7 @@
import org.springframework.security.web.SecurityFilterChain;
@Configuration
-@ConditionalOnExpression("#{environment['MCP_CONFORMANCE_SCENARIO'] != 'auth/pre-registration'}")
+@ConditionalOnScenario(excluded = { "auth/pre-registration", "auth/client-credentials-basic" })
public class DefaultConfiguration {
private final String TEST_CLIENT_ID_URL = "https://conformance-test.local/client-metadata.json";
diff --git a/conformance-tests/client-spring-http-client/src/main/java/io/modelcontextprotocol/conformance/client/configuration/PreRegistrationConfiguration.java b/conformance-tests/client-spring-http-client/src/main/java/io/modelcontextprotocol/conformance/client/configuration/PreRegistrationConfiguration.java
index afe03f85a..2b7efb893 100644
--- a/conformance-tests/client-spring-http-client/src/main/java/io/modelcontextprotocol/conformance/client/configuration/PreRegistrationConfiguration.java
+++ b/conformance-tests/client-spring-http-client/src/main/java/io/modelcontextprotocol/conformance/client/configuration/PreRegistrationConfiguration.java
@@ -4,12 +4,12 @@
package io.modelcontextprotocol.conformance.client.configuration;
+import io.modelcontextprotocol.conformance.client.condition.ConditionalOnScenario;
import io.modelcontextprotocol.conformance.client.scenario.PreRegistrationScenario;
import org.springaicommunity.mcp.security.client.sync.config.McpClientOAuth2Configurer;
import org.springaicommunity.mcp.security.client.sync.oauth2.metadata.McpMetadataDiscoveryService;
import org.springaicommunity.mcp.security.client.sync.oauth2.registration.McpClientRegistrationRepository;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
@@ -18,7 +18,7 @@
import org.springframework.security.web.SecurityFilterChain;
@Configuration
-@ConditionalOnProperty(name = "mcp.conformance.scenario", havingValue = "auth/pre-registration")
+@ConditionalOnScenario(included = { "auth/pre-registration", "auth/client-credentials-basic" })
public class PreRegistrationConfiguration {
@Bean