MCP server for interacting with your LINE Official Account
Ethora is installed from its publisher's own source and answers where it runs, so this marketplace is not in the path of a single call. There is no address here to send one to, and a panel that pretended otherwise would be showing you an answer we made up. Install it and call it from your own client — the Installation tab has the entry for each one.
What it does
MCP server for the Ethora chat & messaging platform: login, manage apps and chat rooms, broadcast messages, and deploy AI agents / chatbots with RAG sources.
Quickstart
# 1 — add it to Claude Code
claude mcp add --scope user ethora-mcp '--' npx -y @ethora/mcp-server
# 2 — ask your agent for something these tools do
# ethora-tools-enable, ethora-session-configure, ethora-status and 155 more
Ethora costs nothing on mcprush: there is no plan to choose here, no cap to set and nothing mcprush can bill you for.
Collected from a public index. Nobody has claimed this account, so nothing here was written by its author — claim it if it is yours.
Where are you running it?
Every route below installs the same thing and ends at the same approval screen. This one runs on your machine: your client starts Ethora as a process under your own user, with your files and your network, so the tool surface below is what it can do to your computer rather than to a server somewhere else. Its scan result is on the Security tab — read the surface before you approve it.
This is a public server: you run it yourself and this marketplace is not in the path. You need Node.js — the current LTS (24) is the safe choice; npx comes with it. Claude Code registers it in one command; --scope user makes it available in every project. The '--' is in quotes so that PowerShell passes it on.
claude mcp add --scope user ethora-mcp '--' npx -y @ethora/mcp-serverReconnect, or start a new session, and the tools appear in the model’s tool list.
Nothing is required, but it can take ETHORA_API_URL (Full Ethora API URL. Defaults to https://api.chat.ethora.com/v1 if neither ETHORA_API_URL nor ETHORA_BASE_URL is set.), ETHORA_BASE_URL (Base host URL (e.g. https://api.chat.ethora.com). The server appends /v1 automatically. Use ETHORA_API_URL instead if you need a non-/v1 path.), ETHORA_APP_JWT (App JWT used for the user-auth bootstrap flow (login/register). Usually starts with 'JWT '. Optional; can also be set at runtime via the ethora-configure tool.), ETHORA_B2B_TOKEN (B2B server token used for tenant-actor x-custom-token auth (JWT with type=server). Required for B2B / app provisioning flows. Optional; can also be set at runti), ETHORA_MCP_ENABLE_DANGEROUS_TOOLS (Set to 'true' to expose destructive tools (app deletion, wallet transfers, bulk delete). Disabled by default.) if you want to set them.
One config entry your client uses to start the process locally. A local server runs with your file system and your network, which is why it is priced without metering.
158 tools, with what each one reads, writes and reaches shown before you agree — the same list on every route above. Read the tool surface.
Tool surface
What the model actually sees. Descriptions are diffed on every release — see version history.
Only the core tools are listed by default. Call this to enable another group for this session; the tool list refreshes automatically (tools/list_changed). Without group it returns the catalogue: each group's summary, tool count and whether it is enabled. Groups: …; all enables everything.…
No parameter schema on file.
Set the Ethora API URL and credentials for this MCP session. Stores values in memory only; each call merges with omitted fields kept. Alternative to env vars (ETHORA_API_URL / ETHORA_APP_JWT / ETHORA_APP_TOKEN / ETHORA_B2B_TOKEN). On a hosted server apiUrl is fixed and cannot be changed;…
No parameter schema on file.
Report the current Ethora MCP session state: configured API URL, active auth mode, which credentials are present (booleans like hasAppJwt — values never echoed), the selected appId/agentId, and hosted/sessionId on the hosted (Streamable HTTP) server. Auth: none required. Errors: effectively…
No parameter schema on file.
Task-oriented orientation for this MCP server: explains the three Ethora auth modes (user / app-token / B2B) and recommends next tool calls + recipes based on current session state. Auth: none required — inspects state, no API calls. Errors: effectively none. Related: pass a recommended recipe id…
No parameter schema on file.
Execute a built-in recipe — an ordered sequence of this server's own tool calls — by id. Recipes capture common flows (B2B bootstrap, broadcast, sources ingest). Use dryRun: true to preview resolved steps. Omit recipeId to list runnable recipes for a goal. Requires: the inputs the chosen…
No parameter schema on file.
Diagnose the session: validate the config is internally consistent for the active auth mode and ping the Ethora API (GET /v1/ping). Returns { state, checks, ping, suggestions }. Auth: none required; report is tailored to whatever credentials are set. Errors: rarely throws — instead returns…
No parameter schema on file.
Switch this session's active auth mode: user (a logged-in Ethora user, the normal mode and the only one the hosted agents/rooms routes accept), app (the configured appToken, for app-scoped automation such as broadcast, sources and the legacy bot) or b2b (a tenant actor via the…
No parameter schema on file.
Set the current app context for this session so app-scoped tools can omit their appId argument. Stores currentAppId and, if given, appToken (which defaults the auth mode to app-token unless authMode overrides). Auth: none required to set the context. Errors: effectively none — a…
No parameter schema on file.
Set the current saved-agent context for this session, so agent-scoped tools can omit their agentId argument. Stores currentAgentId in session state. Requires: an agent id or address from ethora-agent-list or ethora-agent-create. Auth: none required. Errors: effectively none — the agentId…
No parameter schema on file.
Enqueue an asynchronous broadcast job posting a message to one or more chat rooms of an app — returns a jobId; messages are not sent synchronously. Targeting is exclusive: allRooms, chatIds, or chatNames, not a mix. Requires: a selected app with at least one room (ethora-chat-create).…
No parameter schema on file.
Fetch the current status and per-room results of a broadcast job by jobId (one-shot, no polling). Returns the job object with its state (pending/running/completed/failed). Requires: a selected app with at least one room (ethora-chat-create). Auth: app-token mode OR B2B mode with an explicit…
No parameter schema on file.
Block until a broadcast job reaches a terminal state (completed or failed) or until timeoutMs — read-only polling wrapper around ethora-broadcast-job-start. Returns { done, state, job }, or { done: false, reason: "timeout" } on timeout. Requires: a jobId returned by…
No parameter schema on file.
Upload 1–5 files to the authenticated user's Ethora file storage (POST /v2/files). Each upload is a new record (no overwrite-by-name); files passed as base64, 50MB max each. Auth: user-auth mode with an active user session (ethora-user-login first). Errors: 401 not logged in; 413 size limit…
No parameter schema on file.
List the authenticated user's files, or fetch one file's metadata by id (GET /v2/files). Returns an array when id is omitted, a single record when given. Requires: a file id from ethora-file-upload. Auth: user-auth mode with an active user session. Errors: 401 not logged in; 404 unknown id…
No parameter schema on file.
Permanently delete one of the authenticated user's files by id (DELETE /v2/files/:id). Removes the record and its stored content; not reversible. Requires: a file id from ethora-file-upload. Auth: user-auth mode with an active user session. Errors: 401 not logged in; 403 not owned by the user;…
No parameter schema on file.
Upload documents (1–5; PDF, text, etc.) into an app's RAG sources (legacy user-auth route). Async — content becomes queryable once indexing finishes; files passed as base64, 50MB max each. Requires: a selected app (ethora-app-select) or an explicit appId. Auth: user-auth mode, active session;…
No parameter schema on file.
Remove a previously ingested document from an app's RAG sources by docId (legacy user-auth route). Deletes the document record and its embeddings; not reversible. Requires: a document id from ethora-source-doc-list. Auth: user-auth mode, active session; the user must own the app. Errors: 401…
No parameter schema on file.
Authenticate as an existing Ethora user with email + password. Stores the user session token in this MCP session and unlocks user-auth tools (ethora-app-list, ethora-files-*, ethora-wallet-*). Auth: user-auth mode (ethora-auth-mode-set first) and a configured appJwt. Errors: 401/403 bad…
No parameter schema on file.
Create a new Ethora user account by email + first/last name, then log in and bind the session. A password is generated when omitted and returned once. By default also mints a long-lived API key so an agent can reconnect later with Authorization: Bearer <key> (no human step needed). Auth:…
No parameter schema on file.
Send feedback about Ethora to the Ethora team: something that does not work, behaves differently from what the tool description promised, is missing, or is badly documented. It reaches the team directly, so prefer it over guessing or silently giving up when a tool fails. Recent failures in this…
No parameter schema on file.
Reveal the appToken of an app the caller owns, for a chat-component snippet or a widget config. Every other tool redacts appToken, appSecret and tenantSecret from its results because tool output enters the model's context and client logs; this tool returns exactly { appId, appToken, note } and…
No parameter schema on file.
Mint a long-lived, revocable API key for the currently logged-in user. The key is a user token: send it as Authorization: Bearer <key> to the hosted MCP endpoint (or set it in the stdio client) to skip ethora-user-login. Shown once. Auth: user auth (logged in). Errors: 401 not logged in; 404…
No parameter schema on file.
List the current user's API keys (id, name, createdAt, expiresAt). Token values are never returned. Auth: user auth.
No parameter schema on file.
Revoke one of the current user's API keys by id. Clients using that key stop working immediately. Requires: a key id from ethora-api-key-list or ethora-api-key-create. Auth: user auth. Errors: 404 unknown id.
No parameter schema on file.
List all Ethora apps (tenants) owned by the currently logged-in user. Returns an array with appId (24-char hex), displayName, domainName, ownership and bot-status metadata. Credential fields (appSecret, tenantSecret, appToken, passwords) are redacted in the result; call…
No parameter schema on file.
Create a new Ethora app (tenant) owned by the currently logged-in user. Allocates a fresh 24-char hex appId and sets the caller as owner; counts against the owner's plan limit. Returns the new app object including appId. The returned app has its credential fields redacted; call…
No parameter schema on file.
Permanently delete an Ethora app the caller owns — removes its chat rooms, files, indexed RAG sources, and bot config; end users are immediately signed out. Irreversible; gated behind ETHORA_MCP_ENABLE_DANGEROUS_TOOLS=true. Requires: an appId from ethora-app-list or ethora-app-create. Auth:…
No parameter schema on file.
Update mutable fields on an app the caller owns (displayName, domainName, appTagline, primaryColor, botStatus). Partial update — omitted fields are left unchanged. Requires: an appId from ethora-app-list or ethora-app-create. Auth: user-auth mode, active session; the caller must own the app.…
No parameter schema on file.
List the default chat rooms of a specific Ethora app, passed via appId (or the currently selected app). Returns rooms with their JIDs and titles. Requires: an appId from ethora-app-list or ethora-app-create. Auth: user-auth mode, active session; the caller needs read access (ownership or…
No parameter schema on file.
Create a new chat room (MUC room) inside an app the caller owns. Every room created this way is listed in the app's rooms (defaultRooms); pinned: true additionally makes new users auto-join it (existing users are not added), pinned: false (default) keeps it opt-in. Returns the new room…
No parameter schema on file.
Permanently delete a chat room from an app the caller owns — removes the MUC room, its message archive, and all member affiliations. Irreversible; gated behind ETHORA_MCP_ENABLE_DANGEROUS_TOOLS=true. Requires: a room from ethora-app-rooms-list or ethora-chat-create. Auth: user-auth mode,…
No parameter schema on file.
Read the authenticated user's on-chain ERC-20 wallet balance(s). Auth: user-auth (log in first). Errors: 401 not logged in; 503 wallet RPC unreachable — retry with backoff.
No parameter schema on file.
STDIO ONLY: not available on the hosted server (directory rules forbid connectors that move money or crypto). Send ERC-20 tokens from the authenticated user's wallet to another address — submits a signed on-chain transaction; consumes gas and reduces the sender's balance. Irreversible and NOT…
No parameter schema on file.
Create a new Ethora app (tenant) server-side using B2B auth — the partner/integrator equivalent of ethora-app-create. Allocates a fresh 24-char hex appId; does not create tokens, rooms, or a bot. Returns the new app object including appId. Auth: B2B mode (ethora-auth-mode-set + a…
No parameter schema on file.
Enable the LEGACY per-app aiBot (B2B auth). NOTE: apps created via the API/B2B no longer auto-provision a legacy aiBot, so this returns 422 BOT_NOT_INITIALIZED on a clean app. The forward path for B2B AI is the Agents API — use ethora-b2b-app-bootstrap-ai or ethora-agent-create +…
No parameter schema on file.
Read the current AI bot configuration for an app: status, trigger, prompt, greeting, LLM provider/model, RAG settings, widget config. Requires: an app with a legacy per-app aiBot (dashboard-created). API-created apps have none: use ethora-agent-create -> ethora-agent-invite ->…
No parameter schema on file.
Configure the AI bot for an app — prompt, LLM, trigger, greeting, RAG behavior, identity, and public widget settings. Partial update — omitted fields are left unchanged. status: "on" activates the bot (best-effort; needs a prompt + LLM and a backend AI service). Requires: an app with a legacy…
No parameter schema on file.
List the reusable saved agents of an app (GET /v2/apps/:appId/agents, or GET /v2/agents for the token's own app) — a saved agent is a reusable bot definition. Returns an array of agents with ids, names, and config. Auth: app-token mode (after ethora-app-select + ethora-auth-mode-set).…
No parameter schema on file.
Fetch one reusable saved agent's full config by id (GET /v2/agents/:agentId) — prompt, LLM, RAG settings, visibility. Also sets this agent as the session's current agent context (no server-side change). Requires: an agent id or address from ethora-agent-list or ethora-agent-create. Auth:…
No parameter schema on file.
Create a reusable AI agent (POST /v2/apps/:appId/agents). Works in user auth mode (the normal hosted mode) or B2B mode; app-token mode is not accepted by the backend. Each agent is a persona — name, avatar, system prompt, LLM config, plus response-gate settings (responseMode, cooldownSec) that…
No parameter schema on file.
Update a saved AI agent (PUT /v2/agents/:agentId). All fields are optional — only what you pass is updated. Common uses: tune the system prompt after a test run, switch responseMode to control turn-taking in multi-agent rooms, or adjust cooldownSec. See ethora-agents-quickstart prompt for…
No parameter schema on file.
Duplicate an existing saved agent into a new agent, optionally overriding its name/slug/summary (POST /v2/agents/:agentId/clone). The source agent is unchanged; the new clone becomes the session's current agent context. Requires: an agent id or address from ethora-agent-list or…
No parameter schema on file.
Make an agent the app's ACTIVE widget bot: sets App.defaultBotInstanceId (and botStatus: on), which is what POST /v2/widget/sessions uses to decide who answers website visitors. Required before an embedded widget can answer on an API-created app. Preconditions: the agent was invited into a…
No parameter schema on file.
Set an Agent's visibility (private | unlisted | public). Public agents can be invited cross-app by anyone who knows the address. Pass the agent as agentId or agentIdOrAddress (one of the two is required, the schema marks both optional because either is accepted), from ethora-agent-list or…
No parameter schema on file.
Invite an Agent into a chat room. Multiple agents can coexist in the same room — call this tool once per agent and they will all appear as members able to converse. Lazily creates a per-App BotInstance (an Ethora user with isBot:true) if one does not already exist for (agent, app). Spawns the XMPP…
No parameter schema on file.
Append a fragment to an Agent's SOUL.MD (its evolving identity / private notes). Operator-driven; the Agent itself can also self-edit via the same endpoint when called by ai-service. Requires: an agent id or address from ethora-agent-list or ethora-agent-create.
No parameter schema on file.
Replace an Agent's SOUL.MD with the provided markdown. Operator-driven; alternative to -append. Requires: an agent id or address from ethora-agent-list or ethora-agent-create.
No parameter schema on file.
List BotInstances. Filter by appId (caller's App by default) and/or agentId. Requires: at least one invited agent in the app (ethora-agent-invite); otherwise the list is empty.
No parameter schema on file.
Turn a specific BotInstance on or off. Off detaches it from XMPP; on re-spawns the XMPP client live. Setting the state it already has changes nothing. Requires: a bot instance id from ethora-bot-instance-list (instances are created by ethora-agent-invite).
No parameter schema on file.
Delete an Agent (DELETE /v2/agents/:idOrAddress). Destructive — removes the saved Agent and its BotInstances. Gated behind ETHORA_MCP_ENABLE_DANGEROUS_TOOLS. Requires: an agent id or address from ethora-agent-list or ethora-agent-create.
No parameter schema on file.
Export an Agent as a portable bundle (GET /v2/agents/:idOrAddress/export). format=json returns the bundle object directly; feed it back to ethora-agent-import to recreate the Agent in another App/tenant. Requires: an agent id or address from ethora-agent-list or ethora-agent-create.
No parameter schema on file.
Import an Agent from a bundle produced by ethora-agent-export (POST /v2/agents/import, application/json body IS the bundle). Optionally scope the new Agent to an owning App via ownerAppId. Requires: a bundle produced by ethora-agent-export with format json.
No parameter schema on file.
Diagnose a specific BotInstance for an Agent (GET /v2/agents/:idOrAddress/bot-instances/:botInstanceId/diag). Returns live XMPP/ai-service status and recent activity for troubleshooting. Requires: a bot instance id from ethora-bot-instance-list (instances are created by ethora-agent-invite).
No parameter schema on file.
Send a test message from a BotInstance (POST /v2/agents/:idOrAddress/bot-instances/:botInstanceId/test-message). Omit roomJid to fan out to every room the BotInstance is in. Requires the ai-service to be running. Requires: a bot instance id from ethora-bot-instance-list (instances are created by…
No parameter schema on file.
Remove a BotInstance from a chat room (POST /v2/agents/:idOrAddress/bot-instances/:botInstanceId/leave-chat). The inverse of ethora-agent-invite. Requires: a bot instance id from ethora-bot-instance-list (instances are created by ethora-agent-invite).
No parameter schema on file.
Search an App's chat messages (GET /v2/apps/:appId/messages/search). B2B / tenant-actor auth. Filter by room (chatId), author (fromUserId), and time window. Requires: a selected app (ethora-app-select) or an explicit appId.
No parameter schema on file.
Fetch the messages surrounding a target message (GET /v2/apps/:appId/chats/:chatId/messages/context). Provide either aroundStanzaId or aroundMessageId; radius controls how many messages before/after. Requires: a message id from ethora-message-search or ethora-chat-history.
No parameter schema on file.
Batch per-room unread message counts for a set of users (POST /v2/apps/:appId/users/unread-counts). mode=count returns numbers (capped); mode=flag returns booleans. Requires Mongo message archiving enabled on the deployment. Requires: a selected app (ethora-app-select) or an explicit appId.
No parameter schema on file.
Export an App as a portable bundle (GET /v2/apps/:appId/export). format=json returns the bundle object directly. Use include to select sections (e.g. 'chats,users,sources,botInstances'). Feed the result to ethora-app-import. Requires: a selected app (ethora-app-select) or an explicit appId.
No parameter schema on file.
Import an App from a bundle produced by ethora-app-export (POST /v2/apps/import, application/json body IS the bundle). B2B / tenant-actor auth. domainNameOverride renames the imported App's domain. Requires: a bundle produced by ethora-app-export.
No parameter schema on file.
Enable the LEGACY per-app aiBot using app-token or B2B auth. NOTE: clean API/B2B-created apps have no legacy aiBot, so this returns 422 BOT_NOT_INITIALIZED there — use the Agents API (ethora-agent-create + ethora-agent-invite, or ethora-b2b-app-bootstrap-ai) for B2B AI. Valid for apps that…
No parameter schema on file.
Turn the AI bot off for an app (sets bot status: "off") — it stops responding. The configured prompt/LLM/RAG and any activated agent are preserved, so re-enabling restores the same behavior. Requires: an app with a legacy per-app aiBot (dashboard-created). API-created apps have none: use…
No parameter schema on file.
LEGACY: read the per-app bot widget config (GET /v2/bot/widget); only apps that already have a legacy aiBot have one, API-created apps get 422. For the embeddable AI chat widget use ethora-widget-snippet-get instead — the widget config and public widget URL metadata needed to embed the bot on…
No parameter schema on file.
Post a message into a chat room of an app (POST /v2/apps/:appId/chats/broadcast targeting one room). The message is attributed to the app's broadcast sender (override the shown name with senderName). Use it to seed or test a conversation, e.g. right after ethora-agent-invite, and set…
No parameter schema on file.
Read the archived messages of a chat room (GET /v2/apps/:appId/chats/:chatId/messages, newest last). Returns results with from, nick, body, ts (ms) plus a nextBefore cursor for older pages. Identify the room by roomJid (${appId}_${chatId}) or bare chatId plus the selected app.…
No parameter schema on file.
DEPRECATED alias of ethora-message-send (the old /v2/chats/messages automation route no longer exists). Posts a message into a room by roomJid or chatId; prefer ethora-message-send, which also supports waitForReplySec. Requires: an app with a legacy per-app aiBot (dashboard-created).…
No parameter schema on file.
DEPRECATED alias of ethora-chat-history (the old /v2/chats/history automation route no longer exists). Reads a room's archived messages by roomJid or chatId. Requires: an app with a legacy per-app aiBot (dashboard-created). API-created apps have none: use ethora-agent-create ->…
No parameter schema on file.
Dot-namespaced alias for ethora-auth-mode-set — switches the session's active auth mode to B2B (x-custom-token). Behavior is identical. Auth: requires a b2bToken to already be configured. Errors: returns an error if no b2bToken is configured.
No parameter schema on file.
Dot-namespaced alias for ethora-b2b-app-create — create a new Ethora app server-side, allocating a fresh appId. Auth: B2B mode (ethora.b2b.auth.use / ethora-auth-mode-set + a configured b2bToken). Errors: 401/403 not in B2B mode; 422 invalid displayName. Related: prefer…
No parameter schema on file.
Dot-namespaced alias for ethora-bot-enable-b2b — turn on the AI bot for an app (sets botStatus: "on"). The bot only responds if a prompt + LLM are configured and the backend has an AI service. Auth: B2B mode (ethora.b2b.auth.use / ethora-auth-mode-set + a configured b2bToken). Errors:…
No parameter schema on file.
Dot-namespaced sibling of ethora-broadcast-job-wait — block until a broadcast job reaches a terminal state (completed / failed) or timeoutMs. Read-only polling. Returns { done, state, job }, or { done: false, reason: "timeout" } on timeout. Auth: app-token mode (despite b2b in the…
No parameter schema on file.
Dot-namespaced alias for ethora-b2b-app-bootstrap-ai — one-call B2B orchestrator: create an app, index RAG sources, then configure and enable its AI bot. Source ingest and bot activation are best-effort (the app is still created if a later step fails). Returns a per-step log including the new…
No parameter schema on file.
One-call B2B orchestrator: create an app, set it as the current context, index RAG sources, then configure and enable its AI bot. Source ingest and bot activation are best-effort (the app is still created if a later step fails); crawl/embedding continues asynchronously after this returns. Returns…
No parameter schema on file.
Generate a ready-to-paste React App.tsx snippet that mounts @ethora/chat-component. Returns { filename: "App.tsx", snippet }; unpassed values are emitted as placeholders. Does not write any file. Get the appToken from ethora-app-credentials-reveal { appId, confirm: true } (other tools…
No parameter schema on file.
Generate .env.example templates for the three common Ethora integration targets: the frontend chat component, the backend SDK, and this MCP server. Returns { target, template } when target is given, or { templates } with all three. Placeholder values only; does not write any file. Auth:…
No parameter schema on file.
Generate a human-readable runbook listing this server's tool calls in the right order for a B2B bootstrap, with example payloads. Documentation only — does not write any file or execute any step. Auth: none required — pure text generator, no API calls. Errors: effectively none. Related: to…
No parameter schema on file.
Crawl a website URL and ingest its content into an app's RAG sources (app-token / B2B variant of ethora-sources-site-crawl). Async — returns once the job is accepted; followLink: true follows in-domain links and can ingest many pages. Requires: a selected app (ethora-app-select) or an…
No parameter schema on file.
Re-crawl and re-embed a previously crawled URL by its urlId, refreshing its RAG content (app-token / B2B variant of ethora-sources-site-reindex). Async — the existing source record is updated in place once indexing finishes. Requires: an indexed site URL from ethora-source-site-list (crawled…
No parameter schema on file.
Crawl a website URL and wait for the crawl to finish: enqueues the job, then polls it until it reports completed or failed. Returns { done, status, jobId, polls, durationMs, result }; done: false with a note means the budget ran out while the job was still running (it usually finishes…
No parameter schema on file.
Re-crawl and re-embed a previously crawled URL and wait for it to finish: enqueues the job, then polls it until it reports completed or failed. Returns { done, status, jobId, polls, durationMs, result }; done: false with a note means the budget ran out while the job was still running.…
No parameter schema on file.
List an app's crawled website sources, including each source's id, URL, and current RAG tags. Their ids feed ethora-source-site-tags-update, ethora-source-site-url-delete-batch, and ethora-source-site-reindex. Requires: a selected app (ethora-app-select) or an explicit appId. Auth:…
No parameter schema on file.
Set the RAG retrieval tags on a crawled website source — replaces the source's tag set with the provided tags array (not additive; pass [] to clear all). Tags let the bot's ragTags narrow retrieval. Requires: an indexed site URL from ethora-source-site-list (crawled with…
No parameter schema on file.
Provision many Ethora users (1–100) in one asynchronous batch job — the bulk equivalent of ethora-user-register. Enqueues a background job (HTTP 202); the job reports per-user conflicts rather than failing the whole batch. Returns { jobId, statusUrl }. Auth: B2B mode (ethora-auth-mode-set +…
No parameter schema on file.
Fetch the current status and per-user results of a users batch job by jobId (one-shot, no polling). Returns the job object with its state (pending/running/completed/failed) and per-user outcomes. Requires: a jobId returned by ethora-user-batch-create. Auth: B2B mode (ethora-auth-mode-set…
No parameter schema on file.
Block until a users batch job reaches a terminal state (completed or failed) or timeoutMs — read-only polling wrapper around ethora-user-batch-job-start. Returns { done, state, job }, or { done: false, reason: "timeout" } on timeout. Requires: a jobId returned by…
No parameter schema on file.
List the app tokens issued for an app — metadata only (tokenId, label, created/rotated timestamps, status); the secret token values are never returned (only shown once at create/rotate time). Auth: B2B mode (ethora-auth-mode-set + a configured b2bToken). Errors: 401/403 not in B2B mode; 400…
No parameter schema on file.
Mint a new app token for an app. The secret token value is returned exactly once and cannot be retrieved again — capture it immediately. Returns the new token including its one-time secret value and tokenId. Auth: B2B mode (ethora-auth-mode-set + a configured b2bToken). Errors: 401/403 not…
No parameter schema on file.
Rotate an app token: revoke an existing token and issue a replacement in one step. The old tokenId is revoked immediately — anything using it stops working at once. The new secret value is returned exactly once — capture it immediately. Requires: a token id from ethora-app-token-list. Auth:…
No parameter schema on file.
Permanently revoke an app token by tokenId — it stops working immediately; any client, SDK, or MCP session still using it gets auth failures. No replacement is issued. Requires: a token id from ethora-app-token-list. Auth: B2B mode (ethora-auth-mode-set + a configured b2bToken). Errors:…
No parameter schema on file.
One-call B2B orchestrator: create an app, mint one or more app tokens, provision default chat rooms, then configure and enable its AI bot. Later-step failures don't undo earlier steps. Returns a per-step log including appId and the created tokens (returned once — capture them). Auth: B2B mode…
No parameter schema on file.
Remove a single crawled URL from an app's RAG sources, matched by its exact url string (app-token / B2B variant of ethora-sources-site-delete-url). Deletes the source record and its embeddings; not reversible. Matches on the exact stored URL string. Requires: an indexed site URL from…
No parameter schema on file.
Bulk-remove crawled website sources (1–100) from an app in one call, matched by their source record ids. Deletes each matching record and its embeddings; not reversible. Ids not present are skipped. Requires: an indexed site URL from ethora-source-site-list (crawled with…
No parameter schema on file.
Upload documents (1–5; PDF, text, etc.) into an app's RAG sources (app-token / B2B variant of ethora-source-doc-upload-legacy). Async — content becomes queryable once indexing finishes; files passed as base64, 50MB max each. Requires: a selected app (ethora-app-select) or an explicit appId.…
No parameter schema on file.
Remove a previously ingested document from an app's RAG sources by docId (app-token / B2B variant of ethora-source-doc-delete-legacy). Deletes the document record and its embeddings; not reversible. Requires: a document id from ethora-source-doc-list. Auth: app-token mode OR B2B mode with an…
No parameter schema on file.
List an app's ingested documents, including each document's id, name, and current RAG tags. Their ids feed ethora-source-doc-tags-update and ethora-source-doc-delete. Requires: a selected app (ethora-app-select) or an explicit appId. Auth: app-token mode OR B2B mode with an explicit…
No parameter schema on file.
Set the RAG retrieval tags on an ingested document — replaces the document's tag set with the provided tags array (not additive; pass [] to clear all). Tags let the bot's ragTags narrow retrieval. Requires: a document id from ethora-source-doc-list. Auth: app-token mode OR B2B mode with an…
No parameter schema on file.
Generate the <script> tag that embeds the Ethora AI chat widget (the floating launcher + chat panel that website visitors use) for an app, plus the prerequisites that must hold before it answers. No API call; pure generator using this deployment's hosted widget URL and public API base. The widget…
No parameter schema on file.
Search the Ethora documentation and tool reference: auth model (app JWT vs app token vs B2B token vs API keys), hosted-server getting started, chat-component and backend SDK quickstarts, recipes, and a reference entry for every tool with its inputs. Use it for any "how do I ..." question about…
No parameter schema on file.
Fetch the full text of a documentation section or tool reference entry by the id returned from search (e.g. tool:ethora-app-create, doc:auth-map#app-jwt, doc:hosted-guide). Auth: none required. Errors: unknown id.
No parameter schema on file.
No parameter schema on file.
Execute a built-in recipe — an ordered sequence of this server
No parameter schema on file.
Switch this session
No parameter schema on file.
Switch this session
No parameter schema on file.
Switch this session
No parameter schema on file.
Enqueue an asynchronous broadcast job posting a message to one or more chat rooms of an app — returns a
No parameter schema on file.
Fetch the current status and per-room results of a broadcast job by
No parameter schema on file.
Block until a broadcast job reaches a terminal state (
No parameter schema on file.
Upload 1–5 files to the authenticated user
No parameter schema on file.
List the authenticated user
No parameter schema on file.
Permanently delete one of the authenticated user
No parameter schema on file.
Upload documents (1–5; PDF, text, etc.) into an app
No parameter schema on file.
Remove a previously ingested document from an app
No parameter schema on file.
List the default chat rooms (MUC rooms) of the currently selected Ethora app — every new user auto-joins these. Returns rooms with their JIDs and titles. Auth: user-auth mode, active session; operates against the app set via
No parameter schema on file.
List the default chat rooms of a specific Ethora app, passed via
No parameter schema on file.
Create a new chat room (MUC room) inside an app the caller owns. If
No parameter schema on file.
No parameter schema on file.
Read the authenticated user
No parameter schema on file.
Enable the LEGACY per-app aiBot (B2B auth). NOTE: apps created via the API/B2B no longer auto-provision a legacy aiBot, so this returns 422 BOT_NOT_INITIALIZED on a clean app. The forward path for B2B AI is the Agents API — use
No parameter schema on file.
Read the current AI bot configuration for an app: status, trigger, prompt, greeting, LLM provider/model, RAG settings, widget config. Auth: app-token mode OR B2B mode with an explicit
No parameter schema on file.
Configure the AI bot for an app — prompt, LLM, trigger, greeting, RAG behavior, identity, and public widget settings. Partial update — omitted fields are left unchanged.
No parameter schema on file.
List the reusable saved agents owned by the current app (
No parameter schema on file.
Fetch one reusable saved agent
No parameter schema on file.
No parameter schema on file.
Update a saved AI agent (PUT /v2/agents/:agentId). All fields are optional — only what you pass is updated. Common uses: tune the system
No parameter schema on file.
Duplicate an existing saved agent into a new agent, optionally overriding its name/slug/summary (
No parameter schema on file.
Bind a saved agent as the active AI bot for the current app — copies the agent
No parameter schema on file.
Set an Agent
No parameter schema on file.
No parameter schema on file.
List BotInstances. Filter by appId (caller
No parameter schema on file.
Turn a specific BotInstance on or off. Off detaches it from XMPP; on re-spawns the XMPP client live.
No parameter schema on file.
Delete an Agent (DELETE /v2/agents/:idOrAddress). Destructive — removes the saved Agent and its BotInstances. Gated behind ETHORA_ENABLE_DANGEROUS_TOOLS.
No parameter schema on file.
Export an Agent as a portable bundle (GET /v2/agents/:idOrAddress/export). format=json returns the bundle object directly; feed it back to
No parameter schema on file.
Import an Agent from a bundle produced by
No parameter schema on file.
Diagnose a specific BotInstance for an Agent (GET /v2/agents/:idOrAddress/bot-instances/:botInstanceId/diag). Returns live XMPP/ai-service status and recent activity for troubleshooting.
No parameter schema on file.
Send a test message from a BotInstance (POST /v2/agents/:idOrAddress/bot-instances/:botInstanceId/test-message). Omit roomJid to fan out to every room the BotInstance is in. Requires the ai-service to be running.
No parameter schema on file.
Remove a BotInstance from a chat room (POST /v2/agents/:idOrAddress/bot-instances/:botInstanceId/leave-chat). The inverse of
No parameter schema on file.
Search an App
No parameter schema on file.
Fetch the messages surrounding a target message (GET /v2/apps/:appId/chats/:chatId/messages/context). Provide either aroundStanzaId or aroundMessageId; radius controls how many messages before/after.
No parameter schema on file.
Batch per-room unread message counts for a set of users (POST /v2/apps/:appId/users/unread-counts). mode=count returns numbers (capped); mode=flag returns booleans. Requires Mongo message archiving enabled on the deployment.
No parameter schema on file.
Export an App as a portable bundle (GET /v2/apps/:appId/export). format=json returns the bundle object directly. Use
No parameter schema on file.
Import an App from a bundle produced by
No parameter schema on file.
Enable the LEGACY per-app aiBot using app-token or B2B auth. NOTE: clean API/B2B-created apps have no legacy aiBot, so this returns 422 BOT_NOT_INITIALIZED there — use the Agents API (
No parameter schema on file.
Turn the AI bot off for an app (sets bot
No parameter schema on file.
Read the public chat-widget / embed configuration for the current app
No parameter schema on file.
Send a message through the app
No parameter schema on file.
Read the persisted message history of a chat automation session — the conversation produced by
No parameter schema on file.
Compatibility alias for
No parameter schema on file.
Compatibility alias for
No parameter schema on file.
Generate a ready-to-paste React
No parameter schema on file.
Generate
No parameter schema on file.
Generate a human-readable runbook listing this server
No parameter schema on file.
Crawl a website URL and ingest its content into an app
No parameter schema on file.
Re-crawl and re-embed a previously crawled URL by its
No parameter schema on file.
Crawl a website URL and block until the server finishes — a single-call, long-timeout variant of
No parameter schema on file.
Re-crawl and re-embed a previously crawled URL and block until the server finishes — a single-call, long-timeout variant of
No parameter schema on file.
List an app
No parameter schema on file.
Set the RAG retrieval tags on a crawled website source — replaces the source
No parameter schema on file.
Provision many Ethora users (1–100) in one asynchronous batch job — the bulk equivalent of
No parameter schema on file.
- Every tool, no call limit
- No card, and mcprush charges nothing for it
- Source published under MIT
- Runs on your machine — nothing of it reaches our gateway
- Nothing to cap, because mcprush bills nothing
What counts against your monthly calls
| Tool | Unit | Calls used | Out of the allowance |
|---|
Nothing here is billable: mcprush charges nothing to install Ethora or to call it, at any volume.
Two independent axes, because powerful and malicious are different questions. The grade is threat only. The capability level is blast radius, and it is never a penalty on the grade — it is priced as one subtract-only term in the score, where you can see it.
| Term | Level | What it prices | Points |
|---|---|---|---|
| capability-exposure | moderate | capability blast radius (moderate) — client exposure if the model is manipulated | −3 |
| verification-discount | repo | publisher verification (public source) — no provenance, but the source is public and inspectable | −1 |
| coverage-honesty | source | inspection depth (source) — how much of the target the scan could see | −0 |
What the scan could actually read
A grade is only as meaningful as its coverage, so the scanner publishes its own depth before it publishes its result.
Tools were statically extracted from the published source (99 recovered), not enumerated from a running server. Tool-poisoning, Unicode-smuggling, capability and toxic-flow analysis ran on this inferred surface, but a mis-parsed registration could be missed or mis-attributed, so tool-derived findings are capped below “confirmed”. To grade the real runtime surface, scan the running server: --command "npx -y <package>".
4 of the 99 recovered tools are registered only when isDangerousToolsEnabled() holds (dist/tools.js:4123) — typically when a key or option is configured. They are part of the server's surface and were analysed; a server started without that configuration exposes only the other 88.
7 of the 99 recovered tools are registered only when isAliasesEnabled() holds (dist/tools.js:4165) — typically when a key or option is configured. They are part of the server's surface and were analysed; a server started without that configuration exposes only the other 88.
Capability — what it could do if the model were manipulated
Tags derived from each tool’s schema and the implementation, not from what the tool calls itself. moderate is the level these add up to.
88 tools are registered unconditionally · (1) 4 more only when isDangerousToolsEnabled() holds (dist/tools.js:4123) · (2) 7 more only when isAliasesEnabled() holds (dist/tools.js:4165) — typically when a key or option is configured. All 99 are in the table below and were analysed; the conditional ones are marked.
| Tool | Capability tags | Why the tag was assigned |
|---|---|---|
| search | no tags | |
| fetch | untrusted-input | untrusted-input: keyword "fetch" |
| ethora-tools-enable | state-write | state-write: declares readOnlyHint: false |
| ethora-session-configure | state-write | state-write: declares readOnlyHint: false |
| ethora-status | no tags | |
| ethora-help | no tags | |
| ethora-recipe-run | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-doctor | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-auth-mode-set | state-write | state-write: declares readOnlyHint: false |
| ethora-app-select | state-write | state-write: declares readOnlyHint: false |
| ethora-agent-select | state-write | state-write: declares readOnlyHint: false |
| ethora-broadcast-send | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-broadcast-job-start | untrusted-input | untrusted-input: keyword "fetch", declares openWorldHint: true (interacts with entities outside the server) |
| ethora-broadcast-job-wait | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-file-upload | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-file-get | untrusted-input | untrusted-input: keyword "fetch", declares openWorldHint: true (interacts with entities outside the server) |
| ethora-file-delete | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| ethora-source-doc-upload-legacy | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-source-doc-delete-legacy | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| ethora-user-login | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-user-register | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-feedback-submit | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-app-credentials-reveal | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-api-key-create | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-api-key-list | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-api-key-revoke | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| ethora-app-list | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-app-create | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-app-delete conditional (1) | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| ethora-app-update | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-app-rooms-list | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-chat-create | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-chat-delete | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| ethora-wallet-balance-get | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-wallet-erc20-transfer conditional (1) | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| ethora-b2b-app-create | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-bot-enable-b2b | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-bot-get | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-bot-update | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-agent-list | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-agent-get | untrusted-input | untrusted-input: keyword "fetch", declares openWorldHint: true (interacts with entities outside the server) |
| ethora-agent-create | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-agent-update | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-agent-clone | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-agent-activate | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-agent-visibility-set | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-agent-invite | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-agent-soul-append | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-agent-soul-set | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-bot-instance-list | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-bot-instance-status-set | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-agent-delete conditional (1) | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| ethora-agent-export | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-agent-import | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-bot-instance-diagnose | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-bot-instance-test | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-bot-instance-leave | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| ethora-message-search | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-message-context | untrusted-input | untrusted-input: keyword "fetch", declares openWorldHint: true (interacts with entities outside the server) |
| ethora-chat-unread-counts | untrusted-input | untrusted-input: keyword "read_message", declares openWorldHint: true (interacts with entities outside the server) |
| ethora-app-export | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-app-import | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-bot-enable | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-bot-disable | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-bot-widget-get | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-message-send | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-chat-history | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-bot-message-send conditional (2) | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-bot-history conditional (2) | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora.b2b.auth.use conditional (2) | state-write | state-write: declares readOnlyHint: false |
| ethora.b2b.app.create conditional (2) | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora.b2b.bot.enable conditional (2) | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora.b2b.broadcast.wait conditional (2) | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora.b2b.app.bootstrap-ai conditional (2) | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-b2b-app-bootstrap-ai | untrusted-inputexternal-sink | untrusted-input: keyword "crawl"; external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-chat-component-app-generate | no tags | |
| ethora-env-examples-generate | no tags | |
| ethora-b2b-runbook-generate | no tags | |
| ethora-source-site-crawl | untrusted-inputexternal-sink | untrusted-input: keyword "crawl"; external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-source-site-reindex | untrusted-inputexternal-sink | untrusted-input: keyword "crawl"; external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-source-site-crawl-wait | untrusted-inputexternal-sink | untrusted-input: keyword "crawl"; external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-source-site-reindex-wait | untrusted-inputexternal-sink | untrusted-input: keyword "crawl"; external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-source-site-list | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-source-site-tags-update | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-user-batch-create | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-user-batch-job-start | untrusted-input | untrusted-input: keyword "fetch", declares openWorldHint: true (interacts with entities outside the server) |
| ethora-user-batch-job-wait | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-app-token-list | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-app-token-create | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-app-token-rotate | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| ethora-app-token-revoke | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| ethora-b2b-app-provision | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-source-site-url-delete | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| ethora-source-site-url-delete-batch conditional (1) | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| ethora-source-doc-upload | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-source-doc-delete | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| ethora-source-doc-list | untrusted-input | untrusted-input: declares openWorldHint: true (interacts with entities outside the server) |
| ethora-source-doc-tags-update | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| ethora-widget-snippet-get | no tags |
Toxic-flow graph
The lethal trifecta, checked as a graph rather than as a checklist: untrusted input, a sensitive source and an external sink have to meet before there is a path worth worrying about.
Supply chain and provenance
This is the first scan of this surface here, so there is nothing yet to compare it against.
Every result on this tab comes from one deterministic pass over the published package — offline, rule by rule, and auditable line by line above. Same methodology version, same bytes, same score.
Release history
Always latest — the install command names no version, so it installs the newest release when it runs; the current release on file is 26.10.0. Pin a release below and the command asks for exactly that one.
No release note was published with this version.
No release note was published with this version.
No release note was published with this version.
No release note was published with this version.
- The version this listing was on when mcprush began following its releases. The registry was not asked when it shipped, so this row carries no date.
One review per account, from a signed-in account that does not publish this listing. Nothing else is asked — you can say what you think before you install it. Publishers can reply once per review, and a review can be edited or deleted by whoever wrote it.
Any signed-in account that does not publish Ethora can review it, once — before installing it or after. A review from an account that has installed it is marked as one.
Nobody has reviewed this listing. The rating on the card is the mean of the reviews written here and nothing else, so there is no rating until somebody writes the first — which takes a signed-in account that does not publish it, and nothing else.