Desktop App
Portuni.app is the Tauri-built macOS desktop client. It’s the daily-driver way to use Portuni: install one DMG and you get the UI, the MCP server, and the integration glue in a single application.
What it gives you
Section titled “What it gives you”A native macOS window (1600×1000 by default, opens maximized) with:
- Graph view — Cytoscape-rendered interactive node graph using the
fcoseforce-directed layout. Pan, zoom, click a node to focus. - Detail pane — the right column shows the focused node’s full detail: owner, responsibilities, data sources, tools, events timeline, files. Same payload
portuni_get_nodereturns over MCP, rendered as a panel rather than JSON. The Files tab remembers which folders you collapsed per node, on this device. The header shows the node’s ID and its local path (both click-to-copy), an Open-in-Finder button, and — when the folder lives on Google Drive — copy-link and open-on-Drive actions. If the node has no local mirror on this device yet, the header shows a “Create mirror” button that creates it directly. - Workspace view — a node browser with type / status filters, sidebar navigation, and a status footer.
- Task chat (Work) — a node’s action bar is “New task”: one click opens an empty thread (a draft), and your first message is what starts the task — no picker, no required field. The runner and the provider instance are resolved for you (the node’s organization default when it has one); model and reasoning effort are per-thread pickers in the composer. See Working in the app. There is no embedded terminal; an agent runs only as a task.
- Actors page — browse and manage actors and assignments.
- Settings page — workspaces (create, enable, open a window for one, pick each one’s data mode), per-workspace Turso credentials and workspace root, a Runners section (replaces Profiles, #344: detected runner adapters with their install/login status, and provider instances — env vars, typically
CLAUDE_CONFIG_DIR, with a default assignable per organization — edited through the sidecar’sGET/POST/PATCH/DELETE /runners/instancesREST API instead of the desktop’s ownconfig.json; see Runners), an Account section (the interface language — English or Čeština, saved to your account so it applies on every device and takes effect without a reload; the app menu and the browser page shown after Google sign-in follow the language of the focused window — plus Google sign-in and device tokens for a team workspace), a Sync section (informational — Drive sync is configured once on the central server via a Service Account, see Setting Up Remotes; a personal workspace shows a “no remote” note instead), and an MCP Server section with one-click install buttons for Claude Code, Codex, and Mistral Vibe. - Create-node modal, date picker, and other interactive controls for editing the graph directly from the UI.
Embedded MCP sidecar
Section titled “Embedded MCP sidecar”The app bundles the Portuni MCP server as an embedded binary (binaries/portuni-sidecar) and spawns it on launch. You do not need to:
- Clone the GitHub repo.
- Install Node.js or Varlock.
- Run
npm startin a tmux session.
Each enabled workspace runs its own sidecar on a fixed loopback port, allocated from 47011 up (the first workspace gets 47011). Any MCP client — Claude Code, Codex CLI, Gemini CLI, Mistral Vibe — can point at http://localhost:<port>/mcp the same way it would at a standalone server. The sidecar’s bearer token is persisted per workspace in the macOS Keychain (it survives restarts and can be rotated from Settings); the easiest way to wire up an external client is the one-click install buttons in Settings → MCP Server, which register the right URL and token for each workspace. For a client the install buttons don’t cover, copy each workspace’s token from Settings → MCP Server (PORTUNI_MCP_TOKEN_<workspace-id>, plus PORTUNI_MCP_TOKEN as an alias for the active workspace) and export it in your own shell.
Workspaces
Section titled “Workspaces”The app manages one or more workspaces — think of each as an independent Portuni: its own database, its own workspace root for mirrors, its own sidecar port, and its own Keychain-held credentials. All enabled workspaces run concurrently, each in its own window: the switcher in the sidebar (and the workspace list in Settings) opens or focuses a workspace’s window rather than swapping the content of the current one, so several workspaces are usable side by side. Each workspace also picks its data mode: local (its own Turso/SQLite database) or central (your organization’s server — see Files: the two sync planes), so a personal graph and a company graph can live side by side in one app.
Install
Section titled “Install”- Open the GitHub releases page.
- Download the DMG matching your CPU:
Portuni_<version>_aarch64.dmg— Apple Silicon (M1/M2/M3/M4)- Intel Macs are no longer targeted; use the CLI install below if you’re on Intel.
- Open the DMG and drag
Portuni.appto/Applications/. - Launch it.
Release DMGs are Developer ID signed and notarized, so the app opens without Gatekeeper warnings. If you built the app yourself without signing secrets, you’ll see the “unidentified developer” dialog — right-click → Open to bypass.
First run
Section titled “First run”A fresh install creates your first workspace and walks you through its setup. What you’re asked depends on the workspace’s data mode:
- Personal workspace — paste your
TURSO_URLandTURSO_AUTH_TOKEN, or skip to use a local SQLite database, and pick the root directory where mirror folders will live (e.g.~/Workspaces/portuni; the equivalent ofPORTUNI_WORKSPACE_ROOTin the CLI install). Credentials go to the macOS Keychain — you never edit.env.localfor the desktop install. - Team workspace — sign in with your Google account instead; no database credentials needed. See Files: the two sync planes.
After that, you land in the Workspace view. Create your first organization node, then add projects / processes / areas / principles under it. (Upgrading from an older single-workspace install? The app migrates your existing configuration into the first workspace automatically.)
Updates (auto-update)
Section titled “Updates (auto-update)”Starting with 0.8.0, the app checks for updates itself — no more manual DMG downloads for every release.
- Check cadence. The app checks the latest GitHub release 10 s after the backend is ready, then every 6 h while running, plus on demand from Settings. Checks only run in a release build —
cargo tauri devand the web app opened in a browser never check, and Settings explains updates are desktop-only there. - Footer button. When a newer version is published, the status footer shows
↑ X.Y.Zon the right. Clicking it opens Settings → General. - Settings → General → “Updates”. Shows the current version and, once a check has run, whether it’s up to date or a newer version is available. “Check now” checks on demand. “Download and install” downloads and installs the update, with a progress bar; “What’s new” links to the GitHub release page. A download or signature-verification failure leaves the running app untouched and shows the error inline — retry by clicking the button again.
- Restart behaviour. Installing an update replaces
Portuni.appon disk, but the running process keeps executing the old version until you click „Restartovat” (footer or Settings). „Restartovat” runs the same guards as ⌘Q — it warns about a dirty editor or unsynced files before proceeding — then stops all sidecars and relaunches the app, which now runs the new version. If you quit without restarting, the next launch runs the new version regardless. - Versions before 0.8.0 have no updater: download the DMG from GitHub releases and drag-replace
Portuni.appin/Applications/one last time to get onto 0.8.0 or later. From then on, updates happen in-app. Your settings, database (local SQLite or Turso), and mirror folders are unaffected either way.
Reporting a problem
Section titled “Reporting a problem”When something in the app breaks, two things help whoever looks at it: the log files and the trail of what you did right before.
- Logs. The app writes
~/Library/Logs/<bundle_id>/sidecar.log(five files of 10 MB are kept) and onesidecar-<workspace>.logper workspace next to it. When something fails in a window – an error on screen, a server error, a request that never got an answer – the window writes its recent steps intosidecar.logunder theuitarget. - Copy diagnostics (Settings → General → Reporting a problem) copies to the clipboard as plain text: the app version, the workspace kind (personal or team) and the workspace id, and the last 300 steps in the window: the views you opened (view, node id, settings tab), each API call with its method, its path without the query string, its status, how long it took, its request id and the error code, and every error the app reported. It holds no node titles, no message text and no request or response body.
- Request id. Every API call carries one id (
X-Portuni-Request-Id) from the window through the app to the server that answers it; the server echoes it and writes it into its error lines, and an “Internal server error” message shows it. The same id in the copied diagnostics, insidecar.logand in the server’s log ties one click to what happened on the server – on this Mac in a personal workspace, on the central server in a team workspace (including calls the sync agent makes there on the window’s behalf).
Nothing is sent anywhere: the trail lives in the window’s memory and in the log files on this Mac, and leaves it only when you paste it somewhere.
Connecting external MCP clients to the app’s sidecar
Section titled “Connecting external MCP clients to the app’s sidecar”The desktop app and an external MCP client (Claude Code, Codex CLI, Gemini CLI, Mistral Vibe) can share the same backend:
- The easiest way: use the one-click install buttons in Settings → MCP Server, which register each workspace’s URL and token for you.
- Wiring by hand instead? Point the external client at the workspace’s sidecar,
http://localhost:<port>/mcp(ports start at47011; shown in Settings), with the workspace’s token as a bearer header. - Reads and writes from the external client land in the same graph as the app — keep the app open or the sidecar will exit with it.
For the per-client configuration details see Claude Code, Codex CLI, Gemini CLI, Mistral Vibe.
When to use the CLI server instead
Section titled “When to use the CLI server instead”Stick with the standalone CLI server (covered in Setup) when:
- You’re contributing to Portuni — the CLI dev loop is faster than rebuilding the
.appon every change. - You’re on Linux or Windows. Native bundles for those platforms aren’t on the near roadmap.
- You’re deploying Portuni to a shared server, not a personal machine — see Team Setup.
Running multiple graphs side by side used to be a CLI-only affair; today it’s a desktop feature — create another workspace instead.
See also
Section titled “See also”- Setup — install paths and configuration
- MCP Clients overview — how each client treats your local files
- Local Mirrors — the per-device mirror model the app surfaces in the Workspace view
- Workspaces (Team & Personal) — the two kinds of workspace; Files: the two sync planes — what each can do with files