Install Eniyan on your computer
Eniyan’s tools for your computer come in one Python package, eniyan, on PyPI. Pick your system and what you want to set up, and this page shows the exact commands for it. The address bar keeps your choices, so you can share the link.
On PACH 1, that is local discovery (eniyan-scan), which shows what your AI tools have set up, and the gates your agents work through: files, websites, email and your card. You need an account and, for the gates, an enrolled agent. Start with the quickstart if you have neither.
Your computer
Pick your computer and what you want to set up. The steps below follow.
Install steps for macOS
Commands are for your terminal (bash or zsh).
1 · Get Python 3.10 or newer
Eniyan needs Python 3.10 or newer. Check what you have:
python3 --versionIf it prints Python 3.9.6, that is the copy that comes with Apple’s Command Line Tools, and it is too old. pip will not say so. It fails like this instead:
ERROR: Could not find a version that satisfies the requirement eniyan[scan] (from versions: none)
ERROR: No matching distribution found for eniyan[scan]Install a current Python from python.org or with Homebrew:
brew install python2 · Install Eniyan with pipx
You will install eniyan[scan,mcp]>=0.9. The part in brackets adds what your choices need:
scan: for eniyan-scan: a keyring for the device token, and readers for AI tools that keep their settings in YAML or TOMLmcp: for eniyan-mcp, eniyan-fs and eniyan-web
Keep the double quotes around it. They stop your shell from reading the brackets (zsh, the macOS default, refuses them) and from reading >= as a redirect.
Install pipx
With Homebrew:
brew install pipxInstall Eniyan
pipx install "eniyan[scan,mcp]>=0.9"Put the commands on your PATH
pipx ensurepathThis adds ~/.local/bin to your PATH. Open a new terminal so it takes effect.
If pip says “externally-managed-environment”
error: externally-managed-environment
× This environment is externally managedYour system’s Python is protecting itself (Homebrew’s Python does this). Use pipx or a virtual environment, the methods on this page. Do not pass --break-system-packages.
Don’t set up eniyan-scan with pipx run or uvx
They run from a cache that is cleared, so the background jobs would stop starting. --install refuses them before it asks for anything: it says the program runs from a cache that is pruned, and ends with Nothing was installed.
Install it to stay, with one of the methods above.
3 · Turn on local discovery (eniyan-scan)
eniyan-scan reads the settings of the AI tools on your computer and reports which agents and MCP servers are set up and what they can reach, so they appear on your Agent Fleet page. It sends names, hostnames and hashed references, never file contents, full paths, settings values, tokens or your username. It only reports: it does not stop, block or change anything.
Get a device token
- In the dashboard, open Settings, then Agent Directory, and find the Local discovery on your computer card.
- Name this computer and click Add this computer.
- Copy the token. It starts with
esd_and is shown once: Eniyan keeps only a fingerprint of it. If you lose it, revoke the computer and add it again.
Only an organization admin can add or revoke a computer. An account can have up to 5.
Run the installer
eniyan-scan --installPaste the token when it asks (the input is hidden). It checks the token with Eniyan before it stores anything, sets up the background jobs, and sends a first report before it finishes.
What it sets up on macOS
- Two LaunchAgents in
~/Library/LaunchAgents:com.eniyantrust.endpoint.watchruns when an AI tool’s settings change, at most once every 5 minutes, andcom.eniyantrust.endpoint.dailyruns daily at 12:30 (on the next wake if your Mac was asleep). - The device token goes in your Keychain (service
eniyan-scan). It is not in any file. - Its state and log (
launchd.log) are in~/.eniyan/scan.
- The daily run skips when your battery is below 20% and not charging. Settings-change runs never skip for the battery.
- An AI tool you install later is picked up by the next daily run.
- If you move your AI tools’ settings with variables such as
CLAUDE_CONFIG_DIR,CODEX_HOMEorXDG_CONFIG_HOME, run--installfrom a terminal where they are set. It records them for the background jobs. After you change one, run--installagain. It asks for a device token again. The dashboard shows each token only once, so use the one you kept, or revoke this computer on the Local discovery card and click Add this computer for a new one. --label "Work laptop"gives the computer a local name that--statusshows.
Installing from a script?
--token-stdin reads the token from standard input instead of the hidden prompt. Never put the token on the command line: it would stay in your shell history.
eniyan-scan --install --token-stdin < token.txtDelete the token file afterwards.
4 · Check it worked
See what is installed, where the token is, the background jobs and the last run:
eniyan-scan --statusSee exactly what a run sends. It prints the report as JSON and sends nothing, and it never prints the token:
eniyan-scan --dry-runOn the dashboard, the computer’s entry on the Local discovery card shows when its last report arrived. What it found appears on the Agent Fleet page.
Projects in Documents, Desktop, Downloads or iCloud Drive
macOS privacy protection treats the background jobs as their own app, so Terminal’s access does not carry over. Without Full Disk Access they skip projects in Documents, Desktop, Downloads, iCloud Drive and other volumes. --status counts the projects it could not read. Grant access in System Settings, Privacy & Security, Full Disk Access, then check --status after the next run.
A --dry-run typed in Terminal reads with Terminal’s access, so it can show more than the background jobs send.
A dashboard entry shows a short hex reference. eniyan-scan --where 3f9a2c1e tells you which folder or job on this computer it means. It sends nothing.
5 · Connect your AI tools
Enroll an agent in the dashboard, then open its Connect screen. It has a ready config for Claude Code, a .mcp.json file, Cursor, the Python SDK, eniyan-fs and eniyan-web. Paste the one for your AI tool.
Each gate needs two secrets from the dashboard:
ENIYAN_API_KEY: your organization’s API key, from API keys.ENIYAN_CREDENTIAL_TOKEN: the agent’s credential, shown once on the Connect screen. Get a fresh token issues a new one and revokes the old one.
Keep these secrets out of shared files
Put them in your own user-level config. Never commit a .mcp.json that holds them to a repository, or paste them into a file other people can read.
Desktop apps started from the Dock may not see ~/.local/bin. If your AI tool says it cannot find a command, put its full path in the config’s command. Find it with:
which eniyan-mcpWrite the path out in full, like /Users/you/.local/bin/eniyan-mcp: configs do not expand ~.
Your files (eniyan-fs)
ENIYAN_FS_ROOTS lists the folders your agent may reach, as alias=path pairs separated by colons, for example projects=/Users/you/code:notes=/Users/you/notes. Each path must be a folder that exists. Anything outside is refused on your computer. See Governed local files.
Websites (eniyan-web)
The sites your agent may visit are set on the agent’s dashboard page, never in the config. eniyan-web has two engines: a plain HTTP fetch (the PACH 1 default) and a real browser (the EACH 1 default). PACH 1 accounts can switch an agent to the real browser on its dashboard page.
Upgrade later
pipx upgrade eniyanAn upgrade keeps the extras you installed with. To add one later, install again with the new list:
pipx install --force "eniyan[scan,mcp]>=0.9"- You do not need to run
eniyan-scan --installagain after upgrading in place: the background jobs point at the program, not a version. Run it again if you recreated the environment somewhere else, switched to another Python, or--statussaysits program is missing. It asks for a device token again. The dashboard shows each token only once, so use the one you kept, or revoke this computer on the Local discovery card and click Add this computer for a new one. - Restart your AI tool so it starts the new version of each gate.
Uninstall
First, while eniyan is still installed, remove what it stored on this computer:
eniyan-scan --uninstall--uninstall removes the background jobs, the stored device token and ~/.eniyan/scan. It waits up to 30 seconds for a running scan. Anything it cannot remove, it names; run it again to finish.
Remove eniyan-scan before the package
Remove the package first and the jobs keep pointing at a program that is gone, with the token still stored. If that happened, install the package again, run --uninstall, then remove it.
Then remove the package:
pipx uninstall eniyan- Revoke the computer on the Local discovery card, so its token stops working.
- Remove the Eniyan entries from your AI tools’ MCP settings.
Troubleshooting on macOS
- “command not found” (or “not recognized”)
- The folder the commands are in,
~/.local/bin, is not on your PATH. Runpipx ensurepathand open a new terminal. - “from versions: none” or “No matching distribution found for eniyan”
- Your Python is older than 3.10, so pip sees no release it can install. Go back to step 1. On a Mac, this is usually Apple’s Python 3.9.6.
- “error: externally-managed-environment”
- Your system Python refuses installs from pip. Use pipx or a virtual environment. Do not pass
--break-system-packages. - “eniyan-fs needs the mcp extra” (or eniyan-mcp, eniyan-web)
- The package was installed without the extras. Install it again with them:bash
pipx install --force "eniyan[scan,mcp]>=0.9" - “That does not look like a scan device token”
- A device token starts with
esd_. The agent’s credential token and your API key are different things. Create a device token with Add this computer. - “Eniyan does not accept that token”
- It was revoked. Add the computer again on the dashboard for a new token.
- “Could not validate the token with Eniyan … Nothing was installed.”
- Eniyan could not be reached. Check your connection and run it again.
- “… LaunchAgents is not writable by you”
- An installer run with sudo can leave that folder owned by root. Take it back:bash
sudo chown "$USER" "$HOME/Library/LaunchAgents" - “Projects it could not read (left out of the report)”
- macOS privacy protection is keeping the background jobs out of Documents, Desktop, Downloads, iCloud Drive or another volume. Grant Full Disk Access (step 4).
- No reports for days
eniyan-scan --statusshows the jobs and the last run. The jobs log to~/.eniyan/scan/launchd.log.- “the credential store … is locked or did not answer”
- A background run could not read the token, so it sent nothing. The next run tries again.
All systems at a glance
The recommended install for each system, and what eniyan-scan sets up there. Pick a system above for the full steps.
| System | Recommended install | eniyan-scan’s background jobs | Device token kept in |
|---|---|---|---|
| macOS | brew install pipx, then pipx install "eniyan[scan,mcp]>=0.9" | Two LaunchAgents: on a settings change (at most every 5 minutes) and daily at 12:30 | Keychain |
| Windows | py -m pip install --upgrade "eniyan[scan,mcp]>=0.9" (or pipx, uv tool, a virtual environment) | Two Task Scheduler tasks: a check every 15 minutes and daily at 12:30, while you are logged on | Credential Manager (this PC only) |
| Linux desktop | pipx (apt or dnf), then pipx install "eniyan[scan,mcp]>=0.9"; or a virtual environment | systemd user units: on a settings change and daily, while you are logged in | Keyring (the Secret Service or KWallet) |
| Linux server or container | pipx install "eniyan[scan,mcp]>=0.9", or a virtual environment | systemd user units if your user manager runs; otherwise one hourly cron line | A private file, with --token-file |
| WSL | pipx install "eniyan[scan,mcp]>=0.9", or a virtual environment | systemd user units with systemd on; otherwise cron (the cron daemon must run) | A private file, with --token-file |
The package shown carries this page’s default choices (local discovery and the gates). The steps above add what the others need. Every system needs Python 3.10 or newer. Keep the double quotes around the package in every shell. eniyan-scan only reports what it finds: it never stops, blocks or changes anything.