skills) {
+ this.skills = skills;
+ }
+
+ /**
+ * Returns whether the agent supports authenticated extended card retrieval.
+ *
+ * @return true if authenticated extended card is supported, false otherwise
+ */
+ public boolean isSupportsAuthenticatedExtendedCard() {
+ return supportsAuthenticatedExtendedCard;
+ }
+
+ /**
+ * Sets whether the agent supports authenticated extended card retrieval.
+ *
+ * @param supportsAuthenticatedExtendedCard true to enable authenticated extended card support, false to disable
+ */
+ public void setSupportsAuthenticatedExtendedCard(boolean supportsAuthenticatedExtendedCard) {
+ this.supportsAuthenticatedExtendedCard = supportsAuthenticatedExtendedCard;
+ }
+
+ /**
+ * Returns the agent capabilities configuration.
+ *
+ * @return the capabilities configuration
+ */
+ public Capabilities getCapabilities() {
+ return capabilities;
+ }
+
+ /**
+ * Sets the agent capabilities configuration.
+ *
+ * @param capabilities the capabilities configuration to set
+ */
+ public void setCapabilities(Capabilities capabilities) {
+ this.capabilities = capabilities;
+ }
+
+ /**
+ * Configuration for agent capabilities.
+ *
+ * This class defines what features the agent supports, such as streaming responses,
+ * push notifications, and state history.
+ */
+ public static class Capabilities implements Serializable {
+
+ private static final long serialVersionUID = 2371695651871067858L;
+
+ /**
+ * Whether the agent supports streaming responses.
+ */
+ private boolean streaming = true;
+
+ /**
+ * Whether the agent supports push notifications.
+ */
+ private boolean pushNotifications = false;
+
+ /**
+ * Whether the agent maintains state transition history.
+ */
+ private boolean stateTransitionHistory = true;
+
+ /**
+ * Returns whether streaming is supported.
+ *
+ * @return true if streaming is supported, false otherwise
+ */
+ public boolean isStreaming() {
+ return streaming;
+ }
+
+ /**
+ * Sets whether streaming is supported.
+ *
+ * @param streaming true to enable streaming support, false to disable
+ */
+ public void setStreaming(boolean streaming) {
+ this.streaming = streaming;
+ }
+
+ /**
+ * Returns whether push notifications are supported.
+ *
+ * @return true if push notifications are supported, false otherwise
+ */
+ public boolean isPushNotifications() {
+ return pushNotifications;
+ }
+
+ /**
+ * Sets whether push notifications are supported.
+ *
+ * @param pushNotifications true to enable push notification support, false to
+ * disable
+ */
+ public void setPushNotifications(boolean pushNotifications) {
+ this.pushNotifications = pushNotifications;
+ }
+
+ /**
+ * Returns whether state transition history is supported.
+ *
+ * @return true if state transition history is supported, false otherwise
+ */
+ public boolean isStateTransitionHistory() {
+ return stateTransitionHistory;
+ }
+
+ /**
+ * Sets whether state transition history is supported.
+ *
+ * @param stateTransitionHistory true to enable state transition history, false to
+ * disable
+ */
+ public void setStateTransitionHistory(boolean stateTransitionHistory) {
+ this.stateTransitionHistory = stateTransitionHistory;
+ }
+
+ }
+
+ /**
+ * Configuration for agent provider information.
+ */
+ public static class Provider implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The name of the provider.
+ */
+ private String name;
+
+ /**
+ * The URL of the provider.
+ */
+ private String url;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+ }
+
+ /**
+ * Configuration for agent authentication.
+ */
+ public static class Authentication implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The type of authentication.
+ */
+ private String type;
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+ }
+
+ /**
+ * Configuration for security scheme.
+ */
+ public static class SecurityScheme implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The type of security scheme.
+ */
+ private String type;
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+ }
+
+ /**
+ * Configuration for agent skill.
+ */
+ public static class Skill implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The name of the skill.
+ */
+ private String name;
+
+ /**
+ * The description of the skill.
+ */
+ private String description;
+
+ /**
+ * Set of tag words describing classes of capabilities for this specific skill.
+ * Example: ["cooking", "customer support", "billing"]
+ */
+ private List tags = new ArrayList<>();
+
+ /**
+ * The set of example scenarios that the skill can perform.
+ * Will be used by the client as a hint to understand how the skill can be used.
+ * Example: ["I need a recipe for bread"]
+ */
+ private List examples;
+
+ /**
+ * The input modes supported by the skill.
+ */
+ private List inputModes = List.of("text");
+
+ /**
+ * The output modes supported by the skill.
+ */
+ private List outputModes = List.of("text");
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public List getTags() {
+ return tags;
+ }
+
+ public void setTags(List tags) {
+ this.tags = tags;
+ }
+
+ public List getExamples() {
+ return examples;
+ }
+
+ public void setExamples(List examples) {
+ this.examples = examples;
+ }
+
+ public List getInputModes() {
+ return inputModes;
+ }
+
+ public void setInputModes(List inputModes) {
+ this.inputModes = inputModes;
+ }
+
+ public List getOutputModes() {
+ return outputModes;
+ }
+
+ public void setOutputModes(List outputModes) {
+ this.outputModes = outputModes;
+ }
+ }
+
+}
diff --git a/sdk-spring/src/main/java/io/a2a/server/apps/spring/A2ASpringAutoConfiguration.java b/sdk-spring/src/main/java/io/a2a/server/apps/spring/A2ASpringAutoConfiguration.java
new file mode 100644
index 000000000..2a53044ee
--- /dev/null
+++ b/sdk-spring/src/main/java/io/a2a/server/apps/spring/A2ASpringAutoConfiguration.java
@@ -0,0 +1,140 @@
+package io.a2a.server.apps.spring;
+
+import io.a2a.server.agentexecution.AgentExecutor;
+import io.a2a.server.events.InMemoryQueueManager;
+import io.a2a.server.events.QueueManager;
+import io.a2a.server.requesthandlers.DefaultRequestHandler;
+import io.a2a.server.requesthandlers.JSONRPCHandler;
+import io.a2a.server.requesthandlers.RequestHandler;
+import io.a2a.server.tasks.InMemoryPushNotifier;
+import io.a2a.server.tasks.InMemoryTaskStore;
+import io.a2a.server.tasks.PushNotifier;
+import io.a2a.server.tasks.TaskStore;
+import io.a2a.spec.AgentCapabilities;
+import io.a2a.spec.AgentCard;
+import io.a2a.spec.AgentProvider;
+import io.a2a.spec.AgentSkill;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ForkJoinPool;
+
+import java.util.stream.Collectors;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Spring Boot auto-configuration for A2A (Agent2Agent) protocol.
+ * Automatically configures the necessary beans for A2A server functionality.
+ */
+@Configuration
+@EnableConfigurationProperties(A2AServerProperties.class)
+public class A2ASpringAutoConfiguration {
+
+ @Bean(name = "a2aServerSelfCard")
+ @ConditionalOnMissingBean
+ @ConditionalOnProperty(name = "a2a.server.enabled", havingValue = "true")
+ public AgentCard agentCard(final A2AServerProperties a2aServerProperties) {
+ AgentCard.Builder builder = new AgentCard.Builder()
+ .name(a2aServerProperties.getName())
+ .url(a2aServerProperties.getUrl())
+ .version(a2aServerProperties.getVersion())
+ .description(a2aServerProperties.getDescription());
+
+ // Add provider information if exists
+ if (a2aServerProperties.getProvider() != null) {
+ builder.provider(new AgentProvider(a2aServerProperties.getProvider().getName(), a2aServerProperties.getProvider().getUrl()));
+ }
+
+ // Add documentation URL if exists
+ if (a2aServerProperties.getDocumentationUrl() != null) {
+ builder.documentationUrl(a2aServerProperties.getDocumentationUrl());
+ }
+
+ // Add capabilities if exists
+ if (a2aServerProperties.getCapabilities() != null) {
+ builder.capabilities(new AgentCapabilities.Builder()
+ .streaming(a2aServerProperties.getCapabilities().isStreaming())
+ .pushNotifications(a2aServerProperties.getCapabilities().isPushNotifications())
+ .stateTransitionHistory(a2aServerProperties.getCapabilities().isStateTransitionHistory())
+ .build());
+ }
+
+ // Add security requirements if exists
+ if (a2aServerProperties.getSecurity() != null && !a2aServerProperties.getSecurity().isEmpty()) {
+ builder.security(a2aServerProperties.getSecurity());
+ }
+
+ // Add default input modes if exists
+ if (a2aServerProperties.getDefaultInputModes() != null && !a2aServerProperties.getDefaultInputModes().isEmpty()) {
+ builder.defaultInputModes(a2aServerProperties.getDefaultInputModes());
+ }
+
+ // Add default output modes if exists
+ if (a2aServerProperties.getDefaultOutputModes() != null && !a2aServerProperties.getDefaultOutputModes().isEmpty()) {
+ builder.defaultOutputModes(a2aServerProperties.getDefaultOutputModes());
+ }
+
+ // Add skills list if exists
+ if (a2aServerProperties.getSkills() != null && !a2aServerProperties.getSkills().isEmpty()) {
+ builder.skills(a2aServerProperties.getSkills().stream()
+ .filter(skill -> skill != null && skill.getName() != null)
+ .map(skill -> new AgentSkill.Builder()
+ .id(skill.getName())
+ .name(skill.getName())
+ .description(skill.getDescription())
+ .tags(skill.getTags())
+ .examples(skill.getExamples())
+ .inputModes(skill.getInputModes())
+ .outputModes(skill.getOutputModes())
+ .build())
+ .collect(Collectors.toList()));
+ }
+
+ // Add authenticated extended card support
+ builder.supportsAuthenticatedExtendedCard(a2aServerProperties.isSupportsAuthenticatedExtendedCard());
+
+ return builder.build();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public Executor a2aExecutor() {
+ return ForkJoinPool.commonPool();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public TaskStore taskStore() {
+ return new InMemoryTaskStore();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public QueueManager queueManager() {
+ return new InMemoryQueueManager();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public PushNotifier pushNotifier() {
+ return new InMemoryPushNotifier();
+ }
+
+ /**
+ * Configure RequestHandler Bean.
+ * This Bean handles all A2A requests.
+ */
+ @Bean
+ @ConditionalOnMissingBean
+ public RequestHandler requestHandler(AgentExecutor agentExecutor, TaskStore taskStore, QueueManager queueManager, PushNotifier pushNotifier, Executor executor) {
+ return new DefaultRequestHandler(agentExecutor, taskStore, queueManager, pushNotifier, executor);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public JSONRPCHandler jsonrpcHandler(AgentCard agentCard, RequestHandler requestHandler) {
+ return new JSONRPCHandler(agentCard, requestHandler);
+ }
+}
diff --git a/sdk-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/sdk-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 000000000..7216f4c58
--- /dev/null
+++ b/sdk-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1 @@
+io.a2a.server.apps.spring.A2ASpringAutoConfiguration