Skip to main content

nace-kit

Multi-key client, presets, CLI and MCP server for the nace.ai Drex API — classify text or JSON with calibrated probabilities, from Python or any MCP-speaking agent.

English | 简体中文

PyPI Python License: MIT CI

Contents

Why this exists

Drex answers typed questions about any text or JSON with calibrated probabilities — great for routing tickets, triaging issues, grading replies. The official nace-sdk wraps the whole API; nace-kit wraps the operations around it:

  • Key pool — several API keys work as one. A dead key (401) or an exhausted quota (429) fails over to the next key mid-request.
  • Response cache — Drex answers are deterministic, so identical requests are served from an LRU cache instead of billed again.
  • Usage metering — calls and tokens, per key, always visible in client.usage.
  • Presets & typed answers — urgency(), sentiment(), severity(), priority() out of the box; pydantic questions and responses throughout.
  • Document pipeline — parse / extract / ground over the official SDK with the same key pool ([docs] extra).

Quick start

Requires Python 3.11+ (Windows / macOS / Linux) and one or more API keys from the console.

pip install nace-kit        # or: uv add nace-kit / uvx nace-kit for one-off use
export NACE_API_KEYS="nace_sk_...,nace_sk_..."   # pool of keys; NACE_API_KEY for one
from nace_kit import NaceClient, presets

client = NaceClient()  # defaults to drex-latest

# binary question -> probability of yes
r = client.classify("Help! My payouts have been failing for 3 days.", presets.urgency())
r.answers["is_urgent"].noul             # 0.7161

# state can be any JSON; questions batch into ONE request
r = client.classify(
    {"ticket": "#42", "subject": "payout failure", "days_stuck": 3},
    [presets.urgency(), presets.severity(), presets.priority()],
)

client.models()   # available models; also a cheap key health check
client.usage      # {'nace_sk_wn…': {'calls': 12, 'input_tokens': 300, ...}}

Async works the same: from nace_kit import AsyncNaceClient.

How it works

Failure Behaviour
401 / 403 (bad or dead key) rotate to the next key immediately
429 (quota), several keys configured rotate to the next key immediately
429, single key configured retry the same key with backoff (honours Retry-After)
408 / 5xx / network / timeout retry the same key — exponential backoff + jitter, Retry-After aware, 30 s total budget — then rotate
4xx (payload rejected) raise immediately, no retries (NaceBadRequest)

Keys are validated at construction (nace_sk_ + 43 chars); retries (max_retries, backoff_*, retry_budget), cache size and timeouts are constructor parameters.

Comparison with the official SDK

official nace-sdk nace-kit
Classification API (all three question types, any-JSON state, models listing, typed objects) ✅ ✅
Multi-key pool with failover ❌ single key ✅
LRU response cache ❌ ✅
Per-key usage metering ❌ ✅
Backoff retries, Retry-After, budget ✅ ✅ (combined with rotation)
Question presets ❌ ✅
Document pipeline (upload/parse/extract/jobs) ✅ ✅ via the official SDK ([docs] extra)
nace login credential file ✅ ❌ env vars
CLI + MCP server in one package ❌ separate nace-mcp ✅

Question types

Type criteria Answer
noul optional {"true": "…", "false": "…"} outcome descriptions {"noul": 0..1} — probability of yes
choice {label: description} — one label wins {"choice": "billing", "probabilities": {...}, "confidence": …}
score ["low", "medium", "high"] — ordered levels {"score": 1.31, "legend": […], "probabilities": {...}, "confidence": …}
from nace_kit import presets as p

p.noul("Refund?", true="wants money back")
p.choice("What is this?", {"billing": "payments", "technical": None})
p.score("How angry?", ["calm", "annoyed", "angry", "furious"])

Pick your own threshold on the probabilities rather than treating them as a verdict.

Document pipeline

The document operations wrap the official nace-sdk (MIT) — their API surface, our key pool on top:

pip install "nace-kit[docs]"
from nace_kit import DocsClient

docs = DocsClient()   # same NACE_API_KEYS pool; rotates on 401/429
job = docs.parse("https://example.com/report.pdf",
                 output={"formats": ["markdown"]}, wait=120)
job.result["document"]["markdown"]

parse / split / classify_document / extract / ground create jobs and (with wait) poll them to completion; docs.job(id), docs.wait(id), docs.jobs() manage them afterwards. Every create is idempotency-keyed, so a key rotation mid-call never bills a second job. AsyncDocsClient mirrors everything.

MCP for agents

One registration, every project. ZCode (~/.zcode/cli/config.json → mcp.servers):

"nace": {
  "type": "stdio",
  "command": "uvx",
  "args": ["nace-kit-mcp"],
  "env": { "NACE_API_KEYS": "nace_sk_...,nace_sk_..." }
}

Claude Desktop / Cursor: same shape under mcpServers.

Tools: classify (full batch interface), ask (single question over noul / score / choice), list_models, and — with the [docs] extra installed — parse_document, extract_data, get_document_job.

Prefer a skill? nace-kit --install-skill copies an Agent Skill (SKILL.md) to ~/.agents/skills/ (or --claude for ~/.claude/skills/), so agents get usage guidance — question phrasing, batching, thresholds — even without the MCP registration.

CLI

nace-kit "Camera 3 is showing a black screen." --no-cache
nace-kit "..." --ask "How angry is the user?" --kind score --levels calm annoyed angry furious
nace-kit "..." --ask "What is this about?" --kind choice --options billing:"payment issues" technical:"bugs"
nace-kit --models

FAQ

Is the cache safe? Drex answers are deterministic for identical input (same model, state, questions), so caching is exact. Pass cache_size=0 to disable.

Which model does it call? drex-latest by default, which nace.ai moves forward on announced dates; pin with NaceClient(model="drex-v2.0") if you need reproducibility.

Where do keys go? NACE_API_KEYS (comma-separated pool) or NACE_API_KEY. For agents, put them in the MCP server's env block. Never in code.

Contributing

Issues and PRs are welcome at lincong1987/nace-kit.

uv sync            # httpx, mcp, pytest
uv run pytest -q   # unit tests — no network or keys needed

License

MIT © nace-kit contributors.

Metadata

Release files for nace-kit 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nace-kit 0.3.0
File Size Uploaded
nace_kit-0.3.0.tar.gz 79.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for nace-kit 0.3.0
File Interpreter ABI Platform
nace_kit-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 102.3 kB

Release files / nace_kit-0.3.0.tar.gz

Download URL nace_kit-0.3.0.tar.gz
Size 79.3 kB
Tags Source
SHA-256 checksum
How to use checksums
c9d8f0d198d48aa68f8907ef23ae05a64d672ce96f9ecddb51b79f47bb2d0bd8
BLAKE2b-256 checksum
How to use checksums
a11c8b42939efc1a5903458625b2faeb92859bc3108d2d0c3feeae8145ff1444
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / nace_kit-0.3.0-py3-none-any.whl

Download URL nace_kit-0.3.0-py3-none-any.whl
Size 23.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8032d3409c088ef8ca184dc8f68ab6e7c34e9847e742e5d179f7548d859845f5
BLAKE2b-256 checksum
How to use checksums
0587c20ccac7a2f6f914110637e04ed2f292a9fe14aa828d27d379c344f6c099
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.1

2 release files

This release

0.3.0 This release

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page