diff --git a/contrib/samples/pom.xml b/contrib/samples/pom.xml
index a926d3b85..2d6c9482b 100644
--- a/contrib/samples/pom.xml
+++ b/contrib/samples/pom.xml
@@ -27,5 +27,6 @@
github/adktriaging
helloworld
mcpfilesystem
+ spring-boot-adk-template
diff --git a/contrib/samples/spring-boot-adk-template/README.md b/contrib/samples/spring-boot-adk-template/README.md
new file mode 100644
index 000000000..b1b8bd864
--- /dev/null
+++ b/contrib/samples/spring-boot-adk-template/README.md
@@ -0,0 +1,55 @@
+# Spring Boot ADK Template
+
+Sample Spring Boot application demonstrating the **`google-adk-spring-boot-starter`** in its simplest form. The user code consists of:
+
+- One `@Bean LlmAgent rootAgent()` — the agent topology
+- One `@Bean App` — wraps the root agent under an app name
+- One `@Service AgentService` — illustrates injection of the starter-provided `Runner`
+
+Everything else (`Runner`, `BaseSessionService`, `BaseArtifactService`, `RunConfig`) is wired by the starter.
+
+## Prerequisites
+
+- Java 17
+- Maven
+- This module is built as part of the ADK aggregator; no separate install of the starter is required.
+
+## Build and run
+
+From the repository root:
+
+```bash
+mvn -pl contrib/samples/spring-boot-adk-template -am verify
+```
+
+To run interactively:
+
+```bash
+mvn -pl contrib/samples/spring-boot-adk-template -am spring-boot:run
+```
+
+## Configuration
+
+`src/main/resources/application.yaml` shows the full property surface as comments. The defaults give an all-in-memory configuration with no GCP credentials required — switch backends by uncommenting the relevant blocks (`adk.session.type=VERTEX_AI`, `adk.session.type=FIRESTORE`, `adk.artifacts.gcs-enabled=true`, etc.).
+
+See the [starter README](../../spring-boot-starter/README.md) for the full property reference.
+
+## Use Spring AI as the LLM substrate (optional)
+
+This sample uses a string model name (`"gemini-2.5-flash"`). To swap to Spring AI's `ChatModel` ecosystem (OpenAI, Anthropic, Gemini, Ollama, Vertex AI, Azure OpenAI, Bedrock):
+
+1. Add `com.google.adk:google-adk-spring-ai` and your preferred Spring AI provider artifact to `pom.xml`.
+2. Configure the provider via `spring.ai.*` properties (e.g. `spring.ai.openai.api-key`).
+3. Inject the auto-configured `SpringAI` bean into `AgentConfig.rootAgent()` and pass it to `.model(...)`.
+
+## Project structure
+
+```
+src/main/java/com/example/springbootadktemplate/
+├── SpringBootAdkTemplateApplication.java — @SpringBootApplication entry point
+├── AgentService.java — sample @Service injecting Runner + LlmAgent
+└── config/AgentConfig.java — @Bean LlmAgent + @Bean App
+src/main/resources/application.yaml — spring.application.name + (commented) adk.* properties
+src/test/java/com/example/springbootadktemplate/
+└── SpringBootAdkTemplateApplicationTest.java — context-load test asserting every starter bean is reachable
+```
diff --git a/contrib/samples/spring-boot-adk-template/pom.xml b/contrib/samples/spring-boot-adk-template/pom.xml
new file mode 100644
index 000000000..6a82ace58
--- /dev/null
+++ b/contrib/samples/spring-boot-adk-template/pom.xml
@@ -0,0 +1,67 @@
+
+
+
+ 4.0.0
+
+
+ com.google.adk
+ google-adk-samples
+ 1.7.2-SNAPSHOT
+ ..
+
+
+ com.google.adk.samples
+ google-adk-sample-spring-boot-template
+ Google ADK - Sample - Spring Boot Template
+ Spring Boot template demonstrating the google-adk-spring-boot-starter.
+ jar
+
+
+ UTF-8
+ 17
+ com.example.springbootadktemplate.SpringBootAdkTemplateApplication
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ com.google.adk
+ google-adk-spring-boot-starter
+ ${project.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ ${exec.mainClass}
+
+
+
+
+
diff --git a/contrib/samples/spring-boot-adk-template/src/main/java/com/example/springbootadktemplate/AgentService.java b/contrib/samples/spring-boot-adk-template/src/main/java/com/example/springbootadktemplate/AgentService.java
new file mode 100644
index 000000000..1f0215a96
--- /dev/null
+++ b/contrib/samples/spring-boot-adk-template/src/main/java/com/example/springbootadktemplate/AgentService.java
@@ -0,0 +1,24 @@
+package com.example.springbootadktemplate;
+
+import com.google.adk.agents.LlmAgent;
+import com.google.adk.runner.Runner;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AgentService {
+
+ private final Runner runner;
+ private final LlmAgent agent;
+
+ public AgentService(Runner runner, LlmAgent agent) {
+ this.runner = runner;
+ this.agent = agent;
+ }
+
+ public String getAgentInfo() {
+ return "Agent created: "
+ + agent.getClass().getSimpleName()
+ + ", Runner: "
+ + runner.getClass().getSimpleName();
+ }
+}
diff --git a/contrib/samples/spring-boot-adk-template/src/main/java/com/example/springbootadktemplate/SpringBootAdkTemplateApplication.java b/contrib/samples/spring-boot-adk-template/src/main/java/com/example/springbootadktemplate/SpringBootAdkTemplateApplication.java
new file mode 100644
index 000000000..37e8577c0
--- /dev/null
+++ b/contrib/samples/spring-boot-adk-template/src/main/java/com/example/springbootadktemplate/SpringBootAdkTemplateApplication.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package com.example.springbootadktemplate;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SpringBootAdkTemplateApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringBootAdkTemplateApplication.class, args);
+ }
+}
diff --git a/contrib/samples/spring-boot-adk-template/src/main/java/com/example/springbootadktemplate/config/AgentConfig.java b/contrib/samples/spring-boot-adk-template/src/main/java/com/example/springbootadktemplate/config/AgentConfig.java
new file mode 100644
index 000000000..8dce9415e
--- /dev/null
+++ b/contrib/samples/spring-boot-adk-template/src/main/java/com/example/springbootadktemplate/config/AgentConfig.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package com.example.springbootadktemplate.config;
+
+import com.google.adk.agents.LlmAgent;
+import com.google.adk.apps.App;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Sample agent topology — defines a root LlmAgent and packages it into an App.
+ *
+ *
The starter provides {@code Runner}, {@code BaseSessionService}, {@code BaseArtifactService},
+ * and {@code RunConfig} automatically — this configuration only declares the user-specific agent
+ * topology.
+ */
+@Configuration
+public class AgentConfig {
+
+ @Bean
+ public LlmAgent rootAgent() {
+ return LlmAgent.builder()
+ .name("root_agent")
+ .description("Sample assistant agent.")
+ .model("gemini-2.5-flash")
+ .instruction("Answer user questions to the best of your knowledge.")
+ .build();
+ }
+
+ @Bean
+ public App app(LlmAgent rootAgent, @Value("${spring.application.name}") String appName) {
+ return App.builder().name(appName).rootAgent(rootAgent).build();
+ }
+}
diff --git a/contrib/samples/spring-boot-adk-template/src/main/resources/application.yaml b/contrib/samples/spring-boot-adk-template/src/main/resources/application.yaml
new file mode 100644
index 000000000..3f5f71e3c
--- /dev/null
+++ b/contrib/samples/spring-boot-adk-template/src/main/resources/application.yaml
@@ -0,0 +1,24 @@
+spring:
+ application:
+ name: spring_boot_adk_template # must be a valid identifier (App#validateAppName regex)
+
+# Defaults — services are in-memory unless these are uncommented.
+# adk:
+# artifacts:
+# gcs-enabled: false
+# # bucket-name: my-bucket
+# session:
+# type: IN_MEMORY # IN_MEMORY | VERTEX_AI | FIRESTORE
+# # project-id: my-project
+# # location: us-central1
+# memory:
+# type: IN_MEMORY # IN_MEMORY | FIRESTORE
+# run-config:
+# streaming-mode: NONE # NONE | SSE | BIDI
+# max-llm-calls: 500
+# tool-execution-mode: NONE # NONE | SEQUENTIAL | PARALLEL | PARALLEL_SUBSCRIBE
+# save-input-blobs-as-artifacts: false
+# auto-create-session: true
+# firestore:
+# # project-id: my-gcp-project
+# # database-id: "(default)"
diff --git a/contrib/samples/spring-boot-adk-template/src/test/java/com/example/springbootadktemplate/SpringBootAdkTemplateApplicationTest.java b/contrib/samples/spring-boot-adk-template/src/test/java/com/example/springbootadktemplate/SpringBootAdkTemplateApplicationTest.java
new file mode 100644
index 000000000..1d4f7bb7d
--- /dev/null
+++ b/contrib/samples/spring-boot-adk-template/src/test/java/com/example/springbootadktemplate/SpringBootAdkTemplateApplicationTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package com.example.springbootadktemplate;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import com.google.adk.agents.LlmAgent;
+import com.google.adk.agents.RunConfig;
+import com.google.adk.apps.App;
+import com.google.adk.artifacts.BaseArtifactService;
+import com.google.adk.runner.Runner;
+import com.google.adk.sessions.BaseSessionService;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.ApplicationContext;
+
+@SpringBootTest
+class SpringBootAdkTemplateApplicationTest {
+
+ @Test
+ void contextLoadsAndStarterBeansArePresent(ApplicationContext ctx) {
+ assertThat(ctx.getBean(LlmAgent.class)).isNotNull();
+ assertThat(ctx.getBean(App.class).name()).isEqualTo("spring_boot_adk_template");
+ assertThat(ctx.getBean(BaseArtifactService.class)).isNotNull();
+ assertThat(ctx.getBean(BaseSessionService.class)).isNotNull();
+ assertThat(ctx.getBean(RunConfig.class)).isNotNull();
+ assertThat(ctx.getBean(Runner.class).appName()).isEqualTo("spring_boot_adk_template");
+ }
+}
diff --git a/contrib/spring-boot-starter/README.md b/contrib/spring-boot-starter/README.md
new file mode 100644
index 000000000..815ed9869
--- /dev/null
+++ b/contrib/spring-boot-starter/README.md
@@ -0,0 +1,174 @@
+# ADK Spring Boot Starter
+
+Spring Boot auto-configuration for the [Agent Development Kit (ADK)](https://github.com/google/adk-java) runtime.
+
+After adding this starter, declare a single `@Bean App` (your agent topology) and the starter wires the rest: `Runner`, `BaseSessionService`, `BaseArtifactService`, optionally `BaseMemoryService`, and `RunConfig`. The starter is **LLM-agnostic** — pair it with `google-adk-spring-ai` for Spring AI LLMs, or declare your own `@Bean BaseLlm`.
+
+## Installation
+
+```xml
+
+ com.google.adk
+ google-adk-spring-boot-starter
+ ${adk.version}
+
+
+
+
+ com.google.adk
+ google-adk-spring-ai
+ ${adk.version}
+
+```
+
+The starter declares `google-adk-firestore-session-service` as an `true` dependency. It is on your runtime classpath by default — explicitly exclude it if you do not want Firestore-related auto-configurations to activate.
+
+## Quick Start
+
+```java
+@SpringBootApplication
+class MyApp {
+ public static void main(String[] args) { SpringApplication.run(MyApp.class, args); }
+}
+
+@Configuration
+class MyAgents {
+ @Bean public LlmAgent rootAgent(SpringAI llm) { // SpringAI bean comes from google-adk-spring-ai
+ return LlmAgent.builder()
+ .name("root_agent")
+ .model(llm)
+ .instruction("Answer concisely.")
+ .build();
+ }
+ @Bean public App app(LlmAgent rootAgent,
+ @Value("${spring.application.name}") String appName) {
+ return App.builder().name(appName).rootAgent(rootAgent).build();
+ }
+}
+
+@RestController
+class ChatController {
+ private final Runner runner; // provided by starter
+ private final RunConfig runConfig; // provided by starter
+ private final BaseSessionService sessionService; // provided by starter
+ ChatController(Runner r, RunConfig c, BaseSessionService s) {
+ this.runner = r; this.runConfig = c; this.sessionService = s;
+ }
+ @PostMapping("/chat") String chat(@RequestBody String prompt) {
+ String userId = "alice";
+ String sessionId = UUID.randomUUID().toString();
+ sessionService.createSession(runner.appName(), userId, null, sessionId).blockingGet();
+ Content msg = Content.builder().role("user").parts(List.of(Part.builder().text(prompt).build())).build();
+ return runner.runAsync(userId, sessionId, msg, runConfig)
+ .toList().blockingGet()
+ .stream().map(Event::stringifyContent).collect(joining());
+ }
+}
+```
+
+## Property Reference
+
+```yaml
+spring:
+ application:
+ name: my_app # used as the App's appName (must match validateAppName regex)
+
+adk:
+ artifacts:
+ gcs-enabled: false # default; switch to true to use Google Cloud Storage
+ # bucket-name: my-artifacts-bucket # required when gcs-enabled=true (fail-fast otherwise)
+
+ session:
+ type: IN_MEMORY # IN_MEMORY | VERTEX_AI | FIRESTORE
+ # project-id: my-gcp-project # required for VERTEX_AI
+ # location: us-central1 # required for VERTEX_AI
+
+ memory:
+ type: IN_MEMORY # IN_MEMORY | FIRESTORE
+ # VERTEX_AI is reserved — fails fast (no impl exists in ADK)
+
+ run-config:
+ streaming-mode: NONE # NONE | SSE | BIDI
+ max-llm-calls: 500
+ tool-execution-mode: NONE # NONE | SEQUENTIAL | PARALLEL | PARALLEL_SUBSCRIBE
+ save-input-blobs-as-artifacts: false
+ auto-create-session: false
+
+ firestore: # only consulted when session/memory type=FIRESTORE
+ # project-id: my-gcp-project # optional — falls back to ADC project
+ # database-id: "(default)" # optional — falls back to "(default)"
+```
+
+## Persistence Backends
+
+| Concern | `IN_MEMORY` | `VERTEX_AI` | `FIRESTORE` | GCS (artifacts only) |
+|------------|-------------|------------------------------------|--------------------------------------------|----------------------|
+| Sessions | default | `VertexAiSessionService` (managed) | `FirestoreSessionService` (contrib module) | — |
+| Memory | default | n/a — fails fast | `FirestoreMemoryService` (contrib module) | — |
+| Artifacts | default | n/a | n/a | `GcsArtifactService` |
+
+The Firestore branches activate only when the `google-adk-firestore-session-service` module is on the classpath (gated by `@ConditionalOnClass`). The starter declares it as an optional dependency — exclude it from your application pom if you want to keep Firestore wiring off the classpath entirely.
+
+## Multiple business-unit agents in one Spring Boot app
+
+ADK's `appName` is the partition key for sessions, memory, and artifacts. A single Spring Boot app can host multiple independent agentic applications (one per business unit) by declaring multiple `@Bean App`. The starter's `@Bean Runner` auto-config uses `@ConditionalOnSingleCandidate(App.class)`, so it steps aside cleanly when multiple Apps exist — wire one `Runner` per `App` explicitly:
+
+```java
+@Configuration
+class BusinessUnits {
+
+ @Bean App salesApp(SpringAI llm) {
+ return App.builder().name("sales").rootAgent(salesRootAgent(llm)).build();
+ }
+ @Bean App supportApp(SpringAI llm) {
+ return App.builder().name("support").rootAgent(supportRootAgent(llm)).build();
+ }
+ // ... per-BU rootAgent bean factories ...
+
+ @Bean Runner salesRunner(
+ @Qualifier("salesApp") App app,
+ BaseArtifactService artifactService,
+ BaseSessionService sessionService) {
+ return Runner.builder().app(app).artifactService(artifactService).sessionService(sessionService).build();
+ }
+ @Bean Runner supportRunner(
+ @Qualifier("supportApp") App app,
+ BaseArtifactService artifactService,
+ BaseSessionService sessionService) {
+ return Runner.builder().app(app).artifactService(artifactService).sessionService(sessionService).build();
+ }
+}
+```
+
+The shared `BaseSessionService`, `BaseArtifactService`, `BaseMemoryService`, and `RunConfig` beans are singletons partitioned internally by `appName`. No duplication — and no per-BU service wiring boilerplate.
+
+## Architecture
+
+Eight auto-configuration classes, each owning one concern:
+
+| Auto-config | Produces | Activation |
+|------------------------------------------------|---------------------------------------|-------------------------------------------------------------------------------|
+| `AdkArtifactsAutoConfiguration` | `BaseArtifactService`, conditional `Storage` | always; `Storage` only when `adk.artifacts.gcs-enabled=true` |
+| `AdkSessionAutoConfiguration` | `BaseSessionService` (IN_MEMORY, VERTEX_AI) | always; FIRESTORE falls through to the Firestore variant when on classpath |
+| `AdkFirestoreSessionAutoConfiguration` | `BaseSessionService` (FIRESTORE) | `@ConditionalOnClass(FirestoreSessionService.class)`; `@AutoConfigureBefore` |
+| `AdkMemoryAutoConfiguration` | `BaseMemoryService` (IN_MEMORY) | always; FIRESTORE falls through; VERTEX_AI fails fast |
+| `AdkFirestoreMemoryAutoConfiguration` | `BaseMemoryService` (FIRESTORE) | `@ConditionalOnClass(FirestoreMemoryService.class)`; `@AutoConfigureBefore` |
+| `AdkRunConfigAutoConfiguration` | `RunConfig` | always |
+| `AdkFirestoreAutoConfiguration` | `Firestore` client | `@ConditionalOnClass(Firestore.class)` |
+| `AdkRunnerAutoConfiguration` | `Runner` | `@ConditionalOnBean(App.class)` + `@ConditionalOnSingleCandidate(App.class)` |
+
+Every `@Bean` factory uses `@ConditionalOnMissingBean` so any user-declared override (`Storage`, `Firestore`, `BaseSessionService`, `Runner`, etc.) always wins.
+
+## Failure Modes
+
+The starter fails fast at startup (throwing `BeanCreationException` with a clear remediation message) when:
+
+- `adk.artifacts.gcs-enabled=true` but `adk.artifacts.bucket-name` is blank.
+- `adk.session.type=VERTEX_AI` but `project-id` or `location` is blank.
+- `adk.session.type=FIRESTORE` but `google-adk-firestore-session-service` is not on the classpath.
+- `adk.memory.type=VERTEX_AI` (no Vertex AI memory service exists in ADK today).
+- `adk.memory.type=FIRESTORE` but the contrib jar is missing.
+
+## Roadmap — not in this module
+
+Bridges from Spring AI primitives into ADK service interfaces (`ChatMemory` → sessions, `VectorStore` → memory, `ToolCallback` → tools incl. MCP) are planned for `contrib/spring-ai` as a follow-up PR. Once they land, this starter will gain `SPRING_AI_CHAT_MEMORY` / `SPRING_AI_VECTOR_STORE` enum values that activate the bridges when the contrib classes are on the classpath. New artifact backends (S3, Azure Blob, filesystem) require new `BaseArtifactService` impls upstream in ADK first.
diff --git a/contrib/spring-boot-starter/pom.xml b/contrib/spring-boot-starter/pom.xml
new file mode 100644
index 000000000..96e8050fc
--- /dev/null
+++ b/contrib/spring-boot-starter/pom.xml
@@ -0,0 +1,71 @@
+
+
+
+ 4.0.0
+
+
+ com.google.adk
+ google-adk-parent
+ 1.7.2-SNAPSHOT
+ ../../pom.xml
+
+
+ google-adk-spring-boot-starter
+ Agent Development Kit - Spring Boot Starter
+ Spring Boot auto-configuration for the Agent Development Kit (ADK) runtime.
+
+
+
+
+ com.google.adk
+ google-adk
+ ${project.version}
+
+
+
+
+ com.google.adk
+ google-adk-firestore-session-service
+ ${project.version}
+ true
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+
+
+ com.google.cloud
+ google-cloud-storage
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
diff --git a/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkArtifactsAutoConfiguration.java b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkArtifactsAutoConfiguration.java
new file mode 100644
index 000000000..15503cfa8
--- /dev/null
+++ b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkArtifactsAutoConfiguration.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package com.google.adk.autoconfigure;
+
+import com.google.adk.artifacts.BaseArtifactService;
+import com.google.adk.artifacts.GcsArtifactService;
+import com.google.adk.artifacts.InMemoryArtifactService;
+import com.google.adk.autoconfigure.properties.AdkArtifactProperties;
+import com.google.cloud.storage.Storage;
+import com.google.cloud.storage.StorageOptions;
+import java.util.Optional;
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+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;
+
+/**
+ * Auto-configures the {@link BaseArtifactService} bean.
+ *
+ *
Default: {@link InMemoryArtifactService}. With {@code adk.artifacts.gcs-enabled=true}: {@link
+ * GcsArtifactService} backed by a {@link Storage} bean (user-supplied or auto-created via {@link
+ * StorageOptions#getDefaultInstance()}).
+ */
+@AutoConfiguration
+@EnableConfigurationProperties(AdkArtifactProperties.class)
+public class AdkArtifactsAutoConfiguration {
+
+ @Bean
+ @ConditionalOnProperty(prefix = "adk.artifacts", name = "gcs-enabled", havingValue = "true")
+ @ConditionalOnMissingBean
+ public Storage googleCloudStorage() {
+ return StorageOptions.getDefaultInstance().getService();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public BaseArtifactService artifactService(
+ AdkArtifactProperties properties, ObjectProvider storageProvider) {
+ if (!properties.isGcsEnabled()) {
+ return new InMemoryArtifactService();
+ }
+ String bucketName =
+ Optional.ofNullable(properties.getBucketName())
+ .filter(s -> !s.isBlank())
+ .orElseThrow(
+ () ->
+ new BeanCreationException(
+ "adk.artifacts.bucket-name must be set when adk.artifacts.gcs-enabled=true"));
+ return new GcsArtifactService(bucketName, storageProvider.getObject());
+ }
+}
diff --git a/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkFirestoreAutoConfiguration.java b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkFirestoreAutoConfiguration.java
new file mode 100644
index 000000000..20ae46c99
--- /dev/null
+++ b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkFirestoreAutoConfiguration.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package com.google.adk.autoconfigure;
+
+import com.google.adk.autoconfigure.properties.AdkFirestoreProperties;
+import com.google.cloud.firestore.Firestore;
+import com.google.cloud.firestore.FirestoreOptions;
+import java.util.Optional;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * Produces a {@link Firestore} client bean from {@code adk.firestore.*} properties when the
+ * Firestore client library is on the classpath and the user has not declared their own.
+ *
+ * Active whenever {@code com.google.cloud.firestore.Firestore} is on the classpath — typically
+ * because the {@code google-adk-firestore-session-service} contrib module is a dependency. Users
+ * who already declare a {@link Firestore} bean (e.g. via Spring Cloud GCP) take precedence through
+ * {@code @ConditionalOnMissingBean}.
+ */
+@AutoConfiguration
+@ConditionalOnClass(Firestore.class)
+@EnableConfigurationProperties(AdkFirestoreProperties.class)
+public class AdkFirestoreAutoConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ public Firestore firestore(AdkFirestoreProperties properties) {
+ FirestoreOptions.Builder builder = FirestoreOptions.newBuilder();
+ Optional.ofNullable(properties.getProjectId())
+ .filter(s -> !s.isBlank())
+ .ifPresent(builder::setProjectId);
+ Optional.ofNullable(properties.getDatabaseId())
+ .filter(s -> !s.isBlank())
+ .ifPresent(builder::setDatabaseId);
+ return builder.build().getService();
+ }
+}
diff --git a/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkFirestoreMemoryAutoConfiguration.java b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkFirestoreMemoryAutoConfiguration.java
new file mode 100644
index 000000000..99e47636c
--- /dev/null
+++ b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkFirestoreMemoryAutoConfiguration.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package com.google.adk.autoconfigure;
+
+import com.google.adk.autoconfigure.properties.AdkMemoryProperties;
+import com.google.adk.memory.BaseMemoryService;
+import com.google.adk.memory.FirestoreMemoryService;
+import com.google.adk.memory.InMemoryMemoryService;
+import com.google.cloud.firestore.Firestore;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * Firestore-backed {@link BaseMemoryService} variant. Active only when {@code
+ * FirestoreMemoryService} is on the classpath; runs before {@link
+ * AdkMemoryAutoConfiguration}.
+ */
+@AutoConfiguration
+@AutoConfigureBefore(AdkMemoryAutoConfiguration.class)
+@ConditionalOnClass(FirestoreMemoryService.class)
+@EnableConfigurationProperties(AdkMemoryProperties.class)
+public class AdkFirestoreMemoryAutoConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ public BaseMemoryService memoryService(
+ AdkMemoryProperties properties, ObjectProvider firestoreProvider) {
+ return switch (properties.getType()) {
+ case VERTEX_AI -> throw AdkMemoryAutoConfiguration.vertexAiUnsupported();
+ case FIRESTORE -> new FirestoreMemoryService(firestoreProvider.getObject());
+ case IN_MEMORY -> new InMemoryMemoryService();
+ };
+ }
+}
diff --git a/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkFirestoreSessionAutoConfiguration.java b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkFirestoreSessionAutoConfiguration.java
new file mode 100644
index 000000000..1e0eca16c
--- /dev/null
+++ b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkFirestoreSessionAutoConfiguration.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package com.google.adk.autoconfigure;
+
+import com.google.adk.autoconfigure.properties.AdkSessionProperties;
+import com.google.adk.sessions.BaseSessionService;
+import com.google.adk.sessions.FirestoreSessionService;
+import com.google.adk.sessions.InMemorySessionService;
+import com.google.cloud.firestore.Firestore;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * Firestore-backed {@link BaseSessionService} variant. Active only when {@code
+ * FirestoreSessionService} is on the classpath; runs before {@link
+ * AdkSessionAutoConfiguration} so the regular factory's {@code @ConditionalOnMissingBean} steps
+ * aside whenever this branch is eligible.
+ */
+@AutoConfiguration
+@AutoConfigureBefore(AdkSessionAutoConfiguration.class)
+@ConditionalOnClass(FirestoreSessionService.class)
+@EnableConfigurationProperties(AdkSessionProperties.class)
+public class AdkFirestoreSessionAutoConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ public BaseSessionService sessionService(
+ AdkSessionProperties properties, ObjectProvider firestoreProvider) {
+ return switch (properties.getType()) {
+ case VERTEX_AI -> AdkSessionAutoConfiguration.buildVertexAiSession(properties);
+ case FIRESTORE -> new FirestoreSessionService(firestoreProvider.getObject());
+ case IN_MEMORY -> new InMemorySessionService();
+ };
+ }
+}
diff --git a/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkMemoryAutoConfiguration.java b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkMemoryAutoConfiguration.java
new file mode 100644
index 000000000..e1916e9dc
--- /dev/null
+++ b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkMemoryAutoConfiguration.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package com.google.adk.autoconfigure;
+
+import com.google.adk.autoconfigure.properties.AdkMemoryProperties;
+import com.google.adk.memory.BaseMemoryService;
+import com.google.adk.memory.InMemoryMemoryService;
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * Auto-configures the {@link BaseMemoryService} bean for the {@code IN_MEMORY} backend.
+ *
+ * {@code VERTEX_AI} fails fast — no Vertex AI memory service exists in ADK today. {@code
+ * FIRESTORE} is handled by {@code AdkFirestoreMemoryAutoConfiguration} when the contrib module is
+ * on the classpath.
+ */
+@AutoConfiguration
+@EnableConfigurationProperties(AdkMemoryProperties.class)
+public class AdkMemoryAutoConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ public BaseMemoryService memoryService(AdkMemoryProperties properties) {
+ return switch (properties.getType()) {
+ case VERTEX_AI -> throw vertexAiUnsupported();
+ case FIRESTORE -> throw firestoreModuleMissing();
+ case IN_MEMORY -> new InMemoryMemoryService();
+ };
+ }
+
+ static BeanCreationException vertexAiUnsupported() {
+ return new BeanCreationException(
+ "adk.memory.type=VERTEX_AI is not supported — no Vertex AI memory service exists in ADK"
+ + " today. Use IN_MEMORY, FIRESTORE, or provide your own BaseMemoryService bean.");
+ }
+
+ static BeanCreationException firestoreModuleMissing() {
+ return new BeanCreationException(
+ "adk.memory.type=FIRESTORE requires the 'google-adk-firestore-session-service' contrib"
+ + " module on the classpath. It is declared as an optional dependency by"
+ + " google-adk-spring-boot-starter — add it explicitly to your application pom if it"
+ + " was excluded.");
+ }
+}
diff --git a/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkRunConfigAutoConfiguration.java b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkRunConfigAutoConfiguration.java
new file mode 100644
index 000000000..dd33cdc10
--- /dev/null
+++ b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkRunConfigAutoConfiguration.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package com.google.adk.autoconfigure;
+
+import com.google.adk.agents.RunConfig;
+import com.google.adk.autoconfigure.properties.AdkRunConfigProperties;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+
+/** Auto-configures the {@link RunConfig} bean from {@code adk.run-config.*} properties. */
+@AutoConfiguration
+@EnableConfigurationProperties(AdkRunConfigProperties.class)
+public class AdkRunConfigAutoConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ public RunConfig runConfig(AdkRunConfigProperties properties) {
+ return RunConfig.builder()
+ .setStreamingMode(properties.getStreamingMode())
+ .setMaxLlmCalls(properties.getMaxLlmCalls())
+ .setToolExecutionMode(properties.getToolExecutionMode())
+ .setSaveInputBlobsAsArtifacts(properties.isSaveInputBlobsAsArtifacts())
+ .setAutoCreateSession(properties.isAutoCreateSession())
+ .build();
+ }
+}
diff --git a/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkRunnerAutoConfiguration.java b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkRunnerAutoConfiguration.java
new file mode 100644
index 000000000..43487e449
--- /dev/null
+++ b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkRunnerAutoConfiguration.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package com.google.adk.autoconfigure;
+
+import com.google.adk.apps.App;
+import com.google.adk.artifacts.BaseArtifactService;
+import com.google.adk.memory.BaseMemoryService;
+import com.google.adk.runner.Runner;
+import com.google.adk.sessions.BaseSessionService;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * Auto-configures a {@link Runner} bean from a user-declared {@link App} plus the starter-provided
+ * service beans.
+ *
+ *
Single-BU case: when exactly one {@link App} bean exists in the context, this factory wires a
+ * single {@link Runner}. Multi-BU case: when multiple {@link App} beans exist (different business
+ * units in the same Spring Boot app), {@link ConditionalOnSingleCandidate} suppresses this factory
+ * and the user is expected to declare one explicit {@link Runner} per business unit.
+ *
+ *
The {@link BaseMemoryService} dependency is injected via {@link ObjectProvider} because it is
+ * optional — {@link Runner.Builder} accepts {@code null} memory and the starter does not always
+ * produce a memory bean.
+ */
+@AutoConfiguration(
+ after = {
+ AdkArtifactsAutoConfiguration.class,
+ AdkSessionAutoConfiguration.class,
+ AdkMemoryAutoConfiguration.class,
+ AdkFirestoreSessionAutoConfiguration.class,
+ AdkFirestoreMemoryAutoConfiguration.class
+ })
+public class AdkRunnerAutoConfiguration {
+
+ @Bean
+ @ConditionalOnBean(App.class)
+ @ConditionalOnSingleCandidate(App.class)
+ @ConditionalOnMissingBean(Runner.class)
+ public Runner runner(
+ App app,
+ BaseArtifactService artifactService,
+ BaseSessionService sessionService,
+ ObjectProvider memoryServiceProvider) {
+ Runner.Builder builder =
+ Runner.builder().app(app).artifactService(artifactService).sessionService(sessionService);
+ memoryServiceProvider.ifAvailable(builder::memoryService);
+ return builder.build();
+ }
+}
diff --git a/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkSessionAutoConfiguration.java b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkSessionAutoConfiguration.java
new file mode 100644
index 000000000..7277e0a4c
--- /dev/null
+++ b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/AdkSessionAutoConfiguration.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package com.google.adk.autoconfigure;
+
+import com.google.adk.autoconfigure.properties.AdkSessionProperties;
+import com.google.adk.sessions.BaseSessionService;
+import com.google.adk.sessions.InMemorySessionService;
+import com.google.adk.sessions.VertexAiSessionService;
+import java.util.Optional;
+import java.util.function.Supplier;
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * Auto-configures the {@link BaseSessionService} bean for the {@code IN_MEMORY} and {@code
+ * VERTEX_AI} backends.
+ *
+ * {@code FIRESTORE} is handled by {@code AdkFirestoreSessionAutoConfiguration} (gated by
+ * {@code @ConditionalOnClass(FirestoreSessionService.class)} and {@code @AutoConfigureBefore} this
+ * class — so when both are eligible, the Firestore branch wins).
+ */
+@AutoConfiguration
+@EnableConfigurationProperties(AdkSessionProperties.class)
+public class AdkSessionAutoConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ public BaseSessionService sessionService(AdkSessionProperties properties) {
+ return switch (properties.getType()) {
+ case VERTEX_AI -> buildVertexAiSession(properties);
+ case FIRESTORE -> throw firestoreModuleMissing();
+ case IN_MEMORY -> new InMemorySessionService();
+ };
+ }
+
+ static VertexAiSessionService buildVertexAiSession(AdkSessionProperties properties) {
+ String projectId = require(properties.getProjectId(), "adk.session.project-id");
+ String location = require(properties.getLocation(), "adk.session.location");
+ return new VertexAiSessionService(projectId, location, null, null);
+ }
+
+ static String require(String value, String propertyKey) {
+ return Optional.ofNullable(value)
+ .filter(s -> !s.isBlank())
+ .orElseThrow(missing(propertyKey + " must be set when adk.session.type=VERTEX_AI"));
+ }
+
+ static Supplier missing(String message) {
+ return () -> new BeanCreationException(message);
+ }
+
+ static BeanCreationException firestoreModuleMissing() {
+ return new BeanCreationException(
+ "adk.session.type=FIRESTORE requires the 'google-adk-firestore-session-service' contrib"
+ + " module on the classpath. It is declared as an optional dependency by"
+ + " google-adk-spring-boot-starter — add it explicitly to your application pom if it"
+ + " was excluded.");
+ }
+}
diff --git a/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/properties/AdkArtifactProperties.java b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/properties/AdkArtifactProperties.java
new file mode 100644
index 000000000..1f74b3eef
--- /dev/null
+++ b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/properties/AdkArtifactProperties.java
@@ -0,0 +1,25 @@
+package com.google.adk.autoconfigure.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties(prefix = "adk.artifacts")
+public class AdkArtifactProperties {
+ private boolean gcsEnabled = false;
+ private String bucketName;
+
+ public boolean isGcsEnabled() {
+ return gcsEnabled;
+ }
+
+ public void setGcsEnabled(boolean gcsEnabled) {
+ this.gcsEnabled = gcsEnabled;
+ }
+
+ public String getBucketName() {
+ return bucketName;
+ }
+
+ public void setBucketName(String bucketName) {
+ this.bucketName = bucketName;
+ }
+}
diff --git a/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/properties/AdkFirestoreProperties.java b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/properties/AdkFirestoreProperties.java
new file mode 100644
index 000000000..ae3e6a942
--- /dev/null
+++ b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/properties/AdkFirestoreProperties.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package com.google.adk.autoconfigure.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Configuration properties for the {@code com.google.cloud.firestore.Firestore} client bean the
+ * starter creates when one of {@code adk.session.type=FIRESTORE} or {@code
+ * adk.memory.type=FIRESTORE} is requested. Both fields are optional — when unset the starter relies
+ * on Application Default Credentials and Firestore's {@code "(default)"} database.
+ */
+@ConfigurationProperties(prefix = "adk.firestore")
+public class AdkFirestoreProperties {
+
+ /** GCP project id. Optional — falls back to the ADC project. */
+ private String projectId;
+
+ /** Firestore database id. Optional — falls back to {@code "(default)"}. */
+ private String databaseId;
+
+ public String getProjectId() {
+ return projectId;
+ }
+
+ public void setProjectId(String projectId) {
+ this.projectId = projectId;
+ }
+
+ public String getDatabaseId() {
+ return databaseId;
+ }
+
+ public void setDatabaseId(String databaseId) {
+ this.databaseId = databaseId;
+ }
+}
diff --git a/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/properties/AdkMemoryProperties.java b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/properties/AdkMemoryProperties.java
new file mode 100644
index 000000000..05b16a27c
--- /dev/null
+++ b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/properties/AdkMemoryProperties.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package com.google.adk.autoconfigure.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Configuration properties for ADK memory-service auto-configuration. Prefix {@code adk.memory}.
+ */
+@ConfigurationProperties(prefix = "adk.memory")
+public class AdkMemoryProperties {
+
+ /** Which memory-service backend to wire. Defaults to {@link Type#IN_MEMORY}. */
+ private Type type = Type.IN_MEMORY;
+
+ public enum Type {
+ /** {@code com.google.adk.memory.InMemoryMemoryService} — default, no external storage. */
+ IN_MEMORY,
+ /** Reserved — no concrete Vertex AI memory service exists in ADK today; fails fast. */
+ VERTEX_AI,
+ /**
+ * {@code com.google.adk.memory.FirestoreMemoryService} — requires the {@code
+ * google-adk-firestore-session-service} contrib module on the classpath.
+ */
+ FIRESTORE
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ public void setType(Type type) {
+ this.type = type;
+ }
+}
diff --git a/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/properties/AdkRunConfigProperties.java b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/properties/AdkRunConfigProperties.java
new file mode 100644
index 000000000..62f838cd9
--- /dev/null
+++ b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/properties/AdkRunConfigProperties.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package com.google.adk.autoconfigure.properties;
+
+import com.google.adk.agents.RunConfig;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Configuration properties for ADK {@link RunConfig} auto-configuration. Prefix {@code
+ * adk.run-config}.
+ *
+ * Exposes the operational subset of {@link RunConfig} called out in PR review feedback. The
+ * remaining {@link RunConfig} fields ({@code speechConfig}, {@code responseModalities}, audio
+ * transcription configs, {@code avatarConfig}) are not exposed here — they require richer binding
+ * logic and are application-specific; users who need them can declare their own {@link RunConfig}
+ * bean which will take precedence via {@code @ConditionalOnMissingBean}.
+ */
+@ConfigurationProperties(prefix = "adk.run-config")
+public class AdkRunConfigProperties {
+
+ /** Streaming mode for the agent loop. Defaults to {@link RunConfig.StreamingMode#NONE}. */
+ private RunConfig.StreamingMode streamingMode = RunConfig.StreamingMode.NONE;
+
+ /** Maximum number of LLM calls per invocation before the agent loop is interrupted. */
+ private int maxLlmCalls = 500;
+
+ /** Tool execution policy. Defaults to {@link RunConfig.ToolExecutionMode#NONE} (parallel-ish). */
+ private RunConfig.ToolExecutionMode toolExecutionMode = RunConfig.ToolExecutionMode.NONE;
+
+ /** Persist user-supplied input blobs as artifacts on session creation. */
+ private boolean saveInputBlobsAsArtifacts = false;
+
+ /** Auto-create the session if a runner invocation references an unknown session id. */
+ private boolean autoCreateSession = false;
+
+ public RunConfig.StreamingMode getStreamingMode() {
+ return streamingMode;
+ }
+
+ public void setStreamingMode(RunConfig.StreamingMode streamingMode) {
+ this.streamingMode = streamingMode;
+ }
+
+ public int getMaxLlmCalls() {
+ return maxLlmCalls;
+ }
+
+ public void setMaxLlmCalls(int maxLlmCalls) {
+ this.maxLlmCalls = maxLlmCalls;
+ }
+
+ public RunConfig.ToolExecutionMode getToolExecutionMode() {
+ return toolExecutionMode;
+ }
+
+ public void setToolExecutionMode(RunConfig.ToolExecutionMode toolExecutionMode) {
+ this.toolExecutionMode = toolExecutionMode;
+ }
+
+ public boolean isSaveInputBlobsAsArtifacts() {
+ return saveInputBlobsAsArtifacts;
+ }
+
+ public void setSaveInputBlobsAsArtifacts(boolean saveInputBlobsAsArtifacts) {
+ this.saveInputBlobsAsArtifacts = saveInputBlobsAsArtifacts;
+ }
+
+ public boolean isAutoCreateSession() {
+ return autoCreateSession;
+ }
+
+ public void setAutoCreateSession(boolean autoCreateSession) {
+ this.autoCreateSession = autoCreateSession;
+ }
+}
diff --git a/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/properties/AdkSessionProperties.java b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/properties/AdkSessionProperties.java
new file mode 100644
index 000000000..4ac419b5d
--- /dev/null
+++ b/contrib/spring-boot-starter/src/main/java/com/google/adk/autoconfigure/properties/AdkSessionProperties.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package com.google.adk.autoconfigure.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * Configuration properties for ADK session-service auto-configuration. Prefix {@code adk.session}.
+ */
+@ConfigurationProperties(prefix = "adk.session")
+public class AdkSessionProperties {
+
+ /** Which session-service backend to wire. Defaults to {@link Type#IN_MEMORY}. */
+ private Type type = Type.IN_MEMORY;
+
+ /** GCP project id (required when {@link #type} = {@link Type#VERTEX_AI}). */
+ private String projectId;
+
+ /** GCP location (required when {@link #type} = {@link Type#VERTEX_AI}). */
+ private String location;
+
+ public enum Type {
+ /** {@code com.google.adk.sessions.InMemorySessionService} — default, no external storage. */
+ IN_MEMORY,
+ /**
+ * {@code com.google.adk.sessions.VertexAiSessionService} — managed Vertex AI Reasoning Engine.
+ */
+ VERTEX_AI,
+ /**
+ * {@code com.google.adk.sessions.FirestoreSessionService} — requires the {@code
+ * google-adk-firestore-session-service} contrib module on the classpath.
+ */
+ FIRESTORE
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ public void setType(Type type) {
+ this.type = type;
+ }
+
+ public String getProjectId() {
+ return projectId;
+ }
+
+ public void setProjectId(String projectId) {
+ this.projectId = projectId;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public void setLocation(String location) {
+ this.location = location;
+ }
+}
diff --git a/contrib/spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/contrib/spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 000000000..a99ecf604
--- /dev/null
+++ b/contrib/spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1,8 @@
+com.google.adk.autoconfigure.AdkArtifactsAutoConfiguration
+com.google.adk.autoconfigure.AdkSessionAutoConfiguration
+com.google.adk.autoconfigure.AdkFirestoreSessionAutoConfiguration
+com.google.adk.autoconfigure.AdkMemoryAutoConfiguration
+com.google.adk.autoconfigure.AdkFirestoreMemoryAutoConfiguration
+com.google.adk.autoconfigure.AdkRunConfigAutoConfiguration
+com.google.adk.autoconfigure.AdkFirestoreAutoConfiguration
+com.google.adk.autoconfigure.AdkRunnerAutoConfiguration
diff --git a/pom.xml b/pom.xml
index 31fe8a93f..710188361 100644
--- a/pom.xml
+++ b/pom.xml
@@ -36,6 +36,7 @@
tutorials/city-time-weather
tutorials/live-audio-single-agent
a2a
+ contrib/spring-boot-starter