Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ethora-mcp-server",
"version": "26.10.1",
"version": "26.10.2",
"description": "MCP server for the open-source Ethora chat & messaging platform — manage apps and chat rooms, broadcast messages, and deploy AI agents / chatbots with RAG sources, across user-auth and B2B/app-token flows.",
"author": {
"name": "Dappros Ltd",
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

All notable changes to this package are documented here. For cross-SDK release notes, see [ethora/RELEASE-NOTES.md](https://github.com/dappros/ethora/blob/main/RELEASE-NOTES.md).

## 26.10.2 - 2026-10-16

### Changed
- OAuth connections (`/mcp/oauth`: ChatGPT, Claude.ai) list every offered tool up front and no longer carry `ethora-tools-enable`; the server-integration groups (keys, session, b2b, legacy-bot) are not offered there at all. Directory scanners require each model-callable operation to be its own listed tool. The open and personal-URL entries keep the compact core plus `ethora-tools-enable`.
- `openWorldHint` is true for every tool that calls the Ethora API (an independently operated system from the client's point of view) or fetches a website, and false only for the tools that run inside the server (status, help, app-select, search, fetch, session configuration, text generators).
- `destructiveHint` is true for the crawl, re-index, refresh and knowledge-rebuild tools: they replace stored pages or index entries (the crawl tools only with `force`).

## 26.10.1 - 2026-10-16

### Added
Expand Down
2 changes: 1 addition & 1 deletion claude-plugin/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "ethora",
"displayName": "Ethora",
"version": "26.10.1",
"version": "26.10.2",
"description": "Build and operate Ethora chat apps and AI agents from Claude: create apps, provision users, open rooms, send messages, configure RAG agents, script conversation flows and generate an embeddable chat widget.",
"author": {
"name": "Dappros Ltd",
Expand Down
188 changes: 94 additions & 94 deletions docs/TOOL_ANNOTATIONS.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions openai-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "ethora",
"version": "26.10.1",
"version": "26.10.2",
"description": "Build and run chat apps, messaging rooms and AI agents on Ethora from ChatGPT: create an app, open rooms, add users, create agents with a knowledge base, put a chat widget on a website.",
"author": {
"name": "Dappros Ltd",
Expand All @@ -24,7 +24,7 @@
"interface": {
"displayName": "Ethora",
"shortDescription": "Chat apps and AI agents",
"longDescription": "Ethora is an open-source chat and messaging platform with a built-in AI agent framework. This plugin connects ChatGPT to your Ethora account so you can build and run chat products by describing them.\n\nWhat you can do:\n- Create a chat app (your own tenant with users, rooms and branding) and open chat rooms.\n- Create AI agents with a persona and a knowledge base from a website or uploaded documents, put them in rooms, and talk to them.\n- Seed a room with several agents that reply to people and to each other.\n- Generate the <script> tag that puts an AI chat widget on any website.\n- Send and read messages, search message history, manage users and files.\n\nWho it is for: product teams and developers adding chat or AI assistants to a website or app, and anyone who wants a working chat space with AI participants without setting up infrastructure.\n\nHow it works: you sign in with your Ethora account (or create one in the conversation). Tools act only on apps you own. A compact core tool set is listed by default; more tools are enabled on request within the conversation.\n\nData: the plugin works with the account, apps, rooms, users, agents, files and messages you create on Ethora, under the Ethora privacy policy. It does not ask for, and must not be used to collect, health or medical information, government identifiers, payment card numbers, biometric data or other sensitive personal data.\n\nLimitations: the plugin manages apps, rooms, users and agents. It does not render chat inside ChatGPT; people chat in the Ethora web client, your app via the chat component, or the website widget. Webhooks, push-notification setup, moderation actions and billing are managed in the Ethora dashboard, not through the plugin. Wallet and crypto features are not available in the hosted server.",
"longDescription": "Ethora is an open-source chat and messaging platform with a built-in AI agent framework. This plugin connects ChatGPT to your Ethora account so you can build and run chat products by describing them.\n\nWhat you can do:\n- Create a chat app (your own tenant with users, rooms and branding) and open chat rooms.\n- Create AI agents with a persona and a knowledge base from a website or uploaded documents, put them in rooms, and talk to them.\n- Seed a room with several agents that reply to people and to each other.\n- Generate the <script> tag that puts an AI chat widget on any website.\n- Send and read messages, search message history, manage users and files.\n\nWho it is for: product teams and developers adding chat or AI assistants to a website or app, and anyone who wants a working chat space with AI participants without setting up infrastructure.\n\nHow it works: you sign in with your Ethora account (or create one in the conversation). Tools act only on apps you own. Every tool is listed up front with its own description, input schema and annotations; nothing is loaded or enabled during the conversation.\n\nData: the plugin works with the account, apps, rooms, users, agents, files and messages you create on Ethora, under the Ethora privacy policy. It does not ask for, and must not be used to collect, health or medical information, government identifiers, payment card numbers, biometric data or other sensitive personal data.\n\nLimitations: the plugin manages apps, rooms, users and agents. It does not render chat inside ChatGPT; people chat in the Ethora web client, your app via the chat component, or the website widget. Webhooks, push-notification setup, moderation actions and billing are managed in the Ethora dashboard, not through the plugin. Wallet and crypto features are not available in the hosted server.",
"developerName": "Dappros Ltd",
"category": "Developer Tools",
"capabilities": [
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ethora/mcp-server",
"version": "26.10.1",
"version": "26.10.2",
"mcpName": "io.github.dappros/ethora-mcp-server",
"description": "MCP server for the Ethora chat & messaging platform: login, manage apps and chat rooms, broadcast messages, and deploy AI agents / chatbots with RAG sources.",
"main": "dist/index.js",
Expand Down
6 changes: 3 additions & 3 deletions scripts/tool-annotations-doc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ lines.push("")
lines.push("Every tool the server lists carries the four MCP annotation hints as explicit booleans. The rules:")
lines.push("")
lines.push("- **readOnlyHint** is true when the call stores nothing on the server: it returns data, or changes only what this conversation points at (the selected app, the listed tools).")
lines.push("- **destructiveHint** is true when the call deletes, revokes, rotates or removes something, or overwrites fields of an existing record. Creating, appending, toggling a reversible flag or starting a job is not destructive. Always false for read-only tools.")
lines.push("- **destructiveHint** is true when the call deletes, revokes, rotates or removes something, or overwrites existing data: updates and sets, and the re-crawl, re-index and refresh jobs that replace stored pages or index entries. Creating, appending, toggling a reversible flag or starting a job that only adds is not destructive. Always false for read-only tools.")
lines.push("- **idempotentHint** is true when repeating the call with the same arguments has no further effect. Create, send, upload, start-a-job, rotate, register, clone, import, append and model runs are not idempotent.")
lines.push("- **openWorldHint** is true when the call reaches beyond the signed-in account's own data on the Ethora server: it fetches external websites, or delivers messages to other people (or to the Ethora team, for feedback). Reading and writing the account's own apps, rooms, users, agents and files is closed-world.")
lines.push("- **openWorldHint** is true when the call leaves the MCP server: every call to the Ethora API (an independently operated system from the client's point of view), every fetch of an external website, every message delivered to other people. It is false only for the tools that run entirely inside the server: session state, help, documentation search and text generators.")
lines.push("")
lines.push("The hosted server (`mcp.chat.ethora.com`) never lists the stdio-only wallet tools. Group `core` is listed by default; the other groups appear after `ethora-tools-enable`.")
lines.push("The hosted server (`mcp.chat.ethora.com`) never lists the stdio-only wallet tools. On the OAuth entry (`/mcp/oauth`, used by ChatGPT and Claude.ai) every tool outside the `keys`, `session`, `b2b` and `legacy-bot` groups is listed up front and `ethora-tools-enable` is absent. On the open and personal-URL entries, group `core` is listed by default and the other groups appear after `ethora-tools-enable`.")
lines.push("")

const order = [CORE_GROUP, ...Object.keys(TOOL_GROUPS).filter((g) => g !== CORE_GROUP).sort(), "stdio-only", "aliases"]
Expand Down
4 changes: 2 additions & 2 deletions server.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
"url": "https://github.com/dappros/ethora-mcp-server",
"source": "github"
},
"version": "26.10.1",
"version": "26.10.2",
"packages": [
{
"registryType": "npm",
"identifier": "@ethora/mcp-server",
"version": "26.10.1",
"version": "26.10.2",
"transport": {
"type": "stdio"
},
Expand Down
9 changes: 6 additions & 3 deletions src/httpServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js"
import { appConfig } from "./config.js"
import { createSessionContext, runWithSession, setHostedMode, SessionContext } from "./session.js"
import { fetchAppJwtByDomainName, usersMe } from "./apiClientDappros.js"
import { ALL_SCOPES, ADVERTISED_SCOPES, hideOAuthTools, parseScopes } from "./scopeGuard.js"
import { ALL_SCOPES, ADVERTISED_SCOPES, parseScopes } from "./scopeGuard.js"
import { applyOAuthSurface } from "./toolGroups.js"
import { renderLandingPage } from "./landingPage.js"
import { AccountMemoryStore, identityKeyFor, applyMemory, snapshotSession } from "./accountMemory.js"
import { enableGroups, enabledGroups } from "./toolGroups.js"
Expand Down Expand Up @@ -371,9 +372,11 @@ export async function startHttpServer(opts: HttpServerOptions) {
const profile = kind === "oauth" ? "oauth" : (pathKey || headerJwt) ? "authenticated" : "open"
// `?tools=all` on the endpoint URL lists the whole catalogue up front
// (scripts, power users); the default is the core group.
const toolsProfile = String((req.query as any)?.tools || "").toLowerCase() === "all" ? "all" : "core"
// OAuth connections list every offered tool up front (directory
// scanners require each operation to be its own listed tool).
const toolsProfile = kind === "oauth" || String((req.query as any)?.tools || "").toLowerCase() === "all" ? "all" : "core"
const server = opts.buildServer(profile, toolsProfile)
if (kind === "oauth") hideOAuthTools(server)
if (kind === "oauth") applyOAuthSurface(server)
entry = { server, transport, session }
fresh = true
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const { installToolAliases } = await import("./toolNames.js")
type ToolsProfile = import("./toolGroups.js").ToolsProfile

const SERVER_NAME = "Ethora MCP Server"
const SERVER_VERSION = "26.10.1"
const SERVER_VERSION = "26.10.2"

export function buildServer(profile?: "open" | "authenticated" | "oauth", toolsProfile?: ToolsProfile) {
// In HTTP mode this runs once per session, after setHostedMode(true); the
Expand Down
11 changes: 10 additions & 1 deletion src/instructions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,21 @@ const AUTHENTICATED_COMMON = [
"Each MCP session is private: nothing from another client's session is visible here. The selected app (`ethora-app-create` selects the new app by itself) and the enabled tool groups are remembered for the signed-in account for 24 hours, so they survive a reconnect or a client that opens a new session per call; an account with exactly one app has it selected automatically.",
"App credentials are never included in tool results: appSecret, tenantSecret, appToken and passwords come back as [redacted]. When a snippet or config needs the appToken, call `ethora-app-credentials-reveal { appId, confirm: true }`; the App Secret is only available in the web dashboard API tab.",
"If a tool fails in a way the user should know about, or something is missing or wrong, offer to report it with `ethora-feedback-submit`; it reaches the Ethora team and attaches this session's recent errors automatically.",
TOOL_GROUPS_LINE,
]

// OAuth connections (ChatGPT, Claude.ai directory listings) list every tool
// up front: directory scanners want each model-callable operation exposed as
// its own tool with a description, schema and annotations, not loaded on
// request. The server-integration groups (keys, session, b2b, legacy-bot) are
// not offered on this entry at all.
export const OAUTH_TOOLS_LINE =
"Every available tool is listed; there is nothing to enable. Read-only tools (list, get, history, search) are safe to call freely; tools marked destructive overwrite or delete the user's data, so confirm first."

export const OAUTH_INSTRUCTIONS = [
"Ethora MCP Server: create and manage Ethora chat/messaging apps, users, chats, AI agents and bots through the Ethora API.",
"This connection is authenticated through OAuth. The Ethora user's credentials are supplied by the MCP client; never ask the user for an Ethora password or API key, and do not look for login or register tools, they are not available on this connection.",
...AUTHENTICATED_COMMON,
OAUTH_TOOLS_LINE,
"If a tool is refused with INSUFFICIENT_SCOPE, the user granted fewer permissions when connecting; explain that and stop rather than retrying.",
].join("\n")

Expand All @@ -60,6 +68,7 @@ export const AUTHENTICATED_INSTRUCTIONS = [
"This connection is already authenticated: the client supplied an API key (personal connector URL or Bearer header). Never ask the user for an Ethora password or API key and do not call login or register tools.",
...AUTHENTICATED_COMMON,
"Keys can be managed with `ethora-api-key-create`, `ethora-api-key-list` and `ethora-api-key-revoke` when the user asks; never print key values unless the user explicitly asks.",
TOOL_GROUPS_LINE,
].join("\n")

export type InstructionProfile = "stdio" | "open" | "authenticated" | "oauth"
Expand Down
Loading
Loading