Skip to content
ONTO
Getting started

From install to an approved plan in five minutes.

No account, no API-key relationship to set up. ONTO defaults to a free open-weight model, so the fastest path to a running agent is a single install and one env var.

The four steps

  1. 1

    Install the SDK

    Install onto-core with pip (Python), @onto/core with npm (TypeScript), or onto-runtime with cargo (Rust). All three bind to the same Rust core.

  2. 2

    Point at a model

    ONTO defaults to a free open-weight model on Ollama Cloud. Export OLLAMA_API_KEY to use it, or set ANTHROPIC_API_KEY / OPENAI_API_KEY to swap providers with no code change.

  3. 3

    Run with consent scopes

    Call run_sync with the consent scopes you want to grant and extract=True to capture typed facts. The agent proposes; nothing side-effectful runs without the scope.

  4. 4

    Review the plan, then approve

    Run again in plan_only mode to get a reviewable task list. Approve it, then run once more with execute scopes to do the work and commit facts to UPO.

Install

Get started in 60 seconds.

No account needed. ONTO defaults to free open-weight models on Ollama Cloud, so you can run your first agent with a single pip install and an env var.

  • No API key relationship needed to start — defaults to free open-weight models.
  • Same primitives in Python, TypeScript, Rust, and over HTTP.
  • On-prem path uses Sled or Postgres + pgvector. No data has to leave your network.
pip install onto-core

Then export OLLAMA_API_KEY to use the free open-weight default. Or set ANTHROPIC_API_KEY / OPENAI_API_KEY to swap providers.

Step 3 · Run

Run an agent — the agent proposes, you granted one scope.

The run below is allowed to write memory and nothing else. It extracts typed facts and routes each to the right level. No web fetch, no side effect — you did not grant those scopes.

quickstart_run.py
from onto import Onto, Models, BuiltinTools

onto = Onto(
    model=Models.GPT_OSS_20B,      # free open-weight default
    builtin_tools=BuiltinTools.STANDARD,
)

# The agent reads state and PROPOSES. extract=True captures typed facts.
result = onto.run_sync(
    "Hi, I'm Alice. UTC, mornings. Plan a 3-day trip to Lyon.",
    user_id="alice",
    consent_scopes=["memory:write"],   # nothing else is permitted
    extract=True,
)

for ea in result.extracted_assertions:
    print(f"{ea.level:8} {ea.subject}.{ea.predicate} = {ea.object!r}")
# profile   alice.timezone = "UTC"
# profile   alice.prefers  = "mornings"
# session   alice.location = "Lyon"
Step 4 · Plan & approve

Halt before execution. Approve. Then run.

Plan Mode is a runtime invariant. The first run proposes a task list and stops. The human reviews it and grants execute scopes for a second run — the model never approves its own work.

plan_then_execute.py
# 1. Plan only — the agent proposes tasks; no tool fires, no write happens.
plan = onto.run_sync(
    "Plan the trip.",
    user_id="alice",
    mode="plan_only",
)

for task in plan.tasks:
    print(task.summary)     # human reads the proposed steps

# 2. Human approves and grants EXECUTE scopes for a second run.
if approve(plan):          # your own review gate
    onto.run_sync(
        "Run the approved plan.",
        user_id="alice",
        consent_scopes=["tools:web.fetch", "memory:write"],
    )

Same agent, in TypeScript

The Node binding is built with napi-rs on the same Rust core, so semantics are identical.

quickstart.ts
import { Onto, Models, BuiltinTools } from "@onto/core";

const onto = new Onto({
  model: Models.GPT_OSS_20B,
  builtinTools: BuiltinTools.STANDARD,
});

const result = await onto.run(
  "I'm Alice. UTC, mornings. Plan a trip to Lyon.",
  { userId: "alice", consentScopes: ["memory:write"], extract: true },
);

for (const ea of result.extractedAssertions) {
  console.log(ea.level, ea.subject, ea.predicate, ea.object);
}
Open source

Star the repo and build in the open.

ONTO is MIT or Apache-2.0. Pre-1.0, with 238 tests across the Rust core and the Python and TypeScript SDKs.