Organize JSON documents into paths. Bundle whole subtrees with one fetch. Versioning and multi-tenancy built in. Cloud hosted or self-hosted.
// npm install @usewren/client import { WrenClient } from "@usewren/client"; const wren = new WrenClient({ baseUrl: "https://…", apiKey: "wren_…" }); // Create an event at /events/masters-2026 const event = await wren.documents.create("events", { name: "Masters 2026", city: "Augusta" }); await wren.trees.set("events", "/masters-2026", event.id); // Fetch the whole events tree in one call const full = await wren.trees.getFull("events"); // Public read — no auth, just a URL const pub = await fetch("https://api.example.com/orgs/tkd/tree/events/masters-2026");
Features
Trees, paths, and public URLs. Everything you need to store and serve nested JSON.
Organize documents into named trees. Any hierarchy works: events, categories, org charts, taxonomies — the path is the data shape.
Grant principal=* read to a tree — optionally only its published versions — and every path is public at /orgs/{slug}/tree/…. Drafts stay private.
Append ?full=true to fetch an entire branch with all documents resolved in a single request. Perfect for client-side caching.
Each document that lives at a path keeps its own version history. Swap in new versions without touching the tree. Roll back, diff, or time-travel.
Read a whole tree at one label with ?label=preview on the private API, then promote it to published in one transaction. A consistent snapshot, every time.
Start free on our cloud, or deploy to your own infrastructure with Docker. Bring your own Postgres. No vendor lock-in.
AI agents
One server, one MCP endpoint. What you publish, anyone’s agent can find and use. What you keep private, only your agents reach — with your permissions, and nothing they do is permanent.
Any agent can connect to /mcp without signing up, see who publishes what, and read published sites and collections. Always the released version, never your drafts.
“Sign in with WREN” from Claude, Cursor or VS Code, pick the org, and the agent works with your groups’ access. Or give it an API key. Revoke either at any time.
Agent writes land as new versions labeled preview. Review the diff, promote what’s good, roll back what isn’t. Nothing is overwritten.
# Read anyone’s public data — no account needed claude mcp add --transport http wren-public https://wren.aemwip.com/mcp # Work in your own org — opens a browser to sign in and choose the org claude mcp add --transport http wren https://wren.aemwip.com/mcp/login
How it works
From an empty org to a publicly readable hierarchy in a few REST calls.
PUT to a tree path to create it. Folders can be empty — you can build the shape before the data lands.
Pass a documentId to assign a JSON doc at that path. The doc keeps its own version history.
GET a single node, GET a whole subtree with ?full=true, or expose it publicly and fetch it from any client.
API Reference
The full API is documented at /docs. Here’s the tree API in one glance.
# Assign a document to a path curl -X PUT /api/v1/tree/events/masters-2026 \ -d '{"documentId": "abc"}' # Create an empty folder (no document yet) curl -X PUT /api/v1/tree/events/2027 -d '{}' # Read a path with its children curl /api/v1/tree/events/masters-2026 # Bundle the whole tree at a specific label curl /api/v1/tree/events?full=true&label=published # Public read via org slug (no auth header) curl /orgs/tkd/tree/events/masters-2026
Client Libraries
Full tree API. Zero extra dependencies. Works in Node, Bun, and async Python.
npm install @usewren/client
import { WrenClient } from "@usewren/client"; const wren = new WrenClient({ baseUrl, apiKey }); // Assign, read, bundle — all strongly typed await wren.trees.set("events", "/masters-2026", docId); const node = await wren.trees.get("events", "/masters-2026"); const full = await wren.trees.getFull("events", { label: "published" }); await wren.trees.delete("events", "/masters-2026");
pip install usewren-client
from wren import WrenClient, AsyncWrenClient # Sync with WrenClient(base_url, api_key=key) as wren: wren.trees.set("events", "/masters-2026", doc_id) node = wren.trees.get("events", "/masters-2026") full = wren.trees.get_full("events", label="published") # Async async with AsyncWrenClient(base_url, api_key=key) as wren: full = await wren.trees.get_full("events")
Pricing
Every plan includes the full API, Admin UI, versioning, labels, trees, and binary assets.
For personal projects and experiments.
For side projects and small teams.
For production workloads and compliance.