Tool

Define and deploy AI agents as declarative infrastructure

Kastor is Terraform for AI agents - a declarative HCL spec that compiles to LangGraph projects or reconciles agents as hosted platform resources.

Works with langgraphcrewaiopenaibedrocktavily

91
Spark score
out of 100
Updated 11 days ago
Version 0.1.2
Models
gpt 4ouniversal

Add to Favorites

Why it matters

Kastor lets teams version, review, and deploy AI agents using a declarative specification language-like Terraform for agents. Instead of imperatively coding agents in frameworks or clicking through platform UIs, you define agents, tools, and prompts in typed HCL files, then either generate runnable framework projects or reconcile them as managed resources on hosted platforms with state tracking and drift detection.

Outcomes

What it gets done

01

Compile typed .agent, .tool, and .prompt specs into runnable LangGraph or CrewAI projects

02

Validate agent definitions and dependency graphs at build time before deployment

03

Reconcile agent state on hosted platforms with plan/apply workflows and drift detection

04

Connect agents to MCP servers and external tools via vendor-neutral configuration

Install

Add it to your toolbox

Run in your project directory:

curl -fsSL https://spark.entire.vc/get/weirdguy-kastor | bash

Overview

Kastor

Kastor is a declarative HCL spec plus Go toolchain that acts as Terraform for AI agents, either compiling .agent/.tool/.prompt files into a runnable framework project (kastor build) or reconciling agents as hosted platform resources with state and drift detection (kastor plan/apply). Use it to define AI agents in a framework-agnostic, versionable spec instead of scattering definitions across imperative framework code or platform UIs; as a v0 project, it doesn't yet auto-run cross-agent output dependencies for you.

What it does

Kastor is described by its author as "Terraform for AI agents." Today, agents are defined imperatively inside frameworks like LangGraph or CrewAI, or clicked together in platform UIs like OpenAI Assistants or Bedrock Agents - there is no vendor-neutral, versionable, reviewable source of truth for what an agent actually is. Kastor provides that source of truth: a typed, declarative spec written in HCL (.agent, .tool, and .prompt files), paired with a Go toolchain offering two distinct paths. kastor build generates a runnable project for a target framework (for example, LangGraph) from the spec. kastor plan and kastor apply instead reconcile agents as long-lived resources directly on hosted platforms, with state tracking, diffs, and drift detection - the Terraform-style workflow the name references.

