@zackbart/connecta 0.34.0 → 0.35.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 (428) hide show
  1. package/CHANGELOG.md +393 -0
  2. package/README.md +62 -105
  3. package/SECURITY.md +3 -2
  4. package/bin/connecta.mjs +41 -16
  5. package/bin/version.mjs +1 -1
  6. package/dist/access-tokens.d.ts +2 -1
  7. package/dist/access-tokens.js +66 -30
  8. package/dist/activity.d.ts +1 -1
  9. package/dist/activity.js +2 -0
  10. package/dist/agent-config.d.ts +23 -0
  11. package/dist/agent-config.js +59 -0
  12. package/dist/agent-description.js +16 -0
  13. package/dist/agent-identity.js +4 -4
  14. package/dist/agent-observation.js +39 -0
  15. package/dist/auth/clerk-sdk/client.d.ts +2 -0
  16. package/dist/auth/clerk-sdk/generated.js +554 -563
  17. package/dist/auth/clerk-transport.js +70 -3
  18. package/dist/auth/clerk.d.ts +13 -0
  19. package/dist/auth/clerk.js +653 -246
  20. package/dist/auth/cloudflare-access.js +46 -42
  21. package/dist/auth/downstream-client-metadata.js +2 -2
  22. package/dist/auth/downstream-oauth.js +2051 -1160
  23. package/dist/auth/downstream-revocation.js +88 -88
  24. package/dist/auth/native-call.js +20 -0
  25. package/dist/auth/native.js +184 -0
  26. package/dist/auth/oauth-start-reset.js +11 -5
  27. package/dist/auth/oauth-token-response.js +121 -102
  28. package/dist/auth/oauth-v2-migration.js +97 -78
  29. package/dist/auth/renewable-grant.js +10 -0
  30. package/dist/auth/static-oauth.js +663 -271
  31. package/dist/auth/vercel-agent.js +266 -0
  32. package/dist/auth-admission.js +204 -0
  33. package/dist/auth-elicitation.js +350 -241
  34. package/dist/authorization-handoff.js +164 -90
  35. package/dist/call-admission-context.js +3 -10
  36. package/dist/call-admission.js +2 -0
  37. package/dist/call-classification.js +9 -0
  38. package/dist/call-recovery.js +32 -13
  39. package/dist/canonical-json.js +8 -0
  40. package/dist/catalog-cache.js +369 -213
  41. package/dist/catalog-service.js +659 -530
  42. package/dist/catalog.js +5 -1
  43. package/dist/concurrency.js +0 -25
  44. package/dist/config-defaults.d.ts +1 -0
  45. package/dist/config-defaults.js +1 -0
  46. package/dist/config-schema.d.ts +3 -1
  47. package/dist/config-schema.js +13 -3
  48. package/dist/config.d.ts +40 -6
  49. package/dist/config.js +40 -26
  50. package/dist/connector-caller.d.ts +4 -0
  51. package/dist/connector-caller.js +17 -4
  52. package/dist/connectors/api-connector.d.ts +15 -7
  53. package/dist/connectors/api-connector.js +147 -57
  54. package/dist/connectors/guarded-fetch.d.ts +51 -17
  55. package/dist/connectors/guarded-fetch.js +215 -121
  56. package/dist/connectors/negotiation-cache.js +20 -10
  57. package/dist/connectors/option-shapes.js +1 -1
  58. package/dist/connectors/remote-mcp.d.ts +12 -30
  59. package/dist/connectors/remote-mcp.js +960 -564
  60. package/dist/d1.js +10 -243
  61. package/dist/derived-context.js +5 -0
  62. package/dist/describe-config.d.ts +5 -1
  63. package/dist/describe-config.js +3 -0
  64. package/dist/downstream-input.js +347 -260
  65. package/dist/errors.d.ts +87 -6
  66. package/dist/errors.js +114 -4
  67. package/dist/execute.js +87 -50
  68. package/dist/executor-admission.js +3 -0
  69. package/dist/executors/quickjs.js +163 -112
  70. package/dist/guarded-transport.js +50 -0
  71. package/dist/guest-runtime.js +1 -1
  72. package/dist/http/client.js +439 -0
  73. package/dist/http/errors.js +558 -0
  74. package/dist/http/fields.js +49 -0
  75. package/dist/http/hatch-paging.js +318 -0
  76. package/dist/http/hatch.js +1279 -0
  77. package/dist/http/json-schema.js +267 -0
  78. package/dist/http/node-transport.js +241 -0
  79. package/dist/http/oauth.js +162 -0
  80. package/dist/http/paging.js +228 -0
  81. package/dist/http/provider.js +221 -0
  82. package/dist/http/safety.js +82 -0
  83. package/dist/http/services.js +79 -0
  84. package/dist/http/tools.js +383 -0
  85. package/dist/http/vendor-index.js +138 -0
  86. package/dist/http/vendor.js +448 -0
  87. package/dist/http/write-request.js +66 -0
  88. package/dist/http-policy.d.ts +11 -0
  89. package/dist/http-policy.js +45 -0
  90. package/dist/inbound-credential.js +1 -1
  91. package/dist/index.d.ts +2 -2
  92. package/dist/index.js +4 -0
  93. package/dist/invocation-auth.js +30 -19
  94. package/dist/invocation.js +221 -87
  95. package/dist/mcp-result.js +0 -4
  96. package/dist/membership.d.ts +4 -0
  97. package/dist/meta-output.js +1 -1
  98. package/dist/meta-tools.js +534 -408
  99. package/dist/native-recovery.js +52 -0
  100. package/dist/native-tools.js +382 -0
  101. package/dist/node.d.ts +4 -3
  102. package/dist/node.js +45 -8
  103. package/dist/oauth-handoff.js +177 -104
  104. package/dist/oauth-partition.js +6 -20
  105. package/dist/oauth-sealing.js +6 -7
  106. package/dist/operation-vocabulary.js +101 -0
  107. package/dist/operator-record.d.ts +2 -2
  108. package/dist/operator-record.js +17 -4
  109. package/dist/operator-ui/agents.d.ts +5 -4
  110. package/dist/operator-ui/agents.js +17 -7
  111. package/dist/operator-ui/config-summary.js +8 -4
  112. package/dist/operator-ui/connection-map.js +9 -6
  113. package/dist/operator-ui/contract.d.ts +7 -3
  114. package/dist/operator-ui/endpoints.js +5 -14
  115. package/dist/operator-ui/fix-prompts.d.ts +1 -1
  116. package/dist/operator-ui/fix-prompts.js +0 -8
  117. package/dist/operator-ui/generated.js +3 -3
  118. package/dist/operator-ui/health.js +52 -0
  119. package/dist/operator-ui/model.d.ts +2 -3
  120. package/dist/operator-ui/overview.js +11 -19
  121. package/dist/operator-ui/setup-commands.js +0 -4
  122. package/dist/operator-ui/view.d.ts +5 -29
  123. package/dist/operator-ui/view.js +3 -59
  124. package/dist/program-writes.js +47 -26
  125. package/dist/provider-call-facts.d.ts +115 -0
  126. package/dist/provider-call-facts.js +182 -0
  127. package/dist/provider-call.d.ts +112 -0
  128. package/dist/provider-call.js +271 -0
  129. package/dist/provider.d.ts +71 -32
  130. package/dist/provider.js +134 -40
  131. package/dist/providers/_shared/google/hatch.js +91 -0
  132. package/dist/providers/_shared/google/kit.js +537 -0
  133. package/dist/providers/_shared/google/result-size.js +15 -2
  134. package/dist/providers/_shared/google/service-account.d.ts +2 -1
  135. package/dist/providers/_shared/google/service-account.js +8 -4
  136. package/dist/providers/_shared/google/workspace.d.ts +8 -209
  137. package/dist/providers/_shared/google/workspace.js +7 -426
  138. package/dist/providers/_shared/rest/compact-index.js +86 -0
  139. package/dist/providers/_shared/rest/dispatch.js +3 -23
  140. package/dist/providers/_shared/rest/kit.js +546 -0
  141. package/dist/providers/_shared/rest/operation-index.js +230 -14
  142. package/dist/providers/_shared/rest/response-media.js +11 -0
  143. package/dist/providers/_shared/rest/tools.js +101 -78
  144. package/dist/providers/_shared/rest/value-safety.js +353 -195
  145. package/dist/providers/_shared/sensitive-fields.js +27 -0
  146. package/dist/providers/breeze/api.js +584 -0
  147. package/dist/providers/breeze/index.d.ts +3 -3
  148. package/dist/providers/breeze/index.js +67 -1420
  149. package/dist/providers/breeze/openapi.generated.js +60 -0
  150. package/dist/providers/breeze/skill.generated.js +2 -6
  151. package/dist/providers/breeze/tools.js +696 -0
  152. package/dist/providers/ccb/api.js +496 -0
  153. package/dist/providers/ccb/index.d.ts +17 -37
  154. package/dist/providers/ccb/index.js +77 -1702
  155. package/dist/providers/ccb/lib/constants.d.ts +34 -0
  156. package/dist/providers/ccb/lib/constants.js +74 -0
  157. package/dist/providers/ccb/lib/guide.js +9 -0
  158. package/dist/providers/ccb/lib/verdicts.js +387 -0
  159. package/dist/providers/ccb/openapi.generated.js +397 -0
  160. package/dist/providers/ccb/safety.js +295 -0
  161. package/dist/providers/ccb/skill.generated.js +2 -6
  162. package/dist/providers/ccb/tools.js +853 -0
  163. package/dist/providers/cloudflare/api.js +1066 -0
  164. package/dist/providers/cloudflare/index.d.ts +7 -22
  165. package/dist/providers/cloudflare/index.js +80 -194
  166. package/dist/providers/cloudflare/lib/config.d.ts +16 -0
  167. package/dist/providers/cloudflare/lib/config.js +2 -0
  168. package/dist/providers/cloudflare/lib/discovery.js +29 -0
  169. package/dist/providers/cloudflare/{graphql.js → lib/graphql.js} +1 -1
  170. package/dist/providers/cloudflare/lib/hatch.js +103 -0
  171. package/dist/providers/cloudflare/lib/path-bounds.js +28 -0
  172. package/dist/providers/cloudflare/lib/response-media.js +75 -0
  173. package/dist/providers/cloudflare/openapi.generated.js +3299 -3208
  174. package/dist/providers/cloudflare/{value-safety.js → safety.js} +538 -18
  175. package/dist/providers/cloudflare/skill.generated.js +2 -10
  176. package/dist/providers/cloudflare/tools.js +360 -0
  177. package/dist/providers/docs/api.js +51 -0
  178. package/dist/providers/docs/index.d.ts +1 -12
  179. package/dist/providers/docs/index.js +53 -1165
  180. package/dist/providers/docs/lib/constants.d.ts +18 -0
  181. package/dist/providers/docs/lib/constants.js +18 -0
  182. package/dist/providers/docs/lib/discovery.js +26 -0
  183. package/dist/providers/docs/lib/requests.js +48 -0
  184. package/dist/providers/docs/lib/schemas.js +168 -0
  185. package/dist/providers/docs/openapi.generated.js +16 -0
  186. package/dist/providers/docs/safety.js +54 -0
  187. package/dist/providers/docs/skill.generated.js +2 -6
  188. package/dist/providers/docs/tools.js +802 -0
  189. package/dist/providers/drive/api.js +177 -0
  190. package/dist/providers/drive/index.d.ts +1 -12
  191. package/dist/providers/drive/index.js +38 -1448
  192. package/dist/providers/drive/lib/constants.d.ts +6 -0
  193. package/dist/providers/drive/lib/constants.js +6 -0
  194. package/dist/providers/drive/lib/contracts.js +532 -0
  195. package/dist/providers/drive/lib/hatch.js +197 -0
  196. package/dist/providers/drive/openapi.generated.js +77 -0
  197. package/dist/providers/drive/safety.js +90 -0
  198. package/dist/providers/drive/skill.generated.js +2 -6
  199. package/dist/providers/drive/tools.js +1290 -0
  200. package/dist/providers/forms/api.js +71 -0
  201. package/dist/providers/forms/index.d.ts +1 -12
  202. package/dist/providers/forms/index.js +49 -1145
  203. package/dist/providers/forms/lib/constants.d.ts +14 -0
  204. package/dist/providers/forms/lib/constants.js +19 -0
  205. package/dist/providers/forms/lib/hatch.js +72 -0
  206. package/dist/providers/forms/openapi.generated.js +23 -0
  207. package/dist/providers/forms/safety.js +34 -0
  208. package/dist/providers/forms/skill.generated.js +2 -8
  209. package/dist/providers/forms/tools.js +1024 -0
  210. package/dist/providers/github/api.js +150 -0
  211. package/dist/providers/github/index.d.ts +4 -5
  212. package/dist/providers/github/index.js +30 -87
  213. package/dist/providers/github/{auth.d.ts → lib/auth.d.ts} +5 -3
  214. package/dist/providers/github/{auth.js → lib/auth.js} +40 -43
  215. package/dist/providers/github/lib/discovery.js +132 -0
  216. package/dist/providers/github/lib/operations.js +58 -0
  217. package/dist/providers/github/{scope.d.ts → lib/scope.d.ts} +2 -0
  218. package/dist/providers/github/{scope.js → lib/scope.js} +25 -1
  219. package/dist/providers/github/openapi.generated.js +1216 -0
  220. package/dist/providers/github/safety.js +216 -0
  221. package/dist/providers/github/skill.generated.js +2 -5
  222. package/dist/providers/github/tools.js +506 -0
  223. package/dist/providers/gmail/api.js +114 -0
  224. package/dist/providers/gmail/index.d.ts +1 -12
  225. package/dist/providers/gmail/index.js +73 -1621
  226. package/dist/providers/gmail/lib/constants.d.ts +13 -0
  227. package/dist/providers/gmail/lib/constants.js +16 -0
  228. package/dist/providers/gmail/lib/index.js +173 -0
  229. package/dist/providers/gmail/lib/schemas.js +176 -0
  230. package/dist/providers/gmail/lib/threading.js +120 -0
  231. package/dist/providers/gmail/openapi.generated.js +92 -0
  232. package/dist/providers/gmail/safety.js +21 -0
  233. package/dist/providers/gmail/skill.generated.js +2 -6
  234. package/dist/providers/gmail/tools.js +1435 -0
  235. package/dist/providers/overflow/api.js +1008 -0
  236. package/dist/providers/overflow/index.d.ts +3 -17
  237. package/dist/providers/overflow/index.js +60 -1488
  238. package/dist/providers/overflow/skill.generated.js +2 -5
  239. package/dist/providers/overflow/tools.js +873 -0
  240. package/dist/providers/planning-center/api.js +467 -0
  241. package/dist/providers/planning-center/index.d.ts +6 -35
  242. package/dist/providers/planning-center/index.js +69 -2445
  243. package/dist/providers/planning-center/lib/constants.d.ts +58 -0
  244. package/dist/providers/planning-center/lib/constants.js +83 -0
  245. package/dist/providers/planning-center/lib/discovery.js +40 -0
  246. package/dist/providers/planning-center/lib/guide.js +39 -0
  247. package/dist/providers/planning-center/lib/json-api.js +83 -0
  248. package/dist/providers/planning-center/lib/verdicts.js +1758 -0
  249. package/dist/providers/planning-center/openapi.generated.js +1764 -0
  250. package/dist/providers/planning-center/safety.js +188 -0
  251. package/dist/providers/planning-center/skill.generated.js +2 -27
  252. package/dist/providers/planning-center/tools.js +1010 -0
  253. package/dist/providers/sheets/api.js +133 -0
  254. package/dist/providers/sheets/index.d.ts +4 -16
  255. package/dist/providers/sheets/index.js +61 -1172
  256. package/dist/providers/sheets/lib/constants.d.ts +14 -0
  257. package/dist/providers/sheets/lib/constants.js +14 -0
  258. package/dist/providers/sheets/lib/hatch.js +163 -0
  259. package/dist/providers/sheets/lib/requests.js +105 -0
  260. package/dist/providers/sheets/lib/schemas.js +138 -0
  261. package/dist/providers/sheets/openapi.generated.js +30 -0
  262. package/dist/providers/sheets/safety.js +27 -0
  263. package/dist/providers/sheets/skill.generated.js +2 -7
  264. package/dist/providers/sheets/tools.js +734 -0
  265. package/dist/providers/slides/api.js +147 -0
  266. package/dist/providers/slides/index.d.ts +2 -10
  267. package/dist/providers/slides/index.js +48 -2555
  268. package/dist/providers/slides/lib/constants.d.ts +11 -0
  269. package/dist/providers/slides/lib/constants.js +11 -0
  270. package/dist/providers/slides/lib/requests.js +60 -0
  271. package/dist/providers/slides/lib/schemas.js +565 -0
  272. package/dist/providers/slides/openapi.generated.js +18 -0
  273. package/dist/providers/slides/skill.generated.js +2 -6
  274. package/dist/providers/slides/tools.js +1968 -0
  275. package/dist/providers/stripe/api.js +401 -0
  276. package/dist/providers/stripe/index.d.ts +7 -27
  277. package/dist/providers/stripe/index.js +75 -191
  278. package/dist/providers/stripe/lib/config.d.ts +4 -0
  279. package/dist/providers/stripe/lib/config.js +2 -0
  280. package/dist/providers/stripe/openapi.generated.js +4 -3
  281. package/dist/providers/stripe/{value-safety.js → safety.js} +5 -5
  282. package/dist/providers/stripe/skill.generated.js +2 -10
  283. package/dist/providers/stripe/tools.js +77 -0
  284. package/dist/providers/tithely/api.js +531 -0
  285. package/dist/providers/tithely/index.d.ts +19 -0
  286. package/dist/providers/tithely/index.js +86 -965
  287. package/dist/providers/tithely/skill.generated.js +2 -5
  288. package/dist/providers/tithely/tools.js +426 -0
  289. package/dist/providers/vercel/api.js +551 -0
  290. package/dist/providers/vercel/index.d.ts +11 -25
  291. package/dist/providers/vercel/index.js +67 -261
  292. package/dist/providers/vercel/lib/config.d.ts +2 -0
  293. package/dist/providers/vercel/lib/config.js +2 -0
  294. package/dist/providers/vercel/lib/index.js +117 -0
  295. package/dist/providers/vercel/lib/logs.js +100 -0
  296. package/dist/providers/vercel/lib/pin.js +270 -0
  297. package/dist/providers/vercel/openapi.generated.js +398 -376
  298. package/dist/providers/vercel/{value-safety.js → safety.js} +261 -42
  299. package/dist/providers/vercel/skill.generated.js +2 -7
  300. package/dist/providers/vercel/tools.js +642 -0
  301. package/dist/redaction-identity.js +47 -0
  302. package/dist/redaction-marker.js +125 -0
  303. package/dist/registry.d.ts +30 -28
  304. package/dist/registry.js +446 -413
  305. package/dist/routes/access-tokens.js +1 -1
  306. package/dist/routes/actor-labels.js +1 -1
  307. package/dist/routes/connect.js +1 -1
  308. package/dist/routes/dispatch.js +103 -0
  309. package/dist/routes/mcp.js +170 -79
  310. package/dist/routes/oauth.js +3 -1
  311. package/dist/routes/operator.js +2 -2
  312. package/dist/routes/shared.d.ts +5 -4
  313. package/dist/routes/shared.js +244 -177
  314. package/dist/routes/skills.js +10 -8
  315. package/dist/routes/ui-config.js +27 -3
  316. package/dist/routes/ui-data.js +29 -22
  317. package/dist/routes/ui.js +1 -1
  318. package/dist/runtime/call-admission.js +0 -26
  319. package/dist/runtime/call-entry.js +30 -0
  320. package/dist/runtime/call.js +556 -0
  321. package/dist/runtime/connector-scope.js +7 -0
  322. package/dist/runtime/credential-probe.js +34 -0
  323. package/dist/runtime/executor.js +40 -0
  324. package/dist/runtime/native-storage.js +63 -0
  325. package/dist/runtime/registry.js +27 -0
  326. package/dist/runtime/request-scope.js +72 -0
  327. package/dist/runtime/run.js +15 -7
  328. package/dist/runtime/shared-read.js +34 -5
  329. package/dist/runtime/storage.js +34 -21
  330. package/dist/sent-secrets.d.ts +194 -37
  331. package/dist/sent-secrets.js +1743 -340
  332. package/dist/server.js +5 -56
  333. package/dist/skills.js +330 -224
  334. package/dist/sqlite.js +15 -14
  335. package/dist/storage/d1-copy.js +255 -0
  336. package/dist/storage/d1-driver.js +15 -0
  337. package/dist/storage/keys.js +28 -0
  338. package/dist/storage/sql-driver.js +88 -0
  339. package/dist/storage/sql-native.js +544 -0
  340. package/dist/storage/sql-schema.d.ts +6 -0
  341. package/dist/storage/sql-schema.js +15 -0
  342. package/dist/storage/sql.d.ts +14 -20
  343. package/dist/storage/sql.js +29 -535
  344. package/dist/timeout.js +0 -26
  345. package/dist/tool-safety.js +20 -10
  346. package/dist/types.d.ts +11 -99
  347. package/dist/upward.js +3 -0
  348. package/dist/usage-guide.js +3 -1
  349. package/dist/validate.d.ts +4 -2
  350. package/dist/validate.js +86 -9
  351. package/dist/version.d.ts +1 -1
  352. package/dist/version.js +1 -1
  353. package/dist/worker.js +312 -292
  354. package/dist/workspace-subject.js +5 -1
  355. package/dist/write-outcome.js +454 -34
  356. package/documentation/README.md +27 -7
  357. package/documentation/architecture.md +2550 -186
  358. package/documentation/auth.md +821 -98
  359. package/documentation/code-mode.md +56 -21
  360. package/documentation/deploying.md +164 -20
  361. package/documentation/hosted-mcp-migration.md +460 -0
  362. package/documentation/integrating.md +144 -105
  363. package/documentation/meta-tools.md +411 -34
  364. package/documentation/operating.md +28 -4
  365. package/documentation/operator-tests.md +11 -2
  366. package/documentation/operator-ui.md +103 -33
  367. package/documentation/provider-auth-migration.md +38 -63
  368. package/documentation/provider-migration-0.29.md +10 -5
  369. package/documentation/provider-migration-0.35.md +975 -0
  370. package/documentation/providers.md +965 -0
  371. package/examples/worker/AGENTS.md +23 -9
  372. package/examples/worker/README.md +254 -135
  373. package/examples/worker/alchemy.run.ts +116 -0
  374. package/examples/worker/gitignore +10 -0
  375. package/examples/worker/src/connecta.config.ts +23 -21
  376. package/examples/worker/wrangler.jsonc +14 -5
  377. package/guides/connecting-agents.md +157 -0
  378. package/guides/how-it-works.md +156 -0
  379. package/guides/safety-and-trust.md +153 -0
  380. package/package.json +27 -42
  381. package/templates/node/.env.example +3 -0
  382. package/templates/node/README.md +22 -2
  383. package/templates/node/docker-compose.yml +1 -0
  384. package/templates/node/package.json +3 -2
  385. package/templates/node/src/connecta.config.ts +8 -0
  386. package/dist/catalog-drift.d.ts +0 -134
  387. package/dist/catalog-drift.js +0 -493
  388. package/dist/providers/_shared/request-token.js +0 -83
  389. package/dist/providers/_shared/rest/operation-index.d.ts +0 -133
  390. package/dist/providers/_shared/rest/tools.d.ts +0 -141
  391. package/dist/providers/_shared/rest/value-safety.d.ts +0 -201
  392. package/dist/providers/basecamp/index.d.ts +0 -43
  393. package/dist/providers/basecamp/index.js +0 -997
  394. package/dist/providers/basecamp/skill.generated.js +0 -9
  395. package/dist/providers/cloudflare/rest.d.ts +0 -37
  396. package/dist/providers/cloudflare/rest.js +0 -1078
  397. package/dist/providers/github/hosted.js +0 -218
  398. package/dist/providers/github/rest.js +0 -321
  399. package/dist/providers/infisical/index.d.ts +0 -7
  400. package/dist/providers/infisical/index.js +0 -713
  401. package/dist/providers/infisical/skill.generated.js +0 -8
  402. package/dist/providers/linear/index.d.ts +0 -55
  403. package/dist/providers/linear/index.js +0 -352
  404. package/dist/providers/linear/skill.generated.js +0 -8
  405. package/dist/providers/mixpanel/index.d.ts +0 -57
  406. package/dist/providers/mixpanel/index.js +0 -468
  407. package/dist/providers/mixpanel/operations.js +0 -20
  408. package/dist/providers/mixpanel/rest.js +0 -603
  409. package/dist/providers/mixpanel/skill.generated.js +0 -10
  410. package/dist/providers/mixpanel/value-safety.js +0 -16
  411. package/dist/providers/notion/index.d.ts +0 -65
  412. package/dist/providers/notion/index.js +0 -368
  413. package/dist/providers/notion/openapi.generated.js +0 -75
  414. package/dist/providers/notion/rest.d.ts +0 -24
  415. package/dist/providers/notion/rest.js +0 -1226
  416. package/dist/providers/notion/skill.generated.js +0 -11
  417. package/dist/providers/notion/value-safety.js +0 -56
  418. package/dist/providers/revenuecat/index.d.ts +0 -49
  419. package/dist/providers/revenuecat/index.js +0 -557
  420. package/dist/providers/revenuecat/skill.generated.js +0 -11
  421. package/dist/providers/stripe/rest.d.ts +0 -14
  422. package/dist/providers/stripe/rest.js +0 -402
  423. package/dist/providers/vercel/rest.d.ts +0 -20
  424. package/dist/providers/vercel/rest.js +0 -1020
  425. package/dist/providers/wispr-flow/index.d.ts +0 -14
  426. package/dist/providers/wispr-flow/index.js +0 -117
  427. package/dist/providers/wispr-flow/skill.generated.js +0 -8
  428. /package/dist/providers/github/{key.js → lib/key.js} +0 -0
