# io.github.dappros/ethora-mcp-cli (npm · @ethora/mcp-server)

MCP server for the Ethora chat & messaging platform: chat ops, AI agents, RAG, automation.

- Trust score: 64/100 (medium)
- Change this week: −10
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- npm · `@ethora/mcp-server`: 64/100 (this document), [markdown](https://verifymcp.io/servers/dappros-ethora-mcp-cli/ethora-mcp-server.md), [page](https://verifymcp.io/servers/dappros-ethora-mcp-cli/ethora-mcp-server)

## Channel facts

- Registry: `npm`
- Package: `@ethora/mcp-server`
- Version: `26.5.2`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-03.

- **Supply Chain Security**: 87/100
  - No malware found by supply-chain analysis.
  - Only part of the dependency tree could be resolved (108 of 109), so this covers what we could see, not the whole tree.
  - No install/post-install scripts declared.
  - Only part of the dependency tree could be resolved (108 of 109), so this covers what we could see, not the whole tree.
- **Provenance & Transparency**: 19/100
  - Repository check failed: the declared repository URL redirects; it must resolve directly.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (ISC).
  - Actively maintained (last published 80 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 77/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 21110 tokens (~263/item across 80 items; 76 tools + 4 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add dappros-ethora-mcp-cli -- npx -y @ethora/mcp-server
```

### Codex

```bash
codex mcp add dappros-ethora-mcp-cli -- npx -y @ethora/mcp-server
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "dappros-ethora-mcp-cli": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "@ethora/mcp-server"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add dappros-ethora-mcp-cli --command npx --arg -y --arg @ethora/mcp-server
```

### Hermes

```yaml
mcp_servers:
  dappros-ethora-mcp-cli:
    command: "npx"
    args: ["-y", "@ethora/mcp-server"]
```

### Other

```json
{
  "mcpServers": {
    "dappros-ethora-mcp-cli": {
      "command": "npx",
      "args": [
        "-y",
        "@ethora/mcp-server"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-03 (score 64, +4)

- [functional improvement] Stability: unverified → 0.27

### 2026-08-02 (score 60, −4)

No change was recorded against any check on this day. Supply Chain Security went from 98 to 87.

### 2026-08-01 (score 64, +64)

- [security regression] Provenance: unverified → fail
- [security improvement] Malware scan: unverified → pass
- [security improvement] Install scripts: unverified → pass
- [security improvement] Known CVEs: unverified → partial
- [security] Stability: Stability not yet verified: not enough scan history yet (needs a 30-day window).
- [functional improvement] Tool coverage: unverified → 100
- [functional improvement] License: unverified → pass
- [functional improvement] Schema quality: unverified → 100
- [functional improvement] Dependency health: unverified → partial
- [functional improvement] Maintenance: unverified → pass
- [functional improvement] MCP protocol: unverified → pass
- [functional] Licence: ISC

### 2026-07-31 (score 0, −4)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 4, −70)

- [security regression] Provenance: fail → unverified
- [security regression] Install scripts: pass → unverified
- [security regression] Malware scan: pass → unverified
- [security regression] Known CVEs: partial → unverified
- [functional regression] License: pass → unverified
- [functional regression] Tool coverage: 100 → unverified
- [functional regression] Schema quality: 100 → unverified
- [functional regression] Maintenance: pass → unverified
- [functional] Licence: ISC

### 2026-07-27 (score 74, +42)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-26 (score 32)

First indexed and scored.

## MCP tools (76)

### `ethora-configure` (~368 tokens)

Set the Ethora API URL and credentials for this MCP session.

Auth: none required — this is the tool that establishes auth material.
Side effects: stores values **in memory only**, scoped to this MCP process; nothing is written to disk and the values reset when the server restarts. Each call merges — fields you omit keep their previous value. An alternative to setting the same values via env vars (ETHORA_API_URL / ETHORA_APP_JWT / ETHORA_APP_TOKEN / ETHORA_B2B_TOKEN).
Idempotent: yes.
Failure modes: rarely fails; returns an error only if a value is structurally invalid.
Returns: the resulting (redacted) client state. Follow with `ethora-status` to confirm, `ethora-doctor` to test connectivity, then an `ethora-auth-use-*` tool to pick the active mode.

Input parameters:

- `apiUrl` (string): Full Ethora API URL including the version path, e.g. `https://api.chat.ethora.com/v1` or `http://localhost:8080/v1`. If you only have the host, set ETHORA_BASE_URL env instead and the server appends…
- `appJwt` (string): Ethora App JWT, used only to bootstrap login/register in user-auth mode. Usually starts with `JWT `. Secret — never commit it.
- `appToken` (string): Per-app appToken for app-scoped flows (broadcast, sources, bot). Setting this makes app-token auth available via `ethora-auth-use-app`. Secret.
- `b2bToken` (string): B2B server token for tenant-actor `x-custom-token` auth (a JWT with `type=server`). Required for B2B provisioning flows. Secret.

### `ethora-status` (~136 tokens)

Report the current Ethora MCP session state: configured API URL, active auth mode, which credentials are present, and the currently selected appId/agentId.

Auth: none required.
Side effects: none — read-only.
Idempotent: yes.
Failure modes: effectively none.
Returns: a state object with booleans like `hasAppJwt` / `hasB2BToken` / `hasUserToken` (credential *values* are never echoed back). Use it to decide which `ethora-auth-use-*` tool to call next, or run `ethora-doctor` for an active connectivity check.

### `ethora-help` (~166 tokens)

Task-oriented orientation for this MCP server: explains the three Ethora auth modes (user / app-token / B2B) and recommends the next tool calls + one-click recipes based on the current session state.

Auth: none required — inspects state, makes no API calls.
Side effects: none — read-only.
Idempotent: yes; recommendations change only as the session state changes.
Failure modes: effectively none.
When to use: call this first if you're unsure which auth mode or tool sequence fits your goal. To then run a recommended sequence, pass its recipe id to `ethora-run-recipe`.

Input parameters:

- `goal` (string): Goal hint to tailor the recommendations and recipe list. Omit or use `auto` to get recommendations inferred from the current session state.

### `ethora-run-recipe` (~394 tokens)

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, etc.).

Auth: depends on the recipe's steps; each step uses whatever auth mode/credentials it needs, so configure those first (see `ethora-help` for the right recipe + prerequisites).
Side effects: runs entirely in-process — **no shell, no file writes**. Real side effects come only from the underlying tool steps (which may create apps, send messages, etc.). Use `dryRun: true` to preview the resolved steps without executing any of them.
Idempotent: only as idempotent as the steps it runs — a recipe that calls `ethora-app-create` is not idempotent.
Failure modes: stops at the first failing step and returns what completed plus the error; a missing required `vars` entry fails fast before any step runs.
Returns: per-step results. Omit `recipeId` to list the runnable recipes for the given `goal` (or `goal: "auto"`).

Input parameters:

- `dryRun` (boolean): If true, resolve and return the step list with `vars` substituted but execute nothing. Use this to preview a recipe before running it for real.
- `goal` (string): Goal scope used to look up recipes when `recipeId` is omitted. Defaults to `auto`.
- `recipeId` (string): Id of the recipe to run. Omit to instead list the runnable recipes for the selected `goal` (get ids from `ethora-help`).
- `vars` (object): Key/value substitutions injected into recipe steps (e.g. appId, appToken, b2bToken, appJwt, email, password, apiUrl). A recipe declares which vars it requires; missing required vars fail the run befo…

### `ethora-doctor` (~194 tokens)

Diagnose the session: validate that the config is internally consistent for the active auth mode and actively ping the Ethora API.

Auth: none required, but the report is tailored to whatever auth mode/credentials are currently set.
Side effects: makes one real network call — `GET /v1/ping` against the configured API URL. No state is changed.
Idempotent: yes.
Failure modes: the tool itself rarely throws; instead it returns `suggestions` for misconfigurations and a `ping.ok: false` block (with the error) when the API is unreachable.
Returns: `{ state, checks, ping, suggestions }`. Run this after `ethora-configure` to confirm everything is wired up before attempting real operations.

Input parameters:

- `timeoutMs` (integer): HTTP timeout in milliseconds for the ping request. Defaults to 3000. Raise it on slow links, lower it to fail fast.

### `ethora-auth-use-app` (~174 tokens)

Switch this session's active auth mode to app-token, so subsequent app-scoped calls authenticate with the configured `appToken`.

Auth: requires an `appToken` to already be configured (via `ethora-configure`, the ETHORA_APP_TOKEN env var, or `ethora-app-select` with an `appToken`).
Side effects: changes session state only (the active auth mode); no API call, no server-side change.
Idempotent: yes.
Failure modes: returns an error if no `appToken` is configured — set one first.
When to use: after `ethora-app-select` when you want app-scoped convenience routes (`/v2/...` resolved against the selected app). For explicit tenant-actor routes use `ethora-auth-use-b2b` instead.

### `ethora-auth-use-user` (~156 tokens)

Switch this session's active auth mode to user-session, so subsequent calls authenticate as a logged-in Ethora user.

Auth: switching the mode itself needs nothing, but user-auth tools only work once `ethora-user-login` has stored a user token. Login also requires a configured `appJwt`.
Side effects: changes session state only; no API call, no server-side change.
Idempotent: yes.
Failure modes: none on the switch itself; downstream user-auth tools return 401 until `ethora-user-login` succeeds.
When to use: first-time local/manual use — switch to this mode, then call `ethora-user-login`. For repeatable automation prefer `ethora-auth-use-b2b`.

### `ethora-auth-use-b2b` (~209 tokens)

Switch this session's active auth mode to B2B, so subsequent calls authenticate as a tenant actor via the `x-custom-token` header.

Auth: requires a `b2bToken` to already be configured (via `ethora-configure` or the ETHORA_B2B_TOKEN env var) — a JWT with `type=server`.
Side effects: changes session state only; no API call, no server-side change.
Idempotent: yes.
Failure modes: returns an error if no `b2bToken` is configured — set one first.
When to use: server-side automation and partner provisioning. B2B tools take an explicit `appId` (or use the one from `ethora-app-select`). Pairs with `ethora-b2b-app-create`, `ethora-b2b-app-bootstrap-ai`, `ethora-users-batch-create-v2`, and the `ethora-app-tokens-*-v2` tools.

### `ethora-app-select` (~312 tokens)

Set the current app context for this session so app-scoped tools can omit their `appId` argument.

Auth: none required to set the context; the tools you then call still need their own auth mode.
Side effects: session state only — stores `currentAppId` and, if given, `appToken`. If `appToken` is supplied the active auth mode defaults to app-token unless `authMode` overrides it. No API call, no server-side change.
Idempotent: yes — calling again just overwrites the selection.
Failure modes: effectively none; passing an `appId` that doesn't exist is not validated here — the first app-scoped API call will surface the 404.
When to use: once per app you're working with, before broadcast/sources/bot/agents tools. Pairs with `ethora-auth-use-app`.

Input parameters:

- `appId` (string, required): 24-char hex Ethora appId to set as the current context. Get it from `ethora-app-list`, `ethora-app-create`, or a B2B create/provision response.
- `appToken` (string): Per-app appToken to store alongside the appId. If provided, the active auth mode switches to app-token (unless `authMode` says otherwise). Secret.
- `authMode` (string): Auth mode to keep after selecting the app. Omit to let the mode default to app-token when an `appToken` is given, or stay unchanged otherwise.

### `ethora-chats-broadcast-v2` (~384 tokens)

Enqueue an asynchronous broadcast job that posts a message to one or more chat rooms of an app.

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`) OR B2B mode with an explicit `appId`.
Side effects: creates a background job on the server and returns immediately with a `jobId` — the messages are **not** sent synchronously. Targeting is exclusive: pass `allRooms: true`, or a `chatIds` list, or a `chatNames` list — not a mix.
Idempotent: no — each call enqueues a new job; calling twice broadcasts twice.
Failure modes: 401/403 on missing/wrong auth; 400 if no target is specified or targets conflict; 404 if `appId` or a target room doesn't exist.
Returns: `{ jobId, ... }`. Track it with `ethora-chats-broadcast-job-v2` (one-shot status) or `ethora-wait-broadcast-job-v2` (poll to completion).

Input parameters:

- `allRooms` (boolean): If true, broadcast to every room in the app. Mutually exclusive with `chatIds` and `chatNames`.
- `appId` (string): 24-char hex appId to broadcast in. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode (the token determines the app).
- `chatIds` (array): Explicit list of chat ids to target. Mutually exclusive with `allRooms` and `chatNames`.
- `chatNames` (array): Explicit list of chat JIDs or localparts to target. Mutually exclusive with `allRooms` and `chatIds`.
- `text` (string, required): Plain-text message body to broadcast to the targeted rooms.

### `ethora-chats-broadcast-job-v2` (~224 tokens)

Fetch the current status and results of a broadcast job by `jobId` (one-shot, no polling).

Auth: app-token mode OR B2B mode with an explicit `appId` — must match the auth used to enqueue the job.
Side effects: none — read-only.
Idempotent: yes.
Failure modes: 401/403 on missing/wrong auth; 404 if the `jobId` is unknown for this app.
Returns: the job object including its `state` (`pending` / `running` / `completed` / `failed`) and per-room results. For a blocking wait-until-done, use `ethora-wait-broadcast-job-v2` instead of polling this yourself.

Input parameters:

- `appId` (string): 24-char hex appId the job belongs to. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode.
- `jobId` (string, required): Job id returned by `ethora-chats-broadcast-v2`.

### `ethora-wait-broadcast-job-v2` (~315 tokens)

Block until a broadcast job reaches a terminal state (`completed` or `failed`), or until a timeout — a convenience wrapper around repeated `ethora-chats-broadcast-job-v2` calls.

Auth: app-token mode OR B2B mode with an explicit `appId` — must match the auth used to enqueue the job.
Side effects: none server-side — read-only polling. Blocks this MCP call for up to `timeoutMs`.
Idempotent: yes.
Failure modes: 401/403 on missing/wrong auth; 404 if the `jobId` is unknown.
Returns: `{ done: true, state, job }` when the job finished, or `{ done: false, reason: "timeout", job }` if `timeoutMs` elapsed first (the job may still finish later — re-check with `ethora-chats-broadcast-job-v2`).

Input parameters:

- `appId` (string): 24-char hex appId the job belongs to. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode.
- `intervalMs` (integer): Delay between status checks, in milliseconds. Default 1000. Lower = more responsive but more API calls.
- `jobId` (string, required): Job id returned by `ethora-chats-broadcast-v2`.
- `timeoutMs` (integer): Maximum time to wait, in milliseconds. Default 60000. Caps at 300000 (5 min).

### `ethora-files-upload-v2` (~223 tokens)

Upload one or more files to the authenticated user's Ethora file storage (`POST /v2/files`).

Auth: user-auth mode with an active user session (`ethora-user-login` first).
Side effects: creates file records server-side owned by the logged-in user; each upload is a new record (no overwrite-by-name).
Idempotent: no — re-uploading creates duplicate records.
Input design: files are passed as base64 so the MCP server never touches your local filesystem. Client-side guardrail rejects any single file over 50MB before upload; the Ethora server enforces its own limits too.
Failure modes: 401 if not logged in; 413 if the server's size limit is exceeded; 422 on an unsupported mime type. Per-call limit: 1–5 files.
Returns: the created file records (with ids). Manage them with `ethora-files-get-v2` and `ethora-files-delete-v2`.

Input parameters:

- `files` (array, required): 1 to 5 files to upload in this call.

### `ethora-files-get-v2` (~153 tokens)

List the authenticated user's files, or fetch one file's metadata by id (`GET /v2/files`).

Auth: user-auth mode with an active user session.
Side effects: none — read-only.
Idempotent: yes.
Failure modes: 401 if not logged in; 404 if a specific `id` is given but not found / not owned by the user.
Returns: an array of file records when `id` is omitted, or a single record when `id` is given. Use the ids with `ethora-files-delete-v2`.

Input parameters:

- `id` (string): File id to fetch a single record. Omit to list all files owned by the logged-in user.

### `ethora-files-delete-v2` (~142 tokens)

Permanently delete one of the authenticated user's files by id (`DELETE /v2/files/:id`).

Auth: user-auth mode with an active user session.
Side effects: removes the file record and its stored content. Not reversible.
Idempotent: yes after success — a second call returns 404.
Failure modes: 401 if not logged in; 403 if the file is not owned by the user; 404 if the `id` does not exist.
Get ids from `ethora-files-get-v2`.

Input parameters:

- `id` (string, required): Id of the file to delete. Get it from `ethora-files-get-v2`.

### `ethora-sources-site-crawl` (~332 tokens)

Crawl a website URL and ingest its content into an app's RAG sources, so the app's AI bot can answer from it (legacy user-auth route).

Auth: user-auth mode with an active user session; the user must own the app.
Side effects: starts a crawl + embedding job on the server; pages become queryable RAG context once indexing finishes (not synchronous). With `followLink: true` the crawler also follows in-domain links, which can ingest many pages.
Idempotent: no — re-crawling the same URL adds/updates source records; combined with `followLink` it can fan out broadly.
Failure modes: 401 if not logged in; 403 if the user doesn't own the app; 400 if `url` is malformed; 404 if `appId` is invalid.
Related: `ethora-sources-site-reindex` (refresh), `ethora-sources-site-delete-url` (remove), `ethora-sources-docs-upload` (ingest documents instead of a URL). For app-token / B2B flows use `ethora-sources-site-crawl-v2`.

Input parameters:

- `appId` (string): 24-char hex appId to ingest into. Optional — defaults to the app set via `ethora-app-select`.
- `followLink` (boolean): If true, also crawl in-domain links reachable from `url`. Can ingest many pages — use with care. Default false (single page).
- `url` (string, required): Absolute URL to crawl, e.g. `https://example.com/docs`.

### `ethora-sources-site-reindex` (~261 tokens)

Re-crawl and re-embed a previously crawled URL by its `urlId`, refreshing the RAG content for that page (legacy user-auth route).

Auth: user-auth mode with an active user session; the user must own the app.
Side effects: starts a refresh job on the server; the page's existing source record is updated in place once indexing finishes (not synchronous).
Idempotent: effectively yes — re-running just refreshes the same record again.
Failure modes: 401 if not logged in; 403 if the user doesn't own the app; 404 if `appId` or `urlId` is unknown.
When to use: the source page changed and you want the bot to pick up the new content. Get `urlId` values from `ethora-sources-site-list-v2`. For app-token / B2B flows use `ethora-sources-site-reindex-v2`.

Input parameters:

- `appId` (string): 24-char hex appId the URL belongs to. Optional — defaults to the app set via `ethora-app-select`.
- `urlId` (string, required): Id of a previously crawled URL record. Get it from `ethora-sources-site-list-v2`.

### `ethora-sources-site-delete-url` (~259 tokens)

Remove a single crawled URL from an app's RAG sources, matched by its exact url string (legacy user-auth route).

Auth: user-auth mode with an active user session; the user must own the app.
Side effects: deletes the source record and its embeddings; the app's bot can no longer answer from that page. Not reversible (re-add via `ethora-sources-site-crawl`).
Idempotent: yes — deleting an already-removed URL is a no-op / 404.
Failure modes: 401 if not logged in; 403 if the user doesn't own the app; 404 if the exact `url` string isn't a crawled source.
Note: matches on the exact URL string — get the stored value from `ethora-sources-site-list-v2`. To delete several at once use `ethora-sources-site-delete-records-v1`.

Input parameters:

- `appId` (string): 24-char hex appId the URL belongs to. Optional — defaults to the app set via `ethora-app-select`.
- `url` (string, required): Exact crawled URL string to remove (must match what was stored — get it from `ethora-sources-site-list-v2`).

### `ethora-sources-site-delete-records-v1` (~247 tokens)

Bulk-remove crawled URLs from an app's RAG sources in one call, matched by exact url strings (legacy owner/admin user-auth route).

Auth: user-auth mode with an active user session; the user must own the app.
Side effects: deletes each matching source record and its embeddings. Not reversible.
Idempotent: yes — URLs not present are skipped.
Failure modes: 401 if not logged in; 403 if the user doesn't own the app; 404 if `appId` is invalid. Per-call limit: 1–100 URLs.
When to use: cleaning up many pages at once. For the single-URL variant use `ethora-sources-site-delete-url`; for app-token / B2B flows use `ethora-sources-site-delete-url-v2-batch`.

Input parameters:

- `appId` (string): 24-char hex appId the URLs belong to. Optional — defaults to the app set via `ethora-app-select`.
- `urls` (array, required): Exact crawled URL strings to remove, 1–100 per call. Get the stored values from `ethora-sources-site-list-v2`.

### `ethora-sources-docs-upload` (~290 tokens)

Upload documents (PDF, text, etc.) into an app's RAG sources so the app's AI bot can answer from them (legacy user-auth route).

Auth: user-auth mode with an active user session; the user must own the app.
Side effects: stores each document and starts a parse + embedding job; content becomes queryable RAG context once indexing finishes (not synchronous).
Idempotent: no — re-uploading the same document creates another source record.
Input design: files are base64 so the MCP server never reads your local filesystem. Client-side guardrail rejects any single file over 50MB; the server enforces its own limits too.
Failure modes: 401 if not logged in; 403 if the user doesn't own the app; 413 if too large; 422 on an unsupported document type. Per-call limit: 1–5 files.
Related: `ethora-sources-docs-delete` (remove), `ethora-sources-site-crawl` (ingest a URL instead). For app-token / B2B flows use `ethora-sources-docs-upload-v2`.

Input parameters:

- `appId` (string): 24-char hex appId to ingest into. Optional — defaults to the app set via `ethora-app-select`.
- `files` (array, required): 1 to 5 documents to ingest in this call.

### `ethora-sources-docs-delete` (~238 tokens)

Remove a previously ingested document from an app's RAG sources by `docId` (legacy user-auth route).

Auth: user-auth mode with an active user session; the user must own the app.
Side effects: deletes the document record and its embeddings; the app's bot can no longer answer from it. Not reversible (re-add via `ethora-sources-docs-upload`).
Idempotent: yes after success — a second call returns 404.
Failure modes: 401 if not logged in; 403 if the user doesn't own the app; 404 if `docId` is unknown.
Get `docId` values from `ethora-sources-docs-list-v2`. For app-token / B2B flows use `ethora-sources-docs-delete-v2`.

Input parameters:

- `appId` (string): 24-char hex appId the document belongs to. Optional — defaults to the app set via `ethora-app-select`.
- `docId` (string, required): Id of the ingested document to delete. Get it from `ethora-sources-docs-list-v2`.

### `ethora-sources-site-crawl-v2` (~333 tokens)

Crawl a website URL and ingest its content into an app's RAG sources (app-token / B2B variant of `ethora-sources-site-crawl`).

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`) OR B2B mode with an explicit `appId`.
Side effects: starts a crawl + embedding job; pages become queryable RAG context once indexing finishes (not synchronous — this returns once the job is accepted). With `followLink: true` the crawler also follows in-domain links and can ingest many pages.
Idempotent: no — re-crawling adds/updates source records.
Failure modes: 401/403 on missing/wrong auth; 400 if `url` is malformed; 404 if `appId` is invalid.
Related: `ethora-sources-site-crawl-v2-wait` (block until done), `ethora-sources-site-list-v2` (see results), `ethora-sources-site-reindex-v2` (refresh), `ethora-sources-site-delete-url-v2` (remove).

Input parameters:

- `appId` (string): 24-char hex appId to ingest into. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode.
- `followLink` (boolean): If true, also crawl in-domain links reachable from `url`. Can ingest many pages — use with care.
- `url` (string, required): Absolute URL to crawl, e.g. `https://example.com/docs`.

### `ethora-sources-site-reindex-v2` (~260 tokens)

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`).

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`) OR B2B mode with an explicit `appId`.
Side effects: starts a refresh job; the existing source record is updated in place once indexing finishes (not synchronous).
Idempotent: effectively yes — re-running just refreshes again.
Failure modes: 401/403 on missing/wrong auth; 404 if `appId` or `urlId` is unknown.
Get `urlId` values from `ethora-sources-site-list-v2`. Use `ethora-sources-site-reindex-v2-wait` to block until done.

Input parameters:

- `appId` (string): 24-char hex appId the URL belongs to. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode.
- `urlId` (string, required): Id of a previously crawled URL record. Get it from `ethora-sources-site-list-v2`.

### `ethora-sources-site-crawl-v2-wait` (~369 tokens)

Crawl a website URL and block until the server finishes the request — a single-call, long-timeout variant of `ethora-sources-site-crawl-v2`.

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`) OR B2B mode with an explicit `appId`.
Side effects: same as `ethora-sources-site-crawl-v2` (crawl + embed into RAG sources), but this MCP call blocks for up to `timeoutMs` waiting for the server's response instead of returning as soon as the job is accepted.
Idempotent: no — re-crawling adds/updates source records.
Failure modes: 401/403 on missing/wrong auth; 400 if `url` is malformed; 504/timeout if the crawl takes longer than `timeoutMs` (the job may still complete server-side — check with `ethora-sources-site-list-v2`).
Returns: `{ done: true, durationMs, result }`. Use the non-wait `ethora-sources-site-crawl-v2` if you'd rather not block.

Input parameters:

- `appId` (string): 24-char hex appId to ingest into. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode.
- `followLink` (boolean): If true, also crawl in-domain links reachable from `url`. Can ingest many pages — use with care.
- `timeoutMs` (integer): How long to wait for the crawl to finish, in milliseconds. Default 120000. Caps at 600000 (10 min).
- `url` (string, required): Absolute URL to crawl, e.g. `https://example.com/docs`.

### `ethora-sources-site-reindex-v2-wait` (~318 tokens)

Re-crawl and re-embed a previously crawled URL and block until the server finishes — a single-call, long-timeout variant of `ethora-sources-site-reindex-v2`.

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`) OR B2B mode with an explicit `appId`.
Side effects: same as `ethora-sources-site-reindex-v2` (refresh the source record's RAG content), but this MCP call blocks for up to `timeoutMs`.
Idempotent: effectively yes.
Failure modes: 401/403 on missing/wrong auth; 404 if `appId` or `urlId` is unknown; 504/timeout if it takes longer than `timeoutMs` (the job may still complete server-side).
Returns: `{ done: true, durationMs, result }`. Get `urlId` values from `ethora-sources-site-list-v2`.

Input parameters:

- `appId` (string): 24-char hex appId the URL belongs to. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode.
- `timeoutMs` (integer): How long to wait for the reindex to finish, in milliseconds. Default 120000. Caps at 600000 (10 min).
- `urlId` (string, required): Id of a previously crawled URL record. Get it from `ethora-sources-site-list-v2`.

### `ethora-sources-site-list-v2` (~208 tokens)

List an app's crawled website sources, including each source's id, URL, and current RAG tags.

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`) OR B2B mode with an explicit `appId`.
Side effects: none — read-only.
Idempotent: yes.
Failure modes: 401/403 on missing/wrong auth; 404 if `appId` is invalid; returns an empty list if nothing has been crawled.
Returns: site source records. Their ids feed `ethora-sources-site-tags-update-v2`, `ethora-sources-site-delete-url-v2-batch`, and `ethora-sources-site-reindex-v2` (`urlId`).

Input parameters:

- `appId` (string): 24-char hex appId to list sources for. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode.

### `ethora-sources-site-tags-update-v2` (~301 tokens)

Set the RAG retrieval tags on a crawled website source. Tags let the bot's `ragTags` setting narrow which sources it retrieves from.

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`) OR B2B mode with an explicit `appId`.
Side effects: **replaces** the source's tag set with the provided `tags` array (it is not additive — pass the full desired set, or an empty array to clear all tags).
Idempotent: yes — re-sending the same tags is a no-op.
Failure modes: 401/403 on missing/wrong auth; 404 if `appId` or `sourceId` is unknown.
Get `sourceId` values from `ethora-sources-site-list-v2`. The doc equivalent is `ethora-sources-docs-tags-update-v2`.

Input parameters:

- `appId` (string): 24-char hex appId the source belongs to. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode.
- `sourceId` (string, required): Id of the crawled site source to tag. Get it from `ethora-sources-site-list-v2`.
- `tags` (array, required): The complete desired tag set for this source (replaces any existing tags). Up to 50 tags; pass `[]` to clear all.

### `ethora-sources-site-delete-url-v2` (~288 tokens)

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`).

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`) OR B2B mode with an explicit `appId`.
Side effects: deletes the source record and its embeddings; the bot can no longer answer from that page. Not reversible (re-add via `ethora-sources-site-crawl-v2`).
Idempotent: yes — deleting an already-removed URL is a no-op / 404.
Failure modes: 401/403 on missing/wrong auth; 404 if the exact `url` isn't a crawled source.
Matches on the exact URL string — get the stored value from `ethora-sources-site-list-v2`. To delete several by id use `ethora-sources-site-delete-url-v2-batch`.

Input parameters:

- `appId` (string): 24-char hex appId the URL belongs to. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode.
- `url` (string, required): Exact crawled URL string to remove (must match what was stored — get it from `ethora-sources-site-list-v2`).

### `ethora-sources-docs-upload-v2` (~317 tokens)

Upload documents (PDF, text, etc.) into an app's RAG sources (app-token / B2B variant of `ethora-sources-docs-upload`).

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`) OR B2B mode with an explicit `appId`.
Side effects: stores each document and starts a parse + embedding job; content becomes queryable RAG context once indexing finishes (not synchronous).
Idempotent: no — re-uploading the same document creates another source record.
Input design: files are base64 so the MCP server never reads your local filesystem. Client-side guardrail rejects any single file over 50MB; the server enforces its own limits too.
Failure modes: 401/403 on missing/wrong auth; 404 if `appId` is invalid; 413 if too large; 422 on an unsupported document type. Per-call limit: 1–5 files.
Related: `ethora-sources-docs-list-v2` (see results), `ethora-sources-docs-delete-v2` (remove), `ethora-sources-docs-tags-update-v2` (tag).

Input parameters:

- `appId` (string): 24-char hex appId to ingest into. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode.
- `files` (array, required): 1 to 5 documents to ingest in this call.

### `ethora-sources-docs-list-v2` (~205 tokens)

List an app's ingested documents, including each document's id, name, and current RAG tags.

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`) OR B2B mode with an explicit `appId`.
Side effects: none — read-only.
Idempotent: yes.
Failure modes: 401/403 on missing/wrong auth; 404 if `appId` is invalid; returns an empty list if nothing has been uploaded.
Returns: document records. Their ids feed `ethora-sources-docs-tags-update-v2` and `ethora-sources-docs-delete-v2`. The website-sources equivalent is `ethora-sources-site-list-v2`.

Input parameters:

- `appId` (string): 24-char hex appId to list documents for. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode.

### `ethora-sources-docs-tags-update-v2` (~302 tokens)

Set the RAG retrieval tags on an ingested document. Tags let the bot's `ragTags` setting narrow which sources it retrieves from.

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`) OR B2B mode with an explicit `appId`.
Side effects: **replaces** the document's tag set with the provided `tags` array (it is not additive — pass the full desired set, or an empty array to clear all tags).
Idempotent: yes — re-sending the same tags is a no-op.
Failure modes: 401/403 on missing/wrong auth; 404 if `appId` or `docId` is unknown.
Get `docId` values from `ethora-sources-docs-list-v2`. The website-source equivalent is `ethora-sources-site-tags-update-v2`.

Input parameters:

- `appId` (string): 24-char hex appId the document belongs to. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode.
- `docId` (string, required): Id of the ingested document to tag. Get it from `ethora-sources-docs-list-v2`.
- `tags` (array, required): The complete desired tag set for this document (replaces any existing tags). Up to 50 tags; pass `[]` to clear all.

### `ethora-sources-docs-delete-v2` (~254 tokens)

Remove a previously ingested document from an app's RAG sources by `docId` (app-token / B2B variant of `ethora-sources-docs-delete`).

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`) OR B2B mode with an explicit `appId`.
Side effects: deletes the document record and its embeddings; the bot can no longer answer from it. Not reversible (re-add via `ethora-sources-docs-upload-v2`).
Idempotent: yes after success — a second call returns 404.
Failure modes: 401/403 on missing/wrong auth; 404 if `appId` or `docId` is unknown.
Get `docId` values from `ethora-sources-docs-list-v2`.

Input parameters:

- `appId` (string): 24-char hex appId the document belongs to. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode.
- `docId` (string, required): Id of the ingested document to delete. Get it from `ethora-sources-docs-list-v2`.

### `ethora-users-batch-create-v2` (~316 tokens)

Provision many Ethora users in one asynchronous batch job — the bulk equivalent of `ethora-user-register`.

Auth: B2B mode (`ethora-auth-use-b2b` + a configured `b2bToken`).
Side effects: enqueues a background job (server responds HTTP 202) — users are **not** created synchronously. Each user is created under the B2B tenant's app. With `bypassEmailConfirmation: true` users are usable immediately; otherwise each receives a verification email.
Idempotent: no — re-running re-attempts creation; the job itself reports per-user conflicts (already-registered emails) rather than failing the whole batch.
Failure modes: 401/403 if not in B2B mode; 422 if the `usersList` fails validation. Per-call limit: 1–100 users.
Returns: `{ jobId, statusUrl }`. Track it with `ethora-users-batch-job-v2` (one-shot) or `ethora-wait-users-batch-job-v2` (poll to completion).

Input parameters:

- `bypassEmailConfirmation` (boolean): If true, created users skip email verification and are immediately usable. If false/omitted, each user receives a verification link.
- `timeoutMs` (integer): HTTP timeout for the job-creation request (not the job itself), in milliseconds. Default 30000.
- `usersList` (array, required): The users to create, 1–100 per batch.

### `ethora-users-batch-job-v2` (~215 tokens)

Fetch the current status and per-user results of a users batch job by `jobId` (one-shot, no polling).

Auth: B2B mode (`ethora-auth-use-b2b` + a configured `b2bToken`) — must match the auth used to create the job.
Side effects: none — read-only.
Idempotent: yes.
Failure modes: 401/403 if not in B2B mode; 404 if the `jobId` is unknown.
Returns: the job object including its `state` (`pending` / `running` / `completed` / `failed`) and per-user outcomes (created / conflict / error). For a blocking wait-until-done, use `ethora-wait-users-batch-job-v2`.

Input parameters:

- `jobId` (string, required): Job id returned by `ethora-users-batch-create-v2`.
- `timeoutMs` (integer): HTTP timeout for this status request, in milliseconds. Default 10000.

### `ethora-wait-users-batch-job-v2` (~273 tokens)

Block until a users batch job reaches a terminal state (`completed` or `failed`), or until a timeout — a convenience wrapper around repeated `ethora-users-batch-job-v2` calls.

Auth: B2B mode (`ethora-auth-use-b2b` + a configured `b2bToken`) — must match the auth used to create the job.
Side effects: none server-side — read-only polling. Blocks this MCP call for up to `timeoutMs`.
Idempotent: yes.
Failure modes: 401/403 if not in B2B mode; 404 if the `jobId` is unknown.
Returns: `{ done: true, state, job }` when finished, or `{ done: false, reason: "timeout", job }` if `timeoutMs` elapsed first (the job may still finish later — re-check with `ethora-users-batch-job-v2`).

Input parameters:

- `intervalMs` (integer): Delay between status checks, in milliseconds. Default 1000.
- `jobId` (string, required): Job id returned by `ethora-users-batch-create-v2`.
- `timeoutMs` (integer): Maximum time to wait, in milliseconds. Default 60000. Caps at 300000 (5 min).

### `ethora-app-tokens-list-v2` (~224 tokens)

List the app tokens issued for an app — **metadata only**, the secret token values are never returned.

Auth: B2B mode (`ethora-auth-use-b2b` + a configured `b2bToken`).
Side effects: none — read-only.
Idempotent: yes.
Failure modes: 401/403 if not in B2B mode; 400 if no `appId` is given and none is selected; 404 if `appId` is invalid.
Returns: token records with `tokenId`, label, created/rotated timestamps, and status. The actual token strings are only ever shown once, at create/rotate time (`ethora-app-tokens-create-v2`, `ethora-app-tokens-rotate-v2`).

Input parameters:

- `appId` (string): 24-char hex appId to list tokens for. Optional — defaults to the app set via `ethora-app-select`.
- `timeoutMs` (integer): HTTP timeout for this request, in milliseconds. Default 10000.

### `ethora-app-tokens-create-v2` (~298 tokens)

Mint a new app token for an app.

Auth: B2B mode (`ethora-auth-use-b2b` + a configured `b2bToken`).
Side effects: creates a new app token server-side. **The secret token value is returned exactly once in this response and cannot be retrieved again** — capture it immediately (e.g. store it, or pass it to `ethora-app-select`).
Idempotent: no — each call mints a distinct token.
Failure modes: 401/403 if not in B2B mode; 400 if no `appId` is given and none is selected; 404 if `appId` is invalid.
Returns: the new token including its one-time secret value and its `tokenId`. Manage it later with `ethora-app-tokens-list-v2`, `ethora-app-tokens-rotate-v2`, `ethora-app-tokens-revoke-v2`.

Input parameters:

- `appId` (string): 24-char hex appId to mint the token for. Optional — defaults to the app set via `ethora-app-select`.
- `label` (string): Human-readable label to identify this token later (e.g. `staging`, `ci`). Shown in `ethora-app-tokens-list-v2`.
- `timeoutMs` (integer): HTTP timeout for this request, in milliseconds. Default 10000.

### `ethora-app-tokens-rotate-v2` (~306 tokens)

Rotate an app token: revoke an existing token and issue a replacement in one step.

Auth: B2B mode (`ethora-auth-use-b2b` + a configured `b2bToken`).
Side effects: the old `tokenId` is revoked **immediately** — anything still using it stops working at once — and a new token is created. **The new secret value is returned exactly once** — capture it immediately.
Idempotent: no — each call revokes and re-issues.
Failure modes: 401/403 if not in B2B mode; 404 if `appId` or `tokenId` is unknown; 400 if no `appId` is given and none is selected.
Returns: the new token including its one-time secret value and `tokenId`. Use `ethora-app-tokens-revoke-v2` if you only want to revoke without a replacement.

Input parameters:

- `appId` (string): 24-char hex appId the token belongs to. Optional — defaults to the app set via `ethora-app-select`.
- `label` (string): Label for the replacement token. Omit to inherit the old token's label.
- `timeoutMs` (integer): HTTP timeout for this request, in milliseconds. Default 10000.
- `tokenId` (string, required): Id of the token to revoke and replace. Get it from `ethora-app-tokens-list-v2`.

### `ethora-app-tokens-revoke-v2` (~260 tokens)

Permanently revoke an app token by `tokenId`.

Auth: B2B mode (`ethora-auth-use-b2b` + a configured `b2bToken`).
Side effects: the token stops working **immediately** — any client, SDK, or MCP session still using it will start getting auth failures. No replacement is issued (use `ethora-app-tokens-rotate-v2` for revoke-and-replace).
Idempotent: yes — revoking an already-revoked token succeeds as a no-op.
Failure modes: 401/403 if not in B2B mode; 404 if `appId` is unknown; 400 if no `appId` is given and none is selected.
Get `tokenId` values from `ethora-app-tokens-list-v2`.

Input parameters:

- `appId` (string): 24-char hex appId the token belongs to. Optional — defaults to the app set via `ethora-app-select`.
- `timeoutMs` (integer): HTTP timeout for this request, in milliseconds. Default 10000.
- `tokenId` (string, required): Id of the token to revoke. Get it from `ethora-app-tokens-list-v2`.

### `ethora-b2b-app-provision` (~503 tokens)

One-call B2B orchestrator: create an app, mint one or more app tokens, provision default chat rooms, then configure and enable its AI bot.

Auth: B2B mode (`ethora-auth-use-b2b` + a configured `b2bToken`). Internally uses the first minted app token for the bot/room steps.
Side effects: runs several real operations in sequence — `appCreate` (B2B), `app-tokens-create` (×N), room creation (×N), bot configure/enable. Returns a per-step log; later-step failures don't undo earlier steps (the app and any tokens already exist).
Idempotent: no — each call creates a new app, new tokens, and new rooms.
Failure modes: aborts with the partial step log if app creation fails; the previous auth mode is restored best-effort on error.
Returns: a per-step result log including `appId` and the created tokens (tokens are returned **once** — capture them). Sibling orchestrator `ethora-b2b-app-bootstrap-ai` does sources+bot but not tokens/rooms.

Input parameters:

- `botGreetingMessage` (string): Greeting message the bot posts when a conversation starts.
- `botPrompt` (string): System prompt for the new app's bot.
- `botTrigger` (string): Bot trigger: `any_message` (every message) or `/bot` (only /bot-prefixed messages).
- `displayName` (string, required): Display name for the new app.
- `enableBot` (boolean): If true, enable the new app's bot using the first minted app token.
- `llmModel` (string): LLM model id for the bot, e.g. `gpt-4o-mini`. Must be available for the chosen provider.
- `llmProvider` (string): LLM provider for the bot, e.g. `openai` or `openai-compatible`. Must be enabled in your Ethora backend.
- `rooms` (array): Default chat rooms to create in the new app. Up to 20.
- `savedAgentId` (string): Optional id of an existing saved agent to bind as the new app's active bot, instead of setting prompt fields by hand.
- `tokenLabels` (array): Labels for the app tokens to mint, one token per label. Default: ['default']. 1–5 tokens.

### `ethora-user-login` (~254 tokens)

Authenticate as an existing Ethora user with email + password.

Auth: user-auth mode (call `ethora-auth-use-user` first) and a configured `appJwt` (env or `ethora-configure`).
Side effects: stores the resulting user session token in this MCP session; unlocks user-auth tools (`ethora-app-list`, `ethora-app-create`, `ethora-files-*`, `ethora-wallet-*`).
Idempotent: yes — safe to retry on transport failures.
Failure modes: 401/403 on bad credentials; 404 if the email isn't registered; 429 if the Ethora server's per-IP login rate limit is hit (retry with backoff).
Related: `ethora-user-register` (create account first), `ethora-auth-use-user` (switch mode), `ethora-status` (verify session).

Input parameters:

- `email` (string, required): User's registered email address (RFC 5322). Must match an account created via `ethora-user-register` and verified via the link sent to that address.
- `password` (string, required): Plain-text password the user set during registration. Sent over TLS to the Ethora API; never echoed back or logged.

### `ethora-user-register` (~320 tokens)

Ethora registration

Register a new Ethora end-user account by email + first/last name.

Auth: user-auth mode and a configured `appJwt` (env or `ethora-configure`) — the JWT tells the server which app the new user belongs to.
Side effects: creates a pending user record on the Ethora server and triggers a verification email to the address; the user must click the link in that email before `ethora-user-login` will succeed.
Idempotent: safe to retry on transport failures (server deduplicates by email within an app). Calling twice with a fresh email creates one account; calling with an already-registered email returns 422.
Failure modes: 422 with a validation error if the email is already registered, if names violate server rules, or if the configured `appJwt` is invalid; 401 if no `appJwt` is configured.
When to use: end-user self-serve sign-up flows. For bulk B2B user provisioning prefer `ethora-users-batch-create-v2`.

Input parameters:

- `email` (string, required): Email address for the new user. Must be RFC-5322 valid and not already registered within this app. The user will receive a verification link they must click before login works.
- `firstName` (string, required): First name shown in the user's profile and message attributions across chat rooms and the app UI.
- `lastName` (string, required): Last name shown in the user's profile. Required by the server; do not omit unless your Ethora deployment explicitly accepts empty strings.

### `ethora-app-list` (~162 tokens)

List all Ethora apps (tenants) owned by the currently logged-in user.

Auth: user-auth mode and an active user session (call `ethora-user-login` first).
Side effects: none — read-only.
Idempotent: yes — repeated calls return the same set unless an app is created/deleted in between.
Failure modes: 401 if not logged in; returns an empty list if the user owns no apps.
Returns: an array where each entry includes `appId` (24-char hex ObjectId), `displayName`, `domainName`, ownership and bot-status metadata. Pass `appId` into `ethora-app-update`, `ethora-app-delete`, or `ethora-app-select` for app-scoped flows.

### `ethora-app-create` (~275 tokens)

Create a new Ethora app (tenant) owned by the currently logged-in user.

Auth: user-auth mode and an active user session (call `ethora-user-login` first).
Side effects: provisions a new app record on the server, allocates a fresh 24-char hex `appId`, sets the caller as owner. Each app counts against the owner's plan limit.
Idempotent: no — calling twice creates two apps. Use `ethora-app-list` first if you want to reuse an existing app.
Failure modes: 401 if not logged in; 402/403 if the owner's plan limit is reached; 422 if `displayName` violates server rules.
Returns: the new app object including `appId`. Pass it to `ethora-app-update` (set domainName/colors/bot), `ethora-app-select` (switch into app-token flows), or `ethora-app-delete` (remove).
When to use: interactive setup by a logged-in user. For server-to-server provisioning prefer `ethora-b2b-app-create` or the one-call orchestrator `ethora-b2b-app-bootstrap-ai`.

Input parameters:

- `displayName` (string, required): Human-readable app name shown to users in the app picker and on the public landing page. Not required to be unique across accounts.

### `ethora-app-update` (~466 tokens)

Update mutable fields on an existing Ethora app the caller owns (displayName, domainName, appDescription, primaryColor, botStatus).

Auth: user-auth mode and an active user session; the caller must own the app.
Side effects: **partial update** — only the fields you pass are changed; omitted fields keep their previous values. `domainName` changes affect the public URL (`<domain>.ethora.com`) immediately. `botStatus: "on"` enables the bot only if the app has a configured prompt (use `ethora-bot-update-v2` / `ethora-bot-enable-v2` for the AI bot lifecycle).
Idempotent: yes — repeating an update with the same values is a no-op.
Failure modes: 401 if not logged in; 403 if not the owner; 404 if `appId` is invalid; 422 on field validation failure (e.g. `domainName` already taken, `primaryColor` not in `#RRGGBB` format).
When to use: change branding, route the web app under a custom subdomain, or quickly toggle the bot on/off without re-running setup.

Input parameters:

- `appDescription` (string): Long-form description shown on the public app landing page.
- `appId` (string): 24-char hex ObjectId of the app to update. Optional — defaults to the app most recently passed to `ethora-app-select`.
- `botStatus` (string): `on` enables the AI bot for new conversations (requires a configured prompt — see `ethora-bot-update-v2`); `off` disables it. Does not change the bot's configured prompt or sources.
- `displayName` (string): New human-readable app name. Visible in the app picker and on the public landing page.
- `domainName` (string): Subdomain to host the web app at. Setting `abcd` makes the web app available at `abcd.ethora.com`. Must be unique across all Ethora apps; lower-case alphanumerics and dashes only.
- `primaryColor` (string): Primary brand color in hex `#RRGGBB` format (e.g. `#F54927`). Used throughout the app UI.

### `ethora-app-get-default-rooms` (~178 tokens)

List the default chat rooms (MUC rooms) of the currently selected Ethora app — every new user of the app auto-joins these.

Auth: user-auth mode and an active user session. Operates against the currently selected app — call `ethora-app-select` first, or use `ethora-app-get-default-rooms-with-app-id` to pass `appId` explicitly.
Side effects: none — read-only.
Idempotent: yes.
Failure modes: 400 if no app is currently selected in this MCP session; 401 if not logged in.
Returns: array of rooms with their JIDs and titles. Use the JIDs with `ethora-chats-broadcast-v2`, `ethora-app-create-chat` (add more), or `ethora-app-delete-chat` (remove).

### `ethora-app-create-chat` (~337 tokens)

Create a new chat room (MUC room) inside an Ethora app the caller owns.

Auth: user-auth mode and an active user session; the caller must own the app.
Side effects: provisions a new MUC room with the given `title`. If `pinned: true` the room is added to the app's default rooms list — every new user of the app will auto-join it from that point on. Existing users are **not** auto-added; for that, see the chat membership v2 endpoints.
Idempotent: no — calling twice with the same title creates two distinct rooms with different JIDs.
Failure modes: 401 if not logged in; 403 if the caller does not own the app; 404 if `appId` is invalid; 422 if `title` is empty or violates server rules.
Returns: the new room object including its JID. Use the JID with `ethora-chats-broadcast-v2` to send messages or `ethora-app-delete-chat` to remove.

Input parameters:

- `appId` (string): 24-char hex ObjectId of the app to create the chat room in. Optional — defaults to the app most recently passed to `ethora-app-select`.
- `pinned` (boolean, required): If `true`, the room is added to the app's default rooms list — every new user of the app auto-joins it. If `false`, the room exists but users must be added explicitly.
- `title` (string, required): Display name for the new chat room. Visible to all members; not required to be unique within the app.

### `ethora-app-delete-chat` (~279 tokens)

Permanently delete a chat room from an Ethora app the caller owns.

\**Destructive and irreversible.** Gated behind `ETHORA_MCP_ENABLE_DANGEROUS_TOOLS=true`; the tool refuses to register otherwise.
Auth: user-auth mode and an active user session; the caller must own the app.
Side effects: removes the MUC room, its message archive, and all member affiliations. Participants will see "room destroyed" on their next reconnect.
Idempotent: yes after success — subsequent calls return 404.
Failure modes: 401 if not logged in; 403 if not the owner; 404 if `chatJid` is not a room in the app.
When to use: explicit room tear-down. To remove only from the default rooms list (without destroying the room) update the default-rooms config rather than deleting.

Input parameters:

- `appId` (string): 24-char hex ObjectId of the app the chat room belongs to. Optional — defaults to the app most recently passed to `ethora-app-select`.
- `chatJid` (string, required): Room JID (XMPP address) of the chat to delete, e.g. `<roomId>@conference.<host>`. Obtain from `ethora-app-get-default-rooms` or the response of `ethora-app-create-chat`.

### `ethora-app-get-default-rooms-with-app-id` (~211 tokens)

List the default chat rooms of a specific Ethora app, passed via `appId` (or defaulted to the currently selected app).

Auth: user-auth mode and an active user session. The caller must have read access to the app — either ownership, or membership of at least one of its rooms.
Side effects: none — read-only.
Idempotent: yes.
Failure modes: 400 if neither `appId` is passed nor an app is currently selected; 401 if not logged in; 403 if the caller lacks read access; 404 if `appId` does not exist.
Returns: array of rooms with their JIDs and titles. Use `ethora-app-get-default-rooms` for the simpler "current app only" variant.

Input parameters:

- `appId` (string): 24-char hex ObjectId of the app whose default rooms you want to read. Optional — defaults to the app most recently passed to `ethora-app-select`.

### `ethora-wallet-get-balance` (~149 tokens)

Read the on-chain wallet balance for the currently authenticated user, across the ERC-20 token(s) the Ethora backend tracks for them.

Auth: user-auth mode and an active user session (call `ethora-user-login` first).
Side effects: none — read-only, no gas consumed.
Idempotent: yes — safe to call repeatedly.
Failure modes: 401 if not logged in; 503 if the wallet RPC is temporarily unreachable (safe to retry on 503 with backoff).
Returns: balances in the units the Ethora backend reports (typically whole-token integers — confirm with your deployment). Pair with `ethora-wallet-erc20-transfer` to spend.

### `ethora-b2b-app-create` (~262 tokens)

Create a new Ethora app (tenant) server-side using B2B auth — the partner/integrator equivalent of `ethora-app-create`.

Auth: B2B mode (`ethora-auth-use-b2b` + a configured `b2bToken`).
Side effects: provisions a new app record owned by the B2B tenant and allocates a fresh 24-char hex `appId`. Does not create tokens, rooms, or a bot.
Idempotent: no — calling twice creates two apps.
Failure modes: 401/403 if not in B2B mode or the `b2bToken` is invalid; 422 if `displayName` violates server rules.
Returns: the new app object including `appId`. Next steps: `ethora-app-tokens-create-v2` (mint an appToken), `ethora-app-select` (set context), `ethora-bot-update-v2` (configure the bot). For the all-in-one path use `ethora-b2b-app-bootstrap-ai` or `ethora-b2b-app-provision`.

Input parameters:

- `displayName` (string, required): Human-readable app name shown to users in the app picker and on the public landing page.

### `ethora-b2b-bot-enable` (~319 tokens)

Turn on the AI bot for an app via B2B auth (sets `botStatus: "on"` on the app record).

Auth: B2B mode (`ethora-auth-use-b2b` + a configured `b2bToken`).
Side effects: flips the app's bot status to on; the backend then makes a **best-effort** activation against the configured AI service. The bot only actually responds if the app already has a prompt + LLM configured (see `ethora-bot-update-v2`) and the Ethora backend has AI service URL/secret set.
Idempotent: yes — enabling an already-enabled bot is a no-op.
Failure modes: 401/403 if not in B2B mode; 404 if `appId` is invalid; 400 if no `appId` is given and none is selected.
Note: this is a thin convenience over `ethora-app-update`. For full bot configuration (prompt, LLM, RAG, greeting) use `ethora-bot-update-v2`; `ethora-bot-enable-v2` is the app-token-friendly equivalent.

Input parameters:

- `appId` (string): 24-char hex appId whose bot to enable. Optional — defaults to the app set via `ethora-app-select`.
- `botTrigger` (string): When the bot responds: `/bot` (only messages starting with /bot) or `any_message` (every message). Omit to leave the existing trigger unchanged.

### `ethora-bot-get-v2` (~196 tokens)

Read the current AI bot configuration for an app: status, trigger, prompt, greeting, LLM provider/model, RAG settings, widget config.

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`) OR B2B mode with an explicit `appId`.
Side effects: none — read-only.
Idempotent: yes.
Failure modes: 401/403 on missing/wrong auth; 404 if `appId` is invalid.
Returns: the bot settings object. Use it to inspect before changing things with `ethora-bot-update-v2`, or to confirm an `ethora-agents-activate-v2` took effect.

Input parameters:

- `appId` (string): 24-char hex appId. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode (the token determines the app).

### `ethora-bot-update-v2` (~730 tokens)

Configure the AI bot for an app — its prompt, LLM, trigger, greeting, RAG behavior, identity, and public widget settings.

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`) OR B2B mode with an explicit `appId`.
Side effects: **partial update** — only the fields you pass are changed; omitted fields keep their values. Setting `status: "on"` activates the bot (best-effort against the configured AI service — needs a prompt + LLM and a backend AI service configured).
Idempotent: yes — re-sending the same values is a no-op.
Failure modes: 401/403 on missing/wrong auth; 404 if `appId` is invalid; 422 on field validation failure (e.g. an `llmProvider`/`llmModel` your backend doesn't have enabled).
Related: `ethora-bot-get-v2` (inspect first), `ethora-bot-enable-v2` / `ethora-bot-disable-v2` (just toggle status), `ethora-agents-activate-v2` (apply a saved agent's config instead of setting fields by hand).

Input parameters:

- `appId` (string): 24-char hex appId. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode.
- `botAvatarUrl` (string): Public URL of the bot's avatar image.
- `botDisplayName` (string): Bot's display name shown in chat.
- `botFirstName` (string): Bot's first name in its user profile.
- `botLastName` (string): Bot's last name in its user profile.
- `chatId` (string): Restrict the bot to a single chat by id. Omit to apply app-wide.
- `greetingMessage` (string): Message the bot posts when a conversation starts.
- `isRAG` (boolean): If true, the bot retrieves from the app's indexed RAG sources (see the `ethora-sources-*` tools) when answering.
- `llmModel` (string): LLM model id, e.g. `gpt-4o-mini`. Must be available for the chosen `llmProvider`.
- `llmProvider` (string): LLM provider, e.g. `openai` or `openai-compatible`. Must be enabled in your Ethora backend's AI service config.
- `prompt` (string): System prompt that defines the bot's persona and behavior.
- `ragTags` (array): Restrict RAG retrieval to sources tagged with these tags (see `ethora-sources-site-tags-update-v2` / `ethora-sources-docs-tags-update-v2`).
- `savedAgentId` (string): Id of a saved agent whose config should back this bot. Alternative to setting prompt/LLM/RAG fields individually.
- `status` (string): `on` activates the bot, `off` deactivates it. Omit to leave the current status unchanged.
- `trigger` (string): When the bot responds: `any_message` (replies to every message) or `/bot` (only messages starting with /bot).
- `widgetPublicEnabled` (boolean): If true, expose the bot through a public embeddable chat widget.
- `widgetPublicUrl` (string): Public URL for the embeddable widget. Usually read via `ethora-bot-widget-v2` rather than set here.

### `ethora-bot-enable-v2` (~279 tokens)

Turn the AI bot on for an app (sets bot `status: "on"`), optionally setting its trigger at the same time.

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`) OR B2B mode with an explicit `appId`.
Side effects: activates the bot. It only actually responds if a prompt + LLM are configured (see `ethora-bot-update-v2` or `ethora-agents-activate-v2`) and the Ethora backend has an AI service configured.
Idempotent: yes — enabling an already-on bot is a no-op.
Failure modes: 401/403 on missing/wrong auth; 404 if `appId` is invalid.
Thin convenience over `ethora-bot-update-v2` for the common "just turn it on" case. Pair with `ethora-bot-disable-v2` to turn it off.

Input parameters:

- `appId` (string): 24-char hex appId. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode.
- `trigger` (string): When the bot responds: `any_message` (every message) or `/bot` (only /bot-prefixed messages). Omit to leave the existing trigger unchanged.

### `ethora-bot-disable-v2` (~210 tokens)

Turn the AI bot off for an app (sets bot `status: "off"`).

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`) OR B2B mode with an explicit `appId`.
Side effects: deactivates the bot — it stops responding to messages. The bot's configured prompt/LLM/RAG and any activated agent are preserved, so re-enabling later restores the same behavior.
Idempotent: yes — disabling an already-off bot is a no-op.
Failure modes: 401/403 on missing/wrong auth; 404 if `appId` is invalid.
Thin convenience over `ethora-bot-update-v2`. Pair with `ethora-bot-enable-v2` to turn it back on.

Input parameters:

- `appId` (string): 24-char hex appId. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode.

### `ethora-bot-widget-v2` (~140 tokens)

Read the public chat-widget / embed configuration for the current app's bot (`GET /v2/bot/widget`).

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`).
Side effects: none — read-only.
Idempotent: yes.
Failure modes: 401/403 if not in app-token mode or the appToken is invalid.
Returns: the widget config and the public widget URL metadata — what you need to embed the bot on a website. To enable/disable the public widget, set `widgetPublicEnabled` via `ethora-bot-update-v2`.

### `ethora-agents-list-v2` (~167 tokens)

List the reusable saved agents owned by the current app (`GET /v2/agents`).

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`).
Side effects: none — read-only.
Idempotent: yes.
Failure modes: 401/403 if not in app-token mode or the appToken is invalid; returns an empty list if the app has no saved agents.
Returns: an array of agents with their ids, names, and config. A saved agent is a reusable bot definition — use the ids with `ethora-agents-get-v2`, `ethora-agents-update-v2`, `ethora-agents-clone-v2`, or `ethora-agents-activate-v2`.

