mcp server
equipr
Installs skills, commands, and MCP servers from marketplaces and Agent Plugins (AP) sources into your coding agents
Set up
Runs on your computer. Pick your agent and operating system.
This project does not publish an install method we can turn into a config. Follow the README instead.
README
synced Oct 27, 2026equipr
equipr installs skills, commands, and MCP servers from marketplaces and
Agent Plugins (AP) sources into your coding agents:
| Agent | Detected by | Install mechanism |
|---|---|---|
claude-code | ~/.claude/ or claude on $PATH | copy |
codex | ~/.codex/ or codex on $PATH | copy |
opencode | ~/.config/opencode/ or opencode on $PATH | symlink (individual components) |
pi | ~/.pi/agent/ or pi on $PATH | symlink (individual components) |
An agent is offered as an install target when either signal is present: a
newly installed agent has no config dir until its first run, and a config dir
outlives an uninstalled agent. The interactive picker lists every agent it found,
labelled with the evidence (configured, on PATH, or both), and pre-checks the
ones on $PATH — a config dir left behind by an uninstalled agent should not be
a default target. If nothing is on $PATH, everything is pre-checked instead.
It never registers as a native plugin and never touches a config key it doesn't
own: every write into a shared agent config file (~/.claude.json,
~/.codex/config.toml, ~/.config/opencode/opencode.json,
~/.config/mcp/mcp.json) is a targeted single-key merge, so every unrelated
byte is preserved.
Install
# Homebrew (macOS / Linux)
brew install maquina-app/tap/equipr
# or the install script — latest release, checksum-verified;
# installs to /usr/local/bin when writable, else ~/.local/bin
curl -fsSL https://github.com/maquina-app/equipr/releases/latest/download/install.sh | sh
.deb / .rpm packages and raw archives (darwin, linux, windows × amd64,
arm64) are on the releases page.
Build it yourself
Go 1.24+, matching go.mod. To build and install in one step, straight onto
your PATH:
go build -o ~/.local/bin/equipr ./cmd/equipr # or any directory on your PATH
go install ./cmd/equipr works too, but it lands in $(go env GOPATH)/bin,
which is not on everyone's PATH.
Just to try it, without installing anywhere:
go build -o equipr ./cmd/equipr && ./equipr --version
Commands
equipr add <origin> add a source (marketplace, AP repo, npm, or archive)
equipr list [source-id|source-id/plugin] list sources and their plugins
equipr show <source-id>[/plugin] show source or plugin details
equipr install <source>/<plugin>[:<comp>] install into detected agents
equipr update re-fetch sources + re-apply installs
equipr remove <source-id> [--purge] remove a source (optionally purge)
equipr uninstall <source>/<plugin>[:<comp>] remove installed files + records
equipr doctor check install health + cache integrity
equipr status report every recorded install
Usage examples
Add a source — the origin form is detected for you:
# a marketplace repo (git)
equipr add https://github.com/coreyhaines31/marketingskills
# an Agent Plugins repo (git) — local path or URL
equipr add ./path/to/ap-repo
# an npm package (fetched via `npm pack`)
equipr add some-package
# or an explicit npm spec / a local package dir
# (a local dir with package.json and no .git is auto-detected as npm)
equipr add npm:@scope/plugin@1.2.3
# an archive URL (zip / tar.gz / tgz, extracted from its single top-level dir)
equipr add https://example.com/releases/plugin-1.0.0.zip
A walkthrough
Add a marketplace — here coreyhaines31/marketingskills, a single-plugin one:
$ equipr add https://github.com/coreyhaines31/marketingskills
Fetching https://github.com/coreyhaines31/marketingskills
Added marketingskills (marketplace, fetched via git) with 1 plugin(s)
- marketing-skills 2.10.0
list shows every source with the plugins inside it and what each one holds, so
you can tell whether a source is worth opening without a second command:
$ equipr list
marketingskills marketplace
marketing-skills 2.10.0 49 skills
--components (-c) expands each plugin to its component names — these are the
names you pass to install:
$ equipr list marketingskills --components
marketingskills (marketplace)
marketing-skills 2.10.0 49 skills
skill ab-testing
skill ad-creative
skill ads
skill ai-seo
...
list also accepts the <source>/<plugin> form, which prints what show
prints — a plugin's description, author, and every component it ships:
$ equipr list marketingskills/marketing-skills
Plugin: marketing-skills
Version: 2.10.0
Description: Marketing skills for AI agents — conversion optimization, ...
Author: Corey Haines
Skills (49):
- ab-testing
- ad-creative
...
Install one skill. With no --yes, equipr prompts for the agents to install
into. Agents on $PATH are pre-checked; a config-only agent is listed but left
unchecked — space toggles, enter confirms:
$ equipr install marketingskills/marketing-skills:seo-audit
Install into which agents?
Agents on $PATH are pre-checked; space toggles, enter confirms
> ✓ claude-code (configured, on PATH)
codex (configured)
✓ opencode (configured, on PATH)
✓ pi (configured, on PATH)
Installed 1 component(s) into 3 agent(s):
[claude-code] seo-audit (copy -> ~/.claude/skills/seo-audit)
[opencode] seo-audit (symlink -> ~/.config/opencode/skills/seo-audit)
[pi] seo-audit (symlink -> ~/.pi/agent/skills/seo-audit)
configured means the agent's config directory exists; on PATH means its
binary is installed. Either is enough to be offered — a freshly installed
agent has no config directory until its first run — but only on PATH is enough
to be pre-checked, which is why codex above is listed and skipped.
status reports every recorded install, and doctor checks their health:
$ equipr status
STATE COMPONENT SOURCE/PLUGIN AGENT MECH TARGET
ok seo-audit(s) marketingskills/marketing-skills claude-code copy ~/.claude/skills/seo-audit
ok seo-audit(s) marketingskills/marketing-skills codex copy ~/.codex/skills/seo-audit
ok seo-audit(s) marketingskills/marketing-skills opencode symlink ~/.config/opencode/skills/seo-audit
ok seo-audit(s) marketingskills/marketing-skills pi symlink ~/.pi/agent/skills/seo-audit
$ equipr doctor
No issues found.
Origin detection: an explicit npm: prefix is npm; a URL ending
in .zip/.tar.gz/.tgz is an archive; a git URL / git@ / .git / an
existing git repo is git; an existing dir with package.json and no .git is an
npm package; anything else is an npm package name.
Archives are extracted with path containment enforced — an entry that would write outside the cache directory aborts the fetch — and are capped at 512 MiB.
What equipr reads from a source
A source is either a marketplace (.claude-plugin/marketplace.json at the
repo root, plugins in subdirectories) or a single Agent Plugins package
(plugin.json at the root). An origin may name a subdirectory of the
fetched tree, which is how a repository holding several independent AP packages
is added one package at a time:
# explicit form — canonical, works for git, archive, and npm origins
equipr add https://github.com/mariochavez/skills#plugins/claude-md-auditor
equipr add https://github.com/mariochavez/skills#plugins/recuerd0-memory-graph
# a forge URL copied out of the browser works too (http/https only)
equipr add https://github.com/mariochavez/skills/tree/main/plugins/claude-md-auditor
Only the part before the # is fetched; the subpath selects which plugin inside
it the source refers to, and becomes the source's identity — so two plugins from
one repository do not collide on the repository name. The Agent Plugins spec
roots a plugin at a directory and defines no multi-plugin index, so this lives
entirely in the origin: the repository stays a plain collection of spec-clean
packages with nothing equipr-specific in it.
The /tree/<ref>/<path> form is resolved after cloning, against the refs the
clone actually has, so a branch name containing a slash splits correctly. equipr
fetches the default branch only; a URL naming any other ref is rejected with a
pointer to the explicit form rather than silently resolving against the default
branch's tree. On a local path a directory named tree is just a directory.
Within each plugin, equipr discovers:
| Component | Discovered at | Installed as |
|---|---|---|
| skills | any directory under skills/ holding a SKILL.md | <agent skills dir>/<name>/ |
| commands | any .md file under commands/ | <agent skills dir>/<name>/SKILL.md |
| MCP servers | mcp.json at the plugin root ({"mcpServers": {...}}) | a single key merged into the agent's own MCP config |
Both trees are walked, so a plugin may group its components in category
directories (skills/engineering/tdd/SKILL.md). <name> is the component's own
directory or file — tdd, not engineering-tdd — and the walk stops descending
at a directory holding a SKILL.md, so a skill's own bundled files are not
mistaken for skills. Since that name is what it installs as, two components
resolving to the same name are reported as an error rather than one overwriting
the other.
Commands are normalized to <name>/SKILL.md for every agent, so a plugin's
command files and its skills land in the same place and are discovered the same
way.
Install into the agents you pick:
# interactive: pick agents (those on $PATH pre-checked) and components
equipr install marketingskills/marketing-skills
# non-interactive: every present agent, every component, auto-accept conflicts
equipr install marketingskills/marketing-skills --yes
# a single component into one agent (":name" and "-c name" are equivalent)
equipr install marketingskills/marketing-skills:seo-audit -a claude-code
equipr install marketingskills/marketing-skills -c seo-audit -a claude-code
# repeat -a to target several agents
equipr install marketingskills/marketing-skills:seo-audit -a claude-code -a pi
# override the fixed per-agent mechanism (copy/symlink)
equipr install marketingskills/marketing-skills --mechanism symlink
Propagate updates from the source:
equipr update # pull sources + re-apply every install
equipr update --dry-run # report what would change, write nothing
equipr update --on-conflict=skip # leave locally-modified targets alone
equipr update --on-conflict=fail # abort on the first local modification
Remove and clean up:
equipr remove marketingskills # drop the source; records become orphaned
equipr doctor # flag orphaned records / broken symlinks
equipr uninstall marketingskills/marketing-skills # remove files + records (works post-remove)
equipr remove marketingskills --purge # drop source + records + files + cache
Health and status:
equipr status # ok / modified / missing per record
equipr doctor # No issues found (exit 0)
doctor is read-only and reports four classes of problem:
orphaned-record— an install record whose source is no longer registered (left behind byequipr removewithout--purge)vanished-config-dir— the target agent's config dir no longer existsbroken-symlink— a symlinked component points at a path that is gonemodified-cache— a source's cached tree no longer matches the digest recorded when it was added
Scripting: --json
Every command accepts --json for machine-readable output — list, show,
status, doctor, update (report), and add/install/uninstall/remove
(confirmation). Progress messages go to stderr, so stdout is pure JSON:
equipr list --json
equipr show marketingskills/marketing-skills --json
equipr status --json
equipr update --json
# add/install/uninstall/remove also accept --json
equipr add https://example.com/releases/plugin-1.0.0.zip --json
--yes / -y skips every interactive prompt: it installs into all detected
agents, installs all components, and resolves conflict prompts as overwrite
(an explicit --on-conflict still wins).
Exit codes
These are equipr's documented, stable choices — safe to branch on in scripts:
| Code | Meaning |
|---|---|
0 | success (including doctor with no issues) |
1 | generic or usage error |
2 | source / plugin / component not found (or nothing to uninstall) |
3 | conflict (--on-conflict=fail, or a declined overwrite that stopped the run) |
4 | environment / usage (HOME unset, no agents detected) |
5 | doctor found issues |
Layout
State, config, and cache follow the XDG Base Directory layout:
$XDG_STATE_HOME/equipr/—sources.json,installs.json,equipr.lock$XDG_CONFIG_HOME/equipr/— reserved forconfig.toml(created, not yet used)$XDG_CACHE_HOME/equipr/— fetched source clones
installs.json records carry a content hash so update can detect local
modifications before overwriting anything. The check is mechanism-aware: for
copied targets equipr compares content hashes, and for symlinked targets it
treats "the user replaced the symlink with a real file or directory" as the
local modification.
Shell completions
cobra generates completion scripts for bash, zsh, fish, and PowerShell:
# bash
source <(equipr completion bash)
# zsh
source <(equipr completion zsh)
# fish
equipr completion fish | source
Persist it by appending the output to your shell's rc file, or install to the
standard location (zsh): equipr completion zsh > ${fpath[1]}/_equipr.
Known limitations
- MCP manifests are read from
mcp.jsononly. A Claude Code plugin that declares its servers in.mcp.jsonor inline inplugin.jsonwill show no MCP components. - Marketplace plugin sources are resolved only when they point inside the
fetched tree — a relative path (
"source": "./path") or agit-subdir-style object carrying one. Entries pointing at a separategithub/npm/archivesource are skipped and reported; the rest of the marketplace still installs. - No ref pinning. Git sources are shallow-cloned from the default branch; there is no way to pin a tag, branch, or commit.
- Skills are installed globally only (each agent's personal skills dir). Project-scoped installs are not supported.
- Subagents are not a component type. A plugin whose content is an
agents/directory (Claude Code subagents) resolves with no installable components; equipr handles skills, commands, and MCP servers.
Releases
Releases are cut manually and locally from a Mac with GoReleaser — there is
no release CI workflow. A release publishes cross-platform binaries, a Homebrew
cask, .deb/.rpm packages, and install.sh; macOS binaries are ad-hoc
codesigned so they run on Apple Silicon.
See CLAUDE.md → Release procedure for the full steps. The goreleaser
setup mirrors maquina-app/recuerd0-cli.
Examples
Ready-to-use manifests live in examples/: a single-plugin Agent
Plugins package (ap-plugin/) and a Claude Code marketplace (marketplace/).
Use them to try equipr add against a local path without a network fetch.
License
MIT — see LICENSE.