Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,44 @@ jobs:
name: dist
path: dist
retention-days: 7

# The MCP Worker in mcp/ is a separate package with its own lockfile, so the
# job above never touches it: the root `npm ci` doesn't install it, and both
# eslint.config.js and .prettierignore exclude mcp/ deliberately. Its
# type-check had never run in CI either. A separate job so a Worker failure
# reads distinctly from a site-build failure.
mcp:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

- name: Set up Node.js
uses: actions/setup-node@v7
with:
# ts-resolve-hook.mjs needs registerHooks, added in 22.15. The `22`
# the job above uses would satisfy that today, but pinning the floor
# here keeps a runner rolling back from failing at link time with
# nothing to point at.
node-version: 22.15
cache: npm
cache-dependency-path: mcp/package-lock.json

- name: Install MCP dependencies
run: npm ci
working-directory: mcp

# src/data.json is generated rather than committed, and src/index.ts
# imports it — so tsc cannot resolve the module until the manifest
# exists. `npm test` regenerates it as well (pretest), but the
# type-check has no such hook and runs first.
- name: Build data manifest
run: npm run build:data
working-directory: mcp

- name: Type-check (tsc)
run: npm run typecheck
working-directory: mcp

- name: Test (node:assert)
run: npm test
working-directory: mcp
8 changes: 5 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ These mirror `CONTRIBUTING.md`. Enforce them in your own writing and when review
| `wrangler.toml` (root) | Pages bindings — the `AGENT_LOG` (`sw_agent_log`) and `REPORT_LOG` (`sw_report_log`) Analytics Engine datasets. Pages itself is deployed via the Pages dashboard's Git integration. |
| `public/_headers` | Cloudflare response headers — strict CSP, HSTS, Permissions-Policy, Vary on .md, content types for well-known files, the discovery `Link` header. |
| `public/.well-known/` | Static well-known URIs (security.txt, change-password, api-catalog, mcp/server-card.json, agent-card.json for A2A discovery, agent-skills/index.json + agent-skills/<name>/SKILL.md per the Agent Skills Discovery RFC v0.2.0 — if you edit a SKILL.md, recompute its sha256 and update the `digest` in index.json; ai-catalog.json is the ARD AI Catalog, published unsigned — see [agentic-resource-discovery](src/content/spec/agent-readiness/agentic-resource-discovery.md) for why a same-origin trust-manifest signature proves nothing). |
| `mcp/` | Cloudflare Worker exposing the spec at `mcp.specification.website`. Serves the MCP transport at `/mcp`, an A2A (Agent-to-Agent) JSON-RPC endpoint at `/a2a/v1`, and mirrors both discovery cards under `/.well-known/`. Has its own `package.json`, `wrangler.toml`, build script. Reads from the same `src/content/spec/` source of truth at build time. Logs each call to the `MCP_LOG` Analytics Engine dataset (`sw_mcp_log`). |
| `mcp/` | Cloudflare Worker exposing the spec at `mcp.specification.website`. Serves the MCP transport at `/mcp`, an A2A (Agent-to-Agent) JSON-RPC endpoint at `/a2a/v1`, and mirrors both discovery cards under `/.well-known/`. Has its own `package.json`, `wrangler.toml`, build script, and assertions (`npm test` — plain `node:assert`, no dependencies, Node >= 22.15). Reads from the same `src/content/spec/` source of truth at build time. Logs each call to the `MCP_LOG` Analytics Engine dataset (`sw_mcp_log`). |
| `public/search-overlay.js` | ⌘K overlay logic. CSP-safe (no inline JS). |
| `public/search-init.js` | `/search/` page Pagefind initialiser. CSP-safe. |
| `scripts/generate-assets.mjs` | Generates icons + OG image from inline SVGs via `sharp`. Wired through `prebuild`/`predev`. |
Expand All @@ -116,7 +116,9 @@ npm run assets # regenerate icons + OG image

`predev` and `prebuild` run `scripts/generate-assets.mjs` automatically.

