kastor
- title
- kastor
- type
- toolbox
- summary
- HCL specs for AI agents, compiled to LangGraph code or reconciled Terraform-style with plan/apply
- tags
- go, ai-agents, spec-driven-development, hcl, langgraph, codegen, infrastructure-as-code, cli, watchlist
- language
- Go
- license
- Apache-2.0
- created
- 2026-07-18
- updated
- 2026-07-18
A source-of-truth layer for AI agents. You define an agent's model, prompts, tools, inputs, outputs, and dependencies in HCL, validate the spec, and then either compile it to runnable framework code or reconcile hosted agents against it with Terraform-style plan / apply / state. The pitch is that an agent's definition today gets scattered across framework code, prompt files, tool files, platform UI settings, and environment variables, and that this scatter should collapse into one versionable, reviewable, diffable contract. Part of the same spec-driven agent family as acai.sh and beads, but aimed at the agent's outer interface rather than its acceptance criteria or task graph.
The author is explicit about the boundary: Kastor is not an agent runtime. Frameworks like LangGraph still execute the agent; hosted platforms still run managed ones. Kastor sits above them and describes only the parts that already show up everywhere no matter which runtime you pick. The bet is that runtime patterns will keep churning while the need for a reviewable agent contract will not.
How it works
A module is a directory of declarative files:
| File type | Holds |
|---|---|
.agent |
Agent definition: model, prompt, tools, inputs, outputs, dependencies |
.tool |
Tool interface plus implementation source |
.prompt |
Prompt template plus its required variables |
kastor.hcl / *.kastor |
Project file: models, targets, defaults |
Blocks reference each other by address, not by file path โ an agent points at model.fast, prompt.weather_system, tool.web_search. Those references also form a dependency graph, and an address like agent.forecast.output.summary is validated at compile time to confirm the output exists and to order the graph. Prompt variables and references are checked during kastor validate.
From a validated module there are two paths. kastor build compiles the spec into a runnable framework project โ LangGraph is the only codegen target working today, with Vercel eve planned and Burr under consideration after a HN suggestion. The generated project is treated as a disposable output, not the source of truth: it isn't committed, it's reproducible from the spec, and codegen determinism is enforced by tests. The second path, kastor plan / apply / destroy, reconciles long-lived hosted agents against a local state file with three-way diffs and drift detection. plan is a pure read that never touches remote resources or state; attribute-level diffs show on updates, and out-of-band remote changes surface as drift warnings. Today the only platform target is a built-in in-memory one, so plan/apply runs without any credentials.
Example
An agent spec:
agent "weather" {
description = "Answers weather questions for a location and date"
model = model.fast
system_prompt = prompt.weather_system
tools = [tool.web_search]
input "location" {
type = string
description = "The location to get weather for"
}
input "date" {
type = string
optional = true
}
output "weather" {
type = string
}
}
kastor init demo scaffolds a minimal module โ one agent, one MCP tool, one prompt, a model, a LangGraph target โ that validates and builds with no edits, using the reference MCP fetch server via uvx so no API key is needed. Beyond that:
kastor init demo
cd demo
kastor validate
kastor build # writes a LangGraph project to the target's declared output dir
kastor plan examples/weather/
kastor apply examples/weather/
Tool endpoints are resolved by spec URI (mcp://search-server/tavily_search); how to actually reach that server is deployment config, supplied through an mcp_servers.json file or the KASTOR_MCP_CONFIG env var, kept out of the spec and gitignored because the URL can embed an API key.
Limitations
Early proof of concept, single author, 57 stars. Only one codegen target (LangGraph) and one platform target (the in-memory one) exist; hosted providers like Bedrock AgentCore or Dify are still in design. Cross-agent dependencies are validated and ordered but not executed โ if one agent's optional input references another agent's output, the generated code will not run the upstream agent for you; you run it yourself and pass its summary in via --inputs. Building the LangGraph example end to end needs Go 1.26+, Python 3.11+, and OpenAI plus Tavily API keys. The HN thread raised the obvious risk directly: nobody has settled what an "agent" is yet, so anything that tries to crystallize the current shape can be obsoleted fast โ the author's counter is that he's deliberately standardizing only the outer contract (inputs, outputs, model, prompt, tools, target), not the control loop, on the theory that the contract is the stable part. On watchlist for that reason; see watchlist.
Repo: https://github.com/weirdGuy/kastor โ 57 stars, Apache-2.0.