Added
- Theme dev server — gains / /
actions. runs
automad-mcp-server@0.7.1 dev
tsx src/index.ts as a detached background process, writes
, and returns the local URL (port
discovered in this order: explicit arg →
( / ) → the first marker in the
log, up to 20 s). sends SIGTERM, escalates to SIGKILL after 5 s,
and removes the record. reports the running state without
blocking. A second call for the same theme returns until
is called. Live-verified end-to-end against
: the dev server's PHP+esbuild pipeline starts and
returns the expected content.
- Two new theme analyzer findings — (locale masks
declared in but no file on disk) and
(a page mask of the form whose
snippet doesn't exist). Both are severity , ordered alongside the
existing / checks. - KB pages split — (the bundled knowledge base) is now a
thin re-exporter over 13 per-page modules in . The split is
invisible at runtime but makes adding / auditing individual KB pages
tractable. A drift test pins order and shape. - GitHub Pages landing page — is now a self-contained
single-file landing page (no script, no remote stylesheet, no remote
image; pinned by ). The tool table is generated from
the capability registry via
automad-mcp-server@0.7.1 docs:sync
node --import tsx scripts/sync.ts
docs:sync: no change (tools table: already in sync; homepage table: already in sync; README.md: already in sync; CLAUDE.md: already in sync; index.html: already in sync), so it cannot drift from
the code. Counts (tool count, read/destructive, test count) are
fenced markers that regenerate alongside the README.
- **
=== build ===
automad-mcp-server@0.7.1 build
tsc
=== lint ===
automad-mcp-server@0.7.1 lint
eslint src tests
=== test ===
automad-mcp-server@0.7.1 test
vitest run
RUN v2.1.9 /Users/cabroe/Projects/automad-mcp-server
✓ tests/unit/theme-schema.test.ts (10 tests) 25ms
✓ tests/unit/theme-analyzer.test.ts (18 tests) 146ms
✓ tests/unit/auth.test.ts (15 tests) 222ms
✓ tests/unit/capabilities.test.ts (11 tests) 14ms
✓ tests/unit/domains/theme.test.ts (16 tests) 578ms
✓ handleTheme > build runs install + build (skipped if no package.json scripts) 444ms
✓ tests/unit/write-guard.test.ts (14 tests) 50ms
✓ tests/unit/server.test.ts (9 tests) 61ms
✓ tests/unit/docs-drift.test.ts (9 tests) 9ms
✓ tests/unit/drift.test.ts (11 tests) 20ms
✓ tests/unit/domains/site.test.ts (11 tests) 11ms
✓ tests/unit/theme-scaffold.test.ts (5 tests) 49ms
✓ tests/unit/schemas.test.ts (17 tests) 15ms
✓ tests/unit/theme-fs.test.ts (10 tests) 45ms
✓ tests/unit/config.test.ts (12 tests) 8ms
↓ tests/e2e/live.test.ts (4 tests | 4 skipped)
✓ tests/unit/domains/media.test.ts (7 tests) 13ms
✓ tests/unit/domains/discover.test.ts (9 tests) 9ms
✓ tests/unit/capabilities-tools.test.ts (6 tests) 11ms
✓ tests/unit/theme-editor.test.ts (6 tests) 58ms
✓ tests/unit/resources.test.ts (5 tests) 33ms
✓ tests/unit/docs-kb.test.ts (10 tests) 20ms
✓ tests/unit/domains/config.test.ts (4 tests) 13ms
✓ tests/unit/client.test.ts (59 tests) 3043ms
✓ HttpClient (v2 /_api) > CSRF-mismatch loop after session timeout -> force re-auth then surface AUTH 504ms
✓ HttpClient (v2 /_api) > CSRF-mismatch loop with dead session AND dead re-auth -> AUTH (not 403) 501ms
✓ tests/unit/theme-dev.test.ts (29 tests) 3032ms
✓ startDev > writes dev.json with the spawned pid and reports running:true 1005ms
✓ startDev > runs npm install only when node_modules is missing 502ms
✓ startDev > returns port:null after portTimeoutMs when no marker appears 503ms
✓ startDev > clears a stale dev.json (dead pid) and proceeds 1002ms
✓ tests/unit/theme/generate.test.ts (8 tests) 10ms
✓ tests/unit/domains/shared.test.ts (3 tests) 18ms
✓ tests/unit/domains/docs.test.ts (6 tests) 9ms
✓ tests/unit/errors.test.ts (6 tests) 9ms
✓ tests/unit/theme/diff.test.ts (4 tests) 5ms
✓ tests/unit/theme/manager.test.ts (3 tests) 7ms
✓ tests/unit/logger.test.ts (2 tests) 7ms
✓ tests/unit/domains/pages.test.ts (33 tests) 4048ms
✓ handlePages (v2 /_api) > get retries on 404 (v2 commit-lag) and eventually surfaces NOT_FOUND 3012ms
Test Files 31 passed | 1 skipped (32)
Tests 368 passed | 4 skipped (372)
Start at 19:14:01
Duration 4.99s (transform 861ms, setup 0ms, collect 2.62s, tests 11.60s, environment 9ms, prepare 2.58s)
=== test:coverage (thresholds gate) ===
automad-mcp-server@0.7.1 test:coverage
vitest run --coverage
RUN v2.1.9 /Users/cabroe/Projects/automad-mcp-server
Coverage enabled with v8
✓ tests/unit/theme-schema.test.ts (10 tests) 28ms
✓ tests/unit/theme-analyzer.test.ts (18 tests) 137ms
✓ tests/unit/auth.test.ts (15 tests) 223ms
✓ tests/unit/capabilities.test.ts (11 tests) 16ms
✓ tests/unit/domains/theme.test.ts (16 tests) 579ms
✓ handleTheme > build runs install + build (skipped if no package.json scripts) 442ms
✓ tests/unit/write-guard.test.ts (14 tests) 50ms
✓ tests/unit/server.test.ts (9 tests) 71ms
✓ tests/unit/docs-drift.test.ts (9 tests) 11ms
✓ tests/unit/drift.test.ts (11 tests) 22ms
✓ tests/unit/domains/site.test.ts (11 tests) 19ms
✓ tests/unit/theme-scaffold.test.ts (5 tests) 46ms
✓ tests/unit/schemas.test.ts (17 tests) 26ms
✓ tests/unit/theme-fs.test.ts (10 tests) 44ms
✓ tests/unit/config.test.ts (12 tests) 9ms
↓ tests/e2e/live.test.ts (4 tests | 4 skipped)
✓ tests/unit/domains/media.test.ts (7 tests) 13ms
✓ tests/unit/domains/discover.test.ts (9 tests) 13ms
✓ tests/unit/capabilities-tools.test.ts (6 tests) 14ms
✓ tests/unit/theme-editor.test.ts (6 tests) 87ms
✓ tests/unit/resources.test.ts (5 tests) 42ms
✓ tests/unit/theme-dev.test.ts (29 tests) 3040ms
✓ startDev > writes dev.json with the spawned pid and reports running:true 1006ms
✓ startDev > runs npm install only when node_modules is missing 502ms
✓ startDev > returns port:null after portTimeoutMs when no marker appears 501ms
✓ startDev > clears a stale dev.json (dead pid) and proceeds 1002ms
✓ tests/unit/client.test.ts (59 tests) 3045ms
✓ HttpClient (v2 /_api) > CSRF-mismatch loop after session timeout -> force re-auth then surface AUTH 501ms
✓ HttpClient (v2 /_api) > CSRF-mismatch loop with dead session AND dead re-auth -> AUTH (not 403) 503ms
✓ tests/unit/docs-kb.test.ts (10 tests) 39ms
✓ tests/unit/domains/config.test.ts (4 tests) 11ms
✓ tests/unit/theme/generate.test.ts (8 tests) 9ms
✓ tests/unit/theme/diff.test.ts (4 tests) 6ms
✓ tests/unit/domains/shared.test.ts (3 tests) 12ms
✓ tests/unit/domains/docs.test.ts (6 tests) 12ms
✓ tests/unit/errors.test.ts (6 tests) 19ms
✓ tests/unit/theme/manager.test.ts (3 tests) 16ms
✓ tests/unit/domains/pages.test.ts (33 tests) 4046ms
✓ handlePages (v2 /_api) > get retries on 404 (v2 commit-lag) and eventually surfaces NOT_FOUND 3008ms
✓ tests/unit/logger.test.ts (2 tests) 5ms
Test Files 31 passed | 1 skipped (32)
Tests 368 passed | 4 skipped (372)
Start at 19:14:07
Duration 5.52s (transform 735ms, setup 0ms, collect 2.79s, tests 11.71s, environment 12ms, prepare 3.80s)
% Coverage report from v8
-------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-------------------|---------|----------|---------|---------|-------------------
All files | 90.98 | 85.51 | 95.15 | 90.98 |
src | 88.63 | 84.7 | 97.56 | 88.63 |
auth.ts | 91.17 | 76.81 | 100 | 91.17 | ...85,217,219-223
client.ts | 96.16 | 88.99 | 92.3 | 96.16 | ...22,194,367-372
config.ts | 92.38 | 83.33 | 100 | 92.38 | 76-80,125,127-128
errors.ts | 100 | 87.5 | 100 | 100 | 33
logger.ts | 80 | 0 | 100 | 80 | 9-12
prompts.ts | 69.6 | 57.14 | 100 | 69.6 | ...,81-93,128-137
schemas.ts | 100 | 100 | 100 | 100 |
server.ts | 65.07 | 72.72 | 100 | 65.07 | ...43-150,158-169
write-guard.ts | 100 | 100 | 100 | 100 |
src/capabilities | 96.25 | 88.05 | 100 | 96.25 |
registry.ts | 99.1 | 90 | 100 | 99.1 | 297-298
tools.ts | 87.32 | 82.35 | 100 | 87.32 | ...09,118,140-141
src/docs | 100 | 83.33 | 100 | 100 |
kb.ts | 100 | 83.33 | 100 | 100 | 58,81-87
src/docs/kb/pages | 100 | 100 | 100 | 100 |
blocks.ts | 100 | 100 | 100 | 100 |
...n-pitfalls.ts | 100 | 100 | 100 | 100 |
...structures.ts | 100 | 100 | 100 | 100 |
...-functions.ts | 100 | 100 | 100 | 100 |
...ng-started.ts | 100 | 100 | 100 | 100 |
headless-api.ts | 100 | 100 | 100 | 100 |
i18n.ts | 100 | 100 | 100 | 100 |
...resolution.ts | 100 | 100 | 100 | 100 |
index.ts | 100 | 100 | 100 | 100 |
navigation.ts | 100 | 100 | 100 | 100 |
runtime-lang.ts | 100 | 100 | 100 | 100 |
...nheritance.ts | 100 | 100 | 100 | 100 |
...ate-syntax.ts | 100 | 100 | 100 | 100 |
theme-json.ts | 100 | 100 | 100 | 100 |
src/domains | 95.48 | 78.92 | 100 | 95.48 |
config.ts | 88.88 | 60 | 100 | 88.88 | 30-31,33-34
discover.ts | 100 | 90.47 | 100 | 100 | 35,63
docs.ts | 100 | 88.88 | 100 | 100 | 22
media.ts | 95.91 | 85.71 | 100 | 95.91 | 22-23
pages.ts | 95.88 | 85.57 | 100 | 95.88 | ...40,242,295-296
shared.ts | 85.71 | 66.66 | 100 | 85.71 | 21-22,24-25
site.ts | 100 | 73.07 | 100 | 100 | ...37,50,60-65,84
theme.ts | 93.63 | 65.38 | 100 | 93.63 | ...07-109,111-113
src/resources | 94.33 | 84 | 100 | 94.33 |
themes.ts | 94.33 | 84 | 100 | 94.33 | 64-66
src/theme | 88.65 | 88.76 | 91.56 | 88.65 |
analyzer.ts | 93.36 | 92.73 | 100 | 93.36 | ...05-209,475-482
build.ts | 70.58 | 81.81 | 60 | 70.58 | ...99-104,115-120
dev.ts | 83.17 | 81.33 | 76.92 | 83.17 | ...51,269-272,285
diff.ts | 100 | 94.87 | 100 | 100 | 20,84
editor.ts | 96.59 | 89.47 | 100 | 96.59 | 71-72,87
fs.ts | 98.43 | 91.17 | 100 | 98.43 | 71-72
generate.ts | 100 | 100 | 100 | 100 |
manager.ts | 54.79 | 48 | 77.77 | 54.79 | ...90,194,209-215
scaffold.ts | 91.37 | 87.5 | 100 | 91.37 | 56-60
schema.ts | 92.91 | 92.85 | 100 | 92.91 | ...71-277,309-311
slug.ts | 80 | 80 | 100 | 80 | 7-8
-------------------|---------|----------|---------|---------|-------------------
=== docs:sync --check ===
docs:sync --check: OK (tools table: already in sync; homepage table: already in sync; README.md: already in sync; CLAUDE.md: already in sync; index.html: already in sync)
verify: all gates passed.** — single-command pre-PR gate: runs
→ → → (with the
thresholds enforcing 80% stmt / 70% branch) →
. Fails fast on the first broken step.
- **** — end-to-end driver that spawns the built server
over stdio, runs → (polls until running) →
(HTTP 2xx/3xx) → . Lives in
automad-mcp-server@0.7.1 smoke
node --import tsx scripts/smoke.ts; no
live Automad instance required ( + a starter kit path
is enough).
- **** — Conventional-Commits validator. Lifecycle scripts included in automad-mcp-server@0.7.1:
start
node dist/index.js
test
vitest run
prepublishOnly
npm run build && npm test
available vianpm run:
build
tsc
dev
tsx src/index.ts
test:watch
vitest
test:coverage
vitest run --coverage
test:e2e
vitest run tests/e2e
lint
eslint src tests
format
prettier --write src tests
docs:sync
node --import tsx scripts/sync.ts
docs:sync:tests
node --import tsx scripts/sync.ts --tests
docs:sync:all
node --import tsx scripts/docs-sync-all.ts
verify
node --import tsx scripts/verify.ts
smoke
node --import tsx scripts/smoke.ts
commit:check
node --import tsx scripts/commit.ts --check
release:patch
node --import tsx scripts/release.ts patch --tag
release:minor
node --import tsx scripts/release.ts minor --tag
release:major
node --import tsx scripts/release.ts major --tag
release:full:patch
node --import tsx scripts/release.ts patch --release
release:full:minor
node --import tsx scripts/release.ts minor --release
release:full:major
node --import tsx scripts/release.ts major --release validates HEAD (for CI / pre-push); validates + commits. Type- and scope-allow-lists are a single
source of truth. - **
=== docs:sync ===
automad-mcp-server@0.7.1 docs:sync
node --import tsx scripts/sync.ts
docs:sync: no change (tools table: already in sync; homepage table: already in sync; README.md: already in sync; CLAUDE.md: already in sync; index.html: already in sync)
=== docs:sync:tests ===
automad-mcp-server@0.7.1 docs:sync:tests
node --import tsx scripts/sync.ts --tests
docs:sync: updated (tools table: already in sync; homepage table: already in sync; README.md: already in sync; CLAUDE.md: updated (TESTCOUNT); index.html: updated (TESTCOUNT))
docs:sync:all: done.** — one-shot: runs (static
markers) and (TESTCOUNT via vitest) back-to-back.
Available as
automad-mcp-server@0.7.1 docs:sync:all
node --import tsx scripts/docs-sync-all.ts
=== docs:sync ===
automad-mcp-server@0.7.1 docs:sync
node --import tsx scripts/sync.ts
docs:sync: no change (tools table: already in sync; homepage table: already in sync; README.md: already in sync; CLAUDE.md: already in sync; index.html: already in sync)
=== docs:sync:tests ===
automad-mcp-server@0.7.1 docs:sync:tests
node --import tsx scripts/sync.ts --tests
docs:sync: no change (tools table: already in sync; homepage table: already in sync; README.md: already in sync; CLAUDE.md: already in sync; index.html: already in sync)
docs:sync:all: done..
- branch=main clean=false kind=patch apply=true tag=false push=false release=false
bump: 0.7.1 -> 0.7.2 / flags — after tagging,
runs ; additionally runs
https://github.com/cabroe/automad-mcp-server/releases/tag/vX.Y.Z with the matching CHANGELOG section as the
release body (extracted via a new export).
Convenience scripts
automad-mcp-server@0.7.2 release:full:patch
node --import tsx scripts/release.ts patch --release release:full:minor release:full:major
branch=main clean=false kind=patch apply=true tag=true push=true release=true
https://github.com/cabroe/automad-mcp-server/releases/tag/v0.7.3
bump: 0.7.2 -> 0.7.3
tagged: v0.7.3
pushed: ok
released: ok
notes file: /var/folders/zl/kyj47ppj4gs9dz5zbx4kfkk00000gn/T/release-notes-64ZjGw/notes.md wrap
all three steps.
Changed
- ** now accepts a field as
(no )** — v2 splits on and appends , so
resolves to . Lets a page
bind to a theme that isn't the site default (the site default itself
is not exposed via the API; it is set in the dashboard). Documented
in JSDoc and in the README. - ** now verifies the starter-kit layout** before copying
(canonical layout: , , ,
, ). A stale or wrong starter-kit
directory now returns with a concrete missing-list
instead of silently producing a broken theme. - Knowledge-base size unchanged at runtime — splitting the KB into
per-page modules does not affect the embedded content; the public
surface (, ) is identical. - ThemeFs abstraction — interface gained
and with a
1 MiB cap and 256 KiB tail retention in the
implementation. The dev server uses these exclusively; no direct
calls in new code. - Documented the field's convention
in JSDoc and the README. A new README section ("Bind a
page to a specific theme/template") walks through it with a worked
example. - README + GitHub Pages homepage — both now describe the theme dev
server, the / / scripts, the
flow, and the page-template convention. The
homepage's "Theme tooling" card mentions the dev server; the tools
table shows / / for .
Fixed
- Two analyzer findings double-fired on generated output — both
and previously reported
against / directories that ship with the starter
kit. The scan is now scoped to and for the
relevant lookups and skips generated paths, so live reports contain
only findings the user can act on. - ** had a brittle fixture** — the test
referenced a field on the analyzer's output that the
code didn't actually return. Added the missing field to the
fixture literal so the test exercises the production
code path. - ** was dead code** — the file existed for an old
page-format reader, but nothing in the live HTTP path uses it. The
tests that referenced it still passed because they imported the
module directly. Removed the file; tests now use the real
v2 response path. No live consumer was affected. - ** was renamed to ** to
match the spec/plan wording and to avoid colliding with any future
"headless" UI module. Pure rename; no behavior change. - ** extraction off-by-one** —
originally searched the slice for the next header before
stripping the current one, so was always 0 and the function
returned a single newline. The function now strips the current
header first; returns the full section block up to the next
(or end of file).