**Pre-commit gate.** A tracked git hook at `.githooks/pre-commit` runs `npm run lint` and `npm run format:check` on every `git commit`; `core.hooksPath` is pointed at `.githooks/` by the `prepare` script on `npm install` (no husky). The same two checks run in CI (`ci.yml`). Run them before committing so the hook passes; `prettier --write .` fixes formatting. Bypass only in a genuine emergency with `git commit --no-verify`.
The Worker in `mcp/` has its own scripts, run from there: `npm test`, `npm run typecheck`, `npm run dev` (wrangler on 31338). On a fresh clone run `npm run build:data` first — `src/data.json` is generated, so `typecheck` fails with `TS2307` without it; `pretest` covers `npm test`. CI's `mcp` job runs the three in that order.

**Pre-commit gate.** A tracked git hook at `.githooks/pre-commit` runs `npm run lint` and `npm run format:check` on every `git commit`; `core.hooksPath` is pointed at `.githooks/` by the `prepare` script on `npm install` (no husky). The same two checks run in CI (`ci.yml`). Run them before committing so the hook passes; `prettier --write .` fixes formatting. Bypass only in a genuine emergency with `git commit --no-verify`. The Worker's assertions are deliberately **not** in the hook: `mcp/` has its own dependency tree that most contributors never install, and running them would rewrite the generated `mcp/src/data.json` on every unrelated commit. CI is the gate for that.

## Workflow when adding or changing a spec page

Expand Down Expand Up @@ -198,7 +200,7 @@ Like the changelog, this collection is **not derived** — nothing generates it.

## Deployment

- `main` → Cloudflare Pages, auto-deployed via the Pages dashboard's Git integration. No GitHub Actions deploy workflow (`ci.yml` only runs type-check + build verification).
- `main` → Cloudflare Pages, auto-deployed via the Pages dashboard's Git integration. No GitHub Actions deploy workflow (`ci.yml` verifies; it does not deploy).
- Custom domain for the site: `specification.website` (configure in the Cloudflare Pages dashboard).
- Functions live in `/functions/` and ship alongside static assets. The Cloudflare build picks them up automatically.
- The **MCP server** in `/mcp/` is a separate Cloudflare Worker. It registers `mcp.specification.website` as a custom domain on first deploy. It is **redeployed automatically** by the `Deploy MCP` GitHub Action whenever a push to `main` touches `src/content/spec/**`, `src/content/changelog/**`, or `mcp/**`, so its bundled data stays in sync (the predeploy hook regenerates `mcp/src/data.json`). The Action authenticates with the `CLOUDFLARE_API_TOKEN` repo secret (Workers Scripts: Edit). Manual fallback: `cd mcp && npm run deploy`.
Expand Down
23 changes: 23 additions & 0 deletions mcp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,29 @@ curl -sX POST http://localhost:31338/mcp \
| jq
```

## Tests

```bash
cd mcp
npm test # scripts/test-protocol.mjs
npm run typecheck
```

`scripts/test-protocol.mjs` drives the Worker's real fetch handler in-process
and asserts the two-era wire contract: the members revision 2026-07-28 requires
on every result, the cache hints only where that revision defines them, the
methods it removed, the transport rules, and that the handshake era keeps
answering. Same idiom as `scripts/test-websub.mjs` at the repo root — plain
node + `node:assert`, no framework, no dependency, no network.

Needs **Node >= 22.15**, above the root's declared `>= 22.12`: the sources are
TypeScript and `ts-resolve-hook.mjs` uses `node:module`'s `registerHooks`, added
in 22.15. Below that the run fails at link time naming the missing export.

`pretest` runs `build:data`, so a fresh clone needs nothing else. `typecheck`
has no such hook — run `npm run build:data` first, or `tsc` cannot resolve the
generated `src/data.json`.

## Deploy

First time:
Expand Down
2 changes: 2 additions & 0 deletions mcp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
"license": "MIT",
"scripts": {
"build:data": "node scripts/build-data.mjs",
"pretest": "npm run build:data",
"test": "node --experimental-strip-types --import ./ts-resolve-hook.mjs scripts/test-protocol.mjs",
"predev": "npm run build:data",
"dev": "wrangler dev --port 31338",
"predeploy": "npm run build:data",
Expand Down
Loading