The industry has solved execution — provider abstraction, structured output, tool calling. It has not solved the layer around execution: a registry of what capabilities exist, who owns them, which version is live, and what each one costs. This is a first-party analysis of that gap and how Capstead closes it, native to the Spring Boot runtime.
Last updated July 2026
Frameworks like Spring AI and LangChain4j made calling an LLM from Java straightforward. Observability tooling followed: you can trace a model call, count its tokens, and price it. But that unit — the model invocation — is the wrong unit for governance. Organizations don't own model calls; they own business capabilities: "Generate Lesson", "Classify Ticket", "Review Answer". A capability may call the model zero, one, or many times, may call other capabilities, and is owned by a team, versioned, and budgeted.
The unanswered question: across all our services, what AI capabilities exist, who owns them, which version is live, and what do they cost?
No mainstream framework answers this, because it is deliberately out of their scope — they are execution libraries. The answer requires a governance layer that treats a capability as a first-class, discoverable, versioned, cost-attributed entity. That is what Capstead is.
Verified from primary documentation, July 2026. The point is not that these tools are lacking — it's that they operate at a different layer. Capstead reuses them and governs on top.
| Concern | Spring AI | LangChain4j | Semantic Kernel | MCP | Capstead |
|---|---|---|---|---|---|
| Provider abstraction · structured output · tool calling | ✓ | ✓ | ✓ | — | reuses |
| Capability registry + metadata | ✗ | ✗ | partial | partial | ✓ |
| Capability versioning | ✗ | ✗ | ✗ | ✗ | ✓ |
Runtime discovery endpoint (/actuator/capabilities) |
✗ | ✗ | ✗ | ✗ | ✓ |
| Cost attributed to a capability (not a model call) | per-call | ✗ | ✗ | ✗ | ✓ |
| Ownership · policy · daily budgets | ✗ | ✗ | ✗ | ✗ | ✓ |
| Durable execution history + parent-child trees | ✗ | ✗ | ✗ | ✗ | ✓ |
| Enforced provider hiding | ✗ | ✗ | ✗ | ✗ | ✓ |
Notes: Spring AI observability is per-model-call (gen_ai.client.operation,
gen_ai.client.token.usage) — no capability registry or governance. Semantic Kernel exposes
in-process plugin metadata (name/description) and can export plugins as MCP tools, but carries no
versioning/ownership/cost/actuator — hence "partial". MCP standardizes tool discovery for an LLM,
not governance (owner/version/cost/health).
Each capability is keyed by name@version with domain, owner, and tags — discovered at startup and served over actuator.
Every call becomes a structured CapabilityExecution with an id, principal, and one ModelInvocation per model call.
When one capability calls another, the nested execution links to its parent — an execution tree with no workflow engine.
Capstead does not count tokens; it attributes the framework's existing token/model data to the capability and prices it per model.
A per-UTC-day spend ledger blocks a capability once its @DailyBudget is reached — governance the runtime enforces.
With capstead-jdbc, executions persist to Postgres/MySQL/H2, so scorecards survive restarts and aggregate across replicas.
Mix and match in the same app. If a method is declared more than one way, the annotation wins. Each of these has a runnable version in the samples.
@Capability(name = "Generate Lesson", domain = "Learning",
owner = "Content Team", version = "2", tags = {"lesson","java"})
@DailyBudget("$25")
public Lesson generateLesson(String topic) { ... }
Ideal for third-party or generically-named methods (generate/ask/review).
capstead:
capabilities:
- name: "Summarize Report"
bean: reportService # the Spring bean name
method: summarize
domain: Reporting
owner: Data Team
version: "1"
Annotate an interface; Capstead synthesizes the implementation and governs it like any other capability. Provider-neutral — supply one CapabilityModelInvoker bean (Spring AI, LangChain4j, a raw SDK).
@CapabilityClient
@ModelProfile("reasoning")
public interface LessonCapability {
@Capability(name = "Generate Lesson", domain = "Learning")
@Prompt("Generate a Java lesson for {{topic}}")
Lesson execute(String topic); // no body — Capstead writes it
}
Capstead is dogfooded at engineerprep.io, an AI-powered
technical-interview-prep platform on Spring Boot. It governs about a dozen capabilities across two domains
and attributes cost across Anthropic Claude and Amazon Nova (via Bedrock) —
all visible on the /capstead dashboard.
<dependency>
<groupId>io.capstead</groupId>
<artifactId>capstead-starter</artifactId>
<version>0.8.0</version>
</dependency>