Calíope app icon

How Calíope is built

The stack, the boundaries, and what was left out on purpose.

This page says how Calíope is put together: which frameworks it stands on, where the engine boundary sits, what the sandbox allows, and what the app deliberately does not do. Every figure comes from the source tree as of September 2026.

One app, three binaries

Calíope ships as a single app, org.caliope.caliope, with universal purchase: one purchase covers every Apple device it runs on. Behind that single app there are three binaries: one for macOS, one for iPhone and iPad (the same binary serves both, and the Apple Watch app travels embedded inside it), and one for Apple TV.

Most of the code is not written three times. Sources/Shared holds 268 Swift files and 234 SwiftUI views that compile into both the Mac binary and the iOS binary. The widgets are extensions of the same app and read what the app publishes through an App Group; the app writes, the widget only reads.

SwiftUI end to end

Every window is native SwiftUI — no web views, no cross-platform emulation. That sentence is on the home page and it is literally true: the 234 shared views are SwiftUI, and where a Mac and an iPad need different behaviour the difference is decided when the code is compiled, inside the same file, not by a compatibility layer at run time.

The engine boundary

Everything that speaks to a database engine lives behind 15 protocols in Sources/Models/Database/Protocols/, one per sub-area. Each engine has one implementation of those protocols, and nothing above the boundary — no view, no orchestrator — writes SQL or knows an engine’s error codes. Adding an engine means implementing the protocols, not editing the callers.

MySQL and MariaDB go through MySQLKit 4.10.1, and PostgreSQL through PostgresKit 2.16.1 on PostgresNIO 1.33.1, all of it on SwiftNIO 2.101.0 (versions as of September 2026). Queries with parameters use native MySQLNIO prepared-statement bindings: the values travel through the wire protocol and are never concatenated into the SQL.

SQLite is different: the SQLite editor talks to the system library through its C API, with no driver in between. MongoDB is different again. It is supported through MongoKitten 7.16.3, a community driver, and it sits outside the engine boundary on purpose: no view imports MongoKitten, and the whole MongoDB layer is designed so that it could be removed without touching the relational side.

SSH without ssh

The SSH tunnel is written inside the app, on SwiftNIO SSH 0.13.0 and swift-crypto 3.15.1. No dependency on system ssh. Decrypted keys never written to disk.

Calíope parses OpenSSH private keys itself, accepts ed25519 and ECDSA P-256, P-384 and P-521, verifies the host key before anything else is sent, and opens a direct-tcpip channel to the database. On your side it listens on 127.0.0.1, on a port chosen when the tunnel opens, and the database connection goes through that local proxy. A passphrase-protected key is decrypted in memory, and it stays there.

Inside the sandbox

Calíope runs with the App Sandbox on, as the Mac App Store requires, and Caliope.entitlements asks for exactly this:

  • com.apple.security.app-sandbox
  • com.apple.security.network.client — the outgoing connections to your servers
  • com.apple.security.network.server — the local listeners: the tunnel’s proxy and the MCP server
  • com.apple.security.device.audio-input — dictation, which runs on the device
  • com.apple.security.files.user-selected.read-write — the .sql files you open and the folders you choose for backups
  • com.apple.security.application-groups — the shared container the widgets read from
  • iCloud: CloudDocuments, CloudKit and the key-value store, for the sync you can opt into

And what is not there: no access to the whole file system, no library-validation opt-out, no JIT.

AI and MCP on your terms

The AI assistant has three kinds of provider. Apple Intelligence runs through Apple’s FoundationModels framework, on the device, with no key and no account. Ollama runs on your own machine, against the models you installed there. The cloud providers work with your own key. The app decides how to talk to a provider by the capabilities it declares, not by its name. It is an assistant, not an agent.

The MCP server, on macOS, turns that around and lets an external AI client — Cursor, Claude Desktop, anything that speaks MCP — ask Calíope about your databases, within boundaries. It is off by default. It listens on 127.0.0.1 only, on port 41500 unless you change it, and that address is not configurable. Every request needs a Bearer token that Calíope generates (32 random bytes) and keeps in the Keychain. The client sees only the connections you explicitly expose, and that list starts empty. It is read-only: one statement per call, checked by a gate that also rejects FOR UPDATE and LOCK IN SHARE MODE, and results are capped at 200 rows. Five tools, JSON-RPC 2.0 over a single POST /mcp route, protocol version 2025-06-18. Neither consent — the switch nor the exposed list — syncs to another device or travels in a settings backup. The MCP server page lists the five tools and explains how to point a client at it.

What it deliberately doesn’t do

  • No Windows, no Linux. Calíope is written for Apple platforms and stays there.
  • No SQL Server, no Oracle, no Redis. The engines are MySQL, MariaDB, PostgreSQL, SQLite and MongoDB.
  • No team workspaces. There is no server of ours and no accounts; your profiles and history are yours, and iCloud sync is an opt-in between your own devices.

If one of those is what you need, the comparison on the home page names the tools that do it well.