Skip to main content
libmoss is the native C library at the core of Moss. It exposes the same API surface as the Python moss-session and Elixir moss_session packages through a plain C ABI, so you can embed real-time semantic search directly into C, C++, or any language with a C FFI. It provides two handles:
  • MossClient - the entry point. Construct it with your credentials, manage cloud indexes, load an index for querying, and open sessions.
  • MossSession - a local index. Add and query documents on the same machine with no per-query network calls, then push to the cloud or pull an existing cloud index in.

Install

libmoss ships as prebuilt binary release tarballs on GitHub, one per target triple. Download the tarball for your platform from the releases page and extract it:
VERSION=0.17.0

# Pick the tarball for your platform:
#   libmoss-v0.17.0-aarch64-apple-darwin.tar.gz      (macOS, Apple Silicon)
#   libmoss-v0.17.0-x86_64-apple-darwin.tar.gz       (macOS, Intel)
#   libmoss-v0.17.0-x86_64-unknown-linux-gnu.tar.gz  (Linux, x86_64)
#   libmoss-v0.17.0-aarch64-unknown-linux-gnu.tar.gz (Linux, arm64)

TARGET=aarch64-apple-darwin
curl -L -o libmoss.tar.gz \
  "https://github.com/usemoss/moss/releases/download/libmoss-v${VERSION}/libmoss-v${VERSION}-${TARGET}.tar.gz"
mkdir -p libmoss && tar -xzf libmoss.tar.gz -C libmoss
Each tarball contains:
  • libmoss.dylib (macOS) / libmoss.so (Linux) - the shared library
  • libmoss.a - the static library
  • libmoss.h - the C header
libmoss is distributed only as GitHub binary releases. It is not published to crates.io.
Point your compiler at the extracted libmoss directory for both the header (-I) and the libraries (-L).
clang your_app.c -o your_app \
  -I/path/to/libmoss -L/path/to/libmoss -lmoss \
  -framework Security -framework SystemConfiguration
At runtime the dynamic loader needs to find the shared library:
export DYLD_LIBRARY_PATH=/path/to/libmoss
./your_app

Static linking

To produce a self-contained binary, replace -lmoss with the full path to libmoss.a and add the platform libraries. No DYLD_LIBRARY_PATH / LD_LIBRARY_PATH is needed at runtime.
clang your_app.c -o your_app \
  -I/path/to/libmoss /path/to/libmoss/libmoss.a \
  -framework Security -framework SystemConfiguration -lresolv

Quick start

Open a session, add documents (embedded locally with the built-in model), query, and push the index to the cloud:
#include "libmoss.h"
#include <stdio.h>

int main(void) {
    MossClient *client = NULL;
    moss_client_new("your-project-id", "your-project-key", &client);

    // Open a session (auto-embeds with the built-in model).
    MossSession *session = NULL;
    moss_client_session(client, "my-index", NULL, &session);

    // Add documents. Metadata is optional; pass NULL / 0 to skip it.
    MossDocumentInfo docs[] = {
        { .id = "1", .text = "Billing refund request" },
        { .id = "2", .text = "How to grow tomatoes" },
    };
    size_t added = 0, updated = 0;
    moss_session_add_docs(session, docs, 2, NULL, &added, &updated);

    // Query locally - no network round trip.
    MossSearchResult *result = NULL;
    moss_session_query(session, "refund", NULL, &result);
    for (size_t i = 0; i < result->doc_count; i++) {
        printf("%s  score=%.4f\n", result->docs[i].id, result->docs[i].score);
    }
    moss_free_search_result(result);

    // Push to the cloud so other devices can load it.
    MossPushIndexResult *push = NULL;
    moss_session_push_index(session, &push);
    moss_free_push_index_result(push);

    moss_session_free(session);
    moss_client_free(client);
    return 0;
}
To query a cloud index from a MossClient instead, load it into memory first with moss_client_load_index and then call moss_client_query. A MossClient query always runs against a loaded index, so the load step is required.
MossIndexInfo *loaded = NULL;
moss_client_load_index(client, "my-index", NULL, &loaded);  // load first
moss_free_index_info(loaded);

MossSearchResult *result = NULL;
moss_client_query(client, "my-index", "refund", NULL, &result);  // then query
moss_free_search_result(result);
Every fallible call returns a MossResult code. The quick start omits the checks for brevity; production code should inspect the return value and call moss_last_error() on failure. See the examples for the full pattern.

Embedding models

Pass the model via MossSessionOptions.model_id when opening a session. The default (NULL) uses the built-in model and embeds documents and queries locally.
ModelBehavior
moss-minilm (default)Auto-embeds documents and queries locally.
moss-mediumlmHigher quality, slightly slower.
customYou supply embeddings via MossDocumentInfo.embedding and MossQueryOptions.embedding.
MossSessionOptions opts = { .model_id = "moss-mediumlm" };
MossSession *session = NULL;
moss_client_session(client, "my-index", &opts, &session);

Next steps

  • API reference - every MossClient and MossSession function, memory-management rules, error handling, and the metadata-filter format.
  • Examples - runnable session, cloud CRUD, and metadata-filtering programs.