Skip to main content

Centurian Python SDK — thin MCP wrapper for AI agents. Auto-registers, instruments tool calls, attributes cost. Implements ADR-017 SDK perf primitives: local rule cache + per-action OPA decision cache + durable sqlite-backed event queue + async batched MCP calls. Owner: Connect agent (T12 W3-W5).

Project description

centurian-sdk (Python)

Thin MCP wrapper for AI agents. See docs/prd/v4.1/Centurian_Solo_Developer_Experience.md.

Status

Version 0.1.0b8 ships real network calls to the Centurian control plane. The previous 0.1.0b7 shipped a stub MCP transport (security audit C1) — anyone on <= 0.1.0b7 should upgrade.

Install

pip install centurian-sdk
# optional: enable httpx transport (otherwise stdlib urllib is used)
pip install 'centurian-sdk[http]'

For local-monorepo development:

pip install -e ./packages/sdk-python

Quickstart

from centurian import Agent

agent = Agent(
    name="my-agent",
    purpose="Answer questions about my docs",
    # token is the provisioning token from your /signup flow
    # (also auto-read from CENTURIAN_TOKEN env)
)

@agent.tool
def search_docs(query: str) -> str:
    return run_my_search(query)

agent.run()

agent.run() does this over the network:

  1. POST /api/mcp/tools/call with tools/call JSON-RPC and tool centurian.register_agent.
  2. GET /api/mcp/resources/org_global_rules_manifest?org_id=... to seed the local rule cache.
  3. Start the durable sqlite-backed event queue. Tool invocations enqueue trajectory + tool-call events; the queue flushes via centurian.report_*_bulk JSON-RPC calls.

Auth

Call Auth
register_agent Authorization: Bearer <provisioning_token> (passed via token constructor arg or CENTURIAN_TOKEN env var)
All spine-ingest tools (report_*, submit_*) signing_credential field inside the tool arguments — extracted from the agent identity returned by register_agent

Action evaluation

agent.evaluate_action(verb, attributes) consults the local rule cache and returns an ActionDecision:

