ente-cli (0.4.43)
Installation
registry=https://gitea.i.ivo-zilkenat.de/api/packages/ivo.zilkenat/npm/npm install ente-cli@0.4.43"ente-cli": "0.4.43"About this package
ente CLI
Command-line interface for ente — a relationship manager and knowledge graph (people, orgs, projects, topics and the notes/calls/tasks/conversations logged against them).
TypeScript, built on clipanion, bundled with esbuild
into a single self-contained file, published to the Gitea npm registry. It talks
to ente's external REST API (/api/external/*) with a static Bearer API key.
Install
npm i -g ente-cli --registry https://gitea.i.ivo-zilkenat.de/api/packages/ivo.zilkenat/npm
# or set the registry once:
npm config set @ivo:registry https://gitea.i.ivo-zilkenat.de/api/packages/ivo.zilkenat/npm
Setup
- Generate an API key in the web app: Settings > API Keys > Generate API Key.
- Authenticate:
ente auth login --url https://your-deployment.convex.site --key <api-key>
Credentials are stored at ~/.config/ente/config.toml (~/Library/Application Support/ente/config.toml on macOS), 0600. ENTE_API_URL and ENTE_API_KEY
override the file only when both are set.
For an agent operator, issue one operator key on that agent's Ente page and use it as the CLI credential. The key includes normal Ente access and is bound to that agent's configuration, threads, scheduled runs, and inbox when enabled:
ente auth login --url https://your-deployment.convex.site --key <agent-operator-key>
ente agent config show
ente agent mail threads --unread
Operator keys use the CLI's scoped REST commands. They cannot be exchanged for the legacy full-account CLI session token, so the bound-agent restriction cannot be bypassed through direct Convex commands. Use a normal account key for legacy administrative CLI commands that require that session token.
Named profiles are optional. Use one only when a person or process deliberately
switches between several credentials. --profile overrides ENTE_PROFILE.
Profiles do not activate from the current directory and are not a security
boundary. Use a separate OS account or container when operators on the same
machine must not read each other's keys. Never commit a key or put it in a
project .env file.
Usage
ente search "Alice"
ente entity list --type person
ente entity rename "Lorey Georg" "Georg Lorey"
ente task list --due today
ente activity create --type note --title "Meeting notes" --entity "Alice" --space "Personal"
ente activity get <activityId> --json # includes the body, nested agenda, messages/replies, entities, and attachments
ente agenda create-point --meeting <meetingActivityId> --title "Decisions" --content="- Ship the smaller scope"
ente agenda link-task --point <agendaPointId> --task "#12"
ente activity message add <activityId> --content "Decision: ship the smaller scope first."
ente activity content read <activityId> --json
ente activity content edit <activityId> --expected-version 42 --operations-file edits.json --json
ente canvas boards <entityId>
ente canvas html create <boardId> --title "Prototype" --file ./prototype.html --operation-id prototype-v1
ente notification send --subject "Weekly brief" --text "Your brief is ready." --html-file ./brief.html --attachment ./brief.pdf --inline-image chart=./chart.png
ente agent config show
ente agent threads
ente agent mail threads --unread
ente agent mail send --to person@example.net --subject "Update" --text "Plain fallback" --attachment ./handoff.md --html "<p><strong>Update</strong></p>" --idempotency-key agent-update-2026-09-01
ente tasks
ente guide # concepts; `ente guide <topic>`: entities, tasks, activities, search, patterns, limits
Every command supports --json. Run ente --help or ente <group> --help.
Command groups
| Group | Commands |
|---|---|
auth |
login, status, logout, profiles |
entity |
list, create, get, update (--name, --tag, --description), rename, archive, restore (--share-parents plus the returned grant fingerprint), pin (--role, optional confirmed parent grants), unpin, add-to-space, remove-from-space (--remove-from-activities optional) |
activity |
list, create, search, get, update, delete, restore, message add, attachment upload |
agenda |
create-point, link-task |
task |
list, get, create, update, done, assign, unassign, set-assignees, clear-assignees |
pins |
list |
space |
members |
recording |
list, show, inspect, rerun (admin only) |
canvas |
boards, html list, html get, html create, html update, html delete |
notification |
send (emails only your own Ente account address; optional HTML, file attachments, and CID inline images) |
agent |
list, threads, show, new, send, config show, config set-prompt, schedules configure |
agent mail |
address, threads, show, send, reply, mark |
| top-level | search, ask, query, tasks, guide |
Agent operators and inboxes
An agent operator key combines normal Ente access with access to one bound
agent. Agent read includes Ente configuration such as the prompt, Ente thread history,
scheduled-run configuration, and inbox reads when an inbox is active. Agent
write additionally allows prompt changes, full scheduled-run replacement, and
inbox send/reply. New write-capable keys also receive agent:communicate, which
lets the bound external agent start, claim, and reply to external threads without
calling an Ente-hosted model. Ente prompt and scheduled runs configure the Ente agent
counterpart; they are not instructions or schedules for the external operator.
The caller cannot select another agent, mailbox, or sender.
The corresponding scopes are agent:read, agent:write, mail:read, and
mail:send, and agent:communicate.
The inbox owner must add each exact correspondent in Ente. Unlisted inbound mail stays owner-only and never appears in operator REST, MCP, WebMCP, or CLI reads. New sends and replies are rejected before persistence unless the final recipient is allowed. An administrator-granted unlimited-mail account may enable send-to-anyone or receive-from-anyone separately for each mailbox.
ente agent config show
ente agent threads --include-archived --limit 20
ente agent show <ente-thread-id>
ente agent new "Can I publish this?" --title "Release note" --request text --idempotency-key release-question-1
ente agent threads --attention agent
ente agent send <ente-thread-id> "Published." --request ack --request-prompt "Release note published" --idempotency-key release-answer-1
ente agent config set-prompt --text "Review finance updates."
ente agent config set-prompt --file ./ente-agent-prompt.md
ente agent schedules configure --file ./schedules.json
ente agent mail address
ente agent mail threads --unread --limit 20
ente agent mail show <thread-id>
ente agent mail send --to person@example.net --subject "Update" --text "Plain fallback" --html "<p>Rich update</p>" --attachment ./reference.pdf --idempotency-key update-2026-09-01
ente agent mail reply <thread-id> --message <message-id> --text-file ./reply.txt --html-file ./reply.html --attachment ./handoff.docx --idempotency-key reply-2026-09-01
ente agent mail mark <thread-id> --state-version 4 --handled
schedules.json is the complete replacement list. Omitted schedules are
deleted:
[
{
"enabled": true,
"prompt": "Review new finance mail and prepare follow-ups.",
"timeMinutes": 480,
"timezone": "Europe/Berlin"
}
]
--text and --html accept inline strings. Their --text-file and
--html-file counterparts read UTF-8 files. After an ambiguous timeout, retry
the exact same operation with the same --idempotency-key; changing the body,
recipient, thread, or message requires a new key.
Operational recipes (playbooks)
Copy-pasteable, task-oriented recipes live in playbooks/ — log a
meeting, rename/merge an entity, work around cross-space linking, etc. Start there
for "how do I do X".
Develop in-repo / build
cd cli
pnpm install --ignore-workspace # standalone (cli/ is not a workspace member)
pnpm dev entity list # run from source via tsx
pnpm typecheck # the build-from-truth gate (tsc --noEmit)
pnpm build # → dist/cli.mjs (+ dist/SKILL.md)
Publishing is automatic: a push to main touching cli/** (or the relevant
backend surface) bumps the patch version and publishes to Gitea npm — see
.github/workflows/publish-cli.yml.
Architecture
core/ brand-neutral: transport (REST/fetch), config, output, errors, update, command base.
ente/ branded: the /api/external client, types, resolve, deadline, formatters, commands/*.
cli.ts clipanion bootstrap: registers every command group.
The dependency direction is one-way — ente/ imports core/, never the reverse.
See CLAUDE.md for the layering rules and conventions.
Public installation and recovery guide
This is the Ente private knowledge-graph / relationship-manager CLI at ente.fast,
not Ente Photos. Follow https://ente.fast/cli.md for new installations, upgrades,
PATH conflicts, configuration reuse, legacy API keys, and stale authentication.
Keep working credentials. ente auth status --json reports local configuration
without key material; verify server access with ente entity list --limit 1 --json.
Use auth login --key-stdin for hidden local key entry as shown in the guide.
Never put secrets in chat, repositories, project .env files, or logs.
Dependencies
Development Dependencies
| ID | Version |
|---|---|
| @types/node | ^22.10.0 |
| clipanion | 4.0.0-rc.4 |
| convex | ^1.37.0 |
| esbuild | 0.27.0 |
| smol-toml | ^1.3.1 |
| tsx | ^4.21.0 |
| typescript | ^6.0.3 |