contextvm-sdk 0.2.1

Rust SDK for the ContextVM protocol — MCP over Nostr
Documentation
# Python examples for the ContextVM FFI binding

These examples use the **UniFFI-generated** Python binding (`contextvm_ffi.py`)
plus the platform native library (`libcontextvm_ffi.so` / `.dylib` /
`contextvm_ffi.dll`). They are the Python equivalents of the Rust examples in
[`../`](../) (`discovery.rs`, `proxy.rs`).

## The one rule: `.py` and native lib must come from the same release

UniFFI embeds a **contract version** and a **per-function checksum** into both
the compiled native library and the generated `contextvm_ffi.py`. At import
time the binding recomputes them against the library and aborts with
`InternalError("UniFFI ... mismatch")` if they differ.

So you must take the native library and the Python binding from the **same
GitHub Release / same CI run**. Never mix an old `.py` with a new `.so`.

## Get the artifacts

### Option A — from a GitHub Release

Download **two** artifacts from the release page:

1. `contextvm-ffi-bindings.tar.gz` → contains `python/contextvm_ffi.py`
2. The native archive for **your platform**:
   - Linux x86_64 → `contextvm-ffi-x86_64-unknown-linux-gnu.tar.gz`
     (`contextvm-ffi/lib/libcontextvm_ffi.so`)
   - macOS Apple Silicon → `contextvm-ffi-aarch64-apple-darwin.tar.gz`
     (`contextvm-ffi/lib/libcontextvm_ffi.dylib`)
   - macOS universal → `contextvm-ffi-universal-apple-darwin.tar.gz`
   - Windows x86_64 → `contextvm-ffi-x86_64-pc-windows-msvc.zip`
     (`contextvm-ffi/lib/contextvm_ffi.dll`)

### Option B — build locally

```bash
# from the repo root
cargo build -p contextvm-ffi                      # -> target/debug/libcontextvm_ffi.so
cargo install --git https://github.com/mozilla/uniffi-rs \
    --tag v0.31.2 uniffi-bindgen-cli --locked      # bindgen matching the runtime `uniffi` version
uniffi-bindgen-cli generate target/debug/libcontextvm_ffi.so \
    --library --language python --out-dir examples/python/
```

## Lay them out side by side

The generated `contextvm_ffi.py` looks for the native library **next to itself**
(`os.path.dirname(__file__)` + `libcontextvm_ffi.so`/`.dylib`/`.dll`). Put the
two files in this directory:

```bash
# from examples/python/
cp /path/to/contextvm-ffi/lib/libcontextvm_ffi.so .
# (place contextvm_ffi.py here too, from either Option A or B)
```

The `.gitignore` in this directory keeps both of these out of version control —
they are build/release artifacts, not source.

## Run the examples

```bash
cd examples/python

# 1. Offline sanity check (no network). Run this first to confirm the install.
python3 01_offline_check.py

# 2. Discover announced servers + their tools (needs internet).
python3 discover_servers.py
python3 discover_servers.py wss://relay.damus.io wss://nos.lol

# 3. Talk to a specific server (needs internet + a known server pubkey).
python3 proxy_tools_list.py <server_pubkey_hex>
```

## API surface

The binding exposes these top-level helpers and objects:

| Category | Names |
|----------|-------|
| Functions | `version()`, `pubkey_hex_to_npub(hex)`, `make_request(id, method, params)`, `make_response(id, result)`, `make_notification(method, params)` |
| Objects | `Keys`, `RelayPool`, `Discovery`, `Server`, `Client`, `Gateway`, `Proxy` |
| Configs | `ServerConfig(...)`, `ClientConfig(...)` (keyword-only fields) |
| Enums | `EncryptionMode.{OPTIONAL,REQUIRED,DISABLED}`, `GiftWrapMode.{OPTIONAL,EPHEMERAL,PERSISTENT}` |
| Records | `JsonRpcMessage`, `IncomingRequest`, `ServerAnnouncement`, `DiscoveredTool`, `ProviderProfile`, `PeerCapabilities` |

All async SDK work runs on an internal Tokio runtime, so every method here is
**blocking** — no `async`/`await` needed on the Python side.

See `contextvm-ffi/README.md` and `contextvm-ffi/src/uniffi_types.rs` for the
full, authoritative API.