Tool bindings in the spec reference external services by a spec URI (e.g. mcp://search-server/tavily_search) rather than embedding deployment details: how to actually reach that MCP server is deployment configuration, kept separate from the spec itself, in a gitignored mcp_servers.json file (or a file pointed to via KASTOR_MCP_CONFIG). Cross-agent references - like one agent's optional input referencing another agent's output - are validated at compile time and used to order the dependency graph, though as of the current version generated code does not automatically run the upstream agent for you.

When to use - and when NOT to

Use Kastor when you want to define AI agents in a framework-agnostic, typed spec that can be versioned, code-reviewed, and diffed like infrastructure - either to generate a runnable project for a specific framework via kastor build, or to manage agents as reconciled, drift-detected resources on a hosted platform via kastor plan/kastor apply. It fits teams who want one declarative source of truth instead of agent definitions scattered across imperative framework code or platform-specific UIs.

It is a v0 project with a documented caveat: cross-agent output references are validated and ordered but not automatically executed, so multi-agent pipelines with dependencies currently require manually running upstream agents and passing their output forward yourself. Generated project output is not meant to be committed to source control - it's treated as reproducible build output from the spec, with codegen determinism enforced by tests, so don't check the gen/ directory into git.

Inputs and outputs

Input is the HCL spec itself (.agent/.tool/.prompt files) plus, at run time, a deployment-specific mcp_servers.json (or KASTOR_MCP_CONFIG-pointed file) describing how to actually reach each referenced MCP server, and provider API keys as environment variables (e.g. OPENAI_API_KEY for a model block using the openai provider).

go build ./cmd/kastor
./kastor validate examples/weather/
./kastor build examples/weather/

Output of kastor build is a generated, runnable project written to the target's declared output directory (e.g. examples/weather/gen/langgraph), including its own generated README.md documenting every agent's inputs and outputs, tool bindings, and MCP configuration. Running the generated project (e.g. python3 main.py weather --inputs '{"location": "Lisbon", "date": "tomorrow"}') prints the agent's declared output contract as JSON, such as {"weather": "..."}.

Integrations

Kastor's example integrates with LangGraph as a codegen target, OpenAI as a model provider (via OPENAI_API_KEY), and Tavily's hosted MCP server for web search (via a streamable_http transport URL embedding a Tavily API key). Tool bindings generally reference any MCP server by spec URI (mcp://<server>/<tool>), decoupling the spec from a specific deployment's server addresses or credentials. The build is a standard Go toolchain (go build ./..., go test ./...), and generated Python projects use a standard venv plus requirements.txt workflow.

Who it's for

Teams and platform engineers who want AI agent definitions to be vendor-neutral, versionable, and reviewable the way infrastructure-as-code is, rather than locked into a specific framework's imperative code or a platform's proprietary UI - especially those managing agents across multiple frameworks or wanting Terraform-style plan/apply/drift-detection semantics for agents deployed to hosted platforms.

Source README

Kastor

Kastor is a source-of-truth layer for AI agents.

Define agents, tools, prompts, models, and targets in HCL. Validate the spec. Compile it to runnable framework code. Later, reconcile hosted agents with Terraform-style plan / apply / state.

kastor validate examples/weather
kastor build examples/weather
kastor plan examples/weather

Agents today are often split across framework code, prompt files, tool files, platform UI settings, and environment configuration. Kastor's idea is that agents need a versionable, reviewable, declarative contract before they become serious software.

The full design lives in SPEC.md.

Status

Kastor is an early proof of concept.

Working today:

  • scaffold a new module with kastor init
  • parse .agent, .tool, .prompt, and kastor.hcl
  • validate references and prompt variables
  • build runnable LangGraph projects
  • run kastor plan / kastor apply / kastor destroy against the built-in in-memory platform
  • local state file, three-way diffs, and drift detection
  • examples: weather agent, content scheduler

Planned for v0:

  • a second codegen target: Vercel eve
  • hosted platform providers (in design - candidates: Bedrock AgentCore, Dify)

Kastor is not an agent runtime.

Demo

How it works

.agent + .tool + .prompt + kastor.hcl
                │
                ▼
        kastor validate
                │
      ┌─────────┴─────────┐
      ▼                   ▼
kastor build        kastor plan/apply
framework code      hosted agents
(LangGraph)         (platform targets)

Kastor has two paths:

  • kastor build compiles a Kastor module into runnable framework code.
  • kastor plan / kastor apply reconciles long-lived hosted agents with state, diffs, and drift detection.

Example

An agent in Kastor is a small declarative 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
  }
}

The generated code is not the source of truth. The Kastor module is.

Quickstart: start your own module

kastor init scaffolds a minimal working module - one agent, one MCP tool, one prompt, a model, and a LangGraph codegen target - that validates and builds with zero edits:

kastor init demo
cd demo
kastor validate
kastor build

The scaffolded agent answers a question by fetching web pages through the reference MCP fetch server (run via uvx, no API key needed). The scaffold's README.md walks through running the generated project end to end.

init refuses a directory that already contains visible files; --force overwrites only the scaffold's own file names and keeps everything else.

Quickstart: no credentials required

This path validates the example and runs plan / apply against the built-in in-memory platform target. It does not create remote resources and does not require API keys.

go build -o kastor ./cmd/kastor
./kastor validate examples/weather/
./kastor plan examples/weather/
./kastor apply examples/weather/

Example plan output:

$ kastor plan examples/weather/
  + agent.forecast (not in state)
  + agent.geocoder (not in state)
  + agent.weather (not in state)

Plan for target.memory: 3 to create, 0 to update, 0 to delete, 0 unchanged.

kastor plan is a pure read: it never touches remote resources or the state file. Updates show attribute-level diffs, and out-of-band remote changes surface as drift warnings.

Quickstart: generate and run LangGraph

This path compiles the weather agent to a runnable LangGraph project.

Prerequisites:

  • Go 1.26+
  • Python 3.11+
  • an OpenAI API key
  • a Tavily API key, because the example's search tool runs against Tavily's hosted MCP server

Compile the spec to a LangGraph project:

go build -o kastor ./cmd/kastor
./kastor validate examples/weather/
./kastor build examples/weather/

kastor build writes the generated project to examples/weather/gen/langgraph - the target's declared output.

