v0.1.0 EARLYMCP server · CLI · 30 skills
Stanford compliance, wired into your agent.
Markdown, YAML, and a small CLI that turns Stanford's web requirements into something your coding agent already knows. No starter templates. No design system fork. Nothing for us to keep updated on your behalf.
Step 1 of 2 · paste this into your agent
Install the Stanford Web Services agent team into my editor.
npx @su-sws/synthetic-web-team install --json
If npx cannot reach the registry, use the repository instead:
git clone --depth 1 https://github.com/SU-SWS/synthetic-web-team /tmp/swt
node /tmp/swt/packages/wizard/bin/wizard.mjs install --json
That writes 30 skills to ~/.claude/skills and ~/.agents/skills and nothing
else: no standards, no AGENTS.md, nothing about any particular site. It never
touches a file it did not write, so unrelated skills already in those
directories are safe, and "install --remove" uninstalls it.
Then ask me which of these I need, and do not install into a project until I
have answered:
- a NEW Stanford site, in an empty directory
- the standards ADDED to a project I already haveWorks in Claude Code, Cursor, VS Code Copilot, Codex, Zed — any agent that can run a command. No flags to learn.
Dogfooded: this page is built by the recipe it documents and scores 100/100 with zero automated failures.
See how it is measured →Two commands, both required
Install once. Then per project.
- Install into your editor.Once per machine. Puts the 30 skills where your tools already look and writes nothing about any site, because at this point there is no site. Undo with
install --remove. - Then, in a project. Pick one. They are different jobs, so nothing is picked for you.
2aStart a new site. In an empty directory. The result names the recipe to follow to build the pages, so there is work after the install.
2bAdd to what you have.Adds the contract, the standards and the record.Touches none of your source, and a file you edited is reported rather than overwritten.
The command is not optional.There is no bare form and no default:install writes to your home directory, whileinit and add write into whichever directory you are standing in. Those are too different to guess between, so it does not. Run it with no command and it prints its help and writes nothing.
Guessing from the directory would not work either: an empty directory is exactly the init case, so treating it as "install into my editor" would hijack the commonest way to start a site.
Every flag is optional. With a terminal on both ends each job interviews you; prompts appear only when stdin and stdout are both a TTY, so an agent runs the same commands to completion and reports instead of hanging. There is alsosws_scaffold over MCP for step 2, if your agent already has the server.
Four fields in the result are the ones to act on.
- next[]
- What to do next, as data rather than prose. Each step has a path or a command and a reason.
- incomplete[]
- Manifest fields still holding placeholders. Ask the user for these; MinWeb requires a named owner and technical administrator with valid Stanford email.
- counts
- created, updated, unchanged, preserved. A re-run reports unchanged, so "already installed" is a truthful answer.
- dependency
- Whether the project now declares this package. It has to, because unscoped
swson the registry is somebody else's package andnpx swswould run that instead.
npx @su-sws/synthetic-web-team installnpx @su-sws/synthetic-web-team initnpx @su-sws/synthetic-web-team add .$ npx @su-sws/synthetic-web-team
synthetic-web-team <install|init|add> [dir]
...prints this help, writes nothing, exits 0
$ npx @su-sws/synthetic-web-team ./my-site
unknown command: ./my-site
Expected install (into your editor), init (a new site), or add
(an existing project). A directory goes after the command, not
before it.
...exits 2, writes nothingPaste-a-prompt versions of step 2
2a · a new site. Installs, then follows the recipe to build it.
Start a new Stanford site here, following Stanford Web Services standards.
This assumes the skills are already installed in my editor. If the sws-*
skills are not available to you, run this first:
npx @su-sws/synthetic-web-team install --json
Then, in the empty directory for the new site:
npx @su-sws/synthetic-web-team init --json --answers '{"siteName":"...","unit":"..."}'
If npx cannot reach the registry, swap it for the repository route:
git clone --depth 1 https://github.com/SU-SWS/synthetic-web-team /tmp/swt
node /tmp/swt/packages/wizard/bin/wizard.mjs --json \
--answers '{"siteName":"...","unit":"..."}'
Fill in siteName and unit from what I tell you. Ask me if it is not obvious.
The installer is non-interactive and prints one JSON document. Then:
1. Read AGENTS.md. That is the behavioural contract for this repository.
Follow it from now on, not only during setup.
2. Work through the result's "next" array in order. For a new site it names
the recipe to follow to actually build the pages.
3. Ask me about every field in "incomplete". Do not invent owner names or
email addresses: Stanford's MinWeb standard requires a named business
owner and technical administrator with real Stanford addresses.
4. Run npm install, then verify: npx sws doctor --format json
5. Tell me which compliance tier it derived, and the one-sentence reason.2b · a project you already have.Adds the standards and changes none of your code.
Add the Stanford Web Services standards to this existing project.
This assumes the skills are already installed in my editor. If the sws-*
skills are not available to you, run this first:
npx @su-sws/synthetic-web-team install --json
Then, in the root of this repository:
npx @su-sws/synthetic-web-team add . --json --answers '{"siteName":"...","unit":"..."}'
If npx cannot reach the registry, swap it for the repository route:
git clone --depth 1 https://github.com/SU-SWS/synthetic-web-team /tmp/swt
node /tmp/swt/packages/wizard/bin/wizard.mjs add . --json \
--answers '{"siteName":"...","unit":"..."}'
Fill in siteName and unit from this repository. Ask me if it is not obvious.
Do not change any of my existing code. The installer adds AGENTS.md, the
standards, and the .sws record; it does not touch my source. If anything comes
back as a conflict, list those files and stop: they are ones I edited and I
will decide. If anything is an orphan, list it and do not delete it.
Then read AGENTS.md and follow it from now on, work through "next" in order,
run npm install before verifying, and ask me about every field in "incomplete"
rather than inventing an owner name or email.npx @su-sws/synthetic-web-team init --json --answers '{
"siteName": "Stanford Bioengineering",
"unit": "Bioengineering",
"businessOwnerEmail": "owner@stanford.edu",
"techAdminEmail": "admin@stanford.edu"
}'{
"ok": true,
"version": "0.1.0",
"counts": { "created": 81, "updated": 0, "unchanged": 0, "preserved": 0 },
"incomplete": ["site.url"],
"dependency": { "name": "@su-sws/synthetic-web-team", "status": "no-package-json" },
"next": [
{ "kind": "read-contract", "path": "AGENTS.md" },
{ "kind": "orient", "skill": "sws-onboard" },
{ "kind": "follow-recipe", "path": "standards/recipes/astro-static/RECIPE.md" },
{ "kind": "add-dependency", "command": "npm install -D @su-sws/synthetic-web-team" },
{ "kind": "verify", "command": "npx sws doctor --format json" }
]
}Two more prompts: review an existing site, and update
Already have a site? This one reports and changes nothing.
Review this project against Stanford Web Services standards. Change nothing.
git clone --depth 1 https://github.com/SU-SWS/synthetic-web-team /tmp/swt
node /tmp/swt/packages/wizard/bin/wizard.mjs add . --json
node /tmp/swt/packages/cli/bin/sws.mjs doctor --format json
Give me the score out of 100, then the three findings most worth fixing: one
sentence each, naming the Stanford policy behind it. Fix nothing yet.Already installed?Re-installing is the update, and it stops on anything you edited.
Update the Stanford Web Services standards in this project.
npx @su-sws/synthetic-web-team add . --json
If npx cannot reach the registry, swap it for the repository route:
git clone --depth 1 https://github.com/SU-SWS/synthetic-web-team /tmp/swt
node /tmp/swt/packages/wizard/bin/wizard.mjs add . --json
Report "previousVersion" against "version", and the "counts" object. If anything
comes back as a conflict, list those files and stop: they are ones I edited and
I will decide. If anything is an orphan, list it and do not delete it.Verified, not asserted
Thirteen check modules. Sixty-three criteria.
Every criterion maps to an implemented check, is marked manual, or declares why it is not built yet. A criterion with no check is a wish, and four CI gates exist to stop wishes accumulating.
npm run build
npx sws a11y # axe-core, every route, real Chromium
npx sws perf # first-party byte budget
npx sws check # reads both, scores out of 100A check that cannot run reports unknown, neverpass. Its points are withheld rather than awarded. That rule exists because a harness here once printedTOTAL VIOLATIONS: 0 while axe had silently failed to load.
| Module | Verifies |
|---|---|
| footer | Global Footer link set, order, and nothing added |
| identity | Identity Bar present, nothing above but skip-nav |
| decanter | Decanter 8 not 7, no tailwind.config.js, no dead packages |
| a11y | axe-core at WCAG 2.1 AA, plus lang, headings, alt, skip link |
| perf | First-party byte budget per route |
| seo | Titles, descriptions, canonical, robots, sitemap, JSON-LD |
| secrets | Committed credentials. The only blocking check |
| manifest | Named owners, Siteimprove, recorded divergences |
Plus build, hygiene, workflow,security, and next.
A real browser
axe and a byte budget, in Chromium.
Both runners serve the build over localhost, drive a real browser, scroll the whole page, and wait for animations to settle before measuring. Each of those steps exists because skipping it produced a wrong answer on this very site.
145
rule-nodes audited
Unscrolled it was 116, and axe reported a clean pass. Entry motion holds content at opacity 0, and axe skips invisible elements — so a fifth of the page went unaudited.
4
false contrast failures avoided
axe reads computed colour. Captured mid-fade, text measured 1.05:1 against white. Waiting for animations to settle removed all four.
77%
less JavaScript
The same entry motion via vanilla motion rather than a React island: 60.4 KB instead of 266.7 KB. The byte budget caught the difference.
A green run means roughly 30 percent of accessibility issues are absent, per the Office of Digital Accessibility's own figure. It is a floor, not a conformance claim, and the report says so every time.
Two entry points
A CLI, and an MCP server.
The server is a second entry point, never a requirement. Everything it exposes is also a plain file under standards/ that an agent can read directly, so if it will not start, nothing else stops working.
Five tools and all 26 documents as resources. sws_checkand sws_scaffold shell out to the same binaries a human runs, so the MCP answer and the terminal answer cannot disagree.
{
"mcpServers": {
"sws": { "command": "npx", "args": ["-y", "@su-sws/synthetic-web-team-mcp"] }
}
}| Tool | Purpose |
|---|---|
| sws_get_standard | Any policy, pattern, recipe or fragment. Understands synonyms |
| sws_footer_html | Global Footer markup, generated from the byte-exact contract |
| sws_check | The compliance report, structured |
| sws_decanter_token | Tokens read from the Decanter actually installed |
| sws_scaffold | Install into a project. Dry run by default |
sws_footer_html justifies the server on its own. The Global Footer is immutable, frequently gotten wrong, and mechanically generable — two of its ten URLs were wrong in this project's first draft because they were typed from memory. The contract was extracted on 2026-08-10.
Updates without surprises
Re-installing is the update.
The standards are vendored into your project rather than resolved at runtime, so an update is a re-copy. The only real question is what it is allowed to touch.
.sws/installed.json records a hash of everything written, which is what lets a re-install tell a local edit from an old version. sws doctor tells you when you are behind: content and tools ship in one package, so the CLI's version is the standards version, and no network call is needed.
npx @su-sws/synthetic-web-team add .preserved
.sws/manifest.yml and .sws/acknowledged.yml. Your owners and accepted risks are never overwritten
conflict
A file you edited. Reported and left alone unless you pass --force
orphan
A file we no longer ship. Reported every run, never deleted
Deleting files in someone else's repository on the strength of a version bump is not a risk worth taking for tidiness.
What is inside
Markdown, YAML, and a small CLI.
No application code, no starter templates, no design system fork. A template starts rotting the day it is committed and every consumer inherits the rot; a recipe says what must be true and delegates the boilerplate to the upstream scaffolder.
8 policy files
MinSec, MinWeb, accessibility, privacy, brand, identity, procurement, escalation. Each dated with a reviewed: field
7 pattern files
Decanter 8, components, content, IA, forms, motion, discoverability
30 skills
8 built roles, 11 honest stubs, 11 shared. Two frontmatter keys, read natively by nine tools
2 recipes
astro-static and next-netlify, with 63 machine-checkable criteria between them
1 fragment
The Global Footer, byte-exact, extracted from the upstream component
One load-bearing version constraint
Recipes name no version numbers, with a single exception:Decanter 8, never 7, because they are architecturally different and getting it wrong fails silently. Everything else installs at latest and records what resolved. Standards are expressed as things to avoid, which age better than versions to require.
Point your agent at it.
Everything is advisory except committed credentials, because that is the only irreversible harm. A tool that fails your build over a contrast ratio gets uninstalled by Friday, and then nothing is compliant.