@@ -0,0 +1,975 @@
1
+ # Provider migration for 0.35
2
+
3
+ This guide collects provider upgrade actions for 0.35.0. Update saved programs,
4
+ pool grants, classification entries and deployment instructions using the exact
5
+ tool and argument mappings below. Restart pre-upgrade provider continuations
6
+ where the provider section requires a new first page.
7
+
8
+ For Node transport requirements, write-outcome recovery, native pools, Vercel
9
+ workload credentials and the Eve helper, follow
10
+ [Upgrade an existing deployment](./deploying.md#upgrade-an-existing-deployment).
11
+
12
+ For hosted MCP removals, follow [Migrate hosted MCP presets](./hosted-mcp-migration.md).
13
+
14
+ ## Node transport and egress
15
+
16
+ On Node, serve with `listen()` from `@zackbart/connecta/node` and install the
17
+ exact `undici@6.29.1` peer. `listen()` installs the owned sender for every
18
+ maintained-provider request, including reads, remote MCP writes, and downstream
19
+ OAuth token, registration and revocation POSTs. It connects directly by default
20
+ or through an explicit HTTP(S) CONNECT `proxy` option on `listen()`. Ambient
21
+ `NODE_USE_ENV_PROXY`, `HTTP_PROXY`, `HTTPS_PROXY` and host proxy dispatchers do
22
+ not configure the owned sender. Remote MCP reads and OAuth discovery GETs retain
23
+ native fetch and need their own host proxy policy.
24
+
25
+ A Node host serving `connecta.fetch` without `listen()` has no owned sender.
26
+ Every maintained-provider write, every reviewed POST read and every remote MCP
27
+ write is refused before sending; each worked in 0.34.1. Downstream OAuth
28
+ credential POSTs also require the owned sender. For example, the reviewed
29
+ `vercel_api_read` POST to `/v1/registrar/domains/availability` requires `listen()`
30
+ even on a read-only endpoint.
31
+
32
+ Before upgrading a deployment that needs a proxy, configure
33
+ `listen(connecta, { port: 3000, proxy: "http://proxy.example.com:8080" })` for
34
+ owned sends and retain the host's separate native-fetch proxy policy for reads
35
+ and discovery. An uncertain OAuth refresh requires fresh authorization rather
36
+ than replaying the spent token. Follow [Node startup](./deploying.md#start-on-node)
37
+ for proxy credentials, TLS trust and startup requirements.
38
+
39
+ ## Provider response media and path hardening
40
+
41
+ JSON-only Stripe and Cloudflare operations now refuse unexpected text, HTML and
42
+ binary success replies. A dispatched unreadable write reports an unknown outcome
43
+ and is sent once; check the target before repeating it. Reviewed PDFs, exports
44
+ and streams remain supported. Cloudflare's three Worker-content operations accept
45
+ any non-JSON media despite the pin's malformed `string` media label, including
46
+ Python modules and multipart bundles. R2 object and KV value reads labelled
47
+ application/json or +json retain parsing and every JSON value-safety layer; other
48
+ stored types return bounded bytes with sent-secret checks.
49
+
50
+ Pinned integer and number path parameters require canonical ASCII decimal
51
+ notation: no hexadecimal, exponents, leading plus, whitespace or leading zeros.
52
+ Integers must be safe integers; negative values remain valid where the pin allows
53
+ them. Number parameters also accept decimal fractions with trailing zeros. Cloudflare's 16 integer parameters with minimum 0 and exclusiveMinimum true
54
+ require at least 1. String ids retain their pinned contracts. Compound telemetry
55
+ segments remain callable when the index cannot extract their individual values.
56
+
57
+ Vercel environment `value` inputs are `writeOnly` on the named upsert/update tools;
58
+ the raw project/shared-env writes register the same private values before sending.
59
+ Hosts and generated clients must treat these inputs as private write arguments;
60
+ they cannot be recovered from a read or a write reply.
61
+ Echoes in ids, keys, codes and successful metadata are withheld. Project-env POST
62
+ and shared-env POST, PATCH and DELETE withhold failed[].error.message before
63
+ fields selection. Named partial-write reports retain safe created ids/keys and
64
+ failed keys/codes with check-before-repeat guidance.
65
+
66
+ Overflow refunds accept an application/json string, a text/plain acknowledgement,
67
+ or an empty 2xx acknowledgement (including 202/204). Plain text is a narrow NestJS
68
+ compatibility exception. Nonempty text/html, binary, other media and JSON-object
69
+ replies report an unknown write outcome, check-before-repeat guidance and one
70
+ dispatch. Other empty write acknowledgements and health text retain their behavior.
71
+
72
+ ## Remove Infisical, Notion, and Mixpanel
73
+
74
+ The `@zackbart/connecta/providers/infisical`, `/providers/notion`, and
75
+ `/providers/mixpanel` subpaths and their maintained API tools are removed.
76
+ Remove their imports and the `infisical()`, `notion()`, and `mixpanel()` calls
77
+ from deployment configuration. Remove or replace pool grants, classification
78
+ entries, and agent instructions that name those connections or tools.
79
+
80
+ For Notion and Mixpanel, configure the hosted server through generic
81
+ `remoteMcp()` entries using the URLs and auth modes in the
82
+ [Notion](./hosted-mcp-migration.md#notion) and
83
+ [Mixpanel](./hosted-mcp-migration.md#mixpanel) hosted MCP migration sections,
84
+ including Mixpanel's regional mapping. Hosted tools
85
+ have the server's live names, schemas, permissions, and classifications;
86
+ rediscover them before updating programs or grants. A Notion integration token
87
+ cannot be reused as user OAuth. Generic hosted connections do not inherit the
88
+ removed API providers' projections, redaction rules, or API coverage.
89
+
90
+ Infisical has no replacement in the package. Remove the connection, or implement
91
+ a deployment-owned [`api()` connector](./integrating.md#a-hand-written-http-capability)
92
+ for the required operations. The deployment owns its authentication, tool
93
+ classification, and handling of secret values.
94
+
95
+ Run the deployment's typecheck, restart Node or redeploy the Worker, and use
96
+ `connecta doctor` and a bounded read from each intended pool to verify the new
97
+ configuration. See [deployment upgrades](./deploying.md#upgrade-an-existing-deployment).
98
+
99
+ ## Stripe
100
+
101
+ The six tool names, factory options, credentials and pinned API version remain
102
+ the same: `stripe_api_search`, `stripe_api_details`, `stripe_api_read`,
103
+ `stripe_api_write`, `get_stripe_account_info` and `get_balance_summary`.
104
+ Update saved programs and deployment instructions using these contracts:
105
+
106
+ | Before | After |
107
+ | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
108
+ | `select` on `stripe_api_read`/`stripe_api_write` | `fields`, validated against declared response roots before dispatch |
109
+ | — | Both named reads accept `fields` into their projected records |
110
+ | `page.next` returned a raw vendor token | `page.nextCursor` returns an authenticated continuation; pass it as top-level `cursor` |
111
+ | Continuation in `query.starting_after`, `query.ending_before` or `query.page` | Omit raw anchors/tokens and pass `cursor`, retaining the same path, filters and fields |
112
+ | Search `limit` default 10, maximum 50 | Default 6, maximum 8; follow its `page.nextCursor` as search's `cursor` |
113
+ | Search entries carry `tag` and always a `tool` | Compact entries omit `tag`, omit `tool` for refused operations, and can carry `named` or `matched` |
114
+ | One details result | Large contracts page/chunk without losing required parameters; follow details' `page.nextCursor` as its `cursor` |
115
+ | HTTP 409 → `invalid_args` | HTTP 409 → `conflict`, matching Stripe's documented request-conflict meaning |
116
+
117
+ A raw record-id `query.starting_after` or `query.ending_before` remains valid
118
+ on the **first request without `cursor`**, for example listing charges after
119
+ `ch_example`. The anchor passes ordinary parameter validation and placeholder
120
+ refusal. A signed cursor combined with any raw anchor, or both directions at
121
+ once, is refused before dispatch. Raw vendor continuation tokens are never
122
+ accepted in place of `cursor`. Previously returned raw tokens require a new
123
+ first request. A cursor is bound to its connection, credential owner, index
124
+ content, method, path, filters and selected fields.
125
+
126
+ Hatch pages now always include `param` and `in`; `nextCursor` appears only
127
+ while `hasMore` is true. Forward, backward, v1 search and v2 pagination remain
128
+ available. v2 next-page URLs supply only a confined page token; Connecta never
129
+ follows the URL or changes the original request path and filters.
130
+ If a v2 URL adds parameters the call omitted, the fetched data is returned
131
+ with `page.hasMore: true` and no `nextCursor`; the result is incomplete and
132
+ Connecta cannot safely continue it. Repeat with explicit parameters or narrow
133
+ the request. A signed cursor placed in a raw anchor is refused with guidance
134
+ to use the top-level `cursor` instead.
135
+
136
+ Whole withheld marker values and withheld links are refused on writes; paths
137
+ and queries refuse any containment. Longer prose can mention the marker.
138
+ An invalid `fields` root is refused before any write leaves. Operations without
139
+ declared response roots, including quote PDFs, cannot accept nonempty `fields`.
140
+ Existing reviewed secret withholding and guest-Checkout rules still apply.
141
+
142
+ An oversized HTTP 424 now retains its dependency-failure meaning, including an
143
+ unknown unkeyed write outcome. A failed response-body read is described as a
144
+ read failure rather than malformed JSON. Standard 5xx failures can retain a
145
+ declared Retry-After hint. POST keys and once-only dispatch remain in effect;
146
+ DELETE and the reviewed invoice-preview read send no idempotency key. See
147
+ [Stripe setup and paging examples](./providers.md#stripe).
148
+
149
+ ## Tithe.ly
150
+
151
+ Tithe.ly's agent-facing tools move to the standard provider surface. The
152
+ factory, its options and the credential do not change, and no configuration is
153
+ required. Deployment `instructions`, pool `tools` grants and saved agent
154
+ programs that name an old tool or argument must be updated before upgrading.
155
+
156
+ | Before | After |
157
+ | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
158
+ | `tithely_api_get` `{ path, query: [{ name, value }] }` | `tithely_api_read` `{ path, query: { name: value }, fields? }` |
159
+ | `tithely_api_mutate` `{ method, path, query, form }` | `tithely_api_write` `{ method, path, query: { … }, body: { … }, fields? }`; form fields as a JSON object |
160
+ | hatch result `{ result }` | `{ status, data }` |
161
+ | — | `tithely_api_search` and `tithely_api_details` find operations and their parameters; they read no data |
162
+ | `get_organization` `{ organizationId }` | a `list_organizations` row, or `tithely_api_read` `{ path: "/organizations/<id>" }` |
163
+ | `get_account` `{ accountId }` | a `list_accounts` row, or `tithely_api_read` `{ path: "/accounts/<id>" }` for phone and address |
164
+ | `raw: true` on every named read | removed; read Tithe.ly's record with `tithely_api_read` |
165
+ | — | `list_organizations` rows include `widgetId`, the organization's giving widget id |
166
+ | list keys `organizations`, `accounts`, `charges`, `recurringCharges`, `paymentMethods` | `items` |
167
+ | `page.nextCursor: null` on the last page | `nextCursor` omitted when `page.hasMore` is false |
168
+ | `list_payment_methods` returned every method | pages with `limit` and `cursor` like the other lists |
169
+ | — | `fields` on every named read and on `tithely_api_read`/`tithely_api_write` narrows the result |
170
+
171
+ A hatch call now names an operation in Tithe.ly's documented v1 reference and
172
+ is checked against its parameters before anything is sent; an unknown path or
173
+ parameter is refused with the nearest match. Every write goes through
174
+ `tithely_api_write`, which always requires approval. `sensitiveFields:
175
+ "return"` now widens only the hatch; the named reads never carry an
176
+ organization's bank or legal details. A 429 or 5xx answer keeps its code but
177
+ no longer carries Tithe.ly-specific wording.
178
+
179
+ ## Breeze ChMS
180
+
181
+ Breeze's provider keeps its `subdomain` and credential setup. Replace programs
182
+ and deployment instructions that use these retired names:
183
+
184
+ | Before | Replacement |
185
+ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
186
+ | `breeze_api_get` | `breeze_api_read` |
187
+ | `breeze_api_mutate` | `breeze_api_write` with `method: "GET"` |
188
+ | `list_calendars` | `breeze_api_read`, `/events/calendars/list` |
189
+ | `list_forms` | `breeze_api_read`, `/forms/list_forms`, `archived` → query `is_archived` |
190
+ | `list_form_fields` | `breeze_api_read`, `/forms/list_form_fields`, query `form_id` |
191
+ | `list_form_entries` | `breeze_api_read`, `/forms/list_form_entries`, query `form_id` and `details` |
192
+ | `list_volunteers` | `breeze_api_read`, `/volunteers/list`, query `instance_id` |
193
+ | `list_volunteer_roles` | `breeze_api_read`, `/volunteers/list_roles`, query `instance_id` and `show_quantity` |
194
+ | `list_account_log` | `breeze_api_read`, `/account/list_log`, query `action`, `start`/`end`, `userId` → `user_id`, `includeDetails` → `details`, and unchanged `limit` |
195
+ | `assign_tag` / `unassign_tag` | `breeze_api_write`, `/tags/assign` or `/tags/unassign`, query `person_id` and `tag_id` |
196
+ | `record_check_in` | `breeze_api_write`, `/events/attendance/add`, query `person_id`, `instance_id`, `direction: "in"` |
197
+
198
+ `breeze_api_search` searches the operation index and `breeze_api_details`
199
+ returns request parameters without reading church data. Both hatches now
200
+ admit only indexed operations with the matching read/write verdict. The former
201
+ mutate hatch's arbitrary paths, unreviewed parameters and use for reads retire.
202
+ Every write uses GET at Breeze but still follows Connecta's write route.
203
+ `assign_tag` and `record_check_in` formerly used the non-destructive write
204
+ route; their hatch replacements now require write approval on every call.
205
+ Trailing-slash paths formerly accepted by the legacy hatch, such as
206
+ `/people/`, are refused; use the indexed path without its trailing slash.
207
+
208
+ Hatch `query` is now a JSON object instead of name/value pairs. Values for
209
+ `filter_json`, `fields_json`, `people_ids_json`, `role_ids_json`, `person_json`
210
+ and `funds_json` must be serialized JSON strings. Replies change from
211
+ `{ result }` to `{ status, data, page? }`. Non-JSON successful bodies now fail
212
+ instead of returning text. Repeated values for a query name remain refused;
213
+ Breeze does not interpret them as a batch. Named person writes return the
214
+ projected record when supplied, otherwise `{ ok: true }`; an acknowledgement
215
+ no longer fabricates an update record id or fails solely for a missing
216
+ creation record. The recorded HTML conversion/pin remains the drift
217
+ reference; the runtime index derives from reviewed vendor declarations.
218
+ For the people hatch, `limit` is a whole decimal count from 1 to 1,000;
219
+ `0` or omission requests all people without paging. Invalid counts are
220
+ refused before dispatch.
221
+
222
+ On `add_person` and `update_person`, rename the profile payload argument
223
+ `fields` to `values`. Its typed field-value entries are unchanged. `fields`
224
+ now consistently means result dot-path selection on named reads and hatches.
225
+
226
+ Remove every `raw` argument. Retained named reads take `fields` to narrow
227
+ records or list items. Other nonsecret vendor columns come through the read
228
+ hatch; calendar feed addresses and embed keys remain unavailable. No new
229
+ `sensitiveFields` option is needed.
230
+
231
+ Named lists return `{ items, page }` instead of `people`, `fields`, `tags`,
232
+ `events`, `attendance`, `contributions` or `funds` keys. `list_contributions`
233
+ no longer supplies `count` or `totalAmount`: reduce all pages in code using
234
+ integer cents for exact decimal totals. Unpaged vendor lists now have local
235
+ `limit`/`cursor` windows. `list_people` cursors are opaque and bound to the
236
+ call; restart old numeric-offset cursors from the first page. On a final page,
237
+ `nextCursor` is absent. A full people page can be followed by an empty page.
238
+
239
+ The people hatch returns `page: { hasMore, nextCursor?, param: "offset",
240
+ in: "query" }` when called with a positive explicit `limit`; pass its opaque
241
+ cursor back as `query.offset`, keeping the other arguments unchanged. Omit
242
+ offset on the first call. Without a positive limit Breeze returns all people
243
+ within the response ceiling and there is no paging metadata.
244
+
245
+ `list_events` returns `page.hasMore: false` because the vendor has no offset
246
+ for that operation. Its former boolean `truncated` becomes `["items[]"]` on
247
+ a full capped result; narrow the date range. The removed account-log wrapper's
248
+ full-result warning likewise requires checking the hatch result against its
249
+ requested limit and narrowing the date range. 400/422/429/5xx diagnostics use
250
+ the provider's standalone detail sentence or HTTP-status fallback through
251
+ the kit; reviewed key/absence meanings and write-once behavior
252
+ remain. Operator setup is in [Maintained provider setup](./providers.md#breeze-chms).
253
+
254
+ ## Church Community Builder
255
+
256
+ The factory and v2 OAuth configuration remain `ccb()` from
257
+ `@zackbart/connecta/providers/ccb`. The legacy v1 XML API is outside this provider.
258
+ Update saved programs, pool grants, classification entries and instructions:
259
+
260
+ | Before | After |
261
+ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
262
+ | `ccb_api_get` | `ccb_api_read` with the same canonical absolute API path, query object and optional response `fields` |
263
+ | `ccb_api_mutate` | `ccb_api_write` with explicit method, canonical path and JSON body; the host may ask the user to confirm |
264
+ | `ccb_api_search({ domain, body, page, perPage })` | `search_records({ domain, body, limit, cursor, fields })` for advanced data searches |
265
+ | — | `ccb_api_search({ query, method?, limit?, cursor? })` searches the offline operation index; `ccb_api_details({ method, path, ... })` reads contracts |
266
+ | `page` and `perPage` on named lists and advanced searches | `limit` is exactly 25, 50, 75 or 100 (default 25, or configured `defaultPerPage`); continue with signed `cursor` |
267
+ | `raw` on named reads/lists | Removed; named results remain projected. Use `fields` for projected records or the read hatch for vendor records |
268
+ | Named list noun keys (`individuals`, `families`, `groups`, `members`, `occurrences`, `attendees`, `notes`) and `page: { hasMore, nextPage, total }` | `{ items, page: { hasMore, nextCursor?, total? } }`; `nextPage` becomes a signed `nextCursor`, with exact vendor `total` |
269
+ | HTTP 409 classified as `conflict` | `connector_call_failed`; the public pin does not establish a conflict meaning |
270
+
271
+ Legacy read/data-search hatch envelopes `{ result, page }` become
272
+ `{ status, data, page }`. `search_records` uses the standard list envelope and
273
+ projects rows to `id`, `name`, `individualId`, `groupId`, `status`, `active`,
274
+ `campusId`, `familyId`, `membershipTypeId`, `email` and `counts`, when present.
275
+ Use `ccb_api_read` with `method: "POST"` and `/search/<domain>/results` for
276
+ full vendor rows instead of that projection.
277
+
278
+ These nine named reads are removed. Use `ccb_api_read` with the following
279
+ indexed paths and vendor query names, after inspecting operation details:
280
+
281
+ | Removed tool | Replacement path and filter changes |
282
+ | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
283
+ | `list_forms` | `/forms`; `status` stays `query.status` |
284
+ | `list_form_responses` | `/forms/{id}/responses`; `formId` becomes the concrete path id |
285
+ | `list_processes` | `/processes`; `status` becomes `query.statuses`, `managedByMe` becomes `query.managed_by_me` |
286
+ | `list_queues` | `/queues`; `processId` becomes `query.process_ids: [id]` |
287
+ | `list_queue_individuals` | `/queues_individuals`; `status` becomes `query.statuses: [value]`, `assignment` stays a query filter |
288
+ | `list_scheduling_categories` | `/scheduling/categories`; the pin declares `search` as a wildcard GET body, so that filter is unsupported. Use advanced category search for filtering |
289
+ | `list_schedules` | `/scheduling/categories/{id}/schedules`; `categoryId` becomes the path id and `after` stays a query filter |
290
+ | `list_individual_assignments` | `/individuals/{id}/assignments`; `individualId` becomes the path id. The pin declares `startDate`/`endDate` as wildcard GET-body fields, which are unsupported; use advanced assignment search |
291
+ | `list_individual_pledges` | `/individuals/{id}/pledges`; `individualId` becomes the path id |
292
+
293
+ Hatch rows preserve vendor names and shapes rather than the removed projections.
294
+ For paged indexed operations, retain `query.per_page`, omit `query.page` on
295
+ continuation, and pass the returned signed token as top-level `cursor`. Keep the
296
+ path, filters, fields, body and page size unchanged. Old numeric or unsigned
297
+ continuations cannot be reused. Metadata search/details also page with signed
298
+ cursors. A result cut for size reports the affected dot paths in `truncated: string[]`;
299
+ uncut results omit that property.
300
+
301
+ Paths must be canonical API paths with concrete ids. Absolute URLs, OAuth paths,
302
+ query strings embedded in a path, percent encodings, semicolons and traversal
303
+ segments are refused. For example delete group members with
304
+ `DELETE /groups/5/members` and JSON `{ ids: [42] }`, rather than an invented
305
+ `/groups/5/members/42` path. JSON-only transport refuses multipart and form request
306
+ bodies. Thirteen reviewed wildcard-labelled JSON writes remain admitted:
307
+ twelve object bodies and the bulk group-removal array. These include
308
+ form-response creation and saved-search creation/update. OAuth exchange and
309
+ password reset remain outside the agent surface. Optional wildcard GET bodies
310
+ may be omitted.
311
+
312
+ Use `ccb_api_write` for writes; the host may ask the user to confirm. Writes
313
+ are sent once. Configured read-only
314
+ OAuth scopes omit the write hatch and refuse writes before dispatch; configure
315
+ authorized write scopes in deployment code when required. The `readOnly` option
316
+ continues to enforce read-only endpoints. `sensitiveFields: "return"` permits
317
+ only the configured sensitive set. Private file destinations, payment links,
318
+ calendar feeds and OAuth credentials remain withheld on reads and write replies.
319
+ See [CCB setup and limits](./providers.md#church-community-builder).
320
+
321
+ ## Planning Center
322
+
323
+ The factory, PAT credential and product-version constants remain. Update
324
+ saved programs, deployment instructions, pool tool grants and classification
325
+ entries that name the old tools or arguments before upgrading.
326
+
327
+ | Before | After |
328
+ | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
329
+ | `pco_api_get` | `pco_api_read` |
330
+ | `pco_api_mutate` | `pco_api_write` (always destructive and approval-gated) |
331
+ | No operation discovery | `pco_api_search` and `pco_api_details` (no account-data reads) |
332
+ | Hatch `query: [{name,value}]` | `query: { name: value }`; repeated names use the indexed array form where declared |
333
+ | Per-call `version` | Removed; request a reviewed product-pin update for another version |
334
+ | Any unindexed path | Only the ten reviewed product pins' indexed operations; no host/query/path shorthand |
335
+ | Hatch `{result}` | `{status,data,page?}`; the JSON:API body remains inside `data` |
336
+ | Every `raw` argument | Removed; use the indexed read for safe vendor fields missing from a named projection |
337
+ | Named-list `perPage`, `offset` | `limit`, then the returned opaque `cursor` |
338
+ | Named-list noun keys | `items` (including people, workflows, cards, notes, fields, serviceTypes, plans, teams, schedules, memberships, donations and funds) |
339
+ | `page.nextOffset` | `page.nextCursor`, present only when `hasMore` is true |
340
+ | `page.totalCount` | Optional reliable `page.total` on named results and paged hatch reads; omitted when the vendor total is invalid or unavailable |
341
+ | `get_plan.plan` | Projected plan properties at the top level, with `id` and `service_type_id` |
342
+ | `itemsTruncated`, `teamMembersTruncated` | `truncated` contains `items[]` and/or `teamMembers[]` |
343
+ | `apply_workflow_card_action` result `{cardId,action,applied}` | `{ok:true}` on acknowledgement |
344
+ | People duplicate HTTP 409 → `invalid_args` | `conflict`; other products retain their own status meaning |
345
+ | Named reads had no projection argument | `fields` only narrows projected results; both call hatches also support it where the pin declares response properties |
346
+
347
+ Every removed wrapper below is replaced by the indexed method/path. Put GET
348
+ parameters in the hatch's query object. A write body is
349
+ `{data:{type:"<type>",attributes:{...}}}`; the table names the type and
350
+ attributes. Substitute each old id argument into its path slot. For every
351
+ removed paged read, `perPage` becomes query `per_page`; start without `offset`,
352
+ then use the returned signed `page.nextCursor` as query `offset`. Unlike a
353
+ raw offset, that cursor is bound to the original read and its other arguments.
354
+ Legacy `raw` and `version` are gone on these routes too. Use operation details
355
+ for current required fields and declared filter spelling.
356
+
357
+ The removed additive write wrappers required a created resource in their reply.
358
+ Their indexed replacements now treat every empty 2xx, including 204, as success
359
+ and return the vendor envelope, for example `{status:204,data:null}`.
360
+ `list_person_field_data` remains a read. To write a custom field value, use
361
+ POST `/people/v2/people/{person_id}/field_data` or PATCH
362
+ `/people/v2/field_data/{field_datum_id}`; GET `/people/v2/field_data` cannot write.
363
+
364
+ Publishing POST `/publishing/v2/episodes/{episode_id}/generate_download_url`
365
+ is refused before transport because it mints a private signed link that cannot
366
+ be returned. Webhooks POST
367
+ `/webhooks/v2/webhook_subscriptions/{webhook_subscription_id}/rotate_secret`
368
+ is also refused: its new signing key stays withheld, so rotation cannot be
369
+ completed on the receiver through this connection. Perform required key
370
+ rotation through the provider's own credential-management workflow.
371
+
372
+ | Removed tool | Indexed replacement | Old arguments / join recipe |
373
+ | ------------------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
374
+ | `add_person_email` | POST `/people/v2/people/{personId}/emails` | JSON:API `Email`; `address`, `location` (Home default), `primary` attributes. |
375
+ | `add_person_phone_number` | POST `/people/v2/people/{personId}/phone_numbers` | `PhoneNumber`; `number`, `location` (Mobile default), `primary`. |
376
+ | `list_lists` | GET `/people/v2/lists` | `name` → `where[name]`; `order` unchanged. |
377
+ | `list_list_people` | GET `/people/v2/lists/{listId}/people` | `include=emails,phone_numbers`. |
378
+ | `run_list` | POST `/people/v2/lists/{listId}/run` | No body; refresh can fire automations. |
379
+ | `add_workflow_card_note` | POST `/people/v2/people/{personId}/workflow_cards/{cardId}/notes` | `WorkflowCardNote`; `note` attribute. |
380
+ | `list_forms` | GET `/people/v2/forms` | `filter=not_archived` unless old `includeArchived` was true. |
381
+ | `list_form_submissions` | GET `/people/v2/forms/{formId}/form_submissions` | `submittedAfter` → `where[created_at][gte]`; `order` (default `-created_at`); `include=form_submission_values,form_fields,person`. |
382
+ | `add_plan_item` | POST `/services/v2/service_types/{serviceTypeId}/plans/{planId}/items` | `Item`; `title`, `length`, `sequence`, `description`; `songId`, `arrangementId`, `keyId`, `servicePosition` → `song_id`, `arrangement_id`, `key_id`, `service_position`. `itemType: header` → `item_type: header`; otherwise omit it. |
383
+ | `list_songs` | GET `/services/v2/songs` | `title`, `author`, `ccliNumber`, `theme` → `where[title]`, `where[author]`, `where[ccli_number]`, `where[themes]`; `order` unchanged. |
384
+ | `list_song_arrangements` | GET `/services/v2/songs/{songId}/arrangements` | `include=keys`. |
385
+ | `list_group_events` | GET `/groups/v2/events` or `/groups/v2/groups/{groupId}/events` | `startsAfter`/`startsBefore` → `where[starts_at][gte]`/`[lt]`; `filter=not_canceled` unless `includeCanceled` was true; `order=starts_at`. |
386
+ | `list_check_in_events` | GET `/check-ins/v2/events` | `name` → `where[name]`; `filter=not_archived` unless `includeArchived` was true. |
387
+ | `list_check_in_event_periods` | GET `/check-ins/v2/events/{eventId}/event_periods` | `startsAfter`/`startsBefore` → `where[starts_at][gte]`/`[lt]`; `order=-starts_at`. |
388
+ | `list_check_ins` | GET `/check-ins/v2/check_ins` or `/check-ins/v2/events/{eventId}/check_ins` | `serviceAfter`/`serviceBefore` → `where[event_period][starts_at][gte]`/`[lt]`; `kind` → `filter`; `order` unchanged. |
389
+ | `list_calendar_event_instances` | GET `/calendar/v2/event_instances` | `startsAfter`/`startsBefore` → `where[starts_at][gte]`/`[lt]`; `eventName` → `where[event_name]`; `order=starts_at`. |
390
+ | `list_signups` | GET `/registrations/v2/signups` | `archived` → `filter` (`unarchived` default; omit for all). |
391
+ | `list_signup_attendees` | GET `/registrations/v2/signups/{signupId}/attendees` | `status` → `filter`; `include=person`. |
392
+ | `list_batches` | GET `/giving/v2/batches` | `status` → `filter`; `order=-updated_at`. |
393
+ | `list_pledge_campaigns` | GET `/giving/v2/pledge_campaigns` | `order=-starts_at`. |
394
+ | `list_pledges` | GET `/giving/v2/pledge_campaigns/{pledgeCampaignId}/pledges` | Person identity remains in relationships; amounts remain cents. |
395
+ | `list_recurring_donations` | GET `/giving/v2/recurring_donations` | `status` → `where[status]`; `include=designations,designations.fund`. |
396
+ | `list_webhook_subscriptions` | GET `/webhooks/v2/webhook_subscriptions` | Use `data` attributes for event name, URL and active state; signing keys remain absent. |
397
+
398
+ Moving an additive named write to `pco_api_write` changes its annotation to
399
+ destructive: every hatch write requires host approval. Paths remain concrete
400
+ `/<app>/v2/...` paths. Metadata-only search/details are reads; a guessed write
401
+ on a read-only endpoint remains refused.
402
+
403
+ Stored credential names remain permanently removed. Private Services calendar
404
+ codes and private attachment/download destinations, opaque webhook event
405
+ payloads and delivery bodies/headers now remain withheld too, including nested
406
+ or included forms. There is no `sensitiveFields` widening option. Documented
407
+ ordinary musical keys and person email signatures remain data. Product
408
+ exclusions still close live People-list and webhook cross-product routes.
409
+ Standard fallback diagnostics replace redundant rate-limit/upstream wording;
410
+ JSON:API diagnostics are complete sentences. Writes are sent once; reconcile
411
+ unknown outcomes with a read.
412
+
413
+ The pinned source describes `send_verification` at the empty People path. That
414
+ single source artifact is omitted from the index; there is no `POST /people/v2`
415
+ operation. Use a reviewed pin update with a documented route to enable it.
416
+ Hatch `per_page` now preserves and enforces the vendor's integer range 1–100
417
+ before transport. Response stream failures now say “Planning Center's
418
+ response body could not be read completely.” Malformed JSON says “Planning
419
+ Center returned malformed JSON.” Both retain `connector_call_failed` and
420
+ unknown write outcomes still require reconciliation.
421
+
422
+ ## Overflow
423
+
424
+ Overflow's standard surface ships in 0.35.0. Update deployment instructions
425
+ and programs that name the retired tools or arguments.
426
+
427
+ | Before | Replacement |
428
+ | -------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
429
+ | `overflow_api_get` | `overflow_api_read` |
430
+ | `overflow_api_mutate` | `overflow_api_write`; remains destructive and host approval rules still apply |
431
+ | `list_tap_events` | `overflow_api_read`, path `/tap/events` |
432
+ | `list_webhooks` | `overflow_api_read`, path `/webhooks` |
433
+ | `list_webhook_event_logs` | `overflow_api_read`, path `/webhooks/<webhookId>/event-logs`; move `webhookId` into the path |
434
+ | Hatch query name/value pairs | A `query` object. Repeated array filters use bracketed keys, for example `{ "statusBucket[]": ["PENDING", "CONFIRMED"] }` |
435
+ | Named-list `page` | Start without a cursor, then pass `page.nextCursor` unchanged as `cursor`; keep `limit` fixed |
436
+ | `raw` on contributions, deposits, refunds, chargebacks, donors, subscriptions, payment methods, campaigns and Tap/event-log reads | Removed. Use the indexed hatch for nonsecret vendor fields beyond the named projection |
437
+ | List keys `contributions`, `deposits`, `refunds`, `chargebacks`, `donors`, `subscriptions`, `paymentMethods`, `campaigns`, `locations` | `items`, beside `page` |
438
+ | Tap `events`, webhook `webhooks`, delivery-log `attempts` | Hatch `data.data`; the hatch body retains the vendor's nested records rather than the retired wrappers' flattened projections |
439
+ | Numbered `page.page`, `page.limit`, `page.totalCount` | `page.hasMore`, optional `page.nextCursor`, and `page.total` only when the vendor states an exact count |
440
+ | Delivery-log top-level `nextCursor` or raw vendor token | Hatch `page.nextCursor`, with `page.param: "cursor"` and `page.in: "query"`; return the signed token in `query.cursor` |
441
+ | Hatch `{ result }` | `{ status, data, page? }`; empty replies have `data: null` |
442
+ | Undocumented `POST /subscriptions` with a body `donorId` | `POST /subscriptions/<donorId>` with the documented creation body, including `paymentMethodId`, `amount` in dollars and the creation frequency spelling such as `month` |
443
+
444
+ `overflow_api_search` and `overflow_api_details` find the 38 reviewed operations
445
+ and their request contracts without reading nonprofit data. Unindexed paths,
446
+ unknown query names and missing required body fields now fail before dispatch.
447
+ Paths remain relative to `/api/v3`; do not include that prefix again. For
448
+ array queries the hatch uses the bracketed spelling the named tools use;
449
+ unbracketed wire framing is not promised. Existing named filter names and
450
+ framing remain.
451
+
452
+ All retained named reads and both call hatches accept narrowing `fields`.
453
+ For a named list these paths address each item; for a hatch they address the
454
+ vendor body, for example `fields: ["data.id", "data.status"]`. Missing declared
455
+ response properties cause a nonempty selection to be refused before sending;
456
+ JSON-string and empty acknowledgements have no selectable object properties.
457
+
458
+ The hatch returns paging metadata before selection can remove it. Put its
459
+ signed `page.nextCursor` back into the parameter named by `page.param`, keeping
460
+ other query arguments and `fields` unchanged. Numbered hatch lists name `page`;
461
+ start by omitting it. Old page numbers and webhook cursors are not continuation
462
+ tokens for the new surface. Payment-method lists gain `limit` and `cursor` even
463
+ though the vendor answers them in one bounded response. A missing vendor count
464
+ may require an empty terminal page; it never creates an estimated `page.total`.
465
+
466
+ `GET /health` still returns its text. Refund initiation accepts its documented
467
+ JSON string, a text/plain acknowledgement, or an empty 2xx acknowledgement,
468
+ including 202/204. Nonempty text/html, binary, other media and JSON-object replies
469
+ fail with an unknown outcome and check-before-repeat guidance. Empty write
470
+ acknowledgements remain valid. Other unexpected non-JSON successes are refused. Webhook keys
471
+ matching `secret|signing|hmac` case-insensitively are permanently removed from
472
+ every webhook reply shape, including nested delivery payloads. Removing `raw` introduces no configurable PII policy:
473
+ the existing lean/full-contact choices remain and the sensitive set is empty.
474
+
475
+ HTTP 422 now uses standard `invalid_args` rather than `connector_call_failed`;
476
+ HTTP 409 remains generic and is not `conflict`. Other classification and write
477
+ settlement rules remain, while messages become complete standalone sentences.
478
+ Writes take no idempotency key and are sent once; reconcile an unknown outcome
479
+ with a read. Setup is in [Maintained provider setup](./providers.md#overflow).
480
+
481
+ ## Vercel
482
+
483
+ The four `vercel_api_search`, `vercel_api_details`, `vercel_api_read` and
484
+ `vercel_api_write` names and `vercel_api_upload` remain. Update programs as follows:
485
+
486
+ | Previous surface | 0.35 replacement |
487
+ | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
488
+ | `delete_project_env_var({projectId,envVarId,teamId})` | `vercel_api_write({method:"DELETE",path:"/v9/projects/<projectId>/env/<envVarId>",query:{teamId}})`; encode each path id as one URI segment. Both calls are destructive; use the host's write route. |
489
+ | Hatch `select` | `fields`, checked before dispatch and applied after safety. Dot paths are rooted in vendor `data`, for example `deployments.uid`. Undeclared response shapes refuse fields. |
490
+ | `list_teams({until})` | `list_teams({cursor:page.nextCursor})`; `limit` remains, default 20/max 100. |
491
+ | Named result `teams` or `variables` | `items`; both list tools return a `page`. Environment metadata is a complete terminal list. |
492
+ | `list_teams.defaultTeamId` | Connection guide context; it was a routing default, not a resource filter. |
493
+ | Hatch `page.next` | Signed `page.nextCursor`; return it unchanged in `query[page.param]`, with `page.in:"query"`. Preserve path, selectors, filters and fields. |
494
+ | `get_runtime_logs.maxRows` | `limit`, default 200/max 1,000. `waitMs` and level filtering remain. |
495
+ | Build-log boolean `truncated`, log-row `textTruncated` | `truncated: string[]` at the result root, such as `events[]`, `events[].text` or `logs[].text`. Runtime `stopped` still explains collection termination. |
496
+ | Undocumented upload text `data.contentType` / `data.bytes` | Removed. JSON-only acknowledgements must be JSON; explicit-byte input and upload `digest` remain. |
497
+ | HTTP 409 → `invalid_args` | Generic `connector_call_failed`; no undocumented conflict meaning. |
498
+
499
+ All named reads now take `fields`; for named lists it selects item properties.
500
+ Search defaults to six hits/max eight and 16 KiB per complete answer; continue
501
+ with its cursor. Details continue losslessly within 32 KiB. No supported versioned
502
+ path syntax changes. Unexpected HTML/text/binary replies to JSON-only operations
503
+ fail rather than report successful writes; an already-dispatched write is not
504
+ resent, and its unknown outcome requires reconciliation. Environment values,
505
+ deployment tokens and integration secrets remain withheld in every reply shape.
506
+
507
+ The reviewed public OpenAPI pin adds four nondeprecated operations and changes
508
+ eight request contracts; six new deprecated operations, including an integration
509
+ secrets PUT, remain uncallable. Configured teamId remains default routing with
510
+ intentional teamId/slug/null overrides, consistently across hatches, named tools
511
+ and uploads. This does not restrict a token's team access. See [Vercel setup](./providers.md#vercel).
512
+
513
+ Numeric hatch `query.until` remains a first-page time-window anchor; continuation
514
+ uses the signed token. Raw opaque vendor tokens cannot replace signed tokens.
515
+ Vendor record-count limits are validated as positive integers before dispatch,
516
+ with a maximum only where the reviewed contract declares one.
517
+
518
+ Raw POST `/v10/projects/{projectId}/env` now raises `invalid_args` for a nonempty
519
+ `failed[]` when nothing was created, including on a 2xx response. The message
520
+ keeps the upsert/update-by-id guidance without inventing HTTP 400. Partial
521
+ batches return both `created` and `failed` through the hatch; a partial named
522
+ upsert reports created ids and failed keys/codes with an unknown outcome.
523
+ Missing acknowledgements fail as unreadable/unknown after one dispatch; reconcile
524
+ before repeating.
525
+
526
+ Documented JSONL billing charges/contract commitments, NDJSON sandbox command
527
+ execution/log reads and stream+json build/runtime logs retain complete-row
528
+ parsing; sandbox file reads retain encoded bytes. These exact operation/media
529
+ exceptions keep the 60-second/8 MiB transport bounds (named logs use 1 MiB).
530
+ GET `/v8/artifacts/{hash}` is explicitly refused because it serves binary bytes
531
+ despite this pin's JSON declaration. Audit-event `drainUrl` is now entirely
532
+ withheld, including credential path components and `?token=` on every shape.
533
+ URL-shaped next-page values retain the data with `page.hasMore:true` and no
534
+ continuation, rather than failing the read.
535
+
536
+ ## GitHub
537
+
538
+ GitHub now exposes seven tools: four `github_api_search`, `github_api_details`,
539
+ `github_api_read`, `github_api_write` hatches plus `list_scopes`, `search_scoped`
540
+ and `merge_pull_request`. Update deployment instructions and programs using
541
+ removed names. The hatch indexes an immutable official API description, with
542
+ reviewed repository reads and the existing release writes. Every operation outside
543
+ that allowlist is refused. The generic hosted MCP connection is still separate.
544
+ [GitHub setup](./providers.md#github) owns App credentials and permissions.
545
+
546
+ | Removed tool | Replacement through `github_api_write` | Argument mapping |
547
+ | ---------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
548
+ | `create_release` | POST `/repos/{owner}/{repo}/releases` | owner/repo into the path; tag_name, target_commitish, name, body, draft and prerelease into body |
549
+ | `update_release` | PATCH `/repos/{owner}/{repo}/releases/{release_id}` | owner/repo/release_id into the path; tag_name, name, body, draft and prerelease into body |
550
+ | `delete_release` | DELETE `/repos/{owner}/{repo}/releases/{release_id}` | owner/repo/release_id into the path; no body |
551
+
552
+ For example, a draft creation is
553
+ `{method:"POST",path:"/repos/alice/widget/releases",body:{tag_name:"v2.3.0",draft:true}}`.
554
+ Release creation previously used a non-destructive write tool; every write hatch
555
+ call is destructive, and the host may ask for confirmation. It is still sent
556
+ once. Release hatch results are `{status,data}`; an empty delete has data:null.
557
+ The `merge_pull_request` name and expected-SHA/same-repository/workflow-write guard
558
+ remain. Its raw PUT route is refused by the write hatch's method schema;
559
+ operation search/details and the write-tool description name `merge_pull_request`. Its PR
560
+ lookup is auxiliary: a failed lookup sends no merge and reports no unknown write
561
+ outcome. A `merged:false` answer now fails instead of returning successful data.
562
+
563
+ `list_scopes` and `search_scoped` replace top-level per_page with limit, and
564
+ page/pages with opaque cursor from page.nextCursor. Supply the same filters and
565
+ limit on continuation. Omission uses 30 and is accepted when the cursor was issued
566
+ with limit 30; repeat other limits explicitly. Mismatches name the expected limit.
567
+ Scopes defaults change from 100 to 30; search stays at 30;
568
+ both cap limit at 100. Old numeric page values and partition-to-page maps are
569
+ refused. Configure the same persistent deployment storage across requests so signed
570
+ cursors can be checked.
571
+
572
+ For list_scopes without owner, the old scopes array becomes items of configured
573
+ grants and remains offline. With owner, old repository strings become item records
574
+ with id, full_name, owner, repo and effective access/workflows. next_page becomes
575
+ page.hasMore/page.nextCursor; an unavailable exact filtered total is omitted.
576
+ Acting identity and configured access are in the connection context.
577
+
578
+ search_scoped changes from partitions containing nested items/next_page/total_count
579
+ to flat `{items,page,incomplete_results}`. Each item is
580
+ `{scope,repository,item}`, where item holds the safe vendor record. One call visits
581
+ one partition page and returns at most limit rows; keep following the single cursor
582
+ across partitions. It no longer fetches up to twenty partitions in one call. The
583
+ twenty-partition and ten-page-per-partition bounds remain, with cumulative
584
+ incomplete_results across continuation. No inexact summed total is reported.
585
+
586
+ Named reads accept fields into each item: `fields:["full_name","id"]` for an
587
+ owner's repositories or `fields:["repository","item.title"]` for search. Hatch
588
+ fields select the vendor response inside data, for example `fields:["id","title"]`
589
+ on an issue list or `fields:["files.filename","files.patch"]` on a commit.
590
+ Unknown roots fail before dispatch, including on writes. Fields only narrow safe
591
+ results; they cannot recover withheld secrets or reduce vendor response bytes.
592
+
593
+ Paged hatch reads return page.hasMore and an opaque page.nextCursor. Pass that
594
+ value as top-level cursor; page.param/page.in describe the restored vendor page
595
+ parameter. Raw query.page is refused on paged hatch operations. Vendor query names
596
+ such as per_page remain inside query, bounded by their documented contract.
597
+ Owner/repo path segments must be canonical GitHub names; URL spellings, escaped
598
+ separators and traversal are refused. Contents paths are canonical relative Git
599
+ paths: `/repos/alice/widget/contents/src/index.ts` reads a nested file, while
600
+ `/repos/alice/widget/contents` lists the root. Empty/dot segments, control
601
+ characters, backslashes and encoded traversal are refused. In `commits/{ref}`
602
+ and `compare/{basehead}`, encode branch-name slashes as `%2F`, for example
603
+ `commits/feature%2Fx` or `compare/main...feature%2Fx`. Owner-prefixed object refs and
604
+ cross-repository compares are refused before authentication. PR-list head filters
605
+ require `login:branch`, for example `head:"alice:feature/x"`; this only filters the
606
+ selected repository's PRs. Bare head branches are refused because GitHub silently
607
+ ignores them. The base filter stays a branch name. No Link or redirect
608
+ URL is followed. Echoes of the configured App private key are withheld too.
609
+
610
+ Inline UTF-8 contents keep GitHub's base64 encoding. Decoded file text and patch
611
+ values are redacted before cuts at 32,768 characters, with paths such as
612
+ `data.content`, `data[].patch` or `data.files[].patch` in top-level truncated.
613
+ Record identifiers remain available. The 4 MiB transport ceiling remains; an
614
+ oversized JSON response fails rather than returning partial JSON. GitHub's own
615
+ missing content/patches and directory/search caps do not establish completeness.
616
+ Raw diff media, binary files, signed download/log/archive routes, uploads,
617
+ Actions secrets/variables, deploy keys, token minting and admin operations are
618
+ refused. Download URLs and permanent secret values remain withheld on every reply.
619
+
620
+ An inaccessible or absent target remains connector_call_failed, since GitHub 404
621
+ cannot prove absence. The shared kit now supplies 400/422 invalid_args, 429 rate_limited
622
+ and read-5xx unavailable fallbacks. GitHub's numeric rate-limit headers retain their
623
+ reviewed meanings; errors never quote vendor bodies. Failed success-body reads
624
+ say the body could not be read completely; malformed JSON retains its own diagnostic.
625
+ Dispatched ambiguous writes remain nonretryable, with write-aware reconciliation
626
+ wording. The guide no longer contains operator setup or hand-written shared
627
+ conventions; construction context and generated Conventions supply those facts.
628
+
629
+ ## Cloudflare
630
+
631
+ All nine tool names remain: `cloudflare_api_search`, `cloudflare_api_details`,
632
+ `cloudflare_api_read`, `cloudflare_api_write`, `cloudflare_api_upload`,
633
+ `verify_credential`, `list_accounts`, `list_zones`, and `graphql_query`.
634
+ Approval classifications do not change: hatch writes and uploads are destructive.
635
+
636
+ - Rename hatch `select` to `fields`. Hatch data now retains the full safe vendor
637
+ envelope: **`data.id` becomes `data.result.id`**, and a result array is
638
+ `data.result`. Select `fields: ["result.id", "result.name"]` (or equivalent
639
+ `result[].id` for list traversal). `fields: ["id"]` on an envelope response is
640
+ refused before any request. Value safety and pin filtering still apply to
641
+ `result`, and `success: false` remains an error rather than returned data.
642
+ - `cloudflare_api_upload` data likewise becomes the envelope: `data.id` → `data.result.id`.
643
+ - On `list_accounts` and `list_zones`, replace `perPage` with `limit` (default
644
+ 20, range 5–50) and numbered `page` with opaque `cursor`. Their noun arrays
645
+ `accounts`/`zones` become `items`. They always return `page.hasMore`; a
646
+ continuing page has `page.nextCursor`, and a terminal page omits it. Exact
647
+ vendor totals appear only when the returned scope supports them. Named tools
648
+ otherwise retain projected shapes; all named reads add narrowing `fields`.
649
+ - Hatch `page.next` becomes signed `page.nextCursor`. Put it unchanged into
650
+ `page.param` at `page.in`; do not send raw vendor page numbers or tokens.
651
+ Preserve the path, filters, page size, selected fields and R2 headers.
652
+ Automatic adapters require an unambiguous pinned `result_info` contract;
653
+ mixed page/cursor or undeclared envelopes retain their vendor query protocol.
654
+ - Operation search defaults to six hits, with maximum eight (previously ten
655
+ and fifty). Search and details expose signed continuation and `truncated`
656
+ paths for labels cut for size; larger details remain recoverable in pages
657
+ or chunks. Refused operations have no callable tool pointer.
658
+ - Documented numeric constraints from the pinned contract now fail before I/O,
659
+ including paging bounds and numeric body fields.
660
+ HTTP 409 is generic `connector_call_failed`, rather than `invalid_args`;
661
+ Cloudflare declares no conflict category. 404 remains `not_found`. 429 keeps
662
+ the reviewed five-minute fallback, overridden by a supplied Retry-After.
663
+ Error wording is complete and includes the HTTP status once.
664
+
665
+ Configured path placeholders, encoded slashes inside KV/R2 keys, closed R2
666
+ headers and reviewed text/SQL/NDJSON/upload framing remain supported. No tool
667
+ argument can widen pin scope or reveal a stored secret. Operator setup is in
668
+ [Cloudflare](./providers.md#cloudflare).
669
+
670
+ ## Gmail
671
+
672
+ Gmail is the approved exception to decision 0014's four-hatch default:
673
+ `gmail_api_search`, `gmail_api_details` and `gmail_api_read` are added;
674
+ there is no `gmail_api_write`. Draft writes remain exclusively in
675
+ `create_draft` and `update_draft`; sending is never available. All nine named
676
+ tools remain. Write classifications and host approval routes stay the same.
677
+ The index displays all 79 pinned methods but admits only eleven reviewed
678
+ reads; refused draft operations point to the guarded named tools.
679
+
680
+ - Replace `get_message({ messageId, raw: true })` with
681
+ `gmail_api_read({ path: "/messages/{id}", query: { format: "full" } })`.
682
+ Replace `{id}` with a message id from an earlier read.
683
+ Read the vendor resource from the tool result's `data`; the hatch envelope
684
+ also has `status` and optional `page`. `raw` is removed, including `raw: false`.
685
+ - `search_threads.threads`, `list_drafts.drafts` and `list_labels.labels` become
686
+ `items`. `get_thread` remains a record with `messages` and `page`.
687
+ `search_threads.resultSizeEstimate` is removed; hatch JSON can retain the
688
+ vendor estimate, which is never an exact total.
689
+ - `search_threads` and `list_drafts` use `limit`/`cursor` and return
690
+ `{ items, page }`; terminal pages omit `nextCursor` instead of returning null.
691
+ `list_labels` returns all labels in one bounded, terminal page from one read;
692
+ `truncated` reports any labels omitted by the byte bound. It takes no paging
693
+ arguments. Every named read accepts `fields`,
694
+ applied to the projected record or to each list item. `get_thread` retains
695
+ `page` after selection; follow `page.nextCursor` while `page.hasMore` is true.
696
+ - Replace `bodyTruncated`, `contentTruncated`, `omittedIds`,
697
+ `labelIdsOmitted`, `attachmentsOmitted` and `labelsOmitted` with top-level
698
+ `truncated` dot paths such as `body`, `content`, `messages[].body` and
699
+ `items[].labelIds[]`. Charset notices, unavailable-body reasons and saved
700
+ state remain semantic metadata. `truncated` survives `fields` selection even
701
+ when the selected result omits the cut value.
702
+ - Discard every pre-upgrade private cursor. New cursors are signed and bound
703
+ to the connection, owner and call. Connections with mapped Workspace
704
+ subjects also bind the admitted caller and pool owner. Named content cursors
705
+ additionally bind earlier safe content. For paged hatches omit `query.pageToken` on the first
706
+ call and pass `page.nextCursor` as top-level `cursor` thereafter, keeping
707
+ path, query and fields fixed. A nonempty token can continue an empty page.
708
+ - Copied Message-ID, In-Reply-To and References require bounded ASCII
709
+ headers, including valid modern and legacy RFC forms. A damaged, withheld,
710
+ NUL, non-ASCII or control-containing threading
711
+ header refuses the draft before POST/PUT. Valid threading bytes are kept.
712
+ - Standard Google error facts and fallback codes replace the legacy message
713
+ mapper. Read 5xx failures are `unavailable`; incomplete response bodies are
714
+ distinguished from malformed complete JSON. A dispatched draft write is
715
+ never replayed and an unknown outcome requires reconciliation.
716
+
717
+ No new privacy-widening argument or scope is introduced. MIME decoding,
718
+ attachment-id rotation, size provenance, one-MiB download limits and refusal
719
+ to replace drafts with carried content remain enforced. The read hatch uses
720
+ paths relative to `/gmail/v1/users/me` and cannot select another subject,
721
+ origin, transport format or caller header.
722
+
723
+ ## Google Docs
724
+
725
+ Keep all six named tool names. `get_document.raw` is removed: replace
726
+ `get_document({documentId:"doc_123",raw:true})` with
727
+ `docs_api_read({path:"/documents/doc_123",query:{includeTabsContent:true}})`.
728
+ Its full vendor document is the hatch value's `data`, rather than a named
729
+ result's `raw`. `get_document` now accepts `fields` for projected result paths;
730
+ hatch `fields` selects vendor-body paths.
731
+
732
+ New `docs_api_search`, `docs_api_details`, `docs_api_read` and `docs_api_write`
733
+ use paths relative to `/v1`: `/documents/doc_123`, never `/v1/documents/doc_123`.
734
+ Operation search never lists a user's documents; continue using Drive.
735
+ For a generic batch, call `docs_api_write` with `method:"POST"`,
736
+ `path:"/documents/doc_123:batchUpdate"`, and
737
+ `body:{requests:[{updateTextStyle:{range:{startIndex:1,endIndex:5},textStyle:{bold:true},fields:"bold"}}],writeControl:{requiredRevisionId:"revision_from_read"}}`.
738
+ The revision and 1–100 supported GA request kinds are mandatory. Preview
739
+ comments/suggestions remain refused. Generic create sends only Google's title
740
+ payload; use `create_document` for create plus initial text and partial recovery.
741
+
742
+ Unsigned `e:` index cursors no longer work; start an indexed read without a
743
+ cursor, then pass `page.nextCursor` with the same arguments. Cursors bind the
744
+ connection, owner, read arguments and document content/revision. Terminal
745
+ pages omit `nextCursor` instead of returning null. There is no vendor pageToken
746
+ protocol for Docs. Fields may narrow between named pages.
747
+
748
+ `tabs[].textTruncated` becomes top-level `truncated:["tabs[0].text"]` (using
749
+ the actual tab index); `repliesTruncated` and `replyCount` are removed, with
750
+ batch size cuts reported as `truncated:["replies[]"]`. Count displayed replies
751
+ with `replies.length`. `notRendered` and `dropped` remain semantic facts.
752
+
753
+ A 404 now reports `connector_call_failed` because absence and sharing denial
754
+ are ambiguous. Standard read 5xx failures report `unavailable`; revision facts
755
+ retain `conflict`. Write outcomes remain conservative and non-retryable after
756
+ dispatch. Additive create/append/insert catalog entries retain the explicit
757
+ `destructiveHint:false` annotation and remain writes.
758
+ Every new hatch
759
+ write requires the host's destructive-write route. No new privacy switch or
760
+ scope is introduced.
761
+
762
+ Docs image `contentUri` values now read `[redacted]` because possession grants
763
+ the requester's temporary image access. Authored image `sourceUri` and text links
764
+ remain available; `fields` cannot widen this boundary.
765
+
766
+ ## Google Sheets
767
+
768
+ All nine named tools remain. Four coverage tools are added:
769
+ `sheets_api_search`, `sheets_api_details`, `sheets_api_read` and
770
+ `sheets_api_write`. Search searches operations, not spreadsheet files or cells;
771
+ use Drive to find a workbook. Update deployment instructions and programs:
772
+
773
+ | Previous use | Replacement |
774
+ | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
775
+ | `get_spreadsheet({ spreadsheetId, raw: true })` | `sheets_api_read({ method: "GET", path: "/spreadsheets/<id>" })`; vendor JSON is under `data` in the hatch result. |
776
+ | Named read without selection | Same call; optional `fields` narrows its projected record. |
777
+ | Terminal `page.nextCursor: null` | Absent `nextCursor` when `page.hasMore` is false. |
778
+ | `namedRangesOmitted` | `truncated: ["namedRanges[]"]`. |
779
+ | `truncatedCells` or per-range `truncated`/`omittedRows` | Top-level `truncated: ["valueRanges[].values"]`; use content continuation or read a cut cell separately. |
780
+ | `repliesSummarized`/`repliesOmitted` | `truncated: ["replies[]"]`, with the saved-edit recovery `note`. |
781
+ | Batch preview comment or external data-source kinds | Refused before dispatch; use a separately authorized Google workflow. |
782
+
783
+ No named tool or other argument is renamed. Named values reads retain the
784
+ `valueRanges` record and `maxCells`, `maxBytes`, `maxCellChars` content budgets.
785
+ All named reads and hatch reads/writes support result `fields`. Cell values
786
+ remain available; there is no privacy-widening argument or empty configurable
787
+ sensitive set. Hatch paths omit `/v4`; values-range `%3A` is accepted, while
788
+ encoded action separators and unreserved path characters are refused.
789
+ Repeated ranges remain arrays in vendor `query.ranges`. Vendor masks under
790
+ `query.fields` or batch `fields` are distinct from result-selection `fields`.
791
+
792
+ The read hatch admits seven explicit methods, including three read-only POSTs;
793
+ the destructive write hatch admits ten methods with the same value limits and
794
+ batch-kind guards. Every hatch write uses the host's destructive route.
795
+ Additive create/add/append catalog entries retain the explicit
796
+ `destructiveHint:false` annotation and remain writes. Generic append can
797
+ explicitly select `OVERWRITE`; named append stays pinned to `INSERT_ROWS`.
798
+ No scope expansion, revision guarantee, idempotency key or write replay is added.
799
+ Standard kit errors now distinguish incomplete reads from malformed complete
800
+ responses and use its shared status fallbacks. An inaccessible or unknown id
801
+ remains ambiguous (`connector_call_failed`); a 404 does not prove absence.
802
+
803
+ Existing `get_values` continuations must restart at the first page after this
804
+ upgrade. New cursors are signed and bound to the deployment store, connection,
805
+ spreadsheet, ranges and render options. Mapped Workspace subjects also bind
806
+ the admitted caller. A cursor from another mapped caller or with edited
807
+ positions is refused before authentication or dispatch. Keep the same caller
808
+ and read arguments when continuing.
809
+ Named-read `fields` selection always retains `truncated`; `get_values` also
810
+ retains its content `page`, so narrowed pages remain complete and resumable.
811
+
812
+ ## Google Forms
813
+
814
+ Keep all six named tools. Four tools are added: `forms_api_search`,
815
+ `forms_api_details`, `forms_api_read` and destructive `forms_api_write`.
816
+ The ten-method frozen inventory is discoverable; only the five existing
817
+ Forms methods execute. Publish settings and all watch methods stay refused.
818
+ Scopes and named-write approval classifications are unchanged.
819
+ The additive `create_form` catalog retains `destructiveHint:false` and remains
820
+ a write.
821
+
822
+ - Replace `get_form({ formId, raw: true })` with
823
+ `forms_api_read({ path: "/forms/<formId>" })`. The vendor Form is in
824
+ `data`, including `info`, `settings`, `items` and `revisionId`. There is no
825
+ `raw` argument or privacy-widening argument on any tool.
826
+ - Read `list_responses` rows from `items`, replacing `responses`; its
827
+ redundant top-level `formId` is removed. `fields` on this tool selects
828
+ paths inside each item. `fields` on `get_form` and `get_response` selects
829
+ paths in the projected record. Content `get_form` pages preserve `page` metadata
830
+ even when selecting other fields. Cuts retain `truncated`, and a selected
831
+ response retains `omittedQuestionIds` for recovery. Invalid roots fail before authentication.
832
+ - Terminal `page` omits `nextCursor` instead of returning null. Discard old
833
+ private cursors after upgrading: content and response cursors now carry a
834
+ signature bound to the connection, credential owner and delegated caller,
835
+ retaining revision
836
+ and mid-page response-fingerprint checks. `fields` may narrow between
837
+ named pages. Continue hatch lists with top-level `cursor`, never raw
838
+ `query.pageToken`; hatch cursors bind the full call, including `fields`.
839
+ Hatch `query.pageSize` must be an integer from 1 to 5000; omit it for the default.
840
+ - `truncated: string[]` reports cut paths, replacing the batch's boolean
841
+ `truncated` and the form's `moreOptions`/`moreQuestions` counts. Continued
842
+ grids retain `questionsFrom`; `omittedQuestionIds` remains a recovery list
843
+ for targeted reads. Text cut markers remain alongside the path report.
844
+ - Indexed batch writes use `POST /forms/<formId>:batchUpdate`, with
845
+ `body: { requests, writeControl: { requiredRevisionId } }`. Use
846
+ `forms_api_details` for nested request contracts. The named wrapper still
847
+ accepts `requests` and `requiredRevisionId` at top level. Both require
848
+ 1–100 requests with exactly one reviewed kind each. Paths are relative to
849
+ `/v1`, never `/v1/forms/...`; create uses `POST /forms`,
850
+ `body.info` and optional `query.unpublished`.
851
+ - Hatch results are `{ status, data, page? }`. `fields` selects safe data;
852
+ `query.fields` is Google's separate wire mask, preserving paging metadata.
853
+ In `execute_code`, unwrap the host result before reading the hatch envelope:
854
+
855
+ ```js
856
+ const { data: reply } = await connecta.call("forms.forms_api_read", {
857
+ path: "/forms/form_123",
858
+ });
859
+ return { title: reply.data.info.title };
860
+ ```
861
+
862
+ Here the first `data` is Connecta's result delivery; `reply` is the hatch
863
+ envelope, and `reply.data` is Google's Form. Hatch list continuation lives
864
+ in `reply.page`, alongside the vendor body.
865
+
866
+ - Standard kit error sentences replace the legacy Google outcome wording.
867
+ Ambiguous 404 remains `connector_call_failed`; structured revision
868
+ preconditions remain `conflict`. A dispatched uncertain write is never
869
+ replayed. Re-read its target before deciding whether another edit is needed.
870
+
871
+ Respondent emails, answers and quiz data remain user data under the same
872
+ boundary on every read. Temporary `Image.contentUri` destinations are now
873
+ permanently withheld, including expanded forms in batch replies. Ordinary
874
+ responder links, image source URLs and feedback links remain available.
875
+
876
+ ## Google Slides
877
+
878
+ All 15 named tools remain. Four indexed tools are added:
879
+ `slides_api_search`, `slides_api_details`, `slides_api_read`, and
880
+ `slides_api_write`. The write hatch is always destructive; the four existing
881
+ additive named tools (`create_presentation`, `create_slide`, `create_comment`
882
+ and `create_comment_reply`) retain the explicit `destructiveHint:false` catalog
883
+ annotation and remain writes. Every write is sent once; a revision precondition
884
+ does not make a replay safe.
885
+
886
+ | Previous program | Replacement |
887
+ | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
888
+ | `get_presentation({presentationId, raw: true})` | `slides_api_read({path: "/presentations/deck1"})`; vendor JSON is in `data` |
889
+ | `get_page({presentationId, pageObjectId, raw: true})` | `slides_api_read({path: "/presentations/deck1/pages/slide1"})` |
890
+ | `list_comments({presentationId, raw: true})` | `slides_api_read({path: "/presentations/deck1", query: {commentsViewMode: "COMMENTS_VIEW_MODE_INCLUDED"}})` |
891
+ | `list_layouts().layouts`, `list_comments().threads` | `.items`; `fields` selects paths inside each item |
892
+ | Terminal `page.nextCursor: null` | Terminal `page: {hasMore: false}`; cursor is absent |
893
+ | Private content cursors | Restart once; new cursors are signed and bound to the connection, owner, delegated caller and content state |
894
+ | Boolean `truncated`, reply `cut`, `elementsNotShown`, `layoutsNotShown`, `repliesNotShown`, `revisionIdNotShown` | `truncated: string[]` names the affected paths; continuation and reconciliation advice remain |
895
+ | Projected `get_presentation.pageSize` | `canvasSize` describes slide width and height; structural hatch JSON retains vendor `data.pageSize` |
896
+ | Image, SheetsChart and StretchedPictureFill `contentUrl` from `raw:true` | `"[redacted]"` in the replacement hatch; possession grants temporary access. `sourceUrl` remains available; the named thumbnail keeps its reviewed link |
897
+ | List `total` | `page.total` retains the exact count of returned vendor content |
898
+
899
+ Every named read gains `fields`; it narrows the safe result while retaining
900
+ `page` and `truncated` metadata on the result and `truncated` on selected nested
901
+ records. Hatch `fields` narrows `data`, while `query.fields` is Google's own wire
902
+ mask. Named
903
+ text and speaker-note cursors continue through `get_page`; they are separate
904
+ from Connecta's large-result delivery handles. Reuse the deployment storage
905
+ between calls so signed continuation remains valid across requests.
906
+
907
+ Operation details for presentations.get retain `presentationsId` (plural):
908
+ `GET /presentations/{presentationsId}`. Page methods and batch updates use
909
+ `presentationId`. Substitute one encoded id segment in the concrete `path`;
910
+ do not supply these path names as query arguments or add `/v1` again.
911
+ Spell colons and unreserved characters literally in hatch paths; encode other
912
+ characters within one id segment. Named tools handle their own id encoding.
913
+
914
+ For example, the retained `batch_update_presentation({presentationId:
915
+ "deck1", requiredRevisionId: "rev1", requests: [...]})` corresponds to
916
+ `slides_api_write({method: "POST", path: "/presentations/deck1:batchUpdate",
917
+ body: {requests: [...], writeControl: {requiredRevisionId: "rev1"}}})`.
918
+ Both keep the 1–100 request bound and the 49 reviewed kinds. The complete
919
+ five-method inventory does not admit generic thumbnails or new preview
920
+ operations. Use `get_slide_thumbnail` for its reviewed private link.
921
+
922
+ Mixed comment/deck batches keep `commentUpdateState`, every created id and
923
+ separate-save advice. Hatch `warnings` keep the observed comment-save state
924
+ (or its absence) and advice after `fields` selection; vendor `data` is unchanged.
925
+ Missing confirmation of comment saves is not a reason to replay an accepted
926
+ deck edit. Read both outcomes and report them separately.
927
+ HTTP 404 remains ambiguous between absence and permission. Standard errors
928
+ retain explicit auth, permission and structured revision-conflict meanings;
929
+ incomplete responses now say the response could not be read completely.
930
+
931
+ See [Google Slides setup](./providers.md#google-slides).
932
+
933
+ ## Google Drive
934
+
935
+ All 17 named tools retain their names and approval routing. The `create_folder`
936
+ and `restore_file` catalog entries retain their explicit
937
+ `destructiveHint:false` annotation and remain writes. Add
938
+ `drive_api_search`, `drive_api_details`, `drive_api_read` and destructive
939
+ `drive_api_write`; these discover 64 pinned operations and execute 13 reviewed
940
+ JSON metadata methods. Permission creation `POST /files/{fileId}/permissions`
941
+ is refused by the hatch: use `share_file` for every new grant. Permanent delete,
942
+ ownership transfer, watches, credential minting and hatch media remain refused.
943
+
944
+ - Read `items` instead of `files` from `search_files`/`list_folder_items`,
945
+ `permissions` from `list_permissions`, or `drives` from `list_shared_drives`.
946
+ Keep named `limit`/`cursor`; terminal `page.nextCursor` is omitted instead of
947
+ null. Old cursors must be discarded; new cursors bind the connection, owner,
948
+ delegated caller and listing arguments, including the source-page checks.
949
+ Named-list `maxBytes` may change or be omitted and `fields` may narrow between
950
+ pages; neither participates in the cursor argument binding.
951
+ - Read `truncated` dot paths instead of `truncatedFields`. A true
952
+ `contentTruncated` becomes `truncated: ["content"]`; false is omitted.
953
+ Every named read accepts `fields`; for lists these paths address each item.
954
+ `incompleteSearch` remains its own completeness fact.
955
+ - For rare metadata, call `drive_api_read` with e.g.
956
+ `{ path: "/files/file_123/revisions", query: { pageSize: 20 } }`.
957
+ Hatch results are `{ status, data, page? }`. Pass `page.nextCursor` as
958
+ top-level `cursor`, never a raw `query.pageToken`. Google's `query.fields`
959
+ mask and Connecta's output `fields` are separate.
960
+ - For a hatch rename use `drive_api_write` with
961
+ `{ method: "PATCH", path: "/files/file_123", body: { name: "Review.pdf" } }`.
962
+ Use named `create_file`/`update_file_content` for multipart/media transport
963
+ and `get_file_content` for content. No existing tool or argument was renamed
964
+ or removed, and no `raw` argument existed on Drive.
965
+ - A dispatched write timeout now reports `write_outcome_unknown` instead of
966
+ `connector_call_failed`, with `uncertainCall` evidence. Re-read the affected
967
+ item before another write.
968
+ - Standard error facts and outcome wording replace legacy Google settlement.
969
+ Failed auxiliary parents lookups no longer claim a move's unknown outcome.
970
+ The actual PATCH stays call-owned. Withheld or altered MIME, shortcut or
971
+ parents decision inputs fail before the next request. Whole binary
972
+ withholding remains conservative; private resource keys and download
973
+ destinations cannot be restored through `fields`.
974
+
975
+ See [Google Drive setup](./providers.md#google-drive) for delegation and limits.