### `ethora-agents-get-v2` (~181 tokens)

Fetch one reusable saved agent's full config by id (`GET /v2/agents/:agentId`).

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`).
Side effects: also sets this agent as the current agent context for the session (so later agent tools can omit `agentId`). No server-side change.
Idempotent: yes.
Failure modes: 401/403 on missing/wrong auth; 404 if `agentId` is not an agent of the current app.
Returns: the agent object (prompt, LLM, RAG settings, visibility, etc.). Get ids from `ethora-agents-list-v2`.

Input parameters:

- `agentId` (string, required): Id of the saved agent to fetch. Get it from `ethora-agents-list-v2`.

### `ethora-agents-create-v2` (~514 tokens)

Create a new reusable saved agent — a named, reusable bot definition (prompt + LLM + RAG settings + identity) that can later be activated onto any app (`POST /v2/agents`).

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`).
Side effects: creates an agent record owned by the current app; also sets it as the session's current agent context. Creating an agent does **not** activate it on the app — call `ethora-agents-activate-v2` for that.
Idempotent: no — calling twice creates two agents.
Failure modes: 401/403 on missing/wrong auth; 422 on field validation failure (e.g. duplicate `slug`, unsupported `llmProvider`/`llmModel`).
Returns: the created agent including its id.

Input parameters:

