---
title: "sx: The Control Plane for Your AI Assets"
description: "I spent an afternoon feeding 200 AI skills, agents, and MCP configs into sx — a tool that promises to be npm for the agent ecosystem. Here's what it actually takes to consolidate three years of accumulated AI configuration."
pubDatetime: 2026-06-07T16:00:00Z
author: hrbrmstr
tags: ["sx", "ai-agent", "developer-tools", "claude-code", "opencode", "mcp", "infrastructure"]
---
> Original: [sx: The Control Plane for Your AI Assets](https://ai.rud.is/posts/2026-06-07-sx-the-control-plane-for-ai-assets)

Run AI coding agents for more than a few months and you'll accumulate a skill problem. The exact shape depends on which clients you use, but the pattern's universal: skills, rules, agents, MCP servers, and commands scattered across `~/.claude/skills/`, `~/.config/opencode/skills/`, `~/.config/opencode/agents/`, `~/.agents/skills/`, and whatever other directories each tool vendor decided was canonical this quarter. Symlinks knit it into something that mostly works, but there's no source of truth, no versioning, and no honest answer to "what AI assets do I actually have?"

My situation: 117 local skill directories, 57 agent definitions, 16 MCP server configs, and another 75 skills symlinked in from upstream repos – spread across three skill directories, lashed together with relative symlinks, maintained entirely by hand. Functional, but fragile and opaque in equal measure.

[SX](https://github.com/sleuth-io/sx) bills itself as "the control plane for your team's AI" – npm for the agent ecosystem, basically. I spent an afternoon feeding my entire collection into it.

## The landscape

Before touching sx, I mapped what I actually had. Three skill directories, each with a different relationship to the truth:

| Directory | Real dirs | Symlinks | Total |
|-----------|-----------|----------|-------|
| `~/.agents/skills/` | 11 | 60 | 71 |
| `~/.claude/skills/` | 16 | 18 | 34 |
| `~/.config/opencode/skills/` | 36 | 46 | 82 |

`~/.agents/skills/` was the closest thing to canonical – most of its real directories were primary copies. `~/.claude/skills/` was a thin layer: half symlinks back into `.agents/skills/`, half standalone skills (the printing-press family, sourcehut, gribouille, ssh-honeypot-dev). `~/.config/opencode/skills/` was the union of everything plus a pile of OpenCode-specific skills (agent-browser, frontend-design, git-commit, etc.).

The symlink web was well-maintained – no divergent copies, every shared name resolved to the same canonical path. But it was still a web. You couldn't hand it to anyone and say "here are my skills."

On top of the skills: 57 agent definitions in `~/.config/opencode/agents/` (review personas, researchers, linters), 14 MCP servers (8 local binaries, 6 remote URLs).

## How sx works

SX has three operations: manage, distribute, and govern.

**Manage**: `sx add /path/to/skill` reads a directory, auto-detects its type (skill, agent, command, mcp, hook, rule), wraps it with version metadata, and stores it in a vault. **Distribute**: `sx install` reads the vault manifest, resolves it against your git identity and client directory, and writes assets into each client's native format. **Govern**: `sx audit` and `sx stats` track who-installed-what and which assets are actually being used.

The vault can be a local directory, a git repository, or the hosted Skills.new service. Multiple vaults can be active simultaneously via profiles.

The design follows the manifest-and-lock pattern from npm, cargo, and uv. `sx.toml` is the manifest – the source of truth, committed to git. A lock file is resolved per-user per-session, and old locks are rotated with timestamps so prior installs stay on disk.

## The consolidation

I wanted everything in one place: local skills, agents, MCP configs, and the symlinked ext-skills from upstream repos. SX handles the first three cleanly. The upstream-managed skills (compound-engineering plugin, duckdb-skills, everyskill, R skills, knowledge-work plugin, etc.) live elsewhere, so sx can't be the canonical source for them – but it can still distribute them.

I set up two vaults.

**Default vault** (path vault at `~/.sx/vault`): 61 local-only skills, 56 agents, and 3 MCP servers. This is the personal canon – anything I maintain myself goes here.

**Ext-skills vault** (git vault at `github.com/hrbrmstr/sx-vault`): 80 skills from upstream repos, managed via a separate sx profile. When the upstream changes, I re-add and bump the version.

The two-profile setup works well. Both profiles can be active simultaneously, and `sx install` resolves assets from both vaults in a single pass. The git vault pushes to a private GitHub repo, so cloning on another machine gives me the same ext-skills without any manual reconstruction.

## The install

Running `sx install` after populating both vaults installed 200 assets across all five detected clients in one pass:

```
Claude Code    →  ~/.claude/skills/  (skills) + settings.json (agents, MCPs)
Cursor         →  ~/.cursor/
Gemini Code    →  ~/.gemini/commands/ (as TOML command files)
Kiro           →  ~/.kiro/
OpenCode       →  ~/.config/opencode/ (skills, agents)
```

Each client gets assets in its native format – Claude Code gets skills in its skills directory and agents in settings.json, Gemini gets TOML command files, OpenCode gets its own directory structure. SX writes all of it from the same vault definitions.

SX also installs session hooks: on every session start, it checks whether the lock file has changed and auto-updates any new or version-bumped assets. No manual sync.

## What worked

The auto-detection is solid. `sx add` identified skill directories, agent `.md` files, and MCP `metadata.toml` directories without any type hints. The distinction between skill files (directory with `SKILL.md`) and agent files (single `.md` with frontmatter) is handled transparently – I didn't have to babysit it.

The cross-client install is the headline feature and it delivers. Add a skill once, it shows up in Claude Code, Cursor, Gemini, Kiro, and OpenCode. That's the value proposition, and it works.

Versioning is straightforward. Each `sx add` creates a new version; old versions stay in the vault. If an upstream repo breaks something, `sx install find-skills==1` rolls you back.

## What didn't

Three rough edges worth knowing about before you commit an afternoon to this.

**Git is required for git vault operations.** This sounds obvious, but sx runs `git rev-parse` as part of version checking in git vaults, and if git isn't in `$PATH` – which happens in non-interactive shells – every operation fails. I had to export PATH explicitly to work around it. macOS users on Homebrew need `/opt/homebrew/bin/` in PATH.

**MCP asset validation requires non-empty args.** For stdio-transport MCP servers, sx's metadata validator requires `args` to be a non-empty array. Standalone binaries like `arkime-mcp` or `censys-mcp` – which take no arguments and communicate over stdio directly – can't be registered as sx MCP assets. Only three of my nine local MCPs made it in: those that already took arguments (joplin-mcp via `uvx`, inoreader via `bun run`, gopls via `gopls mcp`). The other six had to stay in opencode.json.

**No upstream refresh.** SX is a publish-and-distribute system, not a pull-from-upstream system. `sx add <path>` copies the directory into the vault; if the source repo updates, the vault copy doesn't. For personally-maintained skills this doesn't matter – the vault is the source. For skills from upstream repos (compound-engineering, duckdb-skills), you need to remember to re-add them when they change. A `refresh` command that re-imports from the original source path would solve this cleanly.

## Should you use it?

One AI client and ten skills? Sx is overkill. Multiple clients with skills scattered across more than one directory? The hour or two of initial setup pays for itself the first time you add a skill and it shows up everywhere automatically.

The real value shows at team scale. The git vault model means you push the vault and everyone runs `sx install`. The session hook means they get updates without thinking about it. The audit trail means you know who has what.

For a solo operator with a sprawling collection of AI artifacts – which is exactly what I had – the consolidation alone justifies it. Three directories of symlinks and hand-maintained configs became a vaulted asset catalog with versioning and multi-client distribution. The rough edges are real (the MCP args constraint is genuinely annoying), but the underlying model is right: manage once, install everywhere is exactly what this ecosystem needs as every new client vendor keeps reinventing the skills directory.

The repo is at [github.com/sleuth-io/sx](https://github.com/sleuth-io/sx). Install with `brew install sx` or folow the directionsin the repo.