Effect decision.allowed When
allow True Rule explicitly allows or no rule matches and manifest is fresh
deny False Rule explicitly denies
escalate False Synchronous human-in-the-loop gate required
miss False Rule manifest stale or absent — treat as deny (Shadow #21 fix). Re-prime via agent.run() or mcp.prime_rule_cache().

Use agent.assert_action_allowed(...) to raise ActionRefusedError instead of branching.

Configuration

Reads CENTURIAN_TOKEN, CENTURIAN_MCP_URL, CENTURIAN_ORG_ID, CENTURIAN_OWNER_USER_ID, CENTURIAN_QUEUE_PATH from env.

Errors

  • McpRpcError(code, message, data) — JSON-RPC error envelope from the server (4xx).
  • McpTransportError(message, status=None) — network failure after retries exhausted (5xx, DNS, TLS).
  • ActionRefusedError(decision) — local rule cache refused the action.

Multi-rail payment support

A62 reserves rail-agnostic schema across the SDK surface. The exported CostSource Literal accepts legacy uppercase values plus 13 A62-reserved lowercase values (model_provider_*, mcp_call, stablecoin_x402, etc.); P0 wires the first 4 (model_provider_openai, model_provider_anthropic, model_provider_bedrock, mcp_call). The remainder, plus the new PaymentRail / PaymentProtocol / Facilitator Literals, the StablecoinAttributes TypedDict, and is_valid_wallet_identifier, are schema reservation only in v0.1.0.

Live x402 facilitator integration (Coinbase CDP, Cloudflare, Stripe) ships in v0.2.0+ per A63 / task_plan_v4.1.2.md. Until then, payloads carrying payment_rail or stablecoin sub-attributes parse without error but no consumer (cost router, attribute extraction, global rules) acts on them.

Known beta limitations (v0.1.0b8)

These are documented gaps tracked for the 0.1.0 GA release. Production usage on --pre should be aware:

W3-C1c — register_agent provisioning-token binding is surface-only

The HTTP endpoint at /api/mcp/tools/call requires an Authorization: Bearer <provisioning_token> header for register_agent, but only validates that the token is ≥16 characters. The handler trusts the org_id and owner_user_id claims supplied in the call arguments; it does NOT verify that the bearer token is bound to those claims server-side. Implication: anyone with any 16+ char string can register an agent under any org/owner they claim. The registered agent's signing credential IS bound at the row level, so subsequent calls authenticate normally — but the registration itself is a trust gap.

Mitigation in beta: treat your provisioning tokens as confidential; only obtain them through the documented /signup flow; rotate via centurian.rotate_credential if compromised. GA fix planned: introspectable provisioning_tokens table that binds each token to a specific (org_id, owner_user_id, expires_at) and rejects mismatches.

#13 — validateSigningCredential runs scrypt on every event ingest

Each report_trajectory_step, report_tool_call, etc. validates the signing_credential via scrypt (~30ms per call). High-throughput callers should batch via the bulk variants (report_trajectory_steps_bulk, report_tool_calls_bulk) which amortize the auth cost across up to 1,000 events per round trip. The SDK's BatchClient does this automatically; manual MCP callers should follow the pattern. GA fix planned: auth-cache layer keying validated credentials by (prefix, secret_hash) for 60s LRU.

#17 — No nonce/JTI replay defense on signing credentials

Captured cnt_live_* credentials are valid for their full TTL (default 90 days) until rotated. There is no nonce/JTI/timestamp on signed requests. Mitigation in beta: rotate credentials proactively if you suspect interception; restrict your SDK runtime environment so credentials cannot be exfiltrated. GA fix planned: SDK signs requests with timestamp + nonce; server rejects nonces seen within rotation window or timestamps with >5min skew.

A59 plain-English policy authoring — feature-flagged off

Customer-facing plain-English-to-Rego policy compilation is disabled in v0.1.0b8 and ships in v0.2.0 with the ADR-018 neuro-symbolic guardrail. The lower-level compile_plain_english_to_rego remains callable for internal use (e.g. audit-engine evidence predicates), but customer-facing authoring (submit_for_review, approve_review) is gated until the IR + symbolic verifier ship.

v0.2.0 fix: LLM emits an Intermediate Representation using only ontology primitives → deterministic compiler → symbolic verifier proves IR ↔ Rego logical equivalence → Dana reviews all three layers before applying. See task_plan_v4.1.2.md and docs/prd/v4.1/Centurian_PRD_v4.1.2_Amendments.md (ADR-018 §5.1).

Multi-rail payment coverage — schema only

Schema reservation only in v0.1.0: payment_rail attribute and stablecoin sub-attributes (payment_protocol, payment_amount_usdc, payment_token, payment_network, recipient_did, facilitator, transaction_hash) are recognized in attribute extraction. Live x402 facilitator integration (Coinbase CDP, Cloudflare, Stripe) ships v0.2.0 per A63. See task_plan_v4.1.2.md.

Re-attestation cadence (GA #14)

Every agent is issued an Attestation row at register_agent time with a 30-day TTL. The signing credential itself has a separate 90-day TTL, so a credential can remain technically valid while the underlying attestation has lapsed. Per docs/architecture/federated_model.md, agents must re-attest every 30 days.

The Centurian backend now runs a re-attestation worker (src/workers/reattestation.ts) that emits an agent.attestation.expired spine event when an attestation's expires_at passes without a fresh attestation in place. The recommended cadence is once per hour (the worker is idempotent across runs and per-agent — multiple expired rows produce a single warning, and a fresh attestation heals the warning state).

Caller responsibility: observe agent.attestation.expired on your own activity feed and call centurian.attest_owner (which writes a fresh Attestation row, resetting the 30-day clock) before day 30. SDK auto-re-attestation on the next agent.run() is deferred to a future SDK release; for v0.1.0b8 the re-attestation must be triggered explicitly by the operator or a wrapper script. Track the follow-up on the issue tracker.

Other deferred items

  • KMS-managed signing keys for tier-3 audit reports — not yet shipped; tier-3 audit emit throws in production until the host registers a real signer resolver.
  • Per-org rate limiting at the MCP HTTP route — not yet implemented; free-tier $5/mo + 10K-step caps at the cost layer mitigate.

License

Proprietary. © Centurian.

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

centurian_sdk-0.2.0b1.tar.gz (39.9 kB view details)

Uploaded Source

Built Distribution

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

centurian_sdk-0.2.0b1-py3-none-any.whl (29.4 kB view details)

Uploaded Python 3

File details

Details for the file centurian_sdk-0.2.0b1.tar.gz.

File metadata

  • Download URL: centurian_sdk-0.2.0b1.tar.gz
  • Upload date:
  • Size: 39.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for centurian_sdk-0.2.0b1.tar.gz
Algorithm Hash digest
SHA256 d863106cdcd63444396ae889ce4917ea64b1091a94a48d82b319444208d19a49
MD5 7d01386564c4710d9041f3bab377bdb2
BLAKE2b-256 9eec76dd4bbf4b45df97c641df01738ea5a6db4fee8bd0228cfeb6cbb9a9fc97

See more details on using hashes here.

Provenance

The following attestation bundles were made for centurian_sdk-0.2.0b1.tar.gz:

Publisher: release.yml on omniviewai/Centurian

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file centurian_sdk-0.2.0b1-py3-none-any.whl.

File metadata

  • Download URL: centurian_sdk-0.2.0b1-py3-none-any.whl
  • Upload date:
  • Size: 29.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for centurian_sdk-0.2.0b1-py3-none-any.whl
Algorithm Hash digest
SHA256 16699dcddca9207e48f22661bf6160803d6aa500b81b0559710fc19029eee9c9
MD5 f7c8d36c962b5247dd29cb2f267cdbdf
BLAKE2b-256 9b752c5e2eb7bbc396156f54b266aa98af8217200a32cd5b0d388301e9dddaa2

See more details on using hashes here.

Provenance

The following attestation bundles were made for centurian_sdk-0.2.0b1-py3-none-any.whl:

Publisher: release.yml on omniviewai/Centurian

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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