Endara Desktop
A tray app that bundles Endara Relay, manages its lifecycle, and gives you a UI for adding endpoints, running OAuth flows, and watching tool calls live — no terminal required.
Overview
Endara Desktop is a Tauri 2 tray application that wraps the relay. It bundles the endara-relaybinary as a sidecar, spawns it on launch, monitors its health, restarts it if it crashes, and kills it cleanly on quit. Everything you can do from the relay's management API — adding endpoints, completing OAuth flows, browsing tools, streaming logs — is available from the UI, which reaches the management API through a local socket rather than HTTP.
In the standard install, the desktop owns the relay. There is no separate background service: the relay's lifetime is bounded by the desktop's lifetime. The relay's MCP endpoint binds to 127.0.0.1:9400 in production (and 127.0.0.1:9500 in dev), so any MCP client on the same machine can reach it over loopback. The management API used by Endara Desktop is exposed on a separate local Unix-domain socket / Windows Named Pipe — see Management API.
Under the hood the UI is a SvelteKit frontend (Svelte 5 + Tailwind CSS 4). It talks to the bundled relay's management API through a Tauri command (relay_api_request) that proxies HTTP semantics over a local Unix-domain socket (macOS / Linux) or Windows Named Pipe — never over a TCP port. This means a malicious page in your browser can't reach /api/* even if it guesses the right URL. Both the GUI and the bundled relay are open source — see endara-ai/endara-desktop.
Install
macOS — Homebrew (recommended)
brew install --cask endara-ai/tap/endaraInstalls the latest signed and notarized DMG from the endara-ai/homebrew-tap tap and registers the app for brew upgrade. The built-in Tauri updater also continues to work, so new versions arrive whichever way you prefer.
Direct downloads
Grab an installer for your platform from github.com/endara-ai/endara-desktop/releases:
| Platform | Format | File |
|---|---|---|
| macOS | DMG installer | Endara_x.x.x_aarch64.dmg |
| Windows | NSIS setup | Endara_x.x.x_x64-setup.exe |
| Windows | MSI installer | Endara_x.x.x_x64_en-US.msi |
| Linux | Debian package | endara_x.x.x_amd64.deb |
| Linux | AppImage | Endara_x.x.x_amd64.AppImage |
First run
Launch the app. The Endara icon appears in your menu bar (macOS) or system tray (Windows / Linux), and the bundled relay starts automatically on 127.0.0.1:9400. Click the tray icon and choose Open Endara to bring up the main window.
From the dashboard you'll see an empty endpoint list (left sidebar) and a detail panel on the right. Add your first MCP server from + Add server, then point any MCP client at http://localhost:9400/mcp. For Claude Desktop, drop this into claude_desktop_config.json:
{
"mcpServers": {
"endara": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://localhost:9400/mcp"]
}
}
}Claude Desktop's config file does not accept HTTP URLs directly — entries with a top-level url field are silently stripped on startup. The snippet above uses mcp-remote as a stdio shim that proxies to the relay over loopback. It requires npx on your PATH (ships with Node.js).
For Cursor, paste http://localhost:9400/mcp under Settings → MCP → Add new MCP server → HTTP. Restart the client and your endpoint's tools show up in its tool list, prefixed by the endpoint name.
Start on Login
Open Settings (⌘, on macOS) and toggle Start on Login. On macOS this registers a LaunchAgent at ~/Library/LaunchAgents/Endara Desktop.plist that re-launches the desktopat login — the desktop then spawns the relay as its child. The LaunchAgent does not run the relay directly. On Linux and Windows, autostart uses the platform's native mechanism (XDG autostart and the Windows registry, respectively).
Keyboard shortcuts
| Shortcut | Action |
|---|---|
⌘K | Open global tool search |
⌘, | Open settings |
Esc | Go back / close panel |
Managing endpoints
An endpoint is one MCP server the relay talks to. The sidebar lists every endpoint with a transport badge (STDIO / SSE / HTTP / OAuth) and a health dot — 🟢 healthy, 🟡 degraded, 🔴 failed. Selecting one opens a detail panel with tabs for tools, logs, config, and (for OAuth endpoints) auth.
Add a server
Click + Add server and choose a transport:
- STDIO — paste a command and arguments (for example
npx -y @modelcontextprotocol/server-filesystem /Users/me). The relay spawns it as a child process. - HTTP — paste a URL like
https://mcp.context7.com/mcpand any required headers. - SSE — for legacy servers that speak Server-Sent Events instead of streamable HTTP.
- OAuth — for remote servers that require an OAuth token. See OAuth setup.
Saving the form writes the new [[endpoints]] entry into ~/.endara/config.toml. The relay's file watcher picks the change up and reloads adapters without a restart — see hot reload in the relay docs.
Edit, disable, or remove
Right-click an endpoint (or use the ⋯ menu) to edit its configuration, temporarily disable it, restart its adapter, or remove it altogether. Disabling keeps the entry in config.toml but unloads the adapter; removing deletes the entry. STDIO adapters that crash are restarted automatically with exponential backoff — their logs stream to the Logs tab.
Browse tools
The Tools tab lists every tool the endpoint exposes, with the prefixed name the relay advertises (<name>__<tool>), the input schema, and the description. The global ⌘K palette searches across every connected endpoint at once.
OAuth setup
Some MCP servers require an OAuth flow before they expose any tools. Endara Desktop runs the entire flow inside the app: you fill in the + Add serverdialog, complete the provider's consent screen in your default browser, and the relay receives the authorization code on a loopback redirect URI at http://127.0.0.1:9400/oauth/callback.
Add an OAuth endpoint
From + Add server, choose OAuth and fill in:
- Name— used to namespace this server's tools (
<name>__<tool>). - URL — the MCP server's endpoint, e.g.
https://mcp.linear.app/mcp. - OAuth server URL— the authorization server's base URL. Many MCP servers advertise this via OAuth metadata discovery; if not, paste it from the provider's docs.
- Scopes — the scopes you want to request, e.g.
read write.
If the authorization server supports Dynamic Client Registration (RFC 7591), the relay registers a client automatically and you don't have to provide a client_id. If not, follow Manual client setup below.
Manual client setup (Google, GitHub, etc.)
For providers without DCR, register an OAuth app yourself before adding the endpoint. Use these values when registering the app:
- Application type: Web application (or equivalent — anything that supports a redirect URI).
- Redirect URI:
http://127.0.0.1:9400/oauth/callback(or whichever port your relay is listening on).
Back in the + Add server dialog, expand the Advanced section and paste the client_id (and client_secretif the provider is a confidential client) before submitting. If the relay still attempts DCR and the authorization server rejects it, the dialog falls back to a manual credentials prompt — paste the same values there. Credentials are persisted via the relay's management API into ~/.endara/tokens/ with mode 0600; they are not written into config.toml. See OAuth credential storage in the relay docs for details.
Run the flow
Submitting the + Add serverdialog kicks off the OAuth flow automatically: your default browser opens the provider's consent screen, and after you approve, the provider redirects to 127.0.0.1:9400/oauth/callback. The relay exchanges the code for a token, stores it, and the new endpoint appears in the sidebar with its Auth tab badge set to Authenticated. Tools become available immediately.
Token lifecycle
- Refresh. The relay refreshes tokens automatically before expiry when a refresh token is present. The Auth tab shows a live countdown to expiry; click Refresh Now to force one.
- Re-authorize. If a refresh fails (revoked, expired refresh token, scope change), the badge moves to Auth Required. Click Re-authorize in the Auth tab to re-run the browser flow against the same endpoint.
JS execution mode
Endara Desktop exposes a toggle for the relay's JS execution engine. When enabled, the relay stops advertising every tool from every endpoint to the model. Instead it advertises three meta-tools — list_tools, search_tools, and execute_tools — and lets the model run a sandboxed JavaScript program that calls the underlying tools in a single round-trip.
Toggle it from Settings → JS Execution Mode. The relay reloads in place; any open MCP clients pick up the new tool list on their next refresh. The sandbox is in-process boa_engine with no network or filesystem access — see sandbox limits and the meta-tool reference for the full surface area.
Troubleshooting
Relay not starting / port 9400 in use
If the desktop reports the relay failed to start with EADDRINUSE, another process is already bound to 127.0.0.1:9400. The most common cause is having both the bundled relay (inside Endara Desktop) and a separately-installed CLI relay (brew install endara-ai/tap/endara-relay) running. Pick one. Dev builds listen on 127.0.0.1:9500instead — substitute that port below if you're running a dev build.
Find the process holding the port:
# macOS / Linux
lsof -nP -iTCP:9400 -sTCP:LISTEN # use 9500 for dev builds
# Windows (PowerShell)
Get-NetTCPConnection -LocalPort 9400 -State ListenStop whichever instance you don't want. The desktop's relay watchdog restarts the bundled relay automatically on the next health check; if it stays in a failed state, open Settings and use the relay-restart action shown when the relay is down. See also Relay troubleshooting.
NoteThe relay's management API (/api/*) does not bind a TCP port — it lives on a Unix-domain socket / Windows Named Pipe (see Management API). Don't look for an api.sock conflict in the diagnostic above; a separate failure mode is covered in the next subsection.
Management socket conflict (UDS / Named Pipe)
The management API binds to a per-user local endpoint. If the bundled relay reports it can't bind the socket or pipe, a previous process likely left a stale entry behind after a hard kill. The relay attempts to clean these up automatically on the next start, but you can verify and remove the stale entry by hand if needed.
Locations:
- Linux —
$XDG_RUNTIME_DIR/endara-relay/api.sock - macOS —
$TMPDIR/endara-relay-$(id -u)/api.sock(falls back to the relay's data dir if$TMPDIRis unset) - Windows —
\\.\pipe\endara-relay-<sid>(per-user Named Pipe; ACL is restricted to the current user's SID)
Check whether a stale socket is present:
# Linux
ls -l "$XDG_RUNTIME_DIR/endara-relay/api.sock"
# macOS
ls -l "$TMPDIR/endara-relay-$(id -u)/api.sock"
# If you confirm the relay isn't running, a stale file is safe to remove:
rm -f "$XDG_RUNTIME_DIR/endara-relay/api.sock" # or the macOS path aboveNamed Pipes on Windows do not leave a file on disk — the OS releases the pipe when the owning process exits, so the same hard-kill scenario isn't a concern. If a pipe-binding failure persists, another endara-relay instance is still running under the same user account.
Tray icon doesn't appear
If the Endara tray icon is missing from the menu bar — or the Open Endaraentry isn't showing in the tray menu — first quit and relaunch the app. On macOS, check System Settings → Control Center → Menu Bar Only for hidden items, and make sure Endara Desktop is allowed in System Settings → General → Login Items & Extensions if you expect it to launch at login. On Windows and Linux, confirm the system tray / notification area is enabled and not collapsed behind an overflow chevron.
OAuth redirect failed
If the browser approves the consent screen but the Auth tab stays on Needs Login:
- Confirm the Redirect URI registered with the provider is exactly
http://127.0.0.1:9400/oauth/callback(matching the relay's actual port — if you customized it, use that port). - Some VPNs and endpoint security tools block loopback HTTP. Disable them temporarily, or whitelist
127.0.0.1. - Open the Logs tab for the endpoint and look for the OAuth exchange. The same data is available in
~/.endara/logs/relay.log.<YYYY-MM-DD>.
Endpoint stuck in failed or degraded state
Open the Logstab for that endpoint to stream the adapter's stderr live. STDIO adapters auto-restart with exponential backoff, so a transient crash will recover on its own; persistent failures are usually a missing command, an unset env var, or an OAuth flow that hasn't completed. The relay's own log at ~/.endara/logs/relay.log.<YYYY-MM-DD> has the full picture.
Auto-update isn't finding new versions
The Tauri updater checks GitHub Releases. Make sure the app can reach github.com. On macOS you can also force an upgrade through Homebrew:
brew upgrade --cask endara-ai/tap/endaraOn Windows and Linux, re-run the installer from the latest release.
Reset configuration
Quit Endara Desktop, then edit or delete ~/.endara/config.toml. The relay recreates a default config on next start if the file is missing. To force every endpoint back through OAuth, also remove ~/.endara/tokens/.
File locations (macOS)
- Bundled relay binary:
/Applications/Endara Desktop.app/Contents/MacOS/endara-relay - Auto-start LaunchAgent:
~/Library/LaunchAgents/Endara Desktop.plist(only present if Start on Login is enabled) - Desktop log:
~/Library/Logs/ai.endara.desktop/Endara Desktop.log - Relay log:
~/.endara/logs/relay.log.<YYYY-MM-DD>(rotated daily) - Relay config:
~/.endara/config.toml
On Linux and Windows the same parent/child model applies; only the paths differ — the desktop uses Tauri's standard log/config directories for the ai.endara.desktopidentifier, and autostart uses the platform's native mechanism (XDG autostart on Linux, the Run registry key on Windows) instead of a LaunchAgent.