emdash 0.39.0 → 0.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1650) hide show
  1. package/dist/action-token-DYwe4Pk0.mjs +26 -0
  2. package/dist/action-token-DYwe4Pk0.mjs.map +1 -0
  3. package/dist/activation-LOkDM5WT.mjs +382 -0
  4. package/dist/activation-LOkDM5WT.mjs.map +1 -0
  5. package/dist/adapters-B64LbYcB.d.mts +171 -0
  6. package/dist/adapters-B64LbYcB.d.mts.map +1 -0
  7. package/dist/allowed-origins-CHB8oZNM.mjs +116 -0
  8. package/dist/allowed-origins-CHB8oZNM.mjs.map +1 -0
  9. package/dist/api/route-utils.d.mts +4 -4
  10. package/dist/api/route-utils.mjs +49 -40
  11. package/dist/api/route-utils.mjs.map +1 -1
  12. package/dist/api/schemas/index.d.mts +2 -2
  13. package/dist/api/schemas/index.mjs +11 -7
  14. package/dist/api-cFFZpyS0.mjs +4718 -0
  15. package/dist/api-cFFZpyS0.mjs.map +1 -0
  16. package/dist/api-tokens-CE1ECIg0.mjs +3 -0
  17. package/dist/api-tokens-s4i4aUp_.mjs +166 -0
  18. package/dist/api-tokens-s4i4aUp_.mjs.map +1 -0
  19. package/dist/apply-CoT603H3.mjs +1163 -0
  20. package/dist/apply-CoT603H3.mjs.map +1 -0
  21. package/dist/approvals-CqMfNxak.mjs +460 -0
  22. package/dist/approvals-CqMfNxak.mjs.map +1 -0
  23. package/dist/artifact-fetch-DZMOGZ3-.mjs +818 -0
  24. package/dist/artifact-fetch-DZMOGZ3-.mjs.map +1 -0
  25. package/dist/astro/index.d.mts +14 -14
  26. package/dist/astro/index.mjs +62 -12
  27. package/dist/astro/index.mjs.map +1 -1
  28. package/dist/astro/middleware/auth.d.mts +14 -12
  29. package/dist/astro/middleware/auth.d.mts.map +1 -1
  30. package/dist/astro/middleware/auth.mjs +26 -11
  31. package/dist/astro/middleware/auth.mjs.map +1 -1
  32. package/dist/astro/middleware/media-usage-write-fence.d.mts +9 -1
  33. package/dist/astro/middleware/media-usage-write-fence.d.mts.map +1 -1
  34. package/dist/astro/middleware/media-usage-write-fence.mjs +95 -13
  35. package/dist/astro/middleware/media-usage-write-fence.mjs.map +1 -1
  36. package/dist/astro/middleware/redirect.mjs +8 -8
  37. package/dist/astro/middleware/request-context.d.mts.map +1 -1
  38. package/dist/astro/middleware/request-context.mjs +145 -47
  39. package/dist/astro/middleware/request-context.mjs.map +1 -1
  40. package/dist/astro/middleware/setup.mjs +1 -1
  41. package/dist/astro/middleware.d.mts +12 -12
  42. package/dist/astro/middleware.d.mts.map +1 -1
  43. package/dist/astro/middleware.mjs +129 -122
  44. package/dist/astro/middleware.mjs.map +1 -1
  45. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +14 -8
  46. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs.map +1 -1
  47. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +14 -8
  48. package/dist/astro/routes/api/admin/allowed-domains/index.mjs.map +1 -1
  49. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -3
  50. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs.map +1 -1
  51. package/dist/astro/routes/api/admin/api-tokens/index.mjs +6 -4
  52. package/dist/astro/routes/api/admin/api-tokens/index.mjs.map +1 -1
  53. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +6 -4
  54. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs.map +1 -1
  55. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +17 -11
  56. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs.map +1 -1
  57. package/dist/astro/routes/api/admin/byline-fields/index.mjs +17 -11
  58. package/dist/astro/routes/api/admin/byline-fields/index.mjs.map +1 -1
  59. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +17 -11
  60. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs.map +1 -1
  61. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +25 -19
  62. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
  63. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +25 -19
  64. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
  65. package/dist/astro/routes/api/admin/bylines/index.mjs +25 -19
  66. package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
  67. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +19 -13
  68. package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
  69. package/dist/astro/routes/api/admin/comments/_id_.mjs +7 -5
  70. package/dist/astro/routes/api/admin/comments/_id_.mjs.map +1 -1
  71. package/dist/astro/routes/api/admin/comments/bulk.mjs +18 -12
  72. package/dist/astro/routes/api/admin/comments/bulk.mjs.map +1 -1
  73. package/dist/astro/routes/api/admin/comments/counts.mjs +7 -5
  74. package/dist/astro/routes/api/admin/comments/counts.mjs.map +1 -1
  75. package/dist/astro/routes/api/admin/comments/index.mjs +18 -12
  76. package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
  77. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +6 -4
  78. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs.map +1 -1
  79. package/dist/astro/routes/api/admin/hooks/exclusive/index.d.mts.map +1 -1
  80. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +5 -6
  81. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs.map +1 -1
  82. package/dist/astro/routes/api/admin/media-usage/activation.mjs +21 -15
  83. package/dist/astro/routes/api/admin/media-usage/activation.mjs.map +1 -1
  84. package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs +23 -17
  85. package/dist/astro/routes/api/admin/media-usage/collection-deletions/index.mjs.map +1 -1
  86. package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs +23 -17
  87. package/dist/astro/routes/api/admin/media-usage/collection-deletions/retry.mjs.map +1 -1
  88. package/dist/astro/routes/api/admin/media-usage/progress.mjs +26 -15
  89. package/dist/astro/routes/api/admin/media-usage/progress.mjs.map +1 -1
  90. package/dist/astro/routes/api/admin/media-usage/repair.mjs +32 -19
  91. package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -1
  92. package/dist/astro/routes/api/admin/media-usage/work/index.mjs +23 -17
  93. package/dist/astro/routes/api/admin/media-usage/work/index.mjs.map +1 -1
  94. package/dist/astro/routes/api/admin/media-usage/work/retry.mjs +23 -17
  95. package/dist/astro/routes/api/admin/media-usage/work/retry.mjs.map +1 -1
  96. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -3
  97. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs.map +1 -1
  98. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -3
  99. package/dist/astro/routes/api/admin/oauth-clients/index.mjs.map +1 -1
  100. package/dist/astro/routes/api/admin/plugins/_id_/disable.d.mts.map +1 -1
  101. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +10 -8
  102. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
  103. package/dist/astro/routes/api/admin/plugins/_id_/enable.d.mts.map +1 -1
  104. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +10 -8
  105. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
  106. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +72 -61
  107. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  108. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +6 -4
  109. package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs.map +1 -1
  110. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +71 -60
  111. package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -1
  112. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.d.mts.map +1 -1
  113. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +74 -63
  114. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
  115. package/dist/astro/routes/api/admin/plugins/_id_/update.d.mts.map +1 -1
  116. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +84 -73
  117. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
  118. package/dist/astro/routes/api/admin/plugins/index.mjs +72 -61
  119. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  120. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +4 -2
  121. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs.map +1 -1
  122. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +71 -60
  123. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
  124. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.d.mts.map +1 -1
  125. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +83 -72
  126. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
  127. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +71 -60
  128. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
  129. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.d.mts.map +1 -1
  130. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +74 -63
  131. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
  132. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +85 -74
  133. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
  134. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +8 -6
  135. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
  136. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +76 -65
  137. package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
  138. package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.d.mts +8 -0
  139. package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.d.mts.map +1 -0
  140. package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.mjs +221 -0
  141. package/dist/astro/routes/api/admin/plugins/registry/publisher-handle.mjs.map +1 -0
  142. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs +72 -61
  143. package/dist/astro/routes/api/admin/plugins/registry/verify.mjs.map +1 -1
  144. package/dist/astro/routes/api/admin/plugins/updates.mjs +71 -60
  145. package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
  146. package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.mjs +6 -4
  147. package/dist/astro/routes/api/admin/scheduled-policy-rejections/_collection_/_id_.mjs.map +1 -1
  148. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +71 -60
  149. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
  150. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +4 -2
  151. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs.map +1 -1
  152. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +71 -60
  153. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
  154. package/dist/astro/routes/api/admin/transfer/_...path_.d.mts +12 -0
  155. package/dist/astro/routes/api/admin/transfer/_...path_.d.mts.map +1 -0
  156. package/dist/astro/routes/api/admin/transfer/_...path_.mjs +144 -0
  157. package/dist/astro/routes/api/admin/transfer/_...path_.mjs.map +1 -0
  158. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.d.mts +8 -0
  159. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.d.mts.map +1 -0
  160. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs +68 -0
  161. package/dist/astro/routes/api/admin/transfer/approvals/_id_/approve.mjs.map +1 -0
  162. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.d.mts +8 -0
  163. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.d.mts.map +1 -0
  164. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs +68 -0
  165. package/dist/astro/routes/api/admin/transfer/approvals/_id_/deny.mjs.map +1 -0
  166. package/dist/astro/routes/api/admin/transfer/approvals/index.d.mts +8 -0
  167. package/dist/astro/routes/api/admin/transfer/approvals/index.d.mts.map +1 -0
  168. package/dist/astro/routes/api/admin/transfer/approvals/index.mjs +67 -0
  169. package/dist/astro/routes/api/admin/transfer/approvals/index.mjs.map +1 -0
  170. package/dist/astro/routes/api/admin/transfer/capabilities.d.mts +8 -0
  171. package/dist/astro/routes/api/admin/transfer/capabilities.d.mts.map +1 -0
  172. package/dist/astro/routes/api/admin/transfer/capabilities.mjs +70 -0
  173. package/dist/astro/routes/api/admin/transfer/capabilities.mjs.map +1 -0
  174. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.d.mts +8 -0
  175. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.d.mts.map +1 -0
  176. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs +67 -0
  177. package/dist/astro/routes/api/admin/transfer/exports/_id_/advance.mjs.map +1 -0
  178. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.d.mts +8 -0
  179. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.d.mts.map +1 -0
  180. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs +70 -0
  181. package/dist/astro/routes/api/admin/transfer/exports/_id_/archive.mjs.map +1 -0
  182. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.d.mts +8 -0
  183. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.d.mts.map +1 -0
  184. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs +69 -0
  185. package/dist/astro/routes/api/admin/transfer/exports/_id_/files/_...path_.mjs.map +1 -0
  186. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.d.mts +8 -0
  187. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.d.mts.map +1 -0
  188. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs +66 -0
  189. package/dist/astro/routes/api/admin/transfer/exports/_id_/index.mjs.map +1 -0
  190. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.d.mts +8 -0
  191. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.d.mts.map +1 -0
  192. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs +69 -0
  193. package/dist/astro/routes/api/admin/transfer/exports/_id_/manifest.mjs.map +1 -0
  194. package/dist/astro/routes/api/admin/transfer/exports/index.d.mts +9 -0
  195. package/dist/astro/routes/api/admin/transfer/exports/index.d.mts.map +1 -0
  196. package/dist/astro/routes/api/admin/transfer/exports/index.mjs +91 -0
  197. package/dist/astro/routes/api/admin/transfer/exports/index.mjs.map +1 -0
  198. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.d.mts +8 -0
  199. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.d.mts.map +1 -0
  200. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs +66 -0
  201. package/dist/astro/routes/api/admin/transfer/imports/_id_/abandon.mjs.map +1 -0
  202. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.d.mts +8 -0
  203. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.d.mts.map +1 -0
  204. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs +70 -0
  205. package/dist/astro/routes/api/admin/transfer/imports/_id_/advance.mjs.map +1 -0
  206. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.d.mts +8 -0
  207. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.d.mts.map +1 -0
  208. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs +78 -0
  209. package/dist/astro/routes/api/admin/transfer/imports/_id_/analyze.mjs.map +1 -0
  210. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.d.mts +8 -0
  211. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.d.mts.map +1 -0
  212. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs +66 -0
  213. package/dist/astro/routes/api/admin/transfer/imports/_id_/cancel.mjs.map +1 -0
  214. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.d.mts +8 -0
  215. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.d.mts.map +1 -0
  216. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs +77 -0
  217. package/dist/astro/routes/api/admin/transfer/imports/_id_/execute.mjs.map +1 -0
  218. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.d.mts +8 -0
  219. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.d.mts.map +1 -0
  220. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs +77 -0
  221. package/dist/astro/routes/api/admin/transfer/imports/_id_/files/_...path_.mjs.map +1 -0
  222. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.d.mts +8 -0
  223. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.d.mts.map +1 -0
  224. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs +66 -0
  225. package/dist/astro/routes/api/admin/transfer/imports/_id_/index.mjs.map +1 -0
  226. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.d.mts +8 -0
  227. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.d.mts.map +1 -0
  228. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs +70 -0
  229. package/dist/astro/routes/api/admin/transfer/imports/_id_/missing.mjs.map +1 -0
  230. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.d.mts +8 -0
  231. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.d.mts.map +1 -0
  232. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs +67 -0
  233. package/dist/astro/routes/api/admin/transfer/imports/_id_/plan.mjs.map +1 -0
  234. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.d.mts +8 -0
  235. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.d.mts.map +1 -0
  236. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs +66 -0
  237. package/dist/astro/routes/api/admin/transfer/imports/_id_/receipt.mjs.map +1 -0
  238. package/dist/astro/routes/api/admin/transfer/imports/index.d.mts +9 -0
  239. package/dist/astro/routes/api/admin/transfer/imports/index.d.mts.map +1 -0
  240. package/dist/astro/routes/api/admin/transfer/imports/index.mjs +99 -0
  241. package/dist/astro/routes/api/admin/transfer/imports/index.mjs.map +1 -0
  242. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +3 -1
  243. package/dist/astro/routes/api/admin/users/_id_/disable.mjs.map +1 -1
  244. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +3 -1
  245. package/dist/astro/routes/api/admin/users/_id_/enable.mjs.map +1 -1
  246. package/dist/astro/routes/api/admin/users/_id_/index.mjs +14 -8
  247. package/dist/astro/routes/api/admin/users/_id_/index.mjs.map +1 -1
  248. package/dist/astro/routes/api/admin/users/_id_/send-recovery.d.mts.map +1 -1
  249. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +16 -6
  250. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs.map +1 -1
  251. package/dist/astro/routes/api/admin/users/index.mjs +14 -8
  252. package/dist/astro/routes/api/admin/users/index.mjs.map +1 -1
  253. package/dist/astro/routes/api/auth/dev-bypass.mjs +5 -3
  254. package/dist/astro/routes/api/auth/dev-bypass.mjs.map +1 -1
  255. package/dist/astro/routes/api/auth/invite/accept.mjs +3 -1
  256. package/dist/astro/routes/api/auth/invite/accept.mjs.map +1 -1
  257. package/dist/astro/routes/api/auth/invite/complete.mjs +19 -13
  258. package/dist/astro/routes/api/auth/invite/complete.mjs.map +1 -1
  259. package/dist/astro/routes/api/auth/invite/index.d.mts.map +1 -1
  260. package/dist/astro/routes/api/auth/invite/index.mjs +24 -12
  261. package/dist/astro/routes/api/auth/invite/index.mjs.map +1 -1
  262. package/dist/astro/routes/api/auth/invite/register-options.mjs +18 -12
  263. package/dist/astro/routes/api/auth/invite/register-options.mjs.map +1 -1
  264. package/dist/astro/routes/api/auth/logout.mjs +4 -2
  265. package/dist/astro/routes/api/auth/logout.mjs.map +1 -1
  266. package/dist/astro/routes/api/auth/magic-link/send.d.mts.map +1 -1
  267. package/dist/astro/routes/api/auth/magic-link/send.mjs +29 -15
  268. package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
  269. package/dist/astro/routes/api/auth/magic-link/verify.d.mts +2 -1
  270. package/dist/astro/routes/api/auth/magic-link/verify.d.mts.map +1 -1
  271. package/dist/astro/routes/api/auth/magic-link/verify.mjs +37 -17
  272. package/dist/astro/routes/api/auth/magic-link/verify.mjs.map +1 -1
  273. package/dist/astro/routes/api/auth/me.mjs +15 -9
  274. package/dist/astro/routes/api/auth/me.mjs.map +1 -1
  275. package/dist/astro/routes/api/auth/mode.mjs +4 -2
  276. package/dist/astro/routes/api/auth/mode.mjs.map +1 -1
  277. package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +4 -4
  278. package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
  279. package/dist/astro/routes/api/auth/passkey/_id_.mjs +14 -8
  280. package/dist/astro/routes/api/auth/passkey/_id_.mjs.map +1 -1
  281. package/dist/astro/routes/api/auth/passkey/index.mjs +3 -1
  282. package/dist/astro/routes/api/auth/passkey/index.mjs.map +1 -1
  283. package/dist/astro/routes/api/auth/passkey/options.d.mts.map +1 -1
  284. package/dist/astro/routes/api/auth/passkey/options.mjs +21 -24
  285. package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
  286. package/dist/astro/routes/api/auth/passkey/register/options.mjs +18 -12
  287. package/dist/astro/routes/api/auth/passkey/register/options.mjs.map +1 -1
  288. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +19 -13
  289. package/dist/astro/routes/api/auth/passkey/register/verify.mjs.map +1 -1
  290. package/dist/astro/routes/api/auth/passkey/verify.mjs +19 -13
  291. package/dist/astro/routes/api/auth/passkey/verify.mjs.map +1 -1
  292. package/dist/astro/routes/api/auth/signup/complete.mjs +19 -13
  293. package/dist/astro/routes/api/auth/signup/complete.mjs.map +1 -1
  294. package/dist/astro/routes/api/auth/signup/request.mjs +18 -12
  295. package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
  296. package/dist/astro/routes/api/auth/signup/verify.mjs +3 -1
  297. package/dist/astro/routes/api/auth/signup/verify.mjs.map +1 -1
  298. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +14 -11
  299. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
  300. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +21 -15
  301. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -1
  302. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +4 -2
  303. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs.map +1 -1
  304. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +18 -13
  305. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
  306. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +4 -3
  307. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs.map +1 -1
  308. package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs +18 -13
  309. package/dist/astro/routes/api/content/_collection_/_id_/lock.mjs.map +1 -1
  310. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +4 -2
  311. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs.map +1 -1
  312. package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs +10 -8
  313. package/dist/astro/routes/api/content/_collection_/_id_/plugin-extensions/_pluginId_/_kind_/_extensionId_.mjs.map +1 -1
  314. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.d.mts.map +1 -1
  315. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +68 -16
  316. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs.map +1 -1
  317. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +18 -13
  318. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
  319. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +31 -22
  320. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -1
  321. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +31 -22
  322. package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -1
  323. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +4 -3
  324. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs.map +1 -1
  325. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +4 -2
  326. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs.map +1 -1
  327. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +18 -13
  328. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
  329. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.d.mts.map +1 -1
  330. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +38 -19
  331. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
  332. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +4 -2
  333. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs.map +1 -1
  334. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +18 -13
  335. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
  336. package/dist/astro/routes/api/content/_collection_/_id_.mjs +18 -13
  337. package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
  338. package/dist/astro/routes/api/content/_collection_/authors.mjs +4 -2
  339. package/dist/astro/routes/api/content/_collection_/authors.mjs.map +1 -1
  340. package/dist/astro/routes/api/content/_collection_/index.mjs +15 -10
  341. package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
  342. package/dist/astro/routes/api/content/_collection_/trash.mjs +15 -9
  343. package/dist/astro/routes/api/content/_collection_/trash.mjs.map +1 -1
  344. package/dist/astro/routes/api/dashboard.mjs +11 -9
  345. package/dist/astro/routes/api/dashboard.mjs.map +1 -1
  346. package/dist/astro/routes/api/dev/emails.mjs +4 -2
  347. package/dist/astro/routes/api/dev/emails.mjs.map +1 -1
  348. package/dist/astro/routes/api/health.mjs +5 -3
  349. package/dist/astro/routes/api/health.mjs.map +1 -1
  350. package/dist/astro/routes/api/import/probe.d.mts +3 -3
  351. package/dist/astro/routes/api/import/probe.mjs +27 -21
  352. package/dist/astro/routes/api/import/probe.mjs.map +1 -1
  353. package/dist/astro/routes/api/import/wordpress/analyze.mjs +5 -3
  354. package/dist/astro/routes/api/import/wordpress/analyze.mjs.map +1 -1
  355. package/dist/astro/routes/api/import/wordpress/execute.d.mts +13 -13
  356. package/dist/astro/routes/api/import/wordpress/execute.mjs +18 -16
  357. package/dist/astro/routes/api/import/wordpress/execute.mjs.map +1 -1
  358. package/dist/astro/routes/api/import/wordpress/media.d.mts +12 -12
  359. package/dist/astro/routes/api/import/wordpress/media.mjs +19 -13
  360. package/dist/astro/routes/api/import/wordpress/media.mjs.map +1 -1
  361. package/dist/astro/routes/api/import/wordpress/prepare.mjs +18 -12
  362. package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
  363. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.d.mts +5 -1
  364. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.d.mts.map +1 -1
  365. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.mjs +4 -2
  366. package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.mjs.map +1 -1
  367. package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +13 -13
  368. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +29 -15
  369. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
  370. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  371. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +27 -21
  372. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
  373. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +13 -13
  374. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +38 -32
  375. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
  376. package/dist/astro/routes/api/manifest.mjs +6 -4
  377. package/dist/astro/routes/api/manifest.mjs.map +1 -1
  378. package/dist/astro/routes/api/mcp.d.mts.map +1 -1
  379. package/dist/astro/routes/api/mcp.mjs +717 -67
  380. package/dist/astro/routes/api/mcp.mjs.map +1 -1
  381. package/dist/astro/routes/api/media/_id_/confirm.mjs +19 -13
  382. package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
  383. package/dist/astro/routes/api/media/_id_/replace.mjs +16 -10
  384. package/dist/astro/routes/api/media/_id_/replace.mjs.map +1 -1
  385. package/dist/astro/routes/api/media/_id_/upload.mjs +8 -6
  386. package/dist/astro/routes/api/media/_id_/upload.mjs.map +1 -1
  387. package/dist/astro/routes/api/media/_id_/usage.mjs +34 -21
  388. package/dist/astro/routes/api/media/_id_/usage.mjs.map +1 -1
  389. package/dist/astro/routes/api/media/_id_.d.mts.map +1 -1
  390. package/dist/astro/routes/api/media/_id_.mjs +37 -26
  391. package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
  392. package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs +5 -3
  393. package/dist/astro/routes/api/media/asset/_id_/_filename_.mjs.map +1 -1
  394. package/dist/astro/routes/api/media/file/_...key_.d.mts.map +1 -1
  395. package/dist/astro/routes/api/media/file/_...key_.mjs +31 -2
  396. package/dist/astro/routes/api/media/file/_...key_.mjs.map +1 -1
  397. package/dist/astro/routes/api/media/folders/_id_.mjs +16 -10
  398. package/dist/astro/routes/api/media/folders/_id_.mjs.map +1 -1
  399. package/dist/astro/routes/api/media/folders/index.mjs +16 -10
  400. package/dist/astro/routes/api/media/folders/index.mjs.map +1 -1
  401. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -2
  402. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs.map +1 -1
  403. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -2
  404. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs.map +1 -1
  405. package/dist/astro/routes/api/media/providers/index.mjs +4 -2
  406. package/dist/astro/routes/api/media/providers/index.mjs.map +1 -1
  407. package/dist/astro/routes/api/media/upload-url.mjs +18 -12
  408. package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
  409. package/dist/astro/routes/api/media.mjs +36 -24
  410. package/dist/astro/routes/api/media.mjs.map +1 -1
  411. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +18 -12
  412. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
  413. package/dist/astro/routes/api/menus/_name_/items.mjs +18 -12
  414. package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
  415. package/dist/astro/routes/api/menus/_name_/reorder.mjs +18 -12
  416. package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
  417. package/dist/astro/routes/api/menus/_name_/translations.mjs +18 -12
  418. package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
  419. package/dist/astro/routes/api/menus/_name_.mjs +18 -12
  420. package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
  421. package/dist/astro/routes/api/menus/index.mjs +18 -12
  422. package/dist/astro/routes/api/menus/index.mjs.map +1 -1
  423. package/dist/astro/routes/api/oauth/authorize.d.mts.map +1 -1
  424. package/dist/astro/routes/api/oauth/authorize.mjs +9 -6
  425. package/dist/astro/routes/api/oauth/authorize.mjs.map +1 -1
  426. package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -5
  427. package/dist/astro/routes/api/oauth/device/authorize.mjs.map +1 -1
  428. package/dist/astro/routes/api/oauth/device/code.mjs +10 -8
  429. package/dist/astro/routes/api/oauth/device/code.mjs.map +1 -1
  430. package/dist/astro/routes/api/oauth/device/token.mjs +9 -7
  431. package/dist/astro/routes/api/oauth/device/token.mjs.map +1 -1
  432. package/dist/astro/routes/api/oauth/register.mjs +4 -2
  433. package/dist/astro/routes/api/oauth/register.mjs.map +1 -1
  434. package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -5
  435. package/dist/astro/routes/api/oauth/token/refresh.mjs.map +1 -1
  436. package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -5
  437. package/dist/astro/routes/api/oauth/token/revoke.mjs.map +1 -1
  438. package/dist/astro/routes/api/oauth/token.mjs +7 -5
  439. package/dist/astro/routes/api/oauth/token.mjs.map +1 -1
  440. package/dist/astro/routes/api/openapi.json.mjs +497 -12
  441. package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
  442. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +10 -8
  443. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs.map +1 -1
  444. package/dist/astro/routes/api/redirects/404s/index.mjs +21 -15
  445. package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
  446. package/dist/astro/routes/api/redirects/404s/summary.mjs +21 -15
  447. package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
  448. package/dist/astro/routes/api/redirects/_id_.mjs +21 -15
  449. package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
  450. package/dist/astro/routes/api/redirects/index.mjs +21 -15
  451. package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
  452. package/dist/astro/routes/api/relations/_id_/index.mjs +31 -22
  453. package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
  454. package/dist/astro/routes/api/relations/_id_/translations.mjs +21 -16
  455. package/dist/astro/routes/api/relations/_id_/translations.mjs.map +1 -1
  456. package/dist/astro/routes/api/relations/index.mjs +31 -22
  457. package/dist/astro/routes/api/relations/index.mjs.map +1 -1
  458. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -2
  459. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs.map +1 -1
  460. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +4 -3
  461. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs.map +1 -1
  462. package/dist/astro/routes/api/schema/block-types/_slug_/index.d.mts +9 -0
  463. package/dist/astro/routes/api/schema/block-types/_slug_/index.d.mts.map +1 -0
  464. package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs +102 -0
  465. package/dist/astro/routes/api/schema/block-types/_slug_/index.mjs.map +1 -0
  466. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.d.mts +8 -0
  467. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.d.mts.map +1 -0
  468. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs +96 -0
  469. package/dist/astro/routes/api/schema/block-types/_slug_/versions/_version_/activate.mjs.map +1 -0
  470. package/dist/astro/routes/api/schema/block-types/index.d.mts +9 -0
  471. package/dist/astro/routes/api/schema/block-types/index.d.mts.map +1 -0
  472. package/dist/astro/routes/api/schema/block-types/index.mjs +102 -0
  473. package/dist/astro/routes/api/schema/block-types/index.mjs.map +1 -0
  474. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +71 -60
  475. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
  476. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +71 -60
  477. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
  478. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +71 -60
  479. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
  480. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +71 -60
  481. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
  482. package/dist/astro/routes/api/schema/collections/index.mjs +71 -60
  483. package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
  484. package/dist/astro/routes/api/schema/collections/reorder.mjs +71 -60
  485. package/dist/astro/routes/api/schema/collections/reorder.mjs.map +1 -1
  486. package/dist/astro/routes/api/schema/index.mjs +17 -14
  487. package/dist/astro/routes/api/schema/index.mjs.map +1 -1
  488. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +71 -60
  489. package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
  490. package/dist/astro/routes/api/schema/orphans/index.mjs +71 -60
  491. package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
  492. package/dist/astro/routes/api/search/enable.mjs +20 -14
  493. package/dist/astro/routes/api/search/enable.mjs.map +1 -1
  494. package/dist/astro/routes/api/search/index.mjs +19 -13
  495. package/dist/astro/routes/api/search/index.mjs.map +1 -1
  496. package/dist/astro/routes/api/search/rebuild.mjs +20 -14
  497. package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
  498. package/dist/astro/routes/api/search/stats.mjs +10 -8
  499. package/dist/astro/routes/api/search/stats.mjs.map +1 -1
  500. package/dist/astro/routes/api/search/suggest.mjs +19 -13
  501. package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
  502. package/dist/astro/routes/api/sections/_slug_.mjs +19 -13
  503. package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
  504. package/dist/astro/routes/api/sections/index.mjs +19 -13
  505. package/dist/astro/routes/api/sections/index.mjs.map +1 -1
  506. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +8 -7
  507. package/dist/astro/routes/api/settings/backups/archives/_name_.mjs.map +1 -1
  508. package/dist/astro/routes/api/settings/backups/archives/index.mjs +8 -6
  509. package/dist/astro/routes/api/settings/backups/archives/index.mjs.map +1 -1
  510. package/dist/astro/routes/api/settings/backups/export.mjs +8 -7
  511. package/dist/astro/routes/api/settings/backups/export.mjs.map +1 -1
  512. package/dist/astro/routes/api/settings/backups/index.mjs +9 -8
  513. package/dist/astro/routes/api/settings/backups/index.mjs.map +1 -1
  514. package/dist/astro/routes/api/settings/email.mjs +6 -4
  515. package/dist/astro/routes/api/settings/email.mjs.map +1 -1
  516. package/dist/astro/routes/api/settings.mjs +25 -19
  517. package/dist/astro/routes/api/settings.mjs.map +1 -1
  518. package/dist/astro/routes/api/setup/admin-verify.mjs +20 -14
  519. package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
  520. package/dist/astro/routes/api/setup/admin.mjs +19 -13
  521. package/dist/astro/routes/api/setup/admin.mjs.map +1 -1
  522. package/dist/astro/routes/api/setup/dev-bypass.mjs +43 -37
  523. package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
  524. package/dist/astro/routes/api/setup/dev-reset.mjs +4 -2
  525. package/dist/astro/routes/api/setup/dev-reset.mjs.map +1 -1
  526. package/dist/astro/routes/api/setup/index.mjs +48 -38
  527. package/dist/astro/routes/api/setup/index.mjs.map +1 -1
  528. package/dist/astro/routes/api/setup/status.mjs +5 -3
  529. package/dist/astro/routes/api/setup/status.mjs.map +1 -1
  530. package/dist/astro/routes/api/snapshot.mjs +10 -8
  531. package/dist/astro/routes/api/snapshot.mjs.map +1 -1
  532. package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs +25 -19
  533. package/dist/astro/routes/api/taxonomies/_name_/reorder.mjs.map +1 -1
  534. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +25 -19
  535. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
  536. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +25 -19
  537. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
  538. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +25 -19
  539. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
  540. package/dist/astro/routes/api/taxonomies/_name_/translations.mjs +24 -18
  541. package/dist/astro/routes/api/taxonomies/_name_/translations.mjs.map +1 -1
  542. package/dist/astro/routes/api/taxonomies/_name_.mjs +25 -19
  543. package/dist/astro/routes/api/taxonomies/_name_.mjs.map +1 -1
  544. package/dist/astro/routes/api/taxonomies/bulk-tag.d.mts +8 -0
  545. package/dist/astro/routes/api/taxonomies/bulk-tag.d.mts.map +1 -0
  546. package/dist/astro/routes/api/taxonomies/bulk-tag.mjs +295 -0
  547. package/dist/astro/routes/api/taxonomies/bulk-tag.mjs.map +1 -0
  548. package/dist/astro/routes/api/taxonomies/index.mjs +25 -19
  549. package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
  550. package/dist/astro/routes/api/themes/preview.mjs +7 -5
  551. package/dist/astro/routes/api/themes/preview.mjs.map +1 -1
  552. package/dist/astro/routes/api/typegen.d.mts.map +1 -1
  553. package/dist/astro/routes/api/typegen.mjs +12 -9
  554. package/dist/astro/routes/api/typegen.mjs.map +1 -1
  555. package/dist/astro/routes/api/visual-editing/action-token.mjs +7 -5
  556. package/dist/astro/routes/api/visual-editing/action-token.mjs.map +1 -1
  557. package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs +22 -16
  558. package/dist/astro/routes/api/visual-editing/content/_collection_/_id_/publish.mjs.map +1 -1
  559. package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs +3 -1
  560. package/dist/astro/routes/api/visual-editing/toolbar-labels.mjs.map +1 -1
  561. package/dist/astro/routes/api/well-known/auth.mjs +2 -2
  562. package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +2 -2
  563. package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +2 -2
  564. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +16 -10
  565. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
  566. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +20 -14
  567. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
  568. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +20 -14
  569. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
  570. package/dist/astro/routes/api/widget-areas/_name_.mjs +10 -8
  571. package/dist/astro/routes/api/widget-areas/_name_.mjs.map +1 -1
  572. package/dist/astro/routes/api/widget-areas/index.mjs +20 -14
  573. package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
  574. package/dist/astro/routes/api/widget-components.mjs +4 -2
  575. package/dist/astro/routes/api/widget-components.mjs.map +1 -1
  576. package/dist/astro/routes/robots.txt.mjs +10 -10
  577. package/dist/astro/routes/sitemap-_collection_.xml.mjs +13 -13
  578. package/dist/astro/routes/sitemap.xml.mjs +11 -11
  579. package/dist/astro/types.d.mts +21 -17
  580. package/dist/astro/types.d.mts.map +1 -1
  581. package/dist/audit-RfCugiSB.mjs +127 -0
  582. package/dist/audit-RfCugiSB.mjs.map +1 -0
  583. package/dist/auth/providers/github.d.mts +1 -1
  584. package/dist/auth/providers/google.d.mts +1 -1
  585. package/dist/authoritative-records-CoJvBXAD.mjs +5172 -0
  586. package/dist/authoritative-records-CoJvBXAD.mjs.map +1 -0
  587. package/dist/authorize-seCifOMJ.mjs +49 -0
  588. package/dist/authorize-seCifOMJ.mjs.map +1 -0
  589. package/dist/backup-CBu0LrXf.mjs +246 -0
  590. package/dist/backup-CBu0LrXf.mjs.map +1 -0
  591. package/dist/block-type-registry-DUI_3KxT.mjs +6709 -0
  592. package/dist/block-type-registry-DUI_3KxT.mjs.map +1 -0
  593. package/dist/block-types-BmZmLmAD.mjs +132 -0
  594. package/dist/block-types-BmZmLmAD.mjs.map +1 -0
  595. package/dist/block-values-C_VIPr5t.mjs +175 -0
  596. package/dist/block-values-C_VIPr5t.mjs.map +1 -0
  597. package/dist/byline-DYmkXqvo.mjs +909 -0
  598. package/dist/byline-DYmkXqvo.mjs.map +1 -0
  599. package/dist/byline-fields-D28AT-Fh.mjs +123 -0
  600. package/dist/byline-fields-D28AT-Fh.mjs.map +1 -0
  601. package/dist/byline-registry-gnKscbQX.mjs +406 -0
  602. package/dist/byline-registry-gnKscbQX.mjs.map +1 -0
  603. package/dist/bylines-BPwJqoYH.mjs +232 -0
  604. package/dist/bylines-BPwJqoYH.mjs.map +1 -0
  605. package/dist/bylines-ukLaYpVZ.mjs +214 -0
  606. package/dist/bylines-ukLaYpVZ.mjs.map +1 -0
  607. package/dist/cache-m7UEkRFV.mjs +108 -0
  608. package/dist/cache-m7UEkRFV.mjs.map +1 -0
  609. package/dist/canonical-YhEQezjg.mjs +174 -0
  610. package/dist/canonical-YhEQezjg.mjs.map +1 -0
  611. package/dist/capture-triggers-kJyl_yyM.mjs +362 -0
  612. package/dist/capture-triggers-kJyl_yyM.mjs.map +1 -0
  613. package/dist/challenge-store-ppU6Uv13.mjs +51 -0
  614. package/dist/challenge-store-ppU6Uv13.mjs.map +1 -0
  615. package/dist/checksum-B2IINIlN.mjs +162 -0
  616. package/dist/checksum-B2IINIlN.mjs.map +1 -0
  617. package/dist/chrome-tags-DApCQSIk.mjs +24 -0
  618. package/dist/chrome-tags-DApCQSIk.mjs.map +1 -0
  619. package/dist/chunks-Dms7Uxbt.mjs +25 -0
  620. package/dist/chunks-Dms7Uxbt.mjs.map +1 -0
  621. package/dist/cli/index.mjs +1471 -56
  622. package/dist/cli/index.mjs.map +1 -1
  623. package/dist/client/cf-access.d.mts +1 -1
  624. package/dist/client/index.d.mts +1050 -4
  625. package/dist/client/index.d.mts.map +1 -1
  626. package/dist/client/index.mjs +193 -11
  627. package/dist/client/index.mjs.map +1 -1
  628. package/dist/collection-deletion-BIm28mo3.mjs +436 -0
  629. package/dist/collection-deletion-BIm28mo3.mjs.map +1 -0
  630. package/dist/collection-deletion-processor-Br6rxs3u.mjs +217 -0
  631. package/dist/collection-deletion-processor-Br6rxs3u.mjs.map +1 -0
  632. package/dist/collection-slugs-cache-CjGk__zp.mjs +85 -0
  633. package/dist/collection-slugs-cache-CjGk__zp.mjs.map +1 -0
  634. package/dist/comment-CrBl22OF.mjs +313 -0
  635. package/dist/comment-CrBl22OF.mjs.map +1 -0
  636. package/dist/comment-reaction-JEQ2Fpd8.mjs +85 -0
  637. package/dist/comment-reaction-JEQ2Fpd8.mjs.map +1 -0
  638. package/dist/comments-2ah9du9y.mjs +195 -0
  639. package/dist/comments-2ah9du9y.mjs.map +1 -0
  640. package/dist/comments-fHZ8ON9O.mjs +99 -0
  641. package/dist/comments-fHZ8ON9O.mjs.map +1 -0
  642. package/dist/components-CXbq7CSM.mjs +108 -0
  643. package/dist/components-CXbq7CSM.mjs.map +1 -0
  644. package/dist/config-5ii2haYu.d.mts +6528 -0
  645. package/dist/config-5ii2haYu.d.mts.map +1 -0
  646. package/dist/config-CvmjJcVw.mjs +73 -0
  647. package/dist/config-CvmjJcVw.mjs.map +1 -0
  648. package/dist/config-IhybvkIQ.mjs +242 -0
  649. package/dist/config-IhybvkIQ.mjs.map +1 -0
  650. package/dist/config-Py43JK9r.d.mts +39 -0
  651. package/dist/config-Py43JK9r.d.mts.map +1 -0
  652. package/dist/content-DFaIEDj9.mjs +2281 -0
  653. package/dist/content-DFaIEDj9.mjs.map +1 -0
  654. package/dist/content-list-query-Dra4Dalc.d.mts +26 -0
  655. package/dist/content-list-query-Dra4Dalc.d.mts.map +1 -0
  656. package/dist/content-policy-DFNw91-d.mjs +46 -0
  657. package/dist/content-policy-DFNw91-d.mjs.map +1 -0
  658. package/dist/content-repair-Q8IUrpLL.mjs +442 -0
  659. package/dist/content-repair-Q8IUrpLL.mjs.map +1 -0
  660. package/dist/context-BeGccdUX.mjs +1921 -0
  661. package/dist/context-BeGccdUX.mjs.map +1 -0
  662. package/dist/cron-7DCJwPXq.mjs +284 -0
  663. package/dist/cron-7DCJwPXq.mjs.map +1 -0
  664. package/dist/dashboard-DjrB-xxZ.mjs +151 -0
  665. package/dist/dashboard-DjrB-xxZ.mjs.map +1 -0
  666. package/dist/db/index.d.mts +3 -3
  667. package/dist/db/index.mjs +3 -3
  668. package/dist/db/libsql-migrations.d.mts +1 -1
  669. package/dist/db/libsql-migrations.mjs +6 -6
  670. package/dist/db/libsql.d.mts +1 -1
  671. package/dist/db/postgres-migrations.d.mts +1 -1
  672. package/dist/db/postgres-migrations.mjs +6 -6
  673. package/dist/db/postgres.d.mts +1 -1
  674. package/dist/db/sqlite-migrations.d.mts +1 -1
  675. package/dist/db/sqlite-migrations.mjs +6 -6
  676. package/dist/db/sqlite.d.mts +1 -1
  677. package/dist/db/sqlite.mjs +2 -2
  678. package/dist/db/sqlite.mjs.map +1 -1
  679. package/dist/default-DQ6vsviu.mjs +81 -0
  680. package/dist/default-DQ6vsviu.mjs.map +1 -0
  681. package/dist/deferred-tasks-BPxXUB4x.d.mts +9 -0
  682. package/dist/deferred-tasks-BPxXUB4x.d.mts.map +1 -0
  683. package/dist/device-flow-CRd6DXmW.mjs +466 -0
  684. package/dist/device-flow-CRd6DXmW.mjs.map +1 -0
  685. package/dist/dialect-helpers-7_IqPdh9.mjs +307 -0
  686. package/dist/dialect-helpers-7_IqPdh9.mjs.map +1 -0
  687. package/dist/digest-BarSh-pN.mjs +194 -0
  688. package/dist/digest-BarSh-pN.mjs.map +1 -0
  689. package/dist/direct-executor-BmuFJJZV.mjs +104 -0
  690. package/dist/direct-executor-BmuFJJZV.mjs.map +1 -0
  691. package/dist/dist-BNwANFJR.mjs +810 -0
  692. package/dist/dist-BNwANFJR.mjs.map +1 -0
  693. package/dist/email-console-bJn3ctqA.mjs +50 -0
  694. package/dist/email-console-bJn3ctqA.mjs.map +1 -0
  695. package/dist/email-locale-CN6WAMx0.mjs +25 -0
  696. package/dist/email-locale-CN6WAMx0.mjs.map +1 -0
  697. package/dist/emdash-runtime-DAjghyEG.mjs +4186 -0
  698. package/dist/emdash-runtime-DAjghyEG.mjs.map +1 -0
  699. package/dist/enrich-Dl3kZ-lP.mjs +194 -0
  700. package/dist/enrich-Dl3kZ-lP.mjs.map +1 -0
  701. package/dist/entry-lock-BJYdBfXb.mjs +1097 -0
  702. package/dist/entry-lock-BJYdBfXb.mjs.map +1 -0
  703. package/dist/entry-lock-DHQOxN7R.mjs +163 -0
  704. package/dist/entry-lock-DHQOxN7R.mjs.map +1 -0
  705. package/dist/entry-lock-DVhCt49A.d.mts +4368 -0
  706. package/dist/entry-lock-DVhCt49A.d.mts.map +1 -0
  707. package/dist/entry-locks-D0foLdjQ.mjs +167 -0
  708. package/dist/entry-locks-D0foLdjQ.mjs.map +1 -0
  709. package/dist/error-CfvOHP0M.mjs +90 -0
  710. package/dist/error-CfvOHP0M.mjs.map +1 -0
  711. package/dist/errors-BF0_LFhW.mjs +460 -0
  712. package/dist/errors-BF0_LFhW.mjs.map +1 -0
  713. package/dist/errors-DgE1zJGG.mjs +120 -0
  714. package/dist/errors-DgE1zJGG.mjs.map +1 -0
  715. package/dist/escape-CuaZhZvL.mjs +9 -0
  716. package/dist/escape-CuaZhZvL.mjs.map +1 -0
  717. package/dist/fence-CMDXJYc_.mjs +162 -0
  718. package/dist/fence-CMDXJYc_.mjs.map +1 -0
  719. package/dist/field-defs-cache-HIgBbqZZ.mjs +77 -0
  720. package/dist/field-defs-cache-HIgBbqZZ.mjs.map +1 -0
  721. package/dist/fts-manager-S-K0laoS.mjs +443 -0
  722. package/dist/fts-manager-S-K0laoS.mjs.map +1 -0
  723. package/dist/gc-DjKY0Ay1.mjs +75 -0
  724. package/dist/gc-DjKY0Ay1.mjs.map +1 -0
  725. package/dist/hash-SDAW6zC-.mjs +37 -0
  726. package/dist/hash-SDAW6zC-.mjs.map +1 -0
  727. package/dist/hook-result-B5bXDgS2.d.mts +31 -0
  728. package/dist/hook-result-B5bXDgS2.d.mts.map +1 -0
  729. package/dist/hreflang-D5uNnsGJ.d.mts +50 -0
  730. package/dist/hreflang-D5uNnsGJ.d.mts.map +1 -0
  731. package/dist/hreflang-DMFBL2eb.mjs +105 -0
  732. package/dist/hreflang-DMFBL2eb.mjs.map +1 -0
  733. package/dist/http-route-dispatch-BitqzwMy.mjs +339 -0
  734. package/dist/http-route-dispatch-BitqzwMy.mjs.map +1 -0
  735. package/dist/identity-IyNWwXr6.mjs +35 -0
  736. package/dist/identity-IyNWwXr6.mjs.map +1 -0
  737. package/dist/import-C3JZplWq.mjs +2020 -0
  738. package/dist/import-C3JZplWq.mjs.map +1 -0
  739. package/dist/index-D-hdtLe8.d.mts +623 -0
  740. package/dist/index-D-hdtLe8.d.mts.map +1 -0
  741. package/dist/index.d.mts +24 -24
  742. package/dist/index.mjs +105 -93
  743. package/dist/install-finalization-DfM1fj5x.mjs +58 -0
  744. package/dist/install-finalization-DfM1fj5x.mjs.map +1 -0
  745. package/dist/keys-yxLm5l35.mjs +61 -0
  746. package/dist/keys-yxLm5l35.mjs.map +1 -0
  747. package/dist/kinds-CRu_T5T5.mjs +961 -0
  748. package/dist/kinds-CRu_T5T5.mjs.map +1 -0
  749. package/dist/lifecycle-BzeGPeQ-.mjs +25 -0
  750. package/dist/lifecycle-BzeGPeQ-.mjs.map +1 -0
  751. package/dist/load-XgJiE6_3.mjs +28 -0
  752. package/dist/load-XgJiE6_3.mjs.map +1 -0
  753. package/dist/loader-BzqeR1ZN.mjs +1086 -0
  754. package/dist/loader-BzqeR1ZN.mjs.map +1 -0
  755. package/dist/loops-BQSzv5Zn.mjs +203 -0
  756. package/dist/loops-BQSzv5Zn.mjs.map +1 -0
  757. package/dist/manifest-builder-B8zR-73J.mjs +189 -0
  758. package/dist/manifest-builder-B8zR-73J.mjs.map +1 -0
  759. package/dist/manifest-schema-CY3zng_M.mjs +492 -0
  760. package/dist/manifest-schema-CY3zng_M.mjs.map +1 -0
  761. package/dist/media/image-endpoint.mjs +1 -1
  762. package/dist/media/index.d.mts +1 -1
  763. package/dist/media/index.mjs +3 -3
  764. package/dist/media/local-runtime.d.mts +14 -14
  765. package/dist/media/local-runtime.d.mts.map +1 -1
  766. package/dist/media/local-runtime.mjs +15 -16
  767. package/dist/media/local-runtime.mjs.map +1 -1
  768. package/dist/media-Pu1L6xir.mjs +408 -0
  769. package/dist/media-Pu1L6xir.mjs.map +1 -0
  770. package/dist/media-Qp5S3eH3.mjs +355 -0
  771. package/dist/media-Qp5S3eH3.mjs.map +1 -0
  772. package/dist/media-allowlist-BSoa9Vvm.mjs +44 -0
  773. package/dist/media-allowlist-BSoa9Vvm.mjs.map +1 -0
  774. package/dist/media-folders-BE0oo2eX.mjs +210 -0
  775. package/dist/media-folders-BE0oo2eX.mjs.map +1 -0
  776. package/dist/media-h7tOiDLj.mjs +221 -0
  777. package/dist/media-h7tOiDLj.mjs.map +1 -0
  778. package/dist/media-url-jArBpzIG.mjs +43 -0
  779. package/dist/media-url-jArBpzIG.mjs.map +1 -0
  780. package/dist/media-usage-My-Vi-ex.mjs +1629 -0
  781. package/dist/media-usage-My-Vi-ex.mjs.map +1 -0
  782. package/dist/media-usage-activation-HKp7zk7W.mjs +78 -0
  783. package/dist/media-usage-activation-HKp7zk7W.mjs.map +1 -0
  784. package/dist/media-usage-work-C2OZLCAd.mjs +586 -0
  785. package/dist/media-usage-work-C2OZLCAd.mjs.map +1 -0
  786. package/dist/media-usage-work-DwUNbgvS.mjs +152 -0
  787. package/dist/media-usage-work-DwUNbgvS.mjs.map +1 -0
  788. package/dist/menus-BM7BPLOb.mjs +139 -0
  789. package/dist/menus-BM7BPLOb.mjs.map +1 -0
  790. package/dist/menus-ITeAbcIF.mjs +753 -0
  791. package/dist/menus-ITeAbcIF.mjs.map +1 -0
  792. package/dist/menus-TsSGmSR4.mjs +3608 -0
  793. package/dist/menus-TsSGmSR4.mjs.map +1 -0
  794. package/dist/migrations/index.d.mts +1 -1
  795. package/dist/migrations/index.mjs +5 -5
  796. package/dist/mime-ChLqYwDk.mjs +36 -0
  797. package/dist/mime-ChLqYwDk.mjs.map +1 -0
  798. package/dist/mode-CCuKXUci.mjs +23 -0
  799. package/dist/mode-CCuKXUci.mjs.map +1 -0
  800. package/dist/node-sqlite-compat-CONMsl-x.mjs +46 -0
  801. package/dist/node-sqlite-compat-CONMsl-x.mjs.map +1 -0
  802. package/dist/normalize-CO2P8-iE.mjs +191 -0
  803. package/dist/normalize-CO2P8-iE.mjs.map +1 -0
  804. package/dist/oauth-authorization-DlMIL5_h.mjs +274 -0
  805. package/dist/oauth-authorization-DlMIL5_h.mjs.map +1 -0
  806. package/dist/oauth-clients-Djq9r_KP.mjs +266 -0
  807. package/dist/oauth-clients-Djq9r_KP.mjs.map +1 -0
  808. package/dist/oauth-state-store-BbjnZXNC.mjs +50 -0
  809. package/dist/oauth-state-store-BbjnZXNC.mjs.map +1 -0
  810. package/dist/oauth-user-lookup-vue9a64A.mjs +26 -0
  811. package/dist/oauth-user-lookup-vue9a64A.mjs.map +1 -0
  812. package/dist/object-cache/memory.d.mts +1 -1
  813. package/dist/object-cache-CqWNY5uP.mjs +582 -0
  814. package/dist/object-cache-CqWNY5uP.mjs.map +1 -0
  815. package/dist/options-DhrI7eMv.mjs +208 -0
  816. package/dist/options-DhrI7eMv.mjs.map +1 -0
  817. package/dist/options-SQCHQCPH.d.mts +81 -0
  818. package/dist/options-SQCHQCPH.d.mts.map +1 -0
  819. package/dist/page/index.d.mts +2 -2
  820. package/dist/page/index.mjs +9 -9
  821. package/dist/parse-CVgO-Qai.d.mts +168 -0
  822. package/dist/parse-CVgO-Qai.d.mts.map +1 -0
  823. package/dist/parse-DY6OD1j_.mjs +81 -0
  824. package/dist/parse-DY6OD1j_.mjs.map +1 -0
  825. package/dist/passkey-config-X_H8128a.mjs +46 -0
  826. package/dist/passkey-config-X_H8128a.mjs.map +1 -0
  827. package/dist/paths-JxokKIbr.mjs +77 -0
  828. package/dist/paths-JxokKIbr.mjs.map +1 -0
  829. package/dist/patterns-BhAvqO0S.mjs +145 -0
  830. package/dist/patterns-BhAvqO0S.mjs.map +1 -0
  831. package/dist/placeholder-MSEd8gty.d.mts +306 -0
  832. package/dist/placeholder-MSEd8gty.d.mts.map +1 -0
  833. package/dist/plan-xjcWrAah.mjs +135 -0
  834. package/dist/plan-xjcWrAah.mjs.map +1 -0
  835. package/dist/plugin-test-runtime.d.mts +38 -15
  836. package/dist/plugin-test-runtime.d.mts.map +1 -1
  837. package/dist/plugin-test-runtime.mjs +112 -99
  838. package/dist/plugin-types.d.mts +2 -2
  839. package/dist/plugin-utils.d.mts +12 -12
  840. package/dist/plugins/adapt-sandbox-entry.d.mts +12 -12
  841. package/dist/plugins/adapt-sandbox-entry.mjs +3 -3
  842. package/dist/plugins/host.d.mts +5 -5
  843. package/dist/plugins/host.mjs +45 -37
  844. package/dist/plugins-DUXUt8B9.mjs +277 -0
  845. package/dist/plugins-DUXUt8B9.mjs.map +1 -0
  846. package/dist/policy-CUvwAARc.mjs +45 -0
  847. package/dist/policy-CUvwAARc.mjs.map +1 -0
  848. package/dist/portable-text-5O_ZGUjB.mjs +307 -0
  849. package/dist/portable-text-5O_ZGUjB.mjs.map +1 -0
  850. package/dist/preview-CIUcPYr6.mjs +107 -0
  851. package/dist/preview-CIUcPYr6.mjs.map +1 -0
  852. package/dist/protocol-B97DZaFr.d.mts +61 -0
  853. package/dist/protocol-B97DZaFr.d.mts.map +1 -0
  854. package/dist/public-submission-BFBUrqst.mjs +250 -0
  855. package/dist/public-submission-BFBUrqst.mjs.map +1 -0
  856. package/dist/public-url-Bn7U0D7-.mjs +101 -0
  857. package/dist/public-url-Bn7U0D7-.mjs.map +1 -0
  858. package/dist/query-B48peoRT.mjs +890 -0
  859. package/dist/query-B48peoRT.mjs.map +1 -0
  860. package/dist/query-C4IH0uhR.mjs +41 -0
  861. package/dist/query-C4IH0uhR.mjs.map +1 -0
  862. package/dist/rate-limit-BZ6nybgc.mjs +120 -0
  863. package/dist/rate-limit-BZ6nybgc.mjs.map +1 -0
  864. package/dist/receipt-B4wJj5Jq.mjs +43 -0
  865. package/dist/receipt-B4wJj5Jq.mjs.map +1 -0
  866. package/dist/redirect-Cd1E7VUt.mjs +17 -0
  867. package/dist/redirect-Cd1E7VUt.mjs.map +1 -0
  868. package/dist/redirect-iJf5fltD.mjs +415 -0
  869. package/dist/redirect-iJf5fltD.mjs.map +1 -0
  870. package/dist/redirects-CYu1u1aK.mjs +446 -0
  871. package/dist/redirects-CYu1u1aK.mjs.map +1 -0
  872. package/dist/redirects-Cv9apQKj.mjs +148 -0
  873. package/dist/redirects-Cv9apQKj.mjs.map +1 -0
  874. package/dist/registry/testing.mjs +3 -3
  875. package/dist/relation-M4NUCb0b.mjs +334 -0
  876. package/dist/relation-M4NUCb0b.mjs.map +1 -0
  877. package/dist/relations-CCif47Oq.mjs +403 -0
  878. package/dist/relations-CCif47Oq.mjs.map +1 -0
  879. package/dist/relations-CK9CYUyr.mjs +310 -0
  880. package/dist/relations-CK9CYUyr.mjs.map +1 -0
  881. package/dist/request-cache-DzLYKm_x.mjs +104 -0
  882. package/dist/request-cache-DzLYKm_x.mjs.map +1 -0
  883. package/dist/request-context.d.mts +1 -1
  884. package/dist/request-meta-sZXt3sRo.mjs +141 -0
  885. package/dist/request-meta-sZXt3sRo.mjs.map +1 -0
  886. package/dist/resolve-2WbQsCvT.mjs +199 -0
  887. package/dist/resolve-2WbQsCvT.mjs.map +1 -0
  888. package/dist/route-wire--1hLuACz.mjs +197 -0
  889. package/dist/route-wire--1hLuACz.mjs.map +1 -0
  890. package/dist/routes-CUsM40Cc.mjs +272 -0
  891. package/dist/routes-CUsM40Cc.mjs.map +1 -0
  892. package/dist/runner-1y4J9fJB.mjs +5742 -0
  893. package/dist/runner-1y4J9fJB.mjs.map +1 -0
  894. package/dist/runner-D5_LzKXI.d.mts +68 -0
  895. package/dist/runner-D5_LzKXI.d.mts.map +1 -0
  896. package/dist/runtime.d.mts +13 -13
  897. package/dist/runtime.mjs +4 -4
  898. package/dist/schema-BABiRdsH.mjs +13 -0
  899. package/dist/schema-BABiRdsH.mjs.map +1 -0
  900. package/dist/schema-Du3MzCG0.mjs +446 -0
  901. package/dist/schema-Du3MzCG0.mjs.map +1 -0
  902. package/dist/scopes-Dbk-ElhT.mjs +34 -0
  903. package/dist/scopes-Dbk-ElhT.mjs.map +1 -0
  904. package/dist/search-Bt1PL1jf.mjs +448 -0
  905. package/dist/search-Bt1PL1jf.mjs.map +1 -0
  906. package/dist/secrets-CIi0nFiR.mjs +341 -0
  907. package/dist/secrets-CIi0nFiR.mjs.map +1 -0
  908. package/dist/sections-Ddptx_o9.mjs +346 -0
  909. package/dist/sections-Ddptx_o9.mjs.map +1 -0
  910. package/dist/seed/index.d.mts +2 -2
  911. package/dist/seed/index.mjs +35 -30
  912. package/dist/seo/index.d.mts +3 -3
  913. package/dist/seo/index.mjs +25 -21
  914. package/dist/seo/index.mjs.map +1 -1
  915. package/dist/seo-CZT2oLtT.mjs +114 -0
  916. package/dist/seo-CZT2oLtT.mjs.map +1 -0
  917. package/dist/seo-D5w3-Azy.mjs +133 -0
  918. package/dist/seo-D5w3-Azy.mjs.map +1 -0
  919. package/dist/service-DuykXPyW.mjs +150 -0
  920. package/dist/service-DuykXPyW.mjs.map +1 -0
  921. package/dist/session-user-BhaVp8w0.mjs +51 -0
  922. package/dist/session-user-BhaVp8w0.mjs.map +1 -0
  923. package/dist/settings-2xNYr90o.mjs +51 -0
  924. package/dist/settings-2xNYr90o.mjs.map +1 -0
  925. package/dist/settings-CgjRWGW9.mjs +439 -0
  926. package/dist/settings-CgjRWGW9.mjs.map +1 -0
  927. package/dist/settings-DYidIB26.mjs +61 -0
  928. package/dist/settings-DYidIB26.mjs.map +1 -0
  929. package/dist/setup-complete-bOogcHWG.mjs +26 -0
  930. package/dist/setup-complete-bOogcHWG.mjs.map +1 -0
  931. package/dist/setup-nonce-0EGuKM4s.mjs +25 -0
  932. package/dist/setup-nonce-0EGuKM4s.mjs.map +1 -0
  933. package/dist/site-settings-DOgRUoFX.mjs +50 -0
  934. package/dist/site-settings-DOgRUoFX.mjs.map +1 -0
  935. package/dist/site-url-BU_bbxwj.mjs +16 -0
  936. package/dist/site-url-BU_bbxwj.mjs.map +1 -0
  937. package/dist/snapshot-CugwUqKQ.mjs +237 -0
  938. package/dist/snapshot-CugwUqKQ.mjs.map +1 -0
  939. package/dist/ssrf-CJUnJymJ.mjs +406 -0
  940. package/dist/ssrf-CJUnJymJ.mjs.map +1 -0
  941. package/dist/stage-DgrBz_du.mjs +662 -0
  942. package/dist/stage-DgrBz_du.mjs.map +1 -0
  943. package/dist/state-DDiPySSG.mjs +153 -0
  944. package/dist/state-DDiPySSG.mjs.map +1 -0
  945. package/dist/status-DZKIG4a9.mjs +30 -0
  946. package/dist/status-DZKIG4a9.mjs.map +1 -0
  947. package/dist/storage/local.d.mts +1 -1
  948. package/dist/storage/local.mjs +1 -1
  949. package/dist/storage/s3.d.mts +1 -1
  950. package/dist/storage/s3.mjs +1 -1
  951. package/dist/storage-query-Bdv7A62k.d.mts +1576 -0
  952. package/dist/storage-query-Bdv7A62k.d.mts.map +1 -0
  953. package/dist/tar-_1AgTYFu.mjs +449 -0
  954. package/dist/tar-_1AgTYFu.mjs.map +1 -0
  955. package/dist/target-_7pn2Gbg.mjs +27 -0
  956. package/dist/target-_7pn2Gbg.mjs.map +1 -0
  957. package/dist/taxonomies-C1IwNe8Q.mjs +697 -0
  958. package/dist/taxonomies-C1IwNe8Q.mjs.map +1 -0
  959. package/dist/taxonomies-C_XMoRcX.mjs +939 -0
  960. package/dist/taxonomies-C_XMoRcX.mjs.map +1 -0
  961. package/dist/taxonomy-C3Fu1YeH.mjs +525 -0
  962. package/dist/taxonomy-C3Fu1YeH.mjs.map +1 -0
  963. package/dist/tokens-u78jETkX.mjs +171 -0
  964. package/dist/tokens-u78jETkX.mjs.map +1 -0
  965. package/dist/transfer-BhUCrgDc.mjs +8675 -0
  966. package/dist/transfer-BhUCrgDc.mjs.map +1 -0
  967. package/dist/transfer-DIGvR9Af.mjs +166 -0
  968. package/dist/transfer-DIGvR9Af.mjs.map +1 -0
  969. package/dist/transfer-download-Pml7RMio.mjs +33 -0
  970. package/dist/transfer-download-Pml7RMio.mjs.map +1 -0
  971. package/dist/transformations-9gfpwY65.mjs +196 -0
  972. package/dist/transformations-9gfpwY65.mjs.map +1 -0
  973. package/dist/transport-BIfH7_hx.d.mts +42 -0
  974. package/dist/transport-BIfH7_hx.d.mts.map +1 -0
  975. package/dist/transport-DKWIq53q.mjs +136 -0
  976. package/dist/transport-DKWIq53q.mjs.map +1 -0
  977. package/dist/trusted-proxy-tKiVtyTD.mjs +51 -0
  978. package/dist/trusted-proxy-tKiVtyTD.mjs.map +1 -0
  979. package/dist/turnstile-DpsoyOfg.mjs +53 -0
  980. package/dist/turnstile-DpsoyOfg.mjs.map +1 -0
  981. package/dist/types-B4sUC2p1.d.mts +198 -0
  982. package/dist/types-B4sUC2p1.d.mts.map +1 -0
  983. package/dist/types-B7Lmsh1E.d.mts +887 -0
  984. package/dist/types-B7Lmsh1E.d.mts.map +1 -0
  985. package/dist/types-BZakh7Ym.mjs +22 -0
  986. package/dist/types-BZakh7Ym.mjs.map +1 -0
  987. package/dist/types-B_CppEmv.d.mts +264 -0
  988. package/dist/types-B_CppEmv.d.mts.map +1 -0
  989. package/dist/types-BcrBrE6-.mjs +159 -0
  990. package/dist/types-BcrBrE6-.mjs.map +1 -0
  991. package/dist/types-CAZgq9fO.d.mts +124 -0
  992. package/dist/types-CAZgq9fO.d.mts.map +1 -0
  993. package/dist/types-Cd-O03VG.d.mts +363 -0
  994. package/dist/types-Cd-O03VG.d.mts.map +1 -0
  995. package/dist/types-Cr-Kg-3D.d.mts +1641 -0
  996. package/dist/types-Cr-Kg-3D.d.mts.map +1 -0
  997. package/dist/types-D2fvWd1i.d.mts +359 -0
  998. package/dist/types-D2fvWd1i.d.mts.map +1 -0
  999. package/dist/types-D7HUsguf.mjs +77 -0
  1000. package/dist/types-D7HUsguf.mjs.map +1 -0
  1001. package/dist/types-DA1Te3Oy.d.mts +198 -0
  1002. package/dist/types-DA1Te3Oy.d.mts.map +1 -0
  1003. package/dist/types-DhV6Q5bP.mjs +18 -0
  1004. package/dist/types-DhV6Q5bP.mjs.map +1 -0
  1005. package/dist/types-DnnVSl6Y.d.mts +85 -0
  1006. package/dist/types-DnnVSl6Y.d.mts.map +1 -0
  1007. package/dist/types-VT4-BugW.mjs +16 -0
  1008. package/dist/types-VT4-BugW.mjs.map +1 -0
  1009. package/dist/upload-attempts-B68ZGNu9.mjs +32 -0
  1010. package/dist/upload-attempts-B68ZGNu9.mjs.map +1 -0
  1011. package/dist/url-pattern-CCeZMGOh.mjs +33 -0
  1012. package/dist/url-pattern-CCeZMGOh.mjs.map +1 -0
  1013. package/dist/user-DDSL-sGw.mjs +171 -0
  1014. package/dist/user-DDSL-sGw.mjs.map +1 -0
  1015. package/dist/utils-DdhmO9w9.mjs +439 -0
  1016. package/dist/utils-DdhmO9w9.mjs.map +1 -0
  1017. package/dist/validate-CHosPEhs.mjs +453 -0
  1018. package/dist/validate-CHosPEhs.mjs.map +1 -0
  1019. package/dist/validate-CM79QXYE.d.mts +432 -0
  1020. package/dist/validate-CM79QXYE.d.mts.map +1 -0
  1021. package/dist/validation-BFecQczG.mjs +218 -0
  1022. package/dist/validation-BFecQczG.mjs.map +1 -0
  1023. package/dist/version-BRZXVifl.mjs +9 -0
  1024. package/dist/version-BRZXVifl.mjs.map +1 -0
  1025. package/dist/version-DUQDHgrf.mjs +7 -0
  1026. package/dist/version-DUQDHgrf.mjs.map +1 -0
  1027. package/dist/widgets-WdV72brA.mjs +126 -0
  1028. package/dist/widgets-WdV72brA.mjs.map +1 -0
  1029. package/dist/wxr-taxonomies-BHTdqkmZ.d.mts +34 -0
  1030. package/dist/wxr-taxonomies-BHTdqkmZ.d.mts.map +1 -0
  1031. package/dist/wxr-taxonomies-DP6ESgMN.mjs +372 -0
  1032. package/dist/wxr-taxonomies-DP6ESgMN.mjs.map +1 -0
  1033. package/dist/zod-generator-D6uE4WiS.mjs +389 -0
  1034. package/dist/zod-generator-D6uE4WiS.mjs.map +1 -0
  1035. package/package.json +6 -5
  1036. package/src/api/authorize.ts +17 -0
  1037. package/src/api/email-locale.ts +24 -0
  1038. package/src/api/errors.ts +16 -0
  1039. package/src/api/handlers/api-tokens.ts +18 -3
  1040. package/src/api/handlers/block-types.ts +129 -0
  1041. package/src/api/handlers/bulk-tag.ts +309 -0
  1042. package/src/api/handlers/comments.ts +0 -28
  1043. package/src/api/handlers/index.ts +10 -0
  1044. package/src/api/handlers/manifest.ts +8 -1
  1045. package/src/api/handlers/marketplace.ts +22 -16
  1046. package/src/api/handlers/media-usage.ts +31 -12
  1047. package/src/api/handlers/media.ts +19 -14
  1048. package/src/api/handlers/schema.ts +33 -8
  1049. package/src/api/handlers/settings.ts +2 -2
  1050. package/src/api/handlers/snapshot.ts +4 -0
  1051. package/src/api/handlers/taxonomies.ts +132 -83
  1052. package/src/api/handlers/transfer.ts +1347 -0
  1053. package/src/api/handlers/validate-media-fields.ts +124 -12
  1054. package/src/api/media-usage-write-fence.ts +5 -26
  1055. package/src/api/openapi/document.ts +614 -5
  1056. package/src/api/schemas/auth.ts +7 -1
  1057. package/src/api/schemas/common.ts +5 -0
  1058. package/src/api/schemas/content.ts +20 -1
  1059. package/src/api/schemas/media-usage.ts +11 -0
  1060. package/src/api/schemas/menus.ts +1 -1
  1061. package/src/api/schemas/schema.ts +117 -0
  1062. package/src/api/schemas/settings.ts +3 -3
  1063. package/src/api/schemas/taxonomies.ts +18 -0
  1064. package/src/api/schemas/transfer.ts +249 -0
  1065. package/src/api/transfer-download.ts +36 -0
  1066. package/src/api/types.ts +3 -0
  1067. package/src/astro/integration/routes.ts +31 -0
  1068. package/src/astro/integration/vite-config.ts +26 -0
  1069. package/src/astro/middleware/auth.ts +30 -7
  1070. package/src/astro/middleware/media-usage-write-fence.ts +106 -11
  1071. package/src/astro/middleware/request-context.ts +16 -2
  1072. package/src/astro/middleware.ts +38 -18
  1073. package/src/astro/routes/admin.astro +3 -1
  1074. package/src/astro/routes/api/admin/hooks/exclusive/index.ts +1 -5
  1075. package/src/astro/routes/api/admin/plugins/[id]/disable.ts +4 -3
  1076. package/src/astro/routes/api/admin/plugins/[id]/enable.ts +4 -3
  1077. package/src/astro/routes/api/admin/plugins/[id]/uninstall.ts +4 -3
  1078. package/src/astro/routes/api/admin/plugins/[id]/update.ts +4 -3
  1079. package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +4 -3
  1080. package/src/astro/routes/api/admin/plugins/registry/[id]/uninstall.ts +4 -3
  1081. package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +3 -3
  1082. package/src/astro/routes/api/admin/plugins/registry/install.ts +3 -3
  1083. package/src/astro/routes/api/admin/plugins/registry/publisher-handle.ts +59 -0
  1084. package/src/astro/routes/api/admin/transfer/[...path].ts +143 -0
  1085. package/src/astro/routes/api/admin/transfer/approvals/[id]/approve.ts +35 -0
  1086. package/src/astro/routes/api/admin/transfer/approvals/[id]/deny.ts +35 -0
  1087. package/src/astro/routes/api/admin/transfer/approvals/index.ts +33 -0
  1088. package/src/astro/routes/api/admin/transfer/capabilities.ts +36 -0
  1089. package/src/astro/routes/api/admin/transfer/exports/[id]/advance.ts +34 -0
  1090. package/src/astro/routes/api/admin/transfer/exports/[id]/archive.ts +35 -0
  1091. package/src/astro/routes/api/admin/transfer/exports/[id]/files/[...path].ts +40 -0
  1092. package/src/astro/routes/api/admin/transfer/exports/[id]/index.ts +25 -0
  1093. package/src/astro/routes/api/admin/transfer/exports/[id]/manifest.ts +38 -0
  1094. package/src/astro/routes/api/admin/transfer/exports/index.ts +64 -0
  1095. package/src/astro/routes/api/admin/transfer/imports/[id]/abandon.ts +28 -0
  1096. package/src/astro/routes/api/admin/transfer/imports/[id]/advance.ts +37 -0
  1097. package/src/astro/routes/api/admin/transfer/imports/[id]/analyze.ts +51 -0
  1098. package/src/astro/routes/api/admin/transfer/imports/[id]/cancel.ts +27 -0
  1099. package/src/astro/routes/api/admin/transfer/imports/[id]/execute.ts +48 -0
  1100. package/src/astro/routes/api/admin/transfer/imports/[id]/files/[...path].ts +54 -0
  1101. package/src/astro/routes/api/admin/transfer/imports/[id]/index.ts +25 -0
  1102. package/src/astro/routes/api/admin/transfer/imports/[id]/missing.ts +34 -0
  1103. package/src/astro/routes/api/admin/transfer/imports/[id]/plan.ts +29 -0
  1104. package/src/astro/routes/api/admin/transfer/imports/[id]/receipt.ts +25 -0
  1105. package/src/astro/routes/api/admin/transfer/imports/index.ts +85 -0
  1106. package/src/astro/routes/api/admin/users/[id]/send-recovery.ts +9 -1
  1107. package/src/astro/routes/api/auth/invite/index.ts +15 -1
  1108. package/src/astro/routes/api/auth/magic-link/send.ts +9 -1
  1109. package/src/astro/routes/api/auth/magic-link/verify.ts +37 -39
  1110. package/src/astro/routes/api/auth/passkey/options.ts +2 -21
  1111. package/src/astro/routes/api/content/[collection]/[id]/preview-url.ts +64 -13
  1112. package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +16 -1
  1113. package/src/astro/routes/api/import/wordpress/rewrite-url-helpers.ts +11 -4
  1114. package/src/astro/routes/api/mcp.ts +1 -0
  1115. package/src/astro/routes/api/media/[id].ts +5 -15
  1116. package/src/astro/routes/api/media/file/[...key].ts +30 -5
  1117. package/src/astro/routes/api/oauth/authorize.ts +4 -0
  1118. package/src/astro/routes/api/schema/block-types/[slug]/index.ts +29 -0
  1119. package/src/astro/routes/api/schema/block-types/[slug]/versions/[version]/activate.ts +31 -0
  1120. package/src/astro/routes/api/schema/block-types/index.ts +29 -0
  1121. package/src/astro/routes/api/taxonomies/bulk-tag.ts +29 -0
  1122. package/src/astro/routes/api/typegen.ts +8 -4
  1123. package/src/astro/types.ts +4 -0
  1124. package/src/auth/api-tokens.ts +1 -0
  1125. package/src/auth/rate-limit.ts +2 -1
  1126. package/src/auth/scopes.ts +11 -0
  1127. package/src/cleanup.ts +14 -0
  1128. package/src/cli/client-factory.ts +6 -1
  1129. package/src/cli/commands/export-seed.ts +41 -15
  1130. package/src/cli/commands/seed.ts +6 -2
  1131. package/src/cli/commands/site.ts +556 -0
  1132. package/src/cli/index.ts +2 -0
  1133. package/src/cli/site/archive.ts +273 -0
  1134. package/src/cli/site/export.ts +311 -0
  1135. package/src/cli/site/import.ts +815 -0
  1136. package/src/cli/site/shared.ts +241 -0
  1137. package/src/client/index.ts +414 -11
  1138. package/src/client/portable-text.ts +41 -0
  1139. package/src/comments/public-submission.ts +19 -11
  1140. package/src/components/Blocks.astro +46 -0
  1141. package/src/components/Gallery.astro +2 -1
  1142. package/src/components/Image.astro +51 -6
  1143. package/src/components/InlinePortableTextEditor.tsx +28 -18
  1144. package/src/components/blocks.ts +44 -0
  1145. package/src/components/index.ts +14 -4
  1146. package/src/content/converters/gallery.ts +54 -16
  1147. package/src/content/converters/image-link.ts +27 -0
  1148. package/src/content/converters/index.ts +1 -0
  1149. package/src/content/converters/portable-text-to-prosemirror.ts +10 -7
  1150. package/src/content/converters/prosemirror-to-portable-text.ts +14 -0
  1151. package/src/content/converters/types.ts +17 -0
  1152. package/src/database/content-datetime.ts +19 -2
  1153. package/src/database/migrations/035_bounded_404_log.ts +28 -39
  1154. package/src/database/migrations/081_redirect_write_guards.ts +7 -4
  1155. package/src/database/migrations/083_block_types.ts +58 -0
  1156. package/src/database/migrations/084_site_transfer.ts +264 -0
  1157. package/src/database/migrations/085_taxonomy_def_groups.ts +155 -0
  1158. package/src/database/migrations/runner.ts +6 -0
  1159. package/src/database/repositories/audit.ts +10 -1
  1160. package/src/database/repositories/byline.ts +4 -1
  1161. package/src/database/repositories/content.ts +83 -11
  1162. package/src/database/repositories/media-usage.ts +43 -13
  1163. package/src/database/repositories/media.ts +32 -1
  1164. package/src/database/repositories/options.ts +12 -0
  1165. package/src/database/repositories/revision.ts +6 -3
  1166. package/src/database/repositories/taxonomy-def.ts +126 -0
  1167. package/src/database/repositories/taxonomy.ts +65 -26
  1168. package/src/database/types.ts +133 -1
  1169. package/src/db/sqlite.ts +1 -1
  1170. package/src/emdash-runtime.ts +287 -51
  1171. package/src/import/utils.ts +8 -1
  1172. package/src/import/wxr-taxonomies.ts +11 -67
  1173. package/src/index.ts +26 -1
  1174. package/src/loader.ts +9 -5
  1175. package/src/mcp/server.ts +521 -29
  1176. package/src/mcp/transfer.ts +569 -0
  1177. package/src/media/local-runtime.ts +5 -18
  1178. package/src/media/upload-attempts.ts +5 -0
  1179. package/src/media/url.ts +15 -0
  1180. package/src/media/usage/content-fields.ts +69 -5
  1181. package/src/media/usage/content-refresh.ts +13 -66
  1182. package/src/media/usage/content-repair.ts +10 -2
  1183. package/src/media/usage/extractor.ts +74 -3
  1184. package/src/media/usage/projection-fingerprint.ts +14 -0
  1185. package/src/media/usage/schema-invalidation.ts +72 -0
  1186. package/src/media/usage/site-settings.ts +52 -0
  1187. package/src/media/usage/types.ts +2 -0
  1188. package/src/object-cache/index.ts +69 -4
  1189. package/src/plugin-test-runtime.ts +1 -0
  1190. package/src/plugins/context.ts +104 -56
  1191. package/src/plugins/cron.ts +6 -4
  1192. package/src/plugins/define-plugin.ts +11 -1
  1193. package/src/plugins/email-console.ts +2 -0
  1194. package/src/plugins/email.ts +16 -0
  1195. package/src/plugins/hooks.ts +33 -9
  1196. package/src/plugins/manifest-schema.ts +1 -0
  1197. package/src/plugins/route-error.ts +57 -0
  1198. package/src/plugins/routes.ts +5 -60
  1199. package/src/plugins/sandbox/types.ts +22 -2
  1200. package/src/plugins/types.ts +4 -0
  1201. package/src/registry/artifact-fetch.ts +17 -4
  1202. package/src/registry/publisher-handle.ts +273 -0
  1203. package/src/schema/block-type-contract.ts +478 -0
  1204. package/src/schema/block-type-registry.ts +689 -0
  1205. package/src/schema/block-types.ts +110 -0
  1206. package/src/schema/block-values.ts +293 -0
  1207. package/src/schema/byline-registry.ts +1 -1
  1208. package/src/schema/index.ts +28 -0
  1209. package/src/schema/registry.ts +462 -12
  1210. package/src/schema/types.ts +12 -1
  1211. package/src/schema/zod-generator.ts +92 -9
  1212. package/src/search/fts-manager.ts +40 -0
  1213. package/src/seed/apply.ts +173 -49
  1214. package/src/seed/types.ts +23 -3
  1215. package/src/seed/validate.ts +131 -7
  1216. package/src/settings/index.ts +32 -9
  1217. package/src/settings/types.ts +15 -0
  1218. package/src/taxonomies/index.ts +72 -83
  1219. package/src/transfer/analyze/index.ts +45 -0
  1220. package/src/transfer/analyze/issues.ts +55 -0
  1221. package/src/transfer/analyze/plan.ts +327 -0
  1222. package/src/transfer/analyze/read.ts +134 -0
  1223. package/src/transfer/analyze/step.ts +551 -0
  1224. package/src/transfer/analyze/target.ts +269 -0
  1225. package/src/transfer/analyze/unique-keys.ts +228 -0
  1226. package/src/transfer/analyze/validate.ts +1412 -0
  1227. package/src/transfer/analyze/values.ts +227 -0
  1228. package/src/transfer/analyze/write-rules.ts +196 -0
  1229. package/src/transfer/audit.ts +38 -0
  1230. package/src/transfer/auth.ts +25 -0
  1231. package/src/transfer/container/tar.ts +242 -0
  1232. package/src/transfer/domain.ts +248 -0
  1233. package/src/transfer/errors.ts +134 -0
  1234. package/src/transfer/export/exporter.ts +1067 -0
  1235. package/src/transfer/export/fence.ts +84 -0
  1236. package/src/transfer/export/media.ts +165 -0
  1237. package/src/transfer/export/readers.ts +1164 -0
  1238. package/src/transfer/export/verify.ts +677 -0
  1239. package/src/transfer/fence.ts +193 -0
  1240. package/src/transfer/format/canonical.ts +151 -0
  1241. package/src/transfer/format/column-codec.ts +275 -0
  1242. package/src/transfer/format/columns.ts +707 -0
  1243. package/src/transfer/format/digest.ts +287 -0
  1244. package/src/transfer/format/features.ts +91 -0
  1245. package/src/transfer/format/issues.ts +39 -0
  1246. package/src/transfer/format/kinds.ts +936 -0
  1247. package/src/transfer/format/limits.ts +87 -0
  1248. package/src/transfer/format/manifest.ts +297 -0
  1249. package/src/transfer/format/media-refs.ts +716 -0
  1250. package/src/transfer/format/paths.ts +73 -0
  1251. package/src/transfer/format/plan.ts +162 -0
  1252. package/src/transfer/format/receipt.ts +43 -0
  1253. package/src/transfer/format/records.ts +127 -0
  1254. package/src/transfer/format/settings.ts +94 -0
  1255. package/src/transfer/format/transformations.ts +260 -0
  1256. package/src/transfer/format/version.ts +9 -0
  1257. package/src/transfer/gc.ts +103 -0
  1258. package/src/transfer/import/advance.ts +522 -0
  1259. package/src/transfer/import/context.ts +281 -0
  1260. package/src/transfer/import/entries.ts +186 -0
  1261. package/src/transfer/import/ids.ts +40 -0
  1262. package/src/transfer/import/index.ts +15 -0
  1263. package/src/transfer/import/media.ts +141 -0
  1264. package/src/transfer/import/rebuild.ts +300 -0
  1265. package/src/transfer/import/rows.ts +114 -0
  1266. package/src/transfer/import/scaffold.ts +221 -0
  1267. package/src/transfer/import/sql.ts +134 -0
  1268. package/src/transfer/import/stages.ts +329 -0
  1269. package/src/transfer/import/writers.ts +370 -0
  1270. package/src/transfer/index.ts +472 -0
  1271. package/src/transfer/ops/approvals.ts +359 -0
  1272. package/src/transfer/ops/budget.ts +82 -0
  1273. package/src/transfer/ops/collation.ts +21 -0
  1274. package/src/transfer/ops/identity-map.ts +142 -0
  1275. package/src/transfer/ops/media-blobs.ts +135 -0
  1276. package/src/transfer/ops/operations.ts +842 -0
  1277. package/src/transfer/ops/package-index.ts +159 -0
  1278. package/src/transfer/ops/staged-files.ts +231 -0
  1279. package/src/transfer/ops/states.ts +265 -0
  1280. package/src/transfer/ops/time.ts +54 -0
  1281. package/src/transfer/schema-importer.ts +34 -0
  1282. package/src/transfer/site-id.ts +30 -0
  1283. package/src/transfer/staging/assembler.ts +217 -0
  1284. package/src/transfer/staging/keys.ts +94 -0
  1285. package/src/transfer/staging/package.ts +229 -0
  1286. package/src/transfer/staging/stage.ts +231 -0
  1287. package/src/ui.ts +19 -0
  1288. package/src/visual-editing/toolbar.ts +125 -37
  1289. package/dist/action-token-On1sot_c.mjs +0 -26
  1290. package/dist/action-token-On1sot_c.mjs.map +0 -1
  1291. package/dist/activation-CaMfdBt1.mjs +0 -382
  1292. package/dist/activation-CaMfdBt1.mjs.map +0 -1
  1293. package/dist/adapters-Cq10K4_c.d.mts +0 -171
  1294. package/dist/adapters-Cq10K4_c.d.mts.map +0 -1
  1295. package/dist/allowed-origins-1Sa-2wZK.mjs +0 -116
  1296. package/dist/allowed-origins-1Sa-2wZK.mjs.map +0 -1
  1297. package/dist/api-DmjKxPCY.mjs +0 -4831
  1298. package/dist/api-DmjKxPCY.mjs.map +0 -1
  1299. package/dist/api-tokens-BIXItFKV.mjs +0 -163
  1300. package/dist/api-tokens-BIXItFKV.mjs.map +0 -1
  1301. package/dist/api-tokens-DS1VzN7_.mjs +0 -3
  1302. package/dist/apply-drpfmqrR.mjs +0 -1005
  1303. package/dist/apply-drpfmqrR.mjs.map +0 -1
  1304. package/dist/artifact-fetch-COiMhVgk.mjs +0 -813
  1305. package/dist/artifact-fetch-COiMhVgk.mjs.map +0 -1
  1306. package/dist/authoritative-records-DbqshfKD.mjs +0 -5172
  1307. package/dist/authoritative-records-DbqshfKD.mjs.map +0 -1
  1308. package/dist/authorize-BXpfMpp0.mjs +0 -40
  1309. package/dist/authorize-BXpfMpp0.mjs.map +0 -1
  1310. package/dist/backup-BsPQdwnS.mjs +0 -246
  1311. package/dist/backup-BsPQdwnS.mjs.map +0 -1
  1312. package/dist/byline-Doh-wt99.mjs +0 -906
  1313. package/dist/byline-Doh-wt99.mjs.map +0 -1
  1314. package/dist/byline-fields-CsrdvaLV.mjs +0 -123
  1315. package/dist/byline-fields-CsrdvaLV.mjs.map +0 -1
  1316. package/dist/byline-registry-D6lWzXk6.mjs +0 -406
  1317. package/dist/byline-registry-D6lWzXk6.mjs.map +0 -1
  1318. package/dist/bylines-Cop0hkoy.mjs +0 -214
  1319. package/dist/bylines-Cop0hkoy.mjs.map +0 -1
  1320. package/dist/bylines-kpBzHPr8.mjs +0 -232
  1321. package/dist/bylines-kpBzHPr8.mjs.map +0 -1
  1322. package/dist/cache-B0pOlXdM.mjs +0 -108
  1323. package/dist/cache-B0pOlXdM.mjs.map +0 -1
  1324. package/dist/capture-triggers-gxQxnxrJ.mjs +0 -362
  1325. package/dist/capture-triggers-gxQxnxrJ.mjs.map +0 -1
  1326. package/dist/challenge-store-CkRdSdd8.mjs +0 -51
  1327. package/dist/challenge-store-CkRdSdd8.mjs.map +0 -1
  1328. package/dist/checksum-Bsi2D9M1.mjs +0 -162
  1329. package/dist/checksum-Bsi2D9M1.mjs.map +0 -1
  1330. package/dist/chrome-tags-D7LGB91U.mjs +0 -24
  1331. package/dist/chrome-tags-D7LGB91U.mjs.map +0 -1
  1332. package/dist/chunks-BmWyou79.mjs +0 -25
  1333. package/dist/chunks-BmWyou79.mjs.map +0 -1
  1334. package/dist/collection-deletion-C3Xixmkx.mjs +0 -436
  1335. package/dist/collection-deletion-C3Xixmkx.mjs.map +0 -1
  1336. package/dist/collection-slugs-cache-D9auiKmI.mjs +0 -85
  1337. package/dist/collection-slugs-cache-D9auiKmI.mjs.map +0 -1
  1338. package/dist/comment-DcT8qdPK.mjs +0 -313
  1339. package/dist/comment-DcT8qdPK.mjs.map +0 -1
  1340. package/dist/comment-reaction-DY5-y8Y5.mjs +0 -85
  1341. package/dist/comment-reaction-DY5-y8Y5.mjs.map +0 -1
  1342. package/dist/comments-B67VRNGw.mjs +0 -204
  1343. package/dist/comments-B67VRNGw.mjs.map +0 -1
  1344. package/dist/comments-BVzzt6x5.mjs +0 -99
  1345. package/dist/comments-BVzzt6x5.mjs.map +0 -1
  1346. package/dist/components-DIl9Qzh6.mjs +0 -108
  1347. package/dist/components-DIl9Qzh6.mjs.map +0 -1
  1348. package/dist/config-B2acLeC5.mjs +0 -242
  1349. package/dist/config-B2acLeC5.mjs.map +0 -1
  1350. package/dist/config-CGVeT8Hc.mjs +0 -73
  1351. package/dist/config-CGVeT8Hc.mjs.map +0 -1
  1352. package/dist/config-D3HhLON3.d.mts +0 -39
  1353. package/dist/config-D3HhLON3.d.mts.map +0 -1
  1354. package/dist/config-DS7e4EZ9.d.mts +0 -6387
  1355. package/dist/config-DS7e4EZ9.d.mts.map +0 -1
  1356. package/dist/content-DZ3B5qtA.mjs +0 -2216
  1357. package/dist/content-DZ3B5qtA.mjs.map +0 -1
  1358. package/dist/content-list-query-CbPdzsna.d.mts +0 -26
  1359. package/dist/content-list-query-CbPdzsna.d.mts.map +0 -1
  1360. package/dist/content-policy-CM4skrNi.mjs +0 -46
  1361. package/dist/content-policy-CM4skrNi.mjs.map +0 -1
  1362. package/dist/content-refresh-BHLHJgyt.mjs +0 -3599
  1363. package/dist/content-refresh-BHLHJgyt.mjs.map +0 -1
  1364. package/dist/content-repair-BVll5WNl.mjs +0 -440
  1365. package/dist/content-repair-BVll5WNl.mjs.map +0 -1
  1366. package/dist/context-B195kjqZ.mjs +0 -1835
  1367. package/dist/context-B195kjqZ.mjs.map +0 -1
  1368. package/dist/cron-BcR3RN4K.mjs +0 -282
  1369. package/dist/cron-BcR3RN4K.mjs.map +0 -1
  1370. package/dist/dashboard-CZD4G7k_.mjs +0 -151
  1371. package/dist/dashboard-CZD4G7k_.mjs.map +0 -1
  1372. package/dist/default-BtlxWgh9.mjs +0 -81
  1373. package/dist/default-BtlxWgh9.mjs.map +0 -1
  1374. package/dist/deferred-tasks-Ba9fphlE.d.mts +0 -9
  1375. package/dist/deferred-tasks-Ba9fphlE.d.mts.map +0 -1
  1376. package/dist/device-flow-3E5l0fpH.mjs +0 -466
  1377. package/dist/device-flow-3E5l0fpH.mjs.map +0 -1
  1378. package/dist/dialect-helpers-CtYdsX4W.mjs +0 -307
  1379. package/dist/dialect-helpers-CtYdsX4W.mjs.map +0 -1
  1380. package/dist/direct-executor-ZI8E01Yt.mjs +0 -104
  1381. package/dist/direct-executor-ZI8E01Yt.mjs.map +0 -1
  1382. package/dist/dist-2hDLsLeq.mjs +0 -810
  1383. package/dist/dist-2hDLsLeq.mjs.map +0 -1
  1384. package/dist/email-console-gc-E3Eqj.mjs +0 -50
  1385. package/dist/email-console-gc-E3Eqj.mjs.map +0 -1
  1386. package/dist/emdash-runtime-DZGinqTL.mjs +0 -4041
  1387. package/dist/emdash-runtime-DZGinqTL.mjs.map +0 -1
  1388. package/dist/enrich-C2Mk0lwE.mjs +0 -194
  1389. package/dist/enrich-C2Mk0lwE.mjs.map +0 -1
  1390. package/dist/entry-lock-D3C99MXS.mjs +0 -1520
  1391. package/dist/entry-lock-D3C99MXS.mjs.map +0 -1
  1392. package/dist/entry-lock-D9rnj2Lu.mjs +0 -163
  1393. package/dist/entry-lock-D9rnj2Lu.mjs.map +0 -1
  1394. package/dist/entry-lock-DX7QkqEg.d.mts +0 -3503
  1395. package/dist/entry-lock-DX7QkqEg.d.mts.map +0 -1
  1396. package/dist/entry-locks-CO_KaoU5.mjs +0 -167
  1397. package/dist/entry-locks-CO_KaoU5.mjs.map +0 -1
  1398. package/dist/error-CCTCskie.mjs +0 -90
  1399. package/dist/error-CCTCskie.mjs.map +0 -1
  1400. package/dist/errors-W3PA8HqB.mjs +0 -447
  1401. package/dist/errors-W3PA8HqB.mjs.map +0 -1
  1402. package/dist/escape-DN4Qmjsl.mjs +0 -9
  1403. package/dist/escape-DN4Qmjsl.mjs.map +0 -1
  1404. package/dist/field-defs-cache-B337z8UJ.mjs +0 -77
  1405. package/dist/field-defs-cache-B337z8UJ.mjs.map +0 -1
  1406. package/dist/fts-manager-DMb0sbIQ.mjs +0 -413
  1407. package/dist/fts-manager-DMb0sbIQ.mjs.map +0 -1
  1408. package/dist/hash-CLVFzWvx.mjs +0 -37
  1409. package/dist/hash-CLVFzWvx.mjs.map +0 -1
  1410. package/dist/hook-result-KY1jq21o.d.mts +0 -31
  1411. package/dist/hook-result-KY1jq21o.d.mts.map +0 -1
  1412. package/dist/hreflang-BgS2FqhH.d.mts +0 -50
  1413. package/dist/hreflang-BgS2FqhH.d.mts.map +0 -1
  1414. package/dist/hreflang-CrJwqoeb.mjs +0 -105
  1415. package/dist/hreflang-CrJwqoeb.mjs.map +0 -1
  1416. package/dist/http-route-dispatch-DAKlanXb.mjs +0 -339
  1417. package/dist/http-route-dispatch-DAKlanXb.mjs.map +0 -1
  1418. package/dist/identity-DRGSHEEr.mjs +0 -35
  1419. package/dist/identity-DRGSHEEr.mjs.map +0 -1
  1420. package/dist/import-DFr5B_hC.mjs +0 -2020
  1421. package/dist/import-DFr5B_hC.mjs.map +0 -1
  1422. package/dist/index-CDwKDkTq.d.mts +0 -623
  1423. package/dist/index-CDwKDkTq.d.mts.map +0 -1
  1424. package/dist/install-finalization-5Os-QZ-2.mjs +0 -58
  1425. package/dist/install-finalization-5Os-QZ-2.mjs.map +0 -1
  1426. package/dist/lifecycle-7e-Lt_kX.mjs +0 -25
  1427. package/dist/lifecycle-7e-Lt_kX.mjs.map +0 -1
  1428. package/dist/load-Cu5bvCZh.mjs +0 -28
  1429. package/dist/load-Cu5bvCZh.mjs.map +0 -1
  1430. package/dist/loader-t4TxaFiQ.mjs +0 -1004
  1431. package/dist/loader-t4TxaFiQ.mjs.map +0 -1
  1432. package/dist/manifest-builder-D31UoJCu.mjs +0 -189
  1433. package/dist/manifest-builder-D31UoJCu.mjs.map +0 -1
  1434. package/dist/manifest-schema-Bkh8SeHd.mjs +0 -491
  1435. package/dist/manifest-schema-Bkh8SeHd.mjs.map +0 -1
  1436. package/dist/media-TBlKCwo7.mjs +0 -334
  1437. package/dist/media-TBlKCwo7.mjs.map +0 -1
  1438. package/dist/media-allowlist-s60eAIf6.mjs +0 -44
  1439. package/dist/media-allowlist-s60eAIf6.mjs.map +0 -1
  1440. package/dist/media-folders-ClIRLUQv.mjs +0 -210
  1441. package/dist/media-folders-ClIRLUQv.mjs.map +0 -1
  1442. package/dist/media-url-DY_ijO3B.mjs +0 -43
  1443. package/dist/media-url-DY_ijO3B.mjs.map +0 -1
  1444. package/dist/media-usage-C4NolTpQ.mjs +0 -1833
  1445. package/dist/media-usage-C4NolTpQ.mjs.map +0 -1
  1446. package/dist/media-usage-activation-CAhmb14O.mjs +0 -78
  1447. package/dist/media-usage-activation-CAhmb14O.mjs.map +0 -1
  1448. package/dist/media-usage-work-Cu5DqewW.mjs +0 -586
  1449. package/dist/media-usage-work-Cu5DqewW.mjs.map +0 -1
  1450. package/dist/media-usage-work-DJr3rOEN.mjs +0 -152
  1451. package/dist/media-usage-work-DJr3rOEN.mjs.map +0 -1
  1452. package/dist/media-usage-write-fence-DW5oHT7q.mjs +0 -42
  1453. package/dist/media-usage-write-fence-DW5oHT7q.mjs.map +0 -1
  1454. package/dist/menus-DbgU9z5Q.mjs +0 -3732
  1455. package/dist/menus-DbgU9z5Q.mjs.map +0 -1
  1456. package/dist/menus-Wy8m5NcH.mjs +0 -753
  1457. package/dist/menus-Wy8m5NcH.mjs.map +0 -1
  1458. package/dist/mime-CCYRC4r1.mjs +0 -36
  1459. package/dist/mime-CCYRC4r1.mjs.map +0 -1
  1460. package/dist/mode-CkmOhFqj.mjs +0 -23
  1461. package/dist/mode-CkmOhFqj.mjs.map +0 -1
  1462. package/dist/node-sqlite-compat-vpVaILnb.mjs +0 -46
  1463. package/dist/node-sqlite-compat-vpVaILnb.mjs.map +0 -1
  1464. package/dist/normalize-dChXQjwS.mjs +0 -191
  1465. package/dist/normalize-dChXQjwS.mjs.map +0 -1
  1466. package/dist/oauth-authorization-DZ-R-hmx.mjs +0 -274
  1467. package/dist/oauth-authorization-DZ-R-hmx.mjs.map +0 -1
  1468. package/dist/oauth-clients-BMPA8vjl.mjs +0 -266
  1469. package/dist/oauth-clients-BMPA8vjl.mjs.map +0 -1
  1470. package/dist/oauth-state-store-0gIdb48-.mjs +0 -50
  1471. package/dist/oauth-state-store-0gIdb48-.mjs.map +0 -1
  1472. package/dist/oauth-user-lookup-ChVW4UWu.mjs +0 -26
  1473. package/dist/oauth-user-lookup-ChVW4UWu.mjs.map +0 -1
  1474. package/dist/object-cache-DlSVbn5Y.mjs +0 -534
  1475. package/dist/object-cache-DlSVbn5Y.mjs.map +0 -1
  1476. package/dist/options-D5WcorD5.mjs +0 -200
  1477. package/dist/options-D5WcorD5.mjs.map +0 -1
  1478. package/dist/options-DAknChnw.d.mts +0 -77
  1479. package/dist/options-DAknChnw.d.mts.map +0 -1
  1480. package/dist/parse-Cr379Av9.mjs +0 -81
  1481. package/dist/parse-Cr379Av9.mjs.map +0 -1
  1482. package/dist/parse-tj9XLNO_.d.mts +0 -165
  1483. package/dist/parse-tj9XLNO_.d.mts.map +0 -1
  1484. package/dist/passkey-config-BD-wMaCf.mjs +0 -46
  1485. package/dist/passkey-config-BD-wMaCf.mjs.map +0 -1
  1486. package/dist/patterns-Do3iqi7N.mjs +0 -145
  1487. package/dist/patterns-Do3iqi7N.mjs.map +0 -1
  1488. package/dist/placeholder-CubPFn_L.d.mts +0 -306
  1489. package/dist/placeholder-CubPFn_L.d.mts.map +0 -1
  1490. package/dist/plugins-DHurtdXQ.mjs +0 -277
  1491. package/dist/plugins-DHurtdXQ.mjs.map +0 -1
  1492. package/dist/policy-lyZnjpwz.mjs +0 -45
  1493. package/dist/policy-lyZnjpwz.mjs.map +0 -1
  1494. package/dist/portable-text-oAwodbPS.mjs +0 -286
  1495. package/dist/portable-text-oAwodbPS.mjs.map +0 -1
  1496. package/dist/preview-Cup2bj8c.mjs +0 -107
  1497. package/dist/preview-Cup2bj8c.mjs.map +0 -1
  1498. package/dist/protocol-C1CNiKX4.d.mts +0 -61
  1499. package/dist/protocol-C1CNiKX4.d.mts.map +0 -1
  1500. package/dist/public-submission-Cs-pFMQK.mjs +0 -245
  1501. package/dist/public-submission-Cs-pFMQK.mjs.map +0 -1
  1502. package/dist/public-url-BWVHsfQv.mjs +0 -101
  1503. package/dist/public-url-BWVHsfQv.mjs.map +0 -1
  1504. package/dist/query-D-lxiOgn.mjs +0 -890
  1505. package/dist/query-D-lxiOgn.mjs.map +0 -1
  1506. package/dist/query-D7kHKOws.mjs +0 -41
  1507. package/dist/query-D7kHKOws.mjs.map +0 -1
  1508. package/dist/rate-limit-CqJn-w4h.mjs +0 -120
  1509. package/dist/rate-limit-CqJn-w4h.mjs.map +0 -1
  1510. package/dist/redirect-BrChFPIu.mjs +0 -17
  1511. package/dist/redirect-BrChFPIu.mjs.map +0 -1
  1512. package/dist/redirect-D2Yo-b6S.mjs +0 -415
  1513. package/dist/redirect-D2Yo-b6S.mjs.map +0 -1
  1514. package/dist/redirects-BCiTaIQ-.mjs +0 -146
  1515. package/dist/redirects-BCiTaIQ-.mjs.map +0 -1
  1516. package/dist/redirects-ByItliuu.mjs +0 -644
  1517. package/dist/redirects-ByItliuu.mjs.map +0 -1
  1518. package/dist/registry-CkuPoZs7.mjs +0 -1222
  1519. package/dist/registry-CkuPoZs7.mjs.map +0 -1
  1520. package/dist/relation-XTAtOpJO.mjs +0 -334
  1521. package/dist/relation-XTAtOpJO.mjs.map +0 -1
  1522. package/dist/relations-B4w-G5U9.mjs +0 -309
  1523. package/dist/relations-B4w-G5U9.mjs.map +0 -1
  1524. package/dist/relations-O63JWBRj.mjs +0 -403
  1525. package/dist/relations-O63JWBRj.mjs.map +0 -1
  1526. package/dist/request-cache-DaMhSQdx.mjs +0 -104
  1527. package/dist/request-cache-DaMhSQdx.mjs.map +0 -1
  1528. package/dist/request-meta-C8yl_sIs.mjs +0 -141
  1529. package/dist/request-meta-C8yl_sIs.mjs.map +0 -1
  1530. package/dist/resolve-BJIS8wKr.mjs +0 -199
  1531. package/dist/resolve-BJIS8wKr.mjs.map +0 -1
  1532. package/dist/route-wire-D66L2oaZ.mjs +0 -197
  1533. package/dist/route-wire-D66L2oaZ.mjs.map +0 -1
  1534. package/dist/routes-DYsTe-oR.mjs +0 -321
  1535. package/dist/routes-DYsTe-oR.mjs.map +0 -1
  1536. package/dist/runner-3gfxRsJG.d.mts +0 -68
  1537. package/dist/runner-3gfxRsJG.d.mts.map +0 -1
  1538. package/dist/runner-ClrleR8A.mjs +0 -5502
  1539. package/dist/runner-ClrleR8A.mjs.map +0 -1
  1540. package/dist/schema-CPhPM9Do.mjs +0 -420
  1541. package/dist/schema-CPhPM9Do.mjs.map +0 -1
  1542. package/dist/schema-DEERRrKS.mjs +0 -9
  1543. package/dist/schema-DEERRrKS.mjs.map +0 -1
  1544. package/dist/scopes-Bn8_rCSt.mjs +0 -27
  1545. package/dist/scopes-Bn8_rCSt.mjs.map +0 -1
  1546. package/dist/search-lami_Ota.mjs +0 -448
  1547. package/dist/search-lami_Ota.mjs.map +0 -1
  1548. package/dist/secrets-DNgVgz_e.mjs +0 -341
  1549. package/dist/secrets-DNgVgz_e.mjs.map +0 -1
  1550. package/dist/sections-BIpd4Cxf.mjs +0 -346
  1551. package/dist/sections-BIpd4Cxf.mjs.map +0 -1
  1552. package/dist/seo-BtU70b7l.mjs +0 -114
  1553. package/dist/seo-BtU70b7l.mjs.map +0 -1
  1554. package/dist/seo-_4qmazxz.mjs +0 -133
  1555. package/dist/seo-_4qmazxz.mjs.map +0 -1
  1556. package/dist/service-Bpy5iTX0.mjs +0 -150
  1557. package/dist/service-Bpy5iTX0.mjs.map +0 -1
  1558. package/dist/session-user-BQeS2Mrb.mjs +0 -51
  1559. package/dist/session-user-BQeS2Mrb.mjs.map +0 -1
  1560. package/dist/settings-DmroR53o.mjs +0 -420
  1561. package/dist/settings-DmroR53o.mjs.map +0 -1
  1562. package/dist/settings-g2F2a3Ub.mjs +0 -51
  1563. package/dist/settings-g2F2a3Ub.mjs.map +0 -1
  1564. package/dist/setup-complete-BrZaXpVV.mjs +0 -26
  1565. package/dist/setup-complete-BrZaXpVV.mjs.map +0 -1
  1566. package/dist/setup-nonce-Cb9-884O.mjs +0 -25
  1567. package/dist/setup-nonce-Cb9-884O.mjs.map +0 -1
  1568. package/dist/site-url-DjhYCaep.mjs +0 -16
  1569. package/dist/site-url-DjhYCaep.mjs.map +0 -1
  1570. package/dist/snapshot-C32Xuv3o.mjs +0 -233
  1571. package/dist/snapshot-C32Xuv3o.mjs.map +0 -1
  1572. package/dist/ssrf-Co1GGFZz.mjs +0 -406
  1573. package/dist/ssrf-Co1GGFZz.mjs.map +0 -1
  1574. package/dist/state-C7gCoiHr.mjs +0 -153
  1575. package/dist/state-C7gCoiHr.mjs.map +0 -1
  1576. package/dist/status-DLoBmcDz.mjs +0 -30
  1577. package/dist/status-DLoBmcDz.mjs.map +0 -1
  1578. package/dist/storage-query-CPctdMKX.d.mts +0 -1519
  1579. package/dist/storage-query-CPctdMKX.d.mts.map +0 -1
  1580. package/dist/target-CUKlGrXb.mjs +0 -27
  1581. package/dist/target-CUKlGrXb.mjs.map +0 -1
  1582. package/dist/taxonomies-BpqpXJUE.mjs +0 -707
  1583. package/dist/taxonomies-BpqpXJUE.mjs.map +0 -1
  1584. package/dist/taxonomies-ClCo4IGO.mjs +0 -899
  1585. package/dist/taxonomies-ClCo4IGO.mjs.map +0 -1
  1586. package/dist/taxonomy-Dj1vpw5E.mjs +0 -508
  1587. package/dist/taxonomy-Dj1vpw5E.mjs.map +0 -1
  1588. package/dist/tokens-Ns02GAma.mjs +0 -171
  1589. package/dist/tokens-Ns02GAma.mjs.map +0 -1
  1590. package/dist/transport-B8P1xsqk.mjs +0 -136
  1591. package/dist/transport-B8P1xsqk.mjs.map +0 -1
  1592. package/dist/transport-BLHZZcD_.d.mts +0 -42
  1593. package/dist/transport-BLHZZcD_.d.mts.map +0 -1
  1594. package/dist/trusted-proxy-Cg7SuD15.mjs +0 -51
  1595. package/dist/trusted-proxy-Cg7SuD15.mjs.map +0 -1
  1596. package/dist/turnstile-DWCSh_Qc.mjs +0 -53
  1597. package/dist/turnstile-DWCSh_Qc.mjs.map +0 -1
  1598. package/dist/types-B3RkqvDW.mjs +0 -156
  1599. package/dist/types-B3RkqvDW.mjs.map +0 -1
  1600. package/dist/types-BtuppOTV.mjs +0 -16
  1601. package/dist/types-BtuppOTV.mjs.map +0 -1
  1602. package/dist/types-CCR3ivXE.d.mts +0 -363
  1603. package/dist/types-CCR3ivXE.d.mts.map +0 -1
  1604. package/dist/types-CSHgU_-_.mjs +0 -18
  1605. package/dist/types-CSHgU_-_.mjs.map +0 -1
  1606. package/dist/types-CbwqGOXm.d.mts +0 -766
  1607. package/dist/types-CbwqGOXm.d.mts.map +0 -1
  1608. package/dist/types-D4RGIc2I.d.mts +0 -198
  1609. package/dist/types-D4RGIc2I.d.mts.map +0 -1
  1610. package/dist/types-DEHidMEk.d.mts +0 -1637
  1611. package/dist/types-DEHidMEk.d.mts.map +0 -1
  1612. package/dist/types-DQeU2SR7.d.mts +0 -279
  1613. package/dist/types-DQeU2SR7.d.mts.map +0 -1
  1614. package/dist/types-DxQWoQLA.d.mts +0 -264
  1615. package/dist/types-DxQWoQLA.d.mts.map +0 -1
  1616. package/dist/types-FBBnGZ2Y.d.mts +0 -198
  1617. package/dist/types-FBBnGZ2Y.d.mts.map +0 -1
  1618. package/dist/types-ZCnlropY.mjs +0 -69
  1619. package/dist/types-ZCnlropY.mjs.map +0 -1
  1620. package/dist/types-_Qtyawiy.d.mts +0 -124
  1621. package/dist/types-_Qtyawiy.d.mts.map +0 -1
  1622. package/dist/types-gC6FAoa_.d.mts +0 -75
  1623. package/dist/types-gC6FAoa_.d.mts.map +0 -1
  1624. package/dist/types-k--LneIF.mjs +0 -22
  1625. package/dist/types-k--LneIF.mjs.map +0 -1
  1626. package/dist/upload-attempts-2xdnoKGe.mjs +0 -27
  1627. package/dist/upload-attempts-2xdnoKGe.mjs.map +0 -1
  1628. package/dist/url-pattern-3m3reMzr.mjs +0 -33
  1629. package/dist/url-pattern-3m3reMzr.mjs.map +0 -1
  1630. package/dist/user-DroRntkx.mjs +0 -171
  1631. package/dist/user-DroRntkx.mjs.map +0 -1
  1632. package/dist/utils-CC2oNGV8.mjs +0 -435
  1633. package/dist/utils-CC2oNGV8.mjs.map +0 -1
  1634. package/dist/validate-BCP9HNDn.mjs +0 -384
  1635. package/dist/validate-BCP9HNDn.mjs.map +0 -1
  1636. package/dist/validate-CyQ7I3xF.d.mts +0 -410
  1637. package/dist/validate-CyQ7I3xF.d.mts.map +0 -1
  1638. package/dist/validation-DBy6WF94.mjs +0 -216
  1639. package/dist/validation-DBy6WF94.mjs.map +0 -1
  1640. package/dist/version-B57E4Uo7.mjs +0 -7
  1641. package/dist/version-B57E4Uo7.mjs.map +0 -1
  1642. package/dist/widgets-wQ7Xcgq8.mjs +0 -126
  1643. package/dist/widgets-wQ7Xcgq8.mjs.map +0 -1
  1644. package/dist/wxr-taxonomies-DIHfvEDt.mjs +0 -406
  1645. package/dist/wxr-taxonomies-DIHfvEDt.mjs.map +0 -1
  1646. package/dist/wxr-taxonomies-DU2ZSiGc.d.mts +0 -34
  1647. package/dist/wxr-taxonomies-DU2ZSiGc.d.mts.map +0 -1
  1648. package/dist/zod-generator-D_yHIWfs.mjs +0 -329
  1649. package/dist/zod-generator-D_yHIWfs.mjs.map +0 -1
  1650. /package/dist/{ssrf-BRpTDMV6.mjs → ssrf-DpBH7aOt.mjs} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.mjs","names":["hasScope"],"sources":["../../../../src/mcp/server.ts","../../../../src/astro/routes/api/mcp.ts"],"sourcesContent":["/**\n * EmDash MCP Server\n *\n * Exposes content, schema, media, search, taxonomy, and menu operations\n * as MCP tools over the Streamable HTTP transport.\n *\n * Tools use the EmDashHandlers interface (same as locals.emdash) so\n * they work with the pre-bound handlers that the middleware provides.\n * The handlers instance is passed per-request via authInfo on the transport.\n */\n\nimport type { Permission, RoleLevel } from \"@emdash-cms/auth\";\nimport { canActOnOwn, hasPermission, Permissions, Role } from \"@emdash-cms/auth\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { APIContext } from \"astro\";\nimport { z } from \"zod\";\n\nimport {\n\tbylineCreateBody,\n\tbylineUpdateBody,\n\tCONTENT_TYPE_RE,\n\tcontentBylineInputSchema,\n\tcontentSeoInput,\n\tcreateCollectionBody,\n\tcreateTaxonomyDefBody,\n\tupdateCollectionBody,\n\tupdateFieldBody,\n\tupdateTaxonomyDefBody,\n} from \"#api/schemas.js\";\n\nimport type { MediaUsageRepairRequest } from \"../api/schemas/media-usage.js\";\nimport type { EmDashHandlers } from \"../astro/types.js\";\nimport { hasScope } from \"../auth/api-tokens.js\";\nimport { menuTag, siteSettingsTag, taxonomyTag } from \"../cache/chrome-tags.js\";\nimport { convertDataForRead, convertDataForWrite } from \"../client/portable-text.js\";\nimport type { FieldSchema } from \"../client/portable-text.js\";\nimport { decodeCursor, InvalidCursorError } from \"../database/repositories/types.js\";\nimport type { RouteCallerInput } from \"../plugins/routes.js\";\nimport { decodeBase64, encodeBase64 } from \"../utils/base64.js\";\n\nconst COLLECTION_SLUG_PATTERN = /^[a-z][a-z0-9_]*$/;\n/** http(s) scheme matcher used by `settings_update` URL validation. */\nconst HTTP_SCHEME_PATTERN = /^https?:\\/\\//i;\n/**\n * Shared wording for the `_rev` parameter on write tools. Agents only see the\n * tool schema, so the retry protocol is stated here.\n */\nconst REV_PARAM_DESCRIPTION =\n\t\"Revision token proving you have read the current item. Call content_get \" +\n\t\"first and pass back the _rev it returns. If this call fails with CONFLICT \" +\n\t\"the item changed in the meantime: call content_get again and retry with \" +\n\t\"the new token.\";\n\n/**\n * Replaces Zod's \"expected string, received undefined\" for a caller that never\n * read the schema, so the message says where the token comes from.\n */\nconst REV_MISSING_ERROR =\n\t\"_rev is required: call content_get for this item and pass back the _rev it returns.\";\n\nconst TAXONOMY_CURSOR_VERSION = 2;\nconst MAX_TAXONOMY_CURSOR_LENGTH = 2048;\nconst contentDateTimeInputSchema = z.iso\n\t.datetime({ offset: true, message: \"must be an ISO 8601 datetime\" })\n\t.or(\n\t\tz.iso.datetime({\n\t\t\toffset: true,\n\t\t\tprecision: -1,\n\t\t\tmessage: \"must be an ISO 8601 datetime\",\n\t\t}),\n\t);\n\n// ---------------------------------------------------------------------------\n// Shared schemas — kept in sync with `api/schemas/settings.ts` (which the\n// REST handler validates against). Defined inline to match the rest of the\n// MCP tool registrations rather than reaching across into the REST layer.\n// ---------------------------------------------------------------------------\n\nconst settingsMediaReferenceSchema = z.object({\n\tmediaId: z.string().describe(\"Media item ID (use media_create or media_list)\"),\n\talt: z.string().optional().describe(\"Alt text for the media reference\"),\n});\n\nconst settingsSocialSchema = z.object({\n\ttwitter: z.string().optional(),\n\tgithub: z.string().optional(),\n\tfacebook: z.string().optional(),\n\tinstagram: z.string().optional(),\n\tlinkedin: z.string().optional(),\n\tyoutube: z.string().optional(),\n});\n\nconst settingsSeoSchema = z.object({\n\ttitleSeparator: z\n\t\t.string()\n\t\t.max(10)\n\t\t.optional()\n\t\t.describe(\"Separator between page title and site title (e.g. ' | ')\"),\n\tdefaultOgImage: settingsMediaReferenceSchema\n\t\t.optional()\n\t\t.describe(\"Default Open Graph image when content has none\"),\n\trobotsTxt: z\n\t\t.string()\n\t\t.max(5000)\n\t\t.optional()\n\t\t.describe(\"Custom robots.txt body. Leave unset for the EmDash default.\"),\n\tgoogleVerification: z\n\t\t.string()\n\t\t.max(100)\n\t\t.optional()\n\t\t.describe(\"Google Search Console verification token\"),\n\tbingVerification: z\n\t\t.string()\n\t\t.max(100)\n\t\t.optional()\n\t\t.describe(\"Bing Webmaster Tools verification token\"),\n});\n\nconst mediaUsageRepairToolSchema = z\n\t.object({\n\t\tscope: z.enum([\"collection\", \"all\"]).describe(\"Repair one collection or all collections\"),\n\t\tcollection: z\n\t\t\t.string()\n\t\t\t.min(1)\n\t\t\t.max(63)\n\t\t\t.regex(COLLECTION_SLUG_PATTERN, \"Invalid collection slug\")\n\t\t\t.optional()\n\t\t\t.describe(\"Collection slug; required only when scope is collection\"),\n\t})\n\t.strict()\n\t.superRefine((input, ctx) => {\n\t\tif (input.scope === \"collection\" && input.collection === undefined) {\n\t\t\tctx.addIssue({\n\t\t\t\tcode: \"custom\",\n\t\t\t\tpath: [\"collection\"],\n\t\t\t\tmessage: \"Collection is required when scope is collection\",\n\t\t\t});\n\t\t}\n\t\tif (input.scope === \"all\" && input.collection !== undefined) {\n\t\t\tctx.addIssue({\n\t\t\t\tcode: \"custom\",\n\t\t\t\tpath: [\"collection\"],\n\t\t\t\tmessage: \"Collection must be omitted when scope is all\",\n\t\t\t});\n\t\t}\n\t});\n\nconst schemaUpdateCollectionToolSchema = z.object({\n\tslug: z\n\t\t.string()\n\t\t.min(1)\n\t\t.max(63)\n\t\t.regex(COLLECTION_SLUG_PATTERN, \"Invalid collection slug\")\n\t\t.describe(\"Collection slug to update; the slug itself cannot be changed\"),\n\tlabel: updateCollectionBody.shape.label.describe(\"New plural display name\"),\n\tlabelSingular: updateCollectionBody.shape.labelSingular.describe(\"New singular display name\"),\n\tdescription: updateCollectionBody.shape.description.describe(\"New collection description\"),\n\ticon: updateCollectionBody.shape.icon.describe(\"New admin UI icon name\"),\n\tsupports: updateCollectionBody.shape.supports.describe(\n\t\t\"Complete feature list to enable; omit to preserve the current list\",\n\t),\n\turlPattern: updateCollectionBody.shape.urlPattern.describe(\n\t\t\"New public URL pattern; pass null to clear it\",\n\t),\n\troutable: updateCollectionBody.shape.routable.describe(\n\t\t\"Whether entries require a slug before they can be published\",\n\t),\n\thasSeo: updateCollectionBody.shape.hasSeo.describe(\n\t\t\"Whether the collection supports SEO metadata\",\n\t),\n\tgroup: updateCollectionBody.shape.group.describe(\n\t\t\"Admin sidebar folder shared with other collections of the same group; pass null to move the collection back inline\",\n\t),\n\tcommentsEnabled: updateCollectionBody.shape.commentsEnabled.describe(\n\t\t\"Whether comments are enabled for this collection\",\n\t),\n\tcommentsModeration: updateCollectionBody.shape.commentsModeration.describe(\n\t\t\"Comment moderation policy\",\n\t),\n\tcommentsClosedAfterDays: updateCollectionBody.shape.commentsClosedAfterDays.describe(\n\t\t\"Close comments after this many days; 0 keeps them open\",\n\t),\n\tcommentsAutoApproveUsers: updateCollectionBody.shape.commentsAutoApproveUsers.describe(\n\t\t\"Whether comments from authenticated users are automatically approved\",\n\t),\n\teditLocking: updateCollectionBody.shape.editLocking.describe(\n\t\t\"Whether opening an entry takes an edit lock that refuses other editors' writes\",\n\t),\n\ttitleField: updateCollectionBody.shape.titleField.describe(\n\t\t\"Field slug to use as the Title column in admin lists; pass null to fall back to the default\",\n\t),\n\tdateField: updateCollectionBody.shape.dateField.describe(\n\t\t\"Datetime field slug to use as the Date column in admin lists; pass null to fall back to the default\",\n\t),\n});\n\nconst schemaUpdateFieldToolSchema = z.object({\n\tcollection: z\n\t\t.string()\n\t\t.min(1)\n\t\t.max(63)\n\t\t.regex(COLLECTION_SLUG_PATTERN, \"Invalid collection slug\")\n\t\t.describe(\"Collection slug containing the field\"),\n\tfieldSlug: z\n\t\t.string()\n\t\t.min(1)\n\t\t.max(63)\n\t\t.regex(COLLECTION_SLUG_PATTERN, \"Invalid field slug\")\n\t\t.describe(\"Field slug to update; the slug itself cannot be changed\"),\n\tlabel: updateFieldBody.shape.label.describe(\"New display name\"),\n\ttype: updateFieldBody.shape.type.describe(\n\t\t\"New field type; only string, text, and slug aliases can be changed in place\",\n\t),\n\trequired: updateFieldBody.shape.required.describe(\n\t\t\"Whether the field is required; changing this requires a manual content migration\",\n\t),\n\tunique: updateFieldBody.shape.unique.describe(\n\t\t\"Whether field values must be unique; changing this requires a manual content migration\",\n\t),\n\tdefaultValue: updateFieldBody.shape.defaultValue.describe(\"Default value for new content\"),\n\tvalidation: updateFieldBody.shape.validation.describe(\n\t\t\"Validation constraints; pass null to clear existing constraints\",\n\t),\n\twidget: updateFieldBody.shape.widget.describe(\"Admin editor widget name\"),\n\toptions: updateFieldBody.shape.options.describe(\"Widget configuration\"),\n\tsortOrder: updateFieldBody.shape.sortOrder.describe(\"Field order in the content editor\"),\n\tsearchable: updateFieldBody.shape.searchable.describe(\n\t\t\"Whether full-text search indexes the field\",\n\t),\n\ttranslatable: updateFieldBody.shape.translatable.describe(\n\t\t\"Whether values vary by locale; changing to false requires a manual content migration\",\n\t),\n\tindexed: updateFieldBody.shape.indexed.describe(\n\t\t\"Create or remove a physical index for structured sorting\",\n\t),\n});\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\ntype HandlerResult = {\n\tsuccess: boolean;\n\tdata?: unknown;\n\terror?: unknown;\n};\n\ntype SuccessEnvelope = {\n\tcontent: Array<{ type: \"text\"; text: string }>;\n\tstructuredContent?: Record<string, unknown>;\n\t_meta?: Record<string, unknown>;\n};\n\ntype ErrorEnvelope = {\n\tcontent: Array<{ type: \"text\"; text: string }>;\n\tisError: true;\n\t_meta: { code: string; details?: Record<string, unknown> };\n};\n\ntype TaxonomyListCursor = { id: string };\n\nfunction encodeTaxonomyCursor(term: { id: string }): string {\n\tconst cursor = encodeBase64(\n\t\tJSON.stringify({\n\t\t\tv: TAXONOMY_CURSOR_VERSION,\n\t\t\tid: term.id,\n\t\t}),\n\t);\n\tif (cursor.length > MAX_TAXONOMY_CURSOR_LENGTH) {\n\t\tthrow new InvalidCursorError(cursor);\n\t}\n\treturn cursor;\n}\n\nfunction decodeTaxonomyCursor(cursor: string): TaxonomyListCursor {\n\tif (!cursor || cursor.length > MAX_TAXONOMY_CURSOR_LENGTH) {\n\t\tthrow new InvalidCursorError(cursor);\n\t}\n\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(decodeBase64(cursor));\n\t} catch {\n\t\tthrow new InvalidCursorError(cursor);\n\t}\n\n\tif (parsed === null || typeof parsed !== \"object\") {\n\t\tthrow new InvalidCursorError(cursor);\n\t}\n\n\tconst candidate = parsed as Record<string, unknown>;\n\tif (\"v\" in candidate) {\n\t\tconst { v, id } = candidate;\n\t\tif (\n\t\t\tv !== TAXONOMY_CURSOR_VERSION ||\n\t\t\ttypeof id !== \"string\" ||\n\t\t\tid.length === 0 ||\n\t\t\tid.includes(\"\\0\")\n\t\t) {\n\t\t\tthrow new InvalidCursorError(cursor);\n\t\t}\n\t\treturn { id };\n\t}\n\n\tconst legacy = decodeCursor(cursor);\n\tif (legacy.orderValue.includes(\"\\0\") || legacy.id.length === 0 || legacy.id.includes(\"\\0\")) {\n\t\tthrow new InvalidCursorError(cursor);\n\t}\n\treturn { id: legacy.id };\n}\n\n/**\n * Return a successful tool response with the data as pretty-printed JSON.\n */\nfunction respondData(data: unknown): SuccessEnvelope {\n\treturn {\n\t\tcontent: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n\t};\n}\n\n/**\n * Return a structured error tool response.\n *\n * The error code is emitted both in the human-readable message (as a stable\n * `[CODE]` prefix that callers can match on) and in `_meta.code` so MCP-aware\n * clients can read it programmatically once the SDK supports forwarding meta.\n */\nfunction respondError(\n\tcode: string,\n\tmessage: string,\n\tdetails?: Record<string, unknown>,\n): ErrorEnvelope {\n\tconst text = `[${code}] ${message}`;\n\tconst meta: { code: string; details?: Record<string, unknown> } = { code };\n\tif (details !== undefined) meta.details = details;\n\treturn {\n\t\tcontent: [{ type: \"text\", text }],\n\t\tisError: true,\n\t\t_meta: meta,\n\t};\n}\n\n/**\n * Auth/permission errors thrown from `requireScope` / `requireRole` /\n * `requireOwnership` / `requireDraftAccess`. Carries a stable string `code`\n * field so `respondHandlerError` can surface it through `_meta.code` and\n * the message prefix.\n *\n * Distinct from `McpError` (which the SDK catches at JSON-RPC level — the\n * code there is numeric, not a stable EmDash error code).\n */\nclass EmDashAuthError extends Error {\n\toverride readonly name = \"EmDashAuthError\";\n\tconstructor(\n\t\tmessage: string,\n\t\treadonly code: string,\n\t) {\n\t\tsuper(message);\n\t}\n}\n\n/**\n * Map an unknown thrown error to a structured error envelope.\n *\n * Recognises (in priority order):\n * - `EmDashAuthError` — `code` is a stable EmDash auth code\n * (`UNAUTHORIZED`, `INSUFFICIENT_SCOPE`, `INSUFFICIENT_PERMISSIONS`).\n * - `Error` objects with an `apiError: { code, details? }` annotation\n * (handlers throw these for NOT_FOUND / CONFLICT inside transactions;\n * see `api/handlers/content.ts:538`).\n * - `SchemaError` (and any error with a string `code` field) — the code\n * is forwarded verbatim. `details` is forwarded too if present.\n * - Plain `Error` instances — message preserved, code falls back to\n * `fallbackCode` (or `INTERNAL_ERROR`).\n * - Strings — used directly as the message.\n * - Anything else — coerced via `String()`.\n *\n * The original message is always preserved so tests and humans can see the\n * specific failure cause. Numeric `code` values (e.g. on `McpError`) are\n * ignored — the field is reserved for stable string codes.\n */\nfunction respondHandlerError(error: unknown, fallbackCode = \"INTERNAL_ERROR\"): ErrorEnvelope {\n\tlet code = fallbackCode;\n\tlet message: string;\n\tlet details: Record<string, unknown> | undefined;\n\n\tif (error instanceof EmDashAuthError) {\n\t\tmessage = error.message || fallbackCode;\n\t\tcode = error.code;\n\t} else if (error instanceof Error) {\n\t\tmessage = error.message || fallbackCode;\n\t\tconst apiError = (error as { apiError?: { code?: string; details?: unknown } }).apiError;\n\t\tif (apiError && typeof apiError.code === \"string\" && apiError.code) {\n\t\t\tcode = apiError.code;\n\t\t\tif (apiError.details && typeof apiError.details === \"object\") {\n\t\t\t\tdetails = apiError.details as Record<string, unknown>;\n\t\t\t}\n\t\t} else {\n\t\t\t// Errors that carry their own `code` (SchemaError, custom errors).\n\t\t\t// Skip numeric codes (McpError, Node fs errors) — `_meta.code` is\n\t\t\t// reserved for stable string codes.\n\t\t\tconst rawCode = (error as { code?: unknown }).code;\n\t\t\tif (typeof rawCode === \"string\" && rawCode) {\n\t\t\t\tcode = rawCode;\n\t\t\t}\n\t\t\tconst rawDetails = (error as { details?: unknown }).details;\n\t\t\tif (rawDetails && typeof rawDetails === \"object\") {\n\t\t\t\tdetails = rawDetails as Record<string, unknown>;\n\t\t\t}\n\t\t}\n\t} else if (typeof error === \"string\") {\n\t\tmessage = error;\n\t} else {\n\t\tmessage = String(error);\n\t}\n\n\treturn respondError(code, message, details);\n}\n\n/**\n * Unwrap an ApiResult<T> into MCP tool result format.\n *\n * On success returns the data as JSON. On failure propagates the structured\n * `{ code, message, details }` from the handler so the caller sees both a\n * machine-readable code (in `_meta.code` and as a `[CODE]` message prefix)\n * and the original human-readable message.\n */\nfunction unwrap(result: HandlerResult): SuccessEnvelope | ErrorEnvelope {\n\tif (result.success && result.data !== undefined) {\n\t\treturn respondData(result.data);\n\t}\n\tconst err =\n\t\tresult.error && typeof result.error === \"object\"\n\t\t\t? (result.error as { code?: unknown; message?: unknown; details?: unknown })\n\t\t\t: undefined;\n\tif (!err) return respondError(\"INTERNAL_ERROR\", \"Unknown error\");\n\tconst code = typeof err.code === \"string\" && err.code ? err.code : \"INTERNAL_ERROR\";\n\tconst message = typeof err.message === \"string\" && err.message ? err.message : \"Unknown error\";\n\tconst details =\n\t\terr.details && typeof err.details === \"object\"\n\t\t\t? (err.details as Record<string, unknown>)\n\t\t\t: undefined;\n\treturn respondError(code, message, details);\n}\n\n/**\n * Return a JSON text block (success path for tools that don't go through\n * the ApiResult-returning handler layer, e.g. schema/menu/taxonomy).\n */\nfunction jsonResult(data: unknown): SuccessEnvelope {\n\treturn respondData(data);\n}\n\n// ---------------------------------------------------------------------------\n// Context extraction\n//\n// The route handler passes the runtime and authenticated user in authInfo.extra.\n// ---------------------------------------------------------------------------\n\ninterface EmDashExtra {\n\temdash: EmDashHandlers;\n\tuser: RouteCallerInput;\n\tuserId: string;\n\t/** The authenticated user's RBAC role level. */\n\tuserRole: RoleLevel;\n\t/** Token scopes — undefined for session auth (all access allowed). */\n\ttokenScopes?: string[];\n\t/** The route cache of the MCP request, used to invalidate the same tags the REST routes do. */\n\tcache?: APIContext[\"cache\"];\n}\n\nfunction isPublished(t: unknown): boolean {\n\treturn (\n\t\ttypeof t === \"object\" &&\n\t\tt !== null &&\n\t\t\"status\" in t &&\n\t\t(t as Record<string, unknown>).status === \"published\"\n\t);\n}\n\nfunction getExtra(extra: { authInfo?: { extra?: Record<string, unknown> } }): EmDashExtra {\n\tconst payload = extra.authInfo?.extra as EmDashExtra | undefined;\n\tif (!payload?.emdash) {\n\t\tthrow new Error(\"EmDash not available — server misconfigured\");\n\t}\n\treturn payload;\n}\n\nfunction getEmDash(extra: { authInfo?: { extra?: Record<string, unknown> } }): EmDashHandlers {\n\treturn getExtra(extra).emdash;\n}\n\n/**\n * Unwrap a write result, first invalidating `tags` in the route cache when the\n * write succeeded. Pass `changedEarlier` when an earlier step of the same tool\n * already changed live content, so a failure in a later step still invalidates.\n */\nasync function unwrapAndInvalidate(\n\textra: { authInfo?: { extra?: Record<string, unknown> } },\n\tresult: HandlerResult,\n\ttags: string[],\n\tchangedEarlier = false,\n): Promise<SuccessEnvelope | ErrorEnvelope> {\n\tif (result.success || changedEarlier) {\n\t\tconst { cache } = getExtra(extra);\n\t\tif (cache?.enabled) await cache.invalidate({ tags });\n\t}\n\treturn unwrap(result);\n}\n\nasync function getCollectionFields(\n\tec: EmDashHandlers,\n\tcollection: string,\n): Promise<FieldSchema[] | null> {\n\ttry {\n\t\tconst { SchemaRegistry } = await import(\"../schema/index.js\");\n\t\tconst col = await new SchemaRegistry(ec.db).getCollectionWithFields(collection);\n\t\treturn col ? col.fields : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Convert markdown strings to Portable Text for `portableText` fields on write.\n * Non-string values pass through, so callers may still send Portable Text. If\n * the schema can't be loaded, data is returned unchanged for the handler to\n * validate.\n */\nasync function convertWriteData(\n\tec: EmDashHandlers,\n\tcollection: string,\n\tdata: Record<string, unknown>,\n): Promise<Record<string, unknown>> {\n\tconst fields = await getCollectionFields(ec, collection);\n\tif (!fields) return data;\n\treturn convertDataForWrite(data, fields);\n}\n\n/**\n * Convert `portableText` field values on each item's `data` to markdown,\n * mutating in place. Inverse of {@link convertWriteData}, gated on the read\n * tools' `markdown` argument.\n */\nasync function applyReadMarkdown(\n\tec: EmDashHandlers,\n\tcollection: string,\n\titems: Array<Record<string, unknown>>,\n): Promise<void> {\n\tconst fields = await getCollectionFields(ec, collection);\n\tif (!fields) return;\n\tfor (const item of items) {\n\t\tif (item.data && typeof item.data === \"object\") {\n\t\t\titem.data = convertDataForRead(\n\t\t\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- narrowed by typeof check above\n\t\t\t\titem.data as Record<string, unknown>,\n\t\t\t\tfields,\n\t\t\t\tfalse,\n\t\t\t);\n\t\t}\n\t}\n}\n\nasync function invalidateBylines(): Promise<void> {\n\tconst { invalidateBylineCache } = await import(\"../bylines/index.js\");\n\tinvalidateBylineCache();\n}\n\n/**\n * Enforce a scope requirement on the current request.\n *\n * When tokenScopes is undefined (session auth), all operations are allowed\n * since session users have full access based on their role. When scopes are\n * present (token auth), the required scope must be included.\n */\nfunction requireScope(\n\textra: { authInfo?: { extra?: Record<string, unknown> } },\n\tscope: string,\n): void {\n\tconst payload = getExtra(extra);\n\tif (payload.tokenScopes && !hasScope(payload.tokenScopes, scope)) {\n\t\tthrow new EmDashAuthError(`Insufficient scope: requires ${scope}`, \"INSUFFICIENT_SCOPE\");\n\t}\n}\n\n/**\n * Defense-in-depth: enforce a minimum RBAC role on the current request.\n *\n * This is checked in addition to scope requirements. Even if a token has\n * the right scopes (e.g. due to a bug in scope clamping), the user's\n * actual role must still meet the minimum.\n */\nfunction requireRole(\n\textra: { authInfo?: { extra?: Record<string, unknown> } },\n\tminRole: RoleLevel,\n): void {\n\tconst payload = getExtra(extra);\n\tif (payload.userRole < minRole) {\n\t\tthrow new EmDashAuthError(\n\t\t\t\"Insufficient permissions for this operation\",\n\t\t\t\"INSUFFICIENT_PERMISSIONS\",\n\t\t);\n\t}\n}\n\n/**\n * Whether the current user may read non-published content (drafts, scheduled,\n * trashed, revisions, compare). SUBSCRIBER may hold content:read for\n * member-only published content but must not see drafts.\n */\nfunction canReadDrafts(extra: { authInfo?: { extra?: Record<string, unknown> } }): boolean {\n\tconst payload = getExtra(extra);\n\treturn hasPermission({ role: payload.userRole }, \"content:read_drafts\");\n}\n\n/**\n * Throw if the current user cannot read non-published content. Used by\n * editor-only views (revisions, compare, trash, preview-url).\n */\nfunction requireDraftAccess(extra: { authInfo?: { extra?: Record<string, unknown> } }): void {\n\tif (!canReadDrafts(extra)) {\n\t\tthrow new EmDashAuthError(\n\t\t\t\"Insufficient permissions for this operation\",\n\t\t\t\"INSUFFICIENT_PERMISSIONS\",\n\t\t);\n\t}\n}\n\n/**\n * Enforce ownership-based permission checks, mirroring the REST API's\n * requireOwnerPerm() pattern.\n *\n * If the user is the owner, checks ownPermission. Otherwise checks\n * anyPermission (which requires EDITOR+ role).\n */\nfunction requireOwnership(\n\textra: { authInfo?: { extra?: Record<string, unknown> } },\n\townerId: string,\n\townPermission: Permission,\n\tanyPermission: Permission,\n): void {\n\tconst payload = getExtra(extra);\n\tconst user = { id: payload.userId, role: payload.userRole };\n\tif (!canActOnOwn(user, ownerId, ownPermission, anyPermission)) {\n\t\tthrow new EmDashAuthError(\n\t\t\t\"Insufficient permissions for this operation\",\n\t\t\t\"INSUFFICIENT_PERMISSIONS\",\n\t\t);\n\t}\n}\n\n/**\n * Extract the author ID from a content handler response.\n *\n * Content handlers return `{ item: { id, authorId, ... }, _rev? }`.\n * This helper navigates that shape safely. Returns \"\" when authorId is\n * missing or non-string (e.g. seed-imported content with no author);\n * `canActOnOwn` then decides based on the caller's permissions —\n * an actor with `*:edit_any` succeeds, an actor with only `*:edit_own`\n * is denied with a clean permission error.\n */\nfunction extractContentAuthorId(data: unknown): string {\n\tif (!data || typeof data !== \"object\") return \"\";\n\tconst obj = data as Record<string, unknown>;\n\tconst item =\n\t\tobj.item && typeof obj.item === \"object\" ? (obj.item as Record<string, unknown>) : obj;\n\treturn typeof item?.authorId === \"string\" ? item.authorId : \"\";\n}\n\n/**\n * Extract the resolved ID from a content handler response.\n * Handles slug -> ID resolution performed by the handler.\n */\nfunction extractContentId(data: unknown): string | undefined {\n\tif (!data || typeof data !== \"object\") return undefined;\n\tconst obj = data as Record<string, unknown>;\n\tconst item =\n\t\tobj.item && typeof obj.item === \"object\" ? (obj.item as Record<string, unknown>) : obj;\n\treturn typeof item?.id === \"string\" ? item.id : undefined;\n}\n\n/** Extract the `_rev` token from a content handler response. */\nfunction extractContentRev(data: unknown): string | undefined {\n\tif (!data || typeof data !== \"object\") return undefined;\n\tconst rev = (data as Record<string, unknown>)._rev;\n\treturn typeof rev === \"string\" ? rev : undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Server factory\n// ---------------------------------------------------------------------------\n\nexport interface PluginMcpRegistration {\n\tpluginId: string;\n\tname: string;\n\tdescription: string;\n\troute: string;\n\tpermission: string;\n\tdestructive: boolean;\n\tinputSchema: z.ZodType;\n\toutputSchema?: z.ZodType;\n}\n\nexport function createMcpServer(\n\tpluginTools: PluginMcpRegistration[] = [],\n\trequest?: Request,\n): McpServer {\n\tconst server = new McpServer(\n\t\t{ name: \"emdash\", version: \"0.1.0\" },\n\t\t{ capabilities: { logging: {} } },\n\t);\n\n\t// Wrap every tool registration's callback so EmDashAuthError throws\n\t// (from requireScope / requireRole / requireOwnership / requireDraftAccess)\n\t// surface as structured `_meta.code`-bearing tool error envelopes\n\t// instead of the SDK's text-only fallback in createToolError().\n\t//\n\t// Type-erased on purpose — the SDK's overloads are too narrow for a\n\t// generic wrapper, but the runtime contract (callback returns the tool\n\t// result envelope) holds for every registered tool.\n\tconst originalRegisterTool = server.registerTool.bind(server);\n\t(server as { registerTool: typeof server.registerTool }).registerTool = ((\n\t\tname: string,\n\t\tconfig: unknown,\n\t\tcallback: (...callbackArgs: unknown[]) => Promise<SuccessEnvelope | ErrorEnvelope>,\n\t) => {\n\t\tconst wrapped = async (\n\t\t\t...callbackArgs: unknown[]\n\t\t): Promise<SuccessEnvelope | ErrorEnvelope> => {\n\t\t\ttry {\n\t\t\t\treturn await callback(...callbackArgs);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"INTERNAL_ERROR\");\n\t\t\t}\n\t\t};\n\t\treturn (\n\t\t\toriginalRegisterTool as unknown as (n: string, c: unknown, cb: typeof wrapped) => unknown\n\t\t)(name, config, wrapped);\n\t}) as typeof server.registerTool;\n\n\tfor (const tool of pluginTools) {\n\t\tif (!Object.hasOwn(Permissions, tool.permission)) continue;\n\t\tserver.registerTool(\n\t\t\t`${tool.pluginId}__${tool.name}`,\n\t\t\t{\n\t\t\t\tdescription: tool.description,\n\t\t\t\tinputSchema: tool.inputSchema,\n\t\t\t\toutputSchema: tool.outputSchema,\n\t\t\t\tannotations: { destructiveHint: tool.destructive },\n\t\t\t},\n\t\t\tasync (input, extra) => {\n\t\t\t\tconst payload = getExtra(extra);\n\t\t\t\tconst requiredScope = `mcp:tools:${tool.pluginId}`;\n\t\t\t\tif (payload.tokenScopes && !hasScope(payload.tokenScopes, requiredScope)) {\n\t\t\t\t\tif (request) {\n\t\t\t\t\t\tawait payload.emdash.handlePluginMcpDenied(\n\t\t\t\t\t\t\ttool.pluginId,\n\t\t\t\t\t\t\ttool.name,\n\t\t\t\t\t\t\ttool.route,\n\t\t\t\t\t\t\tpayload.userId,\n\t\t\t\t\t\t\trequest,\n\t\t\t\t\t\t\t`Missing scope: ${requiredScope}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tthrow new EmDashAuthError(\n\t\t\t\t\t\t`Insufficient scope: requires ${requiredScope}`,\n\t\t\t\t\t\t\"INSUFFICIENT_SCOPE\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (!hasPermission({ role: payload.userRole }, tool.permission as Permission)) {\n\t\t\t\t\tif (request) {\n\t\t\t\t\t\tawait payload.emdash.handlePluginMcpDenied(\n\t\t\t\t\t\t\ttool.pluginId,\n\t\t\t\t\t\t\ttool.name,\n\t\t\t\t\t\t\ttool.route,\n\t\t\t\t\t\t\tpayload.userId,\n\t\t\t\t\t\t\trequest,\n\t\t\t\t\t\t\t`Missing permission: ${tool.permission}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tthrow new EmDashAuthError(\n\t\t\t\t\t\t`Insufficient permission: requires ${tool.permission}`,\n\t\t\t\t\t\t\"INSUFFICIENT_PERMISSIONS\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (!request) return respondError(\"INTERNAL_ERROR\", \"Missing MCP request context\");\n\t\t\t\tconst routeCache = payload.cache;\n\t\t\t\tconst result = await payload.emdash.handlePluginMcpTool(\n\t\t\t\t\ttool.pluginId,\n\t\t\t\t\ttool.name,\n\t\t\t\t\ttool.route,\n\t\t\t\t\tinput,\n\t\t\t\t\tpayload.userId,\n\t\t\t\t\trequest,\n\t\t\t\t\tpayload.user,\n\t\t\t\t\trouteCache?.enabled ? (tags) => routeCache.invalidate({ tags }) : undefined,\n\t\t\t\t);\n\t\t\t\tif (!result.success) return unwrap(result);\n\t\t\t\tif (tool.outputSchema) {\n\t\t\t\t\tif (!result.data || typeof result.data !== \"object\" || Array.isArray(result.data)) {\n\t\t\t\t\t\treturn respondError(\n\t\t\t\t\t\t\t\"INVALID_PLUGIN_OUTPUT\",\n\t\t\t\t\t\t\t\"Plugin tool output must be an object when outputSchema is declared\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: JSON.stringify(result.data, null, 2) }],\n\t\t\t\t\t\tstructuredContent: result.data as Record<string, unknown>,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn respondData(result.data);\n\t\t\t},\n\t\t);\n\t}\n\n\t// =====================================================================\n\t// Content tools\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"content_list\",\n\t\t{\n\t\t\ttitle: \"List Content\",\n\t\t\tdescription:\n\t\t\t\t\"List content items in a collection with optional filtering and pagination. \" +\n\t\t\t\t\"Returns items sorted by the specified field. Use the nextCursor value from \" +\n\t\t\t\t\"the response to fetch the next page. Status can be 'draft', 'published', \" +\n\t\t\t\t\"or 'scheduled'. If no status is given, all non-trashed items are returned.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug (e.g. 'posts', 'pages')\"),\n\t\t\t\tstatus: z\n\t\t\t\t\t.enum([\"draft\", \"published\", \"scheduled\"])\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Filter by content status\"),\n\t\t\t\tlimit: z\n\t\t\t\t\t.number()\n\t\t\t\t\t.int()\n\t\t\t\t\t.min(1)\n\t\t\t\t\t.max(100)\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Max items to return (default 50, max 100)\"),\n\t\t\t\tcursor: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.min(1)\n\t\t\t\t\t.max(2048)\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Pagination cursor from a previous response\"),\n\t\t\t\torderBy: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Field to sort by (e.g. 'created_at', 'updated_at')\"),\n\t\t\t\torder: z.enum([\"asc\", \"desc\"]).optional().describe(\"Sort direction (default 'desc')\"),\n\t\t\t\tlocale: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Filter by locale (e.g. 'en', 'fr'). Only relevant when i18n is enabled.\"),\n\t\t\t\tmarkdown: z\n\t\t\t\t\t.boolean()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Return rich text (portableText) fields as Markdown strings instead of Portable Text arrays (default false).\",\n\t\t\t\t\t),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\t// Subscribers must only see published content; force the status\n\t\t\t// filter regardless of caller-supplied value.\n\t\t\tconst status = canReadDrafts(extra) ? args.status : \"published\";\n\t\t\tconst result = await ec.handleContentList(args.collection, {\n\t\t\t\tstatus,\n\t\t\t\tlimit: args.limit,\n\t\t\t\tcursor: args.cursor,\n\t\t\t\torderBy: args.orderBy,\n\t\t\t\torder: args.order,\n\t\t\t\tlocale: args.locale,\n\t\t\t});\n\t\t\tif (result.success && args.markdown) {\n\t\t\t\tconst payload = result.data;\n\t\t\t\tif (\n\t\t\t\t\tpayload &&\n\t\t\t\t\ttypeof payload === \"object\" &&\n\t\t\t\t\t\"items\" in payload &&\n\t\t\t\t\tArray.isArray(payload.items)\n\t\t\t\t) {\n\t\t\t\t\tawait applyReadMarkdown(ec, args.collection, payload.items);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn unwrap(result);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_get\",\n\t\t{\n\t\t\ttitle: \"Get Content\",\n\t\t\tdescription:\n\t\t\t\t\"Get a single content item by its ID or slug. Returns the full content data \" +\n\t\t\t\t\"including all field values, metadata, and a _rev token. content_update, \" +\n\t\t\t\t\"content_publish, content_unpublish and content_discard_draft require that \" +\n\t\t\t\t\"token, so read the item here before calling them.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug (e.g. 'posts', 'pages')\"),\n\t\t\t\tid: z.string().describe(\"Content item ID (ULID) or slug\"),\n\t\t\t\tlocale: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Locale to scope slug lookup (e.g. 'fr'). Only affects slug resolution; IDs are globally unique.\",\n\t\t\t\t\t),\n\t\t\t\tmarkdown: z\n\t\t\t\t\t.boolean()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Return rich text (portableText) fields as Markdown strings instead of Portable Text arrays (default false).\",\n\t\t\t\t\t),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\tconst result = await ec.handleContentGet(args.collection, args.id, args.locale);\n\t\t\t// Hide non-published items from users without draft access. Return a\n\t\t\t// not-found error so subscribers can't enumerate draft IDs by status.\n\t\t\tif (result.success && !canReadDrafts(extra)) {\n\t\t\t\tconst data =\n\t\t\t\t\tresult.data && typeof result.data === \"object\"\n\t\t\t\t\t\t? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- handler returns unknown data; narrowed by typeof check\n\t\t\t\t\t\t\t(result.data as Record<string, unknown>)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tconst item =\n\t\t\t\t\tdata?.item && typeof data.item === \"object\"\n\t\t\t\t\t\t? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- narrowed by typeof check\n\t\t\t\t\t\t\t(data.item as Record<string, unknown>)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tconst status = typeof item?.status === \"string\" ? item.status : null;\n\t\t\t\tif (status !== \"published\") {\n\t\t\t\t\treturn unwrap({\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\terror: { code: \"NOT_FOUND\", message: `Content item not found: ${args.id}` },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (result.success && args.markdown && result.data?.item) {\n\t\t\t\tawait applyReadMarkdown(ec, args.collection, [result.data.item]);\n\t\t\t}\n\t\t\treturn unwrap(result);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_create\",\n\t\t{\n\t\t\ttitle: \"Create Content\",\n\t\t\tdescription:\n\t\t\t\t\"Create a new content item in a collection. The 'data' object should \" +\n\t\t\t\t\"contain field values matching the collection's schema (use \" +\n\t\t\t\t\"schema_get_collection to check). For rich text (portableText) fields, \" +\n\t\t\t\t\"pass a Markdown string — converted to Portable Text automatically; prefer \" +\n\t\t\t\t\"this. Pass a Portable Text JSON array only for complex content Markdown \" +\n\t\t\t\t\"can't express (custom blocks, embeds). A slug is auto-generated if not \" +\n\t\t\t\t\"provided. Items are created as 'draft' by default — use content_publish \" +\n\t\t\t\t\"to make them live.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug (e.g. 'posts', 'pages')\"),\n\t\t\t\tdata: z\n\t\t\t\t\t.record(z.string(), z.unknown())\n\t\t\t\t\t.describe(\"Field values as key-value pairs matching the collection schema\"),\n\t\t\t\tslug: z.string().optional().describe(\"URL slug (auto-generated from title if omitted)\"),\n\t\t\t\tstatus: z\n\t\t\t\t\t.enum([\"draft\", \"published\"])\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Initial status (default 'draft'). Requires publish permission.\"),\n\t\t\t\tlocale: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Locale for this content (e.g. 'fr'). Defaults to default locale.\"),\n\t\t\t\ttranslationOf: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"ID of the content item this is a translation of. Links items in the same translation group.\",\n\t\t\t\t\t),\n\t\t\t\tbylines: z\n\t\t\t\t\t.array(contentBylineInputSchema)\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Bylines to credit. Each entry references an existing byline by id (see byline_list / byline_create) with an optional roleLabel. The first entry becomes the primary byline.\",\n\t\t\t\t\t),\n\t\t\t\ttaxonomies: z\n\t\t\t\t\t.record(z.string(), z.array(z.string()))\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Taxonomy term assignments as { taxonomyName: [termSlug, ...] }. Term slugs are resolved in the entry's locale. Call taxonomy_list to see available taxonomies and taxonomy_list_terms to look up slugs. Missing keys leave that taxonomy unchanged.\",\n\t\t\t\t\t),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: false },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.CONTRIBUTOR);\n\t\t\tconst { emdash, userId, userRole } = getExtra(extra);\n\t\t\tconst actor = { id: userId, role: userRole };\n\n\t\t\t// Creating a translation requires edit permission on the source item\n\t\t\tif (args.translationOf) {\n\t\t\t\tconst source = await emdash.handleContentGet(args.collection, args.translationOf);\n\t\t\t\tif (!source.success) return unwrap(source);\n\t\t\t\trequireOwnership(\n\t\t\t\t\textra,\n\t\t\t\t\textractContentAuthorId(source.data),\n\t\t\t\t\t\"content:edit_own\",\n\t\t\t\t\t\"content:edit_any\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst data = await convertWriteData(emdash, args.collection, args.data);\n\n\t\t\t// Publishing requires publish permission — create as draft then publish\n\t\t\tif (args.status === \"published\") {\n\t\t\t\tconst user = { id: userId, role: userRole };\n\t\t\t\tif (!hasPermission(user, \"content:publish_own\")) {\n\t\t\t\t\tthrow new EmDashAuthError(\n\t\t\t\t\t\t\"Insufficient permissions: publishing requires content:publish_own\",\n\t\t\t\t\t\t\"INSUFFICIENT_PERMISSIONS\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst result = await emdash.handleContentCreate(args.collection, {\n\t\t\t\t\tdata,\n\t\t\t\t\tslug: args.slug,\n\t\t\t\t\tauthorId: userId,\n\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\ttranslationOf: args.translationOf,\n\t\t\t\t\tbylines: args.bylines,\n\t\t\t\t\ttaxonomies: args.taxonomies,\n\t\t\t\t\tactor,\n\t\t\t\t});\n\t\t\t\tif (!result.success) return unwrap(result);\n\t\t\t\tconst itemId = extractContentId(result.data);\n\t\t\t\tif (itemId) {\n\t\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\t\textra,\n\t\t\t\t\t\tawait emdash.handleContentPublish(args.collection, itemId, {\n\t\t\t\t\t\t\tactor: { ...actor, source: \"mcp\" },\n\t\t\t\t\t\t\torigin: { source: \"mcp\" },\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t[args.collection, itemId],\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn unwrapAndInvalidate(extra, result, [args.collection]);\n\t\t\t}\n\n\t\t\treturn unwrapAndInvalidate(\n\t\t\t\textra,\n\t\t\t\tawait emdash.handleContentCreate(args.collection, {\n\t\t\t\t\tdata,\n\t\t\t\t\tslug: args.slug,\n\t\t\t\t\tauthorId: userId,\n\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\ttranslationOf: args.translationOf,\n\t\t\t\t\tbylines: args.bylines,\n\t\t\t\t\ttaxonomies: args.taxonomies,\n\t\t\t\t\tactor,\n\t\t\t\t}),\n\t\t\t\t[args.collection],\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_update\",\n\t\t{\n\t\t\ttitle: \"Update Content\",\n\t\t\tdescription:\n\t\t\t\t\"Update an existing content item. Only include fields you want to change \" +\n\t\t\t\t\"in the 'data' object — unspecified fields are left unchanged. Rich text \" +\n\t\t\t\t\"(portableText) fields accept a Markdown string (recommended, converted \" +\n\t\t\t\t\"automatically); use a Portable Text JSON array only for complex content \" +\n\t\t\t\t\"Markdown can't express (custom blocks, embeds). Requires the _rev \" +\n\t\t\t\t\"token from content_get, so read the item before updating it: the \" +\n\t\t\t\t\"update fails if the item changed since that read. When status is not \" +\n\t\t\t\t\"set, a change to a published item is staged as a draft, so the \" +\n\t\t\t\t\"response shows the new values while the live version keeps the old \" +\n\t\t\t\t\"ones until content_publish. \" +\n\t\t\t\t\"`seo` and `bylines` are persisted alongside the field updates in a \" +\n\t\t\t\t\"single transaction. `publishedAt` requires the content:publish_any \" +\n\t\t\t\t\"permission and is useful for migrations or correcting historical dates.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t\tlocale: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Locale to scope slug lookup (e.g. 'fr'). Only affects slug resolution; IDs are globally unique.\",\n\t\t\t\t\t),\n\t\t\t\tdata: z\n\t\t\t\t\t.record(z.string(), z.unknown())\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Field values to update (only include changed fields)\"),\n\t\t\t\tslug: z.string().optional().describe(\"New URL slug\"),\n\t\t\t\tstatus: z\n\t\t\t\t\t.enum([\"draft\", \"published\"])\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"New status. Setting to 'published' requires publish permission. Setting to 'draft' unpublishes the item and also requires publish permission.\",\n\t\t\t\t\t),\n\t\t\t\t// Reuse the REST schema rather than redefining inline. The REST schema's\n\t\t\t\t// `canonical` field is gated through `httpUrl` (validates the URL parses\n\t\t\t\t// AND has an http(s) scheme) which rejects javascript:/data: URIs that\n\t\t\t\t// would otherwise become stored XSS in the rendered <link rel=\"canonical\">.\n\t\t\t\t// Inlining a looser shape here would let MCP callers bypass that.\n\t\t\t\tseo: contentSeoInput\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Per-content SEO metadata. Only valid for collections with SEO enabled (see schema_get_collection.hasSeo). Fields not included are left unchanged; pass null to clear.\",\n\t\t\t\t\t),\n\t\t\t\tbylines: z\n\t\t\t\t\t.array(contentBylineInputSchema)\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Replace the byline list for this item. The first entry becomes the primary byline. Pass an empty array to clear all bylines.\",\n\t\t\t\t\t),\n\t\t\t\ttaxonomies: z\n\t\t\t\t\t.record(z.string(), z.array(z.string()))\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Replace taxonomy term assignments as { taxonomyName: [termSlug, ...] }. Term slugs are resolved in the entry's locale. Only named taxonomies are touched; other taxonomies are left unchanged. Pass an empty array to clear a taxonomy.\",\n\t\t\t\t\t),\n\t\t\t\tpublishedAt: contentDateTimeInputSchema\n\t\t\t\t\t.nullish()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Override the publication timestamp (ISO 8601). Requires content:publish_any permission. Pass null to clear. Useful for content migrations.\",\n\t\t\t\t\t),\n\t\t\t\t_rev: z.string({ error: REV_MISSING_ERROR }).describe(REV_PARAM_DESCRIPTION),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst { emdash, userId, userRole } = getExtra(extra);\n\t\t\tconst actor = { id: userId, role: userRole };\n\n\t\t\t// Fetch item to check ownership\n\t\t\tconst existing = await emdash.handleContentGet(args.collection, args.id, args.locale);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\tconst ownerId = extractContentAuthorId(existing.data);\n\t\t\trequireOwnership(extra, ownerId, \"content:edit_own\", \"content:edit_any\");\n\n\t\t\tconst data = args.data\n\t\t\t\t? await convertWriteData(emdash, args.collection, args.data)\n\t\t\t\t: args.data;\n\n\t\t\t// Writing publishedAt directly (incl. clearing to null) overwrites\n\t\t\t// historical record — gate behind publish_any, mirroring the REST PUT\n\t\t\t// route. Status-driven publishes are gated separately below.\n\t\t\tif (args.publishedAt !== undefined) {\n\t\t\t\tconst user = { id: userId, role: userRole };\n\t\t\t\tif (!hasPermission(user, \"content:publish_any\")) {\n\t\t\t\t\tthrow new EmDashAuthError(\n\t\t\t\t\t\t\"Setting publishedAt requires content:publish_any permission\",\n\t\t\t\t\t\t\"INSUFFICIENT_PERMISSIONS\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst resolvedId = extractContentId(existing.data) ?? args.id;\n\n\t\t\t// Status transitions route through dedicated handlers for proper revision management\n\t\t\tif (args.status === \"published\") {\n\t\t\t\trequireOwnership(extra, ownerId, \"content:publish_own\", \"content:publish_any\");\n\t\t\t\tlet rev: string | undefined = args._rev;\n\t\t\t\tlet liveChanged = false;\n\t\t\t\tif (\n\t\t\t\t\targs.data ||\n\t\t\t\t\targs.slug ||\n\t\t\t\t\targs.seo !== undefined ||\n\t\t\t\t\targs.bylines !== undefined ||\n\t\t\t\t\targs.taxonomies !== undefined ||\n\t\t\t\t\targs.publishedAt !== undefined\n\t\t\t\t) {\n\t\t\t\t\tconst updateResult = await emdash.handleContentUpdate(args.collection, resolvedId, {\n\t\t\t\t\t\tdata,\n\t\t\t\t\t\tslug: args.slug,\n\t\t\t\t\t\tactor,\n\t\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\t\tseo: args.seo,\n\t\t\t\t\t\tbylines: args.bylines,\n\t\t\t\t\t\ttaxonomies: args.taxonomies,\n\t\t\t\t\t\tpublishedAt: args.publishedAt,\n\t\t\t\t\t\t_rev: args._rev,\n\t\t\t\t\t});\n\t\t\t\t\tif (!updateResult.success) return unwrap(updateResult);\n\t\t\t\t\tliveChanged = updateResult.liveContentChanged !== false;\n\t\t\t\t\trev = extractContentRev(updateResult.data);\n\t\t\t\t}\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait emdash.handleContentPublish(args.collection, resolvedId, {\n\t\t\t\t\t\t_rev: rev,\n\t\t\t\t\t\tactor: { ...actor, source: \"mcp\" },\n\t\t\t\t\t\torigin: { source: \"mcp\" },\n\t\t\t\t\t}),\n\t\t\t\t\t[args.collection, resolvedId],\n\t\t\t\t\tliveChanged,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (args.status === \"draft\") {\n\t\t\t\trequireOwnership(extra, ownerId, \"content:publish_own\", \"content:publish_any\");\n\t\t\t\tlet rev: string | undefined = args._rev;\n\t\t\t\tlet liveChanged = false;\n\t\t\t\tif (\n\t\t\t\t\targs.data ||\n\t\t\t\t\targs.slug ||\n\t\t\t\t\targs.seo !== undefined ||\n\t\t\t\t\targs.bylines !== undefined ||\n\t\t\t\t\targs.taxonomies !== undefined ||\n\t\t\t\t\targs.publishedAt !== undefined\n\t\t\t\t) {\n\t\t\t\t\tconst updateResult = await emdash.handleContentUpdate(args.collection, resolvedId, {\n\t\t\t\t\t\tdata,\n\t\t\t\t\t\tslug: args.slug,\n\t\t\t\t\t\tactor,\n\t\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\t\tseo: args.seo,\n\t\t\t\t\t\tbylines: args.bylines,\n\t\t\t\t\t\ttaxonomies: args.taxonomies,\n\t\t\t\t\t\tpublishedAt: args.publishedAt,\n\t\t\t\t\t\t_rev: args._rev,\n\t\t\t\t\t});\n\t\t\t\t\tif (!updateResult.success) return unwrap(updateResult);\n\t\t\t\t\tliveChanged = updateResult.liveContentChanged !== false;\n\t\t\t\t\trev = extractContentRev(updateResult.data);\n\t\t\t\t}\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait emdash.handleContentUnpublish(args.collection, resolvedId, {\n\t\t\t\t\t\t_rev: rev,\n\t\t\t\t\t\tactor: { ...actor, source: \"mcp\" },\n\t\t\t\t\t\torigin: { source: \"mcp\" },\n\t\t\t\t\t}),\n\t\t\t\t\t[args.collection, resolvedId],\n\t\t\t\t\tliveChanged,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst result = await emdash.handleContentUpdate(args.collection, resolvedId, {\n\t\t\t\tdata,\n\t\t\t\tslug: args.slug,\n\t\t\t\tactor,\n\t\t\t\tlocale: args.locale,\n\t\t\t\tseo: args.seo,\n\t\t\t\tbylines: args.bylines,\n\t\t\t\ttaxonomies: args.taxonomies,\n\t\t\t\tpublishedAt: args.publishedAt,\n\t\t\t\t_rev: args._rev,\n\t\t\t});\n\t\t\tif (result.liveContentChanged === false) return unwrap(result);\n\t\t\treturn unwrapAndInvalidate(extra, result, [args.collection, resolvedId]);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_delete\",\n\t\t{\n\t\t\ttitle: \"Delete Content (Trash)\",\n\t\t\tdescription:\n\t\t\t\t\"Soft-delete a content item by moving it to the trash. The item can be \" +\n\t\t\t\t\"restored later with content_restore, or permanently deleted with \" +\n\t\t\t\t\"content_permanent_delete.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst ec = getEmDash(extra);\n\n\t\t\t// Fetch item to check ownership\n\t\t\tconst existing = await ec.handleContentGet(args.collection, args.id);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\trequireOwnership(\n\t\t\t\textra,\n\t\t\t\textractContentAuthorId(existing.data),\n\t\t\t\t\"content:delete_own\",\n\t\t\t\t\"content:delete_any\",\n\t\t\t);\n\n\t\t\tconst resolvedId = extractContentId(existing.data) ?? args.id;\n\t\t\treturn unwrapAndInvalidate(extra, await ec.handleContentDelete(args.collection, resolvedId), [\n\t\t\t\targs.collection,\n\t\t\t\tresolvedId,\n\t\t\t]);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_restore\",\n\t\t{\n\t\t\ttitle: \"Restore Content\",\n\t\t\tdescription:\n\t\t\t\t\"Restore a soft-deleted content item from the trash. It comes back as a draft \" +\n\t\t\t\t\"with no schedule, even if it was published or scheduled before it was trashed.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst ec = getEmDash(extra);\n\n\t\t\t// Fetch trashed item to check ownership\n\t\t\tconst existing = await ec.handleContentGetIncludingTrashed(args.collection, args.id);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\trequireOwnership(\n\t\t\t\textra,\n\t\t\t\textractContentAuthorId(existing.data),\n\t\t\t\t\"content:edit_own\",\n\t\t\t\t\"content:edit_any\",\n\t\t\t);\n\n\t\t\tconst resolvedId = extractContentId(existing.data) ?? args.id;\n\t\t\treturn unwrapAndInvalidate(\n\t\t\t\textra,\n\t\t\t\tawait ec.handleContentRestore(args.collection, resolvedId),\n\t\t\t\t[args.collection, resolvedId],\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_permanent_delete\",\n\t\t{\n\t\t\ttitle: \"Permanently Delete Content\",\n\t\t\tdescription:\n\t\t\t\t\"Permanently and irreversibly delete a trashed content item. The item \" +\n\t\t\t\t\"must be in the trash first (use content_delete). This cannot be undone.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\treturn unwrapAndInvalidate(\n\t\t\t\textra,\n\t\t\t\tawait ec.handleContentPermanentDelete(args.collection, args.id),\n\t\t\t\t[args.collection, args.id],\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_publish\",\n\t\t{\n\t\t\ttitle: \"Publish Content\",\n\t\t\tdescription:\n\t\t\t\t\"Publish a content item, making it live on the site. Creates a published \" +\n\t\t\t\t\"revision from the current draft. Further edits create a new draft without \" +\n\t\t\t\t\"affecting the live version until re-published. Pass `publishedAt` to \" +\n\t\t\t\t\"backdate (e.g. when migrating content from another CMS) — this requires \" +\n\t\t\t\t\"the content:publish_any permission. Without `publishedAt`, the existing \" +\n\t\t\t\t\"`published_at` is preserved on re-publish (idempotent) and falls back to \" +\n\t\t\t\t\"the current time on first publish.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t\t_rev: z.string({ error: REV_MISSING_ERROR }).describe(REV_PARAM_DESCRIPTION),\n\t\t\t\tpublishedAt: contentDateTimeInputSchema\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Override publication timestamp (ISO 8601). Requires content:publish_any permission. Useful when importing content with original publish dates.\",\n\t\t\t\t\t),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst { emdash, userId, userRole } = getExtra(extra);\n\n\t\t\t// Fetch item to check ownership\n\t\t\tconst existing = await emdash.handleContentGet(args.collection, args.id);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\tconst ownerId = extractContentAuthorId(existing.data);\n\t\t\trequireOwnership(extra, ownerId, \"content:publish_own\", \"content:publish_any\");\n\n\t\t\t// Backdating overwrites historical record — gate behind publish_any\n\t\t\t// regardless of ownership (mirrors the REST PUT route's publishedAt gate).\n\t\t\tif (args.publishedAt !== undefined) {\n\t\t\t\tconst user = { id: userId, role: userRole };\n\t\t\t\tif (!hasPermission(user, \"content:publish_any\")) {\n\t\t\t\t\tthrow new EmDashAuthError(\n\t\t\t\t\t\t\"Setting publishedAt requires content:publish_any permission\",\n\t\t\t\t\t\t\"INSUFFICIENT_PERMISSIONS\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst resolvedId = extractContentId(existing.data) ?? args.id;\n\t\t\treturn unwrapAndInvalidate(\n\t\t\t\textra,\n\t\t\t\tawait emdash.handleContentPublish(args.collection, resolvedId, {\n\t\t\t\t\tpublishedAt: args.publishedAt,\n\t\t\t\t\t_rev: args._rev,\n\t\t\t\t\tactor: { id: userId, role: userRole, source: \"mcp\" },\n\t\t\t\t\torigin: { source: \"mcp\" },\n\t\t\t\t}),\n\t\t\t\t[args.collection, resolvedId],\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_unpublish\",\n\t\t{\n\t\t\ttitle: \"Unpublish Content\",\n\t\t\tdescription:\n\t\t\t\t\"Unpublish a content item, reverting it to draft status. It will no \" +\n\t\t\t\t\"longer be visible on the live site, but its content and publication date are preserved. \" +\n\t\t\t\t\"Any pending schedule is cancelled.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t\t_rev: z.string({ error: REV_MISSING_ERROR }).describe(REV_PARAM_DESCRIPTION),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst { emdash: ec, userId, userRole } = getExtra(extra);\n\n\t\t\t// Fetch item to check ownership\n\t\t\tconst existing = await ec.handleContentGet(args.collection, args.id);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\trequireOwnership(\n\t\t\t\textra,\n\t\t\t\textractContentAuthorId(existing.data),\n\t\t\t\t\"content:publish_own\",\n\t\t\t\t\"content:publish_any\",\n\t\t\t);\n\n\t\t\tconst resolvedId = extractContentId(existing.data) ?? args.id;\n\t\t\treturn unwrapAndInvalidate(\n\t\t\t\textra,\n\t\t\t\tawait ec.handleContentUnpublish(args.collection, resolvedId, {\n\t\t\t\t\t_rev: args._rev,\n\t\t\t\t\tactor: { id: userId, role: userRole, source: \"mcp\" },\n\t\t\t\t\torigin: { source: \"mcp\" },\n\t\t\t\t}),\n\t\t\t\t[args.collection, resolvedId],\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_schedule\",\n\t\t{\n\t\t\ttitle: \"Schedule Content\",\n\t\t\tdescription:\n\t\t\t\t\"Schedule a content item for future publication. It will be automatically \" +\n\t\t\t\t\"published at the specified date/time. The scheduledAt value must be an \" +\n\t\t\t\t\"ISO 8601 datetime string in the future (e.g. '2025-06-01T09:00:00Z').\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t\t_rev: z.string({ error: REV_MISSING_ERROR }).describe(REV_PARAM_DESCRIPTION),\n\t\t\t\tscheduledAt: contentDateTimeInputSchema.describe(\n\t\t\t\t\t\"ISO 8601 datetime for publication (e.g. '2025-06-01T09:00:00Z')\",\n\t\t\t\t),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst { emdash: ec, userId, userRole } = getExtra(extra);\n\n\t\t\t// Fetch item to check ownership\n\t\t\tconst existing = await ec.handleContentGet(args.collection, args.id);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\trequireOwnership(\n\t\t\t\textra,\n\t\t\t\textractContentAuthorId(existing.data),\n\t\t\t\t\"content:publish_own\",\n\t\t\t\t\"content:publish_any\",\n\t\t\t);\n\n\t\t\tconst resolvedId = extractContentId(existing.data) ?? args.id;\n\t\t\treturn unwrapAndInvalidate(\n\t\t\t\textra,\n\t\t\t\tawait ec.handleContentSchedule(args.collection, resolvedId, args.scheduledAt, {\n\t\t\t\t\t_rev: args._rev,\n\t\t\t\t\tactor: { id: userId, role: userRole, source: \"mcp\" },\n\t\t\t\t\torigin: { source: \"mcp\" },\n\t\t\t\t}),\n\t\t\t\t[args.collection, resolvedId],\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_unschedule\",\n\t\t{\n\t\t\ttitle: \"Cancel Scheduled Publication\",\n\t\t\tdescription:\n\t\t\t\t\"Cancel a previously scheduled publication. Scheduled drafts return to draft status; \" +\n\t\t\t\t\"published items stay published. The scheduledAt timestamp is cleared. Idempotent — \" +\n\t\t\t\t\"calling on an item that isn't scheduled is a no-op.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst ec = getEmDash(extra);\n\n\t\t\tconst existing = await ec.handleContentGet(args.collection, args.id);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\trequireOwnership(\n\t\t\t\textra,\n\t\t\t\textractContentAuthorId(existing.data),\n\t\t\t\t\"content:publish_own\",\n\t\t\t\t\"content:publish_any\",\n\t\t\t);\n\n\t\t\tconst resolvedId = extractContentId(existing.data) ?? args.id;\n\t\t\treturn unwrapAndInvalidate(\n\t\t\t\textra,\n\t\t\t\tawait ec.handleContentUnschedule(args.collection, resolvedId),\n\t\t\t\t[args.collection, resolvedId],\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_compare\",\n\t\t{\n\t\t\ttitle: \"Compare Live vs Draft\",\n\t\t\tdescription:\n\t\t\t\t\"Compare the published (live) version of a content item with its current \" +\n\t\t\t\t\"draft. Returns both versions and a flag indicating whether there are \" +\n\t\t\t\t\"changes. Useful for reviewing unpublished edits before publishing.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\trequireDraftAccess(extra);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\treturn unwrap(await ec.handleContentCompare(args.collection, args.id));\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_discard_draft\",\n\t\t{\n\t\t\ttitle: \"Discard Draft\",\n\t\t\tdescription:\n\t\t\t\t\"Discard the current draft revision. Published content reverts to its live \" +\n\t\t\t\t\"version; an item without a pending draft is unchanged.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t\t_rev: z.string({ error: REV_MISSING_ERROR }).describe(REV_PARAM_DESCRIPTION),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst ec = getEmDash(extra);\n\n\t\t\t// Fetch item to check ownership\n\t\t\tconst existing = await ec.handleContentGet(args.collection, args.id);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\trequireOwnership(\n\t\t\t\textra,\n\t\t\t\textractContentAuthorId(existing.data),\n\t\t\t\t\"content:edit_own\",\n\t\t\t\t\"content:edit_any\",\n\t\t\t);\n\n\t\t\tconst resolvedId = extractContentId(existing.data) ?? args.id;\n\t\t\treturn unwrapAndInvalidate(\n\t\t\t\textra,\n\t\t\t\tawait ec.handleContentDiscardDraft(args.collection, resolvedId, { _rev: args._rev }),\n\t\t\t\t[args.collection, resolvedId],\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_list_trashed\",\n\t\t{\n\t\t\ttitle: \"List Trashed Content\",\n\t\t\tdescription:\n\t\t\t\t\"List soft-deleted content items in a collection's trash. These items \" +\n\t\t\t\t\"can be restored with content_restore or permanently deleted with \" +\n\t\t\t\t\"content_permanent_delete.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tlimit: z.number().int().min(1).max(100).optional().describe(\"Max items (default 50)\"),\n\t\t\t\tcursor: z.string().min(1).max(2048).optional().describe(\"Pagination cursor\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\trequireDraftAccess(extra);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\treturn unwrap(\n\t\t\t\tawait ec.handleContentListTrashed(args.collection, {\n\t\t\t\t\tlimit: args.limit,\n\t\t\t\t\tcursor: args.cursor,\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_duplicate\",\n\t\t{\n\t\t\ttitle: \"Duplicate Content\",\n\t\t\tdescription:\n\t\t\t\t\"Create a copy of an existing content item. The duplicate is created \" +\n\t\t\t\t\"as a draft with '(Copy)' appended to the title and an auto-generated slug.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug to duplicate\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.CONTRIBUTOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\treturn unwrapAndInvalidate(extra, await ec.handleContentDuplicate(args.collection, args.id), [\n\t\t\t\targs.collection,\n\t\t\t]);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_translations\",\n\t\t{\n\t\t\ttitle: \"Get Content Translations\",\n\t\t\tdescription:\n\t\t\t\t\"Get all locale variants of a content item. Returns the translation group \" +\n\t\t\t\t\"and a summary of each locale version (id, locale, slug, status). Only \" +\n\t\t\t\t\"relevant when i18n is enabled on the site.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\tconst result = await ec.handleContentTranslations(args.collection, args.id);\n\t\t\t// Filter out non-published translations for users without draft\n\t\t\t// access so a subscriber can't enumerate locales that aren't yet live.\n\t\t\tif (result.success && !canReadDrafts(extra)) {\n\t\t\t\tconst data =\n\t\t\t\t\tresult.data && typeof result.data === \"object\"\n\t\t\t\t\t\t? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- handler returns unknown data; narrowed by typeof check\n\t\t\t\t\t\t\t(result.data as Record<string, unknown>)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tconst translations = Array.isArray(data?.translations) ? data.translations : [];\n\t\t\t\tconst filtered = translations.filter(isPublished);\n\t\t\t\treturn unwrap({\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tdata: { ...data, translations: filtered },\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn unwrap(result);\n\t\t},\n\t);\n\n\t// =====================================================================\n\t// Byline tools\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"byline_list\",\n\t\t{\n\t\t\ttitle: \"List Bylines\",\n\t\t\tdescription:\n\t\t\t\t\"List bylines (author/contributor credits) with optional filtering and \" +\n\t\t\t\t\"pagination. Bylines are standalone records referenced by content items; \" +\n\t\t\t\t\"use the returned id with content_create/content_update or byline_get. Use \" +\n\t\t\t\t\"the nextCursor value from the response to fetch the next page.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tsearch: z.string().optional().describe(\"Filter by display name or slug substring\"),\n\t\t\t\tisGuest: z.boolean().optional().describe(\"Filter by guest (true) or linked-user (false)\"),\n\t\t\t\tuserId: z.string().optional().describe(\"Filter to the byline linked to a CMS user ID\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Filter by locale (omit for all)\"),\n\t\t\t\tlimit: z.number().int().min(1).max(100).optional().describe(\"Max items (default 50)\"),\n\t\t\t\tcursor: z.string().min(1).max(2048).optional().describe(\"Pagination cursor\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { BylineRepository } = await import(\"../database/repositories/byline.js\");\n\t\t\t\tconst repo = new BylineRepository(ec.db);\n\t\t\t\treturn jsonResult(\n\t\t\t\t\tawait repo.findMany({\n\t\t\t\t\t\tsearch: args.search,\n\t\t\t\t\t\tisGuest: args.isGuest,\n\t\t\t\t\t\tuserId: args.userId,\n\t\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\t\tlimit: args.limit,\n\t\t\t\t\t\tcursor: args.cursor,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"BYLINE_LIST_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"byline_get\",\n\t\t{\n\t\t\ttitle: \"Get Byline\",\n\t\t\tdescription:\n\t\t\t\t\"Get a single byline by its ID, including bio, avatar, website, linked \" +\n\t\t\t\t\"user, and any custom fields.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tid: z.string().describe(\"Byline ID\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { BylineRepository } = await import(\"../database/repositories/byline.js\");\n\t\t\t\tconst byline = await new BylineRepository(ec.db).findById(args.id);\n\t\t\t\tif (!byline) return respondError(\"NOT_FOUND\", `Byline '${args.id}' not found`);\n\t\t\t\treturn jsonResult(byline);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"BYLINE_GET_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"byline_create\",\n\t\t{\n\t\t\ttitle: \"Create Byline\",\n\t\t\tdescription:\n\t\t\t\t\"Create a new byline (author/contributor credit). The slug must be unique \" +\n\t\t\t\t\"and contain only lowercase letters, digits, and hyphens. Link the byline \" +\n\t\t\t\t\"to a CMS user via userId, or leave it as a standalone guest credit. The \" +\n\t\t\t\t\"returned id can then be passed to content_create/content_update bylines.\",\n\t\t\tinputSchema: z.object({ ...bylineCreateBody.shape }),\n\t\t\tannotations: { destructiveHint: false },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleBylineCreate } = await import(\"../api/handlers/bylines.js\");\n\t\t\t\tconst result = await handleBylineCreate(ec.db, args);\n\t\t\t\tif (result.success) await invalidateBylines();\n\t\t\t\treturn unwrap(result);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"BYLINE_CREATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"byline_update\",\n\t\t{\n\t\t\ttitle: \"Update Byline\",\n\t\t\tdescription:\n\t\t\t\t\"Update an existing byline. Any field can be omitted to leave it \" +\n\t\t\t\t\"unchanged. Renaming the slug must not collide with another byline.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tid: z.string().describe(\"Byline ID to update\"),\n\t\t\t\t...bylineUpdateBody.shape,\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleBylineUpdate } = await import(\"../api/handlers/bylines.js\");\n\t\t\t\tconst { id, ...input } = args;\n\t\t\t\tconst result = await handleBylineUpdate(ec.db, id, input);\n\t\t\t\tif (result.success) await invalidateBylines();\n\t\t\t\treturn unwrap(result);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"BYLINE_UPDATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"byline_delete\",\n\t\t{\n\t\t\ttitle: \"Delete Byline\",\n\t\t\tdescription:\n\t\t\t\t\"Permanently delete a byline. Any content crediting this byline loses the \" +\n\t\t\t\t\"association, and it is cleared as a primary byline where set.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tid: z.string().describe(\"Byline ID to delete\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { BylineRepository } = await import(\"../database/repositories/byline.js\");\n\t\t\t\tconst deleted = await new BylineRepository(ec.db).delete(args.id);\n\t\t\t\tif (!deleted) return respondError(\"NOT_FOUND\", `Byline '${args.id}' not found`);\n\t\t\t\tawait invalidateBylines();\n\t\t\t\treturn jsonResult({ deleted: args.id });\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"BYLINE_DELETE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"byline_translations\",\n\t\t{\n\t\t\ttitle: \"List Byline Translations\",\n\t\t\tdescription:\n\t\t\t\t\"Return every locale variant of a byline, identified via its shared translation_group.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tid: z.string().describe(\"Byline id (or translation_group)\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleBylineTranslations } = await import(\"../api/handlers/bylines.js\");\n\t\t\t\treturn unwrap(await handleBylineTranslations(ec.db, args.id));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"BYLINE_TRANSLATIONS_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\t// =====================================================================\n\t// Schema tools\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"schema_list_collections\",\n\t\t{\n\t\t\ttitle: \"List Collections\",\n\t\t\tdescription:\n\t\t\t\t\"List all content collections defined in the CMS. Each collection \" +\n\t\t\t\t\"represents a content type (e.g. posts, pages, products) with its own \" +\n\t\t\t\t\"schema and database table. Returns slug, label, supported features, \" +\n\t\t\t\t\"and timestamps.\",\n\t\t\tinputSchema: z.object({}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (_args, extra) => {\n\t\t\trequireScope(extra, \"schema:read\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { SchemaRegistry } = await import(\"../schema/index.js\");\n\t\t\t\tconst registry = new SchemaRegistry(ec.db);\n\t\t\t\tconst items = await registry.listCollections();\n\t\t\t\treturn jsonResult({ items });\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"SCHEMA_LIST_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_get_collection\",\n\t\t{\n\t\t\ttitle: \"Get Collection Schema\",\n\t\t\tdescription:\n\t\t\t\t\"Get detailed info about a collection including all field definitions. \" +\n\t\t\t\t\"Fields describe the data model: name, type (string, text, number, \" +\n\t\t\t\t\"boolean, datetime, portableText, image, reference, json, select, \" +\n\t\t\t\t\"multiSelect, slug), constraints, and validation rules. Use this to \" +\n\t\t\t\t\"understand what data content_create and content_update expect.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tslug: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Collection slug (e.g. 'posts'). Use schema_list_collections to see available slugs.\",\n\t\t\t\t\t),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"schema:read\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { SchemaRegistry } = await import(\"../schema/index.js\");\n\t\t\t\tconst registry = new SchemaRegistry(ec.db);\n\t\t\t\tconst collection = await registry.getCollectionWithFields(args.slug);\n\t\t\t\tif (!collection) {\n\t\t\t\t\treturn respondError(\"NOT_FOUND\", `Collection '${args.slug}' not found`);\n\t\t\t\t}\n\t\t\t\treturn jsonResult(collection);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"SCHEMA_GET_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_create_collection\",\n\t\t{\n\t\t\ttitle: \"Create Collection\",\n\t\t\tdescription:\n\t\t\t\t\"Create a new content collection (content type). This creates a database \" +\n\t\t\t\t\"table and schema definition. The slug must be lowercase alphanumeric \" +\n\t\t\t\t\"with underscores, starting with a letter. Supports: 'drafts' (draft/\" +\n\t\t\t\t\"publish workflow), 'revisions' (version history), 'preview' (live \" +\n\t\t\t\t\"preview), 'scheduling' (timed publish), 'search' (full-text indexing), \" +\n\t\t\t\t\"and 'seo' (SEO metadata).\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tslug: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.regex(COLLECTION_SLUG_PATTERN)\n\t\t\t\t\t.describe(\"Unique identifier (lowercase letters, numbers, underscores)\"),\n\t\t\t\tlabel: z.string().describe(\"Display name (plural, e.g. 'Blog Posts')\"),\n\t\t\t\tlabelSingular: z.string().optional().describe(\"Singular display name (e.g. 'Blog Post')\"),\n\t\t\t\tdescription: z.string().optional().describe(\"Description of this collection\"),\n\t\t\t\ticon: z.string().optional().describe(\"Icon name for the admin UI\"),\n\t\t\t\tsupports: createCollectionBody.shape.supports.describe(\n\t\t\t\t\t\"Features to enable (default: ['drafts', 'revisions'])\",\n\t\t\t\t),\n\t\t\t\troutable: createCollectionBody.shape.routable.describe(\n\t\t\t\t\t\"Require a slug before publishing (default: true)\",\n\t\t\t\t),\n\t\t\t\teditLocking: createCollectionBody.shape.editLocking.describe(\n\t\t\t\t\t\"Take an edit lock when an entry is opened (default: true)\",\n\t\t\t\t),\n\t\t\t\tgroup: createCollectionBody.shape.group.describe(\n\t\t\t\t\t\"Admin sidebar folder shared with other collections of the same group\",\n\t\t\t\t),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"schema:write\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { SchemaRegistry } = await import(\"../schema/index.js\");\n\t\t\t\tconst registry = new SchemaRegistry(ec.db);\n\t\t\t\tconst collection = await registry.createCollection({\n\t\t\t\t\tslug: args.slug,\n\t\t\t\t\tlabel: args.label,\n\t\t\t\t\tlabelSingular: args.labelSingular,\n\t\t\t\t\tdescription: args.description,\n\t\t\t\t\ticon: args.icon,\n\t\t\t\t\t// SchemaRegistry.createCollection now defaults `supports` to\n\t\t\t\t\t// ['drafts', 'revisions'] when undefined; pass through verbatim.\n\t\t\t\t\tsupports: args.supports,\n\t\t\t\t\troutable: args.routable,\n\t\t\t\t\teditLocking: args.editLocking,\n\t\t\t\t\tgroup: args.group,\n\t\t\t\t});\n\t\t\t\tec.invalidateUrlPatternCache();\n\t\t\t\treturn jsonResult(collection);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"SCHEMA_CREATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_delete_collection\",\n\t\t{\n\t\t\ttitle: \"Delete Collection\",\n\t\t\tdescription:\n\t\t\t\t\"Delete a collection and its database table. This is irreversible and \" +\n\t\t\t\t\"deletes all content in the collection. Use with extreme caution.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tslug: z.string().describe(\"Collection slug to delete\"),\n\t\t\t\tforce: z\n\t\t\t\t\t.boolean()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Force deletion even if the collection has content (default false)\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"schema:write\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { SchemaRegistry } = await import(\"../schema/index.js\");\n\t\t\t\tconst registry = new SchemaRegistry(ec.db);\n\t\t\t\tawait registry.deleteCollection(args.slug, { force: args.force });\n\t\t\t\tec.invalidateUrlPatternCache();\n\t\t\t\treturn jsonResult({ deleted: args.slug });\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"SCHEMA_DELETE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_update_collection\",\n\t\t{\n\t\t\ttitle: \"Update Collection\",\n\t\t\tdescription:\n\t\t\t\t\"Update an existing collection without deleting its table, fields, or content. \" +\n\t\t\t\t\"Only provided settings change; omitted settings keep their current values. \" +\n\t\t\t\t\"The collection slug cannot be changed.\",\n\t\t\tinputSchema: schemaUpdateCollectionToolSchema,\n\t\t\tannotations: { destructiveHint: false },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"schema:write\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\tconst { slug, ...input } = args;\n\t\t\ttry {\n\t\t\t\tconst { handleSchemaCollectionUpdate } = await import(\"../api/handlers/schema.js\");\n\t\t\t\tconst result = await handleSchemaCollectionUpdate(ec.db, slug, input);\n\t\t\t\tif (result.success) ec.invalidateUrlPatternCache();\n\t\t\t\treturn unwrap(result);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"SCHEMA_UPDATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_create_field\",\n\t\t{\n\t\t\ttitle: \"Add Field to Collection\",\n\t\t\tdescription:\n\t\t\t\t\"Add a new field to a collection's schema. This adds a column to the \" +\n\t\t\t\t\"database table. Field types: string (short text), text (long text), \" +\n\t\t\t\t\"number (decimal), integer, boolean, datetime, select (single choice), \" +\n\t\t\t\t\"multiSelect (multiple), portableText (rich text), image, file, \" +\n\t\t\t\t\"reference (link to another collection), json, slug (URL-safe id). \" +\n\t\t\t\t\"For select/multiSelect, provide choices in validation.options array.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug to add the field to\"),\n\t\t\t\tslug: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.regex(COLLECTION_SLUG_PATTERN)\n\t\t\t\t\t.describe(\"Field identifier (lowercase letters, numbers, underscores)\"),\n\t\t\t\tlabel: z.string().describe(\"Display name for the field\"),\n\t\t\t\ttype: z\n\t\t\t\t\t.enum([\n\t\t\t\t\t\t\"string\",\n\t\t\t\t\t\t\"text\",\n\t\t\t\t\t\t\"number\",\n\t\t\t\t\t\t\"integer\",\n\t\t\t\t\t\t\"boolean\",\n\t\t\t\t\t\t\"datetime\",\n\t\t\t\t\t\t\"select\",\n\t\t\t\t\t\t\"multiSelect\",\n\t\t\t\t\t\t\"portableText\",\n\t\t\t\t\t\t\"image\",\n\t\t\t\t\t\t\"file\",\n\t\t\t\t\t\t\"reference\",\n\t\t\t\t\t\t\"json\",\n\t\t\t\t\t\t\"slug\",\n\t\t\t\t\t])\n\t\t\t\t\t.describe(\"Data type for this field\"),\n\t\t\t\trequired: z.boolean().optional().describe(\"Whether the field is required (default false)\"),\n\t\t\t\tunique: z.boolean().optional().describe(\"Whether values must be unique (default false)\"),\n\t\t\t\tdefaultValue: z.unknown().optional().describe(\"Default value for new items\"),\n\t\t\t\tvalidation: z\n\t\t\t\t\t.object({\n\t\t\t\t\t\tmin: z.number().optional(),\n\t\t\t\t\t\tmax: z.number().optional(),\n\t\t\t\t\t\tminLength: z.number().optional(),\n\t\t\t\t\t\tmaxLength: z.number().optional(),\n\t\t\t\t\t\tpattern: z.string().optional(),\n\t\t\t\t\t\toptions: z\n\t\t\t\t\t\t\t.array(z.string())\n\t\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t\t.describe(\"Allowed values for select/multiSelect\"),\n\t\t\t\t\t})\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Validation constraints\"),\n\t\t\t\toptions: z\n\t\t\t\t\t.object({\n\t\t\t\t\t\tcollection: z\n\t\t\t\t\t\t\t.string()\n\t\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t\t.describe(\"Target collection slug for reference fields\"),\n\t\t\t\t\t\trows: z.number().optional().describe(\"Number of rows for textarea\"),\n\t\t\t\t\t})\n\t\t\t\t\t.loose()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Widget configuration\"),\n\t\t\t\tsearchable: z\n\t\t\t\t\t.boolean()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Include in full-text search index (default false)\"),\n\t\t\t\tindexed: z.boolean().optional().describe(\"Create a physical index for structured sorting\"),\n\t\t\t\ttranslatable: z\n\t\t\t\t\t.boolean()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Whether this field is translatable (default true). \" +\n\t\t\t\t\t\t\t\"Non-translatable fields are synced across all locales in a translation group.\",\n\t\t\t\t\t),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"schema:write\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { SchemaRegistry } = await import(\"../schema/index.js\");\n\t\t\t\tconst registry = new SchemaRegistry(ec.db);\n\t\t\t\tconst field = await registry.createField(args.collection, {\n\t\t\t\t\tslug: args.slug,\n\t\t\t\t\tlabel: args.label,\n\t\t\t\t\ttype: args.type,\n\t\t\t\t\trequired: args.required,\n\t\t\t\t\tunique: args.unique,\n\t\t\t\t\tdefaultValue: args.defaultValue,\n\t\t\t\t\tvalidation: args.validation,\n\t\t\t\t\toptions: args.options,\n\t\t\t\t\tsearchable: args.searchable,\n\t\t\t\t\tindexed: args.indexed,\n\t\t\t\t\ttranslatable: args.translatable,\n\t\t\t\t});\n\t\t\t\treturn jsonResult(field);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"FIELD_CREATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_delete_field\",\n\t\t{\n\t\t\ttitle: \"Remove Field from Collection\",\n\t\t\tdescription:\n\t\t\t\t\"Remove a field from a collection. This drops the column from the \" +\n\t\t\t\t\"database table and deletes all data in that field. Irreversible.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tfieldSlug: z.string().describe(\"Field slug to remove\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"schema:write\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { SchemaRegistry } = await import(\"../schema/index.js\");\n\t\t\t\tconst registry = new SchemaRegistry(ec.db);\n\t\t\t\tawait registry.deleteField(args.collection, args.fieldSlug);\n\t\t\t\treturn jsonResult({ deleted: args.fieldSlug, collection: args.collection });\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"FIELD_DELETE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_update_field\",\n\t\t{\n\t\t\ttitle: \"Update Field\",\n\t\t\tdescription:\n\t\t\t\t\"Update an existing field without deleting its column or stored values. Only \" +\n\t\t\t\t\"provided settings change; omitted settings keep their current values. Changes \" +\n\t\t\t\t\"that require a content or column migration are rejected with migration guidance.\",\n\t\t\tinputSchema: schemaUpdateFieldToolSchema,\n\t\t\tannotations: { destructiveHint: false },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"schema:write\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\tconst { collection, fieldSlug, ...input } = args;\n\t\t\ttry {\n\t\t\t\tconst { handleSchemaFieldUpdate } = await import(\"../api/handlers/schema.js\");\n\t\t\t\treturn unwrap(await handleSchemaFieldUpdate(ec.db, collection, fieldSlug, input));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"SCHEMA_FIELD_UPDATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\t// =====================================================================\n\t// Media tools\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"media_list\",\n\t\t{\n\t\t\ttitle: \"List Media\",\n\t\t\tdescription:\n\t\t\t\t\"List uploaded media files (images, documents, etc.) with optional MIME \" +\n\t\t\t\t\"type filtering and pagination. Returns file metadata including filename, \" +\n\t\t\t\t\"URL, dimensions, and alt text.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tmimeType: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Filter by MIME type prefix (e.g. 'image/', 'application/pdf')\"),\n\t\t\t\tlimit: z.number().int().min(1).max(100).optional().describe(\"Max items (default 50)\"),\n\t\t\t\tcursor: z.string().min(1).max(2048).optional().describe(\"Pagination cursor\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"media:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\treturn unwrap(\n\t\t\t\tawait ec.handleMediaList({\n\t\t\t\t\tmimeType: args.mimeType,\n\t\t\t\t\tlimit: args.limit,\n\t\t\t\t\tcursor: args.cursor,\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"media_create\",\n\t\t{\n\t\t\ttitle: \"Register Uploaded Media\",\n\t\t\tdescription:\n\t\t\t\t\"Register a media file that has already been uploaded to storage. The \" +\n\t\t\t\t\"caller is responsible for placing the file at `storageKey` (typically \" +\n\t\t\t\t\"using a signed upload URL obtained from the admin UI or a separate API). \" +\n\t\t\t\t\"This tool persists the metadata record so the file is discoverable via \" +\n\t\t\t\t\"media_list / media_get and can be referenced by content. To upload the \" +\n\t\t\t\t\"file itself, use media_upload (base64 data or a public URL) instead.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tfilename: z.string().describe(\"Original filename (e.g. 'logo.png')\"),\n\t\t\t\tmimeType: z.string().describe(\"MIME type (e.g. 'image/png')\"),\n\t\t\t\tstorageKey: z.string().describe(\"Storage path/key the file was uploaded to\"),\n\t\t\t\tsize: z.number().int().nonnegative().optional().describe(\"File size in bytes\"),\n\t\t\t\twidth: z.number().int().positive().optional().describe(\"Image width in pixels\"),\n\t\t\t\theight: z.number().int().positive().optional().describe(\"Image height in pixels\"),\n\t\t\t\tcontentHash: z.string().optional().describe(\"Hash of the file contents (for dedupe)\"),\n\t\t\t\tblurhash: z.string().optional().describe(\"Blurhash for image placeholders\"),\n\t\t\t\tdominantColor: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Hex color string for the image's dominant color\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"media:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst { emdash, userId } = getExtra(extra);\n\t\t\treturn unwrap(\n\t\t\t\tawait emdash.handleMediaCreate({\n\t\t\t\t\tfilename: args.filename,\n\t\t\t\t\tmimeType: args.mimeType,\n\t\t\t\t\tstorageKey: args.storageKey,\n\t\t\t\t\tsize: args.size,\n\t\t\t\t\twidth: args.width,\n\t\t\t\t\theight: args.height,\n\t\t\t\t\tcontentHash: args.contentHash,\n\t\t\t\t\tblurhash: args.blurhash,\n\t\t\t\t\tdominantColor: args.dominantColor,\n\t\t\t\t\tauthorId: userId,\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"media_upload\",\n\t\t{\n\t\t\ttitle: \"Upload Media\",\n\t\t\tdescription:\n\t\t\t\t\"Upload a media file from base64-encoded data or an external URL and \" +\n\t\t\t\t\"register it in the media library. Returns the media item with id, \" +\n\t\t\t\t\"storageKey, and url — ready to reference from content fields (e.g. \" +\n\t\t\t\t\"featured_image) via content_create / content_update. Uploads are \" +\n\t\t\t\t\"deduplicated by content hash: re-uploading identical bytes returns \" +\n\t\t\t\t\"the existing item with deduplicated: true. URL fetches must resolve \" +\n\t\t\t\t\"to a public http(s) host (SSRF-guarded). Subject to the global \" +\n\t\t\t\t\"upload MIME allowlist and the configured maximum upload size.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tfilename: z.string().min(1).describe(\"Filename including extension (e.g. 'cover.png')\"),\n\t\t\t\tbase64: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Base64-encoded file contents. Provide exactly one of base64 / url.\"),\n\t\t\t\turl: z\n\t\t\t\t\t.url()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Public http(s) URL to fetch the file from. Provide exactly one of base64 / url.\",\n\t\t\t\t\t),\n\t\t\t\tcontentType: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.regex(CONTENT_TYPE_RE, \"Invalid content type\")\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"MIME type (e.g. 'image/png'). Required with base64; with url it \" +\n\t\t\t\t\t\t\t\"defaults to the response's Content-Type header.\",\n\t\t\t\t\t),\n\t\t\t\talt: z.string().optional().describe(\"Alt text for accessibility\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: false },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"media:write\");\n\t\t\trequireRole(extra, Role.CONTRIBUTOR);\n\t\t\tconst { emdash, userId } = getExtra(extra);\n\t\t\tif (!emdash.storage) {\n\t\t\t\treturn respondError(\"NO_STORAGE\", \"Storage not configured\");\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn unwrap(\n\t\t\t\t\tawait emdash.handleMediaUpload({\n\t\t\t\t\t\tfilename: args.filename,\n\t\t\t\t\t\tbase64: args.base64,\n\t\t\t\t\t\turl: args.url,\n\t\t\t\t\t\tcontentType: args.contentType,\n\t\t\t\t\t\talt: args.alt,\n\t\t\t\t\t\tauthorId: userId,\n\t\t\t\t\t\tmaxUploadSize: emdash.config.maxUploadSize,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"UPLOAD_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"media_get\",\n\t\t{\n\t\t\ttitle: \"Get Media Item\",\n\t\t\tdescription:\n\t\t\t\t\"Get details of a single media file by its ID. Returns metadata \" +\n\t\t\t\t\"including filename, MIME type, size, dimensions, alt text, and URL.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tid: z.string().describe(\"Media item ID\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"media:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\treturn unwrap(await ec.handleMediaGet(args.id));\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"media_update\",\n\t\t{\n\t\t\ttitle: \"Update Media Metadata\",\n\t\t\tdescription:\n\t\t\t\t\"Update the metadata of an uploaded media file. You can change the \" +\n\t\t\t\t\"alt text, caption, and dimensions. The file itself cannot be changed.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tid: z.string().describe(\"Media item ID\"),\n\t\t\t\talt: z.string().optional().describe(\"Alt text for accessibility\"),\n\t\t\t\tcaption: z.string().optional().describe(\"Caption text\"),\n\t\t\t\twidth: z.number().int().optional().describe(\"Image width in pixels\"),\n\t\t\t\theight: z.number().int().optional().describe(\"Image height in pixels\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"media:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst ec = getEmDash(extra);\n\n\t\t\t// Fetch media item for ownership check\n\t\t\tconst existing = await ec.handleMediaGet(args.id);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\tconst media = (existing.data as Record<string, unknown> | undefined)?.item as\n\t\t\t\t| Record<string, unknown>\n\t\t\t\t| undefined;\n\t\t\tconst authorId = typeof media?.authorId === \"string\" ? media.authorId : \"\";\n\t\t\trequireOwnership(extra, authorId, \"media:edit_own\", \"media:edit_any\");\n\n\t\t\treturn unwrap(\n\t\t\t\tawait ec.handleMediaUpdate(args.id, {\n\t\t\t\t\talt: args.alt,\n\t\t\t\t\tcaption: args.caption,\n\t\t\t\t\twidth: args.width,\n\t\t\t\t\theight: args.height,\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"media_delete\",\n\t\t{\n\t\t\ttitle: \"Delete Media\",\n\t\t\tdescription:\n\t\t\t\t\"Permanently delete an uploaded media file. Removes the database record \" +\n\t\t\t\t\"and the file from storage. Content referencing this media will have \" +\n\t\t\t\t\"broken references. Cannot be undone.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tid: z.string().describe(\"Media item ID\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"media:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst ec = getEmDash(extra);\n\n\t\t\t// Fetch media item for ownership check\n\t\t\tconst existing = await ec.handleMediaGet(args.id);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\tconst media = (existing.data as Record<string, unknown> | undefined)?.item as\n\t\t\t\t| Record<string, unknown>\n\t\t\t\t| undefined;\n\t\t\tconst authorId = typeof media?.authorId === \"string\" ? media.authorId : \"\";\n\t\t\trequireOwnership(extra, authorId, \"media:delete_own\", \"media:delete_any\");\n\n\t\t\treturn unwrap(await ec.handleMediaDelete(args.id));\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"media_usage_repair\",\n\t\t{\n\t\t\ttitle: \"Repair Media Usage Index\",\n\t\t\tdescription:\n\t\t\t\t\"Repair content media usage indexes for one collection or every collection. \" +\n\t\t\t\t\"Returns complete, partial, failed, or stale status; inspect the structured result.\",\n\t\t\tinputSchema: mediaUsageRepairToolSchema,\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"admin\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\n\t\t\tlet input: MediaUsageRepairRequest;\n\t\t\tif (args.scope === \"collection\") {\n\t\t\t\tif (args.collection === undefined) {\n\t\t\t\t\treturn respondError(\n\t\t\t\t\t\t\"VALIDATION_ERROR\",\n\t\t\t\t\t\t\"Collection is required when scope is collection\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tinput = { scope: \"collection\", collection: args.collection };\n\t\t\t} else {\n\t\t\t\tinput = { scope: \"all\" };\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst { handleMediaUsageRepair } = await import(\"../api/handlers/media-usage.js\");\n\t\t\t\treturn unwrap(await handleMediaUsageRepair(ec.db, input));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"MEDIA_USAGE_REPAIR_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\t// =====================================================================\n\t// Search tool\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"search\",\n\t\t{\n\t\t\ttitle: \"Search Content\",\n\t\t\tdescription:\n\t\t\t\t\"Full-text search across content collections. Searches indexed fields \" +\n\t\t\t\t\"for matching content. Collections must have 'search' in their supports \" +\n\t\t\t\t\"list and fields must be marked as searchable. Returns collection, item \" +\n\t\t\t\t\"ID, title, excerpt, and relevance score.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tquery: z.string().describe(\"Search query text\"),\n\t\t\t\tcollections: z\n\t\t\t\t\t.array(z.string())\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Limit search to specific collection slugs (all if omitted)\"),\n\t\t\t\tlocale: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Filter results by locale (omit to search all locales)\"),\n\t\t\t\tlimit: z.number().int().min(1).max(50).optional().describe(\"Max results (default 20)\"),\n\t\t\t\tcursor: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.min(1)\n\t\t\t\t\t.max(2048)\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Pagination cursor from a previous response\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { searchWithDb } = await import(\"../search/index.js\");\n\t\t\t\tconst results = await searchWithDb(ec.db, args.query, {\n\t\t\t\t\tcollections: args.collections,\n\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\tlimit: args.limit,\n\t\t\t\t\tcursor: args.cursor,\n\t\t\t\t});\n\t\t\t\treturn jsonResult(results);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"SEARCH_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\t// =====================================================================\n\t// Taxonomy tools\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"taxonomy_list\",\n\t\t{\n\t\t\ttitle: \"List Taxonomies\",\n\t\t\tdescription:\n\t\t\t\t\"List all taxonomy definitions (e.g. categories, tags). Taxonomies are \" +\n\t\t\t\t\"classification systems applied to content. Each has a name, label, and \" +\n\t\t\t\t\"can be hierarchical (categories) or flat (tags). Optionally filter by \" +\n\t\t\t\t\"locale.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tlocale: z.string().optional().describe(\"Filter by locale (omit for all)\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTaxonomyList } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\treturn unwrap(await handleTaxonomyList(ec.db, { locale: args.locale }));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TAXONOMY_LIST_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"taxonomy_get\",\n\t\t{\n\t\t\ttitle: \"Get Taxonomy Definition\",\n\t\t\tdescription:\n\t\t\t\t\"Get a single taxonomy definition by name. Taxonomy definitions describe \" +\n\t\t\t\t\"a classification system (e.g. categories or tags), which collections \" +\n\t\t\t\t\"it applies to, and whether it is hierarchical. Pass `locale` to resolve \" +\n\t\t\t\t\"a specific translation; otherwise the lowest matching locale is returned.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tname: z.string().describe(\"Taxonomy name (e.g. 'categories', 'tags')\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale to resolve the definition for\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTaxonomyGet } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\treturn unwrap(await handleTaxonomyGet(ec.db, args.name, { locale: args.locale }));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TAXONOMY_GET_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"taxonomy_create\",\n\t\t{\n\t\t\ttitle: \"Create Taxonomy Definition\",\n\t\t\tdescription:\n\t\t\t\t\"Create a new taxonomy definition. Definitions are per-locale; pass \" +\n\t\t\t\t\"`locale` when the same taxonomy name exists in multiple translations. \" +\n\t\t\t\t\"`collections` names which content types the taxonomy applies to. \" +\n\t\t\t\t\"If `translationOf` is set, the new definition joins the source's \" +\n\t\t\t\t\"translation group and inherits `hierarchical` and `collections` from \" +\n\t\t\t\t\"the source when those fields are omitted.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tname: createTaxonomyDefBody.shape.name.describe(\n\t\t\t\t\t\"Taxonomy name (lowercase letters, numbers, underscores)\",\n\t\t\t\t),\n\t\t\t\tlabel: createTaxonomyDefBody.shape.label.describe(\"Display name\"),\n\t\t\t\tlabelSingular: createTaxonomyDefBody.shape.labelSingular.describe(\n\t\t\t\t\t\"Singular form of the display name\",\n\t\t\t\t),\n\t\t\t\thierarchical: createTaxonomyDefBody.shape.hierarchical.describe(\n\t\t\t\t\t\"Whether the taxonomy supports parent/child terms (defaults to false, or inherited from translationOf)\",\n\t\t\t\t),\n\t\t\t\tcollections: createTaxonomyDefBody.shape.collections.describe(\n\t\t\t\t\t\"Collection slugs this taxonomy applies to (defaults to [], or inherited from translationOf)\",\n\t\t\t\t),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale for this definition (e.g. 'fr-fr')\"),\n\t\t\t\ttranslationOf: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Existing taxonomy definition id to create this locale variant from\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"taxonomies:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTaxonomyCreate } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait handleTaxonomyCreate(ec.db, {\n\t\t\t\t\t\tname: args.name,\n\t\t\t\t\t\tlabel: args.label,\n\t\t\t\t\t\tlabelSingular: args.labelSingular,\n\t\t\t\t\t\thierarchical: args.hierarchical,\n\t\t\t\t\t\tcollections: args.collections,\n\t\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\t\ttranslationOf: args.translationOf,\n\t\t\t\t\t}),\n\t\t\t\t\t[taxonomyTag(args.name)],\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TAXONOMY_CREATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"taxonomy_update\",\n\t\t{\n\t\t\ttitle: \"Update Taxonomy Definition\",\n\t\t\tdescription:\n\t\t\t\t\"Update an existing taxonomy definition. The taxonomy `name` cannot be \" +\n\t\t\t\t\"changed. Pass `locale` to update a specific translation; otherwise the \" +\n\t\t\t\t\"lowest matching locale is updated. Any field may be omitted to leave it \" +\n\t\t\t\t\"unchanged.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tname: z.string().describe(\"Taxonomy name to update\"),\n\t\t\t\tlabel: updateTaxonomyDefBody.shape.label.describe(\"New display name\"),\n\t\t\t\tlabelSingular: updateTaxonomyDefBody.shape.labelSingular.describe(\n\t\t\t\t\t\"New singular display name; pass null to clear\",\n\t\t\t\t),\n\t\t\t\thierarchical: updateTaxonomyDefBody.shape.hierarchical.describe(\n\t\t\t\t\t\"Whether the taxonomy supports parent/child terms\",\n\t\t\t\t),\n\t\t\t\tcollections: updateTaxonomyDefBody.shape.collections.describe(\n\t\t\t\t\t\"Collection slugs this taxonomy applies to\",\n\t\t\t\t),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale of the definition to update\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"taxonomies:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTaxonomyUpdate } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait handleTaxonomyUpdate(ec.db, args.name, {\n\t\t\t\t\t\tlabel: args.label,\n\t\t\t\t\t\tlabelSingular: args.labelSingular,\n\t\t\t\t\t\thierarchical: args.hierarchical,\n\t\t\t\t\t\tcollections: args.collections,\n\t\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\t}),\n\t\t\t\t\t[taxonomyTag(args.name)],\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TAXONOMY_UPDATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"taxonomy_delete\",\n\t\t{\n\t\t\ttitle: \"Delete Taxonomy Definition\",\n\t\t\tdescription:\n\t\t\t\t\"Delete a taxonomy definition and all of its terms in every locale, \" +\n\t\t\t\t\"along with any content assignments those terms hold. This cannot be undone.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tname: z.string().describe(\"Taxonomy name to delete\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"taxonomies:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTaxonomyDelete } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\treturn unwrapAndInvalidate(extra, await handleTaxonomyDelete(ec.db, args.name), [\n\t\t\t\t\ttaxonomyTag(args.name),\n\t\t\t\t]);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TAXONOMY_DELETE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"taxonomy_list_terms\",\n\t\t{\n\t\t\ttitle: \"List Taxonomy Terms\",\n\t\t\tdescription:\n\t\t\t\t\"List terms in a taxonomy with pagination. Terms are individual entries \" +\n\t\t\t\t\"(e.g. specific categories or tags). Hierarchical taxonomies can have \" +\n\t\t\t\t\"parent-child relationships.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\ttaxonomy: z.string().describe(\"Taxonomy name (e.g. 'categories', 'tags')\"),\n\t\t\t\tlimit: z.number().int().min(1).max(100).optional().describe(\"Max items (default 50)\"),\n\t\t\t\tcursor: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.min(1)\n\t\t\t\t\t.max(MAX_TAXONOMY_CURSOR_LENGTH)\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Pagination cursor\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Filter by locale (omit for all)\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTaxonomyList } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\tconst listResult = await handleTaxonomyList(ec.db, { locale: args.locale });\n\t\t\t\tif (!listResult.success) return unwrap(listResult);\n\n\t\t\t\tconst taxonomies = (listResult.data as { taxonomies: Array<{ name: string; id?: string }> })\n\t\t\t\t\t.taxonomies;\n\t\t\t\tconst taxonomy = taxonomies.find((t: { name: string }) => t.name === args.taxonomy);\n\t\t\t\tif (!taxonomy) return respondError(\"NOT_FOUND\", `Taxonomy '${args.taxonomy}' not found`);\n\n\t\t\t\tconst { TaxonomyRepository } = await import(\"../database/repositories/taxonomy.js\");\n\t\t\t\tconst repo = new TaxonomyRepository(ec.db);\n\t\t\t\tconst limit = Math.min(args.limit ?? 50, 100);\n\t\t\t\tlet cursor: TaxonomyListCursor | undefined;\n\t\t\t\tif (args.cursor) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tcursor = decodeTaxonomyCursor(args.cursor);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (error instanceof InvalidCursorError) {\n\t\t\t\t\t\t\treturn respondError(\"INVALID_CURSOR\", error.message);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlet pageCursor: { sortOrder: number; label: string; id: string } | undefined;\n\t\t\t\tif (cursor) {\n\t\t\t\t\tconst cursorTerm = await repo.findById(cursor.id);\n\t\t\t\t\tif (\n\t\t\t\t\t\t!cursorTerm ||\n\t\t\t\t\t\tcursorTerm.name !== args.taxonomy ||\n\t\t\t\t\t\t(args.locale !== undefined && cursorTerm.locale !== args.locale)\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn respondError(\"INVALID_CURSOR\", \"Pagination cursor no longer identifies a term\");\n\t\t\t\t\t}\n\t\t\t\t\tpageCursor = {\n\t\t\t\t\t\tsortOrder: cursorTerm.sortOrder,\n\t\t\t\t\t\tlabel: cursorTerm.label,\n\t\t\t\t\t\tid: cursorTerm.id,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst page = await repo.findPageByName(args.taxonomy, {\n\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\tlimit,\n\t\t\t\t\t...(pageCursor ? { cursor: pageCursor } : {}),\n\t\t\t\t});\n\t\t\t\tconst last = page.items.at(-1);\n\t\t\t\tconst nextCursor = page.hasMore && last ? encodeTaxonomyCursor(last) : undefined;\n\n\t\t\t\treturn jsonResult({\n\t\t\t\t\titems: page.items.map((t) => ({\n\t\t\t\t\t\tid: t.id,\n\t\t\t\t\t\tname: t.name,\n\t\t\t\t\t\tslug: t.slug,\n\t\t\t\t\t\tlabel: t.label,\n\t\t\t\t\t\tparentId: t.parentId,\n\t\t\t\t\t\tdescription: typeof t.data?.description === \"string\" ? t.data.description : undefined,\n\t\t\t\t\t\tlocale: t.locale,\n\t\t\t\t\t\ttranslationGroup: t.translationGroup,\n\t\t\t\t\t})),\n\t\t\t\t\tnextCursor,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TAXONOMY_LIST_TERMS_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"taxonomy_create_term\",\n\t\t{\n\t\t\ttitle: \"Create Taxonomy Term\",\n\t\t\tdescription:\n\t\t\t\t\"Create a new term in a taxonomy. For hierarchical taxonomies like \" +\n\t\t\t\t\"categories, you can specify a parentId to create a child term. The \" +\n\t\t\t\t\"parent must exist and belong to the same taxonomy. The parent's \" +\n\t\t\t\t\"ancestor chain must not exceed 100 levels — attempts to attach a \" +\n\t\t\t\t\"new term beneath a chain of 100+ existing ancestors are rejected.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\ttaxonomy: z.string().describe(\"Taxonomy name (e.g. 'categories', 'tags')\"),\n\t\t\t\tslug: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.min(1)\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"URL identifier for the term; omit to derive it from the label\"),\n\t\t\t\tlabel: z.string().describe(\"Display name\"),\n\t\t\t\tparentId: z.string().optional().describe(\"Parent term ID for hierarchical taxonomies\"),\n\t\t\t\tdescription: z.string().optional().describe(\"Description of the term\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale for the new term (e.g. 'es')\"),\n\t\t\t\ttranslationOf: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Term id to join as a translation (same translation_group)\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"taxonomies:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTermCreate } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait handleTermCreate(ec.db, args.taxonomy, {\n\t\t\t\t\t\tslug: args.slug,\n\t\t\t\t\t\tlabel: args.label,\n\t\t\t\t\t\tparentId: args.parentId,\n\t\t\t\t\t\tdescription: args.description,\n\t\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\t\ttranslationOf: args.translationOf,\n\t\t\t\t\t}),\n\t\t\t\t\t[taxonomyTag(args.taxonomy)],\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TAXONOMY_TERM_CREATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"taxonomy_update_term\",\n\t\t{\n\t\t\ttitle: \"Update Taxonomy Term\",\n\t\t\tdescription:\n\t\t\t\t\"Update an existing term in a taxonomy. Any field can be omitted to leave \" +\n\t\t\t\t\"it unchanged. Renaming a term's slug must not collide with another term in \" +\n\t\t\t\t\"the same taxonomy. Set parentId to null to detach from a parent. The new \" +\n\t\t\t\t\"parent must exist, belong to the same taxonomy, and not introduce a cycle \" +\n\t\t\t\t\"(a term cannot be its own ancestor). The new parent's ancestor chain must \" +\n\t\t\t\t\"not exceed 100 levels — reparenting under a chain of 100+ ancestors is \" +\n\t\t\t\t\"rejected. Translations of a term can share a slug: pass `locale` to \" +\n\t\t\t\t\"update a specific translation; otherwise the lowest matching locale is \" +\n\t\t\t\t\"updated.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\ttaxonomy: z.string().describe(\"Taxonomy name (e.g. 'categories', 'tags')\"),\n\t\t\t\ttermSlug: z.string().describe(\"Current slug of the term to update\"),\n\t\t\t\tslug: z.string().optional().describe(\"New slug (must be unique in the taxonomy)\"),\n\t\t\t\tlabel: z.string().optional().describe(\"New display name\"),\n\t\t\t\tparentId: z.string().nullable().optional().describe(\"New parent term ID; null to detach\"),\n\t\t\t\tdescription: z.string().optional().describe(\"New description\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale of the term to update (e.g. 'fr')\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"taxonomies:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTermUpdate } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait handleTermUpdate(\n\t\t\t\t\t\tec.db,\n\t\t\t\t\t\targs.taxonomy,\n\t\t\t\t\t\targs.termSlug,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tslug: args.slug,\n\t\t\t\t\t\t\tlabel: args.label,\n\t\t\t\t\t\t\tparentId: args.parentId,\n\t\t\t\t\t\t\tdescription: args.description,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ locale: args.locale },\n\t\t\t\t\t),\n\t\t\t\t\t[taxonomyTag(args.taxonomy)],\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TAXONOMY_TERM_UPDATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"taxonomy_delete_term\",\n\t\t{\n\t\t\ttitle: \"Delete Taxonomy Term\",\n\t\t\tdescription:\n\t\t\t\t\"Permanently delete a term from a taxonomy. Any content tagged with this \" +\n\t\t\t\t\"term loses the association. Cannot delete a term that has children — \" +\n\t\t\t\t\"delete children first. Translations of a term can share a slug: pass \" +\n\t\t\t\t\"`locale` to delete a specific translation; otherwise the lowest matching \" +\n\t\t\t\t\"locale is deleted.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\ttaxonomy: z.string().describe(\"Taxonomy name\"),\n\t\t\t\ttermSlug: z.string().describe(\"Slug of the term to delete\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale of the term to delete (e.g. 'fr')\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"taxonomies:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTermDelete } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait handleTermDelete(ec.db, args.taxonomy, args.termSlug, { locale: args.locale }),\n\t\t\t\t\t[taxonomyTag(args.taxonomy)],\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TAXONOMY_TERM_DELETE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"taxonomy_term_translations\",\n\t\t{\n\t\t\ttitle: \"List Term Translations\",\n\t\t\tdescription:\n\t\t\t\t\"Return every locale variant of a taxonomy term, identified via its shared translation_group.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tid: z.string().describe(\"Term id (or translation_group)\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTermTranslations } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\treturn unwrap(await handleTermTranslations(ec.db, args.id));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TERM_TRANSLATIONS_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\t// =====================================================================\n\t// Menu tools\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"menu_list\",\n\t\t{\n\t\t\ttitle: \"List Menus\",\n\t\t\tdescription:\n\t\t\t\t\"List navigation menus. Menus are per-locale: filter by `locale` to \" +\n\t\t\t\t\"get just one locale's worth, or omit to list every row (one per \" +\n\t\t\t\t\"locale per menu name).\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tlocale: z.string().optional().describe(\"Filter by locale (omit for all)\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleMenuList } = await import(\"../api/handlers/menus.js\");\n\t\t\t\treturn unwrap(await handleMenuList(ec.db, { locale: args.locale }));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"MENU_LIST_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"menu_get\",\n\t\t{\n\t\t\ttitle: \"Get Menu with Items\",\n\t\t\tdescription:\n\t\t\t\t\"Get a menu by name, including its items. When multiple locales exist, \" +\n\t\t\t\t\"pass `locale` to pick the right one.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tname: z.string().describe(\"Menu name (e.g. 'main', 'footer')\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale to resolve the menu for\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleMenuGet } = await import(\"../api/handlers/menus.js\");\n\t\t\t\treturn unwrap(await handleMenuGet(ec.db, args.name, { locale: args.locale }));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"MENU_GET_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"menu_translations\",\n\t\t{\n\t\t\ttitle: \"List Menu Translations\",\n\t\t\tdescription:\n\t\t\t\t\"Return every locale variant of a menu, identified via the shared translation_group.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tid: z.string().describe(\"Menu id (or translation_group)\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleMenuTranslations } = await import(\"../api/handlers/menus.js\");\n\t\t\t\treturn unwrap(await handleMenuTranslations(ec.db, args.id));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"MENU_TRANSLATIONS_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"menu_create\",\n\t\t{\n\t\t\ttitle: \"Create Menu\",\n\t\t\tdescription:\n\t\t\t\t\"Create a new navigation menu. The `name` is the stable identifier used \" +\n\t\t\t\t\"by site templates (e.g. 'main', 'footer'); `label` is the human-readable \" +\n\t\t\t\t\"name shown in the admin. Menus are per-locale, so pass `locale` when \" +\n\t\t\t\t\"the same menu name exists in multiple translations. Add items afterwards \" +\n\t\t\t\t\"with menu_set_items. If `translationOf` is set, `locale` must also be set.\",\n\t\t\t// `locale`-when-`translationOf` is enforced inside handleMenuCreate\n\t\t\t// so REST/SDK callers get the same guard. The description above\n\t\t\t// documents the rule; the handler returns VALIDATION_ERROR.\n\t\t\tinputSchema: z.object({\n\t\t\t\tname: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.regex(COLLECTION_SLUG_PATTERN)\n\t\t\t\t\t.describe(\"Stable identifier (lowercase letters, numbers, underscores)\"),\n\t\t\t\tlabel: z.string().describe(\"Display name for the admin\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale for this menu (e.g. 'fr-fr')\"),\n\t\t\t\ttranslationOf: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Existing menu id to create this locale variant from\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"menus:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleMenuCreate } = await import(\"../api/handlers/menus.js\");\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait handleMenuCreate(ec.db, {\n\t\t\t\t\t\tname: args.name,\n\t\t\t\t\t\tlabel: args.label,\n\t\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\t\ttranslationOf: args.translationOf,\n\t\t\t\t\t}),\n\t\t\t\t\t[menuTag(args.name)],\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"MENU_CREATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"menu_update\",\n\t\t{\n\t\t\ttitle: \"Update Menu\",\n\t\t\tdescription:\n\t\t\t\t\"Update a menu's label. The `name` (stable identifier) cannot be changed. \" +\n\t\t\t\t\"On multi-locale installs, pass `locale` so the correct translation is updated.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tname: z.string().describe(\"Menu name to update\"),\n\t\t\t\tlabel: z.string().describe(\"New display label\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale of the menu to update\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"menus:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleMenuUpdate } = await import(\"../api/handlers/menus.js\");\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait handleMenuUpdate(ec.db, args.name, { label: args.label, locale: args.locale }),\n\t\t\t\t\t[menuTag(args.name)],\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"MENU_UPDATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"menu_delete\",\n\t\t{\n\t\t\ttitle: \"Delete Menu\",\n\t\t\tdescription:\n\t\t\t\t\"Delete a menu. Items are also removed. Cannot be undone. On multi-locale \" +\n\t\t\t\t\"installs, pass `locale` so only the intended translation is removed.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tname: z.string().describe(\"Menu name to delete\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale of the menu to delete\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"menus:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleMenuDelete } = await import(\"../api/handlers/menus.js\");\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait handleMenuDelete(ec.db, args.name, { locale: args.locale }),\n\t\t\t\t\t[menuTag(args.name)],\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"MENU_DELETE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"menu_set_items\",\n\t\t{\n\t\t\ttitle: \"Set Menu Items\",\n\t\t\tdescription:\n\t\t\t\t\"Replace the entire item list of a menu in one call. This is atomic: the \" +\n\t\t\t\t\"existing items are deleted and the new list is inserted in the order \" +\n\t\t\t\t\"provided. Use this rather than per-item add/remove tools so the resulting \" +\n\t\t\t\t\"order and parent links are unambiguous. On multi-locale installs, pass \" +\n\t\t\t\t\"`locale` so only the intended translation is rewritten.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tname: z.string().describe(\"Menu name to update\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale of the menu to rewrite\"),\n\t\t\t\titems: z\n\t\t\t\t\t.array(\n\t\t\t\t\t\tz.object({\n\t\t\t\t\t\t\tlabel: z.string().describe(\"Item display text\"),\n\t\t\t\t\t\t\ttype: z\n\t\t\t\t\t\t\t\t.enum([\"custom\", \"page\", \"post\", \"taxonomy\", \"collection\"])\n\t\t\t\t\t\t\t\t.describe(\"Item kind\"),\n\t\t\t\t\t\t\tcustomUrl: z\n\t\t\t\t\t\t\t\t.string()\n\t\t\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t\t\t.describe(\"URL for type='custom' items (ignored otherwise)\"),\n\t\t\t\t\t\t\treferenceCollection: z\n\t\t\t\t\t\t\t\t.string()\n\t\t\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t\t\t.describe(\"Target collection slug for content references\"),\n\t\t\t\t\t\t\treferenceId: z.string().optional().describe(\"Target content/term ID for references\"),\n\t\t\t\t\t\t\ttitleAttr: z.string().optional().describe(\"HTML title attribute\"),\n\t\t\t\t\t\t\ttarget: z.string().optional().describe(\"HTML target attribute, e.g. '_blank'\"),\n\t\t\t\t\t\t\tcssClasses: z.string().optional().describe(\"Space-separated CSS classes\"),\n\t\t\t\t\t\t\t/**\n\t\t\t\t\t\t\t * Items are positioned by array index, but parents may be referenced\n\t\t\t\t\t\t\t * by their array index — items with `parentIndex` set are nested under\n\t\t\t\t\t\t\t * the item at that position. Items without `parentIndex` are top-level.\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\tparentIndex: z\n\t\t\t\t\t\t\t\t.number()\n\t\t\t\t\t\t\t\t.int()\n\t\t\t\t\t\t\t\t.nonnegative()\n\t\t\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t\t\t.describe(\n\t\t\t\t\t\t\t\t\t\"Array index of the parent item (must be earlier in the list). Omit for top-level items.\",\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t\t.describe(\"Ordered list of menu items\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"menus:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleMenuSetItems } = await import(\"../api/handlers/menus.js\");\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait handleMenuSetItems(ec.db, args.name, args.items, { locale: args.locale }),\n\t\t\t\t\t[menuTag(args.name)],\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"MENU_SET_ITEMS_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\t// =====================================================================\n\t// Revision tools\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"revision_list\",\n\t\t{\n\t\t\ttitle: \"List Revisions\",\n\t\t\tdescription:\n\t\t\t\t\"List revision history for a content item. Revisions are snapshots \" +\n\t\t\t\t\"created on publish or update. Returns newest-first. Requires the \" +\n\t\t\t\t\"collection to support 'revisions'.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t\tlimit: z.number().int().min(1).max(50).optional().describe(\"Max revisions (default 20)\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\trequireDraftAccess(extra);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\treturn unwrap(\n\t\t\t\tawait ec.handleRevisionList(args.collection, args.id, {\n\t\t\t\t\tlimit: args.limit,\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"revision_restore\",\n\t\t{\n\t\t\ttitle: \"Restore Revision\",\n\t\t\tdescription:\n\t\t\t\t\"Restore a content item to a previous revision. Replaces the current \" +\n\t\t\t\t\"draft with the specified revision's data. Not automatically published — \" +\n\t\t\t\t\"use content_publish afterward if needed.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\trevisionId: z.string().describe(\"Revision ID to restore\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst { emdash, userId } = getExtra(extra);\n\n\t\t\t// Fetch the revision to discover the parent content entry\n\t\t\tconst revision = await emdash.handleRevisionGet(args.revisionId);\n\t\t\tif (!revision.success) {\n\t\t\t\treturn unwrap(revision);\n\t\t\t}\n\t\t\tconst revItem = revision.data?.item;\n\t\t\tif (!revItem?.collection || !revItem?.entryId) {\n\t\t\t\treturn respondError(\n\t\t\t\t\t\"VALIDATION_ERROR\",\n\t\t\t\t\t\"Revision is missing collection or entry reference\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Fetch the content entry to check ownership\n\t\t\tconst existing = await emdash.handleContentGet(revItem.collection, revItem.entryId);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\trequireOwnership(\n\t\t\t\textra,\n\t\t\t\textractContentAuthorId(existing.data),\n\t\t\t\t\"content:edit_own\",\n\t\t\t\t\"content:edit_any\",\n\t\t\t);\n\n\t\t\treturn unwrap(await emdash.handleRevisionRestore(args.revisionId, userId));\n\t\t},\n\t);\n\n\t// =====================================================================\n\t// Settings tools\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"settings_get\",\n\t\t{\n\t\t\ttitle: \"Get Site Settings\",\n\t\t\tdescription:\n\t\t\t\t\"Get all site-wide settings (title, tagline, logo, favicon, URL, \" +\n\t\t\t\t\"date/time formatting, social links, SEO defaults). Media references \" +\n\t\t\t\t\"(logo, favicon, defaultOgImage) include resolved URLs. Unset values \" +\n\t\t\t\t\"are omitted from the response.\",\n\t\t\tinputSchema: z.object({}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (_args, extra) => {\n\t\t\trequireScope(extra, \"settings:read\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleSettingsGet } = await import(\"../api/handlers/settings.js\");\n\t\t\t\treturn unwrap(await handleSettingsGet(ec.db, ec.storage));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"SETTINGS_READ_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"settings_update\",\n\t\t{\n\t\t\ttitle: \"Update Site Settings\",\n\t\t\tdescription:\n\t\t\t\t\"Update one or more site-wide settings. This is a partial update: only \" +\n\t\t\t\t\"the fields provided are changed; omitted fields are left as-is. Returns \" +\n\t\t\t\t\"the full settings object after the update. To set a media reference \" +\n\t\t\t\t\"(logo, favicon, seo.defaultOgImage), pass an object with `mediaId` \" +\n\t\t\t\t\"(and optional `alt`) — the media item must already exist (use \" +\n\t\t\t\t\"media_create first).\",\n\t\t\tinputSchema: z.object({\n\t\t\t\ttitle: z.string().optional().describe(\"Site title\"),\n\t\t\t\ttagline: z.string().optional().describe(\"Site tagline / short description\"),\n\t\t\t\tlogo: settingsMediaReferenceSchema\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Logo media reference ({ mediaId, alt? })\"),\n\t\t\t\tfavicon: settingsMediaReferenceSchema\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Favicon media reference ({ mediaId, alt? })\"),\n\t\t\t\turl: z\n\t\t\t\t\t.union([\n\t\t\t\t\t\tz.url().refine((u) => HTTP_SCHEME_PATTERN.test(u), \"URL must use http or https\"),\n\t\t\t\t\t\tz.literal(\"\"),\n\t\t\t\t\t])\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Canonical site URL (http or https). Empty string clears it.\"),\n\t\t\t\tpostsPerPage: z\n\t\t\t\t\t.number()\n\t\t\t\t\t.int()\n\t\t\t\t\t.min(1)\n\t\t\t\t\t.max(100)\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Default page size for content listings\"),\n\t\t\t\tdateFormat: z.string().optional().describe(\"Date format token string\"),\n\t\t\t\ttimezone: z.string().optional().describe(\"IANA timezone identifier\"),\n\t\t\t\tsocial: settingsSocialSchema.optional().describe(\"Social handles / URLs\"),\n\t\t\t\tseo: settingsSeoSchema.optional().describe(\"Site-wide SEO defaults\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"settings:manage\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleSettingsUpdate } = await import(\"../api/handlers/settings.js\");\n\t\t\t\treturn unwrapAndInvalidate(extra, await handleSettingsUpdate(ec.db, ec.storage, args), [\n\t\t\t\t\tsiteSettingsTag(),\n\t\t\t\t]);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"SETTINGS_UPDATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\treturn server;\n}\n","/**\n * MCP Streamable HTTP endpoint\n *\n * Exposes an MCP server at /_emdash/api/mcp using the Streamable HTTP\n * transport (Web Standard variant). The server runs stateless — each\n * request creates a fresh transport, so no session tracking is needed.\n * Authentication is handled by the existing EmDash auth middleware.\n *\n * POST /_emdash/api/mcp — JSON-RPC tool calls\n * GET /_emdash/api/mcp — SSE stream (not used in stateless mode)\n * DELETE /_emdash/api/mcp — Session close (not used in stateless mode)\n */\n\nimport { WebStandardStreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js\";\nimport type { APIRoute } from \"astro\";\n\nimport { apiError } from \"#api/error.js\";\nimport { createMcpServer } from \"#mcp/server.js\";\n\nexport const prerender = false;\n\nexport const POST: APIRoute = async ({ request, locals, cache }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tif (!user) {\n\t\treturn apiError(\"UNAUTHORIZED\", \"Authentication required\", 401);\n\t}\n\n\tconst pluginTools = await emdash.getEnabledPluginMcpTools();\n\tconst server = createMcpServer(pluginTools, request);\n\n\ttry {\n\t\tconst transport = new WebStandardStreamableHTTPServerTransport({\n\t\t\t// Stateless: no session management\n\t\t\tsessionIdGenerator: undefined,\n\t\t});\n\n\t\tawait server.connect(transport);\n\n\t\treturn await transport.handleRequest(request, {\n\t\t\tauthInfo: {\n\t\t\t\ttoken: \"\",\n\t\t\t\tclientId: \"emdash-admin\",\n\t\t\t\tscopes: [],\n\t\t\t\textra: {\n\t\t\t\t\temdash,\n\t\t\t\t\tuser,\n\t\t\t\t\tuserId: user.id,\n\t\t\t\t\tuserRole: user.role,\n\t\t\t\t\ttokenScopes: locals.tokenScopes,\n\t\t\t\t\tcache,\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\t} catch (error) {\n\t\tconsole.error(\"[MCP]\", error);\n\t\tawait server.close().catch(() => {});\n\n\t\treturn new Response(\n\t\t\tJSON.stringify({\n\t\t\t\tjsonrpc: \"2.0\",\n\t\t\t\terror: {\n\t\t\t\t\tcode: -32603,\n\t\t\t\t\tmessage: \"Internal server error\",\n\t\t\t\t},\n\t\t\t\tid: null,\n\t\t\t}),\n\t\t\t{\n\t\t\t\tstatus: 500,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\"Cache-Control\": \"private, no-store\",\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}\n};\n\n/**\n * GET — SSE stream. Not used in stateless mode.\n */\nexport const GET: APIRoute = async () => {\n\treturn new Response(\n\t\tJSON.stringify({\n\t\t\tjsonrpc: \"2.0\",\n\t\t\terror: {\n\t\t\t\tcode: -32000,\n\t\t\t\tmessage: \"Method not allowed. This is a stateless MCP endpoint — use POST.\",\n\t\t\t},\n\t\t\tid: null,\n\t\t}),\n\t\t{\n\t\t\tstatus: 405,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\"Cache-Control\": \"private, no-store\",\n\t\t\t},\n\t\t},\n\t);\n};\n\n/**\n * DELETE — Session close. Not used in stateless mode.\n */\nexport const DELETE: APIRoute = async () => {\n\treturn new Response(\n\t\tJSON.stringify({\n\t\t\tjsonrpc: \"2.0\",\n\t\t\terror: {\n\t\t\t\tcode: -32000,\n\t\t\t\tmessage: \"Method not allowed. This is a stateless MCP endpoint.\",\n\t\t\t},\n\t\t\tid: null,\n\t\t}),\n\t\t{\n\t\t\tstatus: 405,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\"Cache-Control\": \"private, no-store\",\n\t\t\t},\n\t\t},\n\t);\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"mcp.mjs","names":["hasScope"],"sources":["../../../../src/mcp/transfer.ts","../../../../src/mcp/server.ts","../../../../src/astro/routes/api/mcp.ts"],"sourcesContent":["/**\n * Site transfer operations behind the `site_*` MCP tools.\n *\n * Every result is a bounded summary built field by field from operation rows,\n * plans, manifests, and receipts. Nothing here returns package contents,\n * record values, principal emails, staging secrets, lease tokens, storage\n * keys, or download URLs, and the tools never carry package bytes: imports\n * are uploaded over HTTP (CLI or admin) and referred to by operation id.\n *\n * Starting an export or an import needs the matching transfer scope on the\n * caller's token, or a one-time approval grant. A call without either creates\n * a pending grant bound to the user, the token, and the exact request, and\n * fails with `TRANSFER_APPROVAL_REQUIRED`; an admin approves it in the admin\n * UI, and the caller repeats the call with `approvalId`. Once a grant has\n * started an operation, the same user and token may keep driving and reading\n * that one operation without the scope.\n */\n\nimport type { Kysely } from \"kysely\";\n\nimport {\n\texportParamsDigest,\n\thandleExportAdvance,\n\thandleExportCreate,\n\thandleExportGet,\n\thandleImportAdvance,\n\thandleImportAnalyze,\n\thandleImportExecute,\n\thandleImportGet,\n\thandleImportReceipt,\n\thandleTransferCapabilities,\n\trequestTransferApproval,\n\ttype TransferCapabilities,\n} from \"../api/handlers/transfer.js\";\nimport type { ApiResult } from \"../api/types.js\";\nimport type { Database } from \"../database/types.js\";\nimport { getI18nConfig } from \"../i18n/config.js\";\nimport type { Storage } from \"../storage/types.js\";\nimport { loadImportPlan } from \"../transfer/analyze/step.js\";\nimport { analysisTargetContext } from \"../transfer/analyze/target.js\";\nimport type { TransferApprovalAction } from \"../transfer/auth.js\";\nimport { isTransferError, TransferError } from \"../transfer/errors.js\";\nimport { openExportPackage } from \"../transfer/export/exporter.js\";\nimport type { Sha256Digest } from \"../transfer/format/digest.js\";\nimport { RECORD_KINDS, type RecordKind } from \"../transfer/format/kinds.js\";\nimport {\n\tisPlanExecutable,\n\ttype PlanBlocker,\n\ttype PlanWarning,\n\ttype SiteImportDecisionsInput,\n\ttype SiteImportPlan,\n} from \"../transfer/format/plan.js\";\nimport type { SiteImportReceipt } from \"../transfer/format/receipt.js\";\nimport type { PlanTransformation } from \"../transfer/format/transformations.js\";\nimport { TransferApprovalRepository } from \"../transfer/ops/approvals.js\";\nimport {\n\tTransferOperationRepository,\n\ttype PublicTransferOperation,\n} from \"../transfer/ops/operations.js\";\n\n/** Plan principals, warnings, and blockers listed per call; the totals are always reported. */\nexport const MCP_PLAN_LIST_LIMIT = 50;\n\n/** The authenticated MCP caller, as the MCP route resolves it. */\nexport interface TransferCaller {\n\tuserId: string;\n\t/** Id of the API or OAuth token; required to request or use an approval grant. */\n\ttokenId?: string;\n}\n\nexport interface TransferContext {\n\tdb: Kysely<Database>;\n\tstorage: Storage | null;\n\tmaxUploadSize?: number;\n}\n\ntype Result<T> = ApiResult<T>;\n\nfunction failure(code: string, message: string, details?: Record<string, unknown>): Result<never> {\n\treturn {\n\t\tsuccess: false,\n\t\terror: details === undefined ? { code, message } : { code, message, details },\n\t};\n}\n\nfunction transferFailure(error: unknown, fallbackCode: string): Result<never> {\n\tif (isTransferError(error)) return failure(error.code, error.message);\n\t// Storage errors can name staging keys, which carry the staging secret.\n\tconsole.error(\"[transfer] MCP tool failed:\", error);\n\treturn failure(fallbackCode, \"Site transfer request failed\");\n}\n\nfunction storageMissing(): Result<never> {\n\treturn failure(\"STORAGE_NOT_CONFIGURED\", \"No storage backend is configured\");\n}\n\nfunction tokenRequired(): Result<never> {\n\treturn failure(\n\t\t\"INSUFFICIENT_SCOPE\",\n\t\t\"Approval grants need a caller authenticated with an API or OAuth token\",\n\t);\n}\n\n// ── Summaries ───────────────────────────────────────────────────\n\nexport interface OperationSummary {\n\tid: string;\n\tkind: \"export\" | \"import\";\n\tstate: string;\n\tstage: string | null;\n\tprogress: {\n\t\tdone: number;\n\t\ttotal: number;\n\t\trecords?: number;\n\t\tbytesDone?: number;\n\t\tbytesTotal?: number;\n\t} | null;\n\tpackageDigest: string | null;\n\tplanDigest: string | null;\n\terror: { code: string } | null;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\tcompletedAt: string | null;\n\texpiresAt: string | null;\n}\n\nexport function summarizeOperation(operation: PublicTransferOperation): OperationSummary {\n\tconst progress = operation.progress;\n\treturn {\n\t\tid: operation.id,\n\t\tkind: operation.kind,\n\t\tstate: operation.state,\n\t\tstage: operation.stage,\n\t\tprogress: progress\n\t\t\t? {\n\t\t\t\t\tdone: progress.done,\n\t\t\t\t\ttotal: progress.total,\n\t\t\t\t\t...(progress.records === undefined ? {} : { records: progress.records }),\n\t\t\t\t\t...(progress.bytesDone === undefined ? {} : { bytesDone: progress.bytesDone }),\n\t\t\t\t\t...(progress.bytesTotal === undefined ? {} : { bytesTotal: progress.bytesTotal }),\n\t\t\t\t}\n\t\t\t: null,\n\t\tpackageDigest: operation.packageDigest,\n\t\tplanDigest: operation.planDigest,\n\t\terror: operation.errorCode ? { code: operation.errorCode } : null,\n\t\tcreatedAt: operation.createdAt,\n\t\tupdatedAt: operation.updatedAt,\n\t\tcompletedAt: operation.completedAt,\n\t\texpiresAt: operation.expiresAt,\n\t};\n}\n\nexport interface PlanIssueSummary {\n\tcode: string;\n\tmessage: string;\n\tkind?: RecordKind;\n\tid?: string;\n\tcount?: number;\n\tdetail?: Record<string, string | number | boolean | null>;\n}\n\nfunction summarizeIssue(issue: PlanBlocker | PlanWarning): PlanIssueSummary {\n\treturn {\n\t\tcode: issue.code,\n\t\tmessage: issue.message,\n\t\t...(issue.kind === undefined ? {} : { kind: issue.kind }),\n\t\t...(issue.id === undefined ? {} : { id: issue.id }),\n\t\t...(issue.count === undefined ? {} : { count: issue.count }),\n\t\t...(issue.detail === undefined ? {} : { detail: { ...issue.detail } }),\n\t};\n}\n\nexport interface PlanSummary {\n\tpackageDigest: string;\n\tplanDigest: string;\n\texecutable: boolean;\n\torigin: { siteId: string; packageId: string; createdAt: string; emdashVersion: string };\n\tcounts: Partial<Record<RecordKind, number>>;\n\tbytes: { records: number; media: number };\n\t/** Origin users the package references, most referenced first. Emails are never listed here. */\n\tprincipals: {\n\t\ttotal: number;\n\t\titems: Array<{\n\t\t\tid: string;\n\t\t\tdisplayName: string;\n\t\t\treferences: number;\n\t\t\tsuggestedUserId: string | null;\n\t\t\tmappedUserId: string | null;\n\t\t}>;\n\t};\n\tdecisions: { siteTitle: \"package\" | \"target\"; siteTagline: \"package\" | \"target\" };\n\ttransformations: Array<{ code: string; kind?: string; count: number }>;\n\twarnings: { total: number; items: PlanIssueSummary[] };\n\tblockers: { total: number; items: PlanIssueSummary[] };\n\testimatedSteps: number;\n}\n\n/** How many records a transformation touches; its listed ids and values are not returned. */\nfunction transformationCount(item: PlanTransformation): number {\n\tswitch (item.code) {\n\t\tcase \"redirect_loop_disabled\":\n\t\tcase \"search_unsupported\":\n\t\t\treturn item.ids.length;\n\t\tcase \"locale_recased\":\n\t\t\treturn item.locales.length;\n\t\tdefault:\n\t\t\treturn item.count;\n\t}\n}\n\nexport function summarizePlan(plan: SiteImportPlan, planDigest: string): PlanSummary {\n\treturn {\n\t\tpackageDigest: plan.packageDigest,\n\t\tplanDigest,\n\t\texecutable: isPlanExecutable(plan),\n\t\torigin: {\n\t\t\tsiteId: plan.origin.siteId,\n\t\t\tpackageId: plan.origin.packageId,\n\t\t\tcreatedAt: plan.origin.createdAt,\n\t\t\temdashVersion: plan.origin.createdByEmDashVersion,\n\t\t},\n\t\tcounts: { ...plan.counts },\n\t\tbytes: { records: plan.bytes.records, media: plan.bytes.media },\n\t\tprincipals: {\n\t\t\ttotal: plan.principals.length,\n\t\t\titems: plan.principals\n\t\t\t\t.toSorted((a, b) => b.references - a.references || a.id.localeCompare(b.id))\n\t\t\t\t.slice(0, MCP_PLAN_LIST_LIMIT)\n\t\t\t\t.map((principal) => ({\n\t\t\t\t\tid: principal.id,\n\t\t\t\t\tdisplayName: principal.displayName,\n\t\t\t\t\treferences: principal.references,\n\t\t\t\t\tsuggestedUserId: principal.suggestedUserId ?? null,\n\t\t\t\t\tmappedUserId: plan.decisions.principalMappings[principal.id] ?? null,\n\t\t\t\t})),\n\t\t},\n\t\tdecisions: {\n\t\t\tsiteTitle: plan.decisions.siteTitle,\n\t\t\tsiteTagline: plan.decisions.siteTagline,\n\t\t},\n\t\ttransformations: plan.transformations.map((item) => ({\n\t\t\tcode: item.code,\n\t\t\t...(\"kind\" in item ? { kind: item.kind } : {}),\n\t\t\tcount: transformationCount(item),\n\t\t})),\n\t\twarnings: {\n\t\t\ttotal: plan.warnings.length,\n\t\t\titems: plan.warnings.slice(0, MCP_PLAN_LIST_LIMIT).map(summarizeIssue),\n\t\t},\n\t\tblockers: {\n\t\t\ttotal: plan.blockers.length,\n\t\t\titems: plan.blockers.slice(0, MCP_PLAN_LIST_LIMIT).map(summarizeIssue),\n\t\t},\n\t\testimatedSteps: plan.estimatedSteps,\n\t};\n}\n\n// ── Access ──────────────────────────────────────────────────────\n\n/**\n * Whether `caller` may drive or read `operationId` through a grant it\n * consumed for it, in place of the transfer scope.\n */\nexport async function hasOperationGrant(\n\tdb: Kysely<Database>,\n\tcaller: TransferCaller,\n\taction: TransferApprovalAction,\n\toperationId: string,\n): Promise<boolean> {\n\tif (caller.tokenId === undefined) return false;\n\treturn new TransferApprovalRepository(db).hasConsumed({\n\t\tuserId: caller.userId,\n\t\taction,\n\t\toperationId,\n\t\ttokenId: caller.tokenId,\n\t});\n}\n\n// ── Capabilities ────────────────────────────────────────────────\n\nexport async function transferCapabilities(\n\tcontext: TransferContext,\n): Promise<Result<TransferCapabilities>> {\n\treturn handleTransferCapabilities(\n\t\tcontext.db,\n\t\tanalysisTargetContext({ i18n: getI18nConfig(), maxUploadSize: context.maxUploadSize }),\n\t);\n}\n\n// ── Export ──────────────────────────────────────────────────────\n\nexport interface StartExportInput {\n\tcomments?: boolean;\n\tapprovalId?: string;\n\t/** Whether the caller's token holds `transfer:export`. */\n\tscoped: boolean;\n}\n\nexport async function startExport(\n\tcontext: TransferContext,\n\tcaller: TransferCaller,\n\tinput: StartExportInput,\n): Promise<Result<{ operation: OperationSummary }>> {\n\tconst options = input.comments === undefined ? {} : { comments: input.comments };\n\tif (!input.scoped) {\n\t\tif (caller.tokenId === undefined) return tokenRequired();\n\t\tif (input.approvalId === undefined) {\n\t\t\treturn withInstruction(\n\t\t\t\tawait requestTransferApproval(context.db, {\n\t\t\t\t\tuserId: caller.userId,\n\t\t\t\t\taction: \"export\",\n\t\t\t\t\tparamsDigest: await exportParamsDigest(options),\n\t\t\t\t\trequestedByTokenId: caller.tokenId,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\tconst created = await handleExportCreate(context.db, {\n\t\tuserId: caller.userId,\n\t\toptions,\n\t\t...(input.scoped || input.approvalId === undefined\n\t\t\t? {}\n\t\t\t: { approval: { id: input.approvalId, tokenId: caller.tokenId } }),\n\t});\n\tif (!created.success) return created;\n\treturn { success: true, data: { operation: summarizeOperation(created.data.operation) } };\n}\n\n/**\n * Put the approval id and the next step in the message text, which is all\n * many MCP clients show the model; `details` carries the same values.\n */\nfunction withInstruction(result: Result<never>): Result<never> {\n\tif (result.success || result.error.code !== \"TRANSFER_APPROVAL_REQUIRED\") return result;\n\tconst details = result.error.details ?? {};\n\tconst approvalId = String(details.approvalId);\n\tconst expiresAt = String(details.expiresAt);\n\treturn failure(\n\t\t\"TRANSFER_APPROVAL_REQUIRED\",\n\t\t`Approval ${approvalId} is pending until ${expiresAt}. An admin must approve it in the ` +\n\t\t\t\"EmDash admin under Settings → Transfer. Then call this tool again with the same \" +\n\t\t\t`arguments and approvalId \"${approvalId}\".`,\n\t\tdetails,\n\t);\n}\n\nexport interface ExportTotals {\n\trecords: { total: number; byKind: Partial<Record<RecordKind, number>> };\n\tmedia: { count: number; totalBytes: number };\n\tfiles: { count: number; totalBytes: number };\n}\n\nasync function exportTotals(\n\tdb: Kysely<Database>,\n\tstorage: Storage,\n\toperationId: string,\n): Promise<ExportTotals> {\n\tconst operation = await new TransferOperationRepository(db).require(operationId);\n\tconst manifest = await openExportPackage({ db, storage, operation }).manifest();\n\tconst byKind: Partial<Record<RecordKind, number>> = {};\n\tlet total = 0;\n\tfor (const kind of RECORD_KINDS) {\n\t\tconst summary = manifest.records[kind];\n\t\tif (!summary) continue;\n\t\tbyKind[kind] = summary.count;\n\t\ttotal += summary.count;\n\t}\n\treturn {\n\t\trecords: { total, byKind },\n\t\tmedia: { count: manifest.media.count, totalBytes: manifest.media.totalBytes },\n\t\tfiles: { count: manifest.files.count, totalBytes: manifest.files.totalBytes },\n\t};\n}\n\nexport interface ExportStatus {\n\toperation: OperationSummary;\n\t/** Present once the export is complete. */\n\ttotals?: ExportTotals;\n\t/** Milliseconds until the next call makes progress, or null once the export has ended. */\n\tnextRequestInMs: number | null;\n}\n\nexport async function exportStatus(\n\tcontext: TransferContext,\n\tinput: { operationId: string; advance: boolean },\n): Promise<Result<ExportStatus>> {\n\tlet operation: PublicTransferOperation;\n\tlet nextRequestInMs: number | null;\n\tif (input.advance) {\n\t\tif (!context.storage) return storageMissing();\n\t\tconst step = await handleExportAdvance(context.db, context.storage, {\n\t\t\toperationId: input.operationId,\n\t\t});\n\t\tif (!step.success) return step;\n\t\toperation = step.data.operation;\n\t\tnextRequestInMs = step.data.nextRequestInMs;\n\t} else {\n\t\tconst read = await handleExportGet(context.db, input.operationId);\n\t\tif (!read.success) return read;\n\t\toperation = read.data.operation;\n\t\tnextRequestInMs = operation.state === \"pending\" || operation.state === \"running\" ? 0 : null;\n\t}\n\tconst status: ExportStatus = { operation: summarizeOperation(operation), nextRequestInMs };\n\tif (operation.state === \"complete\" && operation.stagingCollectedAt === null) {\n\t\tif (!context.storage) return storageMissing();\n\t\ttry {\n\t\t\tstatus.totals = await exportTotals(context.db, context.storage, operation.id);\n\t\t} catch (error) {\n\t\t\treturn transferFailure(error, \"TRANSFER_EXPORT_ERROR\");\n\t\t}\n\t}\n\treturn { success: true, data: status };\n}\n\n// ── Import ──────────────────────────────────────────────────────\n\nexport interface AnalyzeStatus {\n\toperation: OperationSummary;\n\tplan?: PlanSummary;\n\tnextRequestInMs: number | null;\n}\n\nexport async function analyzeImport(\n\tcontext: TransferContext,\n\tinput: { operationId: string; decisions?: SiteImportDecisionsInput },\n): Promise<Result<AnalyzeStatus>> {\n\tif (!context.storage) return storageMissing();\n\tconst result = await handleImportAnalyze(context.db, context.storage, {\n\t\toperationId: input.operationId,\n\t\tdecisions: input.decisions,\n\t\ttarget: analysisTargetContext({\n\t\t\ti18n: getI18nConfig(),\n\t\t\tmaxUploadSize: context.maxUploadSize,\n\t\t}),\n\t});\n\tif (!result.success) return result;\n\tconst { operation, plan, planDigest, nextRequestInMs } = result.data;\n\treturn {\n\t\tsuccess: true,\n\t\tdata: {\n\t\t\toperation: summarizeOperation(operation),\n\t\t\t...(plan && planDigest ? { plan: summarizePlan(plan, planDigest) } : {}),\n\t\t\tnextRequestInMs,\n\t\t},\n\t};\n}\n\nexport interface StartImportInput {\n\toperationId: string;\n\tpackageDigest: Sha256Digest;\n\tplanDigest: Sha256Digest;\n\tapprovalId?: string;\n\t/** Whether the caller's token holds `transfer:execute`. */\n\tscoped: boolean;\n}\n\n/**\n * Check what `handleImportExecute` would, before a pending grant is created,\n * so an admin is only ever asked to approve an import that can run.\n */\nasync function assertExecutable(\n\tcontext: TransferContext & { storage: Storage },\n\tinput: StartImportInput,\n): Promise<void> {\n\tconst operation = await new TransferOperationRepository(context.db).get(input.operationId);\n\tif (!operation || operation.kind !== \"import\") {\n\t\tthrow new TransferError(\"TRANSFER_OPERATION_NOT_FOUND\", \"Transfer operation not found\");\n\t}\n\tif (operation.packageDigest !== input.packageDigest) {\n\t\tthrow new TransferError(\"TRANSFER_PACKAGE_DIGEST_MISMATCH\", \"Package digest does not match\");\n\t}\n\tif (operation.planDigest === null || operation.planDigest !== input.planDigest) {\n\t\tthrow new TransferError(\"TRANSFER_PLAN_DIGEST_MISMATCH\", \"Plan digest does not match\");\n\t}\n\tif (operation.state !== \"planned\") {\n\t\tthrow new TransferError(\"TRANSFER_INVALID_STATE\", \"Import is not waiting to be started\");\n\t}\n\tconst plan = await loadImportPlan(context.storage, operation);\n\tif (!plan || !isPlanExecutable(plan)) {\n\t\tthrow new TransferError(\"TRANSFER_PLAN_BLOCKED\", \"The import plan has blockers\");\n\t}\n}\n\nexport async function startImport(\n\tcontext: TransferContext,\n\tcaller: TransferCaller,\n\tinput: StartImportInput,\n): Promise<Result<{ operation: OperationSummary }>> {\n\tconst storage = context.storage;\n\tif (!storage) return storageMissing();\n\tif (!input.scoped) {\n\t\tif (caller.tokenId === undefined) return tokenRequired();\n\t\tif (input.approvalId === undefined) {\n\t\t\ttry {\n\t\t\t\tawait assertExecutable({ ...context, storage }, input);\n\t\t\t} catch (error) {\n\t\t\t\treturn transferFailure(error, \"TRANSFER_IMPORT_ERROR\");\n\t\t\t}\n\t\t\treturn withInstruction(\n\t\t\t\tawait requestTransferApproval(context.db, {\n\t\t\t\t\tuserId: caller.userId,\n\t\t\t\t\taction: \"import\",\n\t\t\t\t\toperationId: input.operationId,\n\t\t\t\t\tpackageDigest: input.packageDigest,\n\t\t\t\t\tplanDigest: input.planDigest,\n\t\t\t\t\trequestedByTokenId: caller.tokenId,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\tconst executed = await handleImportExecute(context.db, storage, {\n\t\toperationId: input.operationId,\n\t\tuserId: caller.userId,\n\t\tpackageDigest: input.packageDigest,\n\t\tplanDigest: input.planDigest,\n\t\t...(input.scoped || input.approvalId === undefined\n\t\t\t? {}\n\t\t\t: { approval: { id: input.approvalId, tokenId: caller.tokenId } }),\n\t});\n\tif (!executed.success) return executed;\n\treturn { success: true, data: { operation: summarizeOperation(executed.data.operation) } };\n}\n\nexport interface ImportStatus {\n\toperation: OperationSummary;\n\tfiles: { declared: number; verified: number };\n}\n\nexport async function importStatus(\n\tcontext: TransferContext,\n\toperationId: string,\n): Promise<Result<ImportStatus>> {\n\tconst result = await handleImportGet(context.db, operationId);\n\tif (!result.success) return result;\n\treturn {\n\t\tsuccess: true,\n\t\tdata: {\n\t\t\toperation: summarizeOperation(result.data.operation),\n\t\t\tfiles: { declared: result.data.files.declared, verified: result.data.files.verified },\n\t\t},\n\t};\n}\n\nexport async function resumeImport(\n\tcontext: TransferContext,\n\tcaller: TransferCaller,\n\toperationId: string,\n): Promise<Result<{ operation: OperationSummary; nextRequestInMs: number | null }>> {\n\tif (!context.storage) return storageMissing();\n\tconst step = await handleImportAdvance(context.db, context.storage, {\n\t\toperationId,\n\t\tuserId: caller.userId,\n\t});\n\tif (!step.success) return step;\n\treturn {\n\t\tsuccess: true,\n\t\tdata: {\n\t\t\toperation: summarizeOperation(step.data.operation),\n\t\t\tnextRequestInMs: step.data.nextRequestInMs,\n\t\t},\n\t};\n}\n\nexport async function importReceipt(\n\tcontext: TransferContext,\n\toperationId: string,\n): Promise<Result<{ receipt: SiteImportReceipt }>> {\n\treturn handleImportReceipt(context.db, operationId);\n}\n","/**\n * EmDash MCP Server\n *\n * Exposes content, schema, media, search, taxonomy, and menu operations\n * as MCP tools over the Streamable HTTP transport.\n *\n * Tools use the EmDashHandlers interface (same as locals.emdash) so\n * they work with the pre-bound handlers that the middleware provides.\n * The handlers instance is passed per-request via authInfo on the transport.\n */\n\nimport type { Permission, RoleLevel } from \"@emdash-cms/auth\";\nimport { canActOnOwn, hasPermission, Permissions, Role } from \"@emdash-cms/auth\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { APIContext } from \"astro\";\nimport { z } from \"zod\";\n\nimport {\n\tbylineCreateBody,\n\tbylineUpdateBody,\n\tCONTENT_TYPE_RE,\n\tcontentBylineInputSchema,\n\tcontentSeoInput,\n\tcreateBlockTypeBody,\n\tcreateCollectionBody,\n\tcreateTaxonomyDefBody,\n\tupdateCollectionBody,\n\tupdateBlockTypeBody,\n\tupdateFieldBody,\n\tupdateTaxonomyDefBody,\n} from \"#api/schemas.js\";\n\nimport type { MediaUsageRepairRequest } from \"../api/schemas/media-usage.js\";\nimport type { EmDashHandlers } from \"../astro/types.js\";\nimport { hasScope } from \"../auth/api-tokens.js\";\nimport { menuTag, siteSettingsTag, taxonomyTag } from \"../cache/chrome-tags.js\";\nimport { convertDataForRead, convertDataForWrite } from \"../client/portable-text.js\";\nimport type { FieldSchema } from \"../client/portable-text.js\";\nimport { decodeCursor, InvalidCursorError } from \"../database/repositories/types.js\";\nimport type { RouteCallerInput } from \"../plugins/routes.js\";\nimport {\n\tTRANSFER_SCOPES,\n\ttype TransferApprovalAction,\n\ttype TransferScope,\n} from \"../transfer/auth.js\";\nimport { readSiteWriteFence, recordSiteWrite } from \"../transfer/fence.js\";\nimport { toSha256Digest } from \"../transfer/format/digest.js\";\nimport { siteImportDecisionsInputSchema } from \"../transfer/format/plan.js\";\nimport { decodeBase64, encodeBase64 } from \"../utils/base64.js\";\nimport {\n\tanalyzeImport,\n\texportStatus,\n\thasOperationGrant,\n\timportReceipt,\n\timportStatus,\n\tresumeImport,\n\tstartExport,\n\tstartImport,\n\ttransferCapabilities,\n\ttype TransferContext,\n} from \"./transfer.js\";\n\nconst COLLECTION_SLUG_PATTERN = /^[a-z][a-z0-9_]*$/;\n/** http(s) scheme matcher used by `settings_update` URL validation. */\nconst HTTP_SCHEME_PATTERN = /^https?:\\/\\//i;\n/**\n * Shared wording for the `_rev` parameter on write tools. Agents only see the\n * tool schema, so the retry protocol is stated here.\n */\nconst REV_PARAM_DESCRIPTION =\n\t\"Revision token proving you have read the current item. Call content_get \" +\n\t\"first and pass back the _rev it returns. If this call fails with CONFLICT \" +\n\t\"the item changed in the meantime: call content_get again and retry with \" +\n\t\"the new token.\";\n\n/**\n * Replaces Zod's \"expected string, received undefined\" for a caller that never\n * read the schema, so the message says where the token comes from.\n */\nconst REV_MISSING_ERROR =\n\t\"_rev is required: call content_get for this item and pass back the _rev it returns.\";\n\nconst SHA256_DIGEST_PATTERN = /^sha256:[0-9a-f]{64}$/;\nconst TRANSFER_OPERATION_ID_PATTERN = /^[0-9A-Za-z_-]{1,64}$/;\n\nconst transferOperationIdSchema = z\n\t.string()\n\t.regex(TRANSFER_OPERATION_ID_PATTERN, \"Invalid operation id\")\n\t.describe(\"Transfer operation id\");\n\nconst transferApprovalIdSchema = z\n\t.string()\n\t.min(1)\n\t.max(64)\n\t.describe(\"Approval id from an earlier TRANSFER_APPROVAL_REQUIRED error, once approved\");\n\n/**\n * The site transfer tools. Like the transfer REST API they are exempt from\n * the site write fence, so an import started over MCP can be driven to\n * completion over MCP.\n */\nconst TRANSFER_TOOL_NAMES: ReadonlySet<string> = new Set([\n\t\"site_transfer_capabilities\",\n\t\"site_export_start\",\n\t\"site_export_status\",\n\t\"site_import_analyze\",\n\t\"site_import_start\",\n\t\"site_import_status\",\n\t\"site_import_resume\",\n\t\"site_import_receipt\",\n]);\n\nconst APPROVAL_FLOW_DESCRIPTION =\n\t\"If the token lacks the scope, the first call fails with TRANSFER_APPROVAL_REQUIRED and \" +\n\t\"details.approvalId; an admin must approve that request in the EmDash admin \" +\n\t\"(Settings → Transfer). Then repeat the call with the same arguments plus approvalId. \" +\n\t\"Approvals are single-use, bound to this user, this token, and these exact arguments, \" +\n\t\"and expire 15 minutes after they are requested or approved.\";\n\nconst TAXONOMY_CURSOR_VERSION = 2;\nconst MAX_TAXONOMY_CURSOR_LENGTH = 2048;\nconst contentDateTimeInputSchema = z.iso\n\t.datetime({ offset: true, message: \"must be an ISO 8601 datetime\" })\n\t.or(\n\t\tz.iso.datetime({\n\t\t\toffset: true,\n\t\t\tprecision: -1,\n\t\t\tmessage: \"must be an ISO 8601 datetime\",\n\t\t}),\n\t);\n\n// ---------------------------------------------------------------------------\n// Shared schemas — kept in sync with `api/schemas/settings.ts` (which the\n// REST handler validates against). Defined inline to match the rest of the\n// MCP tool registrations rather than reaching across into the REST layer.\n// ---------------------------------------------------------------------------\n\nconst settingsMediaReferenceSchema = z.object({\n\tmediaId: z.string().describe(\"Media item ID (use media_create or media_list)\"),\n\talt: z.string().optional().describe(\"Alt text for the media reference\"),\n});\n\nconst settingsSocialSchema = z.object({\n\ttwitter: z.string().optional(),\n\tgithub: z.string().optional(),\n\tfacebook: z.string().optional(),\n\tinstagram: z.string().optional(),\n\tlinkedin: z.string().optional(),\n\tyoutube: z.string().optional(),\n});\n\nconst settingsSeoSchema = z.object({\n\ttitleSeparator: z\n\t\t.string()\n\t\t.max(10)\n\t\t.optional()\n\t\t.describe(\"Separator between page title and site title (e.g. ' | ')\"),\n\tdefaultOgImage: settingsMediaReferenceSchema\n\t\t.nullable()\n\t\t.optional()\n\t\t.describe(\"Default Open Graph image when content has none; null removes it\"),\n\trobotsTxt: z\n\t\t.string()\n\t\t.max(5000)\n\t\t.optional()\n\t\t.describe(\"Custom robots.txt body. Leave unset for the EmDash default.\"),\n\tgoogleVerification: z\n\t\t.string()\n\t\t.max(100)\n\t\t.optional()\n\t\t.describe(\"Google Search Console verification token\"),\n\tbingVerification: z\n\t\t.string()\n\t\t.max(100)\n\t\t.optional()\n\t\t.describe(\"Bing Webmaster Tools verification token\"),\n});\n\nconst mediaUsageRepairToolSchema = z\n\t.object({\n\t\tscope: z.enum([\"collection\", \"all\"]).describe(\"Repair one collection or all collections\"),\n\t\tcollection: z\n\t\t\t.string()\n\t\t\t.min(1)\n\t\t\t.max(63)\n\t\t\t.regex(COLLECTION_SLUG_PATTERN, \"Invalid collection slug\")\n\t\t\t.optional()\n\t\t\t.describe(\"Collection slug; required only when scope is collection\"),\n\t})\n\t.strict()\n\t.superRefine((input, ctx) => {\n\t\tif (input.scope === \"collection\" && input.collection === undefined) {\n\t\t\tctx.addIssue({\n\t\t\t\tcode: \"custom\",\n\t\t\t\tpath: [\"collection\"],\n\t\t\t\tmessage: \"Collection is required when scope is collection\",\n\t\t\t});\n\t\t}\n\t\tif (input.scope === \"all\" && input.collection !== undefined) {\n\t\t\tctx.addIssue({\n\t\t\t\tcode: \"custom\",\n\t\t\t\tpath: [\"collection\"],\n\t\t\t\tmessage: \"Collection must be omitted when scope is all\",\n\t\t\t});\n\t\t}\n\t});\n\nconst schemaUpdateCollectionToolSchema = z.object({\n\tslug: z\n\t\t.string()\n\t\t.min(1)\n\t\t.max(63)\n\t\t.regex(COLLECTION_SLUG_PATTERN, \"Invalid collection slug\")\n\t\t.describe(\"Collection slug to update; the slug itself cannot be changed\"),\n\tlabel: updateCollectionBody.shape.label.describe(\"New plural display name\"),\n\tlabelSingular: updateCollectionBody.shape.labelSingular.describe(\"New singular display name\"),\n\tdescription: updateCollectionBody.shape.description.describe(\"New collection description\"),\n\ticon: updateCollectionBody.shape.icon.describe(\"New admin UI icon name\"),\n\tsupports: updateCollectionBody.shape.supports.describe(\n\t\t\"Complete feature list to enable; omit to preserve the current list\",\n\t),\n\turlPattern: updateCollectionBody.shape.urlPattern.describe(\n\t\t\"New public URL pattern; pass null to clear it\",\n\t),\n\troutable: updateCollectionBody.shape.routable.describe(\n\t\t\"Whether entries require a slug before they can be published\",\n\t),\n\thasSeo: updateCollectionBody.shape.hasSeo.describe(\n\t\t\"Whether the collection supports SEO metadata\",\n\t),\n\tgroup: updateCollectionBody.shape.group.describe(\n\t\t\"Admin sidebar folder shared with other collections of the same group; pass null to move the collection back inline\",\n\t),\n\tcommentsEnabled: updateCollectionBody.shape.commentsEnabled.describe(\n\t\t\"Whether comments are enabled for this collection\",\n\t),\n\tcommentsModeration: updateCollectionBody.shape.commentsModeration.describe(\n\t\t\"Comment moderation policy\",\n\t),\n\tcommentsClosedAfterDays: updateCollectionBody.shape.commentsClosedAfterDays.describe(\n\t\t\"Close comments after this many days; 0 keeps them open\",\n\t),\n\tcommentsAutoApproveUsers: updateCollectionBody.shape.commentsAutoApproveUsers.describe(\n\t\t\"Whether comments from authenticated users are automatically approved\",\n\t),\n\teditLocking: updateCollectionBody.shape.editLocking.describe(\n\t\t\"Whether opening an entry takes an edit lock that refuses other editors' writes\",\n\t),\n\ttitleField: updateCollectionBody.shape.titleField.describe(\n\t\t\"Field slug to use as the Title column in admin lists; pass null to fall back to the default\",\n\t),\n\tdateField: updateCollectionBody.shape.dateField.describe(\n\t\t\"Datetime field slug to use as the Date column in admin lists; pass null to fall back to the default\",\n\t),\n});\n\nconst schemaUpdateFieldToolSchema = z.object({\n\tcollection: z\n\t\t.string()\n\t\t.min(1)\n\t\t.max(63)\n\t\t.regex(COLLECTION_SLUG_PATTERN, \"Invalid collection slug\")\n\t\t.describe(\"Collection slug containing the field\"),\n\tfieldSlug: z\n\t\t.string()\n\t\t.min(1)\n\t\t.max(63)\n\t\t.regex(COLLECTION_SLUG_PATTERN, \"Invalid field slug\")\n\t\t.describe(\"Field slug to update; the slug itself cannot be changed\"),\n\tlabel: updateFieldBody.shape.label.describe(\"New display name\"),\n\ttype: updateFieldBody.shape.type.describe(\n\t\t\"New field type; only string, text, and slug aliases can be changed in place\",\n\t),\n\trequired: updateFieldBody.shape.required.describe(\n\t\t\"Whether the field is required; changing this requires a manual content migration\",\n\t),\n\tunique: updateFieldBody.shape.unique.describe(\n\t\t\"Whether field values must be unique; changing this requires a manual content migration\",\n\t),\n\tdefaultValue: updateFieldBody.shape.defaultValue.describe(\"Default value for new content\"),\n\tvalidation: updateFieldBody.shape.validation.describe(\n\t\t\"Validation constraints; pass null to clear existing constraints\",\n\t),\n\twidget: updateFieldBody.shape.widget.describe(\"Admin editor widget name\"),\n\toptions: updateFieldBody.shape.options.describe(\"Widget configuration\"),\n\tsortOrder: updateFieldBody.shape.sortOrder.describe(\"Field order in the content editor\"),\n\tsearchable: updateFieldBody.shape.searchable.describe(\n\t\t\"Whether full-text search indexes the field\",\n\t),\n\ttranslatable: updateFieldBody.shape.translatable.describe(\n\t\t\"Whether values vary by locale; changing to false requires a manual content migration\",\n\t),\n\tindexed: updateFieldBody.shape.indexed.describe(\n\t\t\"Create or remove a physical index for structured sorting\",\n\t),\n});\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\ntype HandlerResult = {\n\tsuccess: boolean;\n\tdata?: unknown;\n\terror?: unknown;\n};\n\ntype SuccessEnvelope = {\n\tcontent: Array<{ type: \"text\"; text: string }>;\n\tstructuredContent?: Record<string, unknown>;\n\t_meta?: Record<string, unknown>;\n};\n\ntype ErrorEnvelope = {\n\tcontent: Array<{ type: \"text\"; text: string }>;\n\tisError: true;\n\t_meta: { code: string; details?: Record<string, unknown> };\n};\n\ntype TaxonomyListCursor = { id: string };\n\nfunction encodeTaxonomyCursor(term: { id: string }): string {\n\tconst cursor = encodeBase64(\n\t\tJSON.stringify({\n\t\t\tv: TAXONOMY_CURSOR_VERSION,\n\t\t\tid: term.id,\n\t\t}),\n\t);\n\tif (cursor.length > MAX_TAXONOMY_CURSOR_LENGTH) {\n\t\tthrow new InvalidCursorError(cursor);\n\t}\n\treturn cursor;\n}\n\nfunction decodeTaxonomyCursor(cursor: string): TaxonomyListCursor {\n\tif (!cursor || cursor.length > MAX_TAXONOMY_CURSOR_LENGTH) {\n\t\tthrow new InvalidCursorError(cursor);\n\t}\n\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(decodeBase64(cursor));\n\t} catch {\n\t\tthrow new InvalidCursorError(cursor);\n\t}\n\n\tif (parsed === null || typeof parsed !== \"object\") {\n\t\tthrow new InvalidCursorError(cursor);\n\t}\n\n\tconst candidate = parsed as Record<string, unknown>;\n\tif (\"v\" in candidate) {\n\t\tconst { v, id } = candidate;\n\t\tif (\n\t\t\tv !== TAXONOMY_CURSOR_VERSION ||\n\t\t\ttypeof id !== \"string\" ||\n\t\t\tid.length === 0 ||\n\t\t\tid.includes(\"\\0\")\n\t\t) {\n\t\t\tthrow new InvalidCursorError(cursor);\n\t\t}\n\t\treturn { id };\n\t}\n\n\tconst legacy = decodeCursor(cursor);\n\tif (legacy.orderValue.includes(\"\\0\") || legacy.id.length === 0 || legacy.id.includes(\"\\0\")) {\n\t\tthrow new InvalidCursorError(cursor);\n\t}\n\treturn { id: legacy.id };\n}\n\n/**\n * Return a successful tool response with the data as pretty-printed JSON.\n */\nfunction respondData(data: unknown): SuccessEnvelope {\n\treturn {\n\t\tcontent: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n\t};\n}\n\n/**\n * Return a structured error tool response.\n *\n * The error code is emitted both in the human-readable message (as a stable\n * `[CODE]` prefix that callers can match on) and in `_meta.code` so MCP-aware\n * clients can read it programmatically once the SDK supports forwarding meta.\n */\nfunction respondError(\n\tcode: string,\n\tmessage: string,\n\tdetails?: Record<string, unknown>,\n): ErrorEnvelope {\n\tconst text = `[${code}] ${message}`;\n\tconst meta: { code: string; details?: Record<string, unknown> } = { code };\n\tif (details !== undefined) meta.details = details;\n\treturn {\n\t\tcontent: [{ type: \"text\", text }],\n\t\tisError: true,\n\t\t_meta: meta,\n\t};\n}\n\n/**\n * Auth/permission errors thrown from `requireScope` / `requireRole` /\n * `requireOwnership` / `requireDraftAccess`. Carries a stable string `code`\n * field so `respondHandlerError` can surface it through `_meta.code` and\n * the message prefix.\n *\n * Distinct from `McpError` (which the SDK catches at JSON-RPC level — the\n * code there is numeric, not a stable EmDash error code).\n */\nclass EmDashAuthError extends Error {\n\toverride readonly name = \"EmDashAuthError\";\n\tconstructor(\n\t\tmessage: string,\n\t\treadonly code: string,\n\t) {\n\t\tsuper(message);\n\t}\n}\n\n/**\n * Map an unknown thrown error to a structured error envelope.\n *\n * Recognises (in priority order):\n * - `EmDashAuthError` — `code` is a stable EmDash auth code\n * (`UNAUTHORIZED`, `INSUFFICIENT_SCOPE`, `INSUFFICIENT_PERMISSIONS`).\n * - `Error` objects with an `apiError: { code, details? }` annotation\n * (handlers throw these for NOT_FOUND / CONFLICT inside transactions;\n * see `api/handlers/content.ts:538`).\n * - `SchemaError` (and any error with a string `code` field) — the code\n * is forwarded verbatim. `details` is forwarded too if present.\n * - Plain `Error` instances — message preserved, code falls back to\n * `fallbackCode` (or `INTERNAL_ERROR`).\n * - Strings — used directly as the message.\n * - Anything else — coerced via `String()`.\n *\n * The original message is always preserved so tests and humans can see the\n * specific failure cause. Numeric `code` values (e.g. on `McpError`) are\n * ignored — the field is reserved for stable string codes.\n */\nfunction respondHandlerError(error: unknown, fallbackCode = \"INTERNAL_ERROR\"): ErrorEnvelope {\n\tlet code = fallbackCode;\n\tlet message: string;\n\tlet details: Record<string, unknown> | undefined;\n\n\tif (error instanceof EmDashAuthError) {\n\t\tmessage = error.message || fallbackCode;\n\t\tcode = error.code;\n\t} else if (error instanceof Error) {\n\t\tmessage = error.message || fallbackCode;\n\t\tconst apiError = (error as { apiError?: { code?: string; details?: unknown } }).apiError;\n\t\tif (apiError && typeof apiError.code === \"string\" && apiError.code) {\n\t\t\tcode = apiError.code;\n\t\t\tif (apiError.details && typeof apiError.details === \"object\") {\n\t\t\t\tdetails = apiError.details as Record<string, unknown>;\n\t\t\t}\n\t\t} else {\n\t\t\t// Errors that carry their own `code` (SchemaError, custom errors).\n\t\t\t// Skip numeric codes (McpError, Node fs errors) — `_meta.code` is\n\t\t\t// reserved for stable string codes.\n\t\t\tconst rawCode = (error as { code?: unknown }).code;\n\t\t\tif (typeof rawCode === \"string\" && rawCode) {\n\t\t\t\tcode = rawCode;\n\t\t\t}\n\t\t\tconst rawDetails = (error as { details?: unknown }).details;\n\t\t\tif (rawDetails && typeof rawDetails === \"object\") {\n\t\t\t\tdetails = rawDetails as Record<string, unknown>;\n\t\t\t}\n\t\t}\n\t} else if (typeof error === \"string\") {\n\t\tmessage = error;\n\t} else {\n\t\tmessage = String(error);\n\t}\n\n\treturn respondError(code, message, details);\n}\n\n/**\n * Unwrap an ApiResult<T> into MCP tool result format.\n *\n * On success returns the data as JSON. On failure propagates the structured\n * `{ code, message, details }` from the handler so the caller sees both a\n * machine-readable code (in `_meta.code` and as a `[CODE]` message prefix)\n * and the original human-readable message.\n */\nfunction unwrap(result: HandlerResult): SuccessEnvelope | ErrorEnvelope {\n\tif (result.success && result.data !== undefined) {\n\t\treturn respondData(result.data);\n\t}\n\tconst err =\n\t\tresult.error && typeof result.error === \"object\"\n\t\t\t? (result.error as { code?: unknown; message?: unknown; details?: unknown })\n\t\t\t: undefined;\n\tif (!err) return respondError(\"INTERNAL_ERROR\", \"Unknown error\");\n\tconst code = typeof err.code === \"string\" && err.code ? err.code : \"INTERNAL_ERROR\";\n\tconst message = typeof err.message === \"string\" && err.message ? err.message : \"Unknown error\";\n\tconst details =\n\t\terr.details && typeof err.details === \"object\"\n\t\t\t? (err.details as Record<string, unknown>)\n\t\t\t: undefined;\n\treturn respondError(code, message, details);\n}\n\n/**\n * Return a JSON text block (success path for tools that don't go through\n * the ApiResult-returning handler layer, e.g. schema/menu/taxonomy).\n */\nfunction jsonResult(data: unknown): SuccessEnvelope {\n\treturn respondData(data);\n}\n\n// ---------------------------------------------------------------------------\n// Context extraction\n//\n// The route handler passes the runtime and authenticated user in authInfo.extra.\n// ---------------------------------------------------------------------------\n\ninterface EmDashExtra {\n\temdash: EmDashHandlers;\n\tuser: RouteCallerInput;\n\tuserId: string;\n\t/** The authenticated user's RBAC role level. */\n\tuserRole: RoleLevel;\n\t/** Token scopes — undefined for session auth (all access allowed). */\n\ttokenScopes?: string[];\n\t/** Id of the API or OAuth token the caller authenticated with. */\n\ttokenId?: string;\n\t/** The route cache of the MCP request, used to invalidate the same tags the REST routes do. */\n\tcache?: APIContext[\"cache\"];\n}\n\nfunction isPublished(t: unknown): boolean {\n\treturn (\n\t\ttypeof t === \"object\" &&\n\t\tt !== null &&\n\t\t\"status\" in t &&\n\t\t(t as Record<string, unknown>).status === \"published\"\n\t);\n}\n\nfunction getExtra(extra: { authInfo?: { extra?: Record<string, unknown> } }): EmDashExtra {\n\tconst payload = extra.authInfo?.extra as EmDashExtra | undefined;\n\tif (!payload?.emdash) {\n\t\tthrow new Error(\"EmDash not available — server misconfigured\");\n\t}\n\treturn payload;\n}\n\nfunction getEmDash(extra: { authInfo?: { extra?: Record<string, unknown> } }): EmDashHandlers {\n\treturn getExtra(extra).emdash;\n}\n\n/**\n * Unwrap a write result, first invalidating `tags` in the route cache when the\n * write succeeded. Pass `changedEarlier` when an earlier step of the same tool\n * already changed live content, so a failure in a later step still invalidates.\n */\nasync function unwrapAndInvalidate(\n\textra: { authInfo?: { extra?: Record<string, unknown> } },\n\tresult: HandlerResult,\n\ttags: string[],\n\tchangedEarlier = false,\n): Promise<SuccessEnvelope | ErrorEnvelope> {\n\tif (result.success || changedEarlier) {\n\t\tconst { cache } = getExtra(extra);\n\t\tif (cache?.enabled) await cache.invalidate({ tags });\n\t}\n\treturn unwrap(result);\n}\n\nasync function getCollectionFields(\n\tec: EmDashHandlers,\n\tcollection: string,\n): Promise<FieldSchema[] | null> {\n\ttry {\n\t\tconst { SchemaRegistry } = await import(\"../schema/index.js\");\n\t\tconst { expandCollectionBlockFields } = await import(\"../schema/block-values.js\");\n\t\tconst col = await new SchemaRegistry(ec.db).getCollectionWithFields(collection);\n\t\treturn col ? (await expandCollectionBlockFields(ec.db, col)).fields : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Convert markdown strings to Portable Text for `portableText` fields on write.\n * Non-string values pass through, so callers may still send Portable Text. If\n * the schema can't be loaded, data is returned unchanged for the handler to\n * validate.\n */\nasync function convertWriteData(\n\tec: EmDashHandlers,\n\tcollection: string,\n\tdata: Record<string, unknown>,\n): Promise<Record<string, unknown>> {\n\tconst fields = await getCollectionFields(ec, collection);\n\tif (!fields) return data;\n\treturn convertDataForWrite(data, fields);\n}\n\n/**\n * Convert `portableText` field values on each item's `data` to markdown,\n * mutating in place. Inverse of {@link convertWriteData}, gated on the read\n * tools' `markdown` argument.\n */\nasync function applyReadMarkdown(\n\tec: EmDashHandlers,\n\tcollection: string,\n\titems: Array<Record<string, unknown>>,\n): Promise<void> {\n\tconst fields = await getCollectionFields(ec, collection);\n\tif (!fields) return;\n\tfor (const item of items) {\n\t\tif (item.data && typeof item.data === \"object\") {\n\t\t\titem.data = convertDataForRead(\n\t\t\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- narrowed by typeof check above\n\t\t\t\titem.data as Record<string, unknown>,\n\t\t\t\tfields,\n\t\t\t\tfalse,\n\t\t\t);\n\t\t}\n\t}\n}\n\nasync function invalidateBylines(): Promise<void> {\n\tconst { invalidateBylineCache } = await import(\"../bylines/index.js\");\n\tinvalidateBylineCache();\n}\n\n/**\n * Enforce a scope requirement on the current request.\n *\n * When tokenScopes is undefined (session auth), all operations are allowed\n * since session users have full access based on their role. When scopes are\n * present (token auth), the required scope must be included.\n */\nfunction requireScope(\n\textra: { authInfo?: { extra?: Record<string, unknown> } },\n\tscope: string,\n): void {\n\tconst payload = getExtra(extra);\n\tif (payload.tokenScopes && !hasScope(payload.tokenScopes, scope)) {\n\t\tthrow new EmDashAuthError(`Insufficient scope: requires ${scope}`, \"INSUFFICIENT_SCOPE\");\n\t}\n}\n\n/**\n * Defense-in-depth: enforce a minimum RBAC role on the current request.\n *\n * This is checked in addition to scope requirements. Even if a token has\n * the right scopes (e.g. due to a bug in scope clamping), the user's\n * actual role must still meet the minimum.\n */\nfunction requireRole(\n\textra: { authInfo?: { extra?: Record<string, unknown> } },\n\tminRole: RoleLevel,\n): void {\n\tconst payload = getExtra(extra);\n\tif (payload.userRole < minRole) {\n\t\tthrow new EmDashAuthError(\n\t\t\t\"Insufficient permissions for this operation\",\n\t\t\t\"INSUFFICIENT_PERMISSIONS\",\n\t\t);\n\t}\n}\n\ntype TransferScopeRequirement = TransferScope | \"transfer:*\";\n\n/**\n * Whether the caller's token holds `scope` (`transfer:*`: any transfer\n * scope). A caller without token scopes holds none.\n */\nfunction transferScopeHeld(\n\textra: { authInfo?: { extra?: Record<string, unknown> } },\n\tscope: TransferScopeRequirement,\n): boolean {\n\tconst { tokenScopes } = getExtra(extra);\n\tif (!tokenScopes) return false;\n\tif (scope === \"transfer:*\") return TRANSFER_SCOPES.some((held) => hasScope(tokenScopes, held));\n\treturn hasScope(tokenScopes, scope);\n}\n\nfunction insufficientTransferScope(scope: TransferScopeRequirement): EmDashAuthError {\n\tconst required = scope === \"transfer:*\" ? TRANSFER_SCOPES.join(\" or \") : scope;\n\treturn new EmDashAuthError(`Insufficient scope: requires ${required}`, \"INSUFFICIENT_SCOPE\");\n}\n\nfunction requireTransferScope(\n\textra: { authInfo?: { extra?: Record<string, unknown> } },\n\tscope: TransferScopeRequirement,\n): void {\n\tif (!transferScopeHeld(extra, scope)) throw insufficientTransferScope(scope);\n}\n\n/**\n * Require `scope`, or a grant this user consumed with this token to start\n * `operationId`.\n */\nasync function requireTransferAccess(\n\textra: { authInfo?: { extra?: Record<string, unknown> } },\n\tscope: TransferScopeRequirement,\n\taction: TransferApprovalAction,\n\toperationId: string,\n): Promise<void> {\n\tif (transferScopeHeld(extra, scope)) return;\n\tconst { emdash, userId, tokenId } = getExtra(extra);\n\tif (await hasOperationGrant(emdash.db, { userId, tokenId }, action, operationId)) return;\n\tthrow insufficientTransferScope(scope);\n}\n\nfunction transferContext(extra: {\n\tauthInfo?: { extra?: Record<string, unknown> };\n}): TransferContext {\n\tconst { emdash } = getExtra(extra);\n\treturn { db: emdash.db, storage: emdash.storage, maxUploadSize: emdash.config.maxUploadSize };\n}\n\nfunction transferDigest(value: string) {\n\treturn toSha256Digest(value.slice(\"sha256:\".length));\n}\n\n/**\n * Whether the current user may read non-published content (drafts, scheduled,\n * trashed, revisions, compare). SUBSCRIBER may hold content:read for\n * member-only published content but must not see drafts.\n */\nfunction canReadDrafts(extra: { authInfo?: { extra?: Record<string, unknown> } }): boolean {\n\tconst payload = getExtra(extra);\n\treturn hasPermission({ role: payload.userRole }, \"content:read_drafts\");\n}\n\n/**\n * Throw if the current user cannot read non-published content. Used by\n * editor-only views (revisions, compare, trash, preview-url).\n */\nfunction requireDraftAccess(extra: { authInfo?: { extra?: Record<string, unknown> } }): void {\n\tif (!canReadDrafts(extra)) {\n\t\tthrow new EmDashAuthError(\n\t\t\t\"Insufficient permissions for this operation\",\n\t\t\t\"INSUFFICIENT_PERMISSIONS\",\n\t\t);\n\t}\n}\n\n/**\n * Enforce ownership-based permission checks, mirroring the REST API's\n * requireOwnerPerm() pattern.\n *\n * If the user is the owner, checks ownPermission. Otherwise checks\n * anyPermission (which requires EDITOR+ role).\n */\nfunction requireOwnership(\n\textra: { authInfo?: { extra?: Record<string, unknown> } },\n\townerId: string,\n\townPermission: Permission,\n\tanyPermission: Permission,\n): void {\n\tconst payload = getExtra(extra);\n\tconst user = { id: payload.userId, role: payload.userRole };\n\tif (!canActOnOwn(user, ownerId, ownPermission, anyPermission)) {\n\t\tthrow new EmDashAuthError(\n\t\t\t\"Insufficient permissions for this operation\",\n\t\t\t\"INSUFFICIENT_PERMISSIONS\",\n\t\t);\n\t}\n}\n\n/**\n * Extract the author ID from a content handler response.\n *\n * Content handlers return `{ item: { id, authorId, ... }, _rev? }`.\n * This helper navigates that shape safely. Returns \"\" when authorId is\n * missing or non-string (e.g. seed-imported content with no author);\n * `canActOnOwn` then decides based on the caller's permissions —\n * an actor with `*:edit_any` succeeds, an actor with only `*:edit_own`\n * is denied with a clean permission error.\n */\nfunction extractContentAuthorId(data: unknown): string {\n\tif (!data || typeof data !== \"object\") return \"\";\n\tconst obj = data as Record<string, unknown>;\n\tconst item =\n\t\tobj.item && typeof obj.item === \"object\" ? (obj.item as Record<string, unknown>) : obj;\n\treturn typeof item?.authorId === \"string\" ? item.authorId : \"\";\n}\n\n/**\n * Extract the resolved ID from a content handler response.\n * Handles slug -> ID resolution performed by the handler.\n */\nfunction extractContentId(data: unknown): string | undefined {\n\tif (!data || typeof data !== \"object\") return undefined;\n\tconst obj = data as Record<string, unknown>;\n\tconst item =\n\t\tobj.item && typeof obj.item === \"object\" ? (obj.item as Record<string, unknown>) : obj;\n\treturn typeof item?.id === \"string\" ? item.id : undefined;\n}\n\n/** Extract the `_rev` token from a content handler response. */\nfunction extractContentRev(data: unknown): string | undefined {\n\tif (!data || typeof data !== \"object\") return undefined;\n\tconst rev = (data as Record<string, unknown>)._rev;\n\treturn typeof rev === \"string\" ? rev : undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Server factory\n// ---------------------------------------------------------------------------\n\nexport interface PluginMcpRegistration {\n\tpluginId: string;\n\tname: string;\n\tdescription: string;\n\troute: string;\n\tpermission: string;\n\tdestructive: boolean;\n\tinputSchema: z.ZodType;\n\toutputSchema?: z.ZodType;\n}\n\nexport function createMcpServer(\n\tpluginTools: PluginMcpRegistration[] = [],\n\trequest?: Request,\n): McpServer {\n\tconst server = new McpServer(\n\t\t{ name: \"emdash\", version: \"0.1.0\" },\n\t\t{ capabilities: { logging: {} } },\n\t);\n\n\t// Wrap every tool registration's callback so EmDashAuthError throws\n\t// (from requireScope / requireRole / requireOwnership / requireDraftAccess)\n\t// surface as structured `_meta.code`-bearing tool error envelopes\n\t// instead of the SDK's text-only fallback in createToolError().\n\t//\n\t// The wrapper also applies the site write fence. Every MCP request is a\n\t// POST, so the fence middleware leaves the endpoint to this per-tool\n\t// check: every tool is fenced unless it is annotated `readOnlyHint: true`\n\t// or is a transfer tool. A tool annotated read-only must never write.\n\t//\n\t// Type-erased on purpose — the SDK's overloads are too narrow for a\n\t// generic wrapper, but the runtime contract (callback returns the tool\n\t// result envelope) holds for every registered tool.\n\tconst originalRegisterTool = server.registerTool.bind(server);\n\t(server as { registerTool: typeof server.registerTool }).registerTool = ((\n\t\tname: string,\n\t\tconfig: { annotations?: { readOnlyHint?: boolean } },\n\t\tcallback: (...callbackArgs: unknown[]) => Promise<SuccessEnvelope | ErrorEnvelope>,\n\t) => {\n\t\tconst fenced = config.annotations?.readOnlyHint !== true && !TRANSFER_TOOL_NAMES.has(name);\n\t\tconst wrapped = async (\n\t\t\t...callbackArgs: unknown[]\n\t\t): Promise<SuccessEnvelope | ErrorEnvelope> => {\n\t\t\ttry {\n\t\t\t\tif (!fenced) return await callback(...callbackArgs);\n\t\t\t\t// The SDK passes the request extra as the last callback argument.\n\t\t\t\tconst extra = callbackArgs.at(-1) as { authInfo?: { extra?: Record<string, unknown> } };\n\t\t\t\tconst { db } = getEmDash(extra);\n\t\t\t\tconst fence = await readSiteWriteFence(db);\n\t\t\t\tif (fence.error) return respondError(fence.error.code, fence.error.message);\n\t\t\t\tconst result = await callback(...callbackArgs);\n\t\t\t\t// Recorded after the write so an export whose fence was captured\n\t\t\t\t// while this tool ran still sees it.\n\t\t\t\tif (fence.exportRunning && !(\"isError\" in result && result.isError)) {\n\t\t\t\t\tawait recordSiteWrite(db);\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"INTERNAL_ERROR\");\n\t\t\t}\n\t\t};\n\t\treturn (\n\t\t\toriginalRegisterTool as unknown as (n: string, c: unknown, cb: typeof wrapped) => unknown\n\t\t)(name, config, wrapped);\n\t}) as typeof server.registerTool;\n\n\tfor (const tool of pluginTools) {\n\t\tif (!Object.hasOwn(Permissions, tool.permission)) continue;\n\t\tserver.registerTool(\n\t\t\t`${tool.pluginId}__${tool.name}`,\n\t\t\t{\n\t\t\t\tdescription: tool.description,\n\t\t\t\tinputSchema: tool.inputSchema,\n\t\t\t\toutputSchema: tool.outputSchema,\n\t\t\t\tannotations: { destructiveHint: tool.destructive },\n\t\t\t},\n\t\t\tasync (input, extra) => {\n\t\t\t\tconst payload = getExtra(extra);\n\t\t\t\tconst requiredScope = `mcp:tools:${tool.pluginId}`;\n\t\t\t\tif (payload.tokenScopes && !hasScope(payload.tokenScopes, requiredScope)) {\n\t\t\t\t\tif (request) {\n\t\t\t\t\t\tawait payload.emdash.handlePluginMcpDenied(\n\t\t\t\t\t\t\ttool.pluginId,\n\t\t\t\t\t\t\ttool.name,\n\t\t\t\t\t\t\ttool.route,\n\t\t\t\t\t\t\tpayload.userId,\n\t\t\t\t\t\t\trequest,\n\t\t\t\t\t\t\t`Missing scope: ${requiredScope}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tthrow new EmDashAuthError(\n\t\t\t\t\t\t`Insufficient scope: requires ${requiredScope}`,\n\t\t\t\t\t\t\"INSUFFICIENT_SCOPE\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (!hasPermission({ role: payload.userRole }, tool.permission as Permission)) {\n\t\t\t\t\tif (request) {\n\t\t\t\t\t\tawait payload.emdash.handlePluginMcpDenied(\n\t\t\t\t\t\t\ttool.pluginId,\n\t\t\t\t\t\t\ttool.name,\n\t\t\t\t\t\t\ttool.route,\n\t\t\t\t\t\t\tpayload.userId,\n\t\t\t\t\t\t\trequest,\n\t\t\t\t\t\t\t`Missing permission: ${tool.permission}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tthrow new EmDashAuthError(\n\t\t\t\t\t\t`Insufficient permission: requires ${tool.permission}`,\n\t\t\t\t\t\t\"INSUFFICIENT_PERMISSIONS\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (!request) return respondError(\"INTERNAL_ERROR\", \"Missing MCP request context\");\n\t\t\t\tconst routeCache = payload.cache;\n\t\t\t\tconst result = await payload.emdash.handlePluginMcpTool(\n\t\t\t\t\ttool.pluginId,\n\t\t\t\t\ttool.name,\n\t\t\t\t\ttool.route,\n\t\t\t\t\tinput,\n\t\t\t\t\tpayload.userId,\n\t\t\t\t\trequest,\n\t\t\t\t\tpayload.user,\n\t\t\t\t\trouteCache?.enabled ? (tags) => routeCache.invalidate({ tags }) : undefined,\n\t\t\t\t);\n\t\t\t\tif (!result.success) return unwrap(result);\n\t\t\t\tif (tool.outputSchema) {\n\t\t\t\t\tif (!result.data || typeof result.data !== \"object\" || Array.isArray(result.data)) {\n\t\t\t\t\t\treturn respondError(\n\t\t\t\t\t\t\t\"INVALID_PLUGIN_OUTPUT\",\n\t\t\t\t\t\t\t\"Plugin tool output must be an object when outputSchema is declared\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: JSON.stringify(result.data, null, 2) }],\n\t\t\t\t\t\tstructuredContent: result.data as Record<string, unknown>,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn respondData(result.data);\n\t\t\t},\n\t\t);\n\t}\n\n\t// =====================================================================\n\t// Content tools\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"content_list\",\n\t\t{\n\t\t\ttitle: \"List Content\",\n\t\t\tdescription:\n\t\t\t\t\"List content items in a collection with optional filtering and pagination. \" +\n\t\t\t\t\"Returns items sorted by the specified field. Use the nextCursor value from \" +\n\t\t\t\t\"the response to fetch the next page. Status can be 'draft', 'published', \" +\n\t\t\t\t\"or 'scheduled'. If no status is given, all non-trashed items are returned.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug (e.g. 'posts', 'pages')\"),\n\t\t\t\tstatus: z\n\t\t\t\t\t.enum([\"draft\", \"published\", \"scheduled\"])\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Filter by content status\"),\n\t\t\t\tlimit: z\n\t\t\t\t\t.number()\n\t\t\t\t\t.int()\n\t\t\t\t\t.min(1)\n\t\t\t\t\t.max(100)\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Max items to return (default 50, max 100)\"),\n\t\t\t\tcursor: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.min(1)\n\t\t\t\t\t.max(2048)\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Pagination cursor from a previous response\"),\n\t\t\t\torderBy: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Field to sort by (e.g. 'created_at', 'updated_at')\"),\n\t\t\t\torder: z.enum([\"asc\", \"desc\"]).optional().describe(\"Sort direction (default 'desc')\"),\n\t\t\t\tlocale: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Filter by locale (e.g. 'en', 'fr'). Only relevant when i18n is enabled.\"),\n\t\t\t\tmarkdown: z\n\t\t\t\t\t.boolean()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Return rich text (portableText) fields as Markdown strings instead of Portable Text arrays (default false).\",\n\t\t\t\t\t),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\t// Subscribers must only see published content; force the status\n\t\t\t// filter regardless of caller-supplied value.\n\t\t\tconst status = canReadDrafts(extra) ? args.status : \"published\";\n\t\t\tconst result = await ec.handleContentList(args.collection, {\n\t\t\t\tstatus,\n\t\t\t\tlimit: args.limit,\n\t\t\t\tcursor: args.cursor,\n\t\t\t\torderBy: args.orderBy,\n\t\t\t\torder: args.order,\n\t\t\t\tlocale: args.locale,\n\t\t\t});\n\t\t\tif (result.success && args.markdown) {\n\t\t\t\tconst payload = result.data;\n\t\t\t\tif (\n\t\t\t\t\tpayload &&\n\t\t\t\t\ttypeof payload === \"object\" &&\n\t\t\t\t\t\"items\" in payload &&\n\t\t\t\t\tArray.isArray(payload.items)\n\t\t\t\t) {\n\t\t\t\t\tawait applyReadMarkdown(ec, args.collection, payload.items);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn unwrap(result);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_get\",\n\t\t{\n\t\t\ttitle: \"Get Content\",\n\t\t\tdescription:\n\t\t\t\t\"Get a single content item by its ID or slug. Returns the full content data \" +\n\t\t\t\t\"including all field values, metadata, and a _rev token. content_update, \" +\n\t\t\t\t\"content_publish, content_unpublish and content_discard_draft require that \" +\n\t\t\t\t\"token, so read the item here before calling them.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug (e.g. 'posts', 'pages')\"),\n\t\t\t\tid: z.string().describe(\"Content item ID (ULID) or slug\"),\n\t\t\t\tlocale: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Locale to scope slug lookup (e.g. 'fr'). Only affects slug resolution; IDs are globally unique.\",\n\t\t\t\t\t),\n\t\t\t\tmarkdown: z\n\t\t\t\t\t.boolean()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Return rich text (portableText) fields as Markdown strings instead of Portable Text arrays (default false).\",\n\t\t\t\t\t),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\tconst result = await ec.handleContentGet(args.collection, args.id, args.locale);\n\t\t\t// Hide non-published items from users without draft access. Return a\n\t\t\t// not-found error so subscribers can't enumerate draft IDs by status.\n\t\t\tif (result.success && !canReadDrafts(extra)) {\n\t\t\t\tconst data =\n\t\t\t\t\tresult.data && typeof result.data === \"object\"\n\t\t\t\t\t\t? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- handler returns unknown data; narrowed by typeof check\n\t\t\t\t\t\t\t(result.data as Record<string, unknown>)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tconst item =\n\t\t\t\t\tdata?.item && typeof data.item === \"object\"\n\t\t\t\t\t\t? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- narrowed by typeof check\n\t\t\t\t\t\t\t(data.item as Record<string, unknown>)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tconst status = typeof item?.status === \"string\" ? item.status : null;\n\t\t\t\tif (status !== \"published\") {\n\t\t\t\t\treturn unwrap({\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\terror: { code: \"NOT_FOUND\", message: `Content item not found: ${args.id}` },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (result.success && args.markdown && result.data?.item) {\n\t\t\t\tawait applyReadMarkdown(ec, args.collection, [result.data.item]);\n\t\t\t}\n\t\t\treturn unwrap(result);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_create\",\n\t\t{\n\t\t\ttitle: \"Create Content\",\n\t\t\tdescription:\n\t\t\t\t\"Create a new content item in a collection. The 'data' object should \" +\n\t\t\t\t\"contain field values matching the collection's schema (use \" +\n\t\t\t\t\"schema_get_collection to check). For rich text (portableText) fields, \" +\n\t\t\t\t\"pass a Markdown string — converted to Portable Text automatically; prefer \" +\n\t\t\t\t\"this. Pass a Portable Text JSON array only for complex content Markdown \" +\n\t\t\t\t\"can't express (custom blocks, embeds). A slug is auto-generated if not \" +\n\t\t\t\t\"provided. Items are created as 'draft' by default — use content_publish \" +\n\t\t\t\t\"to make them live.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug (e.g. 'posts', 'pages')\"),\n\t\t\t\tdata: z\n\t\t\t\t\t.record(z.string(), z.unknown())\n\t\t\t\t\t.describe(\"Field values as key-value pairs matching the collection schema\"),\n\t\t\t\tslug: z.string().optional().describe(\"URL slug (auto-generated from title if omitted)\"),\n\t\t\t\tstatus: z\n\t\t\t\t\t.enum([\"draft\", \"published\"])\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Initial status (default 'draft'). Requires publish permission.\"),\n\t\t\t\tlocale: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Locale for this content (e.g. 'fr'). Defaults to default locale.\"),\n\t\t\t\ttranslationOf: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"ID of the content item this is a translation of. Links items in the same translation group.\",\n\t\t\t\t\t),\n\t\t\t\tmigrateBlocks: z\n\t\t\t\t\t.boolean()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Allow retained blocks to migrate to their type's active version\"),\n\t\t\t\treplaceBlocks: z\n\t\t\t\t\t.boolean()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Treat an entirely keyless blocks array as an explicit replacement\"),\n\t\t\t\tbylines: z\n\t\t\t\t\t.array(contentBylineInputSchema)\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Bylines to credit. Each entry references an existing byline by id (see byline_list / byline_create) with an optional roleLabel. The first entry becomes the primary byline.\",\n\t\t\t\t\t),\n\t\t\t\ttaxonomies: z\n\t\t\t\t\t.record(z.string(), z.array(z.string()))\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Taxonomy term assignments as { taxonomyName: [termSlug, ...] }. Term slugs are resolved in the entry's locale. Call taxonomy_list to see available taxonomies and taxonomy_list_terms to look up slugs. Missing keys leave that taxonomy unchanged.\",\n\t\t\t\t\t),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: false },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.CONTRIBUTOR);\n\t\t\tconst { emdash, userId, userRole } = getExtra(extra);\n\t\t\tconst actor = { id: userId, role: userRole };\n\n\t\t\t// Creating a translation requires edit permission on the source item\n\t\t\tif (args.translationOf) {\n\t\t\t\tconst source = await emdash.handleContentGet(args.collection, args.translationOf);\n\t\t\t\tif (!source.success) return unwrap(source);\n\t\t\t\trequireOwnership(\n\t\t\t\t\textra,\n\t\t\t\t\textractContentAuthorId(source.data),\n\t\t\t\t\t\"content:edit_own\",\n\t\t\t\t\t\"content:edit_any\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst data = await convertWriteData(emdash, args.collection, args.data);\n\n\t\t\t// Publishing requires publish permission — create as draft then publish\n\t\t\tif (args.status === \"published\") {\n\t\t\t\tconst user = { id: userId, role: userRole };\n\t\t\t\tif (!hasPermission(user, \"content:publish_own\")) {\n\t\t\t\t\tthrow new EmDashAuthError(\n\t\t\t\t\t\t\"Insufficient permissions: publishing requires content:publish_own\",\n\t\t\t\t\t\t\"INSUFFICIENT_PERMISSIONS\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst result = await emdash.handleContentCreate(args.collection, {\n\t\t\t\t\tdata,\n\t\t\t\t\tslug: args.slug,\n\t\t\t\t\tauthorId: userId,\n\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\ttranslationOf: args.translationOf,\n\t\t\t\t\tbylines: args.bylines,\n\t\t\t\t\ttaxonomies: args.taxonomies,\n\t\t\t\t\tmigrateBlocks: args.migrateBlocks,\n\t\t\t\t\treplaceBlocks: args.replaceBlocks,\n\t\t\t\t\tactor,\n\t\t\t\t});\n\t\t\t\tif (!result.success) return unwrap(result);\n\t\t\t\tconst itemId = extractContentId(result.data);\n\t\t\t\tif (itemId) {\n\t\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\t\textra,\n\t\t\t\t\t\tawait emdash.handleContentPublish(args.collection, itemId, {\n\t\t\t\t\t\t\tactor: { ...actor, source: \"mcp\" },\n\t\t\t\t\t\t\torigin: { source: \"mcp\" },\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t[args.collection, itemId],\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn unwrapAndInvalidate(extra, result, [args.collection]);\n\t\t\t}\n\n\t\t\treturn unwrapAndInvalidate(\n\t\t\t\textra,\n\t\t\t\tawait emdash.handleContentCreate(args.collection, {\n\t\t\t\t\tdata,\n\t\t\t\t\tslug: args.slug,\n\t\t\t\t\tauthorId: userId,\n\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\ttranslationOf: args.translationOf,\n\t\t\t\t\tbylines: args.bylines,\n\t\t\t\t\ttaxonomies: args.taxonomies,\n\t\t\t\t\tmigrateBlocks: args.migrateBlocks,\n\t\t\t\t\treplaceBlocks: args.replaceBlocks,\n\t\t\t\t\tactor,\n\t\t\t\t}),\n\t\t\t\t[args.collection],\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_update\",\n\t\t{\n\t\t\ttitle: \"Update Content\",\n\t\t\tdescription:\n\t\t\t\t\"Update an existing content item. Only include fields you want to change \" +\n\t\t\t\t\"in the 'data' object — unspecified fields are left unchanged. Rich text \" +\n\t\t\t\t\"(portableText) fields accept a Markdown string (recommended, converted \" +\n\t\t\t\t\"automatically); use a Portable Text JSON array only for complex content \" +\n\t\t\t\t\"Markdown can't express (custom blocks, embeds). Requires the _rev \" +\n\t\t\t\t\"token from content_get, so read the item before updating it: the \" +\n\t\t\t\t\"update fails if the item changed since that read. When status is not \" +\n\t\t\t\t\"set, a change to a published item is staged as a draft, so the \" +\n\t\t\t\t\"response shows the new values while the live version keeps the old \" +\n\t\t\t\t\"ones until content_publish. \" +\n\t\t\t\t\"`seo` and `bylines` are persisted alongside the field updates in a \" +\n\t\t\t\t\"single transaction. `publishedAt` requires the content:publish_any \" +\n\t\t\t\t\"permission and is useful for migrations or correcting historical dates.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t\tlocale: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Locale to scope slug lookup (e.g. 'fr'). Only affects slug resolution; IDs are globally unique.\",\n\t\t\t\t\t),\n\t\t\t\tdata: z\n\t\t\t\t\t.record(z.string(), z.unknown())\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Field values to update (only include changed fields)\"),\n\t\t\t\tslug: z.string().optional().describe(\"New URL slug\"),\n\t\t\t\tstatus: z\n\t\t\t\t\t.enum([\"draft\", \"published\"])\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"New status. Setting to 'published' requires publish permission. Setting to 'draft' unpublishes the item and also requires publish permission.\",\n\t\t\t\t\t),\n\t\t\t\t// Reuse the REST schema rather than redefining inline. The REST schema's\n\t\t\t\t// `canonical` field is gated through `httpUrl` (validates the URL parses\n\t\t\t\t// AND has an http(s) scheme) which rejects javascript:/data: URIs that\n\t\t\t\t// would otherwise become stored XSS in the rendered <link rel=\"canonical\">.\n\t\t\t\t// Inlining a looser shape here would let MCP callers bypass that.\n\t\t\t\tseo: contentSeoInput\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Per-content SEO metadata. Only valid for collections with SEO enabled (see schema_get_collection.hasSeo). Fields not included are left unchanged; pass null to clear.\",\n\t\t\t\t\t),\n\t\t\t\tbylines: z\n\t\t\t\t\t.array(contentBylineInputSchema)\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Replace the byline list for this item. The first entry becomes the primary byline. Pass an empty array to clear all bylines.\",\n\t\t\t\t\t),\n\t\t\t\ttaxonomies: z\n\t\t\t\t\t.record(z.string(), z.array(z.string()))\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Replace taxonomy term assignments as { taxonomyName: [termSlug, ...] }. Term slugs are resolved in the entry's locale. Only named taxonomies are touched; other taxonomies are left unchanged. Pass an empty array to clear a taxonomy.\",\n\t\t\t\t\t),\n\t\t\t\tpublishedAt: contentDateTimeInputSchema\n\t\t\t\t\t.nullish()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Override the publication timestamp (ISO 8601). Requires content:publish_any permission. Pass null to clear. Useful for content migrations.\",\n\t\t\t\t\t),\n\t\t\t\tmigrateBlocks: z\n\t\t\t\t\t.boolean()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Allow existing blocks to migrate to their type's active version\"),\n\t\t\t\treplaceBlocks: z\n\t\t\t\t\t.boolean()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Treat an entirely keyless blocks array as an explicit replacement\"),\n\t\t\t\t_rev: z.string({ error: REV_MISSING_ERROR }).describe(REV_PARAM_DESCRIPTION),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst { emdash, userId, userRole } = getExtra(extra);\n\t\t\tconst actor = { id: userId, role: userRole };\n\n\t\t\t// Fetch item to check ownership\n\t\t\tconst existing = await emdash.handleContentGet(args.collection, args.id, args.locale);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\tconst ownerId = extractContentAuthorId(existing.data);\n\t\t\trequireOwnership(extra, ownerId, \"content:edit_own\", \"content:edit_any\");\n\n\t\t\tconst data = args.data\n\t\t\t\t? await convertWriteData(emdash, args.collection, args.data)\n\t\t\t\t: args.data;\n\n\t\t\t// Writing publishedAt directly (incl. clearing to null) overwrites\n\t\t\t// historical record — gate behind publish_any, mirroring the REST PUT\n\t\t\t// route. Status-driven publishes are gated separately below.\n\t\t\tif (args.publishedAt !== undefined) {\n\t\t\t\tconst user = { id: userId, role: userRole };\n\t\t\t\tif (!hasPermission(user, \"content:publish_any\")) {\n\t\t\t\t\tthrow new EmDashAuthError(\n\t\t\t\t\t\t\"Setting publishedAt requires content:publish_any permission\",\n\t\t\t\t\t\t\"INSUFFICIENT_PERMISSIONS\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst resolvedId = extractContentId(existing.data) ?? args.id;\n\n\t\t\t// Status transitions route through dedicated handlers for proper revision management\n\t\t\tif (args.status === \"published\") {\n\t\t\t\trequireOwnership(extra, ownerId, \"content:publish_own\", \"content:publish_any\");\n\t\t\t\tlet rev: string | undefined = args._rev;\n\t\t\t\tlet liveChanged = false;\n\t\t\t\tif (\n\t\t\t\t\targs.data ||\n\t\t\t\t\targs.slug ||\n\t\t\t\t\targs.seo !== undefined ||\n\t\t\t\t\targs.bylines !== undefined ||\n\t\t\t\t\targs.taxonomies !== undefined ||\n\t\t\t\t\targs.publishedAt !== undefined\n\t\t\t\t) {\n\t\t\t\t\tconst updateResult = await emdash.handleContentUpdate(args.collection, resolvedId, {\n\t\t\t\t\t\tdata,\n\t\t\t\t\t\tslug: args.slug,\n\t\t\t\t\t\tactor,\n\t\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\t\tseo: args.seo,\n\t\t\t\t\t\tbylines: args.bylines,\n\t\t\t\t\t\ttaxonomies: args.taxonomies,\n\t\t\t\t\t\tpublishedAt: args.publishedAt,\n\t\t\t\t\t\tmigrateBlocks: args.migrateBlocks,\n\t\t\t\t\t\treplaceBlocks: args.replaceBlocks,\n\t\t\t\t\t\t_rev: args._rev,\n\t\t\t\t\t});\n\t\t\t\t\tif (!updateResult.success) return unwrap(updateResult);\n\t\t\t\t\tliveChanged = updateResult.liveContentChanged !== false;\n\t\t\t\t\trev = extractContentRev(updateResult.data);\n\t\t\t\t}\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait emdash.handleContentPublish(args.collection, resolvedId, {\n\t\t\t\t\t\t_rev: rev,\n\t\t\t\t\t\tactor: { ...actor, source: \"mcp\" },\n\t\t\t\t\t\torigin: { source: \"mcp\" },\n\t\t\t\t\t}),\n\t\t\t\t\t[args.collection, resolvedId],\n\t\t\t\t\tliveChanged,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (args.status === \"draft\") {\n\t\t\t\trequireOwnership(extra, ownerId, \"content:publish_own\", \"content:publish_any\");\n\t\t\t\tlet rev: string | undefined = args._rev;\n\t\t\t\tlet liveChanged = false;\n\t\t\t\tif (\n\t\t\t\t\targs.data ||\n\t\t\t\t\targs.slug ||\n\t\t\t\t\targs.seo !== undefined ||\n\t\t\t\t\targs.bylines !== undefined ||\n\t\t\t\t\targs.taxonomies !== undefined ||\n\t\t\t\t\targs.publishedAt !== undefined\n\t\t\t\t) {\n\t\t\t\t\tconst updateResult = await emdash.handleContentUpdate(args.collection, resolvedId, {\n\t\t\t\t\t\tdata,\n\t\t\t\t\t\tslug: args.slug,\n\t\t\t\t\t\tactor,\n\t\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\t\tseo: args.seo,\n\t\t\t\t\t\tbylines: args.bylines,\n\t\t\t\t\t\ttaxonomies: args.taxonomies,\n\t\t\t\t\t\tpublishedAt: args.publishedAt,\n\t\t\t\t\t\tmigrateBlocks: args.migrateBlocks,\n\t\t\t\t\t\treplaceBlocks: args.replaceBlocks,\n\t\t\t\t\t\t_rev: args._rev,\n\t\t\t\t\t});\n\t\t\t\t\tif (!updateResult.success) return unwrap(updateResult);\n\t\t\t\t\tliveChanged = updateResult.liveContentChanged !== false;\n\t\t\t\t\trev = extractContentRev(updateResult.data);\n\t\t\t\t}\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait emdash.handleContentUnpublish(args.collection, resolvedId, {\n\t\t\t\t\t\t_rev: rev,\n\t\t\t\t\t\tactor: { ...actor, source: \"mcp\" },\n\t\t\t\t\t\torigin: { source: \"mcp\" },\n\t\t\t\t\t}),\n\t\t\t\t\t[args.collection, resolvedId],\n\t\t\t\t\tliveChanged,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst result = await emdash.handleContentUpdate(args.collection, resolvedId, {\n\t\t\t\tdata,\n\t\t\t\tslug: args.slug,\n\t\t\t\tactor,\n\t\t\t\tlocale: args.locale,\n\t\t\t\tseo: args.seo,\n\t\t\t\tbylines: args.bylines,\n\t\t\t\ttaxonomies: args.taxonomies,\n\t\t\t\tpublishedAt: args.publishedAt,\n\t\t\t\tmigrateBlocks: args.migrateBlocks,\n\t\t\t\treplaceBlocks: args.replaceBlocks,\n\t\t\t\t_rev: args._rev,\n\t\t\t});\n\t\t\tif (result.liveContentChanged === false) return unwrap(result);\n\t\t\treturn unwrapAndInvalidate(extra, result, [args.collection, resolvedId]);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_delete\",\n\t\t{\n\t\t\ttitle: \"Delete Content (Trash)\",\n\t\t\tdescription:\n\t\t\t\t\"Soft-delete a content item by moving it to the trash. The item can be \" +\n\t\t\t\t\"restored later with content_restore, or permanently deleted with \" +\n\t\t\t\t\"content_permanent_delete.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst ec = getEmDash(extra);\n\n\t\t\t// Fetch item to check ownership\n\t\t\tconst existing = await ec.handleContentGet(args.collection, args.id);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\trequireOwnership(\n\t\t\t\textra,\n\t\t\t\textractContentAuthorId(existing.data),\n\t\t\t\t\"content:delete_own\",\n\t\t\t\t\"content:delete_any\",\n\t\t\t);\n\n\t\t\tconst resolvedId = extractContentId(existing.data) ?? args.id;\n\t\t\treturn unwrapAndInvalidate(extra, await ec.handleContentDelete(args.collection, resolvedId), [\n\t\t\t\targs.collection,\n\t\t\t\tresolvedId,\n\t\t\t]);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_restore\",\n\t\t{\n\t\t\ttitle: \"Restore Content\",\n\t\t\tdescription:\n\t\t\t\t\"Restore a soft-deleted content item from the trash. It comes back as a draft \" +\n\t\t\t\t\"with no schedule, even if it was published or scheduled before it was trashed.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst ec = getEmDash(extra);\n\n\t\t\t// Fetch trashed item to check ownership\n\t\t\tconst existing = await ec.handleContentGetIncludingTrashed(args.collection, args.id);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\trequireOwnership(\n\t\t\t\textra,\n\t\t\t\textractContentAuthorId(existing.data),\n\t\t\t\t\"content:edit_own\",\n\t\t\t\t\"content:edit_any\",\n\t\t\t);\n\n\t\t\tconst resolvedId = extractContentId(existing.data) ?? args.id;\n\t\t\treturn unwrapAndInvalidate(\n\t\t\t\textra,\n\t\t\t\tawait ec.handleContentRestore(args.collection, resolvedId),\n\t\t\t\t[args.collection, resolvedId],\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_permanent_delete\",\n\t\t{\n\t\t\ttitle: \"Permanently Delete Content\",\n\t\t\tdescription:\n\t\t\t\t\"Permanently and irreversibly delete a trashed content item. The item \" +\n\t\t\t\t\"must be in the trash first (use content_delete). This cannot be undone.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\treturn unwrapAndInvalidate(\n\t\t\t\textra,\n\t\t\t\tawait ec.handleContentPermanentDelete(args.collection, args.id),\n\t\t\t\t[args.collection, args.id],\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_publish\",\n\t\t{\n\t\t\ttitle: \"Publish Content\",\n\t\t\tdescription:\n\t\t\t\t\"Publish a content item, making it live on the site. Creates a published \" +\n\t\t\t\t\"revision from the current draft. Further edits create a new draft without \" +\n\t\t\t\t\"affecting the live version until re-published. Pass `publishedAt` to \" +\n\t\t\t\t\"backdate (e.g. when migrating content from another CMS) — this requires \" +\n\t\t\t\t\"the content:publish_any permission. Without `publishedAt`, the existing \" +\n\t\t\t\t\"`published_at` is preserved on re-publish (idempotent) and falls back to \" +\n\t\t\t\t\"the current time on first publish.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t\t_rev: z.string({ error: REV_MISSING_ERROR }).describe(REV_PARAM_DESCRIPTION),\n\t\t\t\tpublishedAt: contentDateTimeInputSchema\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Override publication timestamp (ISO 8601). Requires content:publish_any permission. Useful when importing content with original publish dates.\",\n\t\t\t\t\t),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst { emdash, userId, userRole } = getExtra(extra);\n\n\t\t\t// Fetch item to check ownership\n\t\t\tconst existing = await emdash.handleContentGet(args.collection, args.id);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\tconst ownerId = extractContentAuthorId(existing.data);\n\t\t\trequireOwnership(extra, ownerId, \"content:publish_own\", \"content:publish_any\");\n\n\t\t\t// Backdating overwrites historical record — gate behind publish_any\n\t\t\t// regardless of ownership (mirrors the REST PUT route's publishedAt gate).\n\t\t\tif (args.publishedAt !== undefined) {\n\t\t\t\tconst user = { id: userId, role: userRole };\n\t\t\t\tif (!hasPermission(user, \"content:publish_any\")) {\n\t\t\t\t\tthrow new EmDashAuthError(\n\t\t\t\t\t\t\"Setting publishedAt requires content:publish_any permission\",\n\t\t\t\t\t\t\"INSUFFICIENT_PERMISSIONS\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst resolvedId = extractContentId(existing.data) ?? args.id;\n\t\t\treturn unwrapAndInvalidate(\n\t\t\t\textra,\n\t\t\t\tawait emdash.handleContentPublish(args.collection, resolvedId, {\n\t\t\t\t\tpublishedAt: args.publishedAt,\n\t\t\t\t\t_rev: args._rev,\n\t\t\t\t\tactor: { id: userId, role: userRole, source: \"mcp\" },\n\t\t\t\t\torigin: { source: \"mcp\" },\n\t\t\t\t}),\n\t\t\t\t[args.collection, resolvedId],\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_unpublish\",\n\t\t{\n\t\t\ttitle: \"Unpublish Content\",\n\t\t\tdescription:\n\t\t\t\t\"Unpublish a content item, reverting it to draft status. It will no \" +\n\t\t\t\t\"longer be visible on the live site, but its content and publication date are preserved. \" +\n\t\t\t\t\"Any pending schedule is cancelled.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t\t_rev: z.string({ error: REV_MISSING_ERROR }).describe(REV_PARAM_DESCRIPTION),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst { emdash: ec, userId, userRole } = getExtra(extra);\n\n\t\t\t// Fetch item to check ownership\n\t\t\tconst existing = await ec.handleContentGet(args.collection, args.id);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\trequireOwnership(\n\t\t\t\textra,\n\t\t\t\textractContentAuthorId(existing.data),\n\t\t\t\t\"content:publish_own\",\n\t\t\t\t\"content:publish_any\",\n\t\t\t);\n\n\t\t\tconst resolvedId = extractContentId(existing.data) ?? args.id;\n\t\t\treturn unwrapAndInvalidate(\n\t\t\t\textra,\n\t\t\t\tawait ec.handleContentUnpublish(args.collection, resolvedId, {\n\t\t\t\t\t_rev: args._rev,\n\t\t\t\t\tactor: { id: userId, role: userRole, source: \"mcp\" },\n\t\t\t\t\torigin: { source: \"mcp\" },\n\t\t\t\t}),\n\t\t\t\t[args.collection, resolvedId],\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_schedule\",\n\t\t{\n\t\t\ttitle: \"Schedule Content\",\n\t\t\tdescription:\n\t\t\t\t\"Schedule a content item for future publication. It will be automatically \" +\n\t\t\t\t\"published at the specified date/time. The scheduledAt value must be an \" +\n\t\t\t\t\"ISO 8601 datetime string in the future (e.g. '2025-06-01T09:00:00Z').\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t\t_rev: z.string({ error: REV_MISSING_ERROR }).describe(REV_PARAM_DESCRIPTION),\n\t\t\t\tscheduledAt: contentDateTimeInputSchema.describe(\n\t\t\t\t\t\"ISO 8601 datetime for publication (e.g. '2025-06-01T09:00:00Z')\",\n\t\t\t\t),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst { emdash: ec, userId, userRole } = getExtra(extra);\n\n\t\t\t// Fetch item to check ownership\n\t\t\tconst existing = await ec.handleContentGet(args.collection, args.id);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\trequireOwnership(\n\t\t\t\textra,\n\t\t\t\textractContentAuthorId(existing.data),\n\t\t\t\t\"content:publish_own\",\n\t\t\t\t\"content:publish_any\",\n\t\t\t);\n\n\t\t\tconst resolvedId = extractContentId(existing.data) ?? args.id;\n\t\t\treturn unwrapAndInvalidate(\n\t\t\t\textra,\n\t\t\t\tawait ec.handleContentSchedule(args.collection, resolvedId, args.scheduledAt, {\n\t\t\t\t\t_rev: args._rev,\n\t\t\t\t\tactor: { id: userId, role: userRole, source: \"mcp\" },\n\t\t\t\t\torigin: { source: \"mcp\" },\n\t\t\t\t}),\n\t\t\t\t[args.collection, resolvedId],\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_unschedule\",\n\t\t{\n\t\t\ttitle: \"Cancel Scheduled Publication\",\n\t\t\tdescription:\n\t\t\t\t\"Cancel a previously scheduled publication. Scheduled drafts return to draft status; \" +\n\t\t\t\t\"published items stay published. The scheduledAt timestamp is cleared. Idempotent — \" +\n\t\t\t\t\"calling on an item that isn't scheduled is a no-op.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst ec = getEmDash(extra);\n\n\t\t\tconst existing = await ec.handleContentGet(args.collection, args.id);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\trequireOwnership(\n\t\t\t\textra,\n\t\t\t\textractContentAuthorId(existing.data),\n\t\t\t\t\"content:publish_own\",\n\t\t\t\t\"content:publish_any\",\n\t\t\t);\n\n\t\t\tconst resolvedId = extractContentId(existing.data) ?? args.id;\n\t\t\treturn unwrapAndInvalidate(\n\t\t\t\textra,\n\t\t\t\tawait ec.handleContentUnschedule(args.collection, resolvedId),\n\t\t\t\t[args.collection, resolvedId],\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_compare\",\n\t\t{\n\t\t\ttitle: \"Compare Live vs Draft\",\n\t\t\tdescription:\n\t\t\t\t\"Compare the published (live) version of a content item with its current \" +\n\t\t\t\t\"draft. Returns both versions and a flag indicating whether there are \" +\n\t\t\t\t\"changes. Useful for reviewing unpublished edits before publishing.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\trequireDraftAccess(extra);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\treturn unwrap(await ec.handleContentCompare(args.collection, args.id));\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_discard_draft\",\n\t\t{\n\t\t\ttitle: \"Discard Draft\",\n\t\t\tdescription:\n\t\t\t\t\"Discard the current draft revision. Published content reverts to its live \" +\n\t\t\t\t\"version; an item without a pending draft is unchanged.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t\t_rev: z.string({ error: REV_MISSING_ERROR }).describe(REV_PARAM_DESCRIPTION),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst ec = getEmDash(extra);\n\n\t\t\t// Fetch item to check ownership\n\t\t\tconst existing = await ec.handleContentGet(args.collection, args.id);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\trequireOwnership(\n\t\t\t\textra,\n\t\t\t\textractContentAuthorId(existing.data),\n\t\t\t\t\"content:edit_own\",\n\t\t\t\t\"content:edit_any\",\n\t\t\t);\n\n\t\t\tconst resolvedId = extractContentId(existing.data) ?? args.id;\n\t\t\treturn unwrapAndInvalidate(\n\t\t\t\textra,\n\t\t\t\tawait ec.handleContentDiscardDraft(args.collection, resolvedId, { _rev: args._rev }),\n\t\t\t\t[args.collection, resolvedId],\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_list_trashed\",\n\t\t{\n\t\t\ttitle: \"List Trashed Content\",\n\t\t\tdescription:\n\t\t\t\t\"List soft-deleted content items in a collection's trash. These items \" +\n\t\t\t\t\"can be restored with content_restore or permanently deleted with \" +\n\t\t\t\t\"content_permanent_delete.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tlimit: z.number().int().min(1).max(100).optional().describe(\"Max items (default 50)\"),\n\t\t\t\tcursor: z.string().min(1).max(2048).optional().describe(\"Pagination cursor\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\trequireDraftAccess(extra);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\treturn unwrap(\n\t\t\t\tawait ec.handleContentListTrashed(args.collection, {\n\t\t\t\t\tlimit: args.limit,\n\t\t\t\t\tcursor: args.cursor,\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_duplicate\",\n\t\t{\n\t\t\ttitle: \"Duplicate Content\",\n\t\t\tdescription:\n\t\t\t\t\"Create a copy of an existing content item. The duplicate is created \" +\n\t\t\t\t\"as a draft with '(Copy)' appended to the title and an auto-generated slug.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug to duplicate\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.CONTRIBUTOR);\n\t\t\tconst { emdash, userId } = getExtra(extra);\n\t\t\tconst existing = await emdash.handleContentGet(args.collection, args.id);\n\t\t\tif (!existing.success) return unwrap(existing);\n\t\t\trequireOwnership(\n\t\t\t\textra,\n\t\t\t\textractContentAuthorId(existing.data),\n\t\t\t\t\"content:edit_own\",\n\t\t\t\t\"content:edit_any\",\n\t\t\t);\n\t\t\tconst resolvedId = extractContentId(existing.data) ?? args.id;\n\t\t\treturn unwrapAndInvalidate(\n\t\t\t\textra,\n\t\t\t\tawait emdash.handleContentDuplicate(args.collection, resolvedId, userId),\n\t\t\t\t[args.collection],\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"content_translations\",\n\t\t{\n\t\t\ttitle: \"Get Content Translations\",\n\t\t\tdescription:\n\t\t\t\t\"Get all locale variants of a content item. Returns the translation group \" +\n\t\t\t\t\"and a summary of each locale version (id, locale, slug, status). Only \" +\n\t\t\t\t\"relevant when i18n is enabled on the site.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\tconst result = await ec.handleContentTranslations(args.collection, args.id);\n\t\t\t// Filter out non-published translations for users without draft\n\t\t\t// access so a subscriber can't enumerate locales that aren't yet live.\n\t\t\tif (result.success && !canReadDrafts(extra)) {\n\t\t\t\tconst data =\n\t\t\t\t\tresult.data && typeof result.data === \"object\"\n\t\t\t\t\t\t? // eslint-disable-next-line typescript/no-unsafe-type-assertion -- handler returns unknown data; narrowed by typeof check\n\t\t\t\t\t\t\t(result.data as Record<string, unknown>)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tconst translations = Array.isArray(data?.translations) ? data.translations : [];\n\t\t\t\tconst filtered = translations.filter(isPublished);\n\t\t\t\treturn unwrap({\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tdata: { ...data, translations: filtered },\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn unwrap(result);\n\t\t},\n\t);\n\n\t// =====================================================================\n\t// Byline tools\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"byline_list\",\n\t\t{\n\t\t\ttitle: \"List Bylines\",\n\t\t\tdescription:\n\t\t\t\t\"List bylines (author/contributor credits) with optional filtering and \" +\n\t\t\t\t\"pagination. Bylines are standalone records referenced by content items; \" +\n\t\t\t\t\"use the returned id with content_create/content_update or byline_get. Use \" +\n\t\t\t\t\"the nextCursor value from the response to fetch the next page.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tsearch: z.string().optional().describe(\"Filter by display name or slug substring\"),\n\t\t\t\tisGuest: z.boolean().optional().describe(\"Filter by guest (true) or linked-user (false)\"),\n\t\t\t\tuserId: z.string().optional().describe(\"Filter to the byline linked to a CMS user ID\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Filter by locale (omit for all)\"),\n\t\t\t\tlimit: z.number().int().min(1).max(100).optional().describe(\"Max items (default 50)\"),\n\t\t\t\tcursor: z.string().min(1).max(2048).optional().describe(\"Pagination cursor\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { BylineRepository } = await import(\"../database/repositories/byline.js\");\n\t\t\t\tconst repo = new BylineRepository(ec.db);\n\t\t\t\treturn jsonResult(\n\t\t\t\t\tawait repo.findMany({\n\t\t\t\t\t\tsearch: args.search,\n\t\t\t\t\t\tisGuest: args.isGuest,\n\t\t\t\t\t\tuserId: args.userId,\n\t\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\t\tlimit: args.limit,\n\t\t\t\t\t\tcursor: args.cursor,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"BYLINE_LIST_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"byline_get\",\n\t\t{\n\t\t\ttitle: \"Get Byline\",\n\t\t\tdescription:\n\t\t\t\t\"Get a single byline by its ID, including bio, avatar, website, linked \" +\n\t\t\t\t\"user, and any custom fields.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tid: z.string().describe(\"Byline ID\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { BylineRepository } = await import(\"../database/repositories/byline.js\");\n\t\t\t\tconst byline = await new BylineRepository(ec.db).findById(args.id);\n\t\t\t\tif (!byline) return respondError(\"NOT_FOUND\", `Byline '${args.id}' not found`);\n\t\t\t\treturn jsonResult(byline);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"BYLINE_GET_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"byline_create\",\n\t\t{\n\t\t\ttitle: \"Create Byline\",\n\t\t\tdescription:\n\t\t\t\t\"Create a new byline (author/contributor credit). The slug must be unique \" +\n\t\t\t\t\"and contain only lowercase letters, digits, and hyphens. Link the byline \" +\n\t\t\t\t\"to a CMS user via userId, or leave it as a standalone guest credit. The \" +\n\t\t\t\t\"returned id can then be passed to content_create/content_update bylines.\",\n\t\t\tinputSchema: z.object({ ...bylineCreateBody.shape }),\n\t\t\tannotations: { destructiveHint: false },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleBylineCreate } = await import(\"../api/handlers/bylines.js\");\n\t\t\t\tconst result = await handleBylineCreate(ec.db, args);\n\t\t\t\tif (result.success) await invalidateBylines();\n\t\t\t\treturn unwrap(result);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"BYLINE_CREATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"byline_update\",\n\t\t{\n\t\t\ttitle: \"Update Byline\",\n\t\t\tdescription:\n\t\t\t\t\"Update an existing byline. Any field can be omitted to leave it \" +\n\t\t\t\t\"unchanged. Renaming the slug must not collide with another byline.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tid: z.string().describe(\"Byline ID to update\"),\n\t\t\t\t...bylineUpdateBody.shape,\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleBylineUpdate } = await import(\"../api/handlers/bylines.js\");\n\t\t\t\tconst { id, ...input } = args;\n\t\t\t\tconst result = await handleBylineUpdate(ec.db, id, input);\n\t\t\t\tif (result.success) await invalidateBylines();\n\t\t\t\treturn unwrap(result);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"BYLINE_UPDATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"byline_delete\",\n\t\t{\n\t\t\ttitle: \"Delete Byline\",\n\t\t\tdescription:\n\t\t\t\t\"Permanently delete a byline. Any content crediting this byline loses the \" +\n\t\t\t\t\"association, and it is cleared as a primary byline where set.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tid: z.string().describe(\"Byline ID to delete\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { BylineRepository } = await import(\"../database/repositories/byline.js\");\n\t\t\t\tconst deleted = await new BylineRepository(ec.db).delete(args.id);\n\t\t\t\tif (!deleted) return respondError(\"NOT_FOUND\", `Byline '${args.id}' not found`);\n\t\t\t\tawait invalidateBylines();\n\t\t\t\treturn jsonResult({ deleted: args.id });\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"BYLINE_DELETE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"byline_translations\",\n\t\t{\n\t\t\ttitle: \"List Byline Translations\",\n\t\t\tdescription:\n\t\t\t\t\"Return every locale variant of a byline, identified via its shared translation_group.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tid: z.string().describe(\"Byline id (or translation_group)\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleBylineTranslations } = await import(\"../api/handlers/bylines.js\");\n\t\t\t\treturn unwrap(await handleBylineTranslations(ec.db, args.id));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"BYLINE_TRANSLATIONS_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\t// =====================================================================\n\t// Schema tools\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"schema_list_collections\",\n\t\t{\n\t\t\ttitle: \"List Collections\",\n\t\t\tdescription:\n\t\t\t\t\"List all content collections defined in the CMS. Each collection \" +\n\t\t\t\t\"represents a content type (e.g. posts, pages, products) with its own \" +\n\t\t\t\t\"schema and database table. Returns slug, label, supported features, \" +\n\t\t\t\t\"and timestamps.\",\n\t\t\tinputSchema: z.object({}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (_args, extra) => {\n\t\t\trequireScope(extra, \"schema:read\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { SchemaRegistry } = await import(\"../schema/index.js\");\n\t\t\t\tconst registry = new SchemaRegistry(ec.db);\n\t\t\t\tconst items = await registry.listCollections();\n\t\t\t\treturn jsonResult({ items });\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"SCHEMA_LIST_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_get_collection\",\n\t\t{\n\t\t\ttitle: \"Get Collection Schema\",\n\t\t\tdescription:\n\t\t\t\t\"Get detailed info about a collection including all field definitions. \" +\n\t\t\t\t\"Fields describe the data model: name, type (string, text, number, \" +\n\t\t\t\t\"boolean, datetime, portableText, image, reference, json, select, \" +\n\t\t\t\t\"multiSelect, slug, blocks), constraints, and validation rules. Blocks fields \" +\n\t\t\t\t\"include every allowed and retired block type version. Use this to \" +\n\t\t\t\t\"understand what data content_create and content_update expect.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tslug: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Collection slug (e.g. 'posts'). Use schema_list_collections to see available slugs.\",\n\t\t\t\t\t),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"schema:read\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { SchemaRegistry, expandCollectionBlockFields } = await import(\"../schema/index.js\");\n\t\t\t\tconst registry = new SchemaRegistry(ec.db);\n\t\t\t\tconst collection = await registry.getCollectionWithFields(args.slug);\n\t\t\t\tif (!collection) {\n\t\t\t\t\treturn respondError(\"NOT_FOUND\", `Collection '${args.slug}' not found`);\n\t\t\t\t}\n\t\t\t\treturn jsonResult(await expandCollectionBlockFields(ec.db, collection));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"SCHEMA_GET_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_list_block_types\",\n\t\t{\n\t\t\ttitle: \"List Block Types\",\n\t\t\tdescription: \"List every database-owned block type and all retained versions.\",\n\t\t\tinputSchema: z.object({}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (_args, extra) => {\n\t\t\trequireScope(extra, \"schema:read\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\tconst { handleBlockTypeList } = await import(\"../api/handlers/block-types.js\");\n\t\t\treturn unwrap(await handleBlockTypeList(ec.db));\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_get_block_type\",\n\t\t{\n\t\t\ttitle: \"Get Block Type\",\n\t\t\tdescription: \"Get one block type, including active, inactive, and historical versions.\",\n\t\t\tinputSchema: z.object({ slug: z.string().describe(\"Block type slug\") }),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"schema:read\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\tconst { handleBlockTypeGet } = await import(\"../api/handlers/block-types.js\");\n\t\t\treturn unwrap(await handleBlockTypeGet(ec.db, args.slug));\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_create_block_type\",\n\t\t{\n\t\t\ttitle: \"Create Block Type\",\n\t\t\tdescription: \"Create a block type with active version 1.\",\n\t\t\tinputSchema: z.object(createBlockTypeBody.shape),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"schema:write\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\tconst { handleBlockTypeCreate } = await import(\"../api/handlers/block-types.js\");\n\t\t\treturn unwrap(await handleBlockTypeCreate(ec.db, args));\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_update_block_type\",\n\t\t{\n\t\t\ttitle: \"Update Block Type\",\n\t\t\tdescription:\n\t\t\t\t\"Update presentation or compatible fields in place. Set breaking to create an inactive retained version.\",\n\t\t\tinputSchema: z.object({ slug: z.string(), ...updateBlockTypeBody.shape }),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"schema:write\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\tconst { slug, ...input } = args;\n\t\t\tconst { handleBlockTypeUpdate } = await import(\"../api/handlers/block-types.js\");\n\t\t\treturn unwrap(await handleBlockTypeUpdate(ec.db, slug, input));\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_activate_block_type_version\",\n\t\t{\n\t\t\ttitle: \"Activate Block Type Version\",\n\t\t\tdescription: \"Make a retained version the active version used by newly created blocks.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tslug: z.string(),\n\t\t\t\tversion: z.number().int().positive(),\n\t\t\t\texpectedFingerprint: z.string().min(1),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"schema:write\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\tconst { handleBlockTypeVersionActivate } = await import(\"../api/handlers/block-types.js\");\n\t\t\treturn unwrap(\n\t\t\t\tawait handleBlockTypeVersionActivate(\n\t\t\t\t\tec.db,\n\t\t\t\t\targs.slug,\n\t\t\t\t\targs.version,\n\t\t\t\t\targs.expectedFingerprint,\n\t\t\t\t),\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_create_collection\",\n\t\t{\n\t\t\ttitle: \"Create Collection\",\n\t\t\tdescription:\n\t\t\t\t\"Create a new content collection (content type). This creates a database \" +\n\t\t\t\t\"table and schema definition. The slug must be lowercase alphanumeric \" +\n\t\t\t\t\"with underscores, starting with a letter. Supports: 'drafts' (draft/\" +\n\t\t\t\t\"publish workflow), 'revisions' (version history), 'preview' (live \" +\n\t\t\t\t\"preview), 'scheduling' (timed publish), 'search' (full-text indexing), \" +\n\t\t\t\t\"and 'seo' (SEO metadata).\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tslug: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.regex(COLLECTION_SLUG_PATTERN)\n\t\t\t\t\t.describe(\"Unique identifier (lowercase letters, numbers, underscores)\"),\n\t\t\t\tlabel: z.string().describe(\"Display name (plural, e.g. 'Blog Posts')\"),\n\t\t\t\tlabelSingular: z.string().optional().describe(\"Singular display name (e.g. 'Blog Post')\"),\n\t\t\t\tdescription: z.string().optional().describe(\"Description of this collection\"),\n\t\t\t\ticon: z.string().optional().describe(\"Icon name for the admin UI\"),\n\t\t\t\tsupports: createCollectionBody.shape.supports.describe(\n\t\t\t\t\t\"Features to enable (default: ['drafts', 'revisions'])\",\n\t\t\t\t),\n\t\t\t\troutable: createCollectionBody.shape.routable.describe(\n\t\t\t\t\t\"Require a slug before publishing (default: true)\",\n\t\t\t\t),\n\t\t\t\teditLocking: createCollectionBody.shape.editLocking.describe(\n\t\t\t\t\t\"Take an edit lock when an entry is opened (default: true)\",\n\t\t\t\t),\n\t\t\t\tgroup: createCollectionBody.shape.group.describe(\n\t\t\t\t\t\"Admin sidebar folder shared with other collections of the same group\",\n\t\t\t\t),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"schema:write\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { SchemaRegistry } = await import(\"../schema/index.js\");\n\t\t\t\tconst registry = new SchemaRegistry(ec.db);\n\t\t\t\tconst collection = await registry.createCollection({\n\t\t\t\t\tslug: args.slug,\n\t\t\t\t\tlabel: args.label,\n\t\t\t\t\tlabelSingular: args.labelSingular,\n\t\t\t\t\tdescription: args.description,\n\t\t\t\t\ticon: args.icon,\n\t\t\t\t\t// SchemaRegistry.createCollection now defaults `supports` to\n\t\t\t\t\t// ['drafts', 'revisions'] when undefined; pass through verbatim.\n\t\t\t\t\tsupports: args.supports,\n\t\t\t\t\troutable: args.routable,\n\t\t\t\t\teditLocking: args.editLocking,\n\t\t\t\t\tgroup: args.group,\n\t\t\t\t});\n\t\t\t\tec.invalidateUrlPatternCache();\n\t\t\t\treturn jsonResult(collection);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"SCHEMA_CREATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_delete_collection\",\n\t\t{\n\t\t\ttitle: \"Delete Collection\",\n\t\t\tdescription:\n\t\t\t\t\"Delete a collection and its database table. This is irreversible and \" +\n\t\t\t\t\"deletes all content in the collection. Use with extreme caution.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tslug: z.string().describe(\"Collection slug to delete\"),\n\t\t\t\tforce: z\n\t\t\t\t\t.boolean()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Force deletion even if the collection has content (default false)\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"schema:write\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { SchemaRegistry } = await import(\"../schema/index.js\");\n\t\t\t\tconst registry = new SchemaRegistry(ec.db);\n\t\t\t\tawait registry.deleteCollection(args.slug, { force: args.force });\n\t\t\t\tec.invalidateUrlPatternCache();\n\t\t\t\treturn jsonResult({ deleted: args.slug });\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"SCHEMA_DELETE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_update_collection\",\n\t\t{\n\t\t\ttitle: \"Update Collection\",\n\t\t\tdescription:\n\t\t\t\t\"Update an existing collection without deleting its table, fields, or content. \" +\n\t\t\t\t\"Only provided settings change; omitted settings keep their current values. \" +\n\t\t\t\t\"The collection slug cannot be changed.\",\n\t\t\tinputSchema: schemaUpdateCollectionToolSchema,\n\t\t\tannotations: { destructiveHint: false },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"schema:write\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\tconst { slug, ...input } = args;\n\t\t\ttry {\n\t\t\t\tconst { handleSchemaCollectionUpdate } = await import(\"../api/handlers/schema.js\");\n\t\t\t\tconst result = await handleSchemaCollectionUpdate(ec.db, slug, input);\n\t\t\t\tif (result.success) ec.invalidateUrlPatternCache();\n\t\t\t\treturn unwrap(result);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"SCHEMA_UPDATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_create_field\",\n\t\t{\n\t\t\ttitle: \"Add Field to Collection\",\n\t\t\tdescription:\n\t\t\t\t\"Add a new field to a collection's schema. This adds a column to the \" +\n\t\t\t\t\"database table. Field types: string (short text), text (long text), \" +\n\t\t\t\t\"number (decimal), integer, boolean, datetime, select (single choice), \" +\n\t\t\t\t\"multiSelect (multiple), portableText (rich text), image, file, \" +\n\t\t\t\t\"reference (link to another collection), json, slug (URL-safe id), or blocks. \" +\n\t\t\t\t\"For select/multiSelect, provide choices in validation.options array.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug to add the field to\"),\n\t\t\t\tslug: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.regex(COLLECTION_SLUG_PATTERN)\n\t\t\t\t\t.describe(\"Field identifier (lowercase letters, numbers, underscores)\"),\n\t\t\t\tlabel: z.string().describe(\"Display name for the field\"),\n\t\t\t\ttype: z\n\t\t\t\t\t.enum([\n\t\t\t\t\t\t\"string\",\n\t\t\t\t\t\t\"text\",\n\t\t\t\t\t\t\"number\",\n\t\t\t\t\t\t\"integer\",\n\t\t\t\t\t\t\"boolean\",\n\t\t\t\t\t\t\"datetime\",\n\t\t\t\t\t\t\"select\",\n\t\t\t\t\t\t\"multiSelect\",\n\t\t\t\t\t\t\"portableText\",\n\t\t\t\t\t\t\"image\",\n\t\t\t\t\t\t\"file\",\n\t\t\t\t\t\t\"reference\",\n\t\t\t\t\t\t\"json\",\n\t\t\t\t\t\t\"slug\",\n\t\t\t\t\t\t\"blocks\",\n\t\t\t\t\t])\n\t\t\t\t\t.describe(\"Data type for this field\"),\n\t\t\t\trequired: z.boolean().optional().describe(\"Whether the field is required (default false)\"),\n\t\t\t\tunique: z.boolean().optional().describe(\"Whether values must be unique (default false)\"),\n\t\t\t\tdefaultValue: z.unknown().optional().describe(\"Default value for new items\"),\n\t\t\t\tvalidation: z\n\t\t\t\t\t.object({\n\t\t\t\t\t\tmin: z.number().optional(),\n\t\t\t\t\t\tmax: z.number().optional(),\n\t\t\t\t\t\tminLength: z.number().optional(),\n\t\t\t\t\t\tmaxLength: z.number().optional(),\n\t\t\t\t\t\tpattern: z.string().optional(),\n\t\t\t\t\t\toptions: z\n\t\t\t\t\t\t\t.array(z.string())\n\t\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t\t.describe(\"Allowed values for select/multiSelect\"),\n\t\t\t\t\t\tallowedTypes: z\n\t\t\t\t\t\t\t.array(z.string())\n\t\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t\t.describe(\"Ordered block type slugs allowed by a blocks field\"),\n\t\t\t\t\t\tminItems: z.number().int().min(0).optional(),\n\t\t\t\t\t\tmaxItems: z.number().int().min(1).optional(),\n\t\t\t\t\t})\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Validation constraints\"),\n\t\t\t\toptions: z\n\t\t\t\t\t.object({\n\t\t\t\t\t\tcollection: z\n\t\t\t\t\t\t\t.string()\n\t\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t\t.describe(\"Target collection slug for reference fields\"),\n\t\t\t\t\t\trows: z.number().optional().describe(\"Number of rows for textarea\"),\n\t\t\t\t\t})\n\t\t\t\t\t.loose()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Widget configuration\"),\n\t\t\t\tsearchable: z\n\t\t\t\t\t.boolean()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Include in full-text search index (default false)\"),\n\t\t\t\tindexed: z.boolean().optional().describe(\"Create a physical index for structured sorting\"),\n\t\t\t\ttranslatable: z\n\t\t\t\t\t.boolean()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Whether this field is translatable (default true). \" +\n\t\t\t\t\t\t\t\"Non-translatable fields are synced across all locales in a translation group.\",\n\t\t\t\t\t),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"schema:write\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { SchemaRegistry } = await import(\"../schema/index.js\");\n\t\t\t\tconst registry = new SchemaRegistry(ec.db);\n\t\t\t\tconst field = await registry.createField(args.collection, {\n\t\t\t\t\tslug: args.slug,\n\t\t\t\t\tlabel: args.label,\n\t\t\t\t\ttype: args.type,\n\t\t\t\t\trequired: args.required,\n\t\t\t\t\tunique: args.unique,\n\t\t\t\t\tdefaultValue: args.defaultValue,\n\t\t\t\t\tvalidation: args.validation,\n\t\t\t\t\toptions: args.options,\n\t\t\t\t\tsearchable: args.searchable,\n\t\t\t\t\tindexed: args.indexed,\n\t\t\t\t\ttranslatable: args.translatable,\n\t\t\t\t});\n\t\t\t\treturn jsonResult(field);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"FIELD_CREATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_delete_field\",\n\t\t{\n\t\t\ttitle: \"Remove Field from Collection\",\n\t\t\tdescription:\n\t\t\t\t\"Remove a field from a collection. This drops the column from the \" +\n\t\t\t\t\"database table and deletes all data in that field. Irreversible.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tfieldSlug: z.string().describe(\"Field slug to remove\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"schema:write\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { SchemaRegistry } = await import(\"../schema/index.js\");\n\t\t\t\tconst registry = new SchemaRegistry(ec.db);\n\t\t\t\tawait registry.deleteField(args.collection, args.fieldSlug);\n\t\t\t\treturn jsonResult({ deleted: args.fieldSlug, collection: args.collection });\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"FIELD_DELETE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"schema_update_field\",\n\t\t{\n\t\t\ttitle: \"Update Field\",\n\t\t\tdescription:\n\t\t\t\t\"Update an existing field without deleting its column or stored values. Only \" +\n\t\t\t\t\"provided settings change; omitted settings keep their current values. Changes \" +\n\t\t\t\t\"that require a content or column migration are rejected with migration guidance.\",\n\t\t\tinputSchema: schemaUpdateFieldToolSchema,\n\t\t\tannotations: { destructiveHint: false },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"schema:write\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\tconst { collection, fieldSlug, ...input } = args;\n\t\t\ttry {\n\t\t\t\tconst { handleSchemaFieldUpdate } = await import(\"../api/handlers/schema.js\");\n\t\t\t\treturn unwrap(await handleSchemaFieldUpdate(ec.db, collection, fieldSlug, input));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"SCHEMA_FIELD_UPDATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\t// =====================================================================\n\t// Media tools\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"media_list\",\n\t\t{\n\t\t\ttitle: \"List Media\",\n\t\t\tdescription:\n\t\t\t\t\"List uploaded media files (images, documents, etc.) with optional MIME \" +\n\t\t\t\t\"type filtering and pagination. Returns file metadata including filename, \" +\n\t\t\t\t\"URL, dimensions, and alt text.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tmimeType: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Filter by MIME type prefix (e.g. 'image/', 'application/pdf')\"),\n\t\t\t\tlimit: z.number().int().min(1).max(100).optional().describe(\"Max items (default 50)\"),\n\t\t\t\tcursor: z.string().min(1).max(2048).optional().describe(\"Pagination cursor\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"media:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\treturn unwrap(\n\t\t\t\tawait ec.handleMediaList({\n\t\t\t\t\tmimeType: args.mimeType,\n\t\t\t\t\tlimit: args.limit,\n\t\t\t\t\tcursor: args.cursor,\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"media_create\",\n\t\t{\n\t\t\ttitle: \"Register Uploaded Media\",\n\t\t\tdescription:\n\t\t\t\t\"Register a media file that has already been uploaded to storage. The \" +\n\t\t\t\t\"caller is responsible for placing the file at `storageKey` (typically \" +\n\t\t\t\t\"using a signed upload URL obtained from the admin UI or a separate API). \" +\n\t\t\t\t\"This tool persists the metadata record so the file is discoverable via \" +\n\t\t\t\t\"media_list / media_get and can be referenced by content. To upload the \" +\n\t\t\t\t\"file itself, use media_upload (base64 data or a public URL) instead.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tfilename: z.string().describe(\"Original filename (e.g. 'logo.png')\"),\n\t\t\t\tmimeType: z.string().describe(\"MIME type (e.g. 'image/png')\"),\n\t\t\t\tstorageKey: z.string().describe(\"Storage path/key the file was uploaded to\"),\n\t\t\t\tsize: z.number().int().nonnegative().optional().describe(\"File size in bytes\"),\n\t\t\t\twidth: z.number().int().positive().optional().describe(\"Image width in pixels\"),\n\t\t\t\theight: z.number().int().positive().optional().describe(\"Image height in pixels\"),\n\t\t\t\tcontentHash: z.string().optional().describe(\"Hash of the file contents (for dedupe)\"),\n\t\t\t\tblurhash: z.string().optional().describe(\"Blurhash for image placeholders\"),\n\t\t\t\tdominantColor: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Hex color string for the image's dominant color\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"media:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst { emdash, userId } = getExtra(extra);\n\t\t\treturn unwrap(\n\t\t\t\tawait emdash.handleMediaCreate({\n\t\t\t\t\tfilename: args.filename,\n\t\t\t\t\tmimeType: args.mimeType,\n\t\t\t\t\tstorageKey: args.storageKey,\n\t\t\t\t\tsize: args.size,\n\t\t\t\t\twidth: args.width,\n\t\t\t\t\theight: args.height,\n\t\t\t\t\tcontentHash: args.contentHash,\n\t\t\t\t\tblurhash: args.blurhash,\n\t\t\t\t\tdominantColor: args.dominantColor,\n\t\t\t\t\tauthorId: userId,\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"media_upload\",\n\t\t{\n\t\t\ttitle: \"Upload Media\",\n\t\t\tdescription:\n\t\t\t\t\"Upload a media file from base64-encoded data or an external URL and \" +\n\t\t\t\t\"register it in the media library. Returns the media item with id, \" +\n\t\t\t\t\"storageKey, and url — ready to reference from content fields (e.g. \" +\n\t\t\t\t\"featured_image) via content_create / content_update. Uploads are \" +\n\t\t\t\t\"deduplicated by content hash: re-uploading identical bytes returns \" +\n\t\t\t\t\"the existing item with deduplicated: true. URL fetches must resolve \" +\n\t\t\t\t\"to a public http(s) host (SSRF-guarded). Subject to the global \" +\n\t\t\t\t\"upload MIME allowlist and the configured maximum upload size.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tfilename: z.string().min(1).describe(\"Filename including extension (e.g. 'cover.png')\"),\n\t\t\t\tbase64: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Base64-encoded file contents. Provide exactly one of base64 / url.\"),\n\t\t\t\turl: z\n\t\t\t\t\t.url()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Public http(s) URL to fetch the file from. Provide exactly one of base64 / url.\",\n\t\t\t\t\t),\n\t\t\t\tcontentType: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.regex(CONTENT_TYPE_RE, \"Invalid content type\")\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"MIME type (e.g. 'image/png'). Required with base64; with url it \" +\n\t\t\t\t\t\t\t\"defaults to the response's Content-Type header.\",\n\t\t\t\t\t),\n\t\t\t\talt: z.string().optional().describe(\"Alt text for accessibility\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: false },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"media:write\");\n\t\t\trequireRole(extra, Role.CONTRIBUTOR);\n\t\t\tconst { emdash, userId } = getExtra(extra);\n\t\t\tif (!emdash.storage) {\n\t\t\t\treturn respondError(\"NO_STORAGE\", \"Storage not configured\");\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn unwrap(\n\t\t\t\t\tawait emdash.handleMediaUpload({\n\t\t\t\t\t\tfilename: args.filename,\n\t\t\t\t\t\tbase64: args.base64,\n\t\t\t\t\t\turl: args.url,\n\t\t\t\t\t\tcontentType: args.contentType,\n\t\t\t\t\t\talt: args.alt,\n\t\t\t\t\t\tauthorId: userId,\n\t\t\t\t\t\tmaxUploadSize: emdash.config.maxUploadSize,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"UPLOAD_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"media_get\",\n\t\t{\n\t\t\ttitle: \"Get Media Item\",\n\t\t\tdescription:\n\t\t\t\t\"Get details of a single media file by its ID. Returns metadata \" +\n\t\t\t\t\"including filename, MIME type, size, dimensions, alt text, and URL.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tid: z.string().describe(\"Media item ID\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"media:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\treturn unwrap(await ec.handleMediaGet(args.id));\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"media_update\",\n\t\t{\n\t\t\ttitle: \"Update Media Metadata\",\n\t\t\tdescription:\n\t\t\t\t\"Update the metadata of an uploaded media file. You can change the \" +\n\t\t\t\t\"alt text, caption, and dimensions. The file itself cannot be changed.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tid: z.string().describe(\"Media item ID\"),\n\t\t\t\talt: z.string().optional().describe(\"Alt text for accessibility\"),\n\t\t\t\tcaption: z.string().optional().describe(\"Caption text\"),\n\t\t\t\twidth: z.number().int().optional().describe(\"Image width in pixels\"),\n\t\t\t\theight: z.number().int().optional().describe(\"Image height in pixels\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"media:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst ec = getEmDash(extra);\n\n\t\t\t// Fetch media item for ownership check\n\t\t\tconst existing = await ec.handleMediaGet(args.id);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\tconst media = (existing.data as Record<string, unknown> | undefined)?.item as\n\t\t\t\t| Record<string, unknown>\n\t\t\t\t| undefined;\n\t\t\tconst authorId = typeof media?.authorId === \"string\" ? media.authorId : \"\";\n\t\t\trequireOwnership(extra, authorId, \"media:edit_own\", \"media:edit_any\");\n\n\t\t\treturn unwrap(\n\t\t\t\tawait ec.handleMediaUpdate(args.id, {\n\t\t\t\t\talt: args.alt,\n\t\t\t\t\tcaption: args.caption,\n\t\t\t\t\twidth: args.width,\n\t\t\t\t\theight: args.height,\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"media_delete\",\n\t\t{\n\t\t\ttitle: \"Delete Media\",\n\t\t\tdescription:\n\t\t\t\t\"Permanently delete an uploaded media file. Removes the database record \" +\n\t\t\t\t\"and the file from storage. Content referencing this media will have \" +\n\t\t\t\t\"broken references. Cannot be undone.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tid: z.string().describe(\"Media item ID\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"media:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst ec = getEmDash(extra);\n\n\t\t\t// Fetch media item for ownership check\n\t\t\tconst existing = await ec.handleMediaGet(args.id);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\tconst media = (existing.data as Record<string, unknown> | undefined)?.item as\n\t\t\t\t| Record<string, unknown>\n\t\t\t\t| undefined;\n\t\t\tconst authorId = typeof media?.authorId === \"string\" ? media.authorId : \"\";\n\t\t\trequireOwnership(extra, authorId, \"media:delete_own\", \"media:delete_any\");\n\n\t\t\treturn unwrap(await ec.handleMediaDelete(args.id));\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"media_usage_repair\",\n\t\t{\n\t\t\ttitle: \"Repair Media Usage Index\",\n\t\t\tdescription:\n\t\t\t\t\"Repair content media usage indexes for one collection or every collection. \" +\n\t\t\t\t\"Returns complete, partial, failed, or stale status; inspect the structured result.\",\n\t\t\tinputSchema: mediaUsageRepairToolSchema,\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"admin\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\n\t\t\tlet input: MediaUsageRepairRequest;\n\t\t\tif (args.scope === \"collection\") {\n\t\t\t\tif (args.collection === undefined) {\n\t\t\t\t\treturn respondError(\n\t\t\t\t\t\t\"VALIDATION_ERROR\",\n\t\t\t\t\t\t\"Collection is required when scope is collection\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tinput = { scope: \"collection\", collection: args.collection };\n\t\t\t} else {\n\t\t\t\tinput = { scope: \"all\" };\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst { handleMediaUsageRepair } = await import(\"../api/handlers/media-usage.js\");\n\t\t\t\treturn unwrap(await handleMediaUsageRepair(ec.db, input));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"MEDIA_USAGE_REPAIR_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\t// =====================================================================\n\t// Search tool\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"search\",\n\t\t{\n\t\t\ttitle: \"Search Content\",\n\t\t\tdescription:\n\t\t\t\t\"Full-text search across content collections. Searches indexed fields \" +\n\t\t\t\t\"for matching content. Collections must have 'search' in their supports \" +\n\t\t\t\t\"list and fields must be marked as searchable. Returns collection, item \" +\n\t\t\t\t\"ID, title, excerpt, and relevance score.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tquery: z.string().describe(\"Search query text\"),\n\t\t\t\tcollections: z\n\t\t\t\t\t.array(z.string())\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Limit search to specific collection slugs (all if omitted)\"),\n\t\t\t\tlocale: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Filter results by locale (omit to search all locales)\"),\n\t\t\t\tlimit: z.number().int().min(1).max(50).optional().describe(\"Max results (default 20)\"),\n\t\t\t\tcursor: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.min(1)\n\t\t\t\t\t.max(2048)\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Pagination cursor from a previous response\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { searchWithDb } = await import(\"../search/index.js\");\n\t\t\t\tconst results = await searchWithDb(ec.db, args.query, {\n\t\t\t\t\tcollections: args.collections,\n\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\tlimit: args.limit,\n\t\t\t\t\tcursor: args.cursor,\n\t\t\t\t});\n\t\t\t\treturn jsonResult(results);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"SEARCH_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\t// =====================================================================\n\t// Taxonomy tools\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"taxonomy_list\",\n\t\t{\n\t\t\ttitle: \"List Taxonomies\",\n\t\t\tdescription:\n\t\t\t\t\"List all taxonomy definitions (e.g. categories, tags). Taxonomies are \" +\n\t\t\t\t\"classification systems applied to content. Each has a name, label, and \" +\n\t\t\t\t\"can be hierarchical (categories) or flat (tags). Optionally filter by \" +\n\t\t\t\t\"locale.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tlocale: z.string().optional().describe(\"Filter by locale (omit for all)\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTaxonomyList } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\treturn unwrap(await handleTaxonomyList(ec.db, { locale: args.locale }));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TAXONOMY_LIST_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"taxonomy_get\",\n\t\t{\n\t\t\ttitle: \"Get Taxonomy Definition\",\n\t\t\tdescription:\n\t\t\t\t\"Get a single taxonomy definition by name. Taxonomy definitions describe \" +\n\t\t\t\t\"a classification system (e.g. categories or tags), which collections \" +\n\t\t\t\t\"it applies to, and whether it is hierarchical. Pass `locale` to resolve \" +\n\t\t\t\t\"a specific translation; otherwise the lowest matching locale is returned.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tname: z.string().describe(\"Taxonomy name (e.g. 'categories', 'tags')\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale to resolve the definition for\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTaxonomyGet } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\treturn unwrap(await handleTaxonomyGet(ec.db, args.name, { locale: args.locale }));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TAXONOMY_GET_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"taxonomy_create\",\n\t\t{\n\t\t\ttitle: \"Create Taxonomy Definition\",\n\t\t\tdescription:\n\t\t\t\t\"Create a taxonomy definition in one locale. `label` and `labelSingular` \" +\n\t\t\t\t\"belong to that locale; `hierarchical` and `collections` belong to the \" +\n\t\t\t\t\"taxonomy and are the same in every locale. `collections` names which \" +\n\t\t\t\t\"content types the taxonomy applies to. A definition for a name that \" +\n\t\t\t\t\"already exists in another locale joins that taxonomy and takes its \" +\n\t\t\t\t\"`hierarchical` and `collections`; passing different values is an error \" +\n\t\t\t\t\"(change them with taxonomy_update).\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tname: createTaxonomyDefBody.shape.name.describe(\n\t\t\t\t\t\"Taxonomy name (lowercase letters, numbers, underscores)\",\n\t\t\t\t),\n\t\t\t\tlabel: createTaxonomyDefBody.shape.label.describe(\"Display name\"),\n\t\t\t\tlabelSingular: createTaxonomyDefBody.shape.labelSingular.describe(\n\t\t\t\t\t\"Singular form of the display name\",\n\t\t\t\t),\n\t\t\t\thierarchical: createTaxonomyDefBody.shape.hierarchical.describe(\n\t\t\t\t\t\"Whether the taxonomy supports parent/child terms, in every locale (defaults to false; must match when the taxonomy exists in another locale)\",\n\t\t\t\t),\n\t\t\t\tcollections: createTaxonomyDefBody.shape.collections.describe(\n\t\t\t\t\t\"Collection slugs this taxonomy applies to, in every locale (defaults to []; must match when the taxonomy exists in another locale)\",\n\t\t\t\t),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale for this definition (e.g. 'fr-fr')\"),\n\t\t\t\ttranslationOf: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Existing taxonomy definition id to create this locale variant from\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"taxonomies:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTaxonomyCreate } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait handleTaxonomyCreate(ec.db, {\n\t\t\t\t\t\tname: args.name,\n\t\t\t\t\t\tlabel: args.label,\n\t\t\t\t\t\tlabelSingular: args.labelSingular,\n\t\t\t\t\t\thierarchical: args.hierarchical,\n\t\t\t\t\t\tcollections: args.collections,\n\t\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\t\ttranslationOf: args.translationOf,\n\t\t\t\t\t}),\n\t\t\t\t\t[taxonomyTag(args.name)],\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TAXONOMY_CREATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"taxonomy_update\",\n\t\t{\n\t\t\ttitle: \"Update Taxonomy Definition\",\n\t\t\tdescription:\n\t\t\t\t\"Update an existing taxonomy definition. The taxonomy `name` cannot be \" +\n\t\t\t\t\"changed. Pass `locale` to update a specific translation's `label` and \" +\n\t\t\t\t\"`labelSingular`; otherwise the lowest matching locale is updated. \" +\n\t\t\t\t\"`hierarchical` and `collections` change for every locale. Any field \" +\n\t\t\t\t\"may be omitted to leave it unchanged.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tname: z.string().describe(\"Taxonomy name to update\"),\n\t\t\t\tlabel: updateTaxonomyDefBody.shape.label.describe(\"New display name\"),\n\t\t\t\tlabelSingular: updateTaxonomyDefBody.shape.labelSingular.describe(\n\t\t\t\t\t\"New singular display name; pass null to clear\",\n\t\t\t\t),\n\t\t\t\thierarchical: updateTaxonomyDefBody.shape.hierarchical.describe(\n\t\t\t\t\t\"Whether the taxonomy supports parent/child terms, in every locale\",\n\t\t\t\t),\n\t\t\t\tcollections: updateTaxonomyDefBody.shape.collections.describe(\n\t\t\t\t\t\"Collection slugs this taxonomy applies to, in every locale\",\n\t\t\t\t),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale of the definition to update\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"taxonomies:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTaxonomyUpdate } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait handleTaxonomyUpdate(ec.db, args.name, {\n\t\t\t\t\t\tlabel: args.label,\n\t\t\t\t\t\tlabelSingular: args.labelSingular,\n\t\t\t\t\t\thierarchical: args.hierarchical,\n\t\t\t\t\t\tcollections: args.collections,\n\t\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\t}),\n\t\t\t\t\t[taxonomyTag(args.name)],\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TAXONOMY_UPDATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"taxonomy_delete\",\n\t\t{\n\t\t\ttitle: \"Delete Taxonomy Definition\",\n\t\t\tdescription:\n\t\t\t\t\"Delete a taxonomy definition and all of its terms in every locale, \" +\n\t\t\t\t\"along with any content assignments those terms hold. This cannot be undone.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tname: z.string().describe(\"Taxonomy name to delete\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"taxonomies:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTaxonomyDelete } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\treturn unwrapAndInvalidate(extra, await handleTaxonomyDelete(ec.db, args.name), [\n\t\t\t\t\ttaxonomyTag(args.name),\n\t\t\t\t]);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TAXONOMY_DELETE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"taxonomy_list_terms\",\n\t\t{\n\t\t\ttitle: \"List Taxonomy Terms\",\n\t\t\tdescription:\n\t\t\t\t\"List terms in a taxonomy with pagination. Terms are individual entries \" +\n\t\t\t\t\"(e.g. specific categories or tags). Hierarchical taxonomies can have \" +\n\t\t\t\t\"parent-child relationships.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\ttaxonomy: z.string().describe(\"Taxonomy name (e.g. 'categories', 'tags')\"),\n\t\t\t\tlimit: z.number().int().min(1).max(100).optional().describe(\"Max items (default 50)\"),\n\t\t\t\tcursor: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.min(1)\n\t\t\t\t\t.max(MAX_TAXONOMY_CURSOR_LENGTH)\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Pagination cursor\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Filter by locale (omit for all)\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTaxonomyList } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\tconst listResult = await handleTaxonomyList(ec.db, { locale: args.locale });\n\t\t\t\tif (!listResult.success) return unwrap(listResult);\n\n\t\t\t\tconst taxonomies = (listResult.data as { taxonomies: Array<{ name: string; id?: string }> })\n\t\t\t\t\t.taxonomies;\n\t\t\t\tconst taxonomy = taxonomies.find((t: { name: string }) => t.name === args.taxonomy);\n\t\t\t\tif (!taxonomy) return respondError(\"NOT_FOUND\", `Taxonomy '${args.taxonomy}' not found`);\n\n\t\t\t\tconst { TaxonomyRepository } = await import(\"../database/repositories/taxonomy.js\");\n\t\t\t\tconst repo = new TaxonomyRepository(ec.db);\n\t\t\t\tconst limit = Math.min(args.limit ?? 50, 100);\n\t\t\t\tlet cursor: TaxonomyListCursor | undefined;\n\t\t\t\tif (args.cursor) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tcursor = decodeTaxonomyCursor(args.cursor);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (error instanceof InvalidCursorError) {\n\t\t\t\t\t\t\treturn respondError(\"INVALID_CURSOR\", error.message);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlet pageCursor: { sortOrder: number; label: string; id: string } | undefined;\n\t\t\t\tif (cursor) {\n\t\t\t\t\tconst cursorTerm = await repo.findById(cursor.id);\n\t\t\t\t\tif (\n\t\t\t\t\t\t!cursorTerm ||\n\t\t\t\t\t\tcursorTerm.name !== args.taxonomy ||\n\t\t\t\t\t\t(args.locale !== undefined && cursorTerm.locale !== args.locale)\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn respondError(\"INVALID_CURSOR\", \"Pagination cursor no longer identifies a term\");\n\t\t\t\t\t}\n\t\t\t\t\tpageCursor = {\n\t\t\t\t\t\tsortOrder: cursorTerm.sortOrder,\n\t\t\t\t\t\tlabel: cursorTerm.label,\n\t\t\t\t\t\tid: cursorTerm.id,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst page = await repo.findPageByName(args.taxonomy, {\n\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\tlimit,\n\t\t\t\t\t...(pageCursor ? { cursor: pageCursor } : {}),\n\t\t\t\t});\n\t\t\t\tconst last = page.items.at(-1);\n\t\t\t\tconst nextCursor = page.hasMore && last ? encodeTaxonomyCursor(last) : undefined;\n\n\t\t\t\treturn jsonResult({\n\t\t\t\t\titems: page.items.map((t) => ({\n\t\t\t\t\t\tid: t.id,\n\t\t\t\t\t\tname: t.name,\n\t\t\t\t\t\tslug: t.slug,\n\t\t\t\t\t\tlabel: t.label,\n\t\t\t\t\t\tparentId: t.parentId,\n\t\t\t\t\t\tdescription: typeof t.data?.description === \"string\" ? t.data.description : undefined,\n\t\t\t\t\t\tlocale: t.locale,\n\t\t\t\t\t\ttranslationGroup: t.translationGroup,\n\t\t\t\t\t})),\n\t\t\t\t\tnextCursor,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TAXONOMY_LIST_TERMS_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"taxonomy_create_term\",\n\t\t{\n\t\t\ttitle: \"Create Taxonomy Term\",\n\t\t\tdescription:\n\t\t\t\t\"Create a new term in a taxonomy. For hierarchical taxonomies like \" +\n\t\t\t\t\"categories, you can specify a parentId to create a child term. The \" +\n\t\t\t\t\"parent must exist and belong to the same taxonomy. The parent's \" +\n\t\t\t\t\"ancestor chain must not exceed 100 levels — attempts to attach a \" +\n\t\t\t\t\"new term beneath a chain of 100+ existing ancestors are rejected.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\ttaxonomy: z.string().describe(\"Taxonomy name (e.g. 'categories', 'tags')\"),\n\t\t\t\tslug: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.min(1)\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"URL identifier for the term; omit to derive it from the label\"),\n\t\t\t\tlabel: z.string().describe(\"Display name\"),\n\t\t\t\tparentId: z.string().optional().describe(\"Parent term ID for hierarchical taxonomies\"),\n\t\t\t\tdescription: z.string().optional().describe(\"Description of the term\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale for the new term (e.g. 'es')\"),\n\t\t\t\ttranslationOf: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Term id to join as a translation (same translation_group). The new term takes that term's parent and position; a different parentId moves the term in every locale\",\n\t\t\t\t\t),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"taxonomies:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTermCreate } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait handleTermCreate(ec.db, args.taxonomy, {\n\t\t\t\t\t\tslug: args.slug,\n\t\t\t\t\t\tlabel: args.label,\n\t\t\t\t\t\tparentId: args.parentId,\n\t\t\t\t\t\tdescription: args.description,\n\t\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\t\ttranslationOf: args.translationOf,\n\t\t\t\t\t}),\n\t\t\t\t\t[taxonomyTag(args.taxonomy)],\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TAXONOMY_TERM_CREATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"taxonomy_update_term\",\n\t\t{\n\t\t\ttitle: \"Update Taxonomy Term\",\n\t\t\tdescription:\n\t\t\t\t\"Update an existing term in a taxonomy. Any field can be omitted to leave \" +\n\t\t\t\t\"it unchanged. Renaming a term's slug must not collide with another term in \" +\n\t\t\t\t\"the same taxonomy. Set parentId to null to detach from a parent. The new \" +\n\t\t\t\t\"parent must exist, belong to the same taxonomy, and not introduce a cycle \" +\n\t\t\t\t\"(a term cannot be its own ancestor). The new parent's ancestor chain must \" +\n\t\t\t\t\"not exceed 100 levels — reparenting under a chain of 100+ ancestors is \" +\n\t\t\t\t\"rejected. Translations of a term can share a slug: pass `locale` to \" +\n\t\t\t\t\"update a specific translation; otherwise the lowest matching locale is \" +\n\t\t\t\t\"updated.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\ttaxonomy: z.string().describe(\"Taxonomy name (e.g. 'categories', 'tags')\"),\n\t\t\t\ttermSlug: z.string().describe(\"Current slug of the term to update\"),\n\t\t\t\tslug: z.string().optional().describe(\"New slug (must be unique in the taxonomy)\"),\n\t\t\t\tlabel: z.string().optional().describe(\"New display name\"),\n\t\t\t\tparentId: z.string().nullable().optional().describe(\"New parent term ID; null to detach\"),\n\t\t\t\tdescription: z.string().optional().describe(\"New description\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale of the term to update (e.g. 'fr')\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"taxonomies:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTermUpdate } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait handleTermUpdate(\n\t\t\t\t\t\tec.db,\n\t\t\t\t\t\targs.taxonomy,\n\t\t\t\t\t\targs.termSlug,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tslug: args.slug,\n\t\t\t\t\t\t\tlabel: args.label,\n\t\t\t\t\t\t\tparentId: args.parentId,\n\t\t\t\t\t\t\tdescription: args.description,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ locale: args.locale },\n\t\t\t\t\t),\n\t\t\t\t\t[taxonomyTag(args.taxonomy)],\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TAXONOMY_TERM_UPDATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"taxonomy_delete_term\",\n\t\t{\n\t\t\ttitle: \"Delete Taxonomy Term\",\n\t\t\tdescription:\n\t\t\t\t\"Permanently delete a term from a taxonomy. Any content tagged with this \" +\n\t\t\t\t\"term loses the association. Cannot delete a term that has children — \" +\n\t\t\t\t\"delete children first. Translations of a term can share a slug: pass \" +\n\t\t\t\t\"`locale` to delete a specific translation; otherwise the lowest matching \" +\n\t\t\t\t\"locale is deleted.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\ttaxonomy: z.string().describe(\"Taxonomy name\"),\n\t\t\t\ttermSlug: z.string().describe(\"Slug of the term to delete\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale of the term to delete (e.g. 'fr')\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"taxonomies:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTermDelete } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait handleTermDelete(ec.db, args.taxonomy, args.termSlug, { locale: args.locale }),\n\t\t\t\t\t[taxonomyTag(args.taxonomy)],\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TAXONOMY_TERM_DELETE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"taxonomy_term_translations\",\n\t\t{\n\t\t\ttitle: \"List Term Translations\",\n\t\t\tdescription:\n\t\t\t\t\"Return every locale variant of a taxonomy term, identified via its shared translation_group.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tid: z.string().describe(\"Term id (or translation_group)\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleTermTranslations } = await import(\"../api/handlers/taxonomies.js\");\n\t\t\t\treturn unwrap(await handleTermTranslations(ec.db, args.id));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"TERM_TRANSLATIONS_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\t// =====================================================================\n\t// Menu tools\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"menu_list\",\n\t\t{\n\t\t\ttitle: \"List Menus\",\n\t\t\tdescription:\n\t\t\t\t\"List navigation menus. Menus are per-locale: filter by `locale` to \" +\n\t\t\t\t\"get just one locale's worth, or omit to list every row (one per \" +\n\t\t\t\t\"locale per menu name).\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tlocale: z.string().optional().describe(\"Filter by locale (omit for all)\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleMenuList } = await import(\"../api/handlers/menus.js\");\n\t\t\t\treturn unwrap(await handleMenuList(ec.db, { locale: args.locale }));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"MENU_LIST_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"menu_get\",\n\t\t{\n\t\t\ttitle: \"Get Menu with Items\",\n\t\t\tdescription:\n\t\t\t\t\"Get a menu by name, including its items. When multiple locales exist, \" +\n\t\t\t\t\"pass `locale` to pick the right one.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tname: z.string().describe(\"Menu name (e.g. 'main', 'footer')\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale to resolve the menu for\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleMenuGet } = await import(\"../api/handlers/menus.js\");\n\t\t\t\treturn unwrap(await handleMenuGet(ec.db, args.name, { locale: args.locale }));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"MENU_GET_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"menu_translations\",\n\t\t{\n\t\t\ttitle: \"List Menu Translations\",\n\t\t\tdescription:\n\t\t\t\t\"Return every locale variant of a menu, identified via the shared translation_group.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tid: z.string().describe(\"Menu id (or translation_group)\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleMenuTranslations } = await import(\"../api/handlers/menus.js\");\n\t\t\t\treturn unwrap(await handleMenuTranslations(ec.db, args.id));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"MENU_TRANSLATIONS_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"menu_create\",\n\t\t{\n\t\t\ttitle: \"Create Menu\",\n\t\t\tdescription:\n\t\t\t\t\"Create a new navigation menu. The `name` is the stable identifier used \" +\n\t\t\t\t\"by site templates (e.g. 'main', 'footer'); `label` is the human-readable \" +\n\t\t\t\t\"name shown in the admin. Menus are per-locale, so pass `locale` when \" +\n\t\t\t\t\"the same menu name exists in multiple translations. Add items afterwards \" +\n\t\t\t\t\"with menu_set_items. If `translationOf` is set, `locale` must also be set.\",\n\t\t\t// `locale`-when-`translationOf` is enforced inside handleMenuCreate\n\t\t\t// so REST/SDK callers get the same guard. The description above\n\t\t\t// documents the rule; the handler returns VALIDATION_ERROR.\n\t\t\tinputSchema: z.object({\n\t\t\t\tname: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.regex(COLLECTION_SLUG_PATTERN)\n\t\t\t\t\t.describe(\"Stable identifier (lowercase letters, numbers, underscores)\"),\n\t\t\t\tlabel: z.string().describe(\"Display name for the admin\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale for this menu (e.g. 'fr-fr')\"),\n\t\t\t\ttranslationOf: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Existing menu id to create this locale variant from\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"menus:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleMenuCreate } = await import(\"../api/handlers/menus.js\");\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait handleMenuCreate(ec.db, {\n\t\t\t\t\t\tname: args.name,\n\t\t\t\t\t\tlabel: args.label,\n\t\t\t\t\t\tlocale: args.locale,\n\t\t\t\t\t\ttranslationOf: args.translationOf,\n\t\t\t\t\t}),\n\t\t\t\t\t[menuTag(args.name)],\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"MENU_CREATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"menu_update\",\n\t\t{\n\t\t\ttitle: \"Update Menu\",\n\t\t\tdescription:\n\t\t\t\t\"Update a menu's label. The `name` (stable identifier) cannot be changed. \" +\n\t\t\t\t\"On multi-locale installs, pass `locale` so the correct translation is updated.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tname: z.string().describe(\"Menu name to update\"),\n\t\t\t\tlabel: z.string().describe(\"New display label\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale of the menu to update\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"menus:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleMenuUpdate } = await import(\"../api/handlers/menus.js\");\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait handleMenuUpdate(ec.db, args.name, { label: args.label, locale: args.locale }),\n\t\t\t\t\t[menuTag(args.name)],\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"MENU_UPDATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"menu_delete\",\n\t\t{\n\t\t\ttitle: \"Delete Menu\",\n\t\t\tdescription:\n\t\t\t\t\"Delete a menu. Items are also removed. Cannot be undone. On multi-locale \" +\n\t\t\t\t\"installs, pass `locale` so only the intended translation is removed.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tname: z.string().describe(\"Menu name to delete\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale of the menu to delete\"),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"menus:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleMenuDelete } = await import(\"../api/handlers/menus.js\");\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait handleMenuDelete(ec.db, args.name, { locale: args.locale }),\n\t\t\t\t\t[menuTag(args.name)],\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"MENU_DELETE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"menu_set_items\",\n\t\t{\n\t\t\ttitle: \"Set Menu Items\",\n\t\t\tdescription:\n\t\t\t\t\"Replace the entire item list of a menu in one call. This is atomic: the \" +\n\t\t\t\t\"existing items are deleted and the new list is inserted in the order \" +\n\t\t\t\t\"provided. Use this rather than per-item add/remove tools so the resulting \" +\n\t\t\t\t\"order and parent links are unambiguous. On multi-locale installs, pass \" +\n\t\t\t\t\"`locale` so only the intended translation is rewritten.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tname: z.string().describe(\"Menu name to update\"),\n\t\t\t\tlocale: z.string().optional().describe(\"Locale of the menu to rewrite\"),\n\t\t\t\titems: z\n\t\t\t\t\t.array(\n\t\t\t\t\t\tz.object({\n\t\t\t\t\t\t\tlabel: z.string().describe(\"Item display text\"),\n\t\t\t\t\t\t\ttype: z\n\t\t\t\t\t\t\t\t.enum([\"custom\", \"page\", \"post\", \"taxonomy\", \"collection\"])\n\t\t\t\t\t\t\t\t.describe(\"Item kind\"),\n\t\t\t\t\t\t\tcustomUrl: z\n\t\t\t\t\t\t\t\t.string()\n\t\t\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t\t\t.describe(\"URL for type='custom' items (ignored otherwise)\"),\n\t\t\t\t\t\t\treferenceCollection: z\n\t\t\t\t\t\t\t\t.string()\n\t\t\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t\t\t.describe(\"Target collection slug for content references\"),\n\t\t\t\t\t\t\treferenceId: z.string().optional().describe(\"Target content/term ID for references\"),\n\t\t\t\t\t\t\ttitleAttr: z.string().optional().describe(\"HTML title attribute\"),\n\t\t\t\t\t\t\ttarget: z.string().optional().describe(\"HTML target attribute, e.g. '_blank'\"),\n\t\t\t\t\t\t\tcssClasses: z.string().optional().describe(\"Space-separated CSS classes\"),\n\t\t\t\t\t\t\t/**\n\t\t\t\t\t\t\t * Items are positioned by array index, but parents may be referenced\n\t\t\t\t\t\t\t * by their array index — items with `parentIndex` set are nested under\n\t\t\t\t\t\t\t * the item at that position. Items without `parentIndex` are top-level.\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\tparentIndex: z\n\t\t\t\t\t\t\t\t.number()\n\t\t\t\t\t\t\t\t.int()\n\t\t\t\t\t\t\t\t.nonnegative()\n\t\t\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t\t\t.describe(\n\t\t\t\t\t\t\t\t\t\"Array index of the parent item (must be earlier in the list). Omit for top-level items.\",\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t\t.describe(\"Ordered list of menu items\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"menus:manage\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleMenuSetItems } = await import(\"../api/handlers/menus.js\");\n\t\t\t\treturn unwrapAndInvalidate(\n\t\t\t\t\textra,\n\t\t\t\t\tawait handleMenuSetItems(ec.db, args.name, args.items, { locale: args.locale }),\n\t\t\t\t\t[menuTag(args.name)],\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"MENU_SET_ITEMS_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\t// =====================================================================\n\t// Revision tools\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"revision_list\",\n\t\t{\n\t\t\ttitle: \"List Revisions\",\n\t\t\tdescription:\n\t\t\t\t\"List revision history for a content item. Revisions are snapshots \" +\n\t\t\t\t\"created on publish or update. Returns newest-first. Requires the \" +\n\t\t\t\t\"collection to support 'revisions'.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\tcollection: z.string().describe(\"Collection slug\"),\n\t\t\t\tid: z.string().describe(\"Content item ID or slug\"),\n\t\t\t\tlimit: z.number().int().min(1).max(50).optional().describe(\"Max revisions (default 20)\"),\n\t\t\t}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:read\");\n\t\t\trequireDraftAccess(extra);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\treturn unwrap(\n\t\t\t\tawait ec.handleRevisionList(args.collection, args.id, {\n\t\t\t\t\tlimit: args.limit,\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"revision_restore\",\n\t\t{\n\t\t\ttitle: \"Restore Revision\",\n\t\t\tdescription:\n\t\t\t\t\"Restore a content item to a previous revision. Replaces the current \" +\n\t\t\t\t\"draft with the specified revision's data. Not automatically published — \" +\n\t\t\t\t\"use content_publish afterward if needed.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\trevisionId: z.string().describe(\"Revision ID to restore\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"content:write\");\n\t\t\trequireRole(extra, Role.AUTHOR);\n\t\t\tconst { emdash, userId } = getExtra(extra);\n\n\t\t\t// Fetch the revision to discover the parent content entry\n\t\t\tconst revision = await emdash.handleRevisionGet(args.revisionId);\n\t\t\tif (!revision.success) {\n\t\t\t\treturn unwrap(revision);\n\t\t\t}\n\t\t\tconst revItem = revision.data?.item;\n\t\t\tif (!revItem?.collection || !revItem?.entryId) {\n\t\t\t\treturn respondError(\n\t\t\t\t\t\"VALIDATION_ERROR\",\n\t\t\t\t\t\"Revision is missing collection or entry reference\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Fetch the content entry to check ownership\n\t\t\tconst existing = await emdash.handleContentGet(revItem.collection, revItem.entryId);\n\t\t\tif (!existing.success) {\n\t\t\t\treturn unwrap(existing);\n\t\t\t}\n\t\t\trequireOwnership(\n\t\t\t\textra,\n\t\t\t\textractContentAuthorId(existing.data),\n\t\t\t\t\"content:edit_own\",\n\t\t\t\t\"content:edit_any\",\n\t\t\t);\n\n\t\t\treturn unwrap(await emdash.handleRevisionRestore(args.revisionId, userId));\n\t\t},\n\t);\n\n\t// =====================================================================\n\t// Settings tools\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"settings_get\",\n\t\t{\n\t\t\ttitle: \"Get Site Settings\",\n\t\t\tdescription:\n\t\t\t\t\"Get all site-wide settings (title, tagline, logo, favicon, URL, \" +\n\t\t\t\t\"date/time formatting, social links, SEO defaults). Media references \" +\n\t\t\t\t\"(logo, favicon, defaultOgImage) include resolved URLs. Unset values \" +\n\t\t\t\t\"are omitted from the response.\",\n\t\t\tinputSchema: z.object({}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (_args, extra) => {\n\t\t\trequireScope(extra, \"settings:read\");\n\t\t\trequireRole(extra, Role.EDITOR);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleSettingsGet } = await import(\"../api/handlers/settings.js\");\n\t\t\t\treturn unwrap(await handleSettingsGet(ec.db, ec.storage));\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"SETTINGS_READ_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"settings_update\",\n\t\t{\n\t\t\ttitle: \"Update Site Settings\",\n\t\t\tdescription:\n\t\t\t\t\"Update one or more site-wide settings. This is a partial update: only \" +\n\t\t\t\t\"the fields provided are changed; omitted fields are left as-is. Returns \" +\n\t\t\t\t\"the full settings object after the update. To set a media reference \" +\n\t\t\t\t\"(logo, favicon, seo.defaultOgImage), pass an object with `mediaId` \" +\n\t\t\t\t\"(and optional `alt`) — the media item must already exist (use \" +\n\t\t\t\t\"media_create first), or pass null to remove it.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\ttitle: z.string().optional().describe(\"Site title\"),\n\t\t\t\ttagline: z.string().optional().describe(\"Site tagline / short description\"),\n\t\t\t\tlogo: settingsMediaReferenceSchema\n\t\t\t\t\t.nullable()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Logo media reference ({ mediaId, alt? }); null removes it\"),\n\t\t\t\tfavicon: settingsMediaReferenceSchema\n\t\t\t\t\t.nullable()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Favicon media reference ({ mediaId, alt? }); null removes it\"),\n\t\t\t\turl: z\n\t\t\t\t\t.union([\n\t\t\t\t\t\tz.url().refine((u) => HTTP_SCHEME_PATTERN.test(u), \"URL must use http or https\"),\n\t\t\t\t\t\tz.literal(\"\"),\n\t\t\t\t\t])\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Canonical site URL (http or https). Empty string clears it.\"),\n\t\t\t\tpostsPerPage: z\n\t\t\t\t\t.number()\n\t\t\t\t\t.int()\n\t\t\t\t\t.min(1)\n\t\t\t\t\t.max(100)\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Default page size for content listings\"),\n\t\t\t\tdateFormat: z.string().optional().describe(\"Date format token string\"),\n\t\t\t\ttimezone: z.string().optional().describe(\"IANA timezone identifier\"),\n\t\t\t\tsocial: settingsSocialSchema.optional().describe(\"Social handles / URLs\"),\n\t\t\t\tseo: settingsSeoSchema.optional().describe(\"Site-wide SEO defaults\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireScope(extra, \"settings:manage\");\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst ec = getEmDash(extra);\n\t\t\ttry {\n\t\t\t\tconst { handleSettingsUpdate } = await import(\"../api/handlers/settings.js\");\n\t\t\t\treturn unwrapAndInvalidate(extra, await handleSettingsUpdate(ec.db, ec.storage, args), [\n\t\t\t\t\tsiteSettingsTag(),\n\t\t\t\t]);\n\t\t\t} catch (error) {\n\t\t\t\treturn respondHandlerError(error, \"SETTINGS_UPDATE_ERROR\");\n\t\t\t}\n\t\t},\n\t);\n\n\t// =====================================================================\n\t// Site transfer tools\n\t// =====================================================================\n\n\tserver.registerTool(\n\t\t\"site_transfer_capabilities\",\n\t\t{\n\t\t\ttitle: \"Get Site Transfer Capabilities\",\n\t\t\tdescription:\n\t\t\t\t\"Site package format versions, features, and limits this site supports, and whether \" +\n\t\t\t\t\"it can receive an import (its portable content is empty) with the reasons it cannot. \" +\n\t\t\t\t\"Requires any transfer scope (transfer:export, transfer:analyze, or transfer:execute).\",\n\t\t\tinputSchema: z.object({}),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (_args, extra) => {\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\trequireTransferScope(extra, \"transfer:*\");\n\t\t\treturn unwrap(await transferCapabilities(transferContext(extra)));\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"site_export_start\",\n\t\t{\n\t\t\ttitle: \"Start Site Export\",\n\t\t\tdescription:\n\t\t\t\t\"Start exporting the whole site as a portable site package (schema, content, media, \" +\n\t\t\t\t\"settings; never users, credentials, or secrets). Returns the operation id and \" +\n\t\t\t\t\"status only; drive it with site_export_status. The package itself is downloaded \" +\n\t\t\t\t\"outside MCP, from the admin or the CLI. Requires the transfer:export scope. \" +\n\t\t\t\tAPPROVAL_FLOW_DESCRIPTION,\n\t\t\tinputSchema: z.object({\n\t\t\t\tcomments: z.boolean().optional().describe(\"Include comments and reactions (default true)\"),\n\t\t\t\tapprovalId: transferApprovalIdSchema.optional(),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst scoped = transferScopeHeld(extra, \"transfer:export\");\n\t\t\tconst { userId, tokenId } = getExtra(extra);\n\t\t\treturn unwrap(\n\t\t\t\tawait startExport(transferContext(extra), { userId, tokenId }, { ...args, scoped }),\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"site_export_status\",\n\t\t{\n\t\t\ttitle: \"Get Site Export Status\",\n\t\t\tdescription:\n\t\t\t\t\"Report an export's state, stage, and progress, and once it is complete its package \" +\n\t\t\t\t\"digest and record and media totals. By default each call also runs one bounded \" +\n\t\t\t\t\"export step, so call it repeatedly until nextRequestInMs is null; pass advance: \" +\n\t\t\t\t\"false to only read. Requires the transfer:export scope, or the approval that \" +\n\t\t\t\t\"started this export (same token).\",\n\t\t\tinputSchema: z.object({\n\t\t\t\toperationId: transferOperationIdSchema,\n\t\t\t\tadvance: z\n\t\t\t\t\t.boolean()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\"Run one bounded export step before reporting (default true)\"),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tawait requireTransferAccess(extra, \"transfer:export\", \"export\", args.operationId);\n\t\t\treturn unwrap(\n\t\t\t\tawait exportStatus(transferContext(extra), {\n\t\t\t\t\toperationId: args.operationId,\n\t\t\t\t\tadvance: args.advance ?? true,\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"site_import_analyze\",\n\t\t{\n\t\t\ttitle: \"Analyze Site Import\",\n\t\t\tdescription:\n\t\t\t\t\"Validate an uploaded site package against this site and produce an import plan. \" +\n\t\t\t\t\"The package must already be uploaded over HTTP, from the admin or the CLI; MCP \" +\n\t\t\t\t\"never carries package bytes. Each call runs one bounded analysis step: repeat until \" +\n\t\t\t\t\"nextRequestInMs is null, then read plan (counts, principals with suggested user \" +\n\t\t\t\t\"mappings, warnings, blockers, packageDigest, planDigest). Pass decisions to map \" +\n\t\t\t\t\"principals or keep this site's title and tagline; that produces a new planDigest. \" +\n\t\t\t\t\"Principal emails are never returned. Writes no site content. Requires the \" +\n\t\t\t\t\"transfer:analyze scope.\",\n\t\t\tinputSchema: z.object({\n\t\t\t\toperationId: transferOperationIdSchema,\n\t\t\t\tdecisions: siteImportDecisionsInputSchema\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"principalMappings (principal id to target user id, or null to drop the \" +\n\t\t\t\t\t\t\t\"reference) and siteTitle / siteTagline ('package' or 'target'). Omitted \" +\n\t\t\t\t\t\t\t\"values keep the plan defaults.\",\n\t\t\t\t\t),\n\t\t\t}),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\trequireTransferScope(extra, \"transfer:analyze\");\n\t\t\treturn unwrap(await analyzeImport(transferContext(extra), args));\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"site_import_start\",\n\t\t{\n\t\t\ttitle: \"Start Site Import\",\n\t\t\tdescription:\n\t\t\t\t\"Start importing an analyzed package into this site. packageDigest and planDigest \" +\n\t\t\t\t\"must be the values from the latest site_import_analyze plan, which must have no \" +\n\t\t\t\t\"blockers. Returns the operation id and status; drive it with site_import_resume. \" +\n\t\t\t\t\"The site refuses ordinary content writes until the import completes or an admin \" +\n\t\t\t\t\"abandons it. Requires the transfer:execute scope. \" +\n\t\t\t\tAPPROVAL_FLOW_DESCRIPTION,\n\t\t\tinputSchema: z.object({\n\t\t\t\toperationId: transferOperationIdSchema,\n\t\t\t\tpackageDigest: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.regex(SHA256_DIGEST_PATTERN, \"Expected sha256:<64 hex>\")\n\t\t\t\t\t.describe(\"Package digest from the plan\"),\n\t\t\t\tplanDigest: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.regex(SHA256_DIGEST_PATTERN, \"Expected sha256:<64 hex>\")\n\t\t\t\t\t.describe(\"Plan digest from the latest analysis\"),\n\t\t\t\tapprovalId: transferApprovalIdSchema.optional(),\n\t\t\t}),\n\t\t\tannotations: { destructiveHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tconst scoped = transferScopeHeld(extra, \"transfer:execute\");\n\t\t\tconst { userId, tokenId } = getExtra(extra);\n\t\t\treturn unwrap(\n\t\t\t\tawait startImport(\n\t\t\t\t\ttransferContext(extra),\n\t\t\t\t\t{ userId, tokenId },\n\t\t\t\t\t{\n\t\t\t\t\t\toperationId: args.operationId,\n\t\t\t\t\t\tpackageDigest: transferDigest(args.packageDigest),\n\t\t\t\t\t\tplanDigest: transferDigest(args.planDigest),\n\t\t\t\t\t\tapprovalId: args.approvalId,\n\t\t\t\t\t\tscoped,\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"site_import_status\",\n\t\t{\n\t\t\ttitle: \"Get Site Import Status\",\n\t\t\tdescription:\n\t\t\t\t\"Report an import's state, stage, progress, digests, and uploaded file counts. Does \" +\n\t\t\t\t\"not advance the import. Requires any transfer scope, or the approval that started \" +\n\t\t\t\t\"this import (same token).\",\n\t\t\tinputSchema: z.object({ operationId: transferOperationIdSchema }),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tawait requireTransferAccess(extra, \"transfer:*\", \"import\", args.operationId);\n\t\t\treturn unwrap(await importStatus(transferContext(extra), args.operationId));\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"site_import_resume\",\n\t\t{\n\t\t\ttitle: \"Resume Site Import\",\n\t\t\tdescription:\n\t\t\t\t\"Run one bounded step of a started import and report its status. Call repeatedly \" +\n\t\t\t\t\"until nextRequestInMs is null; safe to repeat after a disconnect. Requires the \" +\n\t\t\t\t\"transfer:execute scope, or the approval that started this import (same token).\",\n\t\t\tinputSchema: z.object({ operationId: transferOperationIdSchema }),\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tawait requireTransferAccess(extra, \"transfer:execute\", \"import\", args.operationId);\n\t\t\tconst { userId, tokenId } = getExtra(extra);\n\t\t\treturn unwrap(\n\t\t\t\tawait resumeImport(transferContext(extra), { userId, tokenId }, args.operationId),\n\t\t\t);\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"site_import_receipt\",\n\t\t{\n\t\t\ttitle: \"Get Site Import Receipt\",\n\t\t\tdescription:\n\t\t\t\t\"Return the verified receipt of a completed import: package and plan digests, \" +\n\t\t\t\t\"origin and target site ids, logical digest, record counts, warnings, and the \" +\n\t\t\t\t\"receipt's own digest. Requires any transfer scope, or the approval that started \" +\n\t\t\t\t\"this import (same token).\",\n\t\t\tinputSchema: z.object({ operationId: transferOperationIdSchema }),\n\t\t\tannotations: { readOnlyHint: true },\n\t\t},\n\t\tasync (args, extra) => {\n\t\t\trequireRole(extra, Role.ADMIN);\n\t\t\tawait requireTransferAccess(extra, \"transfer:*\", \"import\", args.operationId);\n\t\t\treturn unwrap(await importReceipt(transferContext(extra), args.operationId));\n\t\t},\n\t);\n\n\treturn server;\n}\n","/**\n * MCP Streamable HTTP endpoint\n *\n * Exposes an MCP server at /_emdash/api/mcp using the Streamable HTTP\n * transport (Web Standard variant). The server runs stateless — each\n * request creates a fresh transport, so no session tracking is needed.\n * Authentication is handled by the existing EmDash auth middleware.\n *\n * POST /_emdash/api/mcp — JSON-RPC tool calls\n * GET /_emdash/api/mcp — SSE stream (not used in stateless mode)\n * DELETE /_emdash/api/mcp — Session close (not used in stateless mode)\n */\n\nimport { WebStandardStreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js\";\nimport type { APIRoute } from \"astro\";\n\nimport { apiError } from \"#api/error.js\";\nimport { createMcpServer } from \"#mcp/server.js\";\n\nexport const prerender = false;\n\nexport const POST: APIRoute = async ({ request, locals, cache }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tif (!user) {\n\t\treturn apiError(\"UNAUTHORIZED\", \"Authentication required\", 401);\n\t}\n\n\tconst pluginTools = await emdash.getEnabledPluginMcpTools();\n\tconst server = createMcpServer(pluginTools, request);\n\n\ttry {\n\t\tconst transport = new WebStandardStreamableHTTPServerTransport({\n\t\t\t// Stateless: no session management\n\t\t\tsessionIdGenerator: undefined,\n\t\t});\n\n\t\tawait server.connect(transport);\n\n\t\treturn await transport.handleRequest(request, {\n\t\t\tauthInfo: {\n\t\t\t\ttoken: \"\",\n\t\t\t\tclientId: \"emdash-admin\",\n\t\t\t\tscopes: [],\n\t\t\t\textra: {\n\t\t\t\t\temdash,\n\t\t\t\t\tuser,\n\t\t\t\t\tuserId: user.id,\n\t\t\t\t\tuserRole: user.role,\n\t\t\t\t\ttokenScopes: locals.tokenScopes,\n\t\t\t\t\ttokenId: locals.tokenId,\n\t\t\t\t\tcache,\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\t} catch (error) {\n\t\tconsole.error(\"[MCP]\", error);\n\t\tawait server.close().catch(() => {});\n\n\t\treturn new Response(\n\t\t\tJSON.stringify({\n\t\t\t\tjsonrpc: \"2.0\",\n\t\t\t\terror: {\n\t\t\t\t\tcode: -32603,\n\t\t\t\t\tmessage: \"Internal server error\",\n\t\t\t\t},\n\t\t\t\tid: null,\n\t\t\t}),\n\t\t\t{\n\t\t\t\tstatus: 500,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\"Cache-Control\": \"private, no-store\",\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}\n};\n\n/**\n * GET — SSE stream. Not used in stateless mode.\n */\nexport const GET: APIRoute = async () => {\n\treturn new Response(\n\t\tJSON.stringify({\n\t\t\tjsonrpc: \"2.0\",\n\t\t\terror: {\n\t\t\t\tcode: -32000,\n\t\t\t\tmessage: \"Method not allowed. This is a stateless MCP endpoint — use POST.\",\n\t\t\t},\n\t\t\tid: null,\n\t\t}),\n\t\t{\n\t\t\tstatus: 405,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\"Cache-Control\": \"private, no-store\",\n\t\t\t},\n\t\t},\n\t);\n};\n\n/**\n * DELETE — Session close. Not used in stateless mode.\n */\nexport const DELETE: APIRoute = async () => {\n\treturn new Response(\n\t\tJSON.stringify({\n\t\t\tjsonrpc: \"2.0\",\n\t\t\terror: {\n\t\t\t\tcode: -32000,\n\t\t\t\tmessage: \"Method not allowed. This is a stateless MCP endpoint.\",\n\t\t\t},\n\t\t\tid: null,\n\t\t}),\n\t\t{\n\t\t\tstatus: 405,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\"Cache-Control\": \"private, no-store\",\n\t\t\t},\n\t\t},\n\t);\n};\n"],"mappings":"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"}