u/pivoshenko

Kasetto - a declarative AI agent environment manager

Kasetto - a declarative AI agent environment manager

https://preview.redd.it/e5mlrb1pby1h1.png?width=1650&format=png&auto=webp&s=96b31df64005a0d96a4e5900cd5c8dd39426e013

I've been building Kasetto: a single Rust binary that takes one YAML config and syncs Skills and MCP servers into every AI agent on your machine or your teammates' machines. Supported: Claude Code, Cursor, Codex, Windsurf, Copilot, Gemini CLI, and more.

Sources can be GitHub, GitLab, Bitbucket, Codeberg, Gitea, self-hosted instances, or local directories. MCP configs are auto-merged into the right format per agent so you don't have to hand-edit four different settings files every time you add a server.

The core idea: the YAML is the source of truth. Version it, share it, bootstrap a teammate's whole agent setup in one command. No registry, no boilerplate — any directory with a SKILL.md is a skill.

>Inspired by uv - what uv did for Python packages, Kasetto aims to do for AI skills.

What it gives you:

  • Declarative - one YAML describes your entire setup. Version-controlled, readable, auditable.
  • Multi-agent - Claude Code, Cursor, Codex, Windsurf, Copilot, Gemini CLI, and more. One config, every agent updated.
  • Enterprise & private repos — GitHub, GitLab, Bitbucket, Codeberg, Gitea, and self-hosted instances out of the box.
  • Skills & MCP - any directory with a SKILL.md is a skill. MCP server configs are auto-merged into every supported format (Cursor JSON, Claude JSON, Copilot VS Code, Codex TOML).
  • Fast - written in Rust. SHA-256 content hashing and lock file diffing mean only what changed gets touched.
  • Universal - single static binary for macOS, Linux, and Windows. Install as kasetto, run as kst. CI-friendly with --json output and proper exit codes.

A kasetto.yaml looks like this - multiple agents, multiple sources, pinned refs/branches, per-skill paths, and an optional extends: for inheriting a shared team base:

# inherit a shared base config — overrides merge on top
# extends: github.com/acme/kasetto-base/raw/main/kasetto.yaml
agent:
  - claude-code
  - cursor
  - opencode

scope: project # or global
# destination: ./.agents/skills  # optional, override install path

skills:
  - source: github.com/acme/frontend-pack
    skills: "*"

  - source: gitlab.com/team/internal-tools
    branch: master
    skills:
      - react-patterns
      - go-standards

  - source: codeberg.org/oss/shared
    ref: v2.1.0
    skills:
      - name: custom-lint
        path: rules/custom-lint
      - name: format-helpers
        path: rules/format

mcps:
  - source: github.com/acme/mcp-pack
    mcps: "*"

  - source: github.com/acme/monorepo
    ref: v1.4.0
    mcps:
      - github
      - linear

Running it:

# uses ./kasetto.yaml in the current directory
kst sync

# or point at a shared team config over HTTPS
kst sync --config https://example.com/team-skills.yaml

Want bare kst sync to always pull from a remote URL? Persist it once in ~/.config/kasetto/config.yaml:

source: https://github.com/pivoshenko/pivoshenko.ai/blob/main/kasetto.yaml

After that, kst sync resolves the URL automatically — no --config flag needed. Then to see what landed:

kst list      # interactive browser with vim-style navigation
kst doctor    # version, paths, last sync status

For a real, runnable example: pivoshenko/pivoshenko.ai is my public config — it pulls skills from Anthropic, Vercel Labs, Apollo, and a few independent authors into Claude Code and OpenCode. Fork it, point your own config at it with extends:, or use it as the source: above.

Install:

curl -fsSL kasetto.dev/install | sh
# or: brew install pivoshenko/tap/kasetto
# or: cargo install kasetto

Docs: https://kasetto.dev

Repository: https://github.com/pivoshenko/kasetto

Happy to hear feedback, especially from anyone juggling skills across multiple agents or sharing setups across a team.

reddit.com
u/pivoshenko — 4 days ago