iOS & iPadOS App
Overview
Section titled “Overview”mycellm turns your iPhone or iPad into a node on the distributed inference network — serve inference, earn credits, and chat with on-device privacy protection. An M-series iPad Pro is a desktop-lite powerhouse: it runs 3B+ models at 30+ tokens/sec on Metal, serving the swarm rather than just using it. On iPhone, run smaller models locally — or route from your phone to a trusted device on your own network (your Mac mini, MacBook Air, or Studio) for far bigger models, no cloud involved.
Download: App Store · Source: github.com/mycellm/mycellm-ios (Apache 2.0)
Requires iOS / iPadOS 17.0+ on iPhone or iPad. M-series recommended for on-device inference.
Build from source
Section titled “Build from source”The app is open source (Apache 2.0). The simplest way to get it is the App Store; to build it yourself:
# Clone and generate Xcode projectgit clone https://github.com/mycellm/mycellm-ioscd mycellm-iosxcodegen generateopen Mycellm.xcodeprojSet your DEVELOPMENT_TEAM in project.yml, then build and run (⌘R).
First launch
Section titled “First launch”- Splash screen with spore particle animation
- The app generates your device identity (Ed25519 keypair, stored in Keychain)
- Auto-connects to the public mycellm network via
bootstrap.mycellm.dev - Auto-loads the last model you used (if any)
No account creation or sign-up required. Your identity is your cryptographic key.
Download a model
Section titled “Download a model”Open the Models tab. Suggested starters:
| Model | Size | Good for |
|---|---|---|
| Llama 3.2 1B Q4 | 0.8 GB | Fast responses, limited device |
| Llama 3.2 3B Q4 | 1.9 GB | Balanced quality/speed |
| Phi-3 Mini Q4 | 2.3 GB | Reasoning tasks |
| Gemma 2 2B Q4 | 1.5 GB | General purpose |
Tap a model to download from HuggingFace. Models persist across app launches but are removed if you delete the app.
Two inference modes, selectable at the top of the chat screen:
Network mode
Section titled “Network mode”Prompts route through the public gateway to any available node on the network. Uses credits. Best for larger models you don’t have locally. Responses include node attribution (which peer served the request).
On-Device mode
Section titled “On-Device mode”Runs inference locally using llama.cpp on Metal. No network required. Works in airplane mode. Conversation context is managed automatically — older messages are compacted into summaries when the context window fills.
Switch between modes mid-conversation. Each message bubble shows a colored border indicating which route was used (blue = network, green = on-device).
Chat features
Section titled “Chat features”- Persistent threads — conversations are saved with full metadata (model, node, tokens/sec, route, duration)
- Thread management — switch between threads, delete threads or individual messages
- Export/share — share any thread via the system share sheet (Notes, Mail, Messages, etc.)
- Private sessions — ephemeral mode that doesn’t save to disk (eye-slash icon in thread list)
- Copy messages — long-press any message for copy/delete options
- Timestamps — visible on every message
- Date dividers — visual grouping between different days
- AI disclaimer — dismissable reminder above the input field
Sensitive Data Guard
Section titled “Sensitive Data Guard”The privacy guard scans every outgoing prompt for API keys, passwords, credit card numbers, and PII patterns. When a match is detected:
- High severity (API keys, passwords) — automatically redirects to your local model
- Medium severity (email addresses, phone numbers) — warns with option to send anyway
This runs on-device before any data leaves your device.
Settings
Section titled “Settings”| Setting | Description |
|---|---|
| Remote Endpoint | Point to a private bootstrap, OpenRouter, ollama, etc. |
| Privacy Guard | Toggle scanning, view built-in rules |
| Screensaver | Ambient spore animation, prevents OLED burn-in |
| Tip Jar | Support development (StoreKit 2 IAP) |
| Network | View joined networks, manage membership |
Serve inference
Section titled “Serve inference”Your device contributes compute to the network and earns credits automatically when a model is loaded and the node is running. The bootstrap relays inference requests to your device via QUIC.
Tip: iPad with M-series chips can serve 3B models at 30+ tokens/sec — competitive with many cloud instances.
Your device also runs a local HTTP server that exposes an OpenAI-compatible API on your LAN. Other tools on your network can use your iPad as an inference backend.
The node API on iOS
Section titled “The node API on iOS”As of app 1.2.0, an iOS node answers the same paths as the Python node, with
the same payload shapes — so the dashboard, mycellm CLI and any fleet tooling
manage an iPad exactly as they manage a Linux box. Everything under
/v1/node/** requires the node API key (set it in Settings → API);
/health, /metrics and the inference paths are open.
Inference — /v1/chat/completions (streaming, tools, vision),
/v1/embeddings, /v1/models, /v1/models/{id}, /v1/models/capabilities.
Status & observability — /v1/node/status, /system, /version, /peers,
/connections, /activity (+ /activity/stream SSE), /logs
(+ /logs/stream SSE), and Prometheus /metrics.
Model management — /v1/node/models/ local, saved, suggested,
search, search/{repo}/files, {name}/config, download, downloads,
downloads/abort, load, unload, reload, update, scope,
load-status, load-status/clear, remove-config, delete-file.
Credits & relays — /v1/node/credits (+ /tier, /history, /networks),
/v1/node/relay (+ /add, /remove, /refresh).
App 1.2.0 reports core parity 0.7.1 — /health, /v1/node/status and the
peer capability advertisement all carry that version, and it is the number fleet
tooling should compare against. It moves independently of the App Store version
above: a security fix shipped on both platforms bumps it even when no wire
format changed, so a patched build and an unpatched one never report the same
number.
The next release (1.3.0, core parity 0.8.0) adds the additive half of the
execution fabric: embedding models declare
execution_roles: ["embed"] so a planner stops routing chat to them instead of
learning by refusal, and the device conditions below travel with the capability
advertisement rather than being visible only on /v1/node/status. Every field
is omitted when unset, so a 0.7.x or 0.6.3 peer sees a byte-identical payload.
Installing models from a URL
Section titled “Installing models from a URL”POST /v1/node/models/download takes the same three forms as the Python node —
a Hugging Face repo_id/filename pair, a single url + sha256, or a files
manifest for an MLX directory. See the
Models API for the request shapes and
the verification rules, which are identical on both platforms.
Device telemetry
Section titled “Device telemetry”A phone knows things a Linux box doesn’t, and a scheduler that routes on
hardware specs alone will send work to a device that is throttling or nearly
flat. /v1/node/status carries a device block:
thermal—state,throttled,unloadingpower—battery_percent,charging,low_power_modenetwork—interface,expensive,constrained,downloads_allowed_on_meteredruntime—app_state,foreground,serving_requires_foreground
expensive (costs money) and constrained (Low Data Mode) are reported
separately rather than OR’d into one flag, because the right response differs.
/v1/node/system adds storage.models_free_bytes, so a caller planning a
download gets an honest figure before starting one.
The node demotes itself. A device that is thermally critical, in Low Power
Mode, or under 20% on battery advertises role: consumer instead of seeder —
in /v1/node/status and in what peers see. It needs no agreement from any
scheduler to protect itself.
Downloads on cellular
Section titled “Downloads on cellular”Off by default. A download requested on cellular or in Low Data Mode is refused
with 409 expensive_network, reporting network and estimated_bytes so
the caller can decide with the real size in hand:
{"error": {"code": "expensive_network", "network": "cellular", "estimated_bytes": 4128309248, "message": "…"}}Send "allow_expensive": true to override per request, or grant standing
permission in Settings → Downloads → Allow on Cellular. The policy is
enforced per request rather than per session, and there is no confirmation
dialog, because the caller is a dashboard or a script with nobody at the device
to tap anything.
Embeddings
Section titled “Embeddings”POST /v1/embeddings is served with the same request validation and OpenAI
error envelope as the Python node. On-device embedding execution is disabled
in app 1.2.0: the endpoint answers 400 with code embeddings_not_supported,
which is what the Python node returns for a backend that cannot embed, and
supports_embeddings on /v1/models/capabilities reports false. Check that
field before sending, and route embeddings to a Python node meanwhile.
The backend path is written but produced numerically incorrect vectors in testing, so it is gated off rather than shipped — see the app CHANGELOG for the detail.
Not served on iOS
Section titled “Not served on iOS”Some Python routes are deliberately absent, because they are coordinator or credential surfaces that don’t belong on a device:
| Surface | Why not |
|---|---|
/v1/admin/** | Fleet approval and the node registry are a coordinator’s job |
/v1/public/** | The credit-tracker gateway runs on a bootstrap, not a leaf |
/v1/node/federation/** | Joining and inviting is driven from the app UI |
/v1/node/settings/** | Credentials live in the Keychain, not behind an HTTP write |
/v1/node/proxy | There is no hosted dashboard on a device to proxy for |
/api/** (Ollama compat) | Not implemented |
Fleet commands over the network protocol (node.status, node.config,
model.list / load / unload / scope) are fully supported; train.status
is not, since iOS nodes don’t train.
Fork-friendly
Section titled “Fork-friendly”All network endpoints are centralized in Mycellm/Core/NetworkConfig.swift. To run your own network, edit one file:
enum NetworkConfig { static let bootstrapHost = "bootstrap.yournetwork.dev" static let apiBase = "https://api.yournetwork.dev" // ...}Known limitations
Section titled “Known limitations”- Foreground only — iOS suspends network activity after ~30 seconds in the background. The app must stay in the foreground to serve inference.
- No DHT — queries the bootstrap as a gateway (battery/NAT constraints on mobile).
- Memory pressure — models >3B may be evicted on <8 GB RAM devices. The app recovers gracefully.
- No background downloads — model downloads pause if backgrounded.