offline-cli 0.3.3

The Offline Protocol developer CLI
offline-cli-0.3.3 is not a library.
Visit the last successful build: offline-cli-0.0.0

Offline Protocol CLI (offline)

CI License Release

One CLI to build offline-first apps on the Offline Protocol ecosystem — and the MCP server that makes the whole ecosystem AI-native.

New here? → docs/QUICKSTART.md (install, first app, MCP with AI agents)

offline create --prompt "Durable equipment handoff between field engineers, with backend reconciliation" --name handoff --yes
offline create backend-delivery --name telemetry --yes   # retained events to a backend
offline create nearby-service --name status --yes        # discover and invoke a nearby service
offline login                                       # only for hosted services (Offline ID starters)
offline doctor                                      # validate your environment
offline mcp serve                                   # MCP server for AI agents (stdio)

What's inside

Crate Purpose
crates/offline-cli The offline binary: login, create, init, add, plan, doctor, update, registry, skills, mcp
crates/offline-registry Knowledge core: packages, skills, workflows, templates — embedded, fully offline
crates/offline-generator Tera-based project scaffolding (used by create and MCP scaffold_project)
crates/offline-mcp Model Context Protocol server: plan, scaffold, and integrate Offline Protocol components
crates/offline-registry/registry/ Content: packages, skills, workflows, starter templates

Workflows & templates

The three entrances for operational apps come first; the planner selects them from prompts about handoffs, retained events for a backend, or calling a service on a nearby device. Each starter ships the application logic the SDK leaves to you (durable records, stable IDs, explicit acceptance, retries, recovery) with tests, and the first two include a reference backend.

Workflow Templates
local-handoff (share a local workflow) react-native-mesh-handoff
backend-delivery (deliver retained events to a backend) react-native-mesh-event-delivery
nearby-service (discover and invoke a nearby service) react-native-mesh-service
custom-p2p-app react-native-mesh-custom-app
offline-social-network react-native-social, nextjs-social, react-vite-social
offline-id-mesh-chat react-native-social (+ mesh via enableMesh)
offline-id-mobile react-native-id-only
nearby-chat react-native-mesh-app
group-messaging react-native-mesh-app

Example app scaffolds

Full React Native sample apps from offline-app-examples (vendored packages/mesh, packages/ui, and native android/ios):

Template Demonstrates
orderup Host-authoritative kitchen POS: waiters send orders over Bluetooth mesh to a kitchen display
stocksync Shared inventory counter with host-authoritative sync and optimistic taps
cowrite Collaborative plain-text editing with MLS group sync and live cursors
offline create orderup --name my-kitchen --dir ./my-kitchen
offline create --template stocksync --name stock-demo -y
offline registry list templates   # includes exampleApp metadata

Regenerate embedded copies after changing the upstream examples:

node scripts/sync-example-app-templates.mjs

Install

The installed command is always offline.

npm (recommended):

npm install -g @offline-protocol/cli
offline --version

crates.io: not available yet. The offline-cli crate on crates.io is a placeholder until the first real publish; use npm or build from source.

From source (developers):

git clone https://github.com/Offline-Protocol/CLI.git
cd CLI
cargo install --path crates/offline-cli
offline --version

From GitHub Releases (archives + SHA256SUMS; members of the Offline-Protocol organization only, because the repository is internal):

  1. Download the archive for your platform from Offline-Protocol/CLI releases
  2. Verify with SHA256SUMS or the matching .sha256 file
  3. Extract and put offline on your PATH
  4. Run offline doctor and offline update

Maintainer release process: docs/RELEASING.md.

Homebrew distribution is still planned.

Command reference

Quick map of top-level commands. Full descriptions, flags, and examples: docs/COMMANDS.md.

