Adapstory Docs
Platform

Platform overview

The shape of Adapstory — bounded contexts, plugin runtime, and where your code runs.

Adapstory is built around a minimal core of bounded contexts (BCs) and a plugin runtime that hosts everything else.

Core bounded contexts

BCNameWhat it owns
BC-01Plugin GatewayMCP tool registry, LLM routing, OpenAPI aggregation
BC-02Plugin LifecycleInstall / update / rollback of plugin manifests
BC-10IdentityUsers, tenants, SSO, RBAC (Keycloak-backed)
BC-15Data Model EngineDynamic entities, schemas, validation, event projection
BC-16Identity RuntimeJWT issuance, token introspection, per-tenant keys
BC-19Multi-Tenant RuntimePlugin isolation, per-tenant DB walls, sidecar injection

Everything outside this list is a plugin.

Two-plane architecture

Control plane (Java 25 + Spring Boot 4): the BCs above, each as its own microservice with its own PostgreSQL database. jOOQ for data access, Kafka for events, CloudEvents 1.0 on the wire.

Data plane (Python 3.12 + FastAPI): AI microservices behind the Plugin Gateway. LangChain / LangGraph, vLLM or Ollama for inference, PyTorch for custom models. One service per capability.

Plugin runtime (BC-19): your plugin ships as a signed container image. At install time the runtime schedules it into the tenant's namespace with the right secrets, resource limits, and network policies.

How plugins plug in

A plugin declares its integration points in plugin.yaml:

apiVersion: adapstory.com/v1
kind: Plugin
metadata:
  name: course-recommender
  version: 1.4.0
spec:
  mcpTools:
    - name: recommend_next_course
      description: Suggest the next course for a given learner
      endpoint: /mcp/recommend
  dataModels:
    extends: [bc15.course, bc15.enrollment]
  events:
    produces: [course.recommended.v1]
    consumes: [enrollment.completed.v1]
  llm:
    gatewayBudget: 500000   # tokens/day per tenant
    defaultModel: claude-sonnet-4-6
  guardrails:
    content:
      - no-pii
      - education-safe

All fields in plugin.yaml are versioned and immutable once published. To change anything material, publish a new version and let the lifecycle controller migrate tenants.

Data boundaries

  • Java ↔ Python — strictly over REST or Kafka. No shared databases. Ever.
  • Plugin ↔ Core — MCP tools (for LLM-driven calls) or Kafka (for async workflows). No direct SQL into core tables.
  • Tenant ↔ tenant — isolated at the schema level (PostgreSQL) and namespace level (Kubernetes). The runtime enforces; you don't have to.

Where to go next

On this page