e9-cli
Skill1 starsChanged 48 days agoApache-2.0View on GitHub
Connect Cursor to engine9 MCP — log in first via mcp_auth, set account scope with /e9a, and handle /e9 command-style interactions including plugin install, people lookup, and task scheduling.
We split this skill into the rules it gives an agent
46 rules. About 0 are common, 5 are distinctive, and 41 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
41
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 8
Use this skill to configure or troubleshoot an engine9 MCP connection in Cursor or another MCP client.
- Very specific: line 30
Rule: Every /e9 request starts by logging in.
- Very specific: line 32
Call mcp_auth on the engine9 MCP server with {}.
- Very specific: line 34
Call ok, then user, to confirm signed in.
- Very specific: line 37
If user already succeeds this session, skip to step 4.
- Very specific: line 43
Only if login succeeded (user works) but other MCP calls still fail:
- Distinctive: line 45
Ask the user to reload MCP servers in Cursor (Settings → MCP) if config recently changed.
- Distinctive: line 48
Do not use shell commands or config greps as a substitute for step 0 login.
- Very specific: line 58
Rule: When an account or parent is not found, stop.
- Very specific: line 88
Create or update ~/.cursor/mcp.json:
- Very specific: line 103
If local standalone MCP runs without TLS, use http://127.0.0.1:3334/mcp.
- Distinctive: line 104
After config changes, reload MCP servers in Cursor.
- Very specific: line 152
Do not call user (or any account lookup tool) to resolve <lookup>.
- Distinctive: line 153
Do not perform fuzzy matching, alias matching, or ambiguity checks.
- Very specific: line 155
Call MCP account with { "account_id": "<lookup>" } (plugins command.
- Very specific: line 163
If search count is 0 or user.accounts is empty: stop.
- Very specific: line 165
Do not load plugins for every account (or for the first id).
- Very specific: line 178
Always replace prior account scope and plugin list on each /e9a.
- Very specific: line 179
Do not call account again on every /e9 subcommand if engine9.plugins is already loaded for the current engine9.account_id.
- Very specific: line 207
Every MCP call that is account-scoped MUST include account_id when the op is single-account (lookup, sql, eql, plugin schedule, etc.).
- Very specific: line 208
If account_id is already known in this chat session (engine9.account_id from /e9a or an explicit user statement), reuse it.
- Very specific: line 209
If scope is missing, ask the user (single id, /e9a parent …, or /e9a all) before running scoped tools.
- Very specific: line 210
Do not guess account_id. If MCP did not return it, stop.
- Very specific: line 216
Prefer remote multi-account filters: parent_account_id for parent scope, or the remote API’s multi-account / auth-scoped listing for all — …
- Very specific: line 217
Use Prefect state_type filters only (FAILED, RUNNING, COMPLETED, PAUSED, …).
- Very specific: line 218
Do not call MCP account (plugins) for each child, and do not pick engine9.account_id (the first resolved id) and probe that account’s …
- Very specific: line 219
Do not treat account-DB failures (Cannot connect to the … database) as blocking for these ops — remote flow-run listing does not need …
- Very specific: line 220
Do not require engine9.plugins for remote flow-run listing.
- Very specific: line 230
If engine9.plugins is not cached for that account, call MCP account or suggest /e9a.
- Very specific: line 232
Ensure active account_id exists (or request it / suggest /e9a).
- Very specific: line 234
Call lookup with mapped filters and account_id.
- Very specific: line 238
If /e9a or MCP account failed for this account, stop — do not call task.
- Very specific: line 241
If MCP task returns isError: true or a fatal error message, stop — do not retry or call other account tools.
- Very specific: line 244
Call MCP segment with { "command": "list", "account_id": "<account_id>" }.
- Very specific: line 246
Ensure active account_id exists.
- Very specific: line 247
Call MCP segment with command: build and either segment_id or definition_path from the user args.
- Very specific: line 253
Call MCP report with command: run, path, and any filter options (start, end, limit).
- Very specific: line 256
Call MCP apiKey. Never schedule createApiKey via task.
- Very specific: line 258
Follow e9-plugin. Native plugin only — do not use task.
- Distinctive: line 270
When multiple values exist for a filter, pass them as arrays.
- Very specific: line 307
Do not pass legacy remote job paths such as channelbots.RENxtBot.People.
- Very specific: line 313
If the path is @engine9/plugins/e9workers:<Worker>, pass it through — do not require engine9.plugins / MCP account.
- Very specific: line 315
If the user path is already plugin.path or plugin.path:Submodule and matches an installed plugin, use it.
- Very specific: line 316
If the path is alias/submodule (e.g.
- Very specific: line 320
Call MCP task with account_id from engine9.account_id, resolved path, and method.
- Very specific: line 338
Use action: "listTasks" with flow_run_id and optional task_run_ids from the schedule response to poll status.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
engine9 CLI
Use this skill to configure or troubleshoot an engine9 MCP connection in Cursor or another MCP client. It also defines /e9 and /e9a command behavior, including account scope, plugin install, people lookup, reports, segments, API keys, and task scheduling.
Quick reference
| Need | Action |
| Sign in | Call mcp_auth with {}, then verify with ok and user |
| Select one account | /e9a <account_id> |
| Select children of a parent | /e9a parent <parent_account_id> |
| Install a plugin | /e9 plugin install <path> — e9-plugin |
| Look up people | /e9 lookup <terms> |
| Run an on-demand method | /e9 task <plugin-path-or-alias> <method> [options...] |
| Configure Cursor | Add the server to ~/.cursor/mcp.json and permissions to ~/.cursor/permissions.json |
Rule: On any MCP tool error, follow e9-mcp — MCP tool errors — stop immediately; do not call downstream account-scoped tools after a failed account, task, lookup, or similar call.
Rule: If an account or parent cannot be found, stop. Do not resolve it by any other mechanism. A miss is MCP account search count: 0, an empty user.accounts, or plugins reporting the account unknown or unauthorized. Tell the user and end the turn. Do not search again with a different filter, a guessed id, or include_disabled. Do not read accounts.d, accounts.compiled.json5, account-config.json, frakture-account-config.json, .e9_parameters, or any other file, and do not run the e9 CLI or a shell search to find the id.
Access has two tiers: a superadmin (a file on the server) can open every account, and an admin (a member of an account's admin role segment) can open that account. Either can do everything in an account they can open. Manage an account's admins with account listAdmins / addAdmin / removeAdmin.
Step 0 — Log in (always first)
Rule: Every /e9 request starts by logging in. Do not grep, curl, read config files, start servers, or run CLI commands to "figure out" auth.
- Call
mcp_authon the engine9 MCP server with{}. - Cursor opens a sign-in prompt for the user — wait for them to complete it.
- Call
ok, thenuser, to confirm signed in. - Proceed with the user's request.
If user already succeeds this session, skip to step 4.
Login is only mcp_auth → user completes prompt → verify with user. Nothing else.
Troubleshooting after login
Only if login succeeded (user works) but other MCP calls still fail:
- Ask the user to reload MCP servers in Cursor (Settings → MCP) if config recently changed.
- For local dev server issues, see Server endpoint and startup below.
Do not use shell commands or config greps as a substitute for step 0 login.
Local dev without OAuth
Project .cursor/mcp.json may define engine9.local_noauth with Authorization: Bearer localdev. That entry skips the OAuth prompt; it is not a login workaround when the OAuth server is configured — still call mcp_auth on the correct server entry first.
MCP-only discovery
When handling /e9 or /e9a requests, do not read local workspace code to discover plugins, worker methods, paths, or options. Local source does not reliably match the connected MCP server or the account's installed plugins. Use MCP tool schemas, MCP account (cached as engine9.plugins), and MCP task / sql / analyze / timelinePerson / timelinePersonLegacy / file / apiKey only. See e9-mcp — MCP-only discovery.
Rule: When an account or parent is not found, stop. Do not resolve it by any other mechanism. Account discovery is MCP user / account search only.
Rule: Discover accounts, plugins, methods, paths, and options from the connected MCP server only.
Concepts
- Cursor MCP config (
mcp.json,permissions.json) - Auth expectations (OAuth vs
localdevbearer) /e9aaccount scope and plugin cache/e9session behavior, lookup parsing, and task scheduling
Server endpoint and startup
engine9 MCP is exposed at POST /mcp (with GET /mcp/health for health checks).
Production default: https://data.engine9.ai/mcp (same host as the Task API and /data routes).
- Preferred server startup: run the main API (
node api/index.js) so MCP and other APIs share one port. - Standalone MCP startup: from
engine9/server, runnpm run mcp. - Local standalone MCP URL:
http://127.0.0.1:3334/mcp(when TLS is off)https://127.0.0.1:3334/mcp(whenENGINE9_SSL_CERT_PATHis set)
Quick health checks:
- HTTP:
curl -sS http://127.0.0.1:3334/mcp/health - HTTPS (self-signed local cert):
curl -k -sS https://127.0.0.1:3334/mcp/health
Cursor MCP configuration
Create or update ~/.cursor/mcp.json:
{
"mcpServers": {
"engine9.ai": {
"url": "https://data.engine9.ai/mcp"
}
}
}Notes:
- The server key (
engine9.aiabove) should match engine9's MCP server name (ENGINE9_MCP_SERVER_NAME, defaultengine9.ai). - If local standalone MCP runs without TLS, use
http://127.0.0.1:3334/mcp. - After config changes, reload MCP servers in Cursor.
Cursor permissions configuration
Create or update ~/.cursor/permissions.json:
Allow all engine9 tools:
{
"mcpAllowlist": ["engine9.ai:*"]
}Or allow a subset:
{
"mcpAllowlist": ["engine9.ai:ok", "engine9.ai:user", "engine9.ai:account", "engine9.ai:lookup", "engine9.ai:task"]
}Auth expectations
- MCP requests to
/mcprequire Bearer auth (OAuth orlocaldev). - In Cursor, normal flow is OAuth connect on first request.
- For local/offline testing,
Authorization: Bearer localdevcan be used with server-side localdev account configuration (ENGINE9_MCP_LOCALDEV_ACCOUNTS).
/e9a — account scope
Primary command forms:
/e9a <lookup>— single exact account id (default)/e9a parent <parent_id>— active child accounts of<parent_id>(comma-separated parent ids allowed)/e9a all— all active accounts
Examples: /e9a <account_id>, /e9a parent <parent_account_id>, /e9a all
The CLI bin script (server/bin/e9a) writes .e9_parameters for subsequent local e9 worker CLI runs only. Agents handling /e9a in Cursor must not run that bin script or read the files it writes.
Do not use leftover CLI files or compiled catalogs for MCP / Cursor session scope. Never read .e9_parameters, .e9_config.json5, accounts.d/, accounts.compiled.json5, or similar local state to infer account_id. If chat session engine9.account_id is unset, ask the user (or suggest /e9a <account_id>) — do not invent scope from disk.
Discovering accounts (MCP): when the user asks which accounts match a prefix, parent, type, tags, or installed plugin, call MCP account with command: "search" in one request — do not use /e9a all plus per-account plugin loads. Example: { "command": "search", "prefixes": ["<prefix>"], "plugins": ["acoustic"] }. If that search returns count: 0, stop and report that MCP found no matching accounts. Do not resolve the name through another search, user, accounts.d, or the e9 CLI. Use /e9a <id> afterward only when search returned that id.
Required behavior
Default /e9a <lookup>:
- Do not call
user(or any account lookup tool) to resolve<lookup>. - Do not perform fuzzy matching, alias matching, or ambiguity checks.
- Set the provided value as active account scope immediately.
- Call MCP
accountwith{ "account_id": "<lookup>" }(plugins command;command: "plugins"optional). - On success (
{ ok: true, plugins: [...] }or{ ok: true, command: "plugins", plugins: [...] }), persist the returnedpluginsarray for subsequent/e9requests. - On failure (
isError: true, or text likeCannot connect to the … database/Not authorized for account): stop. Report the error. Do not cache plugins. Do not proceed to/e9 taskor other account-scoped calls. - Reuse stored account and plugins unless the user runs another
/e9a.
/e9a parent <parent_id> or /e9a all:
- Resolve ids only via MCP. Parent:
account{ "command": "search", "parents": ["<parent_id>"] }(comma-separated parents →parentsarray; results are flat rows withparent_ids). All: MCPuserand take active keys ofaccounts(disablednot true); each entry includes flatparent_ids(no nested tree). - If search
countis0oruser.accountsis empty: stop. Report that MCP did not find the parent or any accounts. Do not resolve them by any other mechanism. - Set
engine9.account_idsto the MCP list; setengine9.account_idto the first id (label only — not a DB probe target). Clearengine9.plugins. - Do not load plugins for every account (or for the first id). Do not call MCP
accountplugins / open account databases to “check access” across children. Report the resolved ids and count. - For remote task listing under parent/all scope, see Multi-account remote flow runs — those calls must not fan out per-child DB access.
Session persistence
Persist:
engine9.account_id— exact lookup valueengine9.account_ids— single-item array with that same valueengine9.plugins— array from MCPaccounton success (replace entirely on each/e9a)
Rules:
- Always replace prior account scope and plugin list on each
/e9a. - Do not call
accountagain on every/e9subcommand ifengine9.pluginsis already loaded for the currentengine9.account_id; only refresh when the user runs/e9aagain or explicitly asks to reload plugins.
Response requirements
On success: confirm the exact account_id, state how many plugins were loaded, and note that future /e9 requests will use this account.
On MCP failure: confirm account_id was set, report the MCP error verbatim, note that plugins were not cached, and stop — do not run further account-scoped tools in the same request.
/e9 command contract
Supported forms:
/e9— bootstrap (connectivity, identity, account scope)/e9 plugin listAvailable— MCPplugincommand: listAvailable/e9 plugin install <path>— MCPplugincommand: installon session account(s); see e9-plugin/e9 plugin settings [path]— MCPplugincommand: settings/e9 lookup foo@bar.com— MCPlookup/e9 segment list— MCPsegmentwithcommand: list/e9 segment build <segment_id|definition_path>— MCPsegmentwithcommand: build/e9 report list— MCPreportwithcommand: list/e9 report run <path>— MCPreportwithcommand: run(see e9-reports)/e9 apiKey list//e9 apiKey create …— MCPapiKey(see e9-api-key)/e9 task <plugin-path-or-alias> <method> [options...]
Account/domain create and secrets: use e9-account (cloud-services/e9-account), not MCP /e9 domain.
Session and account requirements
- Every MCP call that is account-scoped MUST include
account_idwhen the op is single-account (lookup, sql, eql, plugin schedule, etc.). - If
account_idis already known in this chat session (engine9.account_idfrom/e9aor an explicit user statement), reuse it. - If scope is missing, ask the user (single id,
/e9a parent …, or/e9a all) before running scoped tools. Stop and wait — do not proceed with a guessed id. - Do not guess
account_id. If MCP did not return it, stop. Do not resolve it from.e9_parameters,.e9_cli_history,accounts.d/,accounts.compiled.json5, or any other file.
Multi-account remote flow runs (parent / all)
Use this for requests like “list current errored tasks”, cross-account job status, or anything backed by MCP task action: "list" → TaskWorker.listRemoteFlowRuns / remote-legacy POST /flow_runs/filter when the user wants parent or all scope. For FAILED / RUNNING / COMPLETED totals without paging the list, use action: "metrics" (POST /flow_runs/metrics) and omit status; use action: "count" with the current status for “N of total”. To list tasks inside one flow run, use MCP action: "listTasks" → TaskWorker.listRemoteTaskRuns / remote-legacy POST /task_runs/filter (or REST POST /task_runs/filter).
- Prefer remote multi-account filters:
parent_account_idfor parent scope, or the remote API’s multi-account / auth-scoped listing for all — not a loop of per-account MCP calls. - Use Prefect
state_typefilters only (FAILED,RUNNING,COMPLETED,PAUSED, …). Legacy Mongo tokens (complete,error,in_progress) are rejected with 422. - Do not call MCP
account(plugins) for each child, and do not pickengine9.account_id(the first resolved id) and probe that account’s database as a gate. - Do not treat account-DB failures (
Cannot connect to the … database) as blocking for these ops — remote flow-run listing does not need account DBs. - Do not require
engine9.pluginsfor remote flow-run listing; plugin cache is for single-account plugin method scheduling. - Single-account rules (load plugins via
/e9a <id>, hard-stop on DB connect foraccount/taskschedule path resolution) still apply when scheduling a plugin method on one account. - Archive / bulk retry of those listed runs is also one request: reuse
parent_account_id/account_idsand send everyflow_run_idtogether. Do not fan out one MCP call per child. See e9-mcp — Bulk archive.
Recommended /e9 bootstrap flow
- Step 0 — Log in —
mcp_auth→ user completes prompt →user. /e9with no subcommand:- Confirm signed in via MCP
user. - Confirm active
account_id(from session or user); if missing, suggest/e9a <account_id>. - If
engine9.pluginsis not cached for that account, call MCPaccountor suggest/e9a.
- Confirm signed in via MCP
/e9 lookup ...:- Ensure active
account_idexists (or request it / suggest/e9a). - Parse lookup terms into MCP
lookuparguments. - Call
lookupwith mapped filters andaccount_id.
- Ensure active
/e9 task ...:- Multi-step flow (user asks to deploy/schedule a flow such as identity rebuild): use MCP
taskwithflow_id(e.g.identity-rebuild) — see e9-tasks-api/deploy-flow.md. Do not expand steps into on-demand path/method calls. If MCP returns flow-not-found and you have a localengine9/servercheckout with the flow file, fall back toe9 task runFlow -a <account> --flow=rebuild/identity-rebuild.flow.json5. - On-demand method: require
engine9.account_idand (for non-e9workerspaths)engine9.plugins(run/e9afirst if missing). - If
/e9aor MCPaccountfailed for this account, stop — do not calltask. - Resolve the plugin path from cached plugins before calling MCP
task. - Pass the canonical plugin path (colon submodule form), not remote-legacy dotted paths.
- If MCP
taskreturnsisError: trueor a fatal error message, stop — do not retry or call other account tools.
- Multi-step flow (user asks to deploy/schedule a flow such as identity rebuild): use MCP
/e9 segment list:- Ensure active
account_idexists (or request it / suggest/e9a). - Call MCP
segmentwith{ "command": "list", "account_id": "<account_id>" }.
- Ensure active
/e9 segment build ...:- Ensure active
account_idexists. - Call MCP
segmentwithcommand: buildand eithersegment_idordefinition_pathfrom the user args.
- Ensure active
/e9 report list:- Ensure active
account_idexists (or request it / suggest/e9a). - Call MCP
reportwith{ "command": "list", "account_id": "<account_id>" }.
- Ensure active
/e9 report run <path>:- Ensure active
account_idexists. - Call MCP
reportwithcommand: run,path, and any filter options (start,end,limit).
- Ensure active
/e9 apiKey …:- Catalog needs no account. Other commands need
account_id. - Call MCP
apiKey. Never schedulecreateApiKeyviatask. Show plaintextkeyto the user immediately on create/rotate.
- Catalog needs no account. Other commands need
/e9 plugin …:- Follow e9-plugin. Native
pluginonly — do not usetask. listAvailable/settings: sessionaccount_id.install <path>: resolve path fromlistAvailable; ifengine9.account_idsis a parent/all list, install on each id (parallel batches). Do not callaccountplugins first.
- Follow e9-plugin. Native
/e9 lookup parsing rules
For tokenized arguments after lookup:
- Tokens containing
@MUST be treated as email inputs and mapped toemails. - Tokens that are straight integers (digits only, e.g.
12345) MUST be treated asperson_ids. - Other terms may map to other supported filters (
phones,given_names,last_names) based on context.
When multiple values exist for a filter, pass them as arrays.
People in or out of a current model by source code are not token filters and not a lookup. Build a segment definition from the model's clauses (MCP segmentDefinitionClauses) and preview it with segment command: "preview". Paths and forms: e9-model — Model segment definition clauses. People in a legacy model for a source code and out of the matching current model: e9-model/legacy.md, and only when the user explicitly asked for legacy.
Example mapping for /e9 lookup foo@bar.com 12345:
{
"account_id": "test",
"emails": ["foo@bar.com"],
"person_ids": [12345],
"limit": 10
}/e9 task parsing and path resolution
Command form: /e9 task <plugin-path-or-alias> <method> [options...]
Examples:
/e9 task @engine9/plugins/e9workers:EchoWorker echo/e9 task renxt/people listCustomFields/e9 task @frakture-com/channelbots/RENxtBot:People listCustomFields/e9 task @engine9/plugins/e9workers:SQLWorker query
Path forms (in priority order)
- Reserved engine9 Workers path (no plugin lookup; every bootstrapped account):
@engine9/plugins/e9workers:EchoWorker+ methodecho(smoke test)@engine9/plugins/e9workers:SQLWorker+ methodquery
- Canonical plugin path with colon submodule (account plugins):
@frakture-com/channelbots/RENxtBot:People
- Slash alias shorthand (resolve via
engine9.pluginsbefore MCP):renxt/people→ find plugin wheremetadata.metadata.alias(ormetadata.alias) isrenxt, submodulePeoplefrommetadata.submodules
- Bare plugin path (no submodule):
@frakture-com/channelbots/RENxtBot— only when the method lives on the plugin root
Do not pass legacy remote job paths such as channelbots.RENxtBot.People. Do not treat Echo as a separate installed plugin.
Resolution algorithm
Before MCP task:
- If the path is
@engine9/plugins/e9workers:<Worker>, pass it through — do not requireengine9.plugins/ MCPaccount. - Otherwise require
engine9.pluginsfrom/e9a(or call MCPaccountonce if missing). - If the user path is already
plugin.pathorplugin.path:Submoduleand matches an installed plugin, use it. - If the path is
alias/submodule(e.g.renxt/people), scanengine9.plugins:- Match alias (case-insensitive) on
plugin.metadata.metadata.aliasorplugin.metadata.alias - Match submodule (case-insensitive) on keys of
plugin.metadata.submodules - Build
{plugin.path}:{Submodule}(preserve submodule casing from metadata keys)
- Match alias (case-insensitive) on
- Call MCP
taskwithaccount_idfromengine9.account_id, resolvedpath, andmethod.
The MCP server also resolves slash/colon paths against the account plugin table if the agent passes shorthand.
Example MCP task payload
User: /e9 task renxt/people listCustomFields
Account: <account_id> (from /e9a)
{
"account_id": "<account_id>",
"path": "@frakture-com/channelbots/RENxtBot:People",
"method": "listCustomFields",
"label": "renxt/people listCustomFields"
}Use action: "listTasks" with flow_run_id and optional task_run_ids from the schedule response to poll status. That MCP action calls remote-legacy POST /task_runs/filter.
Related documentation
| Topic | Documentation |
| MCP tools and invocation rules | e9-mcp |
| Install plugins on accounts | e9-plugin |
| API-key management | e9-api-key |
| Direct HTTP Task API | e9-tasks-api |
| Plugin-installed reports | e9-reports |
| Flow deployment | deploy-flow.md |
In this repository24 other files it gives its agents.
- .cursor/rules/no-client-names.mdcCursor rule
- .cursor/rules/skill-writing-standard.mdcCursor rule
- create-engine9-pluginSkill
- e9-api-keySkill
- e9-custom-fieldsSkill
- e9-delegate-domainSkill
- e9-dev-tasksSkill
- e9-eqlSkill
- e9-exportSkill
- e9-funnelSkill
- e9-global-messageSkill
- e9-inputSkill
- e9-inventorySkill
- e9-mcpSkill
- e9-modelSkill
- e9-person-idSkill
- e9-person-remoteSkill
- e9-pii-freeSkill
- e9-pluginSkill
- e9-reportsSkill
- e9-source-codeSkill
- e9-tasks-apiSkill
- e9-timelineSkill
- e9-upgradeSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

