Dev Services
The Memory Service Quarkus extension provides Dev Services that automatically start a memory-service container in development mode. This lets a Quarkus agent app run locally without a separate Memory Service setup.
Why Use Dev Services?
Dev Services automatically:
- Starts a compatible memory-service container using the extension’s
X.Yimage line for releases, orlatestfor SNAPSHOT builds - Configures your application with the correct connection URL and API key
- Uses self-contained local storage inside the container for development
- Encrypts local storage with a well-known development key, enabling public signed attachment URLs without setup
- Connects to Keycloak Dev Services when your app configures OIDC
- Handles container lifecycle when the application starts and stops
- Generates secure API keys automatically if not configured
The default memory-service container does not require PostgreSQL, MongoDB, Redis, Infinispan, Qdrant, or pgvector dev services. It runs with SQLite, local cache, SQLite vector search, local embeddings, and filesystem attachments.
How It Works
When you run your Quarkus application in dev mode (mvn quarkus:dev), the extension:
- Checks if Docker is available
- Checks if
memory-service.client.urlis already configured - If not configured, starts a memory-service container
- Configures your application with:
memory-service.client.url- The base URL of the dev memory-servicememory-service.client.api-key- The API key, generated or from your configquarkus.grpc.clients.responserecorder.*- The gRPC client host, port, and plaintext settings
The memory-service container is configured by default with:
MEMORY_SERVICE_DB_KIND=sqlite
MEMORY_SERVICE_DB_URL=file:/tmp/memory-service-dev/memory-service.db
MEMORY_SERVICE_DB_MIGRATE_AT_START=true
MEMORY_SERVICE_HOST=0.0.0.0
MEMORY_SERVICE_PLAIN_TEXT=true
MEMORY_SERVICE_TLS=false
MEMORY_SERVICE_ALLOW_NON_LOOPBACK_PLAINTEXT=true
MEMORY_SERVICE_CACHE_KIND=local
MEMORY_SERVICE_MANAGEMENT_ON_MAIN_LISTENER=true
MEMORY_SERVICE_VECTOR_KIND=sqlite
MEMORY_SERVICE_EMBEDDING_KIND=local
MEMORY_SERVICE_ATTACHMENTS_KIND=fs
MEMORY_SERVICE_ATTACHMENTS_FS_DIR=/tmp/memory-service-dev/attachments
MEMORY_SERVICE_TEMP_DIR=/tmp/memory-service-dev/tmp
MEMORY_SERVICE_ENCRYPTION_KIND=dek
MEMORY_SERVICE_ENCRYPTION_DEK_KEY=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
The well-known DEK is intended only for the local Dev Services container. Production deployments must configure a securely generated key or another encryption provider.
If the app uses Keycloak Dev Services, the extension also passes the OIDC issuer and internal discovery URL to the memory-service container and defaults MEMORY_SERVICE_OIDC_ALLOWED_AUDIENCES=memory-service. The generated default Keycloak realm is customized to include that audience in access tokens. Imported or custom realms must provide a matching audience mapper; override memory-service.devservices.env.MEMORY_SERVICE_OIDC_ALLOWED_AUDIENCES when they issue a different audience.
Configuration Properties
The following configuration properties control Dev Services behavior.
memory-service.client.url
Type: String
Default: Not set (triggers Dev Services)
Description: The base URL of the memory-service instance. If this is set, Dev Services will not start automatically. Use this to point to an existing memory-service instance.
# Disable Dev Services and use an existing instance
memory-service.client.url=http://localhost:8082
memory-service.client.api-key
Type: String
Default: Auto-generated random key if not set
Description: The API key used to authenticate agent requests to the memory-service. If not configured, Dev Services generates a random Base64-encoded key and exposes it to both the container and your application.
# Use a specific API key
memory-service.client.api-key=my-custom-api-key
memory-service.devservices.port
Type: int
Default: Random Docker host port
Description: Optional fixed host port for the memory-service container. This is useful when you want to call the dev memory-service directly with curl or from browser code.
# Make the dev memory-service available at http://localhost:8082
memory-service.devservices.port=8082
When this property is not set, the Quarkus app still receives the correct dynamic port through generated config.
Setting a fixed port also enables the integrated Memory Service developer frontend and configures its external base URL. The console opens without an OAuth redirect: Dev Services generates a separate browser-visible API key for the developer_frontend client and grants that client the admin role. The underscore matches the preserved suffix in MEMORY_SERVICE_API_KEYS_DEVELOPER_FRONTEND. The agent application’s API key remains separate and does not gain admin privileges.
This no-login mode is intended only for the local Dev Services container. Anyone who can reach the port can load the browser-visible admin key from /developer/config.json. Never copy these settings to a production deployment. To test the production OIDC login flow while using Dev Services, set:
memory-service.devservices.env.MEMORY_SERVICE_DEVELOPER_FRONTEND_AUTH_MODE=oidc
memory-service.devservices.env.MEMORY_SERVICE_DEVELOPER_FRONTEND_CLIENT_ID=developer-frontend
With a random port, the integrated frontend remains disabled because its browser-facing URL cannot be known before the container starts.
memory-service.devservices.image-name
Type: String
Default: ghcr.io/chirino/memory-service:X.Y for a released X.Y.Z extension; ghcr.io/chirino/memory-service:latest for SNAPSHOT builds
Description: Overrides the container image used by Dev Services. Use an immutable version tag or digest when you need an exact server build.
# Pin an exact release
memory-service.devservices.image-name=ghcr.io/chirino/memory-service:0.0.3
# Or pin an immutable digest
memory-service.devservices.image-name=ghcr.io/chirino/memory-service@sha256:...
The default X.Y and latest tags are mutable, so Dev Services always checks the registry before starting them instead of relying on a cached local copy. Explicit image overrides use Testcontainers’ standard pull policy.
memory-service.devservices.env.*
Type: String
Default: Not set
Description: Extra environment variables passed through to the memory-service container after its defaults. Use this for roles, CORS, feature flags, or to override default settings such as local storage and encryption.
memory-service.devservices.env.MEMORY_SERVICE_ROLES_ADMIN_OIDC_ROLE=admin
memory-service.devservices.env.MEMORY_SERVICE_CORS_ENABLED=true
memory-service.devservices.env.MEMORY_SERVICE_CORS_ORIGINS=http://localhost:3000
quarkus.devservices.enabled
Type: boolean
Default: true
Description: Global Quarkus Dev Services toggle. Set to false to disable all Dev Services, including the memory-service container.
# Disable all Dev Services
quarkus.devservices.enabled=false
Required Dependencies
For a basic agent app, add the Memory Service extension:
<dependency>
<groupId>io.github.chirino.memory-service</groupId>
<artifactId>memory-service-extension</artifactId>
<version>999-SNAPSHOT</version>
</dependency>
If your app authenticates users with OIDC, add Quarkus OIDC so Keycloak Dev Services can start and the memory-service container can validate the same tokens:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-oidc</artifactId>
</dependency>
You do not need quarkus-jdbc-postgresql, quarkus-mongodb-client, quarkus-redis-client, or quarkus-infinispan-client just to back the memory-service Dev Service.
Example
<dependencies>
<dependency>
<groupId>io.github.chirino.memory-service</groupId>
<artifactId>memory-service-extension</artifactId>
<version>999-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-oidc</artifactId>
</dependency>
</dependencies>
And the corresponding application.properties:
memory-service.client.api-key=agent-api-key-1
memory-service.devservices.port=8082
memory-service.devservices.env.MEMORY_SERVICE_API_KEYS_AGENT=agent-api-key-1
memory-service.devservices.env.MEMORY_SERVICE_ROLES_ADMIN_OIDC_ROLE=admin
quarkus.oidc.client-id=memory-service-client
quarkus.oidc.credentials.secret=change-me