Generated output is not committed. It is reproducible from the spec, and codegen determinism is enforced by tests.

Set up the generated project:

cd examples/weather/gen/langgraph
python3 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt

The example's web_search tool is pinned to an MCP server and tool by its spec URI:

mcp://search-server/tavily_search

How to reach that server is deployment configuration, not spec. Create mcp_servers.json in the generated project's working directory, or point the KASTOR_MCP_CONFIG environment variable at a file elsewhere.

For Tavily's hosted server:

{
  "search-server": {
    "transport": "streamable_http",
    "url": "https://mcp.tavily.com/mcp/?tavilyApiKey=tvly-YOUR-KEY"
  }
}

The URL embeds your API key, which is why mcp_servers.json is gitignored. Treat it as a secret and never commit it.

The spec URI's last path segment, tavily_search, must name a tool the server actually advertises. If it does not, calls fail with does not expose tool.

Export the model credential. The example's model "fast" block uses provider openai:

export OPENAI_API_KEY=sk-...

Run the agent:

python3 main.py weather --inputs '{"location": "Lisbon", "date": "tomorrow"}'

It prints the agent's declared output contract as JSON:

{
  "weather": "..."
}

The generated README.md inside gen/langgraph owns the run-the-project side in full: every agent's inputs and outputs, tool bindings, and MCP configuration.

One v0 caveat: agent.weather's optional forecast_context input references agent.forecast's output. That reference is validated at compile time and orders the dependency graph, but generated code does not run the upstream agent for you. If you want the context, run forecast yourself and pass its summary via --inputs.

File types

A Kastor module is a directory tree containing declarative files:

File type Purpose
.agent Agent definitions: model, prompt, tools, inputs, outputs, dependencies
.tool Tool interface plus implementation source
.prompt Prompt template plus required variables
kastor.hcl / *.kastor Project file: models, targets, defaults

References connect blocks by address, not by file path. For example, an agent references model.fast, prompt.weather_system, and tool.web_search.

References also build the dependency graph. A reference like agent.forecast.output.summary validates that the output exists and orders the graph.

What Kastor is not

Kastor is not an agent runtime.

Frameworks like LangGraph still execute agents. Hosted platforms like Dify still run managed agents. Kastor sits above them as the declarative source-of-truth layer: model, prompts, tools, inputs, outputs, dependencies, and targets.

Kastor also does not try to standardize the full behavior or control loop of an agent. That layer is still changing quickly. The narrower bet is that the outer contract around agents should be reviewable, versionable, and diffable.

Why not Terraform?

Terraform is great for managing remote resources. A Terraform provider for hosted agents may make sense later.

Kastor starts one layer earlier: the agent spec itself.

The same Kastor module should be able to:

  • generate runnable framework code with kastor build
  • reconcile hosted platform agents with kastor plan / kastor apply

That codegen path is why Kastor is a separate toolchain rather than only a Terraform module or provider.

Why not just LangGraph?

LangGraph is a runtime/framework. Kastor is not trying to replace it.

Kastor defines the agent contract and generates a LangGraph project from that spec. The generated code is an output; the Kastor module is the source of truth.

Install

Homebrew (macOS):

brew install weirdGuy/tap/kastor

Install script:

curl -fsSL https://raw.githubusercontent.com/weirdGuy/kastor/main/scripts/install.sh | sh

The install script verifies the release checksum, installs to /usr/local/bin or ~/.local/bin, and never uses sudo.

With Go 1.26+:

go install github.com/weirdGuy/kastor/cmd/kastor@latest

Or download an archive for your platform from the releases page, verify it against checksums.txt, and put the kastor binary on your PATH.

Development

go build ./...   # build everything
go test ./...    # run all tests
go vet ./...     # static checks
gofmt -l .       # formatting check

SPEC.md is the source of truth for design decisions. CLAUDE.md documents the day-to-day development conventions.

Early feedback

I'm currently looking for feedback from people building agents in production or experimenting with agent tooling.

Useful feedback areas:

  • whether the source-of-truth layer makes sense
  • where the spec is too rigid or too loose
  • what framework or hosted platform target should come next
  • what would make the first-run experience smoother

To follow or discuss the project:

  • star/watch the repo for updates
  • open an issue for bugs or design feedback
  • join the early Discord: invite

FAQ

Common questions

Discussion

Questions & comments · 0

Sign In Sign in to leave a comment.