Skip to main content

vsor

Compile a folder of governed markdown into a website and — in a later release — an MCP server, with cited answers and honest abstention.

You own a body of professional knowledge: tax rules, case notes, a syllabus, an operations manual. vsor turns the folder it lives in into surfaces other people and other software can use, without you owning a toolchain. You write markdown. Everything else derives from it.

Status — 0.1.0

The site half ships. vsor init, vsor dev and vsor build are implemented, tested and walked live end to end. vsor serve — the MCP surface, and the Postgres half behind it — is not in this release: running it says so and exits 2. The API is not stable until 1.0.

Install

uv tool install vsor          # or, without installing: uvx vsor init my-sor

Requirements: Python 3.14+ · Node 20+ and npm on PATH. The first vsor dev or vsor build installs a Docusaurus runtime under .vsor/ — one time, ~1–2 minutes, network required. Nothing is installed into your project outside .vsor/: no node_modules, no package.json, no pyproject. macOS and Linux; on Windows, use WSL.

Five minutes

vsor init my-sor     # scaffolds a project into your own repo, git initialized
cd my-sor
vsor dev             # the live site on 127.0.0.1:3000, hot-reloading from knowledge/
vsor build           # emits build/ (the deployable site) + build.lock.json (the record)

vsor init writes a project that is content and config only — your corpus, one instance.md, a real (thin) Docusaurus site/ whose every key is a live seam, four rules and fourteen skills for the coding agent you already use, and a first commit. No machinery, nothing frozen, nothing rented, and no vendor's config file you did not ask for.

What you get

  • A website that looks like a product, not a docs template: Tailwind v4, shadcn/ui primitives, OKLCH design tokens, lucide icons, local search over your corpus, and a content vocabulary your markdown can use — <Quiz />, <Flashcards />, galleries, callouts. Rebrand by editing design tokens in one file.
  • No external requests. Fonts self-hosted, search a local index, zero analytics, zero CDN.
  • build.lock.json — the committed record of a build: a build_id derived from the inputs, the commit it came from and where in that repository the project sits, one row per document, the tool versions. Same inputs, same build_id. The commit is named only when it genuinely contains what was built, so <commit>:<prefix><path> always fetches the bytes a row describes — and the deployable directory carries a copy of the record at build/build.lock.json, so you can tell which build is live.

Deploy

build/ is a plain directory of static files — upload it to any static host. There is no server, no runtime, no serve-time environment variable.

First, in site/docusaurus.config.ts, set the two values that are baked in at build time and never read at serve time:

Key Set it to
url the origin the site will be served from — scheme and host, no path, e.g. https://sor.acme.dev. It ends up in sitemap.xml, every canonical <link>, every og:url and the JSON-LD, so an unedited config publishes a site whose machine-readable half names the machine that built it. vsor build warns while it is still the placeholder
baseUrl "/" for a domain root; "/<repo>/" — leading and trailing slash — if the site lives in a subpath, as a GitHub Pages project site does. Get it wrong and every asset 404s

Rebuild, then upload. From the project root, where build/ is:

Host Command
Netlify netlify deploy --dir=build --prod
Cloudflare Pages npx wrangler pages deploy build --project-name <name>
Vercel --prebuilt reads one specific directory, so stage into it: rm -rf .vercel/output && mkdir -p .vercel/output && cp -R build .vercel/output/static && printf '{"version":3}' > .vercel/output/config.json && vercel deploy --prebuilt --prod
GitHub Pages publish build/ as the Pages artifact (actions/upload-pages-artifact with path: build, then actions/deploy-pages). It already contains the .nojekyll Pages needs
S3 / R2 / GCS aws s3 sync build s3://<bucket>, then enable website serving on the bucket
your own server rsync -a build/ host:/var/www/<site>/ behind nginx or Caddy — it is files, it needs no runtime

Or let the host build it: .agents/skills/deploy/SKILL.md carries a ready host config for Vercel, Netlify and Cloudflare Pages — the same build command and output directory — for the agent to write into your project once you have picked one, after which a connected repository deploys on push. The scaffold ships none of them: two of any three would always be deleted. That path needs vsor installable from PyPI — check with uvx vsor --version.

Then verify rather than trust the URL a CLI printed — with -L, because the sitemap writes extensionless directory URLs while the build emits index.html files, so a host either redirects or 404s:

curl -sSL -o /dev/null -w '%{http_code}\n' <url>/          # 200
curl -sSL "<url>/docs/<slug>/" | grep -q "<its title>"     # the document really renders
curl -sSL <url>/sitemap.xml | head -c 400                  # every <loc> names the deployed origin

A scaffolded project carries all of this, plus the reasoning, at .agents/skills/deploy/SKILL.md — offline, and pinned to the version that scaffolded it.

More

Apache-2.0. Third-party attribution — the forked upstream app, the shadcn/ui components and the two OFL typefaces — is in the NOTICE file shipped in this distribution.

Download files

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

Source Distribution

vsor-0.1.2.tar.gz (668.6 kB view details)

Uploaded Source

Built Distribution

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

vsor-0.1.2-py3-none-any.whl (638.3 kB view details)

Uploaded Python 3

File details

Details for the file vsor-0.1.2.tar.gz.

File metadata

  • Download URL: vsor-0.1.2.tar.gz
  • Upload date:
  • Size: 668.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.9 {"installer":{"name":"uv","version":"0.9.9"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for vsor-0.1.2.tar.gz
Algorithm Hash digest
SHA256 e3496301accdb7a1d72356c3497c07a2227136dba078359f206a3a432eeaeeb0
MD5 10aa23a7a88ed75dbb2e391662a8a05a
BLAKE2b-256 10f017bf4a7b483a60cb00508c309b87197147c174b17215373c661c742e86eb

See more details on using hashes here.

File details

Details for the file vsor-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: vsor-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 638.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.9 {"installer":{"name":"uv","version":"0.9.9"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for vsor-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b3bb00d4356016db81143d513bba31aedf281f4eaf8167fb7130d94b6dd879ca
MD5 3d97b0b16ab1df7930f36605cd58e331
BLAKE2b-256 2df11739412d4861acd27b1517644271d95b4681e9fe4efa335e251a11503921

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.4

2 files

0.1.3

2 files

This release

0.1.2 This release

2 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