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

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

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

## Components

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

## Channel facts

- Registry: `npm`
- Package: `@ethora/mcp-server`
- Version: `26.5.3`
- 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**: 45/100
  - Source repository is publicly reachable at the declared URL.
  - 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 14235 tokens (~195/item across 73 items; 69 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-server -- npx -y @ethora/mcp-server
```

### Codex

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

### opencode

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

### OpenClaw

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

### Hermes

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

### Other

```json
{
  "mcpServers": {
    "dappros-ethora-mcp-server": {
      "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 70, +1)

No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-08-02 (score 69, +30)

- [security regression] Provenance: unverified → fail
- [security improvement] Install scripts: unverified → pass
- [security improvement] Known CVEs: unverified → partial
- [functional improvement] License: unverified → pass
- [functional improvement] MCP protocol: unverified → pass
- [functional improvement] Stability: unverified → 0.23
- [functional improvement] Schema quality: unverified → excellent
- [functional improvement] Dependency health: unverified → partial
- [functional improvement] Maintenance: unverified → pass
- [functional] Licence: ISC

### 2026-08-01 (score 39, +15)

- [security improvement] Malware scan: unverified → pass

### 2026-07-31 (score 24, −27)

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

### 2026-07-27 (score 51)

First indexed and scored.

## MCP tools (69)

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

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).
Auth: none required — this establishes auth material. Errors: only if a value is structurally invalid. Follow with 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` (~78 tokens)

Report the current Ethora MCP session state: configured API URL, active auth mode, which credentials are present (booleans like `hasAppJwt` — values never echoed), and the selected appId/agentId.
Auth: none required. Errors: effectively none. Related: `ethora-doctor` for an active connectivity check.

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

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 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` (~278 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). Use `dryRun: true` to preview resolved steps. Omit `recipeId` to list runnable recipes for a `goal`.
Auth: depends on the recipe's steps — configure those first (see `ethora-help`). Errors: stops at the first failing step and returns the partial log; a missing required `vars` entry fails fast before any step runs.

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` (~124 tokens)

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 `suggestions` and a `ping.ok: false` block when the API is unreachable.

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` (~93 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`, ETHORA_APP_TOKEN env, or `ethora-app-select`). Errors: returns an error if no `appToken` is configured. Related: use after `ethora-app-select`.

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

Switch this session's active auth mode to user-session, so subsequent calls authenticate as a logged-in Ethora user.
Auth: the switch needs nothing, but user-auth tools only work once `ethora-user-login` stores a user token (login also needs a configured `appJwt`). Errors: none on the switch; downstream tools return 401 until login succeeds. Related: follow with `ethora-user-login`.

### `ethora-auth-use-b2b` (~135 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` (JWT with `type=server`) to already be configured (via `ethora-configure` or ETHORA_B2B_TOKEN env). Errors: returns an error if no `b2bToken` is configured. Related: server-side automation — pairs with `ethora-b2b-app-create`, `ethora-users-batch-create-v2`, `ethora-app-tokens-*-v2`.

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

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 non-existent `appId` is not validated here; the first app-scoped API call surfaces the 404. Related: 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` (~280 tokens)

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.
Auth: app-token mode OR B2B mode with an explicit `appId`. Errors: 401/403 wrong auth; 400 no target or conflicting targets; 404 unknown `appId` or room. Related: track with `ethora-wait-broadcast-job-v2`.

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` (~180 tokens)

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).
Auth: app-token mode OR B2B mode with an explicit `appId` — must match the auth used to enqueue the job. Errors: 401/403 wrong auth; 404 unknown `jobId`. Related: `ethora-wait-broadcast-job-v2` for a blocking wait.

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` (~242 tokens)

Block until a broadcast job reaches a terminal state (`completed` or `failed`) or until `timeoutMs` — read-only polling wrapper around `ethora-chats-broadcast-job-v2`. Returns `{ done, state, job }`, or `{ done: false, reason: "timeout" }` on timeout.
Auth: app-token mode OR B2B mode with an explicit `appId` — must match the auth used to enqueue the job. Errors: 401/403 wrong auth; 404 unknown `jobId`.

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` (~134 tokens)

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 exceeded; 422 unsupported mime type. Related: manage with `ethora-files-get-v2` / `ethora-files-delete-v2`.

Input parameters:

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

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

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.
Auth: user-auth mode with an active user session. Errors: 401 not logged in; 404 unknown `id` or not owned by the user.

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` (~113 tokens)

Permanently delete one of the authenticated user's files by id (`DELETE /v2/files/:id`). Removes the record and its stored content; not reversible.
Auth: user-auth mode with an active user session. Errors: 401 not logged in; 403 not owned by the user; 404 unknown `id`. Related: 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` (~209 tokens)

Crawl a website URL and ingest its content into an app's RAG sources (legacy user-auth route). Async — pages become queryable once indexing finishes; `followLink: true` follows in-domain links and can ingest many pages.
Auth: user-auth mode, active session; the user must own the app. Errors: 401 not logged in; 403 not owner; 400 malformed `url`; 404 unknown `appId`. Related: 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` (~196 tokens)

Re-crawl and re-embed a previously crawled URL by its `urlId`, refreshing the RAG content for that page (legacy user-auth route). Async — the existing source record is updated in place once indexing finishes.
Auth: user-auth mode, active session; the user must own the app. Errors: 401 not logged in; 403 not owner; 404 unknown `appId` or `urlId`. Related: get `urlId` from `ethora-sources-site-list-v2`; app-token/B2B uses `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` (~181 tokens)

Remove a single crawled URL from an app's RAG sources, matched by its exact url string (legacy user-auth route). Deletes the source record and its embeddings; not reversible. Matches on the exact stored URL string.
Auth: user-auth mode, active session; the user must own the app. Errors: 401 not logged in; 403 not owner; 404 `url` not a crawled source. Related: get the stored value from `ethora-sources-site-list-v2`.

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` (~187 tokens)

Bulk-remove crawled URLs (1–100) from an app's RAG sources in one call, matched by exact url strings (legacy owner/admin user-auth route). Deletes each matching source record and its embeddings; not reversible. URLs not present are skipped.
Auth: user-auth mode, active session; the user must own the app. Errors: 401 not logged in; 403 not owner; 404 unknown `appId`. Related: single-URL variant `ethora-sources-site-delete-url`.

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` (~170 tokens)

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.
Auth: user-auth mode, active session; the user must own the app. Errors: 401 not logged in; 403 not owner; 413 too large; 422 unsupported document type. Related: 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` (~182 tokens)

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.
Auth: user-auth mode, active session; the user must own the app. Errors: 401 not logged in; 403 not owner; 404 unknown `docId`. Related: get `docId` from `ethora-sources-docs-list-v2`; app-token/B2B uses `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` (~221 tokens)

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.
Auth: app-token mode OR B2B mode with an explicit `appId`. Errors: 401/403 wrong auth; 400 malformed `url`; 404 unknown `appId`. Related: `ethora-sources-site-crawl-v2-wait` (block until done).

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` (~212 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`). Async — the existing source record is updated in place once indexing finishes.
Auth: app-token mode OR B2B mode with an explicit `appId`. Errors: 401/403 wrong auth; 404 unknown `appId` or `urlId`. Related: get `urlId` from `ethora-sources-site-list-v2`; `ethora-sources-site-reindex-v2-wait` blocks 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` (~257 tokens)

Crawl a website URL and block until the server finishes — a single-call, long-timeout variant of `ethora-sources-site-crawl-v2` (same crawl + embed effect). Returns `{ done: true, durationMs, result }`.
Auth: app-token mode OR B2B mode with an explicit `appId`. Errors: 401/403 wrong auth; 400 malformed `url`; 504/timeout if it takes longer than `timeoutMs` (the job may still complete server-side — check with `ethora-sources-site-list-v2`).

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` (~255 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` (same refresh effect). Returns `{ done: true, durationMs, result }`.
Auth: app-token mode OR B2B mode with an explicit `appId`. Errors: 401/403 wrong auth; 404 unknown `appId` or `urlId`; 504/timeout if it takes longer than `timeoutMs` (the job may still complete server-side). Related: get `urlId` 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` (~158 tokens)

List an app's crawled website sources, including each source's id, URL, and current RAG tags. Their ids feed `ethora-sources-site-tags-update-v2`, `ethora-sources-site-delete-url-v2-batch`, and `ethora-sources-site-reindex-v2`.
Auth: app-token mode OR B2B mode with an explicit `appId`. Errors: 401/403 wrong auth; 404 unknown `appId`; empty list if nothing has been crawled.

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` (~241 tokens)

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.
Auth: app-token mode OR B2B mode with an explicit `appId`. Errors: 401/403 wrong auth; 404 unknown `appId` or `sourceId`. Related: get `sourceId` from `ethora-sources-site-list-v2`; 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` (~217 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`). Deletes the source record and its embeddings; not reversible. Matches on the exact stored URL string.
Auth: app-token mode OR B2B mode with an explicit `appId`. Errors: 401/403 wrong auth; 404 `url` not a crawled source. Related: get the stored value from `ethora-sources-site-list-v2`; bulk-by-id is `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` (~200 tokens)

Upload documents (1–5; PDF, text, etc.) into an app's RAG sources (app-token / B2B variant of `ethora-sources-docs-upload`). Async — content becomes queryable once indexing finishes; files passed as base64, 50MB max each.
Auth: app-token mode OR B2B mode with an explicit `appId`. Errors: 401/403 wrong auth; 404 unknown `appId`; 413 too large; 422 unsupported document type. Related: `ethora-sources-docs-list-v2`, `ethora-sources-docs-delete-v2`.

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` (~162 tokens)

List an app's ingested documents, including each document's id, name, and current RAG tags. Their ids feed `ethora-sources-docs-tags-update-v2` and `ethora-sources-docs-delete-v2`.
Auth: app-token mode OR B2B mode with an explicit `appId`. Errors: 401/403 wrong auth; 404 unknown `appId`; empty list if nothing has been uploaded. Related: 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` (~242 tokens)

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.
Auth: app-token mode OR B2B mode with an explicit `appId`. Errors: 401/403 wrong auth; 404 unknown `appId` or `docId`. Related: get `docId` from `ethora-sources-docs-list-v2`; 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` (~189 tokens)

Remove a previously ingested document from an app's RAG sources by `docId` (app-token / B2B variant of `ethora-sources-docs-delete`). Deletes the document record and its embeddings; not reversible.
Auth: app-token mode OR B2B mode with an explicit `appId`. Errors: 401/403 wrong auth; 404 unknown `appId` or `docId`. Related: get `docId` 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` (~215 tokens)

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-use-b2b` + a configured `b2bToken`). Errors: 401/403 not in B2B mode; 422 `usersList` validation. Related: track with `ethora-wait-users-batch-job-v2`.

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` (~179 tokens)

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.
Auth: B2B mode (`ethora-auth-use-b2b` + a configured `b2bToken`) — must match the auth used to create the job. Errors: 401/403 not in B2B mode; 404 unknown `jobId`. Related: `ethora-wait-users-batch-job-v2` for a blocking wait.

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` (~204 tokens)

Block until a users batch job reaches a terminal state (`completed` or `failed`) or `timeoutMs` — read-only polling wrapper around `ethora-users-batch-job-v2`. Returns `{ done, state, job }`, or `{ done: false, reason: "timeout" }` on timeout.
Auth: B2B mode (`ethora-auth-use-b2b` + a configured `b2bToken`) — must match the auth used to create the job. Errors: 401/403 not in B2B mode; 404 unknown `jobId`.

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` (~164 tokens)

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-use-b2b` + a configured `b2bToken`). Errors: 401/403 not in B2B mode; 400 no `appId` and none selected; 404 unknown `appId`.

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` (~232 tokens)

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-use-b2b` + a configured `b2bToken`). Errors: 401/403 not in B2B mode; 400 no `appId` and none selected; 404 unknown `appId`. Related: manage with `ethora-app-tokens-list-v2` / `-rotate-v2` / `-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` (~246 tokens)

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.
Auth: B2B mode (`ethora-auth-use-b2b` + a configured `b2bToken`). Errors: 401/403 not in B2B mode; 400 no `appId` and none selected; 404 unknown `appId` or `tokenId`. Related: `ethora-app-tokens-revoke-v2` 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` (~222 tokens)

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.
Auth: B2B mode (`ethora-auth-use-b2b` + a configured `b2bToken`). Errors: 401/403 not in B2B mode; 400 no `appId` and none selected; 404 unknown `appId`. Related: get `tokenId` from `ethora-app-tokens-list-v2`; `ethora-app-tokens-rotate-v2` for revoke-and-replace.

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` (~401 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. 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 (`ethora-auth-use-b2b` + a configured `b2bToken`). Errors: aborts with the partial step log if app creation fails; previous auth mode restored best-effort. Related: `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` (~173 tokens)

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-use-user` first) and a configured `appJwt`. Errors: 401/403 bad credentials; 404 email not registered; 429 per-IP rate limit — retry with backoff.

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` (~216 tokens)

Ethora registration

Register a new Ethora end-user account by email + first/last name. Creates a pending user record and triggers a verification email — the user must click the link before `ethora-user-login` succeeds.
Auth: user-auth mode and a configured `appJwt` (tells the server which app the user belongs to). Errors: 401 no `appJwt`; 422 email already registered, invalid names, or invalid `appJwt`. Related: bulk provisioning uses `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` (~108 tokens)

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.
Auth: user-auth mode, active session (`ethora-user-login` first). Errors: 401 not logged in; empty list if the user owns no apps. Related: feed `appId` into `ethora-app-update` / `ethora-app-select`.

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

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`.
Auth: user-auth mode, active session (`ethora-user-login` first). Errors: 401 not logged in; 402/403 plan limit reached; 422 invalid `displayName`. Related: server-side provisioning uses `ethora-b2b-app-create`.

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` (~323 tokens)

Update mutable fields on an app the caller owns (displayName, domainName, appDescription, primaryColor, botStatus). Partial update — omitted fields are left unchanged.
Auth: user-auth mode, active session; the caller must own the app. Errors: 401 not logged in; 403 not owner; 404 unknown `appId`; 422 validation (e.g. `domainName` taken, `primaryColor` not `#RRGGBB`).

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` (~106 tokens)

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 `ethora-app-select`. Errors: 400 no app currently selected; 401 not logged in. Related: `ethora-app-get-default-rooms-with-app-id` to pass `appId` explicitly.

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

Create a new chat room (MUC room) inside an app the caller owns. If `pinned: true` the room is added to the app's default rooms (new users auto-join; existing users are not). Returns the new room object including its JID.
Auth: user-auth mode, active session; the caller must own the app. Errors: 401 not logged in; 403 not owner; 404 unknown `appId`; 422 invalid `title`.

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` (~195 tokens)

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.
Auth: user-auth mode, active session; the caller must own the app. Errors: 401 not logged in; 403 not owner; 404 `chatJid` not a room in the app.

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` (~142 tokens)

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.
Auth: user-auth mode, active session; the caller needs read access (ownership or room membership). Errors: 400 no `appId` and none selected; 401 not logged in; 403 no read access; 404 unknown `appId`.

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` (~53 tokens)

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.

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

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-use-b2b` + a configured `b2bToken`). Errors: 401/403 not in B2B mode or invalid `b2bToken`; 422 invalid `displayName`. Related: all-in-one path is `ethora-b2b-app-bootstrap-ai` / `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` (~214 tokens)

Turn on the AI bot for an app via B2B auth (sets `botStatus: "on"`). The bot only actually responds if a prompt + LLM are configured (see `ethora-bot-update-v2`) and the backend has an AI service set up.
Auth: B2B mode (`ethora-auth-use-b2b` + a configured `b2bToken`). Errors: 401/403 not in B2B mode; 400 no `appId` and none selected; 404 unknown `appId`. Related: full bot config via `ethora-bot-update-v2`.

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` (~132 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 OR B2B mode with an explicit `appId`. Errors: 401/403 wrong auth; 404 unknown `appId`. Related: change config with `ethora-bot-update-v2`.

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` (~621 tokens)

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).
Auth: app-token mode OR B2B mode with an explicit `appId`. Errors: 401/403 wrong auth; 404 unknown `appId`; 422 validation (e.g. an `llmProvider`/`llmModel` not enabled). Related: `ethora-bot-get-v2`, `ethora-agents-activate-v2`.

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` (~191 tokens)

Turn the AI bot on for an app (sets bot `status: "on"`), optionally setting its trigger. It only actually responds if a prompt + LLM are configured (see `ethora-bot-update-v2`) and the backend has an AI service.
Auth: app-token mode OR B2B mode with an explicit `appId`. Errors: 401/403 wrong auth; 404 unknown `appId`. Related: `ethora-bot-disable-v2` to turn 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` (~145 tokens)

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.
Auth: app-token mode OR B2B mode with an explicit `appId`. Errors: 401/403 wrong auth; 404 unknown `appId`. Related: `ethora-bot-enable-v2` to turn 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` (~112 tokens)

Read the public chat-widget / embed configuration for the current app's bot (`GET /v2/bot/widget`) — the widget config and public widget URL metadata needed to embed the bot on a website.
Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`). Errors: 401/403 not in app-token mode or invalid appToken. Related: enable/disable via `widgetPublicEnabled` in `ethora-bot-update-v2`.

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

List the reusable saved agents owned by the current app (`GET /v2/agents`) — 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-use-app`). Errors: 401/403 not in app-token mode or invalid appToken; empty list if the app has no saved agents.

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

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).
Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`). Errors: 401/403 wrong auth; 404 `agentId` not an agent of the current app. Related: 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` (~458 tokens)

Create a new reusable saved agent — a named bot definition (prompt + LLM + RAG settings + identity) that can later be activated onto any app (`POST /v2/agents`). Does not activate it — call `ethora-agents-activate-v2` for that. Returns the created agent including its id.
Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`). Errors: 401/403 wrong auth; 422 validation (e.g. duplicate `slug`, unsupported `llmProvider`/`llmModel`).

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` (~473 tokens)

Update fields on an existing reusable saved agent (`PUT /v2/agents/:agentId`). Partial update — omitted fields are left unchanged. If the agent is currently activated on the app, changes take effect on the live bot.
Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`). Errors: 401/403 wrong auth; 404 `agentId` not an agent of the current app; 422 validation. Related: 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` (~211 tokens)

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.
Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`). Errors: 401/403 wrong auth; 404 source `agentId` not found; 422 overridden `slug` collides.

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` (~172 tokens)

Bind a saved agent as the active AI bot for the current app — copies the agent's config onto the app's bot, replacing whatever was there before (`POST /v2/agents/:agentId/activate`). Does not by itself set `status: "on"` — pair with `ethora-bot-enable-v2` if needed.
Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`). Errors: 401/403 wrong auth; 404 `agentId` not an agent of the current app. Related: verify with `ethora-bot-get-v2`.

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` (~262 tokens)

Send a message through the app's chat/bot automation surface — useful for testing the bot or driving automated conversations. Posts a real message; if the app's bot is enabled it reacts to it. `private` mode = 1:1 session keyed by `nickname`, `group` mode = room by `roomJid`.
Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`). Errors: 401/403 wrong auth; 400 missing `roomJid`/`nickname` for the mode; 404 unknown `roomJid`. Related: read back with `ethora-chats-history-v2`.

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` (~228 tokens)

Read the persisted message history of a chat automation session — the conversation produced by `ethora-chats-message-v2` and the bot's replies. Returns the most recent messages (up to `limit`).
Auth: app-token mode (after `ethora-app-select` + `ethora-auth-use-app`). Errors: 401/403 wrong auth; 400 incomplete `mode`/`nickname`/`roomJid`; 404 room/session not found.

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-b2b-app-bootstrap-ai` (~451 tokens)

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 a per-step log including the new `appId`.
Auth: B2B mode (`ethora-auth-use-b2b` + a configured `b2bToken`); internally switches to app-token mode for source-ingest steps. Errors: aborts with the partial step log if app creation fails; previous auth mode restored best-effort. Related: rooms+tokens variant is `ethora-b2b-app-provision`.

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` (~208 tokens)

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.
Auth: none required — pure code generator, no API calls. Errors: effectively none. Security note: the snippet includes `appToken` inline only as a quickstart convenience — do not ship hardcoded tokens to production.

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` (~144 tokens)

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: none required — pure text generator, no API calls. Errors: effectively none.

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` (~186 tokens)

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 actually run the sequence use `ethora-run-recipe` or `ethora-b2b-app-bootstrap-ai`.

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-server/ethora-mcp-server#diagnostics

## Score history

- 2026-08-03: 70
- 2026-08-02: 69
- 2026-08-01: 39
- 2026-07-31: 24
- 2026-07-30: 51
- 2026-07-28: 51
- 2026-07-27: 51

## Links

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