Skip to main content

Headless Python SDK + CLI for the Nexus skill platform (bundles nexus_core)

Project description

Nexus SDK

Headless Python library + nexus CLI that lets a customer's own client (e.g. OPENCLAW) drive the Nexus Runner's two user-facing surfaces — chat (run skills, including the agentic chat loop) and the skill library (browse / install / uninstall / sync / balance) — without the Electron Runner installed. It shares the Runner's data dir, .ocskill formats, license/offline-token flow and shared Python env via the bundled nexus_core package (the same code the Runner's api.py wraps in FastAPI).

Custom-skill authoring (the Runner's 工作台) is intentionally not part of the SDK — authoring stays in the Runner GUI / the dev sdk/build/ scripts.

Layout

core_service/
  nexus_runner/        Electron app — api.py (FastAPI) + electron/ + src/ (Vue);
                       runner.py / installer.py / bootstrap.py / license_client.py /
                       token_cache.py / migrate.py / skill_review.py / paths.py /
                       runtime_env.py are thin re-exports of nexus_core.
  sdk/
    pyproject.toml     packages nexus_sdk + nexus_core  →  pip install ./core_service/sdk
    README.md          this file
    nexus_core/        GUI-/HTTP-free core:
                         paths · package (read/pack .ocskill: free tar.gz / paid
                         OCSK-v2 AES-256-GCM / legacy ZIP + SHA256SUMS) ·
                         package_verify (Ed25519) · runtime_env · bootstrap
                         (shared <data>/python/ + on-demand skill-dep installs) ·
                         installer · license_client · token_cache · migrate ·
                         skill_review · runner (run_skill: online/offline +
                         license + decrypt + exec) · registry (catalog /
                         my-skills / balance / install-token / download) ·
                         agent_loop (headless chat loop + prompt-skill loop) · config
    nexus_sdk/         SkillClient (high-level facade) · cli.py (`nexus`) ·
                         tools.py (expose skills as tool specs for your own agent loop) ·
                         legacy SkillLoader / SkillExecutor (back-compat)
    tests/             pytest suite (no network / no Runner)
    build/             dev/platform build scripts (not part of the published SDK)

Data dir: NEXUS_DATA_DIR if set (Electron passes app.getPath('userData') = %APPDATA%\Nexus on Windows), else %APPDATA%\Nexus, else ~/.nexus — see nexus_core.paths.

Install

pip install ./core_service/sdk                # nexus_sdk + nexus_core + the `nexus` CLI
pip install "./core_service/sdk[keyring]"     # + OS secret store for the API key
pip install "./core_service/sdk[legacy-zip]"  # + pyzipper for old AES-ZIP .ocskill

Library

from nexus_sdk import SkillClient
c = SkillClient(api_key="sk_live_...")          # or NEXUS_API_KEY env / `nexus config set`

# chat — agentic: the LLM picks/installs/runs skills via tools
res = c.chat("merge these two excels by 科目",
             ask_handler=lambda prompt, schema: my_app.ask_user(prompt, schema))
print(res["reply"]); print(res["tool_calls"])

# or run a skill directly / a prompt skill
c.run("excel-merge-filter", inputs={"input_0": "/a.xlsx"}, params={"mode": "and"})
c.run_prompt("code-review", "review this diff: ...")

# skill library
c.catalog("excel")            # marketplace listing
c.install("excel-merge-filter")   # download + license(if paid) + decrypt + install + pip deps
c.uninstall("excel-merge-filter")
c.list_installed(); c.my_skills(); c.sync()
c.balance()                   # license balance / offline-token inventory
c.prefetch("bank-match", count=10)

nexus_core is usable directly too (from nexus_core.runner import run_skill_sync, etc.).

Integrating chat into your client (OPENCLAW)

c.chat(message, *, history=None, ask_handler=None, skill_hints=None, max_turns=8, locale="zh", on_delta=None, ref_table=None, llm_base_url=None, llm_api_key=None, model=None) runs one agentic turn. The LLM sees five client-side tools — question / list_skills / load_skill / run_skill / read_ref — under a progressive-disclosure system prompt; run_skill is auto-resolved via this client (installs on demand) and question is routed to your ask_handler(prompt, schema, choices) -> str (omit it and such a turn yields an error the LLM works around). on_delta(text) streams assistant tokens; a ref_table keeps file paths / secrets / large outputs out of the LLM context. Returns {"reply", "messages", "tool_calls"}; pass messages back as history.

The SDK ships no model. By default the loop calls the platform LLM proxy (metered, billed to your API key) at <server>/api/v1/chat/completions — the same path skills hit. NEXUS_LLM_URL (server root) overrides server_url for this. To run it against your own OpenAI-compatible LLM instead, pass llm_base_url= (e.g. https://api.openai.com/v1)

  • llm_api_key= + model= (that key is used only for the LLM call, never for skill licensing).

Using Nexus skills as tools in YOUR own agent loop

If you already have an agent framework and just want the skills as callable tools (no Nexus chat loop), use the adapter:

from nexus_sdk import SkillClient, skill_tool_specs, dispatch_tool_call
c = SkillClient()
tools = skill_tool_specs(c, query="excel")             # OpenAI function-tool specs
# register `tools` in your own LLM call; when the model emits e.g.
#   name="nexus__excel-merge-filter", arguments={"input_0": "...", "mode": "and"}:
result = dispatch_tool_call(c, name, arguments,
                            max_output_bytes=8_000,    # optional — cap context bloat from big results
                            confirm_handler=lambda slug, info, args, reason: True)  # optional gate for confirm_required skills

dispatch_tool_call returns {ok: True, slug, output} on success (or {ok, slug, output_ref, output_preview, truncated} when capped; pass a ref_table= to keep the full output reachable). Cloud-execution-mode skills are NOT auto-installed (manifest comes from the catalog; client.run handles cloud routing). confirm_required skills are flagged in the return; omit confirm_handler for back-compat (runs anyway, returns confirm_required: true).

Anthropic (Claude) format — pass flavor="anthropic" and feed results back as tool_result:

import anthropic, json
client = anthropic.Anthropic()                          # uses ANTHROPIC_API_KEY env
nexus = SkillClient()
tools = skill_tool_specs(nexus, query="excel", flavor="anthropic")   # [{name, description, input_schema}, ...]

msg = client.messages.create(model="claude-opus-4-7", max_tokens=2048, tools=tools,
                             messages=[{"role": "user", "content": "merge these two excels by 科目"}])
# the model may emit a tool_use block:
for block in msg.content:
    if block.type == "tool_use":
        out = dispatch_tool_call(nexus, block.name, block.input, max_output_bytes=8000)
        tool_result = {"type": "tool_result", "tool_use_id": block.id,
                       "content": json.dumps(out, ensure_ascii=False, default=str),
                       "is_error": not out.get("ok", False)}
        # feed `tool_result` back as the next user-turn content; loop until no tool_use blocks

Not ported from the Runner's renderer (src/engine/agent-loop.ts): the fixed-rules / TF-IDF chat layer, the quota pre-charge UI, the confirm_required "type CONFIRM" gate.

CLI

nexus chat "merge these two excels by 科目" [--interactive] [--stream] [--turns 8] [--locale zh|en]
nexus chat "..." --llm-base-url https://api.openai.com/v1 --llm-api-key sk-... --model gpt-4o   # BYO LLM
nexus run <slug> --inputs '{"input_0":"/a.xlsx"}' --params '{"mode":"and"}'
nexus run-prompt <slug> "your message"  [--llm-base-url ... --llm-api-key ... --model ...]
nexus install <slug>  |  uninstall <slug>  |  list  |  sync
nexus search [query]  |  balance
nexus env provision   |  env clear   |  prefetch <slug> --count 10
nexus config show  |  config set api_key=sk_live_...  |  config set server_url=...
nexus migrate export <bundle> --pass <p>  |  migrate import <bundle> --pass <p>
nexus version

All commands print JSON to stdout (errors → JSON on stderr, exit 1).

.ocskill format

Format Magic When Payload
plain tar.gz 1f 8b free skills skill.json, main.py/SKILL.md, requirements.txt, assets/*, SHA256SUMS
OCSK-v2 OCSK(4B) + nonce(12B) + AES-256-GCM(tar.gz) paid skills same payload inside; per-skill key = HMAC-SHA256(build_secret, slug), delivered by the license API
legacy ZIP / AES-ZIP PK\x03\x04 old packages same files; AES-ZIP needs the key as password (mcp-nexus-sdk[legacy-zip])

.ocskill packages carry skill source + requirements.txt only — never wheels. Python deps are pip-installed on demand into the shared <data>/python/ env, version-pinned project-wide via skill_packages/constraints.txt. No per-skill venvs.

Testing

Two layers — pytest for unit tests (offline, no network), and a runnable script for end-to-end smoke against a live backend.

Unit tests (offline, ~2s)

cd core_service/sdk
pip install -e ".[test]"     # installs pytest + respx + the SDK editable
pytest -q                    # 44 tests; no network, no Runner, no API key needed

These cover: agent_loop's tool dispatch + streaming SSE assembly, ref-table, skill_tools (partition/validate/resolve_for_run/confirm_info), tools adapter (specs + dispatch + confirm gate + max_output_bytes), CLI subcommands, config/migrate round-trips, package isolation (no nexus_runner / fastapi / electron imports leak into the SDK).

End-to-end smoke (live backend; tests/integration_smoke.py)

A standalone script — not collected by pytest — that walks every SDK surface against a live backend and prints PASS / SKIP / FAIL per step. Uses an isolated NEXUS_DATA_DIR under the system temp dir so it cannot pollute your real Runner install at %APPDATA%\Nexus.

# minimal (no network, no API key) — proves import / version / env / confirm gate / CLI
python core_service/sdk/tests/integration_smoke.py

# add live catalog + balance + tool-spec generation
NEXUS_API_KEY=sk_live_... NEXUS_SERVER_URL=https://mcp-nexus.online \
  python core_service/sdk/tests/integration_smoke.py

# add: actually install a free skill, run it, then uninstall
NEXUS_API_KEY=sk_live_... \
  python core_service/sdk/tests/integration_smoke.py --with-install \
    --skill action-item-extractor

# add: exercise the agentic chat loop through the platform proxy (consumes LLM quota)
NEXUS_API_KEY=sk_live_... \
  python core_service/sdk/tests/integration_smoke.py --with-install --with-chat

# add: also exercise BYO LLM (your own OpenAI-compatible endpoint)
NEXUS_API_KEY=sk_live_... \
  NEXUS_SMOKE_BYO_BASE_URL=https://api.openai.com/v1 \
  NEXUS_SMOKE_BYO_API_KEY=sk-... \
  NEXUS_SMOKE_BYO_MODEL=gpt-4o-mini \
  python core_service/sdk/tests/integration_smoke.py --with-chat

Steps covered, in order: import + __version__, SkillClient instantiation into an isolated data dir, shared Python env provisioning (ensure_env), live catalog(), balance(), tool-spec generation (OpenAI + Anthropic flavors), install + run + uninstall of a free skill, the confirm_handler gate (offline, with a fake client), platform-proxy chat(), BYO-LLM chat(), and python -m nexus_sdk.cli version as a CLI smoke. Each step prints its own elapsed time; exit code 0 iff zero FAIL.

Tunable env vars: NEXUS_API_KEY · NEXUS_SERVER_URL · NEXUS_SMOKE_FREE_SLUG (default action-item-extractor) · NEXUS_SMOKE_RUN_INPUTS / NEXUS_SMOKE_RUN_PARAMS (JSON for the run step) · NEXUS_SMOKE_BYO_BASE_URL / NEXUS_SMOKE_BYO_API_KEY / NEXUS_SMOKE_BYO_MODEL. CLI flags: --with-install, --with-chat, --skill <slug>, --keep-data-dir.

Isolated install (verifies pip install ./core_service/sdk works clean)

# from a checkout of this repo (editable build)
python -m venv /tmp/mcp-nexus-sdk-test && /tmp/mcp-nexus-sdk-test/Scripts/activate   # bash: source ...
pip install ./core_service/sdk

# OR from PyPI (end-user path)
pip install mcp-nexus-sdk

nexus version
python -c "from nexus_sdk import SkillClient, skill_tool_specs, dispatch_tool_call; print('ok')"
python core_service/sdk/tests/integration_smoke.py     # works without the editable install too

PyPI listing: https://pypi.org/project/mcp-nexus-sdk/.

Notes

  • Shared Python env: skill deps install into <data>/python/ (provisioned on demand — copies a bundled CPython if shipped, else downloads python-build-standalone), exactly like the Runner. Set NEXUS_PYTHON=<path> to use a specific interpreter.
  • Local Runner: if a Runner is running on localhost:7432, the legacy SkillLoader prefers its HTTP API; SkillClient always works locally via nexus_core.
  • The vestigial nexus_sdk/setup.py is superseded by core_service/sdk/pyproject.toml.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_nexus_sdk-1.3.1.tar.gz (114.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_nexus_sdk-1.3.1-py3-none-any.whl (128.7 kB view details)

Uploaded Python 3

File details

Details for the file mcp_nexus_sdk-1.3.1.tar.gz.

File metadata

  • Download URL: mcp_nexus_sdk-1.3.1.tar.gz
  • Upload date:
  • Size: 114.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.5

File hashes

Hashes for mcp_nexus_sdk-1.3.1.tar.gz
Algorithm Hash digest
SHA256 54f37afbf5b5b9d1b2d4a7b75164f3cacabd1b0f3a3366a0d07235a2a3f98afb
MD5 72222646dcc4ba1e16d62520e5a196fb
BLAKE2b-256 f7fd335b41f42eaf03ee8e2bfe5270191c7ac98e5dae7c6258e0e39b7ddf363d

See more details on using hashes here.

File details

Details for the file mcp_nexus_sdk-1.3.1-py3-none-any.whl.

File metadata

  • Download URL: mcp_nexus_sdk-1.3.1-py3-none-any.whl
  • Upload date:
  • Size: 128.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.5

File hashes

Hashes for mcp_nexus_sdk-1.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d59a54dcda910954ac5f4a2d8b23754e1fea0d58128e6a71614c4429c8eb65ea
MD5 b4e3bfe0e4e7990a1fe2ffd291b09b53
BLAKE2b-256 21456e9741ea4ae3ae610d91d815a0349c71daf00cc63b101d710f30ae187d06

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page