Show HN: Kastor – Terraform-style specs for AI agents

weirdguy2 pts0 comments

GitHub - weirdGuy/kastor: Declarative language and toolchain for AI agents: define agents, tools and prompts in HCL, then compile to frameworks or manage them on hosted platforms with plan/apply semantics. · GitHub

/" data-turbo-transient="true" />

Skip to content

Search or jump to...

Search code, repositories, users, issues, pull requests...

-->

Search

Clear

Search syntax tips

Provide feedback

--><br>We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Cancel

Submit feedback

Saved searches

Use saved searches to filter your results more quickly

-->

Name

Query

To see all available qualifiers, see our documentation.

Cancel

Create saved search

Sign in

/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up

Appearance settings

Resetting focus

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

weirdGuy

kastor

Public

Notifications<br>You must be signed in to change notification settings

Fork

Star

main

BranchesTags

Go to file

CodeOpen more actions menu

Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit

History<br>53 Commits<br>53 Commits

.github/workflows

.github/workflows

cmd/kastor

cmd/kastor

examples

examples

internal

internal

scripts

scripts

.gitignore

.gitignore

.goreleaser.yaml

.goreleaser.yaml

CLAUDE.md

CLAUDE.md

LICENSE

LICENSE

README.md

README.md

SPEC.md

SPEC.md

go.mod

go.mod

go.sum

go.sum

View all files

Repository files navigation

Kastor

Kastor is "Terraform for AI agents." Agents today are defined imperatively inside frameworks (LangGraph, CrewAI) or clicked together in platform UIs (OpenAI Assistants, Bedrock Agents) — there is no vendor-neutral, versionable, reviewable source of truth. Kastor provides one: a typed, declarative spec (.agent, .tool, .prompt files in HCL) and a Go toolchain with two paths — kastor build generates runnable projects for target frameworks, and kastor plan / kastor apply reconcile agents as long-lived resources on hosted platforms, with state, diffs, and drift detection.

The full design lives in SPEC.md.

Install

Homebrew:

brew tap weirdGuy/tap && brew install kastor

Install script (verifies the release checksum, installs to /usr/local/bin or ~/.local/bin, never sudo):

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

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.

Quickstart: build the weather example

Prerequisites: Go 1.26+, Python 3.11+, an OpenAI API key, and a Tavily API key (the example's search tool runs against Tavily's hosted MCP server).

Compile the spec to a LangGraph project:

go build ./cmd/kastor<br>./kastor validate examples/weather/<br>./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<br>python3 -m venv .venv<br>. .venv/bin/activate<br>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 working directory (or point the KASTOR_MCP_CONFIG env var at a file elsewhere). For Tavily's hosted server:

"search-server": {<br>"transport": "streamable_http",<br>"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, never commit it. Also note the spec URI's last path segment (tavily_search) must name a tool the server actually advertises, or 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 (SPEC.md §3.2/§4): 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.

Development

go build ./... #...

kastor spec search weather agents agent

Related Articles