- `botAvatarUrl` (string): Public URL of the agent's avatar image.
- `botDisplayName` (string): Display name shown in chat when this agent is the active bot.
- `categories` (array): Catalogue categories for a public agent.
- `greetingMessage` (string): Message the agent posts when a conversation starts.
- `isPublished` (boolean): If true and visibility is public, the agent is listed in the public catalogue.
- `isRAG` (boolean): If true, the agent retrieves from the app's indexed RAG sources when answering.
- `llmModel` (string): LLM model id, e.g. `gpt-4o-mini`. Must be available for the chosen provider.
- `llmProvider` (string): LLM provider, e.g. `openai` or `openai-compatible`. Must be enabled in your Ethora backend.
- `name` (string): Human-readable agent name.
- `prompt` (string): System prompt defining the agent's persona and behavior.
- `ragTags` (array): Restrict RAG retrieval to sources carrying these tags.
- `slug` (string): URL-safe unique identifier for the agent within the app. Lower-case alphanumerics and dashes.
- `summary` (string): Short description of what the agent does.
- `trigger` (string): When the agent responds: `any_message` (every message) or `/bot` (only /bot-prefixed messages).
- `visibility` (string): `private` (only this app) or `public` (discoverable in the shared agent catalogue).

### `ethora-agents-update-v2` (~523 tokens)

