Easy Agent: a terminal coding agent whose security story is five independent layers
Production-ready open source terminal coding agent with readable, layered code: permission rules, OS sandboxing, MCP, skills, sub-agents, and Anthropic, OpenAI-compatible, Gemini, or local models.
At a glance
- What is it?
- The repository calls it production ready, the manifest says 0.1.1 with no published releases, and the Windows row of the support table promises support while withholding the sandbox that the security model depends on.
- Who is it for?
- Easy Agent is worth reading even if you never install it, because the security model is written down as separate layers that each fail on their own rather than as a single warning. The three things to check before trusting it on a real machine are concrete.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 9, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Production ready in the description, 0.1.1 in the manifest
Easy Agent sits at 1,009 stars and 138 forks with 18 open issues, MIT licensed, TypeScript, pushed 2026-10-05 on the main branch. The repository description reads production ready open source terminal coding agent with readable, layered code: permission rules, OS sandboxing, MCP, skills, sub-agents, and Anthropic, OpenAI-compatible, Gemini, or local models.
Two pieces of the repository's own state pull against that word. The manifest version is `0.1.1`, and the releases list is empty, so there is no tagged release on GitHub at all even though a `CHANGELOG.md` and a `.github` directory both exist in the tree. A pre-1.0 version number on a project with a thousand stars is not unusual in itself, since plenty of tools reach adoption while staying pre-1.0, but the pairing with the word production ready in the description is the thing a reader has to reconcile.
Publishing is guarded anyway. `prepublishOnly` runs a `verify:release` script, and `prepack` runs typecheck and build, so whatever reaches npm has been through both. That tells you the quality gates exist on the publishing path; it does not tell you how many people have run the artifact, and with no release to install from, the npm version is the only version marker a new user can compare against. The 18 open issues against 138 forks is a healthier ratio than a bare star count would suggest, since forks in this category usually mean people reading the source rather than only running the binary, which is also what the project's own framing asks for.
The package is eagent, and the installer refuses to run lifecycle scripts
The npm name is `eagent`, not `easy-agent`, and the package installs two commands that point at the same file: the short `eagent` and the long alias `easy-agent`. The README's install block is deliberately unusual:
npm install -g --ignore-scripts eagent
eagent --version`--ignore-scripts` on a global install of an agent that can run shell commands is a defensible choice, and the project repeats the idea outside npm. A separate installer is available on macOS and Linux, which checks Node.js, installs the same npm package with `--ignore-scripts`, and verifies that `eagent` is on `PATH`. It explicitly does not install Node.js and does not run package lifecycle scripts. Trying without installing at all goes through:
npx --yes eagent@latestThe quick start sets one environment variable and drops you into a directory, and the variable name is worth noting because it is not the one most people expect:
cd your-project
eagent`ANTHROPIC_AUTH_TOKEN` rather than `ANTHROPIC_API_KEY` is what the README shows, which matters if you are wiring this into an environment where the other variable is already set. On first use in a folder the agent asks whether you trust it, then you type a request, `/help` lists commands, and Ctrl+D exits. Node.js 22 or newer is required on every platform and older versions exit with an explanatory message. One small inconsistency in the packaging: the repository record carries no homepage, while the manifest sets its homepage to the project README on GitHub.
Deny rules win, and a sandbox that cannot start blocks the command
The security model opens by assuming the model makes mistakes and that a repository you open may be hostile, which is a more useful starting position than assuming a trusted checkout. Six layers follow.
Permission rules come first. Tool calls that change files, run commands or reach the network are checked against allow, ask and deny rules, and deny always wins. In the default mode anything not allowed is asked, with the exception that Bash commands proven read-only can run without a prompt through the analysis rules. Permission modes sit on top: `default` asks before risky actions, `plan` reached with `--plan` allows only read-only tools, and `auto` reached with `--auto` lets a classifier approve safe calls, block risky ones and fall back to a prompt when unsure.
Headless runs are the sharpest edge. A `-p` run denies any call that would have prompted, unless you pass `--dangerously-skip-permissions`, and deny rules still apply on top of that. So the same binary behaves more conservatively in a script than in a terminal, which is the right default, and the escape hatch does not remove the deny list.
Workspace trust is the layer that stops a checkout from arming itself. Project settings, `.env`, project MCP servers, hooks, plugins and model profiles are all ignored until you trust the folder, and trust is stored in your home directory so a repository cannot mark itself trusted or replace credentials inherited from your shell. Path boundaries resolve real paths and refuse to follow symlinks out of the workspace. The shell sandbox runs Bash inside an OS sandbox with an allow-only write policy and proxy-filtered network when `sandbox.enabled` is set, and if the sandbox cannot start the command is blocked rather than run unsandboxed. Local sessions, settings, trust state and logs are private to your account, stream debug logging is off by default, and it redacts credentials when on. No analytics or telemetry are sent anywhere.
Windows is supported, and that is a different claim from sandboxed
The support table has three rows and one of them needs reading twice.
macOS is supported with Bash and Seatbelt, and the sandbox needs `rg`. Linux and WSL2 are supported with Bash and bubblewrap, needing `bubblewrap`, `socat`, `rg` and unprivileged user namespaces. Windows is supported without sandbox, its shell tool is PowerShell, and the sandbox column reads Not available; an enabled fail-closed sandbox blocks PowerShell.
That last clause is the design talking. Since an unstartable sandbox blocks the command rather than falling back to running it unsandboxed, turning `sandbox.enabled` on Windows does not degrade to no sandbox, it removes your shell. So on Windows the security model you read is missing its outermost layer by necessity, and what remains is permission rules, workspace trust and path boundaries. The README also flags the Ubuntu AppArmor restriction on user namespaces in its sandbox security document, which is the same problem in a different distribution: a kernel policy, not a missing package, can stop the sandbox from starting.
Two other platform notes are worth having before you promise someone this works on their machine. On Windows, local data relies on the user profile's ACLs instead of POSIX `0600` and `0700` modes, and `/doctor` reports which mode is in effect. Clipboard image paste needs `pngpaste` or `osascript` on macOS and `xclip` or `xsel` on Linux, so image input on a bare Linux box fails until you install one. `/doctor` probes the configured providers as well, which makes it the first command to run on any new machine.
The tarball ships dist, so the documentation links only resolve on GitHub
The manifest's `files` array lists `dist`, `README.md`, `README.zh-CN.md` and `LICENSE`. That is the complete published artifact, and it is worth knowing before you install, because the README is dense with relative links into `docs`.
The README points at `docs/mcp.md` for MCP tools and resources, `docs/hooks.md` for hooks, `docs/subprocesses.md` for controlled subprocesses, `docs/sandbox-security.md` for the shell sandbox and its per-platform setup, `docs/agent-teams.md`, `docs/headless-output.md`, `docs/sdk.md`, `docs/rpc.md`, `docs/acp.md`, `docs/persistence.md`, `docs/local-data-security.md`, `docs/bash-read-only-security.md`, `docs/configuration-security.md` and `docs/workspace-path-security.md`. Every one of those paths resolves when you read the README on GitHub. None of them exists inside an installed `eagent`.
The exports map reinforces the boundary rather than working around it. Only `./sdk` and `./package.json` are exported, with types and import entries for the SDK, so there is no documented route into the packaged internals. The consequence for a reader is practical: the security documentation you would want before enabling the sandbox lives in the repository, not in your node_modules. Fetch it from GitHub, and treat the `learning-path.md` walkthrough the same way, since it is the document that explains the layering the description claims.
This is also the piece that makes the two descriptions consistent rather than contradictory. A package that ships only its build output is a package meant to be run, and the readable layered code is the promise the repository makes to contributors, not to npm consumers.
Headless, RPC and ACP are three doors into the same session
Beyond the interactive terminal UI, Easy Agent documents five ways in, and the interesting one is that each has a matching script in the manifest.
Headless runs pipe input into `eagent -p` and return text, JSON or NDJSON, which is the mode CI uses. An embeddable session SDK is exported as `eagent/sdk` with type declarations, so another program can drive a session in process. JSON-RPC over stdio comes from `eagent --rpc`, aimed at desktop apps, and the repository's only listed example file is `examples/rpc-client.mjs`, which suggests the intended first integration is a client talking to a running agent over pipes. The Agent Client Protocol arrives with `eagent --acp` for Zed, JetBrains IDEs and other ACP editors.
The manifest treats the last two as generated artifacts rather than hand-maintained text. There is an `rpc:schema` script that generates the RPC schema and an `acp:registry-entry` script that produces the ACP registry entry, so the protocol surfaces are derived from the implementation and should stay in step with it. Images and screenshots are supported as input alongside multiple model protocols.
The continuity features underneath are the ones that decide whether a long session is pleasant. Durable persistence, resume, compaction and token budgets sit next to project memory in `AGENTS.md` or `AGENT.md`, file checkpoints and `/rewind` for undoing a bad set of edits. TodoWrite and persistent task graphs give long work a shape, sub-agents and background runs split it, and Git worktree isolation keeps editing children from colliding in your working directory. Plan Mode exists as a read-only pass you can take before committing to changes.
Layered on purpose, with a frontend in the same tree
The layering claim is specific enough to check. The README says model communication, the agentic loop, tools, permissions, context management and each extension system live in separate layers, and that `docs/learning-path.md` walks through those layers in order with code snapshots. Two things in the tree support that being a real constraint rather than a slogan. There are `check:source-hygiene` and `check:frontend-boundaries` scripts, so layer violations and frontend boundaries are things the repository can fail on, and `tsconfig.json` plus `tsup.config.ts` keep the build and the type checker pointed at the same source.
Then there is the part that does not fit the picture. The tree contains `apps/`, `public/`, `assets/` and a `step/` directory, and a script whose job is enforcing frontend boundaries. A terminal coding agent needs no web assets, so the repository also holds something the README never describes. That is not necessarily a problem, since a marketing site or an in-repo UI would explain all four directories, but it is a gap: the front door of the project is a terminal binary while the source tree is larger than the documentation accounts for.
One more detail rewards a reader who intends to contribute. A `.git-blame-ignore-revs` file is present, which is the standard way to tell Git to skip commits when you rewrite history, usually for formatting or lint sweeps. It means `git blame` will not show original authorship across those commits, so if you are trying to work out who changed a security-sensitive line, check that file before trusting the blame output.
Tooling is otherwise conventional and modern: Biome with `biome lint --error-on-warnings` for lint, `tsc --noEmit` for types, tsup for the bundle, and a `test` script that points at `scripts/verify-production.ts` rather than a unit test runner, which is another way the project's emphasis on being readable rather than exhaustively unit-tested shows up in the manifest.
Editorial conclusion
Easy Agent is worth reading even if you never install it, because the security model is written down as separate layers that each fail on their own rather than as a single warning. The three things to check before trusting it on a real machine are concrete. Version 0.1.1 with no published release sits underneath a description that says production ready, so treat the description as intent and the version as the state. On Windows the sandbox does not exist and enabling it blocks PowerShell entirely, which makes that row of the support table a decision rather than a feature. And the npm tarball ships only `dist`, so every documentation path in the README resolves on GitHub and nowhere else. Install with the `--ignore-scripts` form the README documents, keep `default` permission mode on, run `/doctor` to see which providers answer and which local binaries are present, and read `docs/sandbox-security.md` from the repository before you enable `sandbox.enabled`.
Frequently asked questions
Is Easy Agent production ready?
The repository description uses that phrase, and the manifest does gate publishing with a verify:release script. The version is 0.1.1 and no GitHub release has been published, so read the description as the project's intent and the version number as its current state. Installing from npm gives you 0.1.1 and nothing else to compare it against.
Does Easy Agent's sandbox work on Windows?
No. The support table lists Windows as supported without sandbox, and because the sandbox is fail closed, enabling it blocks PowerShell entirely rather than running commands unsandboxed. What still protects you on Windows is the permission rules, workspace trust and path boundaries. macOS uses Seatbelt and Linux uses bubblewrap, and both need extra binaries installed.
How do I run Easy Agent in a script or CI job?
Pipe input into eagent -p and read text, JSON or NDJSON from stdout. A headless run denies any call that would normally prompt, so you get failures instead of hangs, and passing --dangerously-skip-permissions lifts that for calls the deny rules do not cover. The README also documents eagent --rpc for JSON-RPC over stdio.
Where are the Easy Agent security documents after I install the package?
Not in the package. The manifest's files array ships only dist, the two READMEs and the LICENSE, so the docs links in the README, including docs/sandbox-security.md and docs/learning-path.md, resolve on GitHub and nowhere else. The only exported paths are the SDK and the package manifest.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/conardli-easy-agent)