> ## Documentation Index
> Fetch the complete documentation index at: https://www.offlineprotocol.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> These docs target Mesh SDK v0.30.0. Match the installed package and binding before generating code. Start at /getting-started/agents for task-specific reading paths. Apps that call enableTelemetry on 0.26.0 to 0.29.0 should update to 0.30.0: the telemetry uploader now trusts only the telemetry endpoint's issuing roots.
> Call the company and product Offline Protocol, never Offline alone. Current packages: @offline-protocol/mesh-sdk 0.30.0 (React Native), offline-protocol-sdk 0.30.0 on PyPI (Python 3.10 to 3.13; wheels for macOS 14+ arm64, Linux x86_64 and aarch64 with glibc 2.34+, Windows x86_64; other hosts build from source; extras lan and http add LAN discovery, the HTTP front and offline-protocol-verify), the offline-protocol crates 0.30.0 on crates.io, the OfflineProtocolSDK Swift package 0.30.0 (preview, iOS 13+ only), the Android library com.offlineprotocol:offline-protocol-sdk 0.30.0 on Maven Central (preview, minSdk 24), the Java binding com.offlineprotocol:offline-protocol-java 0.30.0 on Maven Central (JDK 22+, native library from the GitHub release's desktop archives), the C header offline_protocol.h with the native library in the GitHub release's desktop archives, the offline_protocol Flutter plugin (preview, not on pub.dev; a path dependency on the SDK repository at tag v0.30.0), @offline-protocol/id-react 0.2.0, @offline-protocol/id-react-native 0.3.3, @offline-protocol/pol 0.1.2 and @offline-protocol/cli 0.2.8. Canonical docs URLs start with https://www.offlineprotocol.com/docs.
> The Mesh SDK runs in a native app or gateway. A browser OfflineID SDK integration does not provide browser mesh transport. Local mesh operation does not require a portal account or API key. The Mesh SDK appId is a mesh app identifier the developer chooses, not the portal App ID (app_...) that OfflineID and Proof of Location require.
> In v0.30.0 service RPC bodies are sealed in the 1:1 MLS session once the recipient runs 0.29 or later and the session is confirmed; discovery, the first request to a provider never met, and requests to older peers are signed plaintext, so keep secrets out of service bodies unless the event says encrypted: true. The HTTP front (offline-protocol-service --http) always carries calls inside encrypted direct messages but does not authorize callers. Message delivery, durable local acceptance and backend commit are distinct outcomes. Use the workflow guide for the required application logic.
> Offline Protocol CLI 0.2.8 is on npm (@offline-protocol/cli, command offline). Its local MCP server, named offline-protocol, runs with npx -y @offline-protocol/cli@0.2.8 mcp serve and requires no login or key. Hosted MCP is at https://mcp.offlineprotocol.com/mcp with an app API key in Authorization: Bearer and the matching App ID in x-app-id; organization keys are rejected, and Claude Desktop and Claude.ai cannot send these headers; there, use the public read-only endpoint https://mcp.offlineprotocol.com/public/mcp as a custom connector, or local MCP to scaffold or edit projects. Follow /tools/overview for setup and do not invent commands beyond it. MCP provides integration context and planning, not mesh execution; file-writing tools are local only.
> In v0.30.0 phone Wi-Fi peer streams carry data: Android over Wi-Fi Direct (the SDK forms the group with autoAccept on Android 10+) and over the Wi-Fi network it is on (DNS-SD), iOS over Network framework (LAN or AWDL). Android and iOS meet over that slot only on a shared Wi-Fi network that allows multicast; iOS 0.28 and later does not see iOS 0.27 or earlier over it. Otherwise use BLE or a provisioned relay across platforms. The Swift and Android packages are previews whose public names may change; the Android library is on Maven Central from 0.29.0 only, so never give a Gradle line for an earlier version. The receiver core ACKs before application persistence; use application acceptance for durable workflows.
> Proof of Location is Sepolia testnet witness evidence, not zero-knowledge proof or proof of presence. The geohash is public onchain. Read /proof-of-location/security before integration.

# Java binding

> Use the Mesh SDK v0.30.0 from Java 22 or later on desktop and server: the typed binding on Maven Central over the native library from the release.

From v0.30.0 the SDK has a typed Java API for the JVM on desktop and server. It is generated from the same interface definition as the Swift, Kotlin and Python bindings and calls the native library through the Java foreign function API, so it needs no JNA, no JNI and no native glue of its own.

On Android, use the [Android library](https://www.offlineprotocol.com/docs/mesh-sdk/native.md#android-bindings) instead. This binding is for any other JVM.

## Install

The jar is on Maven Central as `com.offlineprotocol:offline-protocol-java`:

```kotlin theme={null}
// build.gradle.kts
repositories {
    mavenCentral()
}

dependencies {
    implementation("com.offlineprotocol:offline-protocol-java:0.30.0")
}
```

The jar holds the generated Java and no native code. Download the native library for your platform from the [v0.30.0 GitHub release](https://github.com/Offline-Protocol/offline-protocol-sdk/releases/tag/v0.30.0):

| Platform | Archive | Library |
| - | - | - |
| Linux x86\_64 | `offline-protocol-0.30.0-linux-x86_64.tar.gz` | `liboffline_protocol_uniffi.so` |
| Linux aarch64 | `offline-protocol-0.30.0-linux-aarch64.tar.gz` | `liboffline_protocol_uniffi.so` |
| macOS arm64 | `offline-protocol-0.30.0-macos-arm64.tar.gz` | `liboffline_protocol_uniffi.dylib` |
| Windows x86\_64 | `offline-protocol-0.30.0-windows-x86_64.zip` | `offline_protocol_uniffi.dll` |

Use a jar and a native library from the same release. Run on JDK 22 or later, allow native access, and point the JVM at the library:

```bash theme={null}
java --enable-native-access=ALL-UNNAMED \
     -Djava.library.path=/path/to/library/directory \
     -jar app.jar
```

To name the file by absolute path instead, pass `-Duniffi.component.offline_protocol.libraryOverride=/path/to/liboffline_protocol_uniffi.dylib`. Without `--enable-native-access` the JVM warns on the first native call, and a future JDK refuses it.

## Quick start

```java theme={null}
import com.offlineprotocol.sdk.*;

// The generated record has no defaults: every field is spelled out, in the
// order of the definition (ProtocolConfig in offline_protocol.udl). Optional
// fields (mesh relay, custody) take null.
ProtocolConfig config = new ProtocolConfig(
    "com.example.app", "default",
    false, false, true, false, false, false, // ble, wifi direct, internet, reticulum, nostr, prefer online
    (byte) 8, true, true, true, true,        // ttl, encryption, auto key exchange, store pending, require encryption
    64L, 4096L, 60_000L, OverflowPolicy.DROP_OLDEST,
    false, 256, true, true, false, false,
    true, true, true, false, true, true, true,
    null, null,
    true, true, true);

try (OfflineProtocol engine = new OfflineProtocol(config)) {
    // Storage before start(). The store key seals key material at rest;
    // keep it out of the source.
    engine.initializeMlsWithFileStores("/var/lib/app/mls", "/var/lib/app/state", storeKey32Bytes);

    engine.setEventCallback(json -> queue.add(json)); // copy and return; never call the engine from here
    engine.start();
    System.out.println("this device is " + engine.localAddress());

    try {
        engine.sendMessage("off1...", "hi", MessagePriority.MEDIUM, null);
    } catch (ProtocolException.EncryptFailed e) {
        // each engine refusal is its own exception type
    }
    engine.stop();
}
```

The package is `com.offlineprotocol.sdk`. `OfflineProtocol` is the engine, and `MeshServices` and `DataStore` hang off it. Every record and enum of the definition is a class. An engine refusal is a subclass of `ProtocolException` named for the variant; see [error codes](https://www.offlineprotocol.com/docs/mesh-sdk/errors.md). `OfflineProtocolLib` holds the functions that need no engine, such as `deriveAddress`, `parseInvite` and `runStorageConformance`.

Java has no default arguments, so `new ProtocolConfig(...)` takes every field in order. When a release changes a default in the interface definition, your Java code keeps passing the old value until you change it. The binding's `ConsumerCheckTest.config()` carries the definition's defaults field for field.

## Events

`setEventCallback` installs an `EventCallback`, or `pollEvent` takes the oldest queued event. Every event is queued either way. An event is the engine's JSON text, so parse it with the library you already use; the payloads are the ones in the [event reference](https://www.offlineprotocol.com/docs/mesh-sdk/events.md).

The callback runs on whichever thread is inside the engine, before the engine call that produced it returns. It must be safe from any thread, must not call back into the engine (closing the engine included) and must not throw.

## What your host provides

Your process is the platform, so it owns the radios and sockets:

* **Transports.** Implement `BleTransportCallback`, `WifiDirectTransportCallback`, `ReticulumTransportCallback` and `NostrTransportCallback` to learn when a queue has frames, and drain them with the `ble*`, `wifiDirect*`, `internet*`, `reticulum*` and `nostr*` methods.
* **Storage.** Implement `MlsStorageProvider` (key material, backed by a keystore) and `ProtocolStateStorageProvider` and pass both to `initializeMls`, or use the built-in file stores as above. Prove an adapter with `OfflineProtocolLib.runStorageConformance`.
* **Telemetry platform.** If you enable telemetry, pass `TelemetryConfig.os` and `osMajor` as the platform the process actually runs on (`TelemetryOs.LINUX`, `MACOS` or `WINDOWS`), read from the JVM's `os.name` and `os.version`. No layer in this binding fills them.
* **Lifecycle.** `start`, `stop` and `process` on a timer. `try-with-resources` frees the engine once; it does not wait for calls in flight on other threads.

## Reference

* [Java binding README](https://github.com/Offline-Protocol/offline-protocol-sdk/blob/v0.30.0/bindings/java/README.md): building and testing the binding from source.
* [Java binding contract](https://github.com/Offline-Protocol/offline-protocol-sdk/blob/v0.30.0/docs/bridges/java.md): defaults, telemetry, threading and what the JVM requires.

The SDK is AGPL-3.0-only with a commercial license available; see [licensing](https://www.offlineprotocol.com/docs/operations/licensing.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.