Update fields on an existing reusable saved agent (`PUT /v2/agents/:agentId`).

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`).
Side effects: **partial update** — only the fields you pass change; omitted fields keep their values. Also sets this agent as the session's current agent context. If the agent is currently activated on the app, changes take effect on the live bot.
Idempotent: yes — re-sending the same values is a no-op.
Failure modes: 401/403 on missing/wrong auth; 404 if `agentId` is not an agent of the current app; 422 on field validation failure.
Get `agentId` from `ethora-agents-list-v2`.

Input parameters:

- `agentId` (string, required): Id of the saved agent to update. Get it from `ethora-agents-list-v2`.
- `botAvatarUrl` (string): Public URL of the agent's avatar image.
- `botDisplayName` (string): Display name shown in chat when this agent is the active bot.
- `categories` (array): Catalogue categories for a public agent.
- `greetingMessage` (string): Message the agent posts when a conversation starts.
- `isPublished` (boolean): If true and visibility is public, the agent is listed in the public catalogue.
- `isRAG` (boolean): If true, the agent retrieves from the app's indexed RAG sources when answering.
- `llmModel` (string): LLM model id, e.g. `gpt-4o-mini`. Must be available for the chosen provider.
- `llmProvider` (string): LLM provider, e.g. `openai` or `openai-compatible`. Must be enabled in your Ethora backend.
- `name` (string): Human-readable agent name.
- `prompt` (string): System prompt defining the agent's persona and behavior.
- `ragTags` (array): Restrict RAG retrieval to sources carrying these tags.
- `slug` (string): URL-safe unique identifier within the app. Lower-case alphanumerics and dashes.
- `summary` (string): Short description of what the agent does.
- `trigger` (string): When the agent responds: `any_message` (every message) or `/bot` (only /bot-prefixed messages).
- `visibility` (string): `private` (only this app) or `public` (discoverable in the shared agent catalogue).

### `ethora-agents-clone-v2` (~277 tokens)

Duplicate an existing saved agent into a new agent, optionally overriding its name/slug/summary (`POST /v2/agents/:agentId/clone`).

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`).
Side effects: creates a new agent record copying the source agent's config; also sets the new agent as the session's current agent context. The source agent is unchanged.
Idempotent: no — calling twice creates two clones.
Failure modes: 401/403 on missing/wrong auth; 404 if the source `agentId` doesn't exist; 422 if an overridden `slug` collides.
When to use: branch a working agent before experimenting, instead of mutating the original with `ethora-agents-update-v2`.

