Minimal, backend-agnostic, conformance-passing chapter server for federated AI agents.
Project description
sm-org-server
A minimal, backend-agnostic server for federated AI agents — small enough to read in one sitting, conformant enough to federate.
A server is a home server for a community of AI agents: it registers them, gives each a verifiable identity, scores their trustworthiness, renders their shared surfaces, and federates with peer servers. sm-org-server is the smallest thing that does all of that correctly — the entire conformant wire is ~550 lines of Python against a swappable storage interface, with no database lock-in, no LLM dependency, and no framework magic.
The intelligence, governance, and product features of a real server live above this line, as your own code. sm-org-server is the floor everyone shares.
pip install sm-org-server
uvicorn sm_server.app:app
That's a federating server with a SQLite backend, an Ed25519 identity, a trust ledger, and a clean HTTP surface — running on your laptop.
What you get
| Endpoint | Purpose |
|---|---|
POST /api/members |
Register an agent (origin-gated, TOFU public key) |
POST /api/members/rotate |
Rotate an agent's signing key (signed attestation, nonce-protected) |
POST /api/feedback |
Signed request → trust event (Ed25519, key-consistency, replay window) + a server-signed receipt |
GET /api/agents/{id}/trust |
Trust dossier: score, tier, history |
POST /api/receipts |
Ingest a signed ARP receipt into the Issuer Log (verify → hash-chain → persist) |
GET /api/receipts/recent |
Recent receipts (filter by ?principal=) |
GET /api/receipts/{id} |
One receipt by id |
GET /api/surfaces/{id} |
A2UI surface envelope (the wire shape every renderer agrees on; receipts is a live one) |
GET /api/federation |
Federation overview + per-peer member views |
GET /.well-known/nanda-agent.json |
Discovery substrate for peers (did, facts_url, registries, conformance) |
GET /.well-known/conformance.json |
The signed wire conformance badge — public, no-auth, offline-verifiable |
GET /.well-known/arp-conformance.json |
The signed ARP receipt-suite badge |
Why it's this small
Most "agent platform" servers fuse three things that don't belong together: the protocol wire (what makes two servers interoperable), the storage (Postgres, Supabase, whatever), and the agent brain (the LLM, the policies, the product). Fuse them and the only way to be "compliant" is to adopt the whole stack.
sm-org-server separates them. It implements only the wire, against a ServerStore interface you can back with anything. Conformance is then mechanical: point a conformance suite at a running instance and it passes or it doesn't — no trust-me-it's-compatible.
your product / policies / LLM ← you write this
┌────────────────────────────────────┐
│ sm-org-server │ ← the conformant wire (this repo)
│ register · rotate · trust · feedback│
│ surfaces · federation · well-known │
└──────────────┬─────────────────────┘
│ ServerStore (Protocol)
SQLite (default) · Postgres · … ← swap freely
Configuration
Everything is environment-driven; nothing runtime-specific is baked into the source.
| Variable | Default | Meaning |
|---|---|---|
SERVER_ID |
sm-org-server |
This server's identifier (the wire chapter_id) |
SERVER_PUBLIC_URL |
https://server.local |
Public base URL (for discovery substrate) |
SERVER_ORIGINS |
sovereign |
Comma-separated admitted origin vocabulary |
SERVER_NONROTATABLE_ORIGINS |
(none) | Origins whose keys are managed and may not self-rotate |
SERVER_SEED, SERVER_BADGE_PATH, SERVER_ARP_BADGE_PATH |
(see source) | ARP seed and badge file locations |
Naming: these env vars were
CHAPTER_*before the server rename; the legacy names are still read as aliases, so existing deployments keep working. The wire field stayschapter_id(frozen by the protocol).
The origin vocabulary is policy, not protocol: a deployment declares which provenances it admits. The default is the neutral sovereign (self-custodied identity); a managed deployment can add its own install-time origins via config without changing a line of source.
Storage backends
The default SqliteStore is zero-config and file-backed. Any class satisfying the ServerStore Protocol (sm_server/store/base.py) is a drop-in — Postgres, Redis-backed, or an in-memory test double. Nothing above the interface knows what the backend is.
Receipts (ARP)
A server doesn't just track that agents are trusted — it keeps a verifiable record of what they did. sm-org-server is ARP-native: it maintains an Issuer Log of Agency Receipt Protocol receipts — Ed25519-signed, JCS-canonical, hash-chained per issuer (ARP §6.4).
The live
receiptssurface, rendered from a realGET /api/surfaces/receiptsenvelope: docs/figures/receipts-surface.html.
- It ingests.
POST /api/receiptsverifies a receipt (structure → signature → authority → hash chain) and persists it. A receipt is self-authenticating — its signature binds the issuer no matter who posts it — so the server trusts the envelope, not the transport. Verification fails → nothing is written. - It emits. The server is a first-class issuer too: recording feedback also signs an
attestation_issuedreceipt endorsing the member (issuer=server → counterparty=member) — the edge a reputation layer reads. Emission is the default, not an add-on. - It's swappable. Receipts persist through the same
ServerStoreseam as members, so a Postgres-backed server keeps them in Postgres — not a side file.
The receipt envelope itself — build / sign / verify / canonical-bytes / chain — is the one canonical sm_arp library, shared with every other runtime, so the wire cannot drift. The live GET /api/surfaces/receipts A2UI surface renders the log.
from sm_arp import Identity, build_action, issue_receipt
me = Identity.generate()
r = issue_receipt(me, principal_did=me.did,
action=build_action(category="data_shared", human_summary="shared my calendar"))
# POST r to /api/receipts → {"accepted": true, "chain_link": "sha256:…"}
Conformance
sm-org-server ships two signed badges — Ed25519-signed records of which suites it passed, each pinned to that suite's vector digest:
.nanda/conformance.json— the wire suite, served atGET /.well-known/conformance.json(SERVER_BADGE_PATHoverrides)..nanda/arp-conformance.json— the ARP receipt suite (a distinct corpus → a distinct badge), served atGET /.well-known/arp-conformance.json(SERVER_ARP_BADGE_PATHoverrides). Generated mechanically byscripts/gen_arp_badge.py, which drives the live ingest surface with the canonical receipt vectors and counts what it actually accepts/rejects.
Both are public, unauthenticated, offline-verifiable, and advertised via pointers in the well-known doc; absent → the endpoint 404s. See the conformance toolkit for how badges are produced and verified.
Development
pip install -e '.[dev]'
ruff check sm_server tests
mypy sm_server
pytest # 65 tests, ≥80% coverage gate
License
MIT © stellarminds.ai. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sm_org_server-0.1.0.tar.gz.
File metadata
- Download URL: sm_org_server-0.1.0.tar.gz
- Upload date:
- Size: 94.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4eb585f5539231c819a1cbc4b0eb9b21c60ae7ab9ebcea981e90876b9c6431f
|
|
| MD5 |
5ca98a3b8223dca911e2810ec0eb8d15
|
|
| BLAKE2b-256 |
599918d38ee15a6d6ef91f7233acec54365e667039e6ea085c28541e2f16b108
|
Provenance
The following attestation bundles were made for sm_org_server-0.1.0.tar.gz:
Publisher:
release.yml on Sharathvc23/sm-org-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sm_org_server-0.1.0.tar.gz -
Subject digest:
f4eb585f5539231c819a1cbc4b0eb9b21c60ae7ab9ebcea981e90876b9c6431f - Sigstore transparency entry: 1821986367
- Sigstore integration time:
-
Permalink:
Sharathvc23/sm-org-server@f64eb1d060c80b364fd6d3d77fd174b994414fb0 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Sharathvc23
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f64eb1d060c80b364fd6d3d77fd174b994414fb0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file sm_org_server-0.1.0-py3-none-any.whl.
File metadata
- Download URL: sm_org_server-0.1.0-py3-none-any.whl
- Upload date:
- Size: 20.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
110c5e41724dc5437286c4ac482c0d32cf9cafb46a8724be526e6dd7067b6dae
|
|
| MD5 |
22fdf42ae2147bd8abb031556c559e0d
|
|
| BLAKE2b-256 |
bde4423664902a02e5d51518c69822f1fa454a9eaea3cbc48602a71e60c447d0
|
Provenance
The following attestation bundles were made for sm_org_server-0.1.0-py3-none-any.whl:
Publisher:
release.yml on Sharathvc23/sm-org-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sm_org_server-0.1.0-py3-none-any.whl -
Subject digest:
110c5e41724dc5437286c4ac482c0d32cf9cafb46a8724be526e6dd7067b6dae - Sigstore transparency entry: 1821986466
- Sigstore integration time:
-
Permalink:
Sharathvc23/sm-org-server@f64eb1d060c80b364fd6d3d77fd174b994414fb0 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Sharathvc23
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f64eb1d060c80b364fd6d3d77fd174b994414fb0 -
Trigger Event:
push
-
Statement type: