Skip to main content
Glama

Ethora MCP Server (Model Context Protocol)

npm Node License Glama score Wellknown: live

Add the hosted server in one click. You sign in through your browser; there is nothing to install and no key to paste.

Add to Cursor Install in VS Code Install in VS Code Insiders

For Claude.ai, ChatGPT, Claude Desktop, LM Studio and anything else that takes a connector URL, add https://mcp.chat.ethora.com/mcp/oauth and sign in. Running it yourself instead? See Using with stdio clients.

The MCP server for Ethora, an open-source chat and messaging platform with a built-in AI agent framework. It lets Claude, ChatGPT, Cursor, Claude Code, VS Code and autonomous agents create Ethora apps, chat rooms, users and AI agents, post messages, index RAG sources and produce website chat-widget embeds, all through tool calls.

Part of the Ethora SDK ecosystem. Cross-SDK updates: Release Notes. Package changes: CHANGELOG.md.

Three ways to use it

Where it runs

Best for

Hosted (Ethora Cloud)

https://mcp.chat.ethora.com/mcp (production; https://mcp.chat-qa.ethora.com/mcp is the QA instance)

Claude.ai, ChatGPT, Claude Code, Cursor and agents that talk to Ethora Cloud with no local install

Self-hosted

Ships with the Ethora monoserver deploy; enable services.mcp.enabled in deploy.yml and it is served at mcp.<your domain>/mcp

Dedicated or on-premise Ethora installs; agent traffic never leaves your infrastructure

stdio CLI

npx -y @ethora/mcp-server on your machine, configured with env vars

Local development, CI, and clients that launch a command

The hosted and self-hosted modes are the same server started with ETHORA_MCP_TRANSPORT=http. Every MCP session has private in-memory state: one client's login, selected app or tokens are never visible to another session.

Account memory. Some clients open a new MCP session for every tool call (ChatGPT does), which would lose the selected app between calls. So the server keeps a small snapshot per signed-in account, keyed by the user id in the bearer token: the current app and agent, the appToken the API handed that account for the current app, and the enabled tool groups. A new session that arrives with a token for the same account (OAuth, personal URL or Bearer header) gets it back, after the token has been validated against the API. Memory lives in the process, expires after 24 hours idle, and never holds the user token itself. Two more defaults close the same gap: ethora-app-create selects the new app, and an account that owns exactly one app has it selected automatically on the first app-scoped call.

Related MCP server: MCP REST Server

60-second quickstart