Input parameters:

- `agentId` (string, required): Id of the source agent to clone. Get it from `ethora-agents-list-v2`.
- `name` (string): Name for the clone. Omit to inherit the source agent's name.
- `slug` (string): URL-safe unique slug for the clone. Omit to let the server derive one; must not collide with an existing agent.
- `summary` (string): Summary for the clone. Omit to inherit the source agent's summary.

### `ethora-agents-activate-v2` (~238 tokens)

Bind a saved agent as the active AI bot for the current app — copies the agent's config onto the app's bot (`POST /v2/agents/:agentId/activate`).

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`).
Side effects: the app's live bot now uses this agent's prompt/LLM/RAG/identity. Replaces whatever bot config was there before. Also sets this agent as the session's current agent context. Does not by itself set `status: "on"` if the bot was off — pair with `ethora-bot-enable-v2` if needed.
Idempotent: yes — activating the already-active agent is a no-op.
Failure modes: 401/403 on missing/wrong auth; 404 if `agentId` is not an agent of the current app.
Verify with `ethora-bot-get-v2` afterwards.

Input parameters:

- `agentId` (string, required): Id of the saved agent to activate as the app's bot. Get it from `ethora-agents-list-v2`.

### `ethora-chats-message-v2` (~340 tokens)

Send a message through the app's chat/bot automation surface — useful for testing the bot or driving automated conversations.

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`). Your Ethora backend must expose the chat automation surface on the same API host.
Side effects: posts a real message into the app — in `private` mode to a 1:1 automation session keyed by `nickname`, in `group` mode into the room identified by `roomJid`. If the app's bot is enabled it will react to the message.
Idempotent: no — each call posts another message.
Failure modes: 401/403 on missing/wrong auth; 400 if `mode` is `group` but no `roomJid` is given (or `private` but no `nickname`); 404 if `roomJid` doesn't exist.
Read back the resulting conversation with `ethora-chats-history-v2`. `ethora-bot-message-v2` is an identical alias.

