Skip to main content
This page documents MobKit v0.8.34 (mirrored from v0.8.34). The TypeScript SDK (@rkat/mobkit-sdk) provides type-safe access to the MobKit JSON-RPC gateway from Node.js.

Installation

The npm package is client-only and does not contain rpc_gateway. Download mobkit-rpc-gateway-<version>-<target>.tar.gz for Unix or macOS, or mobkit-rpc-gateway-<version>-<target>.zip for Windows, and extract its rpc_gateway binary (rpc_gateway.exe on Windows). Alternatively, follow the source-build instructions. Pass that binary’s path to .gateway(...).

Quick start

Durable detached tools

Long-running host work must declare detached execution rather than keeping a tool callback open:
The gateway durably accepts the job and returns a receipt; host work runs outside the agent turn. Start, reconcile, and cancel remain short callbacks inside the 120-second public contract (125-second host and 130-second wire margins). Reconnect offers the exact committed attempt, fence, lease, checkpoint, and runner handle. Reopening never mints a fence; only a machine-authorized claim or retry does. Credentials are resolved per attempt and never serialized into durable job state. For identity-first builds with a rosterProvider, .agentMemory() enables optional identity-scoped hot memory injection from <persistentState>/agent-memory with contextual recall by default. Options include realm, selection, maxEntries, recallTimeoutMs, recallFailurePolicy, and instructionHeader; automatic injection defaults to a 500 ms timeout and skips the memory block if recall fails. Write records with handle.rememberAgentMemory(identity, { title, body, tags, realm }), read them with handle.recallAgentMemory(identity, { realm, selection, queryText, queryTerms, maxEntries }), and delete them with handle.forgetAgentMemory(identity, memoryId, { realm }); new records are available on the next identity-first send and during later materialize/resume/respawn/reset flows. Forgetting a record removes it from future recall/injection, but does not erase text already delivered into an active model context.

Type definitions

The SDK exports camelCase result types. Its wire parsers translate snake_case gateway JSON into these shapes:
ModuleConfig is not a public TypeScript SDK export. Pass module declaration objects to .modules(...), whose public parameter type is unknown[]. An identity-first RosterProvider.roster(context) receives a typed RosterContext, a one-to-one mirror of the Rust struct the gateway sends under params.context:

Module support

The SDK supports both ESM and CommonJS:

Cross-module identity check

Because dual CJS+ESM packaging, vitest module isolation, and hoisted-vs-nested monorepos can ship two distinct RpcError constructors in the same process, prefer the structural type guards over instanceof:

Structural mob events + flow runs

Both APIs return the full meerkat ledger projection:

Mobpack authoring

