Show HN: Kastor – Terraform-style specs for AI agents Kastor, a new open-source tool, provides Terraform-style declarative specs for AI agents, allowing developers to define agents in versionable HCL files and compile them to target frameworks like LangGraph or reconcile them as long-lived resources on hosted platforms. The tool aims to replace imperative agent definitions and platform-specific UIs with a vendor-neutral, reviewable source of truth. 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 /weirdGuy/kastor/blob/main/SPEC.md . 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 https://github.com/weirdGuy/kastor/releases , verify it against checksums.txt , and put the kastor binary on your PATH. Prerequisites: Go 1.26+, Python 3.11+, an OpenAI API key, and a Tavily https://tavily.com 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 ./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 working directory or point the KASTOR MCP CONFIG env var 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, 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 . go build ./... build everything go test ./... run all tests SPEC.md is the source of truth for design decisions; CLAUDE.md documents the day-to-day conventions.