Input parameters:

- `mode` (string): `private` = 1:1 automation session keyed by `nickname`; `group` = a room identified by `roomJid`. Defaults to the backend's default mode.
- `nickname` (string): Sender/participant nickname for the private automation session. Required when `mode` is `private`.
- `roomJid` (string): Room JID to post into. Required when `mode` is `group`. Get it from `ethora-app-get-default-rooms`.
- `text` (string, required): Message body to send.

### `ethora-chats-history-v2` (~273 tokens)

Read the persisted message history of a chat automation session — the conversation produced by `ethora-chats-message-v2` and the bot's replies.

Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`).
Side effects: none — read-only.
Idempotent: yes.
Failure modes: 401/403 on missing/wrong auth; 400 if the `mode`/`nickname`/`roomJid` combination is incomplete; 404 if the room/session doesn't exist.
Returns: the most recent messages (up to `limit`) for the identified session. `ethora-bot-history-v2` is an identical alias.

Input parameters:

- `limit` (integer): Maximum number of most-recent messages to return. 1–100. Defaults to the backend's default page size.
- `mode` (string): `private` = 1:1 automation session keyed by `nickname`; `group` = a room identified by `roomJid`. Should match what was used to send.
- `nickname` (string): Participant nickname for the private automation session. Required when `mode` is `private`.
- `roomJid` (string): Room JID to read history from. Required when `mode` is `group`.

### `ethora-bot-message-v2` (~250 tokens)

Compatibility alias for `ethora-chats-message-v2` — identical behavior, kept for clients that expect a `bot-`prefixed name.

Send a message through the app's chat/bot automation surface.
Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`).
Side effects: posts a real message into the app; the enabled bot will react to it. Not idempotent — each call posts another message.
Failure modes: 401/403 on missing/wrong auth; 400 if the `mode`/`nickname`/`roomJid` combination is incomplete.
Prefer `ethora-chats-message-v2` in new integrations.

