trackmcp
Back to directory

One command, every package manager. Installs from pip, npm, and verified binary releases on macOS, Linux, and Windows.

2 stars HTMLOthers Updated Aug 31, 2026

Documentation

poly

**English** Β· FranΓ§ais

One command, every package manager. `poly` installs from pip, npm,

Homebrew, and checksum-verified binary releases behind a single unified

command, on macOS, Linux, and Windows.

Site + account management: **poly.candygate.eu**

code
$ poly install ripgrep
downloading ripgrep  [############################] 100%  1.7MiB/1.7MiB
installed ripgrep 15.1.0 (via tap)
note: tap binaries are installed to ~/.poly/bin β€” make sure it's on your PATH

$ poly install requests@2.31.0
installed requests 2.31.0 (via pip)

$ poly install npm:cowsay
installed cowsay 1.6.0 (via npm)

$ poly install brew:jq
installed jq 1.8.2 (via brew)

$ poly list
NAME      VERSION  ADAPTER  INSTALLED
cowsay    1.6.0    npm      2026-07-11 15:52
jq        1.8.2    brew     2026-07-11 17:30
requests  2.31.0   pip      2026-07-11 15:52
ripgrep   15.1.0   tap      2026-07-11 15:52

Install

macOS β€” download `poly-macos.pkg`,

open it, click through the installer. Installs a universal

(Intel + Apple Silicon) binary to `/usr/local/bin/poly`. It's

unsigned/unnotarized (no Apple Developer account yet), so Gatekeeper

will warn on first open β€” right-click β†’ Open, or

`System Settings β†’ Privacy & Security β†’ Open Anyway`.

Windows β€” download `poly-setup.exe`,

run it. Installs to `%LOCALAPPDATA%\Poly` and adds it to your user

`PATH` (no admin rights needed). It's unsigned, so SmartScreen will

warn β€” "More info" β†’ "Run anyway". *(Built cross-platform via NSIS;

not yet verified on a real Windows machine β€” please report issues.)*

From source (any OS, needs Go 1.21+):

code
git clone https://github.com/opencorp2030-ctrl/poly.git
cd poly
go build -o poly .
./poly version           # sanity check: runs the binary in place

# put it on PATH, e.g.:
cp poly /opt/homebrew/bin/poly   # macOS (Homebrew's bin, no sudo needed)
# or: sudo cp poly /usr/local/bin/poly       # macOS/Linux, needs sudo
# or: add this folder to PATH yourself

poly version              # now works from anywhere

Rebuild the installers yourself with `VERSION=x.y.z installers/build.sh`

(needs `makensis` for the Windows one: `brew install makensis`).

Cross-compile for another OS/arch with `GOOS`/`GOARCH`, or run

`scripts/build-all.sh` to build all five targets (darwin/linux/windows Γ—

amd64/arm64) into `dist/`.

πŸ–₯️ Poly Desktop β€” now available for Windows

**Poly Desktop**

is a native desktop app for managing your Poly account without a

browser: publish and edit apps with a live store-listing preview,

search/install/remove packages through the real CLI, browse the

community and the public apps store, real notifications with native

OS alerts, and a full theme/accent color picker.

**⬇ Download Poly Desktop for Windows**

β€” run the installer, no admin rights needed. Signs in with the same

account as `poly login` on the CLI.

> macOS and Linux builds are coming very soon. Windows ships first

> because that's what's been tested end-to-end; the app itself is

> plain Electron/Node, so the other platforms are mostly a packaging

> step away. Star/watch the repo to know when they land.

How package resolution works

`poly install ` tries each adapter's `Search` in order β€” **tap β†’

brew β†’ pip β†’ npm β†’ cargo β†’ go** β€” and installs through the first one

that reports the package exists. Force a specific backend with a prefix:

CommandResolves to
`poly install ripgrep`first match: tap β†’ brew β†’ pip β†’ npm β†’ cargo β†’ go
`poly install tap:ripgrep`forced binary download from the tap formula
`poly install brew:wget`forced `brew install wget`
`poly install pip:requests`forced `pip install requests`
`poly install npm:lodash`forced `npm install -g lodash`
`poly install cargo:ripgrep`forced `cargo install ripgrep`
`poly install go:golang.org/x/tools/cmd/goimports`forced `go install @latest`
`poly install gem:rails`forced `gem install rails`
`poly install apt:ripgrep`forced `apt-get install ripgrep` (Debian/Ubuntu)
`poly install dnf:ripgrep`forced `dnf install ripgrep` (Fedora/RHEL)
`poly install pacman:ripgrep`forced `pacman -S ripgrep` (Arch)
`poly install winget:BurntSushi.ripgrep`forced `winget install --exact` (Windows)
`poly install choco:ripgrep`forced `choco install ripgrep` (Windows)

`gem`, `apt`, `dnf`, `pacman`, `winget`, and `choco` are explicit-prefix

only, like `community` and `gh` below β€” never auto-resolved, so a

system package or a single-language gem can't silently shadow the

tap/brew/pip/npm/cargo/go chain.

Append `@version` to pin: `poly install requests@2.31.0`. pip, npm, and

cargo pass that straight through; the tap adapter only offers the

version pinned in its formula and errors if you ask for a different

one; `go` treats it as the module's version/tag.

Commands

CommandDoes
`poly install [[adapter:]name[@version] ...]`install packages, auto-routed or forced; no args installs from `poly.json`
`poly remove name`uninstall, via whichever adapter installed it
`poly list`show everything poly has installed, and through what
`poly search [adapter:]name`check existence and latest version across adapters
`poly info [adapter:]name`version, summary, homepage, and install status, per adapter
`poly init`write `poly.json` from your currently installed packages
`poly upgrade`update every installed package to its adapter's latest version
`poly self-update`update the poly binary itself to the latest GitHub release
`poly account`show your signed-in email/username/bio/plan
`poly login` / `poly logout`sign in/out of your Poly account (unlocks Pro)
`poly version`print the poly build version and, if signed in, your account/plan

State lives in `~/.poly/manifest.json`. Tap binaries land in `~/.poly/bin`

(add it to your `PATH`). Login credentials live in `~/.poly/credentials.json`

(mode 0600). `poly self-update` and, for Pro accounts, `poly upgrade` also

run automatically in the background (throttled to ~once/day, logged to

`~/.poly/auto-update.log`) so you don't have to remember to run them.

Reproducible installs with poly.json

`poly init` writes a `poly.json` in the current directory listing every

package poly has installed, pinned to its exact version:

json
{
  "packages": [
    "tap:ripgrep@15.1.0",
    "npm:eslint@9.2.0",
    "pip:requests@2.31.0"
  ]
}

Commit it, and anyone (or any CI machine) can reproduce the same set with

a plain `poly install` β€” no arguments needed.

Poly Pro

Poly is and stays 100% free and open source β€” the whole built-in tap

catalog (`ripgrep`, `fd`, `jq`, ...) is free too, on purpose: Pro isn't

about withholding tools people expect for free. The one real, measurable

perk today:

  • `poly install a b c` (multiple packages in one command) installs them

sequentially on the free tier; signed in with an active Pro plan

(`poly login`), the same command installs them concurrently, and

`poly upgrade` runs automatically in the background instead of only

on demand.

Manage your account (sign up, check your plan) at

poly.candygate.eu/account.html,

backed by Supabase Auth β€” see `internal/account/account.go` for the

client-side logic and the `public.profiles` table for where plan status

lives.

Adapters

  • pip β€” shells out to `pip3`/`pip`, streaming its output live so you

see pip's own download progress. Search hits the PyPI JSON API

(`pypi.org/pypi//json`), an exact-name lookup β€” PyPI has no

public free-text search API anymore.

  • npm β€” shells out to `npm install -g`, same live-streamed output.

Search hits `registry.npmjs.org//latest`.

  • brew β€” shells out to a local `brew install`/`brew uninstall`, same

live-streamed output. Search hits the public

`formulae.brew.sh/api/formula/.json`, so it works even without

brew installed (only actually installing needs it).

  • cargo β€” shells out to `cargo install --force`/`cargo uninstall`.

Search hits the public `crates.io/api/v1/crates/` API.

  • go β€” shells out to `go install @version`. Packages here are

full module import paths, not short names (e.g.

`golang.org/x/tools/cmd/goimports`), so this one is realistically only

used via an explicit `go:` prefix. Search walks the path upward against

the public Go module proxy until it finds the enclosing module, the

same resolution `go install` does internally.

  • tap β€” installs prebuilt binaries directly from a pinned URL, with a

live byte-progress bar during download, verified against a SHA-256

checksum, then extracted (`.tar.gz`/`.zip`) or copied into

`~/.poly/bin`. No Python, Node, Rust, or Homebrew needed.

  • gem β€” shells out to a local `gem install`/`gem uninstall`. Search

hits the public `rubygems.org/api/v1/gems/.json` API. Explicit

`gem:` prefix only, like `cargo`/`go`.

  • apt β€” shells out to a local `apt-get install`/`apt-get remove` on

Debian/Ubuntu. Search reads local `apt-cache show` output, no network

call needed. Explicit `apt:` prefix only β€” auto-resolving a bare name

to a system package would be a surprise on Linux.

  • dnf β€” same idea on Fedora/RHEL, via `dnf install`/`dnf remove` and

`dnf info`. Explicit `dnf:` prefix only.

  • pacman β€” same idea on Arch, via `pacman -S`/`pacman -R` and

`pacman -Si` against the synced repos (not the AUR). Explicit

`pacman:` prefix only; pacman has no built-in way to pin an arbitrary

version from the regular repos, so version pins are rejected.

  • winget β€” shells out to a local `winget install --exact`/`winget

uninstall` on Windows. Search reads local `winget show --exact`

output. Explicit `winget:` prefix only.

  • choco β€” shells out to a local `choco install`/`choco uninstall`

(Chocolatey) on Windows. Search reads local `choco search --exact

--limit-output` output. Explicit `choco:` prefix only.

Adding a tap formula

Drop a YAML file into `~/.poly/taps/.yaml` (this overrides any

built-in formula of the same name β€” see `internal/registry/embedded/taps`

for the ones that ship with poly):

yaml
name: ripgrep
description: "Line-oriented search tool that recursively searches directories for a regex pattern"
homepage: "https://github.com/BurntSushi/ripgrep"
version: "15.1.0"
binary: rg
tier: free   # omit for free, or "pro" to gate it behind an active Pro plan
artifacts:
  darwin_arm64:
    url: "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-aarch64-apple-darwin.tar.gz"
    sha256: "378e973289176ca0c6054054ee7f631a065874a352bf43f0fa60ef079b6ba715"
  darwin_amd64: { url: "...", sha256: "..." }
  linux_amd64: { url: "...", sha256: "..." }
  linux_arm64: { url: "...", sha256: "..." }
  windows_amd64: { url: "...", sha256: "..." }

The artifact key is `_`. `poly install ` picks the

entry matching the machine it's running on. Built-in formulas today, all

free: `ripgrep`, `fd`, `jq` β€” see `internal/registry/embedded/taps`.

Project layout

code
main.go                          entrypoint
cmd/                              cobra commands (install, upgrade, init, info, account, self-update, ...)
internal/manifest/                ~/.poly/manifest.json read/write
internal/lockfile/                poly.json read/write
internal/adapters/                Adapter interface + pip, npm, brew, cargo, go, tap, gem, apt, dnf, pacman, winget, choco implementations
internal/registry/embedded/       tap formulas built into the binary
internal/account/                 Supabase Auth client (login/plan/profile)
internal/selfupdate/              downloads + verifies + replaces the poly binary
installers/                       macOS .pkg and Windows .exe installer sources
site/                             marketing site, docs, account, community pages
scripts/build-all.sh              cross-platform release build

Status

Working: install/remove/list/search/info/upgrade/init across pip, npm,

brew, cargo, go, tap, gem, apt, dnf, pacman, winget, and choco; version

pinning (where the backend supports it); automatic self-update and (Pro)

automatic package upgrades; macOS/Windows installers; a Supabase-backed

account system with a community directory. Not yet built: signed/

notarized installers and a package search UI covering every adapter's

full catalog (vs. exact-name lookups).

Frequently asked questions

What is poly?

poly is One command, every package manager. Installs from pip, npm, and verified binary releases on macOS, Linux, and Windows.

How do I install poly?

Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.

Is poly open source?

Yes β€” it is hosted on GitHub at https://github.com/opencorp2030-ctrl/poly and has 2 stars.

Related MCP tools

Run your own MCP server? See who uses it and what to fix.

Measure it with TrackMCP