Command Purpose
offline login / logout / whoami Interactive auth (localhost callback + poll); logout revokes the key server-side when possible
offline login --email The same login without a browser (SSH, agents). Both ways store the developer session that setup, orgs, apps and keys need; on SSH or a machine with no display, offline login prints the URL instead of opening a browser
offline login --email <address> --code <code> Finish the email sign-in without a prompt (agents, CI). Without a terminal, offline login --email <address> sends the code and exits
offline setup / orgs / apps / keys Provision and manage organizations, applications and API keys (need a developer session). setup reuses the API key this machine already made for the app
offline org use <org> / --org <id> Set the default organization (asked once at login if you belong to several), or override it for one command
offline apps status What the application has set up and what is missing for sign-in on iOS, Android, web and server, with the command that fixes each gap
offline apps native add/remove/list/detect/dev-builds Native apps for app attestation: iOS bundle ID + Team ID, Android package + signing-certificate SHA-256; detect reads them from app.json, Xcode, Gradle and assetlinks.json
offline apps native dev-mode on --hours N / off Development mode (1-72 hours, ends by itself): simulators, emulators and Expo Go sign in without attestation, email codes only
offline apps native production on/off, degraded allow/refuse, history Mark the app production (no development mode), the policy for Android phones that cannot fully attest, and the audit history
offline apps native setup-project [--write] Expo: add the App Attest entitlement to app.json and print the packages to install
offline apps origins add/remove/list Web origins allowed to sign in from a browser
offline apps features enable/disable/list Product features: telemetry, relay, proof-of-location
offline apply [--detect] [--dry-run] Converge the application to the app block of offline.config.json (native apps, origins, features); additive and idempotent
offline create Scaffold from workflow, template, or --prompt; runs npm install and starts the dev server (Metro for React Native) unless --skip-setup
offline plan Plan only (workflow + packages + optional architecture docs)
offline init Wire offline.config.json, .mcp.json, AGENTS.md into an existing app
offline add <package> Add package (+ transitive requires) to package.json
offline doctor Toolchain + auth + API reachability checks
offline update Check npm for a newer CLI and print the upgrade command
offline registry … List / search / show packages, workflows, skills, templates, capabilities; export llms.txt
offline skills list / show List or read an integration skill
offline mcp serve Run the MCP server (stdio)
offline mcp install <client> Print client config (cursor, claude-desktop, vscode, claude-code, codex)
offline mcp tools List MCP tools
offline completions <shell> Shell completions

offline login (browser) stores an application API key, which create and whoami --verify use. Local BLE mesh starters (nearby-chat, group-messaging, custom-p2p-app) scaffold without a login, as does the local MCP server. A template opts out of the login step with "requiresLogin": false in its template.json. setup, orgs, apps and keys call the developer management API and need the developer session that offline login stores; after offline login --api-key (CI) only, they stop with an error that says so. When the API key is shared with the application, offline logout clears this machine but leaves the key active; revoke it in the developer portal if you no longer need it.

Every informational command supports --json. Config: ~/.offline/config.json (0600). Overrides: OFFLINE_API_KEY, OFFLINE_API_BASE, OFFLINE_ENV (prod or dev/local), OFFLINE_PORTAL_BASE, OFFLINE_CONFIG_DIR, OFFLINE_REGISTRY_DIR, OFFLINE_CALLBACK_PORT (pin the localhost login callback port; default: an ephemeral port). The npm launcher forwards SIGINT, SIGTERM and SIGHUP to the native binary and exits with its status; OFFLINE_CLI_BINARY points the launcher at a locally built binary.

What the CLI stores and sends

Stored on your computer. offline login and offline login --email write ~/.offline/config.json (or $OFFLINE_CONFIG_DIR/config.json): the application API key, the developer session token from email sign-in, your email address, developer, organization and application IDs, and any API or portal base URL you set. The file is plain JSON, not encrypted and not in the system keychain. On macOS and Linux the CLI creates it owner read and write only (0600), replaces it atomically, keeps ~/.offline owner-only (0700) and refuses a symlinked file or a directory other users can write to; on Windows it keeps the default permissions of your user profile folder. Anyone who can read the file can use the key.

Removed by offline logout. It deletes the file. A key the CLI created for itself is also revoked on the server; a key shared with the application stays active until you revoke it in the developer portal. After email sign-in, logout clears the session token from this computer.