MobHandle wraps the full Flow Editor authoring surface (mobkit/mobpacks/*) with typed methods: mobpackTemplates, mobpackCatalogs, mobpackValidate, mobpackSource, mobpackExport, mobpackImport, mobpackList, mobpackGet, mobpackCreate, mobpackSave, mobpackDelete, mobpackUndo, mobpackRedo, mobpackApplyOperation, mobpackDeployCommand, and mobpackDeploy.
mobpackDeploy(document, true) sends execute: true, which writes the archive and runs rkat mob run on the host — gated by the surface’s advertised authoring_capabilities and, on ABAC-enforced runtimes, the caller’s mobpack.deploy grant. See the Flow Editor guide.

Rust parity notes

The TypeScript SDK targets the JSON-RPC gateway. Rust also exposes lower-level native builder options for in-process embedding; those remain Rust-native and are not mirrored one-for-one in the gateway SDKs. External identity providers are all-or-nothing: configure continuityStore(), leaseProvider(), and scratchDir() together. The SDK sends the corresponding init flags to Rust, and provider callbacks use Rust’s wire shape (result tags and ttl). LeaseProvider.renewLeases(...) is atomic from the caller’s perspective: a rejected promise means no input grant was changed, while every returned renewed or lost result is already committed for that identity. Providers must not commit a replacement grant and then reject. Continuity stores should treat checkpoint_version as monotonic per identity and continuity generation. A live session rebind changes session_id without resetting the version; only destructive reset advances generation and starts the version stream over. Gateway memory config accepts { backend: "local_json" } with an optional healthCheckEndpoint (memory.localJson(...)); the legacy Elephant { backend, endpoint } shape still works but is deprecated. Store, collection, and space selectors are retained on the helper object for app code but are not sent to the Rust gateway. Gateway auth config supports JWT validation; Google/OIDC helpers are model objects, not accepted by mobkit/init today. The builder exposes no roleMigrations(...) setter and sends no role_migrations init param, so a TypeScript host cannot authorize a role-migrating resume: a durable member whose role changed keeps refusing to resume with MobError::MemberRoleMigrationRequired. Declaring the migration currently requires the Python builder’s .role_migrations([...]) or a hand-built mobkit/init payload; see the configuration reference. The builder forwards consoleConfig(path) as runtime_options.console_config_path, which lets the bundled console consume the same console_config contract projected by /console/experience. The console default is fail-closed: with neither auth(...) nor consoleAuthRequired(false) the gateway trusts no signing key and refuses every console request with 401 (it logs a startup warning naming this). consoleAuthRequired(false) is the explicit opt-out; use it only for a local or host-protected console. The Python twin is .console_auth_required(False). DurableAgentSpec carries the two per-identity knobs the Rust type deserializes: runtimeModeOverride ("autonomous_host" or "turn_driven"; null defers to the profile’s runtime_mode, whose meerkat default is autonomous_host) and initialMessage (the first turn a fresh autonomous_host member runs on: a string or DispatchContentBlock[], Rust ContentInput; null leaves meerkat’s fallback spawn prompt). Both are omitted from the roster payload when unset. durableAgentSpecToDict and parseDurableAgentSpec translate them (runtime_mode_override, initial_message). The Python twins are runtime_mode_override and initial_message on DurableAgentSpec. The gateway binds 127.0.0.1 on an ephemeral port by default. httpListen("0.0.0.0:8080"), allowRemote() and httpPublicBaseUrl(url) are the exposure knobs (runtime_options.http_listen, allow_remote, http_public_base_url): a non-loopback bind is refused at init unless auth(...) enforces console auth or allowRemote() acknowledges the exposure, and the advertised base is read back as runtime.rustHttpPublicBaseUrl while runtime.rustHttpBaseUrl stays the same-host form the SDK itself dials. See Deployment. meerkatConfig(path) forwards a Meerkat host config.toml as runtime_options.meerkat_config_path, the only door for the [self_hosted] and [realm] tables Meerkat keeps out of mob.toml (a host-config [models] table reaches the factory too, but a profile’s model must be catalogued, provider-annotated or defined under mob.toml’s own [models.<id>] to pass the init model check); a missing, malformed or non-validating file refuses init rather than building agents from the default config, and a top-level [self_hosted] or [realm] table inside mob.toml is refused at init with a message naming this option. The Python twin is .meerkat_config(path). See Self-hosted models and the Meerkat host config.

Storage durability declarations

The gateway is fail-closed about durable storage: a store that cannot open is a startup error, never a silent in-memory fallback. The runtimeStore and eventLog config modules produce the explicit declarations:
The resolved picture is the typed storage census: StatusResult.storage / CapabilitiesResult.storage parse the gateway’s storage object into StorageSummary (blob durability, the H2 incremental probe, and the per-slot StorageSlotSummary census with domain, durabilityClass, resolution, backend, degraded, detail); apply parseStorageSummary to the raw storage record of mobkit/storage/doctor. A fail-closed startup refusal — file-name twins, a store that failed to open — surfaces as the typed StorageResolutionError (code -32014, STORAGE_RESOLUTION_CODE), not a TransportError; its message names the remediation (mobkit/storage/doctor, or the explicit ephemeral declaration). Blob-store durability has no wire declaration today — it is declared by Rust embedders via ephemeral_blobs(true) / binary_blob_store(...) and reported read-only in the census.

Gateway logging (stderr)

The persistent gateway reports tracing lines, panic hooks, and storage migration progress on its stderr. By default the SDK inherits the host process’s stderr, so those lines are visible where your application logs. Two environment variables adjust this (same shape as the Python SDK): Discarding is the legacy pre-0.8.9 default and is not recommended: it hides panic output and makes a slow-but-working storage migration indistinguishable from a hang.

Error hook (onError)

category is one of the ErrorCategory constants (spawn_failure, reconcile_incomplete, checkpoint_failure, compaction_persistence_rejected, actor_loop_stalled, actor_loop_recovered, host_loop_crash, rediscover_failure, event_log_flush_failure, identity_materialization_failure, mob_stop_proceeded_without_interrupt), kept in lockstep with the Rust enum by tests/sdk_error_category_parity.rs; context carries the variant’s fields (member_id, error, and so on). The hook is fire-and-forget: a rejected promise is swallowed, and with no callback registered the notification is dropped. The gateway’s own stderr line for the same event (ERROR, or INFO for actor_loop_recovered) is written either way, so the hook adds alerting, not logging. Use isResolutionErrorEvent(event) to tell a failure ending (actor_loop_recovered) from one starting before paging on it. The Python twin is .on_error(callback).

HTTP transport timeout

createJsonRpcHttpTransport defaults to a 60-second timeout (via AbortController) so a server that accepts but never replies cannot hang the caller’s await forever. Override per-call:

Contract parity

The TypeScript SDK includes parity tests that validate type definitions against the Rust core. This ensures the SDK stays in sync with the runtime API across releases.

See also