Input parameters:

- `mode` (string): `private` = 1:1 automation session keyed by `nickname`; `group` = a room identified by `roomJid`.
- `nickname` (string): Sender/participant nickname for the private automation session. Required when `mode` is `private`.
- `roomJid` (string): Room JID to post into. Required when `mode` is `group`.
- `text` (string, required): Message body to send.

### `ethora-bot-history-v2` (~241 tokens)

Compatibility alias for `ethora-chats-history-v2` — identical behavior, kept for clients that expect a `bot-`prefixed name.

Read the persisted message history of a chat automation session.
Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`).
Side effects: none — read-only. Idempotent: yes.
Failure modes: 401/403 on missing/wrong auth; 400 if the `mode`/`nickname`/`roomJid` combination is incomplete.
Prefer `ethora-chats-history-v2` in new integrations.

Input parameters:

- `limit` (integer): Maximum number of most-recent messages to return. 1–100.
- `mode` (string): `private` = 1:1 automation session keyed by `nickname`; `group` = a room identified by `roomJid`.
- `nickname` (string): Participant nickname for the private automation session. Required when `mode` is `private`.
- `roomJid` (string): Room JID to read history from. Required when `mode` is `group`.

### `ethora.b2b.auth.use` (~104 tokens)

Dot-namespaced alias for `ethora-auth-use-b2b` — switches the session's active auth mode to B2B (`x-custom-token`).

Auth: requires a `b2bToken` to already be configured.
Side effects: session state only; no API call.
Idempotent: yes.
Provided to reduce auth-mode mistakes for agents that prefer dotted names; behavior is identical to `ethora-auth-use-b2b`.

### `ethora.b2b.app.create` (~180 tokens)

Dot-namespaced alias for `ethora-b2b-app-create` — create a new Ethora app server-side.

Auth: B2B mode (`ethora.b2b.auth.use` / `ethora-auth-use-b2b` + a configured `b2bToken`).
Side effects: provisions a new app record owned by the B2B tenant and allocates a fresh `appId`. Not idempotent — each call creates a new app.
Failure modes: 401/403 if not in B2B mode; 422 on an invalid `displayName`.
Provided for agents that prefer dotted names. Prefer `ethora-b2b-app-create` in new integrations.

Input parameters:

- `displayName` (string, required): Human-readable app name shown to users in the app picker and on the public landing page.

### `ethora.b2b.bot.enable` (~267 tokens)

Dot-namespaced alias for `ethora-b2b-bot-enable` — turn on the AI bot for an app (sets `botStatus: "on"`).

Auth: B2B mode (`ethora.b2b.auth.use` / `ethora-auth-use-b2b` + a configured `b2bToken`).
Side effects: flips the app's bot status to on; the backend then makes a best-effort activation. The bot only responds if a prompt + LLM are configured and the backend has an AI service set up.
Idempotent: yes — enabling an already-on bot is a no-op.
Failure modes: 401/403 if not in B2B mode; 404 if `appId` is invalid; 400 if no `appId` is given and none is selected.
Provided for agents that prefer dotted names. Prefer `ethora-b2b-bot-enable` in new integrations.

Input parameters:

- `appId` (string): 24-char hex appId whose bot to enable. Optional — defaults to the app set via `ethora-app-select`.
- `botTrigger` (string): When the bot responds: `/bot` or `any_message`. Omit to leave the existing trigger unchanged.

### `ethora.b2b.broadcast.wait` (~263 tokens)

Dot-namespaced sibling of `ethora-wait-broadcast-job-v2` — block until a broadcast job reaches a terminal state (`completed` / `failed`) or until a timeout.

Auth: app-token mode (despite the `b2b` in the name, this variant uses app-token auth — `ethora-app-select` + `ethora-auth-use-app`). Use `ethora-wait-broadcast-job-v2` if you need the B2B-with-explicit-appId path.
Side effects: none server-side — read-only polling. Blocks this MCP call for up to `timeoutMs`.
Idempotent: yes.
Failure modes: 401/403 if not in app-token mode; 404 if the `jobId` is unknown.
Returns: `{ done: true, state, job }` when finished, or `{ done: false, reason: "timeout", job }` on timeout.

Input parameters:

- `intervalMs` (integer): Delay between status checks, in milliseconds. Default 1000.
- `jobId` (string, required): Job id returned by `ethora-chats-broadcast-v2`.
- `timeoutMs` (integer): Maximum time to wait, in milliseconds. Default 60000.

### `ethora.b2b.app.bootstrap-ai` (~463 tokens)

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.

Auth: B2B mode (`ethora.b2b.auth.use` / `ethora-auth-use-b2b` + a configured `b2bToken`).
Side effects: runs multiple real operations in sequence (app create, source ingest, bot configure/enable); source ingestion and bot activation are best-effort, so the app is still created even if a later step fails. Not idempotent — each call creates a new app.
Failure modes: aborts with the partial step log if app creation fails; previous auth mode restored best-effort on error.
Returns: a per-step result log including the new `appId`. Provided for agents that prefer dotted names; behavior matches `ethora-b2b-app-bootstrap-ai`.

Input parameters:

- `botTrigger` (string): Bot trigger: `/bot` or `any_message`.
- `crawlUrl` (string): Optional website URL to crawl and index into the new app's RAG sources.
- `displayName` (string, required): Display name for the new app.
- `docs` (array): Optional documents to ingest into the new app's RAG sources.
- `enableBot` (boolean): If true, set the new app's bot to `status: on` (best-effort AI service activation).
- `followLink` (boolean): For `crawlUrl`: also follow in-domain links (default true). Can ingest many pages.
- `llmModel` (string): LLM model id for the bot, e.g. `gpt-4o-mini`. Must be available for the chosen provider.
- `llmProvider` (string): LLM provider for the bot, e.g. `openai` or `openai-compatible`. Must be enabled in your Ethora backend.
- `savedAgentId` (string): Optional id of an existing saved agent to bind as the new app's active bot.
- `setAsCurrent` (boolean): If true (default), set the new app as the session's current app and switch to app-token auth.

### `ethora-b2b-app-bootstrap-ai` (~588 tokens)

One-call B2B orchestrator: create an app, set it as the current context, index RAG sources, then configure and enable its AI bot.

Auth: B2B mode (`ethora-auth-use-b2b` + a configured `b2bToken`). Internally switches into app-token mode for the source-ingest steps and (if `setAsCurrent`) leaves the session pointed at the new app.
Side effects: runs multiple real operations in sequence — `appCreate` (B2B), set current app, `/v2/sources/*` ingest (app-token), bot configure/enable. Source ingestion and bot activation are **best-effort**: the app is still created even if a later step fails. The crawl/embedding work continues asynchronously after this returns.
Idempotent: no — each call creates a brand-new app.
Failure modes: aborts and returns the partial step log if app creation fails; on a later-step failure the previous auth mode is restored best-effort. Bot activation needs an AI service configured on your Ethora backend.
Returns: a per-step result log including the new `appId`. For the rooms+tokens variant use `ethora-b2b-app-provision`; for full manual control wire `ethora-b2b-app-create` + `ethora-sources-*-v2` + `ethora-bot-update-v2` yourself.

Input parameters:

- `botTrigger` (string): Bot trigger: `/bot` (only /bot-prefixed messages) or `any_message` (every message).
- `crawlUrl` (string): Optional website URL to crawl and index into the new app's RAG sources.
- `displayName` (string, required): Display name for the new app.
- `docs` (array): Optional documents to ingest into the new app's RAG sources.
- `enableBot` (boolean): If true, set the new app's bot to `status: on` (best-effort AI service activation).
- `followLink` (boolean): For `crawlUrl`: also follow in-domain links (default true). Can ingest many pages.
- `llmModel` (string): LLM model id for the bot, e.g. `gpt-4o-mini`. Must be available for the chosen provider.
- `llmProvider` (string): LLM provider for the bot, e.g. `openai` or `openai-compatible`. Must be enabled in your Ethora backend.
- `savedAgentId` (string): Optional id of an existing saved agent to bind as the new app's active bot, instead of configuring prompt/LLM by hand.
- `setAsCurrent` (boolean): If true (default), set the new app as the session's current app and switch to app-token auth so follow-up tools can omit appId.

### `ethora-generate-chat-component-app-tsx` (~254 tokens)

Generate a ready-to-paste React `App.tsx` snippet that mounts `@ethora/chat-component`.

Auth: none required — this is a pure code generator, makes no API calls.
Side effects: none — returns the snippet as text; **does not write any file**.
Idempotent: yes — same inputs produce the same snippet.
Failure modes: effectively none.
Returns: `{ filename: "App.tsx", snippet }`. Any values you don't pass are emitted as clearly-marked placeholders. Security note: the snippet includes `appToken` inline only as a quickstart convenience — do not ship hardcoded tokens to production; have your backend issue short-lived credentials instead.

Input parameters:

- `apiUrl` (string): Ethora API base URL to embed in the snippet, e.g. `https://api.chat.ethora.com/v1`. Omit to emit a placeholder.
- `appToken` (string): appToken to embed in the snippet for quickstart testing. Omit to emit a placeholder. Do NOT hardcode real tokens in production source.
- `roomJid` (string): Room JID to open on load. Omit to emit a commented-out placeholder.

### `ethora-generate-env-examples` (~179 tokens)

Generate `.env.example` templates for the three common Ethora integration targets: the frontend chat component, the backend SDK, and this MCP server.

Auth: none required — pure text generator, makes no API calls.
Side effects: none — returns templates as text; **does not write any file**.
Idempotent: yes.
Failure modes: effectively none.
Returns: a single `{ target, template }` when `target` is given, or `{ templates }` with all three when omitted. Templates contain placeholder values and inline security notes only — never real credentials.

Input parameters:

- `target` (string): Which template to return: `frontend-chat-component` (Vite env), `backend-sdk` (@ethora/sdk-backend env), or `mcp` (this server's env). Omit to return all three.

### `ethora-generate-b2b-bootstrap-runbook` (~244 tokens)

Generate a human-readable runbook listing this server's tool calls in the right order for a B2B bootstrap, with example payloads.

Auth: none required — pure text generator, makes no API calls and runs nothing.
Side effects: none — returns the runbook as text; **does not write any file or execute any step**.
Idempotent: yes.
Failure modes: effectively none.
Returns: the runbook text with your supplied values substituted into the example payloads. This is documentation only — to actually run the sequence use `ethora-run-recipe`, or the one-call orchestrators `ethora-b2b-app-bootstrap-ai` / `ethora-b2b-app-provision`.

Input parameters:

- `apiUrl` (string): Ethora API base URL to show in the runbook's configure step. Omit to emit a placeholder.
- `crawlUrl` (string): Website URL to show in the runbook's source-ingest step. Omit to emit a placeholder.
- `displayName` (string): App display name to show in the runbook's create-app step. Omit to emit a placeholder.

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/dappros-ethora-mcp-cli/ethora-mcp-server#diagnostics

## Score history

- 2026-08-03: 64
- 2026-08-02: 60
- 2026-08-01: 64
- 2026-07-31: 0
- 2026-07-30: 4
- 2026-07-28: 74
- 2026-07-27: 74
- 2026-07-26: 32

## Links

- npm package: https://www.npmjs.com/package/@ethora/mcp-server
- Socket report: https://socket.dev/npm/package/@ethora/mcp-server
- Changelog RSS feed: https://verifymcp.io/servers/dappros-ethora-mcp-cli/ethora-mcp-server/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/dappros-ethora-mcp-cli/ethora-mcp-server/changelog.json
- HTML version of this page: https://verifymcp.io/servers/dappros-ethora-mcp-cli/ethora-mcp-server