Claude.ai or ChatGPT (custom connector). In the Ethora web app open Account, then the AI Assistants tab, create an API key and copy the personal connector URL it shows (https://mcp.chat.ethora.com/mcp/k/<key>). Paste it as a custom connector. Every conversation is authenticated with no login step. For a listed connector that uses the vendor's OAuth login instead, the URL is https://mcp.chat.ethora.com/mcp/oauth.

Claude Code.

# with a personal connector URL (no headers needed)
claude mcp add --transport http ethora https://mcp.chat.ethora.com/mcp/k/<your API key>

# or the open endpoint plus a Bearer header
claude mcp add --transport http ethora https://mcp.chat.ethora.com/mcp --header "Authorization: Bearer <your API key>"

Cursor, VS Code, and any client that takes a URL and headers.

{
  "mcpServers": {
    "ethora": {
      "url": "https://mcp.chat.ethora.com/mcp",
      "headers": { "Authorization": "Bearer <your API key>" }
    }
  }
}

Autonomous agents with no account yet. Connect to https://mcp.chat.ethora.com/mcp with no credentials and call ethora-user-register with an email, first and last name. It creates the account, logs the session in, and returns a generated password plus an API key and connectorUrl exactly once. Store the key and reconnect later with the Bearer header or the personal URL; nothing else is needed, no browser and no email confirmation.

stdio CLI.

ETHORA_API_URL=https://api.chat.ethora.com/v1 ETHORA_APP_JWT="JWT <your app jwt>" npx -y @ethora/mcp-server

Then ask your agent to call ethora-status, ethora-user-login (or ethora-user-register) and ethora-app-list. Lost at any point, call ethora-help: it reads the current state and returns the recommended next calls.

Entry points and authentication

Entry point

Who supplies identity

Typical client

/mcp (add ?tools=all to list every tool up front)

Nobody at connect time. Call ethora-user-login or ethora-user-register inside the session, or send Authorization: Bearer <token> on every request (user API key, app token or B2B token; the server picks the auth mode from the token type)

Agents, Claude Code, Cursor, connectors added as "no auth"

/mcp/k/<api-key>

The key in the path, applied like a Bearer header

Claude.ai and ChatGPT custom connectors, which take a URL but no headers

/mcp/oauth

An OAuth 2.1 access token obtained through the Ethora authorization server (dynamic client registration, PKCE, access scopes read, write, admin, plus the identity scopes openid and email for directories that require them)

Connector directories (Claude, ChatGPT); vendors run the login flow themselves

stdio

Env vars ETHORA_APP_JWT (login/register bootstrap) and optional ETHORA_B2B_TOKEN, or ethora-session-configure at runtime

Local CLI

Stay in user auth mode on the hosted server (ethora-status shows authMode: user). App-token and B2B modes exist for server integrations; the agents and rooms routes reject app tokens.

API keys

  • ethora-api-key-create { name?, ttlDays? } mints a key (default 90 days, max 365), shown once together with connectorUrl. ethora-user-register mints one by default and ethora-user-login { createApiKey: true } on request.

  • ethora-api-key-list shows id, name, created and expiry, never the value. ethora-api-key-revoke { id } invalidates it immediately: the next request with that key fails with REFRESH_RECORD_NOT_FOUND.

  • The same keys are managed in the Ethora web app under Account, AI Assistants, where the personal URL, a Claude Code one-liner and a Cursor config are shown with copy buttons.

  • A key acts as the user. Treat the personal URL like a password: do not share screenshots of it, revoke it if it leaks. The server never logs request URLs, and the monoserver nginx template logs method and status only on the MCP host.

OAuth 2.1 (/mcp/oauth)

Set ETHORA_MCP_AUTH_ISSUER to the public URL of the Ethora API that hosts the authorization server (the monoserver deploy sets it). The MCP server then:

  • serves RFC 9728 protected-resource metadata at /.well-known/oauth-protected-resource and /.well-known/oauth-protected-resource/mcp/oauth, naming the authorization server and the three scopes;

  • answers unauthenticated requests on /mcp/oauth with 401 and WWW-Authenticate: Bearer resource_metadata="...", which is how clients discover the flow;

  • validates each token against the API once per session (cached five minutes) and enforces the token's scope per tool: read-only tools need read; deleting, revoking and rotating (and revealing a credential) need admin; everything else, including updates that overwrite fields and are therefore marked destructive, needs write. search, fetch, ethora-help, ethora-status and ethora-doctor need no scope. Tokens without a scope claim (API keys) get full access;

  • hides the identity tools (ethora-user-login, ethora-user-register, ethora-session-configure, ethora-auth-mode-set, ethora-auth-mode-set, ethora-api-key-create, ethora-api-key-list, ethora-api-key-revoke) because the token already fixes who you are.

The authorization server itself is part of the Ethora backend: <issuer>/.well-known/oauth-authorization-server, /oauth/register, /oauth/authorize (a consent page with sign-in, account creation and Google sign-in), /oauth/token, /oauth/revoke and /oauth/userinfo. Users see and disconnect OAuth grants under Account, AI Assistants, Connected AI apps. When ETHORA_MCP_AUTH_ISSUER is unset, both OAuth routes return 404 and discovery omits them.

Identity scopes. Some directories (ChatGPT) require the minimal OpenID Connect surface on top of OAuth 2.1: the openid and email scopes and a userinfo endpoint that returns sub, email and email_verified. These scopes grant no access to apps or data; they only let the client see who signed in, and the consent page says so in plain words. There are no ID tokens or JWKS, because nothing consumes them.

Email confirmation is optional. Ethora never blocks sign-up or the dashboard on a confirmed address. When a client asks for the identity scopes and the account's address is not yet confirmed, the consent page adds one step: send the confirmation link, continue after confirming, or continue without sharing the address (the identity scopes are dropped from the grant and everything else proceeds). Google sign-ins arrive confirmed and skip the step. The same confirmation can be sent from Account, AI Assistants in the web app.

What agents can do

The end-to-end journey a new user typically asks for, with the tools in order:

  1. ethora-user-register (or ethora-user-login) to get an authenticated session and an API key.

  2. ethora-app-create { displayName } then ethora-app-select { appId } to make the new app current.

  3. ethora-chat-create { title } to create a group room. The result contains the room JID ${appId}_${chatId}; every room tool accepts the JID or the bare chatId.

  4. ethora-agent-create { name, prompt, ... } to create an AI agent persona in that app.

  5. ethora-agent-invite { agentIdOrAddress, chatJid } to put the agent in the room. A bot instance is spawned live, no restart needed.

  6. ethora-message-send { text, roomJid, waitForReplySec: 45 } to post a message and wait for the agent's answer, returned as replies. ethora-chat-history reads the room afterwards.

  7. ethora-agent-activate { agentId, chatJid } to make that agent the app's default responder, then ethora-widget-snippet-get for the <script> tag that puts the AI chat widget on a website.

ethora-help { goal } returns this and the other recipes (user-login, broadcast, sources-ingest, files-upload, bot-manage, chat-test, widget, b2b-bootstrap-ai) with the calls filled in for the current state, and ethora-recipe-run executes them.

First-minute conventions

  • Every create tool answers the same way. ethora-app-create, ethora-chat-create, ethora-agent-create return the raw API object plus created (kind, id, name, and jid or address where relevant) and next, two to four suggested calls with arguments filled in. ethora-app-create also returns dashboardUrl, the app in the web dashboard.

  • ethora-help { goal } has a recipe for each headline job: new-app, in-app-chat, multi-agent-room, widget, chat-test, plus the server-integration goals. Each returns the calls in order with arguments to copy.

  • Who spoke. ethora-message-send replies and ethora-chat-history rows carry senderName and senderKind (human, agent, app), so a multi-agent room reads as "Freud: ..., Jung: ..." rather than instance ids.

  • Search understands intent. search maps the phrases people use ("add chat to my React app", "several agents talking to each other", "webhook when a message arrives") to the documents that answer them, and doc:not-available says plainly what is not exposed over MCP and where it lives instead. Whole documents are fetchable by their bare id (doc:recipes, doc:chat-component-quickstart, doc:sdk-backend-quickstart, doc:auth-map).

Documentation inside the server

  • instructions in the initialize result tell the assistant how identity works on the entry point it connected through: the open endpoint explains login and register, personal-URL and Bearer sessions are told they are already authenticated and must never ask for a password or key, OAuth sessions the same plus how to react to INSUFFICIENT_SCOPE.

  • search { query } and fetch { id } (the ChatGPT connector convention) search an in-memory corpus: the auth map, quickstarts, recipes, a hosted getting-started guide, an API keys guide and one reference entry per tool with its inputs. They work unauthenticated.

  • Resources ethora://docs/auth-map, ethora://docs/chat-component/quickstart, ethora://docs/sdk-backend/quickstart, ethora://docs/recipes and prompts ethora-auth-map, ethora-vite-quickstart, ethora-nextjs-quickstart, ethora-backend-sdk-quickstart, ethora-recipes, ethora-agents-quickstart.

Tool groups

A session lists the core group only at first: 24 tools covering the whole "sign in, create an app, add rooms and messages, create and activate an agent, give it a knowledge base, get the widget" journey, one variant per operation. The other groups are registered but hidden, which keeps tools/list around 40 KB instead of 120 KB and gives assistants a short list to choose from.

Three ways to get more:

  • ethora-tools-enable { group } enables a group for the session (or { group: "all" }); the server sends tools/list_changed and the client refreshes. With no arguments it returns the catalogue with counts.

  • Calling a hidden tool by name enables its group and runs it, so a name learned from the docs or an earlier session is never refused.

  • ?tools=all on the endpoint URL (hosted) or ETHORA_MCP_TOOLS=all (stdio) lists everything up front.

search and fetch describe hidden tools too; every tool doc names its group, and doc:tool-groups is the catalogue. Legacy and async variants carry a first line naming the preferred sibling.

Group

What it covers

Tools

core (listed by default)

Sign in or register, create an app, add rooms and messages, create and activate an AI agent, give it a knowledge base, get the website widget. Always listed.

ethora-status, ethora-help, ethora-feedback-submit, ethora-tools-enable, search, fetch, ethora-user-register, ethora-user-login, ethora-api-key-create, ethora-app-create, ethora-app-list, ethora-app-select, ethora-app-update, ethora-chat-create, ethora-message-send, ethora-chat-history, ethora-agent-create, ethora-agent-list, ethora-agent-update, ethora-agent-invite, ethora-agent-activate, ethora-source-site-crawl-wait, ethora-source-doc-upload, ethora-widget-snippet-get

keys

List and revoke API keys, reveal an app's credentials, mint and rotate app tokens.

ethora-api-key-list, ethora-api-key-revoke, ethora-app-credentials-reveal, ethora-app-token-create, ethora-app-token-list, ethora-app-token-revoke, ethora-app-token-rotate

session

Diagnostics, recipes and switching the session's auth mode (app token, B2B token) for server integrations.

ethora-doctor, ethora-recipe-run, ethora-session-configure, ethora-auth-mode-set, ethora-auth-mode-set, ethora-auth-mode-set

apps-admin

Delete, export and import whole apps; inspect default rooms.

ethora-app-delete, ethora-app-export, ethora-app-import, ethora-app-rooms-list, ethora-app-rooms-list

rooms

Delete rooms, broadcast to many rooms, search messages, read message context and unread counts.

ethora-chat-delete, ethora-broadcast-send, ethora-broadcast-job-get, ethora-broadcast-job-wait, ethora-message-search, ethora-message-context, ethora-chat-unread-counts

agents-admin

Inspect, clone (with or without its knowledge), delete, export and import agents; try an agent without a room; check and rebuild its knowledge index; edit its Memory and visibility.

ethora-agent-get, ethora-agent-clone, ethora-agent-delete, ethora-agent-export, ethora-agent-import, ethora-agent-visibility-set, ethora-agent-soul-set, ethora-agent-soul-append, ethora-agent-try, ethora-agent-knowledge-get, ethora-agent-knowledge-rebuild

sources

Knowledge-base maintenance: async crawl and reindex jobs, stop a crawl, list and tag sites and documents, delete URLs and documents.

ethora-source-site-crawl, ethora-source-site-crawl-cancel, ethora-source-site-reindex, ethora-source-site-reindex-wait, ethora-source-site-list, ethora-source-site-watch-list, ethora-source-site-watch-update, ethora-source-site-refresh, ethora-source-site-tags-update, ethora-source-site-url-delete, ethora-source-site-url-delete-batch, ethora-source-doc-list, ethora-source-doc-tags-update, ethora-source-doc-delete

widget

Read and change the website widget's saved look (colours, fonts, size, launcher, teaser, texts); live embeds pick it up without a new snippet.

ethora-widget-appearance-get, ethora-widget-appearance-set

users-files

Batch-create users and upload, fetch or delete files.

ethora-user-batch-create, ethora-user-batch-job-get, ethora-user-batch-job-wait, ethora-file-upload, ethora-file-get, ethora-file-delete

legacy-bot

The per-app bot of apps created in the dashboard before the agents framework, and the pre-v2 document tools. Prefer the agents and sources tools for anything new.

ethora-bot-get, ethora-bot-update, ethora-bot-enable, ethora-bot-disable, ethora-bot-widget-get, ethora-bot-history, ethora-bot-message-send, ethora-bot-instance-list, ethora-bot-instance-status-set, ethora-bot-instance-diagnose, ethora-bot-instance-leave, ethora-bot-instance-test, ethora-bot-enable-b2b, ethora-source-doc-upload-legacy, ethora-source-doc-delete-legacy

b2b

Server-to-server provisioning with a B2B token, plus code and config generators for integrations.

ethora-b2b-app-create, ethora-b2b-app-provision, ethora-b2b-app-bootstrap-ai, ethora-b2b-runbook-generate, ethora-env-examples-generate, ethora-chat-component-app-generate, ethora.b2b.auth.use, ethora.b2b.app.create, ethora.b2b.bot.enable, ethora.b2b.broadcast.wait, ethora.b2b.app.bootstrap-ai

wallet

Wallet balance and ERC-20 transfer. Local (stdio) only; never offered on the hosted server.

ethora-wallet-balance-get, ethora-wallet-erc20-transfer

App deletion and bulk-delete tools are only registered when ETHORA_MCP_ENABLE_DANGEROUS_TOOLS=true (the monoserver deploy sets it; the stdio default is off). Alias tools (ethora.b2b.*, ethora-bot-message-send, ethora-bot-history) are off by default (ETHORA_MCP_ENABLE_ALIASES=true to expose them); the canonical tools cover the same ground.

Website widget

ethora-widget-snippet-get returns the tag for the embeddable AI chat widget:

<script id="chat-content-assistant" src="https://widget.<your domain>/assistant.js"
  data-app-id="<appId>" data-api-base="https://api.<your domain>" defer></script>

The widget's look (colours, fonts, size, launcher, teaser bubble, texts) is saved on the app: ethora-widget-appearance-set { appearance: { "data-primary-color": "#7c3aed" } } (the widget group), the same setting as App settings > AI Widget in the admin panel. Every embed loads it when it opens, so later changes reach live sites without a new snippet. A data-* attribute written on the tag wins over the saved value on that site.

The widget answers with the app's active bot (defaultBotInstanceId). On an app created through the API run ethora-agent-create, ethora-chat-create, ethora-agent-invite and ethora-agent-activate { agentId, chatJid } first; the tool lists these prerequisites and ethora-help { goal: "widget" } walks through them. Activation runs in user auth by setting the app's default bot instance (what the admin AI Widget dropdown does). Until a bot is active, the widget's session endpoint answers AI_BOT_NOT_CONFIGURED. ethora-chat-component-app-generate produces a React App.tsx for @ethora/chat-component instead.

Configuration

Env vars (stdio and hosted)

Variable

Meaning

ETHORA_API_URL

Full API URL, e.g. https://api.chat.ethora.com/v1 (default). On a hosted server it is fixed for all sessions

ETHORA_BASE_URL

Host-only alternative to ETHORA_API_URL; /v1 is appended

ETHORA_APP_JWT

App JWT used only by login and register (ETHORA_APP_TOKEN is a legacy alias)

ETHORA_APP_DOMAIN_NAME

Base app domainName; when ETHORA_APP_JWT is empty the server fetches the app JWT from GET /v1/apps/get-config?domainName=... at startup

ETHORA_B2B_TOKEN

B2B server token for x-custom-token tenant-actor routes

ETHORA_MCP_TOOLS

all lists every tool from the start instead of the core group (stdio; hosted uses ?tools=all on the URL)

ETHORA_MCP_ENABLE_DANGEROUS_TOOLS

true registers app deletion, wallet transfer and bulk-delete tools (default off)

ETHORA_MCP_OPENAI_APPS_CHALLENGE

Hosted only. Token issued by the OpenAI apps portal for domain verification; served verbatim at /.well-known/openai-apps-challenge (404 when unset)

ETHORA_MCP_ENABLE_ALIASES

true exposes the dot-namespaced alias tools (default off)

Hosted mode only

Variable

Meaning

ETHORA_MCP_TRANSPORT

stdio (default) or http; --http on the command line does the same

ETHORA_MCP_HTTP_HOST, ETHORA_MCP_HTTP_PORT

Bind address, default 127.0.0.1:3030; put nginx in front

ETHORA_MCP_PUBLIC_URL

Public base URL advertised in discovery and used for connectorUrl, e.g. https://mcp.chat.ethora.com/mcp

ETHORA_MCP_TRUST_PROXY

true takes the client IP from X-Forwarded-For; it is forwarded to the API so per-IP limits apply per caller

ETHORA_MCP_SESSION_TTL_MS

Idle session eviction, default 4 hours

ETHORA_MCP_ACCOUNT_MEMORY_TTL_MS

How long an account's remembered context (current app, agent, enabled groups) survives without a session, default 24 hours

ETHORA_MCP_AUTH_ISSUER

Public URL of the OAuth authorization server (the Ethora API host); enables /mcp/oauth

ETHORA_MCP_WIDGET_URL

Base URL of the hosted AI chat widget (<url>/assistant.js) for ethora-widget-snippet-get

ETHORA_MCP_PUBLIC_API_URL

Public API base browsers can reach, emitted as data-api-base; falls back to ETHORA_MCP_AUTH_ISSUER, then a non-loopback ETHORA_API_URL

A .env file in the working directory is loaded at startup; real environment variables win. Credentials can also be set per session with ethora-session-configure (in memory only; on a hosted server apiUrl cannot be changed).

Endpoints (hosted)

Path

Purpose

POST|GET|DELETE /mcp

Streamable HTTP MCP endpoint, open

POST|GET|DELETE /mcp/k/<api-key>

Same, authenticated by the key in the path

POST|GET|DELETE /mcp/oauth

Same, Bearer token required, scopes enforced

GET /healthz

{ ok, sessions, version, appJwtReady, oauth }

GET /.well-known/mcp and GET /

Discovery JSON: endpoint, transport, auth options, OAuth metadata

GET /.well-known/oauth-protected-resource[/mcp/oauth]

RFC 9728 protected-resource metadata

Response envelope

Every tool returns JSON text in one shape: success { ok: true, ts, meta, data }, failure { ok: false, ts, meta, error } where error carries code (the API's own code when it has one), message, httpStatus, requestId and a one-line hint.

Using with stdio clients

Every stdio client runs npx -y @ethora/mcp-server; pass credentials as env vars (preferred) or call ethora-session-configure for a quick local test (its arguments end up in the transcript). For hosted mode use the one-click buttons at the top of this README, or the URL form in the quickstart. One-click buttons for the stdio package:

Add to Cursor Install in VS Code Install in VS Code Insiders

Cursor

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

VS Code (and GitHub Copilot agent mode)

.vscode/mcp.json (note the key is servers):

{ "servers": { "ethora": { "command": "npx", "args": ["-y", "@ethora/mcp-server"] } } }

Claude Code

claude mcp add ethora -e ETHORA_API_URL=https://api.chat.ethora.com/v1 -e ETHORA_APP_JWT="JWT <your app jwt>" -- npx -y @ethora/mcp-server

Add --scope user to make it available in every project; verify with claude mcp list.

Claude Desktop

Settings, Developer, Edit Config (claude_desktop_config.json):

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

Gemini CLI, Windsurf, Cline

Same mcpServers block as above in ~/.gemini/settings.json, ~/.codeium/windsurf/mcp_config.json or cline_mcp_settings.json.

Codex CLI

~/.codex/config.toml (the table is mcp_servers with an underscore):

[mcp_servers.ethora]
command = "npx"
args = ["-y", "@ethora/mcp-server"]

Container

docker build -t ethora-mcp-server .
docker run -i --rm -e ETHORA_API_URL=https://api.chat.ethora.com/v1 -e ETHORA_APP_JWT="JWT <your app jwt>" ethora-mcp-server

Add -e ETHORA_MCP_TRANSPORT=http -e ETHORA_MCP_HTTP_HOST=0.0.0.0 -p 3030:3030 to run the hosted mode in a container.

B2B provisioning (server integrations)

With ETHORA_B2B_TOKEN configured, ethora-auth-mode-set switches the session to tenant-actor auth and ethora-b2b-app-bootstrap-ai creates an app, indexes sources (crawlUrl, docs[] as base64) and configures its bot in one call, with optional llmProvider and llmModel. ethora-b2b-app-provision adds app tokens and default rooms. ethora-user-batch-create plus ethora-user-batch-job-wait provision users asynchronously and ethora-broadcast-send plus ethora-broadcast-job-wait send a message to many rooms. ethora-b2b-runbook-generate prints the call order for your own automation.

Troubleshooting

Symptom

Meaning and fix

TOKEN_MISSING (401)

The session has no user token. Call ethora-user-login or ethora-user-register, or connect with a Bearer header or personal URL

REFRESH_RECORD_NOT_FOUND (401)

The API key or token was revoked. Create a new key

INSUFFICIENT_SCOPE (403) on /mcp/oauth

The OAuth grant lacks the scope the tool needs (read, write or admin). Reconnect and approve the wider scope

This tool requires app-token auth or AUTH_USER_REQUIRED

Wrong auth mode. On the hosted server stay in user mode (ethora-auth-mode-set); app-token mode is only for /v2/bot and widget routes

AI_BOT_NOT_CONFIGURED from the widget

No active bot on the app. Run the agent, invite and ethora-agent-activate steps, then reload the page

BOT_NOT_INITIALIZED (422) from ethora-bot-*

The app has no legacy per-app bot; use the agents tools instead

AGENT_NOT_FOUND or APP_NOT_FOUND (404)

Wrong id or the app was not selected; ethora-app-select first, or pass appId

Not Acceptable (406) from /mcp

The client must accept both application/json and text/event-stream

Consent page says Social sign-in failed (auth/...)

The Firebase code in parentheses names the cause (the browser console has the full error). auth/popup-blocked: allow popups for the API host. A message with no code was fixed in the backend on 2026-09-17; update if you self-host

Client cannot connect (stdio)

Run npx -y @ethora/mcp-server in a terminal and check Node 18 or newer

Hosted server not answering

GET /healthz; appJwtReady: false means the base app JWT bootstrap failed (check ETHORA_APP_DOMAIN_NAME and ETHORA_API_URL)

Feedback

ethora-feedback-submit sends a report (bug, unexpected, feature, docs, other) to the Ethora team from inside a session. The point of doing this over MCP rather than a web form is context: the session's last few tool failures travel with the report - tool name, error code and the API requestId - so a report can be joined to the server-side log entry instead of being re-typed from memory. Set includeRecentErrors: false when the report is unrelated to a failure.

It works whether or not the session is authenticated, because the reporter we most need to hear from is the one whose sign-up or credential is the thing that broke; an authenticated report is attributed to that account, and an anonymous one may carry an email for a reply. It is also exempt from OAuth scope enforcement, so a read-only grant can still report a problem.

Credential-shaped keys in the attached context are redacted before sending. That is key-based, so it cannot catch a credential pasted into the free-text message: the tool description tells the model not to put secrets or end-user personal data there.

Delivery is configured on the API side (FEEDBACK_EMAIL_TO, FEEDBACK_SLACK_WEBHOOK_URL, FEEDBACK_RETENTION_DAYS); the MCP server only submits.

Usage attribution

Outbound API calls carry X-Ethora-Client: mcp/<version> and, for the duration of a tool call, X-Ethora-Tool: <tool-name>. The API records these on its request log as client and source: mcp:<tool>, which is how MCP traffic is separated from the web app and counted per tool. The public unauthenticated endpoints (/ping, /apps/get-config) are left unattributed.

Security notes

  • Credentials are redacted from tool results. appSecret, tenantSecret, appToken, passwords and similar keys come back as [redacted] from every tool (results enter the model's context and client logs). ethora-app-credentials-reveal { appId, confirm: true } reveals an app's appToken on purpose and needs the admin scope over OAuth; the App Secret is only ever shown in the web dashboard API tab. Login, register and the api-key / app-token minting tools still return their credential once by design.

  • API keys and personal URLs act as the user until revoked. Keep them in your client's secret store, never in shared config or screenshots, and revoke on suspicion.

  • The server never logs request URLs or tokens. Keep your reverse proxy's access log free of request paths for the MCP host (the monoserver nginx template does).

  • Anything returned by a tool is visible to the model and stored in the conversation transcript; the server tells assistants not to print keys or passwords, and to confirm destructive tools with the user.

  • This repo runs report-only secret and SAST scans (gitleaks, semgrep) on pushes and PRs.

Development

Version numbers

Versions are calendar-based: YY.M.patch, where YY.M is the year and month the release ships (26.9.5 is the fifth September 2026 release, 26.10.0 the first of October) and patch counts releases within the month. No leading zero on the month, so 26.10 sorts after 26.9 under semver. Breaking changes do not bump a major; they get the next patch and a changelog entry, and earlier tool names stay callable as aliases. npm run sync-version refuses any other shape or any month other than the current one (ETHORA_VERSION_MONTH=YY.M overrides on purpose), and the publish workflow runs it. 27.0.0 and 27.1.0, published on 2026-09-24 against this rule, are deprecated; 26.9.5 is the same code.

Tool naming

Since 27.0 every listed tool follows one rule: ethora-<resource>-<verb>[-<qualifier>].

  • resource is a singular noun, one or two words: app, agent, chat, message, broadcast, source-site, source-doc, user, file, bot, api-key, app-token, widget, wallet, session, auth-mode, recipe, tools.

  • verb is the last word: create, list, get, update, delete, send, set, run, reveal, upload, crawl, reindex, start, wait, enable, disable, generate.

  • a qualifier only ever follows the verb: -wait (blocking form of an async job), -batch, -legacy, -b2b.

  • no API-version suffixes: -v2 is gone from every name. search and fetch keep their names by ChatGPT connector convention.

Every earlier name still works. Old names are aliases: never listed by tools/list, but a call to one is rewritten to the canonical tool (with a preset argument where three or two tools became one, such as ethora-auth-use-app becoming ethora-auth-mode-set { mode: "app" }), so published configs, recipes and saved conversations keep working. Results and usage attribution name the canonical tool. The full mapping is in the alias table at the end of this file and in src/toolNames.ts, which the test suite checks against the registry.

  • ethora-chat-component: the React chat component used in widgets and stand-alone apps

  • ethora-monoserver: deploy automation that ships this server as an optional service (private repository, available to enterprise customers)

  • ethora-wp-plugin: WordPress integration

  • rag_demos: RAG AI assistant examples

Quality and maintenance score

Independently inspected by Glama, which builds the server, catalogues its tools and rates tool-definition quality and maintenance activity.

Ethora MCP Server quality and maintenance score on Glama

Earlier tool names

Names used before 27.0 and the tool each one now resolves to. All of them remain callable.

Earlier name

Canonical tool

ethora-agents-activate-v2

ethora-agent-activate

ethora-agents-clone-v2

ethora-agent-clone

ethora-agents-create-v2

ethora-agent-create

ethora-agents-delete-v2

ethora-agent-delete

ethora-agents-export-v2

ethora-agent-export

ethora-agents-get-v2

ethora-agent-get

ethora-agents-import-v2

ethora-agent-import

ethora-agent-invite-to-chat

ethora-agent-invite

ethora-agents-list-v2

ethora-agent-list

ethora-agents-update-v2

ethora-agent-update

ethora-agent-set-visibility

ethora-agent-visibility-set

ethora-app-credentials

ethora-app-credentials-reveal

ethora-app-export-v2

ethora-app-export

ethora-app-import-v2

ethora-app-import

ethora-app-get-default-rooms

ethora-app-rooms-list

ethora-app-get-default-rooms-with-app-id

ethora-app-rooms-list

ethora-app-tokens-create-v2

ethora-app-token-create

ethora-app-tokens-list-v2

ethora-app-token-list

ethora-app-tokens-revoke-v2

ethora-app-token-revoke

ethora-app-tokens-rotate-v2

ethora-app-token-rotate

ethora-auth-use-app

ethora-auth-mode-set with {"mode": "app"}

ethora-auth-use-b2b

ethora-auth-mode-set with {"mode": "b2b"}

ethora-auth-use-user

ethora-auth-mode-set with {"mode": "user"}

ethora.b2b.auth.use

ethora-auth-mode-set with {"mode": "b2b"}

ethora.b2b.app.bootstrap-ai

ethora-b2b-app-bootstrap-ai

ethora.b2b.app.create

ethora-b2b-app-create

ethora-generate-b2b-bootstrap-runbook

ethora-b2b-runbook-generate

ethora-bot-disable-v2

ethora-bot-disable

ethora-bot-enable-v2

ethora-bot-enable

ethora-b2b-bot-enable

ethora-bot-enable-b2b

ethora.b2b.bot.enable

ethora-bot-enable-b2b

ethora-bot-get-v2

ethora-bot-get

ethora-bot-history-v2

ethora-bot-history

ethora-bot-instance-diag

ethora-bot-instance-diagnose

ethora-bot-instance-leave-chat

ethora-bot-instance-leave

ethora-bot-instances-list

ethora-bot-instance-list

ethora-bot-instance-status

ethora-bot-instance-status-set

ethora-bot-instance-test-message

ethora-bot-instance-test

ethora-bot-message-v2

ethora-bot-message-send

ethora-bot-update-v2

ethora-bot-update

ethora-bot-widget-v2

ethora-bot-widget-get

ethora-chats-broadcast-job-v2, ethora-broadcast-job-start

ethora-broadcast-job-get

ethora-wait-broadcast-job-v2

ethora-broadcast-job-wait

ethora.b2b.broadcast.wait

ethora-broadcast-job-wait

ethora-chats-broadcast-v2

ethora-broadcast-send

ethora-generate-chat-component-app-tsx

ethora-chat-component-app-generate

ethora-app-create-chat

ethora-chat-create

ethora-app-delete-chat

ethora-chat-delete

ethora-chats-history-v2

ethora-chat-history

ethora-unread-counts-v2

ethora-chat-unread-counts

ethora-generate-env-examples

ethora-env-examples-generate

ethora-files-delete-v2

ethora-file-delete

ethora-files-get-v2

ethora-file-get

ethora-files-upload-v2

ethora-file-upload

ethora-messages-context-v2

ethora-message-context

ethora-messages-search-v2

ethora-message-search

ethora-chats-message-v2

ethora-message-send

ethora-run-recipe

ethora-recipe-run

ethora-configure

ethora-session-configure

ethora-sources-docs-delete-v2

ethora-source-doc-delete

ethora-sources-docs-delete

ethora-source-doc-delete-legacy

ethora-sources-docs-list-v2

ethora-source-doc-list

ethora-sources-docs-tags-update-v2

ethora-source-doc-tags-update

ethora-sources-docs-upload-v2

ethora-source-doc-upload

ethora-sources-docs-upload

ethora-source-doc-upload-legacy

ethora-sources-site-crawl-v2

ethora-source-site-crawl

ethora-sources-site-crawl-v2-wait

ethora-source-site-crawl-wait

ethora-sources-site-list-v2

ethora-source-site-list

ethora-sources-site-reindex-v2

ethora-source-site-reindex

ethora-sources-site-reindex-v2-wait

ethora-source-site-reindex-wait

ethora-sources-site-tags-update-v2

ethora-source-site-tags-update

ethora-sources-site-delete-url-v2

ethora-source-site-url-delete

ethora-sources-site-delete-url-v2-batch

ethora-source-site-url-delete-batch

ethora-users-batch-create-v2

ethora-user-batch-create

ethora-users-batch-job-v2, ethora-user-batch-job-start

ethora-user-batch-job-get

ethora-wait-users-batch-job-v2

ethora-user-batch-job-wait

ethora-wallet-get-balance

ethora-wallet-balance-get

ethora-widget-embed-snippet

ethora-widget-snippet-get

License

See LICENSE.

Available Tools

24 tools
ethora-agent-activateActivate Agent for WidgetA
Idempotent

Make an agent the app's ACTIVE widget bot: sets App.defaultBotInstanceId (and botStatus: on), which is what POST /v2/widget/sessions uses to decide who answers website visitors. Required before an embedded widget can answer on an API-created app. Preconditions: the agent was invited into a room of this app with ethora-agent-invite (that creates its bot instance). Works in user auth (app update route); falls back to the app-token /v2/agents/:id/activate route when an appToken is stored. Requires: an agent already invited into a room of the selected app (ethora-agent-create -> ethora-chat-create -> ethora-agent-invite); the invite creates the bot instance this tool binds as the app's default responder. Auth: user session (owner of the app). Errors: 404 no bot instance for this agent in the app (invite first); 403 not the app owner. Related: ethora-widget-snippet-get next, ethora-bot-instance-list to inspect.

NameRequiredDescriptionDefault
appIdNoApp to activate the agent for. Defaults to the app from `ethora-app-select`.
agentIdNoId (or address) of the agent to activate. Get it from `ethora-agent-list` / `ethora-agent-create`.
chatJidNoRoom JID `${appId}_${chatId}` (with or without `@conference...`) that becomes the widget chat. Required for API-created apps; omit only for dashboard-created apps that already have an AI Widget chat bound.
agentIdOrAddressNoAlias for `agentId` - either name is accepted, pass whichever you have.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description discloses meaningful behavioral details: which route is used with user auth, the fallback to the app-token route, the required bot instance precondition, auth requirements, and specific 404/403 error conditions. It also names the side effects it sets on the app record. These details add real value beyond the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is longer than average, but it is front-loaded with the core purpose and follows with preconditions, auth, errors, and related tools. The main redundancy is that the invite precondition is stated twice in the 'Preconditions' and 'Requires' paragraphs, which prevents a perfect score.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no output schema, the description still covers the essential invocation context: prerequisites, required setup chain, auth mode, fallback behavior, and error cases. Combined with complete parameter documentation in the schema, an agent has enough information to select and call this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameters are already well documented in the input schema. The description does not add parameter-level meaning beyond what the schema provides, such as details about `chatJid` or the alias relationship, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description starts with a specific verb and resource: making an agent the app's ACTIVE widget bot, and names the concrete setting `App.defaultBotInstanceId` with `botStatus: on`. It also explains the downstream effect on `POST /v2/widget/sessions`, which cleanly distinguishes this activation tool from sibling tools like `ethora-agent-create` or `ethora-agent-invite`.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives strong context for when the tool is needed: it is required before an embedded widget can answer on an API-created app. It also gives preconditions and a related-tool sequence (`ethora-agent-create` -> `ethora-chat-create` -> `ethora-agent-invite`), plus next steps. It lacks an explicit 'when not to use' statement, so it is just short of a perfect score.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-agent-createCreate AgentA

Create a reusable AI agent (POST /v2/apps/:appId/agents). Works in user auth mode (the normal hosted mode) or B2B mode; app-token mode is not accepted by the backend. Each agent is a persona - name, avatar, system prompt, LLM config, plus response-gate settings (responseMode, cooldownSec) that control when it speaks in a room. For multi-agent scenarios (two or more personas conversing in one chat) create each one separately, then ethora-agent-invite them into the same room. See the ethora-agents-quickstart prompt for the end-to-end recipe. To start from a ready-made public agent instead, ethora-agent-list { visibility: "public" } then ethora-agent-clone. Requires: a selected app (ethora-app-select) or an explicit appId. The agent belongs to your account (only you can change it) and is homed in that app; it can still be used in your other apps.

NameRequiredDescriptionDefault
nameNoShort display name. For multi-agent scenarios, prefer single-word names (e.g. 'Hannibal', 'Varro') — the @-mention matcher uses the exact display name with word-boundary matching.
slugNoURL-safe slug (auto-generated from name if omitted).
appIdNo24-char hex appId the agent belongs to (`POST /v2/apps/:appId/agents`). Defaults to the app selected with `ethora-app-select`. Pass it when you just created an app so the agent lands there rather than in the token's own app.
isRAGNoEnable retrieval-augmented generation from indexed sources.
promptNoSystem prompt — the agent's persona, role, style of speech, and behaviour rules. For multi-agent scenarios, instruct the agent to end every message with an @-mention of who speaks next; that's how turn-handoff works through the response gate.
ragTagsNoOptional RAG tag filter — restrict retrieval to sources matching these tags.
summaryNoShort bio shown in agent lists.
triggerNoLegacy trigger field. Prefer the newer `responseMode` for new agents.
llmModelNoModel id served by this deployment's AI endpoint; omit for the platform default. `ethora-agent-model-list` returns the supported ids; an unsupported id is rejected with LLM_MODEL_UNSUPPORTED and that list.
flowsYamlNoDeterministic scripted conversation for this agent, as YAML. Drives the agent through a fixed sequence (opening menu, appointment request, intake questionnaire, survey) instead of leaving every turn to the model. Compiled and validated server-side on save: an invalid script is rejected with code `FLOWS_INVALID` and per-line details, and nothing is stored. A flow named `start` is reserved and fires when a conversation opens. Buttons are authored here (`buttons:` on a `say` step, or `options:` on an `ask` step). Call `fetch` with id `doc:agent-flows` for the full authoring format before writing one. Pass an empty string to clear the script.
categoriesNoDirectory categories, any of: `customer-support` (customer-facing assistants), `persona` (a character or historical figure), `entertainment` (quizzes, games, scenarios), `worker` (internal work). Used to filter `ethora-agent-list`. Replaces the agent's current set.
visibilityNo'private' (only invitable inside the owning app) or 'public' (cross-app invitable).
cooldownSecNoMinimum seconds between this agent's replies in a given room. Damped 2x for bot-to-bot. Set 0 for quick turn-taking in multi-agent scenarios.
isPublishedNoConvenience alias for setting visibility='public'.
llmProviderNoLeave empty. The deployment has one AI endpoint (OpenAI-compatible); `openai` and `openai-compatible` are accepted as synonyms, anything else is rejected with LLM_PROVIDER_UNSUPPORTED.
botAvatarUrlNoURL of the avatar image shown next to bot messages.
responseModeNoWhen the agent decides to reply. 'always' = every room message; 'mentioned' = only when @-mentioned by display name or via /bot (recommended for multi-agent turn-taking); 'smart' = a mini LLM gate decides per-message; 'probability' = coin-flip per message using `responseProbability`.
botDisplayNameNoDisplay name used inside the chat UI. Defaults to `name`.
greetingMessageNoOptional message the agent posts when it first joins a room.
responseProbabilityNoIf responseMode='probability', odds (0-1) of replying to each message. Damped 0.6x for bot-to-bot messages.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes beyond the annotations (readOnlyHint=false, idempotentHint=false, openWorldHint=true) by disclosing auth-mode constraints — app-token mode is rejected by the backend — plus ownership/homing semantics ('belongs to your account', 'homed in that app'). It does not cover duplicate-name/slug behavior or the shape of the created resource, which matters for a non-idempotent create.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads what the tool does and the endpoint, then moves to auth modes, then to alternatives and prerequisites. Every sentence carries information, though the final 'Requires:' paragraph could be tightened.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 20-parameter, zero-required-parameter create tool with no output schema, the description supplies prerequisites, auth modes, ownership, and the multi-agent recipe. The one gap is that it never says what the call returns (e.g. the new agent's id), which the caller needs before inviting or updating it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already documents all 20 fields in detail, so the baseline is 3. The description adds useful framing by grouping the fields into 'persona' vs 'response-gate settings' and calling out `responseMode`/`cooldownSec` interplay, but no syntax or format beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Create a reusable AI agent') and even names the backing endpoint. It distinguishes itself cleanly from siblings by contrasting with `ethora-agent-update`, `ethora-agent-clone`, and `ethora-agent-invite` in the same paragraph.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent: use this for one persona, repeat for multi-agent scenarios, then `ethora-agent-invite`; or start from a public template via `ethora-agent-list { visibility: "public" }` + `ethora-agent-clone`; and points at the `ethora-agents-quickstart` prompt. Prerequisite is stated ('a selected app ... or an explicit appId').

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-agent-inviteInvite Agent to ChatA

Invite an Agent into a chat room. Multiple agents can coexist in the same room — call this tool once per agent and they will all appear as members able to converse. Lazily creates a per-App BotInstance (an Ethora user with isBot:true) if one does not already exist for (agent, app). Spawns the XMPP client live; no ai-service restart required. For the full multi-agent recipe see the ethora-agents-quickstart prompt. Requires: an agent (ethora-agent-create) and a room (ethora-chat-create) in the selected app.

NameRequiredDescriptionDefault
appIdNoRequired in B2B mode unless already selected via ethora-app-select.
chatIdNoMongo Chat _id (preferred when invoking from admin).
agentIdNoAlias for `agentIdOrAddress` - either name is accepted, pass whichever you have.
chatJidNoRoom JID `${appId}_${chatId}` (optionally with `@conference.<host>`), exactly the `jid` returned by `ethora-chat-create`. Preferred over `chatId`.
agentIdOrAddressNoEither Mongo _id (24 hex chars) or EOA-style address.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description discloses meaningful side effects: it lazily creates a per-App BotInstance if one does not exist, spawns the XMPP client live, and requires no ai-service restart. This is exactly the kind of behavioral context annotations alone do not provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is information-dense and well structured: purpose, multi-agent behavior, side effects, recipe pointer, and prerequisites. Every sentence earns its place, and nothing is redundant with the schema or annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a side-effectful tool with no output schema, the description covers prerequisites, side effects, and usage pattern well. It could be slightly more complete by stating what successful invocation returns or confirms, but the essential information needed to call it correctly is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already documents all 5 parameters with 100% coverage, so the description does not need to re-explain them. It adds only contextual hints like 'in the selected app' and 'call this tool once per agent,' which is acceptable but not a substantial addition beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Invite an Agent into a chat room.' It also clarifies the unique behavior that multiple agents can coexist and that this action is separate from creating agents or rooms, clearly distinguishing it from sibling tools like ethora-agent-create and ethora-chat-create.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear usage context: call it once per agent, and it explicitly states prerequisites ('Requires: an agent... and a room... in the selected app'). It does not explicitly contrast it with alternatives or state when not to use it, but the context is strong enough for an agent to route correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-agent-listList AgentsA
Read-onlyIdempotent

List AI agents (GET /v2/agents): by default your own agents plus the public ones. Pass appId to list only the agents homed in that app (GET /v2/apps/:appId/agents, which needs you to manage the app; B2B tokens always use this form). Agents belong to your account, not to one app, so the same agent can answer in several of your apps. Public agents (e.g. the platform's Support Agent, sample personas) can be tried with ethora-agent-try and copied with ethora-agent-clone, not edited. Returns agents with ids, names, owner, visibility, categories and config. Auth: user session or B2B token. Errors: 401/403 wrong auth; empty list when nothing matches.

NameRequiredDescriptionDefault
appIdNoOnly agents whose home app is this 24-char hex appId. In user auth the selected app is NOT applied by default (agents are account-level); with a B2B token the selected app is used.
limitNoPage size (max 200).
offsetNoNumber of agents to skip, for paging.
categoryNoOnly agents tagged with this category.
visibilityNo`mine` = only your own agents, `public` = only public agents (the directory to clone from). Omit for both.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, and the description still adds material context beyond them: auth requirements (user session or B2B token), error semantics (401/403 wrong auth), empty-list behavior, and the shape of returned fields (ids, names, owner, visibility, categories, config).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core listing behavior and the appId switch are front-loaded, and every clause carries information. It is dense with parenthetical endpoints and error codes, which is slightly heavy but not redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with no output schema, the description covers scoping, the account-vs-app ownership nuance, auth, error behavior, and return fields — everything needed to call it correctly without opening the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already explains limit, offset, category, and visibility. The description still adds value on appId by noting it requires app management rights and that B2B tokens always use the app-scoped form, but it does not add anything for the remaining parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List AI agents') plus the backing endpoint (GET /v2/agents), and immediately distinguishes the appId-scoped variant (GET /v2/apps/:appId/agents). It also clarifies the account-level ownership model, so an agent won't confuse this with per-app listing tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states the default behavior (own agents plus public), the condition that changes it (pass appId, which requires app management; B2B tokens always use this form), and routes public-agent use to the named alternatives ethora-agent-try and ethora-agent-clone, noting they cannot be edited here.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-agent-updateUpdate AgentA
DestructiveIdempotent

Overwrites the fields you pass; previous values are not kept and cannot be restored from the API, so confirm changes to the prompt, name or settings with the user first. Update a saved AI agent (PUT /v2/agents/:agentId). All fields are optional - only what you pass is updated. Common uses: tune the system prompt after a test run, switch responseMode to control turn-taking in multi-agent rooms, or adjust cooldownSec. See ethora-agents-quickstart prompt for the end-to-end recipe. Requires: an agent id or address from ethora-agent-list or ethora-agent-create. Only the agent's owner can update it: a public agent from someone else, including the platform's Support Agent, answers 403, so ethora-agent-clone it and update the copy.

NameRequiredDescriptionDefault
nameNoNew display name. For multi-agent scenarios prefer single-word names — the @-mention matcher uses exact display-name match with word-boundary.
slugNoURL-safe slug.
isRAGNoEnable RAG retrieval.
promptNoUpdated system prompt (persona + behaviour). For multi-agent rooms instruct the agent to end every message with an @-mention of the next speaker — that's how turn-handoff works through the response gate.
agentIdNoMongo _id (24 hex chars) of the agent to update.
ragTagsNoRAG tag filter.
summaryNoShort bio.
triggerNoLegacy trigger field. Prefer `responseMode`.
llmModelNoLLM model override.
flowsYamlNoDeterministic scripted conversation for this agent, as YAML. Drives the agent through a fixed sequence (opening menu, appointment request, intake questionnaire, survey) instead of leaving every turn to the model. Compiled and validated server-side on save: an invalid script is rejected with code `FLOWS_INVALID` and per-line details, and nothing is stored. A flow named `start` is reserved and fires when a conversation opens. Buttons are authored here (`buttons:` on a `say` step, or `options:` on an `ask` step). Call `fetch` with id `doc:agent-flows` for the full authoring format before writing one. Pass an empty string to clear the script.
categoriesNoDirectory categories, any of: `customer-support` (customer-facing assistants), `persona` (a character or historical figure), `entertainment` (quizzes, games, scenarios), `worker` (internal work). Used to filter `ethora-agent-list`. Replaces the agent's current set.
visibilityNo'private' or 'public' (cross-app invitable).
cooldownSecNoMinimum seconds between this agent's replies in a given room. Damped 2x for bot-to-bot. Set 0 for quick turn-taking.
isPublishedNoConvenience alias for visibility='public'.
llmProviderNoLLM provider override.
botAvatarUrlNoAvatar image URL.
responseModeNoWhen the agent replies. 'always' = every message; 'mentioned' = only @-mention or /bot (best for multi-agent turn-taking); 'smart' = mini-LLM decides; 'probability' = coin-flip using `responseProbability`.
botDisplayNameNoDisplay name in chat UI.
greetingMessageNoMessage the agent posts when it first joins a new room.
agentIdOrAddressNoAlias for `agentId` - either name is accepted, pass whichever you have.
responseProbabilityNoIf responseMode='probability', odds (0-1) of replying. Damped 0.6x for bot-to-bot.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (destructiveHint=true, idempotentHint=true), but the description goes well beyond them: it explains that passed fields are overwritten and old values are unrecoverable, advises confirming prompt/name/settings changes with the user, and discloses the 403 ownership failure mode. That is exactly the kind of operational context annotations cannot encode.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The critical destructive-behavior warning is front-loaded, and the second paragraph cleanly handles prerequisites and authorization. Slight redundancy ('Overwrites the fields you pass' vs. 'only what you pass is updated') and the endpoint path add minor noise but no real bloat.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 21-parameter mutation tool with no output schema, the description covers everything an agent needs to call it safely: destructive/partial-update semantics, ownership/auth requirements, and a pointer to external authoring docs (doc:agent-flows) for the complex flowsYaml field. Nothing material is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the per-parameter docs already carry the load and baseline is 3. The description still adds value by calling out specific parameters with rationale (prompt for turn-handoff, responseMode for multi-agent turn-taking, cooldownSec), nudging an agent toward the right fields for common tasks.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Update a saved AI agent') and even anchors it to the endpoint PUT /v2/agents/:agentId. An agent can trivially distinguish this from siblings like ethora-agent-create, ethora-agent-list, and ethora-agent-activate.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It names concrete use cases (tune prompt after a test run, switch responseMode for turn-taking, adjust cooldownSec) and points to the ethora-agents-quickstart prompt for the full recipe. It also spells out prerequisites (agent id/address from list or create) and the ownership constraint with an explicit alternative: clone an un-owned agent and update the copy instead.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-api-key-createCreate API KeyA

Mint a long-lived, revocable API key for the currently logged-in user. The key is a user token: send it as Authorization: Bearer <key> to the hosted MCP endpoint (or set it in the stdio client) to skip ethora-user-login. Shown once. Auth: user auth (logged in). Errors: 401 not logged in; 404 on backends without API key support.

NameRequiredDescriptionDefault
nameNoLabel to recognise the key later (e.g. `ci-runner`, `claude-desktop`).
ttlDaysNoLifetime in days. Server default applies when omitted.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, it discloses that the key is long-lived, revocable, shown only once, and tied to the current user's session. It also documents auth requirements and error cases (401, 404 on unsupported backends), which materially helps an agent handle the result.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: action first, usage next, then one-time visibility and error/auth notes. Every sentence contributes a distinct operational fact with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter creation tool with no output schema, it covers auth, errors, usage, and the one-time display caveat, which is enough to invoke it correctly. It does not specify the exact response shape, so an agent still has to infer how the returned key is surfaced, but the 'Shown once' note mitigates this.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the parameter descriptions are already meaningful. The text does not add further parameter-level detail, so this dimension sits at the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with the specific action 'Mint a long-lived, revocable API key' and scopes it to the currently logged-in user. This clearly differentiates creation from the sibling list/revoke tools without needing to open their schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the prerequisite ('logged-in user') and the practical context: the key is a Bearer token that enables API access and bypasses ethora-user-login. It does not explicitly name list/revoke as alternatives or give when-not-to-use conditions, but the creation use case is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-app-createCreate AppA

Create a new Ethora app (tenant) owned by the currently logged-in user. Allocates a fresh 24-char hex appId and sets the caller as owner; counts against the owner's plan limit. Returns the new app object including appId. The returned app has its credential fields redacted; call ethora-app-credentials-reveal { appId, confirm: true } when a snippet needs the appToken. 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.

NameRequiredDescriptionDefault
displayNameYesHuman-readable app name shown to users in the app picker and on the public landing page. Not required to be unique across accounts.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Even though annotations already indicate this is a write operation, the description adds materially useful behavioral context: counts against plan limit, allocates a fresh appId, sets ownership, returns redacted credentials, and requires a separate reveal call for the appToken. It also specifies auth and error behavior. No contradiction with the annotations is present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well organized: core behavior first, then auth, errors, and alternatives. Every sentence contributes agent-relevant information, with no filler or tautological repetition of the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter creation tool with no output schema, the description covers the return shape, the redaction behavior, the follow-up tool for credentials, auth prerequisites, failure modes, and the related server-side alternative. An agent has enough context to select and invoke the tool correctly without further lookup.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already fully defines displayName and its meaning. The description adds only the indirect detail that an invalid displayName yields a 422 error, which is marginal. Baseline 3 is appropriate because the schema carries the parameter documentation burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource ('Create a new Ethora app (tenant)'), states the concrete outcome (allocation of a fresh 24-char hex appId, caller set as owner), and describes the return value. It also distinguishes this user-facing creation tool from the related server-side ethora-b2b-app-create, making sibling differentiation clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states the required auth mode and prerequisite ('user-auth mode, active session (ethora-user-login first)'), gives error conditions (401, 402/403, 422), and names the alternative for server-side provisioning (ethora-b2b-app-create). This is explicit when-to-use guidance with a clear exclusion.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-app-listList AppsA
Read-onlyIdempotent

List all Ethora apps (tenants) owned by the currently logged-in user. Returns an array with appId (24-char hex), displayName, domainName, ownership and bot-status metadata. Credential fields (appSecret, tenantSecret, appToken, passwords) are redacted in the result; call ethora-app-credentials-reveal { appId, confirm: true } to reveal an app's appToken. 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.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), and the description still adds real behavioral value: credential field redaction (appSecret, tenantSecret, appToken, passwords), the exact 401 failure mode, and the empty-list outcome when the user owns no apps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with what it lists and scoped to ownership, then results, then auth/errors/related tools. No filler, every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates fully by naming the returned fields (appId, displayName, domainName, ownership, bot-status), the redaction policy, the error case, and the related reveal/update/select tools. An agent has everything needed to call it and act on the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4; there is nothing parameter-level the description needs to explain beyond routing the resulting appId into follow-up tools, which it already does.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List all Ethora apps (tenants)') and narrows scope to apps owned by the current user, which separates it from ethora-app-create/update/select. The parenthetical '(tenants)' even disambiguates the domain term.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear activation context: user-auth mode with an active session and 'ethora-user-login first' as a prerequisite. It also routes downstream ('feed appId into ethora-app-update / ethora-app-select'). It stops short of an explicit when-not or a named sibling to use instead, so 4 rather than 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-app-selectSelect AppA
Read-onlyIdempotent

Session-only: remembers which app later calls refer to. Changes nothing on the server and can be called again at any time to switch. Set the current app context for this session so app-scoped tools can omit their appId argument. On the hosted server the selection is remembered for the signed-in account (24 hours), so a client that opens a new session per call keeps it; ethora-app-create selects the new app by itself, and an account with exactly one app has it selected automatically. 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-mode-set.

NameRequiredDescriptionDefault
appIdYes24-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.
appTokenNoPer-app appToken to store alongside the appId. If provided, the active auth mode switches to app-token (unless `authMode` says otherwise). Secret.
authModeNoAuth 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.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, but the description adds substantial context beyond them: 'Changes nothing on the server,' re-callable to switch at any time, 24-hour persistence for the signed-in account on the hosted server, no auth required, and no validation errors (404 surfaces only on the first app-scoped call). This is exactly the kind of behavioral detail annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The key fact (session-only, set app context) is front-loaded and every sentence carries information. It is dense and slightly run-on in the later clauses about hosted-server persistence and authMode defaulting, but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description still covers the full picture: session vs. server scope, auth requirements, error behavior, persistence duration, and interaction with ethora-app-create and ethora-auth-mode-set. An agent has everything needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds the cross-parameter interaction that the schema does not state: providing appToken defaults the auth mode to app-token unless authMode overrides, and it stores currentAppId/appToken. That interplay between the optional params is genuine added value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Set the current app context for this session.' The opening 'Session-only: remembers which app later calls refer to' immediately distinguishes it from server-mutating siblings like ethora-app-create or ethora-app-update.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says when to use it ('so app-scoped tools can omit their appId argument') and when it is unnecessary ('ethora-app-create selects the new app by itself, and an account with exactly one app has it selected automatically'). It also names the related tool it pairs with (ethora-auth-mode-set), giving the agent clear routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-app-updateUpdate AppA
DestructiveIdempotent

Overwrites the fields you pass; previous values are not kept and cannot be restored from the API, so confirm changes to the prompt, name or settings with the user first. Update mutable fields on an app the caller owns (displayName, domainName, appTagline, primaryColor, botStatus). Partial update - omitted fields are left unchanged. Requires: an appId from ethora-app-list or ethora-app-create. Auth: user-auth mode, active session; the caller must own the app. Errors: 401 not logged in; 403 not owner; 404 unknown appId; 422 validation (e.g. domainName taken, primaryColor not #RRGGBB).

NameRequiredDescriptionDefault
appIdNo24-char hex ObjectId of the app to update. Optional — defaults to the app most recently passed to `ethora-app-select`.
botStatusNo`on` enables the AI bot for new conversations (requires a configured prompt — see `ethora-bot-update`); `off` disables it. Does not change the bot's configured prompt or sources.
appTaglineNoShort tagline shown on the public app landing page.
domainNameNoSubdomain 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.
displayNameNoNew human-readable app name. Visible in the app picker and on the public landing page.
primaryColorNoPrimary brand color in hex `#RRGGBB` format (e.g. `#F54927`). Used throughout the app UI.
appDescriptionNoDeprecated alias for `appTagline`, kept so older callers keep working. Prefer `appTagline`.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructive and idempotent, but the description goes well beyond them: it warns that previous values are not kept and cannot be restored from the API, clarifies the partial-update semantics (omitted fields unchanged), and enumerates auth mode plus concrete error codes (401/403/404/422) with a validation example. This is exactly the extra context annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the destructive warning, then the field list, then requirements/auth/errors — a sensible ordering for a mutation tool. Some content (error codes, per-field format rules) duplicates the schema, which is mild redundancy rather than bloat.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter mutation with no output schema and no required fields, the description covers irreversibility, partial-update behavior, ownership requirement, auth mode, and failure modes. Nothing an agent needs to invoke this safely is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter is already documented in the schema, including the botStatus vs. prompt distinction and the appDescription deprecation note. The description's field list largely restates that; baseline 3 applies when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Update mutable fields on an app the caller owns') and enumerates exactly which fields are mutable (displayName, domainName, appTagline, primaryColor, botStatus). The scope is distinct from siblings like ethora-app-create and ethora-app-list, so an agent can route without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives real usage context: confirm changes with the user first, and the `appId` must come from `ethora-app-list` or `ethora-app-create`. It also acknowledges the implicit app from `ethora-app-select`. It stops short of an explicit when-not or a named alternative tool, so it is strong but not fully routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-chat-createCreate Chat RoomA

Create a new chat room (MUC room) inside an app the caller owns. Every room created this way is listed in the app's rooms (defaultRooms); pinned: true additionally makes new users auto-join it (existing users are not added), pinned: false (default) keeps it opt-in. Returns the new room object including its JID. Requires: a selected app (ethora-app-select) or an explicit appId. 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.

NameRequiredDescriptionDefault
appIdNo24-char hex ObjectId of the app to create the chat room in. Optional — defaults to the app most recently passed to `ethora-app-select`.
titleYesDisplay name for the new chat room. Visible to all members; not required to be unique within the app.
pinnedNoIf `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.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes far beyond the annotations by explaining defaultRooms listing, pinned auto-join behavior for new users, the opt-in default, return value with JID, authentication mode, ownership requirement, and specific error codes. This gives an agent a rich behavioral model without needing to call the tool blindly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but appropriately sized: it front-loads the core purpose, then covers behavioral effects, return value, prerequisites, and errors without wasted words. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a create operation with no output schema, the description is complete: it states what is created, side effects, auth requirements, error cases, and what the caller receives back. An agent has enough information to invoke the tool correctly and anticipate failures.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaningful context: every created room is listed in defaultRooms, pinned:true does not add existing users, and pinned:false keeps the room opt-in. These nuances complement the schema definitions rather than merely repeating them.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Create a new chat room (MUC room)') and the resource scope ('inside an app the caller owns'). It clearly distinguishes this tool from siblings like ethora-message-send and ethora-chat-history by focusing on room creation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear usage context by requiring a selected app or explicit appId and stating the ownership prerequisite. It does not explicitly name alternatives or when-not-to-use cases, but no sibling tool performs the same room-creation function, so the guidance is adequate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-chat-historyGet Chat HistoryA
Read-onlyIdempotent

Read the archived messages of a chat room (GET /v2/apps/:appId/chats/:chatId/messages, newest last). Returns results with from, nick, body, ts (ms) plus a nextBefore cursor for older pages. Identify the room by roomJid (${appId}_${chatId}) or bare chatId plus the selected app. Requires: a room in the selected app (ethora-chat-create). Auth: user auth (default on the hosted server) or B2B; app-token mode is not accepted. Errors: 401 not logged in; 403 not the app owner; 404 unknown app/room; 502 MAM_READ_FAILED or mamUnavailable: true when the deployment has no message archive.

NameRequiredDescriptionDefault
appIdNo24-char hex appId. Optional when `roomJid` carries it or an app is selected.
limitNoMaximum number of most-recent messages to return (default 100).
beforeNoPagination cursor: only messages older than this timestamp (ms), from a previous `nextBefore`.
chatIdNoBare chat id. Needs an app: pass `appId` or select one with `ethora-app-select`.
roomJidNoRoom JID `${appId}_${chatId}` (optionally with `@conference.<host>`). Either this or `chatId` is required.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), yet the description adds real behavioral depth: pagination order ('newest last'), the nextBefore cursor, accepted vs rejected auth modes ('app-token mode is not accepted'), and specific error semantics including MAM_READ_FAILED / mamUnavailable. This far exceeds what the annotations convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core purpose before endpoint, return shape, prerequisites, auth, and errors. It is dense but nearly every clause carries distinct, useful information; only the raw endpoint path borders on redundant detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates by describing the return shape (from, nick, body, ts in ms, nextBefore cursor) and enumerating auth and error cases. An agent has everything needed to invoke and interpret the result correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all five parameters (including roomJid format and the before cursor) are already documented in the schema. The description mostly restates the roomJid/chatId relationship and confirms appId is optional rather than adding new syntax or constraints beyond the schema, warranting the baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Read the archived messages of a chat room') and even supplies the underlying endpoint. It is clearly distinguishable from the sibling ethora-message-send (write) without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives the prerequisite ('a room in the selected app' via ethora-chat-create) and names ethora-app-select for app selection, which routes the agent well. It does not explicitly compare against an alternative read tool (none exists), so it stops just short of full when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-feedback-submitSend FeedbackA

Send feedback about Ethora to the Ethora team: something that does not work, behaves differently from what the tool description promised, is missing, or is badly documented. It reaches the team directly, so prefer it over guessing or silently giving up when a tool fails. Recent failures in this session (tool, error code, request id) are attached automatically when includeRecentErrors is true, which is what makes a report from here more useful than a web form: the team can join it to the server-side log. Works whether or not you are signed in, so a problem that blocks sign-up can still be reported. Do not put credentials, API keys or end-user personal data in message; credential-shaped values in the attached context are redacted before sending. Requires: nothing. Auth: none. Works anonymously; when the session is authenticated the report is attributed to that account. Errors: 422 if message is shorter than 5 characters or looks like spam; 429 if too many reports were sent from this address.

NameRequiredDescriptionDefault
emailNoReply address. Only useful when the session is not signed in; an authenticated report already carries the account, so leave this out unless the user offers an address.
messageYesWhat happened, in the user's own words where possible: what was attempted, what was expected, what occurred instead. No credentials or end-user personal data.
categoryNoWhat kind of report this is: `bug` (something is broken), `unexpected` (it works but not as described), `feature` (a request), `docs` (a description or guide is wrong or missing), `other`. Defaults to `other`.
includeRecentErrorsNoAttach this session's last few tool failures (tool name, error code, request id) so the team can trace them. Default true; set false if the report is unrelated to a failure.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations carry only basic hints, so the description carries the behavioral burden. It discloses anonymous operation, account attribution when signed in, redaction of credential-shaped values, automatic attachment of recent failures, and 422/429 error conditions. This goes far beyond what the structured fields provide, with no contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense but efficient: every sentence carries a usage trigger, a constraint, or an error condition. The core purpose is front-loaded, and the labeled auth/error block is easy to scan. Nothing feels redundant or promotional.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-risk feedback submission tool, this covers the decision triggers, parameter guidance, auth behavior, redaction, and failure modes. No output schema is present, but an agent already knows enough to call the tool correctly. There is no meaningful gap that would cause a misinvocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds value by explaining why `includeRecentErrors` matters (server-side log join) and that credential-shaped values in attached context are redacted. It partially duplicates the schema text, but the redaction and error-behavior clarifications push it above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States an unambiguous verb and resource ('Send feedback about Ethora') and enumerates the report types ('does not work, behaves differently, missing, badly documented'). This clearly distinguishes it from the dozens of operational sibling tools in the list.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs the agent to prefer this tool over guessing or silently giving up when a tool fails, and contrasts it with a web form for server-side traceability. It also explains when it is useful even without authentication. The triggers and exclusions are clear enough that an agent can decide when to call it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-helpHelp and Next StepsA
Read-onlyIdempotent

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-recipe-run.

NameRequiredDescriptionDefault
goalNoWhat you are trying to do: `new-app` (a new chat app: create, brand, rooms, users, where it lives), `in-app-chat` (chat inside your existing product with your own UI and users), `multi-agent-room` (several AI agents in one room, talking to people and each other), `widget` (AI chat widget on a website), `chat-test` (post and read messages), `b2b-bootstrap-ai` (server-side provisioning), `broadcast`, `sources-ingest`, `files-upload`, `bot-manage`, `user-login`. Omit or use `auto` for recommendations inferred from the current session state.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=false, so the safety profile is covered. The description adds genuinely new behavioral facts: no auth required, no API calls made, and effectively no error modes. Return shape (recipes/next calls) is only implied.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight blocks: one sentence of purpose, then a compact Auth/Errors/Related line. Front-loaded and waste-free, though the Auth/Errors/Related shorthand is slightly compressed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-required-parameter, read-only helper with no output schema, the definition covers purpose, auth, error behavior and follow-up routing. It could state more concretely what the response contains (recipe ids, next-call list), but nothing needed to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single `goal` enum carries an exhaustive per-value explanation, so the schema does the heavy lifting. The description only gestures at the same behaviors ('based on current session state'), adding little beyond it; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific role (task-oriented orientation for this MCP server) plus concrete content: explaining the three auth modes and recommending next tool calls and recipes. It is clearly not a status/CRUD tool, though it never explicitly contrasts itself with ethora-status, the nearest sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context for invocation (recommendations inferred from current session state) and routes follow-up work by saying a recommended recipe id should be passed to `ethora-recipe-run`. No explicit when-not-to-use or statement of where `ethora-status` is preferred instead.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-message-sendSend Chat MessageA

Post a message into a chat room of an app (POST /v2/apps/:appId/chats/broadcast targeting one room). The message is attributed to the app's broadcast sender (override the shown name with senderName). Use it to seed or test a conversation, e.g. right after ethora-agent-invite, and set waitForReplySec (up to 60) to wait for an AI agent's answer; replies are returned in replies. Identify the room by roomJid (${appId}_${chatId}, exactly what ethora-chat-create returns as jid) or by the bare chatId plus the selected app. Requires: a room in the selected app (ethora-chat-create); for replies, an agent invited into it (ethora-agent-invite). Auth: user auth (the default on the hosted server) or B2B; app-token mode is not accepted by this route. Errors: 401 not logged in; 403 not the app owner; 404 unknown app/room; 422 empty text. Reply detection needs the message archive (MAM) on the deployment; when it is unavailable replies is null and historyUnavailable is true.

NameRequiredDescriptionDefault
textYesMessage body to post (1-4000 chars).
appIdNo24-char hex appId. Optional when `roomJid` carries it or an app is selected.
chatIdNoChat id: either the Mongo chat `_id` (as listed by the app's chat list) or the suffix after `${appId}_` in the room JID. Needs an app: pass `appId` or select one with `ethora-app-select`.
roomJidNoRoom JID `${appId}_${chatId}` (optionally with `@conference.<host>`), as returned by `ethora-chat-create`. Either this or `chatId` is required.
senderNameNoDisplay name shown as the message sender (defaults to the app's broadcast sender / app name).
waitForReplySecNoSeconds to wait for a reply from someone else in the room (an AI agent, typically). 0 (default) returns right after posting.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint=false, etc.), the description discloses specific behavioral traits: auth modes accepted/rejected, error codes (401, 403, 404, 422), the MAM dependency where `replies` becomes null and `historyUnavailable` becomes true, and the wait/reply semantics. This significantly exceeds what annotations alone convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is longer than average but well-structured into purpose, usage, prerequisites, auth, errors, and reply-detection. Each sentence carries distinct information and there is no fluff or repetition. It is front-loaded with the core action and use case.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having no output schema, the description covers return behavior (`replies`, `historyUnavailable`), errors, auth requirements, prerequisites, and room identification. For a 6-parameter tool with this complexity, nothing essential is missing for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description adds meaning beyond schema by explaining room identification via `roomJid` vs `chatId` and the relationship to `ethora-chat-create`'s return value, the `senderName` override, and `waitForReplySec`'s effect on `replies`. This enriches rather than repeats schema details.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states 'Post a message into a chat room of an app' with a specific HTTP route and 'targeting one room', making the action and resource clear. It distinguishes this from siblings like ethora-chat-create and ethora-chat-history by focusing on message posting, not room creation or reading history.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use guidance ('Use it to seed or test a conversation, e.g. right after ethora-agent-invite') and lists prerequisites (`ethora-chat-create`, `ethora-agent-invite`). It does not state a 'when not to use' or name an alternative sending tool, but the context is clear and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-source-doc-uploadUpload Knowledge DocumentA

Upload documents (1–5; PDF, text, etc.) into an agent's knowledge base (the one named by agentId, else the app's default agent) (app-token / B2B variant of ethora-source-doc-upload-legacy). Async - content becomes queryable once indexing finishes; files passed as base64, 50MB max each. Requires: a selected app (ethora-app-select) or an explicit appId. 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-source-doc-list, ethora-source-doc-delete.

NameRequiredDescriptionDefault
appIdNo24-char hex appId to ingest into. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode.
filesYes1 to 5 documents to ingest in this call.
agentIdNoAgent whose knowledge base gets the content (24-char hex, from `ethora-agent-list` / `ethora-agent-create`). Must be your own agent or one of this app's. Omit to file it under the app's default agent (the one answering its website widget); an app still on the shared Support Agent first gets its own copy of it.
agentIdOrAddressNoAlias for `agentId` - either name is accepted, pass whichever you have.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations by disclosing async indexing semantics ('content becomes queryable once indexing finishes'), the 50MB cap, base64 encoding expectations, auth modes, and a full error map (401/403/404/413/422). Annotations already cover safety/idempotency; the description adds the operational behavior an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first sentence, followed by clean Requires/Auth/Errors/Related blocks. Dense with parenthetical detail, but it is organized and nearly every clause carries actionable information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no output schema, the description covers the async lifecycle, auth requirements, default-agent routing, and error codes, which is everything an agent needs to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description restates constraints (1-5 files, base64, 50MB) that the schema already documents, adding only marginal framing rather than new parameter meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (upload documents into an agent's knowledge base) with scope qualifiers: 1-5 files, PDF/text, base64, 50MB each. It also distinguishes itself from the legacy variant, so an agent can tell the two apart without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit prerequisites ('Requires: a selected app (ethora-app-select) or an explicit appId') and names related tools (list/delete). It does not state when NOT to use this tool, so it stops just short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-source-site-crawl-waitCrawl Website Source and WaitA
Destructive

Adds the crawled pages to an agent's knowledge base (the one named by agentId, else the app's default agent); existing documents are kept and nothing is deleted. A URL that is already indexed is refused with 409 unless force: true re-crawls it. Crawl a website URL and wait for the crawl to finish: enqueues the job, then polls it until it reports completed or failed. Returns { done, status, jobId, polls, durationMs, result }; done: false with a note means the budget ran out while the job was still running (it usually finishes server-side anyway). Requires: a selected app (ethora-app-select) or an explicit appId. Auth: app-token mode OR B2B mode with an explicit appId. Errors: 401/403 wrong auth (403 AGENT_NOT_WRITABLE when agentId is someone else's agent); 400 malformed url; 409 already indexed; 504/timeout if it takes longer than timeoutMs (the job may still complete server-side - check with ethora-source-site-list, or stop it with ethora-source-site-crawl-cancel). Related: ethora-agent-knowledge-get shows what the agent can search afterwards.

NameRequiredDescriptionDefault
urlYesAbsolute URL to crawl, e.g. `https://example.com/docs`.
appIdNo24-char hex appId to ingest into. Required in B2B mode unless already set via `ethora-app-select`; ignored in app-token mode.
forceNoRe-crawl a URL that is already indexed and overwrite the stored copy. Without it an already-indexed URL is refused with 409.
agentIdNoAgent whose knowledge base gets the content (24-char hex, from `ethora-agent-list` / `ethora-agent-create`). Must be your own agent or one of this app's. Omit to file it under the app's default agent (the one answering its website widget); an app still on the shared Support Agent first gets its own copy of it.
timeoutMsNoHow long to poll for the crawl to finish, in milliseconds. Default 45000, chosen to stay under the ~60s request timeout most MCP clients enforce. Caps at 600000 (10 min) for clients that allow longer calls.
followLinkNoIf true, also crawl in-domain links reachable from `url`. Can ingest many pages — use with care.
agentIdOrAddressNoAlias for `agentId` - either name is accepted, pass whichever you have.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: it discloses that existing documents are kept and nothing is deleted, the 409 refusal on already-indexed URLs unless force is set, the exact return shape, the done:false budget-exhausted caveat, auth modes, and specific error codes (401/403, 403 AGENT_NOT_WRITABLE, 400, 409, 504). This is exactly the behavioral context annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose, then behaviors, requirements, errors, and related tools in scannable sentences. Dense but each clause carries information; only minor tightening is possible.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutating, long-running, auth-sensitive tool with no output schema, the description compensates fully: it documents the return contract, timeout semantics, and every relevant error. Nothing needed to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents force, timeoutMs, followLink, and the agentId alias in detail; the description mostly corroborates rather than extends these. It adds the 409/force interplay, but that is already present in the schema, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Crawl a website URL') plus the blocking behavior ('wait...enqueues the job, then polls until completed or failed'), which distinguishes it from the sibling crawl-cancel and site-list tools. An agent knows exactly what this does without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit preconditions are given ('requires a selected app via ethora-app-select or an explicit appId'), and failure paths route to named alternatives ('check with ethora-source-site-list, or stop it with ethora-source-site-crawl-cancel'). The force/re-crawl condition is also spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-statusSession StatusA
Read-onlyIdempotent

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

NameRequiredDescriptionDefault

No parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnly/idempotent/non-destructive, but the description adds genuinely new operational context: no auth required, effectively no error paths, and a security-relevant redaction guarantee ('booleans like hasAppJwt — values never echoed'). That is exactly the extra behavioral detail annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Extremely dense with zero filler, and the highest-value fact (what state is reported) is front-loaded. The trailing 'Auth/Errors/Related' fragments are terse to the point of being slightly clipped, but every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description compensates by naming the returned fields, which is the right move. Combined with the auth and error disclosures, an agent has everything needed to call this zero-arg tool correctly and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there are no parameter semantics to document; per the baseline rule this is a 4. The description instead describes the response fields, which is useful but belongs to a different dimension.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Report the current Ethora MCP session state') and then enumerates exactly what is reported (API URL, auth mode, credential presence flags, appId/agentId, hosted/sessionId). It is immediately distinguishable from the large sibling set, which is dominated by create/update/list operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Related: ethora-doctor for an active connectivity check' routes the agent to the alternative and implies the division of labor (passive snapshot vs. active probe). It does not spell out an explicit 'use this when...' trigger, but for a no-arg status tool the context is sufficiently clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-tools-enableEnable More ToolsA
Read-onlyIdempotent

Session-only: changes which tools this connection lists. Touches no account data. Only the core tools are listed by default. Call this to enable another group for this session; the tool list refreshes automatically (tools/list_changed). On the hosted server the enabled groups are remembered for the signed-in account, so a client that opens a new session per call keeps them. Without group it returns the catalogue: each group's summary, tool count and whether it is enabled. Groups: keys, session, apps-admin, rooms, agents-admin, sources, widget, users-files, legacy-bot, b2b, wallet; all enables everything. Hidden tools are still described by search / fetch, and each doc names its group. Auth: none. Errors: UNKNOWN_GROUP for a name outside the list.

NameRequiredDescriptionDefault
groupNoGroup to enable, or `all`. Omit to list the groups.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), and the description layers on real behavioral context: no account data is touched, the list refreshes automatically via tools/list_changed, hosted-server sessions persist enabled groups across clients, auth is none, and the UNKNOWN_GROUP error is named. This is exactly the beyond-annotations detail that prevention-of-misuse requires.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the session-only scope and default behavior before details, and nearly every sentence carries operational value. It is dense and slightly clause-heavy, but no sentence is filler; a small trim of the hosted-server nuance would tighten it without loss.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates by describing the catalogue return shape when `group` is omitted, plus auth, error token, and the full group key list. An agent has everything needed to call this correctly and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the enum already enumerates the groups, so the schema carries the load. The description still adds meaning the schema does not: the semantics of omitting `group` (returns a catalogue with per-group summary, tool count and enabled flag) and that `all` enables everything.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening clause gives a precise verb and resource: it changes which tools the connection lists, and it is session-only. That scope is unmistakably different from every sibling (agents, apps, keys, etc.), so an agent can select it without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the default state ('only core tools are listed by default'), the condition for calling it, the alternative for reaching hidden tools ('described by `search` / `fetch`'), and the distinct behavior of calling it with no `group` argument. When-to-use, when-not, and the fallback path are all explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-user-loginLog InA
Idempotent

Authenticate as an existing Ethora user with email + password. Stores the user session token in this MCP session and unlocks user-auth tools (ethora-app-list, ethora-files-*, ethora-wallet-*). Auth: user-auth mode (ethora-auth-mode-set first) and a configured appJwt. Errors: 401/403 bad credentials; 404 email not registered; 429 per-IP rate limit — retry with backoff.

NameRequiredDescriptionDefault
emailYesUser's registered email address (RFC 5322). Must match an account created via `ethora-user-register`.
passwordYesPlain-text password the user set during registration. Sent over TLS to the Ethora API; never echoed back or logged.
apiKeyNameNoLabel for the API key when `createApiKey` is true (e.g. `claude-code-laptop`).
createApiKeyNoWhen true, also mint a long-lived API key for this user and return it once, so headless clients / agents can reconnect with `Authorization: Bearer <key>` instead of logging in again. Default false.
apiKeyTtlDaysNoLifetime of the API key in days when `createApiKey` is true. Server default applies when omitted.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description discloses session-token storage, tool unlocking, API-key minting behavior, and error conditions. It does not contradict annotations, but it leaves the idempotency implication of createApiKey somewhat ambiguous despite idempotentHint=true.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-structured: the core action and side effect are front-loaded, followed by prerequisites and error semantics. Every sentence earns its place with no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description carries some burden for return-value behavior; it states the session token is stored and an API key may be returned once, but not the response shape. Prerequisites, errors, and side effects are otherwise sufficiently covered for a login tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all five parameters. The description adds narrative context around email/password authentication and API-key minting, but does not materially enrich parameter meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action: authenticate an existing Ethora user with email and password. It also names the session-token side effect and the unlocked user-auth tool families, distinguishing it from sibling tools like ethora-user-register and ethora-api-key-create.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit prerequisites: user-auth mode must be set via ethora-auth-mode-set first, and appJwt must be configured. It also documents error codes and the rate-limit retry guidance. It does not explicitly contrast with alternate authentication or API-key creation flows, but the context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-user-registerRegister AccountA

Create a new Ethora user account by email + first/last name, then log in and bind the session. A password is generated when omitted and returned once. By default also mints a long-lived API key so an agent can reconnect later with Authorization: Bearer <key> (no human step needed). Auth: user-auth mode and a configured appJwt (on a hosted server this is preset). Errors: 401 no appJwt; 422 email already registered or password shorter than 6 chars; 429 rate limited. Related: bulk provisioning uses ethora-user-batch-create.

NameRequiredDescriptionDefault
emailYesEmail address for the new user. Must be RFC-5322 valid and not already registered within this app. No confirmation click is required to log in; the address is used for password reset.
lastNameYesLast name shown in the user's profile.
passwordNoPassword for the account (min 6 chars). Omit to have a strong random password generated and returned once in the result.
firstNameYesFirst name shown in the user's profile and message attributions across chat rooms and the app UI.
apiKeyNameNoLabel for the API key (default `mcp-signup`).
createApiKeyNoMint a long-lived API key right after signup and return it once. Default true. Set false if you only need this session.
apiKeyTtlDaysNoAPI key lifetime in days. Server default applies when omitted.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations' simple write hint, it discloses that a generated password is returned exactly once, a long-lived API key is minted by default for agent reconnection, and that auth uses a configured `appJwt`. It also enumerates concrete error codes for 401, 422, and 429, giving the agent actionable behavioral expectations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact, front-loaded with the core action, and every sentence carries unique value—session binding, API key reconnection, auth prerequisites, error codes, and the sibling alternative. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having no output schema, the description covers the critical operational facts an agent needs: auth requirements, expected errors, default API key creation, and the one-time visibility of generated credentials. For a 7-parameter registration tool, this is complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents every parameter. The description reinforces the generated-password-once behavior and the API key defaults, but adds limited meaning beyond the schema's own field descriptions. A baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Create a new Ethora user account by email + first/last name, then log in and bind the session.' It also differentiates itself from the sibling ethora-user-login and batch creation, making the tool's unique role clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear context: single-user registration with optional API key generation for agent reconnection, and names `ethora-user-batch-create` for bulk provisioning. It doesn't explicitly say 'use ethora-user-login for existing users,' but the registration-vs-bulk distinction is enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ethora-widget-snippet-getWidget Embed SnippetA
Read-onlyIdempotent

Generate the tag that embeds the Ethora AI chat widget (the floating launcher + chat panel that website visitors use) for an app, plus the prerequisites that must hold before it answers. No API call; pure generator using this deployment's hosted widget URL and public API base. The widget answers with the app's ACTIVE bot: for API-created apps run ethora-agent-create -> ethora-agent-invite -> ethora-agent-activate { agentId, chatJid } first, otherwise POST /v2/widget/sessions returns 422 and the widget stays silent. Requires: an activated agent on the app (ethora-agent-activate); without it the widget opens but never answers. Auth: none required (uses the selected app when appId is omitted). Errors: effectively none; when no hosted widget is configured the snippet carries a <WIDGET_URL> placeholder. The widget's look (colours, texts, launcher) is saved on the app with ethora-widget-appearance-set and loads on every embed by itself, so the snippet only needs data-app-id; the cosmetic parameters here write attributes into the tag, which then win over the saved look on that site. Related: ethora-agent-activate, ethora-widget-appearance-set, ethora-bot-widget-get (legacy per-app bot only).

NameRequiredDescriptionDefault
appIdNoApp the widget belongs to (24-char hex). Defaults to the app from `ethora-app-select`.
botIdNoLegacy `data-bot-id` (bot XMPP address); only for old embeds. Prefer `appId`: the backend picks the active agent from the app.
localeNoUI locale (`data-locale`), e.g. `en`, `fr`, `es`.
apiBaseNoOverride the public API base (`data-api-base`). Defaults to this deployment's public API URL.
botNameNoDisplay name shown in the widget header (`data-bot-name`). Usually leave it out: the widget shows the active agent's name.
greetingNoGreeting shown when the panel opens (`data-greeting-message`).
positionNoLauncher corner (`data-position`).
botAvatarNoAvatar image URL shown for the bot (`data-bot-avatar`).
widgetUrlNoOverride the widget bundle base URL (the script is `<widgetUrl>/assistant.js`).
primaryColorNoBrand colour for launcher and bubbles (`data-primary-color`), e.g. `#0052CC`.

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive and openWorld, so the safety profile is covered. The description adds real behavioral context beyond that — no API call, placeholder output when no widget URL is configured, and the rule that inline cosmetic attributes override the app's saved look. This is useful, but a chunk of it (prerequisites) overlaps with usage guidance rather than pure behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose is front-loaded and every sentence carries signal (prerequisites, auth, errors, related tools). It is dense and runs long, with some overlap between the usage and requirements sentences, so it falls short of a tight 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 10-param generator with no output schema, the description covers prerequisites, auth, failure behavior, placeholder output, and related tools — enough for an agent to invoke it correctly. It never explicitly states the return shape (a snippet string), a minor gap given no output schema exists.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3 and the schema does the heavy lifting. The description still adds genuine meaning: it explains that cosmetic parameters write attributes that win over the saved appearance, and that `data-app-id` alone suffices, which is interaction semantics the schema does not convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence names a specific verb and artifact — generating the `<script>` tag that embeds the floating chat widget — and immediately scopes it as a pure generator with no API call. It explicitly distinguishes itself from siblings, noting `ethora-bot-widget-get` is the legacy per-app alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit preconditions (an activated agent, with the exact `create -> invite -> activate` chain that must run first), the failure mode if unmet (422, silent widget), and how to choose between parameters (`appId` preferred, `botId` only for old embeds). This is a full when/when-not/alternatives statement.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fetchFetch DocA
Read-onlyIdempotent

Fetch the full text of a documentation section or tool reference entry by the id returned from search (e.g. tool:ethora-app-create, doc:auth-map#app-jwt, doc:hosted-guide). Auth: none required. Errors: unknown id.

NameRequiredDescriptionDefault
idYesDocument id from a `search` result.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds two useful behavioral details: 'Auth: none required' and 'Errors: unknown id', which are not present in annotations. It also clarifies the return is 'full text'. This adds value beyond the structured metadata without contradicting it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero redundancy. The first sentence front-loads the purpose and input source; the second adds auth and error details. Every clause earns its place. Ideal length for a simple fetch operation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with one parameter, no output schema, and comprehensive annotations, the description covers the essential operational details: what it does, how to get the id, auth requirements, and error behavior. The return content ('full text') is implied. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 100% description coverage for the single 'id' parameter ('Document id from a search result'), so the baseline is 3. The description adds concrete examples of id formats ('tool:ethora-app-create', 'doc:auth-map#app-jwt', 'doc:hosted-guide') and explicitly states the id comes from 'search', reinforcing the schema. This extra context justifies a score above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Fetch'), a specific resource ('the full text of a documentation section or tool reference entry'), and the source of the identifier ('by the id returned from search'). It clearly differentiates from sibling tools like 'search' by specifying it retrieves content by id, not listing/searching. Examples of id formats further clarify the scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly ties usage to the output of 'search' ('by the id returned from search'), giving clear context on when to call this tool. It doesn't explicitly state alternatives or when not to use it, but the sibling relationship with 'search' and the clear input contract make usage straightforward. It could have been more explicit about the search→fetch workflow, but the guidance is adequate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 91 tool updatesv26.11.0
    • Addedethora-agent-activate
    • Addedethora-agent-create
    • Addedethora-agent-invite
    • Removedethora-agent-invite-to-chat
    • Addedethora-agent-list
    • Removedethora-agent-set-visibility
    • Removedethora-agent-soul-append
    • Removedethora-agent-soul-set
    • Addedethora-agent-update
    • Removedethora-agents-activate-v2
    • Removedethora-agents-clone-v2
    • Removedethora-agents-create-v2
    • Removedethora-agents-export-v2
    • Removedethora-agents-get-v2
    • Removedethora-agents-import-v2
    • Removedethora-agents-list-v2
    • Removedethora-agents-update-v2
    • Removedethora-api-key-list
    • Removedethora-api-key-revoke
    • Removedethora-app-create-chat
    • Removedethora-app-credentials
    • Removedethora-app-delete-chat
    • Removedethora-app-export-v2
    • Removedethora-app-get-default-rooms
    • Removedethora-app-get-default-rooms-with-app-id
    • Removedethora-app-import-v2
    • Removedethora-app-tokens-create-v2
    • Removedethora-app-tokens-list-v2
    • Removedethora-app-tokens-revoke-v2
    • Removedethora-app-tokens-rotate-v2
    • Changedethora-app-update1 field changed
      • changedInput schema / properties / botStatus / description
        Previous value: -"`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."New value: +"`on` enables the AI bot for new conversations (requires a configured prompt — see `ethora-bot-update`); `off` disables it. Does not change the bot's configured prompt or sources."
    • Removedethora-auth-use-app
    • Removedethora-auth-use-b2b
    • Removedethora-auth-use-user
    • Removedethora-b2b-app-bootstrap-ai
    • Removedethora-b2b-app-create
    • Removedethora-b2b-app-provision
    • Removedethora-b2b-bot-enable
    • Removedethora-bot-disable-v2
    • Removedethora-bot-enable-v2
    • Removedethora-bot-get-v2
    • Removedethora-bot-instance-diag
    • Removedethora-bot-instance-leave-chat
    • Removedethora-bot-instance-status
    • Removedethora-bot-instance-test-message
    • Removedethora-bot-instances-list
    • Removedethora-bot-update-v2
    • Removedethora-bot-widget-v2
    • Addedethora-chat-create
    • Addedethora-chat-history
    • Removedethora-chats-broadcast-job-v2
    • Removedethora-chats-broadcast-v2
    • Removedethora-chats-history-v2
    • Removedethora-chats-message-v2
    • Removedethora-configure
    • Removedethora-doctor
    • Removedethora-files-delete-v2
    • Removedethora-files-get-v2
    • Removedethora-files-upload-v2
    • Removedethora-generate-b2b-bootstrap-runbook
    • Removedethora-generate-chat-component-app-tsx
    • Removedethora-generate-env-examples
    • Changedethora-help2 fields changed
      • changedInput schema / properties / goal / description
        Previous value: -"Goal hint to tailor the recommendations and recipe list. Omit or use `auto` to get recommendations inferred from the current session state."New value: +"What you are trying to do: `new-app` (a new chat app: create, brand, rooms, users, where it lives), `in-app-chat` (chat inside your existing product with your own UI and users), `multi-agent-room` (several AI agents in one room, talking to people and each other), `widget` (AI chat widget on a website), `chat-test` (post and read messages), `b2b-bootstrap-ai` (server-side provisioning), `broadcast`, `sources-ingest`, `files-upload`, `bot-manage`, `user-login`. Omit or use `auto` for recommendations inferred from the current session state."
      • changedInput schema / properties / goal / enum
        Previous value: -[
        -  "auto",
        -  "b2b-bootstrap-ai",
        -  "broadcast",
        -  "sources-ingest",
        -  "files-upload",
        -  "bot-manage",
        -  "chat-test",
        -  "widget",
        -  "user-login"
        -]New value: +[
        +  "auto",
        +  "new-app",
        +  "in-app-chat",
        +  "multi-agent-room",
        +  "widget",
        +  "chat-test",
        +  "b2b-bootstrap-ai",
        +  "broadcast",
        +  "sources-ingest",
        +  "files-upload",
        +  "bot-manage",
        +  "user-login"
        +]
    • Addedethora-message-send
    • Removedethora-messages-context-v2
    • Removedethora-messages-search-v2
    • Removedethora-run-recipe
    • Addedethora-source-doc-upload
    • Addedethora-source-site-crawl-wait
    • Removedethora-sources-docs-delete
    • Removedethora-sources-docs-delete-v2
    • Removedethora-sources-docs-list-v2
    • Removedethora-sources-docs-tags-update-v2
    • Removedethora-sources-docs-upload
    • Removedethora-sources-docs-upload-v2
    • Removedethora-sources-site-crawl-v2
    • Removedethora-sources-site-crawl-v2-wait
    • Removedethora-sources-site-delete-url-v2
    • Removedethora-sources-site-list-v2
    • Removedethora-sources-site-reindex-v2
    • Removedethora-sources-site-reindex-v2-wait
    • Removedethora-sources-site-tags-update-v2
    • Addedethora-tools-enable
    • Removedethora-unread-counts-v2
    • Removedethora-users-batch-create-v2
    • Removedethora-users-batch-job-v2
    • Removedethora-wait-broadcast-job-v2
    • Removedethora-wait-users-batch-job-v2
    • Removedethora-wallet-get-balance
    • Removedethora-widget-embed-snippet
    • Addedethora-widget-snippet-get
  2. 88 tool updatesv26.9.3
    • Addedethora-agent-invite-to-chat
    • Addedethora-agent-set-visibility
    • Addedethora-agent-soul-append
    • Addedethora-agent-soul-set
    • Addedethora-agents-activate-v2
    • Addedethora-agents-clone-v2
    • Addedethora-agents-create-v2
    • Addedethora-agents-export-v2
    • Addedethora-agents-get-v2
    • Addedethora-agents-import-v2
    • Addedethora-agents-list-v2
    • Addedethora-agents-update-v2
    • Addedethora-api-key-create
    • Addedethora-api-key-list
    • Addedethora-api-key-revoke
    • Changedethora-app-create1 field changed
      • changedInput schema / properties / displayName / description
        Previous value: -"display name for app"New value: +"Human-readable app name shown to users in the app picker and on the public landing page. Not required to be unique across accounts."
    • Changedethora-app-create-chat5 fields changed
      • changedInput schema / properties / appId / description
        Previous value: -"appId for app"New value: +"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`."
      • addedInput schema / properties / pinned / default
        Added value: +false
      • changedInput schema / properties / pinned / description
        Previous value: -"pinned for chat"New value: +"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."
      • changedInput schema / properties / title / description
        Previous value: -"title for chat"New value: +"Display name for the new chat room. Visible to all members; not required to be unique within the app."
      • changedInput schema / required
        Previous value: -[
        -  "appId",
        -  "title",
        -  "pinned"
        -]New value: +[
        +  "title"
        +]
    • Addedethora-app-credentials
    • Removedethora-app-delete
    • Changedethora-app-delete-chat3 fields changed
      • changedInput schema / properties / appId / description
        Previous value: -"appId for app"New value: +"24-char hex ObjectId of the app the chat room belongs to. Optional — defaults to the app most recently passed to `ethora-app-select`."
      • changedInput schema / properties / chatJid / description
        Previous value: -"title for chat"New value: +"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`."
      • changedInput schema / required
        Previous value: -[
        -  "appId",
        -  "chatJid"
        -]New value: +[
        +  "chatJid"
        +]
    • Addedethora-app-export-v2
    • Changedethora-app-get-default-rooms-with-app-id2 fields changed
      • changedInput schema / properties / appId / description
        Previous value: -"appId for app"New value: +"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`."
      • removedInput schema / required
        Removed value: -[
        -  "appId"
        -]
    • Addedethora-app-import-v2
    • Addedethora-app-select
    • Addedethora-app-tokens-create-v2
    • Addedethora-app-tokens-list-v2
    • Addedethora-app-tokens-revoke-v2
    • Addedethora-app-tokens-rotate-v2
    • Changedethora-app-update8 fields changed
      • changedInput schema / properties / appDescription / description
        Previous value: -"Set the application description"New value: +"Deprecated alias for `appTagline`, kept so older callers keep working. Prefer `appTagline`."
      • changedInput schema / properties / appId / description
        Previous value: -"appId for app"New value: +"24-char hex ObjectId of the app to update. Optional — defaults to the app most recently passed to `ethora-app-select`."
      • addedInput schema / properties / appTagline
        Added value: +{
        +  "description": "Short tagline shown on the public app landing page.",
        +  "type": "string"
        +}
      • changedInput schema / properties / botStatus / description
        Previous value: -"Set the bot status to on or off, if on bot is enabled"New value: +"`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."
      • changedInput schema / properties / displayName / description
        Previous value: -"displayName of the application"New value: +"New human-readable app name. Visible in the app picker and on the public landing page."
      • changedInput schema / properties / domainName / description
        Previous value: -"If the domainName is set to 'abcd', your web application will be available at abcd.ethora.com."New value: +"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."
      • changedInput schema / properties / primaryColor / description
        Previous value: -"Set thie color of the application in #F54927 format"New value: +"Primary brand color in hex `#RRGGBB` format (e.g. `#F54927`). Used throughout the app UI."
      • removedInput schema / required
        Removed value: -[
        -  "appId",
        -  "botStatus"
        -]
    • Addedethora-auth-use-app
    • Addedethora-auth-use-b2b
    • Addedethora-auth-use-user
    • Addedethora-b2b-app-bootstrap-ai
    • Addedethora-b2b-app-create
    • Addedethora-b2b-app-provision
    • Addedethora-b2b-bot-enable
    • Addedethora-bot-disable-v2
    • Addedethora-bot-enable-v2
    • Addedethora-bot-get-v2
    • Addedethora-bot-instance-diag
    • Addedethora-bot-instance-leave-chat
    • Addedethora-bot-instance-status
    • Addedethora-bot-instance-test-message
    • Addedethora-bot-instances-list
    • Addedethora-bot-update-v2
    • Addedethora-bot-widget-v2
    • Addedethora-chats-broadcast-job-v2
    • Addedethora-chats-broadcast-v2
    • Addedethora-chats-history-v2
    • Addedethora-chats-message-v2
    • Addedethora-configure
    • Addedethora-doctor
    • Addedethora-feedback-submit
    • Addedethora-files-delete-v2
    • Addedethora-files-get-v2
    • Addedethora-files-upload-v2
    • Addedethora-generate-b2b-bootstrap-runbook
    • Addedethora-generate-chat-component-app-tsx
    • Addedethora-generate-env-examples
    • Addedethora-help
    • Addedethora-messages-context-v2
    • Addedethora-messages-search-v2
    • Addedethora-run-recipe
    • Addedethora-sources-docs-delete
    • Addedethora-sources-docs-delete-v2
    • Addedethora-sources-docs-list-v2
    • Addedethora-sources-docs-tags-update-v2
    • Addedethora-sources-docs-upload
    • Addedethora-sources-docs-upload-v2
    • Addedethora-sources-site-crawl-v2
    • Addedethora-sources-site-crawl-v2-wait
    • Addedethora-sources-site-delete-url-v2
    • Addedethora-sources-site-list-v2
    • Addedethora-sources-site-reindex-v2
    • Addedethora-sources-site-reindex-v2-wait
    • Addedethora-sources-site-tags-update-v2
    • Addedethora-status
    • Addedethora-unread-counts-v2
    • Changedethora-user-login5 fields changed
      • addedInput schema / properties / apiKeyName
        Added value: +{
        +  "description": "Label for the API key when `createApiKey` is true (e.g. `claude-code-laptop`).",
        +  "type": "string"
        +}
      • addedInput schema / properties / apiKeyTtlDays
        Added value: +{
        +  "description": "Lifetime of the API key in days when `createApiKey` is true. Server default applies when omitted.",
        +  "maximum": 365,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / createApiKey
        Added value: +{
        +  "description": "When true, also mint a long-lived API key for this user and return it once, so headless clients / agents can reconnect with `Authorization: Bearer <key>` instead of logging in again. Default false.",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / email / description
        Previous value: -"email for login"New value: +"User's registered email address (RFC 5322). Must match an account created via `ethora-user-register`."
      • changedInput schema / properties / password / description
        Previous value: -"password for login"New value: +"Plain-text password the user set during registration. Sent over TLS to the Ethora API; never echoed back or logged."
    • Changedethora-user-register7 fields changed
      • addedInput schema / properties / apiKeyName
        Added value: +{
        +  "description": "Label for the API key (default `mcp-signup`).",
        +  "type": "string"
        +}
      • addedInput schema / properties / apiKeyTtlDays
        Added value: +{
        +  "description": "API key lifetime in days. Server default applies when omitted.",
        +  "maximum": 365,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / createApiKey
        Added value: +{
        +  "description": "Mint a long-lived API key right after signup and return it once. Default true. Set false if you only need this session.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / email / description
        Added value: +"Email address for the new user. Must be RFC-5322 valid and not already registered within this app. No confirmation click is required to log in; the address is used for password reset."
      • addedInput schema / properties / firstName / description
        Added value: +"First name shown in the user's profile and message attributions across chat rooms and the app UI."
      • addedInput schema / properties / lastName / description
        Added value: +"Last name shown in the user's profile."
      • addedInput schema / properties / password
        Added value: +{
        +  "description": "Password for the account (min 6 chars). Omit to have a strong random password generated and returned once in the result.",
        +  "minLength": 6,
        +  "type": "string"
        +}
    • Addedethora-users-batch-create-v2
    • Addedethora-users-batch-job-v2
    • Addedethora-wait-broadcast-job-v2
    • Addedethora-wait-users-batch-job-v2
    • Removedethora-wallet-erc20-transfer
    • Addedethora-widget-embed-snippet
    • Addedfetch
    • Addedsearch
  3. 12 tool updatesv1.0.0
    • First observedethora-app-create
    • First observedethora-app-create-chat
    • First observedethora-app-delete
    • First observedethora-app-delete-chat
    • First observedethora-app-get-default-rooms
    • First observedethora-app-get-default-rooms-with-app-id
    • First observedethora-app-list
    • First observedethora-app-update
    • First observedethora-user-login
    • First observedethora-user-register
    • First observedethora-wallet-erc20-transfer
    • First observedethora-wallet-get-balance

TDQS

A4.1/5.0

Scored across 24 tools

Disambiguation4/5

Operational tools have clear resource/action boundaries, and potentially confusing agent steps such as create, invite, and activate are explicitly differentiated. There is minor overlap among the orientation and discovery tools (`ethora-status`, `ethora-help`, `search`, and `fetch`), while registration also overlaps slightly with login and API-key creation, but the descriptions generally resolve these choices.

Naming Consistency4/5

Names consistently use kebab-case and usually follow an `ethora-<resource>-<action>` pattern, with predictable app, agent, user, and source families. Bare `search` and `fetch`, noun-only names such as `ethora-status` and `ethora-help`, and the action-less `ethora-chat-history` prevent the pattern from being fully uniform.

Tool Count3/5

At 24 tools, the exposed set is at the heavy end and spans authentication, documentation, apps, agents, chat, knowledge sources, and widgets. Most tools earn their place and session-based group enabling helps manage expansion, but the listed surface is still large for one server.

Completeness3/5

The tools cover a core registration/login-to-app-to-agent-to-room-to-widget workflow, but lifecycle coverage is uneven: room discovery/deletion, app and agent deletion, API-key revocation, and source listing/deletion are absent. Many descriptions reference companion tools outside the supplied set; `ethora-tools-enable` suggests gated groups may fill some gaps, but the visible surface alone still has dead ends.

Maintenance

ActivityNo data
ResponsivenessSyncing

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    F
    maintenance
    Enables interaction with Coolify applications and resources through the Coolify API via a standardized interface, supporting application management operations such as listing, starting, stopping, restarting, and deploying.
    11
    13
    -
  • A
    license
    A
    quality
    C
    maintenance
    Enables interaction with any REST API through token or login authentication, with automatic Swagger/OpenAPI documentation integration for endpoint discovery and comprehensive HTTP request support.
    7
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to create and manage Hellō applications with full developer context, supporting app creation, updates, secret generation, and logo management through a single unified tool.
    1
    59 npm
    4
    MIT