Sent to Offline Protocol. Sign-in requests (including this computer's hostname as the device name, shown when you approve the sign-in), and the calls each command makes to the developer API at api.offlineprotocol.com with your key or session. The hosted MCP server (mcp.offlineprotocol.com) receives the tool arguments your agent sends and returns results; it keeps rate-limit counters, keyed by a hash of the credential or by client address, in memory for about 90 seconds.

Sent elsewhere. offline update asks the public npm registry (registry.npmjs.org, or OFFLINE_NPM_REGISTRY) for the latest @offline-protocol/cli version, only when you run it. Scaffolding and the local MCP server's scaffold_project and integrate_packages tools run npm install and similar package-manager commands, which contact the package registries you have configured. The AI agent or client you connect to the MCP server receives tool inputs and results, and handles them under its own terms.

No telemetry. The CLI and the local MCP server send no usage analytics and no crash reports.

Local MCP tools act with your permissions. offline mcp serve can write files in your project and run package-manager commands, subject to your agent client's approval settings. It is not sandboxed. The hosted MCP server refuses those tools.

The privacy policy covers the same points for every Offline Protocol service. Report security issues to security@offlineprotocol.com (SECURITY.md).

For AI agents (MCP)

The MCP server is local stdio inside the CLI — no separate cloud deploy. Agents plan and integrate Offline Protocol components via tools (not from memory).

Set up Cursor / Claude

# Pick ONE client (do not use | — the shell treats it as a pipe):
offline mcp install cursor
offline mcp install claude-desktop
offline mcp install vscode
offline mcp install claude-code
offline mcp install codex

# Claude Code shortcut:
claude mcp add offline-protocol -- offline mcp serve

# Codex shortcut:
codex mcp add offline-protocol -- offline mcp serve

Paste the printed JSON into the client’s MCP config. Ensure offline is on PATH, then reload the agent / MCP session.

Ask the agent to create a project

Use Agent mode and a prompt like:

Using the offline-protocol MCP only (do not invent package names or SDK APIs):

1. Call generate_architecture with my idea.
2. Follow nextActions.
3. Call scaffold_project with name="festival-pulse" and platform="react-native".
4. Call get_skill for every skill listed before writing Offline Protocol code.

Idea: nearby festival chat with Offline ID login and BLE mesh messaging

Or use the MCP prompt plan-app with description, optional platform, and name.

Flow: generate_architecture → scaffold_project (new) or integrate_packages + init_project (existing) → get_skill → app code.

Full tool list and rules: docs/MCP.md.

Development

cargo build --workspace
cargo test --workspace
cargo clippy --workspace --all-targets -- -D warnings
cargo fmt --all -- --check

# live registry content (not the embedded copy):
OFFLINE_REGISTRY_DIR=./crates/offline-registry/registry cargo run -p offline-cli -- registry list

# local API gateway (typically :3010):
OFFLINE_ENV=dev offline login

CI & releases

Workflow Trigger What it does
.github/workflows/ci.yml PR + push to main fmt, clippy, tests; release-build smoke on main
.github/workflows/release.yml tag v* or manual bump Bumps version, updates CHANGELOG.md, builds binaries, publishes GitHub Release

Manual release: Actions → Release → bump patch/minor/major (needs RELEASE_PAT). Or push a tag: git tag v0.1.2 && git push origin v0.1.2 (add a CHANGELOG.md section for that version first if you skip the bump job).

Release notes on GitHub come from the matching ## [x.y.z] section in CHANGELOG.md, which git-cliff refreshes during the bump job (cliff.toml).

Documentation

Contributing

See CONTRIBUTING.md for setup, PR expectations, and registry guidelines. Please follow the Code of Conduct.

Security reports: SECURITY.md (do not file public issues for vulnerabilities).

License

Licensed under the Apache License, Version 2.0. See NOTICE for copyright attribution.

Terms and privacy

The CLI's source code is licensed under Apache-2.0 (above). Signing in with offline login, and using the Offline Protocol developer portal, the hosted MCP server at mcp.offlineprotocol.com, and hosted services, are governed by the Developer Terms of Service and the Acceptable Use Policy. The Privacy Policy explains what the CLI stores on your computer and what it sends to Offline Protocol. All legal documents: offlineprotocol.com/legal.

Status

Shipped: device-flow auth, deterministic planning, Tera scaffolds, MCP plan + scaffold + integrate, CI, multi-platform GitHub Releases, offline update.

Also shipped: hosted MCP (Streamable HTTP) at https://mcp.offlineprotocol.com/mcp (read-only tools; see docs/MCP-HOSTED.md).

Not yet: hosted registry refresh, Homebrew tap, official crates.io publish (install with npm until then).

Agent plugins and distribution

The agent plugin package provides a shared integration skill and local MCP configuration for Codex, Claude Code, Cursor and Gemini CLI. These packages are review candidates; public listings and client verification are tracked in the distribution plan.

Validate packaging with node scripts/check-agent-distribution.mjs; add --smoke to test the pinned published CLI over MCP. node scripts/check-guidance.mjs fails on SDK guidance that is known to be wrong (web appId on id-react, camelCase event fields, string priorities, Wi-Fi Direct enabled in a cross-platform starter or listed next to BLE as an equal transport, the removed telemetry sink, a Maven Central dependency line for the Android preview before 0.29.0 or for Java before 0.30.0, a pub.dev line, a "no package" claim or a refused Nostr config for the Flutter plugin, a Ruby gem line before 0.31.0 or a "not on RubyGems" claim, an npm line for the browser binding's unpublished JavaScript client, a NuGet line for the C# binding, a silent React Native fallback); CI runs it on every pull request. node scripts/scaffold-matrix.mjs generates every starter template variant with a locally built offline, installs the exact package versions the registry pins, and runs tsc --noEmit; the Scaffolds workflow runs it for every variant on pull requests that touch the registry, generator or CLI. OFFLINE_BIN=target/debug/offline node scripts/agent-readiness-e2e.mjs runs the MCP readiness scenarios against a local build instead of the published npm package.