@zackbart/connecta 0.40.0 → 0.42.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 (195) hide show
  1. package/CHANGELOG.md +148 -0
  2. package/bin/connecta.mjs +26 -17
  3. package/bin/meta-tool-names.d.mts +3 -1
  4. package/bin/meta-tool-names.mjs +4 -1
  5. package/bin/version.mjs +1 -1
  6. package/dist/activity.d.ts +32 -5
  7. package/dist/activity.js +32 -6
  8. package/dist/advertised-schema.js +15 -0
  9. package/dist/agent-observation.js +24 -2
  10. package/dist/agent-routes.js +33 -44
  11. package/dist/auth/clerk.d.ts +6 -1
  12. package/dist/auth/clerk.js +16 -0
  13. package/dist/auth/cloudflare-access.js +49 -7
  14. package/dist/auth/downstream-oauth/consent.js +79 -29
  15. package/dist/auth/downstream-oauth/grant-store.js +58 -7
  16. package/dist/auth/downstream-oauth/refresh-coordinator.js +4 -1
  17. package/dist/auth/downstream-oauth/refresh-records.js +6 -5
  18. package/dist/auth/downstream-oauth.js +15 -4
  19. package/dist/auth/oauth-request-not-sent.js +4 -0
  20. package/dist/auth/static-oauth.js +77 -39
  21. package/dist/auth-elicitation.js +118 -61
  22. package/dist/authorization-handoff.js +36 -3
  23. package/dist/catalog-cache.js +352 -43
  24. package/dist/catalog-freshness.js +25 -0
  25. package/dist/catalog-service.js +408 -78
  26. package/dist/catalog.js +216 -62
  27. package/dist/config-defaults.d.ts +2 -1
  28. package/dist/config-defaults.js +4 -1
  29. package/dist/config.d.ts +53 -21
  30. package/dist/config.js +56 -17
  31. package/dist/connectors/remote-mcp/call.js +1 -1
  32. package/dist/connectors/remote-mcp/catalog.js +52 -28
  33. package/dist/connectors/remote-mcp/connection.js +113 -22
  34. package/dist/connectors/remote-mcp/oauth.js +2 -2
  35. package/dist/connectors/remote-mcp/resources.js +5 -2
  36. package/dist/connectors/remote-mcp/transport.js +24 -6
  37. package/dist/connectors/remote-mcp.js +14 -5
  38. package/dist/credential-contract.d.ts +3 -1
  39. package/dist/describe-config.d.ts +4 -2
  40. package/dist/describe-config.js +1 -0
  41. package/dist/discovery-health.js +26 -11
  42. package/dist/downstream-input.js +11 -2
  43. package/dist/errors.d.ts +60 -4
  44. package/dist/errors.js +88 -3
  45. package/dist/execute.js +491 -202
  46. package/dist/executor-admission.js +2 -0
  47. package/dist/executor-contract.js +6 -0
  48. package/dist/executor-result.js +3 -3
  49. package/dist/executors/quickjs-child.js +14 -5
  50. package/dist/executors/quickjs-runtime.d.ts +2 -0
  51. package/dist/executors/quickjs-runtime.js +37 -20
  52. package/dist/executors/quickjs.js +24 -7
  53. package/dist/guarded-transport.js +2 -0
  54. package/dist/guest-functions.js +5 -4
  55. package/dist/guest-runtime.js +37 -1
  56. package/dist/guest-types.d.ts +18 -0
  57. package/dist/http/client.js +14 -2
  58. package/dist/http/errors.js +9 -4
  59. package/dist/http/fields.js +17 -5
  60. package/dist/http/hatch.js +11 -3
  61. package/dist/http/node-transport.js +110 -4
  62. package/dist/http/oauth.js +17 -6
  63. package/dist/http/paging.js +1 -1
  64. package/dist/http/provider.js +2 -6
  65. package/dist/http/vendor.js +6 -1
  66. package/dist/index.d.ts +1 -1
  67. package/dist/index.js +15 -21
  68. package/dist/invocation-failure.js +28 -0
  69. package/dist/invocation.js +167 -64
  70. package/dist/membership.d.ts +1 -1
  71. package/dist/meta-output.js +24 -18
  72. package/dist/meta-tool-names.d.ts +1 -1
  73. package/dist/meta-tool-names.js +1 -1
  74. package/dist/meta-tools.js +286 -73
  75. package/dist/module-contracts.d.ts +3 -1
  76. package/dist/native-recovery.js +4 -1
  77. package/dist/native-tools.js +177 -55
  78. package/dist/node.d.ts +7 -0
  79. package/dist/node.js +85 -4
  80. package/dist/oauth-handoff.js +53 -43
  81. package/dist/operation-activity.js +104 -0
  82. package/dist/operation-vocabulary.js +6 -0
  83. package/dist/operator-record.d.ts +9 -1
  84. package/dist/operator-record.js +16 -0
  85. package/dist/operator-ui/generated.js +2 -2
  86. package/dist/program-result.js +2 -0
  87. package/dist/program-source.js +1 -1
  88. package/dist/program-writes.js +112 -19
  89. package/dist/provider.d.ts +1 -14
  90. package/dist/provider.js +0 -3
  91. package/dist/providers/_shared/google/kit.js +2 -2
  92. package/dist/providers/_shared/google/workspace.d.ts +1 -1
  93. package/dist/providers/breeze/api.js +2 -2
  94. package/dist/providers/breeze/index.js +1 -1
  95. package/dist/providers/breeze/skill.generated.js +1 -1
  96. package/dist/providers/ccb/api.js +2 -2
  97. package/dist/providers/ccb/index.js +1 -1
  98. package/dist/providers/ccb/skill.generated.js +1 -1
  99. package/dist/providers/cloudflare/api.js +2 -2
  100. package/dist/providers/cloudflare/index.js +3 -1
  101. package/dist/providers/cloudflare/skill.generated.js +1 -1
  102. package/dist/providers/docs/index.js +1 -1
  103. package/dist/providers/docs/skill.generated.js +1 -1
  104. package/dist/providers/drive/index.js +1 -1
  105. package/dist/providers/drive/skill.generated.js +1 -1
  106. package/dist/providers/forms/index.js +2 -1
  107. package/dist/providers/forms/skill.generated.js +1 -1
  108. package/dist/providers/github/api.js +98 -6
  109. package/dist/providers/github/index.js +8 -3
  110. package/dist/providers/github/lib/auth.d.ts +3 -1
  111. package/dist/providers/github/lib/auth.js +43 -12
  112. package/dist/providers/github/lib/discovery.js +11 -1
  113. package/dist/providers/github/lib/operations.js +8 -0
  114. package/dist/providers/github/safety.js +39 -0
  115. package/dist/providers/github/skill.generated.js +1 -1
  116. package/dist/providers/github/tools.js +12 -5
  117. package/dist/providers/gmail/index.js +2 -1
  118. package/dist/providers/gmail/skill.generated.js +1 -1
  119. package/dist/providers/granola/index.js +1 -1
  120. package/dist/providers/granola/skill.generated.js +1 -1
  121. package/dist/providers/overflow/index.js +3 -1
  122. package/dist/providers/overflow/skill.generated.js +1 -1
  123. package/dist/providers/planning-center/index.js +12 -6
  124. package/dist/providers/planning-center/lib/constants.d.ts +1 -1
  125. package/dist/providers/planning-center/skill.generated.js +1 -1
  126. package/dist/providers/quickbooks/api.js +28 -25
  127. package/dist/providers/quickbooks/index.js +3 -6
  128. package/dist/providers/quickbooks/lib/writes.js +55 -0
  129. package/dist/providers/quickbooks/safety.js +17 -5
  130. package/dist/providers/quickbooks/skill.generated.js +1 -1
  131. package/dist/providers/sheets/index.js +2 -1
  132. package/dist/providers/sheets/skill.generated.js +1 -1
  133. package/dist/providers/slides/index.js +3 -3
  134. package/dist/providers/slides/skill.generated.js +1 -1
  135. package/dist/providers/stripe/index.js +2 -2
  136. package/dist/providers/stripe/skill.generated.js +1 -1
  137. package/dist/providers/tithely/index.js +2 -1
  138. package/dist/providers/tithely/skill.generated.js +1 -1
  139. package/dist/providers/vercel/api.js +3 -2
  140. package/dist/providers/vercel/skill.generated.js +1 -1
  141. package/dist/registry.d.ts +36 -4
  142. package/dist/registry.js +142 -30
  143. package/dist/resource-read.js +21 -2
  144. package/dist/result-preview.js +210 -0
  145. package/dist/result-seal.js +168 -0
  146. package/dist/route-names.js +53 -0
  147. package/dist/routes/activity-context.js +1 -0
  148. package/dist/routes/activity-disclosure.js +26 -4
  149. package/dist/routes/activity.js +2 -1
  150. package/dist/routes/connect.js +21 -13
  151. package/dist/routes/mcp.js +83 -35
  152. package/dist/routes/shared.d.ts +6 -0
  153. package/dist/routes/ui-config.js +1 -1
  154. package/dist/routes/ui-data.js +3 -2
  155. package/dist/runtime/call.js +15 -10
  156. package/dist/runtime/native-storage.js +12 -0
  157. package/dist/runtime/request-reads.js +66 -14
  158. package/dist/runtime/request-scope.js +38 -2
  159. package/dist/runtime/run.js +4 -1
  160. package/dist/sent-secrets.d.ts +20 -0
  161. package/dist/sent-secrets.js +49 -1
  162. package/dist/skill-origin.js +16 -0
  163. package/dist/skills.js +213 -57
  164. package/dist/storage/d1-driver.js +33 -5
  165. package/dist/storage/keys.js +16 -7
  166. package/dist/storage/sql-native.js +60 -3
  167. package/dist/storage/sql.js +6 -0
  168. package/dist/timing-trace.js +84 -0
  169. package/dist/tool-safety.d.ts +33 -0
  170. package/dist/tool-safety.js +51 -15
  171. package/dist/types.d.ts +36 -0
  172. package/dist/url-safety.js +38 -20
  173. package/dist/usage-guide.js +14 -13
  174. package/dist/utility-recovery.js +33 -0
  175. package/dist/validate.js +29 -10
  176. package/dist/version.d.ts +1 -1
  177. package/dist/version.js +1 -1
  178. package/dist/worker.js +60 -15
  179. package/documentation/architecture.md +152 -43
  180. package/documentation/auth.md +160 -53
  181. package/documentation/code-mode.md +396 -119
  182. package/documentation/deploying.md +35 -10
  183. package/documentation/hosted-mcp-migration.md +9 -3
  184. package/documentation/integrating.md +27 -5
  185. package/documentation/meta-tools.md +761 -157
  186. package/documentation/operating.md +91 -4
  187. package/documentation/operator-ui.md +51 -2
  188. package/documentation/providers.md +34 -20
  189. package/examples/worker/README.md +3 -3
  190. package/guides/how-it-works.md +2 -1
  191. package/guides/safety-and-trust.md +1 -3
  192. package/package.json +10 -8
  193. package/templates/node/AGENTS.md +3 -3
  194. package/templates/node/README.md +1 -1
  195. package/templates/node/package.json +1 -1
@@ -12,7 +12,7 @@ Use your host's tool search, call a known operation directly, and follow its
12
12
  repair or authorization handoff. Use `execute_code` for combined work when
13
13
  listed; without code, page results through the listed `read_result` tool.
14
14
 
15
- Meta endpoints expose six top-level tools. Read [the tool table](./meta-tools.md#the-six-tools)
15
+ Meta endpoints expose six top-level tools, plus `execute_read_code` on a writable `/mcp` or `/mcp/<pool>`. Read [the tool table](./meta-tools.md#the-meta-tools)
16
16
  for exact arguments and result envelopes. Follow the endpoint's supplied
17
17
  instructions and `skills` usage guide for deployment-specific context.
18
18
 
@@ -22,7 +22,7 @@ instructions and `skills` usage guide for deployment-specific context.
22
22
  | Discover a tool, chain calls, combine services, or reduce a result | `execute_code` |
23
23
  | One known write on a writable endpoint | `call_destructive_tool` |
24
24
  | Obtain connector instructions | `skills` with the returned guide name |
25
- | Start a required authentication handoff | `authorize_connector`, using the returned recovery action |
25
+ | Start an authentication handoff no error has given you | `authorize_connector`, using the returned recovery action |
26
26
 
27
27
  Whether the endpoint is read-only or writable is part of its tool
28
28
  descriptions. On a writable endpoint, programs and `call_destructive_tool` may
@@ -109,7 +109,9 @@ MCP request bodies default to a 4 MiB limit on every endpoint. Deployment code
109
109
  can set `admission.requests.maxBodyBytes`; `describeConfig()` reports its value
110
110
  and source. An oversized body returns 413 before tool dispatch. See
111
111
  [request admission and body limits](./architecture.md#admission-in-two-places)
112
- for Node's separate pre-auth buffer and the listen-classification bound.
112
+ for Node's separate pre-auth buffer and the listen-classification bound. A `503`
113
+ from Node before auth means all in-flight bodies together passed
114
+ [`maxInFlightBodyBytes`](./deploying.md#start-on-node).
113
115
 
114
116
  Direct calls may return a preview and a result handle. Page the handle through
115
117
  `connecta.result` in a program using the returned offset and byte limits, or
@@ -125,7 +127,9 @@ which URIs may be read. Connector guides and native skills are described in
125
127
 
126
128
  ## Recover without replaying a write
127
129
 
128
- Read typed failures and their `nextAction`. Authorization recovery can point
130
+ Read typed failures and their `nextAction`. An auth error that carries a link
131
+ says so in `nextAction.url`: give that link to the user unchanged and stop, with
132
+ no further call. Authorization recovery can point
129
133
  to consent, operator credential setup, or deployment configuration. Discovery
130
134
  and status do not begin consent on their own. Follow
131
135
  [authorization recovery](./meta-tools.md#authorization-recovery),
@@ -162,3 +166,86 @@ and [execution](https://github.com/zackbart/connecta/blob/main/src/execute.ts).
162
166
  and [guest-contract tests](https://github.com/zackbart/connecta/blob/main/test/guest-api-contract.test.ts)
163
167
  check the contracts. Executor-specific evidence is indexed in
164
168
  [code-mode verification](./code-mode.md#verification).
169
+
170
+ ## Sample payload-free timing on Workers
171
+
172
+ Set `timingTraceSampleRate` in deployment code passed to `createConnecta`:
173
+
174
+ ```ts
175
+ const app = createConnecta({
176
+ // ...the deployment's connectors, storage, auth and executor
177
+ timingTraceSampleRate: 0.1, // sample 10% of MCP requests; default 0 (off)
178
+ });
179
+ ```
180
+
181
+ The rate must be a finite number from 0 through 1. Set 1 for a short diagnostic
182
+ window, then return it to 0. Sampling is independent of the caller's
183
+ `diagnostics` argument. Enable Workers observability logs in the deployment's
184
+ Wrangler configuration (`observability.logs.enabled: true`). Its own sampling
185
+ may reduce captured records further. The configured logger receives
186
+ `connecta.timing` and one structured object when the MCP response body closes;
187
+ `logger: "silent"` suppresses these records too. Consume or close streaming
188
+ responses to finish their trace. An isolate-first-request flag means the first
189
+ MCP request that reaches tracing in that isolate, including unsampled requests;
190
+ it does not measure module boot.
191
+
192
+ Each version-1 record contains elapsed request time, the first-request flag,
193
+ weak-reference availability and aggregate operation families. Each family has
194
+ `count`, `durationMs`, `bytes`, `statements`, `items` and `absent` totals.
195
+ `catalog.accepted` counts complete accepted catalogs, serialized bytes and tools. Invocation
196
+ `catalog`, `admission`, `connector` and `result` durations reuse the existing
197
+ `diagnostics` segments. `catalog.cache.lookup` counts cache probes; `catalog.cache.hit` counts accepted
198
+ unexpired entries. Lookups without hits can include misses, expiry, invalid
199
+ entries or interrupted reads; they are not proof of live relisting.
200
+ `catalog.validated.hit`/`miss` report immutable validation reuse.
201
+ `catalog.decode` counts JSON decodes and their UTF-8 input bytes;
202
+ `catalog.validate` and `catalog.intake` count those stages without timing them.
203
+ These three count-only families always have `durationMs: 0`.
204
+ `catalog.chunks` records accepted chunk bytes and counts. These counters do not
205
+ identify a connector, owner or private/public partition.
206
+ Concurrent spans can overlap; do not sum them as wall time.
207
+ `memo.hit`, `memo.miss` and `memo.fresh` describe the request-read memo
208
+ (`absent` counts null values, not cache failures). `d1.read`, `d1.write` and
209
+ `d1.batch` count physical native D1 trips and SQL statements, including
210
+ failed attempts. Batch count is one trip; statements is the batch length.
211
+ All native D1 work carrying the request context shares these totals, including
212
+ admission, credential and catalog work. Comparing them with `catalog` duration
213
+ (the diagnostics `catalogMs` segment) does not isolate catalog storage.
214
+ Returned D1 bytes measure serialized application results, not Cloudflare's wire
215
+ encoding. Memo bytes measure UTF-8 stored values. Result bytes use the existing
216
+ invocation measurement. No keys, tool names, owner identity, arguments, results,
217
+ credentials or error text enter the record. Records retain totals only.
218
+
219
+ On production Workers, `performance.now()` advances only across I/O. Durations
220
+ are I/O-spanning elapsed observations, not CPU attribution: zero is ambiguous,
221
+ and CPU work can appear in a later I/O interval. D1 durations are therefore not
222
+ pure storage latency. Use counts, sizes, cache outcomes and the isolate-first-request
223
+ flag to compare warm direct and one-call program requests with the same catalog.
224
+ For per-invocation CPU, use Workers' invocation telemetry field
225
+ [`$workers.cpuTimeMs`](https://developers.cloudflare.com/workers/observability/query-builder/).
226
+ Deeper attribution requires [CPU profiling](https://developers.cloudflare.com/workers/runtime-apis/performance/).
227
+
228
+ Only work carrying the MCP request's native context contributes D1 counters;
229
+ standalone operator/background or custom Promise adapter work is outside that
230
+ request trace. Sampling does not add reads, change TTLs, bypass generation or
231
+ credential fences, or start authorization.
232
+
233
+ For example, query a ten-minute window for a neutral Worker `assistant` (replace
234
+ the millisecond timestamps with the window you need):
235
+
236
+ ```sh
237
+ cf --profile assistant o11y telemetry query \
238
+ --query-id 00000000-0000-4000-8000-000000000001 \
239
+ --view events --limit 100 \
240
+ --timeframe-from 1793700000000 --timeframe-to 1793700600000 \
241
+ --parameters-order-by-value count --parameters-order-by-order desc \
242
+ --parameters-calculations '[{"operator":"count","alias":"count"}]' \
243
+ --parameters-filters '[{"key":"$workers.scriptName","operation":"eq","type":"string","value":"assistant"}]'
244
+ ```
245
+
246
+ Select `connecta.timing` messages in the returned events and inspect their
247
+ structured operation totals. Use the profile belonging to your deployment.
248
+ The example reads telemetry only; it changes no Worker settings.
249
+
250
+ The example passes CLI dry-run validation; server acceptance has not been verified.
251
+ Use `--dry-run` to validate the request locally without querying telemetry.
@@ -287,7 +287,7 @@ stack each row into a card.
287
287
 
288
288
  ### Activity
289
289
 
290
- Counts for the loaded history (calls, failed, tools, catalog changes), also
290
+ Counts for the loaded history (calls, failed, tools, catalog changes, and opt-in operations), also
291
291
  in its accessible summary, and a strip of calls over time with failures in
292
292
  red when the calls span more than a minute.
293
293
 
@@ -304,7 +304,9 @@ red when the calls span more than a minute.
304
304
  row lists what was recorded: result, how it ran, classification, exact
305
305
  duration and size, caller, stable caller id, request id, client, and
306
306
  connecta version. Unrecorded fields are left out. Catalog changes are rows
307
- with added, removed and changed counts.
307
+ with added, removed and changed counts. Opt-in operation rows use fixed names
308
+ (Search, Describe, Result page, Skill read, Program) and an Operation detail;
309
+ they do not count as calls, failed calls, friction, tools or last calls.
308
310
  - **Empty.** "No calls yet" with Refresh, or "No matches" with Clear filters.
309
311
 
310
312
  ### Navigation, gates and recovery
@@ -767,6 +769,53 @@ names, descriptions or schemas enter the event. Private catalog changes require
767
769
  a matching principal owner even when the connector uses shared auth. Empty credential declarations
768
770
  report `credential_required` before running a connector status or catalog probe.
769
771
 
772
+ ### Opt in to operation history
773
+
774
+ Set `operations: true` on the existing activity module, for example
775
+ `activity: activityHistory({ store, operations: true })`, where `store` is the
776
+ configured platform activity store. The default is off: existing deployments
777
+ emit no operation rows. Each admitted search, describe, result page, skill read
778
+ and whole program adds one event through the existing detached sink. Workers
779
+ attach its promise to `waitUntil`; Node does not await it in the response path.
780
+ This adds storage writes and retention cleanup work for every operation.
781
+
782
+ Rows use `kind: "operation"`, `source: "execute_code"`, and a fixed operation
783
+ name. They contain duration, outcome, a checked error code, returned page
784
+ byte count when already measured, and host-call counts for a program. No query, tool
785
+ address supplied by a caller, skill name, result ID, code, arguments, result
786
+ contents or raw error text enters the row. Custom history readers must exclude
787
+ operation rows from call/friction counts. The public kind union adds
788
+ `"operation"`; exhaustive consumers may need a new case even when their
789
+ runtime configuration leaves recording off.
790
+
791
+ Operation disclosure is deliberately conservative:
792
+
793
+ - The existing maintainer permission and optional `readGate` still apply.
794
+ - Scope means every connector visible to the admitted endpoint, rather than
795
+ just the connectors named by a particular argument. A single-connector scope
796
+ uses that connector ID; other scopes use a reserved operation ID internally.
797
+ - Every connector in that scope must still be visible through a whole-connector
798
+ grant to both the reader and the recorded pool. Address-only grants do not
799
+ disclose operations. Removed pools/connectors or invalid scope metadata
800
+ withhold the entire row.
801
+ - All human operations are owner-only. Scopes containing personal auth,
802
+ caller-bound auth or a dynamically discovered catalog are also owner-only,
803
+ since static configuration cannot prove the catalog public. Owner-only rows
804
+ require the recorded principal basis and an exact match to the reader's
805
+ admitted principal ID and namespace. An agent without a provable admitted
806
+ human owner has those rows withheld.
807
+ - Shared machine operations over statically declared catalogs are visible to
808
+ maintainers only when the complete scope passes those checks. This policy
809
+ can withhold single-connector work performed on a mixed endpoint.
810
+
811
+ Existing D1 and SQLite activity tables need no new columns. The existing
812
+ kind-tagged metadata text slot stores the checked operation scope and counts;
813
+ legacy tool and catalog-change rows keep their format. The timeline shows
814
+ operations separately and excludes them from call totals, friction, tool
815
+ counts, call strips and last-call overlays.
816
+
817
+ ### Activity actor labels
818
+
770
819
  Activity label resolvers receive an optional `AbortSignal`. Pass it to user-directory
771
820
  fetches and stop work when it aborts: the reader has left or the label lookup
772
821
  budget has expired. Clerk label lookups follow the same lifetime and discard
@@ -275,12 +275,12 @@ discovery for your deployment's catalog.
275
275
  </details>
276
276
 
277
277
  <details>
278
- <summary>QuickBooks Online (10 tools)</summary>
278
+ <summary>QuickBooks Online (11 tools)</summary>
279
279
 
280
280
  [Setup](#quickbooks-online). **API source:** Hand-authored endpoint contracts. No vendored OpenAPI document.
281
281
 
282
282
  - **Named reads:** `get_company_info`, `get_record`, `get_report`, `search_records`.
283
- - **Named writes:** `create_customer`, `create_invoice`, `update_customer`.
283
+ - **Named writes:** `create_customer`, `create_invoice`, `update_customer`, `update_unsent_invoice`.
284
284
  - **API reads:** `quickbooks_api_details`, `quickbooks_api_read`, `quickbooks_api_search`.
285
285
  - **API writes:** None.
286
286
 
@@ -409,9 +409,11 @@ path the current response lacks is never refused, and the selection omits it.
409
409
  `fields` entry matched nothing anywhere in a nonempty response. Each warning
410
410
  names the entry position, the segment where matching stopped and the
411
411
  properties the operation's contract declares there, for example
412
- `fields/1 matched nothing in this response after value safety and privacy
413
- filtering, at segment 2; declared there: id, name.` Where the contract
414
- declares none, such as inside an open map, it says so. A warning never lists
412
+ `fields/1 matched nothing after filtering, at segment 2; declared there: id,
413
+ name.` Filtering means value safety and privacy filtering. The list stops at
414
+ 160 characters with a count of the rest, and a later miss stopping at the same
415
+ place says `same as fields/1`. Where the contract declares none, such as inside
416
+ an open map, it says so. A warning never lists
415
417
  the response's own keys, which in an open map such as `metadata` are data, and
416
418
  never repeats the submitted path. A path that matched in any listed item, a
417
419
  path that runs past a scalar (selection keeps the scalar), and any path of an
@@ -941,10 +943,20 @@ Enable only vendor permissions needed by the workflows: Metadata read for
941
943
  repository lookup; Issues read for issues/comments/labels; Pull requests read
942
944
  for PRs/reviews/review comments/changed files/PR commits; Contents read for
943
945
  repository commits/comparisons/contents/releases; Actions read for workflows,
944
- runs and jobs. Release writes require Contents write. The guarded merge retains
946
+ runs and jobs; Checks read for check runs, suites and annotations; Commit statuses
947
+ read for commit statuses. Release writes require Contents write. The guarded merge retains
945
948
  Contents, Pull requests and Workflows write. Code search retains Contents read
946
949
  and GitHub's own search restrictions. Each operation token is narrowed to its
947
950
  reviewed permission and repository IDs; an org grant does not permit org admin.
951
+ A resource 403 that carries no rate-limit header is `provider_permission_denied`, with
952
+ no credential handoff, naming the repository and the permission the endpoint accepts.
953
+ It establishes the refusal, not its cause: a missing permission is likely, but a policy,
954
+ an unmarked secondary rate limit or a lockout gives the same answer, so its message
955
+ ends with credential checks for when every call is refused. A refused token mint is a
956
+ permission gap only when GitHub's installation record lacks the requested permission;
957
+ otherwise a 422 is a neutral `connector_call_failed` and a 403 stays
958
+ `provider_permission_denied` with its causes open. A 401, an unusable key or a 403 on
959
+ the App's own installation list is `auth_required`.
948
960
 
949
961
  The four github_api tools cover a pinned operation index with a bounded reviewed
950
962
  repository read and release-write allowlist. All other operations are refused.
@@ -963,8 +975,8 @@ File contents retain base64 encoding; the character bound applies after decoding
963
975
  Use `/repos/alice/widget/contents/src/index.ts` for a nested file and
964
976
  `/repos/alice/widget/contents` for the root directory. Contents paths must be
965
977
  canonical relative paths, without dot/empty segments, backslashes or encoded
966
- traversal. Encode branch-name slashes as `%2F` in `commits/{ref}` and
967
- `compare/{basehead}`. Owner-prefixed object refs and cross-repository compares are
978
+ traversal. Encode branch-name slashes as `%2F` in `commits/{ref}`, its check and
979
+ status reads, and `compare/{basehead}`. Owner-prefixed object refs and cross-repository compares are
968
980
  refused before authentication. PR-list head filters require `login:branch`, for
969
981
  example `head:"alice:feature/x"`; they filter the selected repository's PRs.
970
982
  Bare head branches are refused because GitHub silently ignores them. The base
@@ -1520,18 +1532,20 @@ Creation fixes EmailStatus to `NotSet` and IPN/online/card/ACH/PayPal/Affirm
1520
1532
  payment flags to false, accepts no email fields, and never calls a send endpoint.
1521
1533
  Intuit's documented autosend path requires company opt-in, enabled online
1522
1534
  payments and `NeedToSend` with BillEmail; the fixed creation body withholds
1523
- those request conditions. Invoice updates remain unavailable because retaining
1524
- an existing send-ready state is not established safe, and resetting that state
1525
- would change existing payment settings. Deletes, voids, delivery, payment
1526
- execution, batch and other accounting writes remain unavailable. The API hatch
1527
- refuses POSTs even when named writes are enabled.
1528
-
1529
- Sparse field preservation, a current SyncToken and requestid do not establish
1530
- that an invoice update cannot send email. For example, changing only DueDate
1531
- on an invoice with NeedToSend and enabled card/ACH payments retains those
1532
- settings; omitting email fields does not disable them. Do not reset delivery or
1533
- payment settings to work around the unavailable update, or replace the invoice
1534
- with a new one. No unsent-only update tool is currently exposed either.
1535
+ those request conditions.
1536
+
1537
+ `update_unsent_invoice` changes only DocNumber. Supply caller-observed Id and
1538
+ SyncToken and an explicit docNumber. It reads the US company and invoice,
1539
+ requires USD, explicit NotSet, no DeliveryInfo and every IPN/online/card/ACH/
1540
+ PayPal/Affirm payment flag explicitly false. Unknown state, send-ready or
1541
+ delivered state and stale versions fail before POST; no newer version is
1542
+ substituted. The sparse body preserves omitted delivery/payment fields.
1543
+ No date edits are exposed. Applying autosend prerequisites to updates is an
1544
+ inference, not an update-specific Intuit no-email guarantee. NotSet and absent
1545
+ delivery information cannot prove there was never historical delivery.
1546
+ Do not reset state to qualify or replace an invoice to bypass a refusal.
1547
+ Deletes, voids, delivery, payment execution, batch and other accounting writes
1548
+ remain unavailable. The API hatch refuses POSTs even when named writes are enabled.
1535
1549
 
1536
1550
  Each write requires `requestId`, a stable identifier for the exact intent,
1537
1551
  unique across all requests/tools for this company: 1–50 ASCII letters, digits,
@@ -10,7 +10,7 @@ runnable Worker steps.
10
10
  A deployable Worker that aggregates a downstream remote MCP and an in-code HTTP
11
11
  API connector, guarded by Cloudflare Access. It uses three Cloudflare resources
12
12
  and nothing else: one D1 database (`CONNECTA_DB`) for every piece of state, the
13
- Worker Loader binding (`LOADER`) behind the six-tool surface, which requires
13
+ Worker Loader binding (`LOADER`) behind the meta-tool surface, which requires
14
14
  the Workers Paid plan, and two secrets: `DOWNSTREAM_TOKEN` (the example remote
15
15
  MCP connector's token) and `CREDENTIAL_ENCRYPTION_KEY` (the credential vault).
16
16
 
@@ -493,7 +493,7 @@ from `@zackbart/connecta/d1`. See [Activity history](#activity-history-optional)
493
493
  Omit the module and store wiring to record no history and show no Activity tab. Diagnostics remain independent; `logger: "silent"` suppresses
494
494
  them explicitly.
495
495
 
496
- Verify MCP health and the exact six tools with the following. Doctor reads
496
+ Verify MCP health and the exact tool list with the following. Doctor reads
497
497
  `/health` through Access with the service credentials, then checks `/agent/ci`
498
498
  with the `cta_` token alone:
499
499
 
@@ -526,7 +526,7 @@ LOADER: Cloudflare.WorkerLoader(),
526
526
  `@zackbart/connecta/worker`. The adapter constructs the upstream
527
527
  `DynamicWorkerExecutor` with only the loader and a deadline, and disposes each
528
528
  run's loader and RPC handles when its lease ends, even if the guest has not
529
- settled. It serves the six-tool surface. Its admission pool is per isolate:
529
+ settled. It serves the meta-tool surface. Its admission pool is per isolate:
530
530
  two runs, eight queued for up to 60 seconds, then a retryable
531
531
  `executor_overloaded`. Pass `admission` to `workerExecutor()` to change it; see
532
532
  [code mode](../../documentation/code-mode.md#deploy-time-capability). Do not
@@ -77,7 +77,7 @@ account choices, including the Google Workspace exception.
77
77
  ## Finding a tool and using it are separate steps
78
78
 
79
79
  First the agent finds an action and learns what information it needs.
80
- Then it calls that action. The default connection gives the AI app six small
80
+ Then it calls that action. The default connection gives the AI app a few small
81
81
  **meta-tools** to help it do this without loading every service's tools into
82
82
  the conversation.
83
83
 
@@ -87,6 +87,7 @@ the conversation.
87
87
  | `call_tool` | Call a discovered action that reads data. |
88
88
  | `call_destructive_tool` | Call a discovered action that changes data, under the app's approval policy. |
89
89
  | `execute_code` | Combine discovery, actions, and a small answer in a program. |
90
+ | `execute_read_code` | The same for read-only work. It refuses anything that changes data. |
90
91
  | `authorize_connector` | Request the permitted account-connection handoff. |
91
92
  | `skills` | Read guidance for using a connection. |
92
93
 
@@ -74,9 +74,7 @@ credentials as another boundary where possible.
74
74
  The Eve helper defaults to unattended authorized writes. For interactive use,
75
75
  `gateWrites: true` asks before tools not marked read-only; an explicit Eve
76
76
  approval policy takes precedence. The AI app owns approvals. It may ask based
77
- on an earlier tool label. If a
78
- read becomes a write, a writable pool can execute it without a fresh
79
- approval; a read-only pool refuses it. Connecta does not pause a program to
77
+ on an earlier tool label. If a native tool becomes a write, its cached read name is refused before dispatch. Refresh `tools/list` and use the write's name; approval follows the host's policy. Read-only pools refuse writes. `execute_read_code` is the exception an app need not ask about: it refuses anything that can change data. It can still read, so a page's text can try to talk an agent into sending data through a read action; see [read programs](../documentation/meta-tools.md#read-programs). Connecta does not pause a program to
80
78
  ask a person partway through.
81
79
 
82
80
  See [read-only setup](../documentation/integrating.md#make-one-connection-read-only)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zackbart/connecta",
3
- "version": "0.40.0",
3
+ "version": "0.42.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "One MCP to rule them all — a single MCP endpoint aggregating many downstream connectors behind a code-first surface of six meta-tools.",
@@ -173,8 +173,8 @@
173
173
  "build:operator-ui": "node scripts/build-operator-ui.mjs",
174
174
  "check:operator-ui": "node scripts/build-operator-ui.mjs --check",
175
175
  "check:clerk-sdk": "node scripts/build-clerk-sdk.mjs --check",
176
- "build": "pnpm run providers:generate && pnpm run clean && tsc -p tsconfig.build.json && node scripts/prune-declarations.mjs",
177
- "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.operator-ui.json --noEmit",
176
+ "build": "node scripts/eval-runtime.mjs --build",
177
+ "typecheck": "node node_modules/typescript-native/bin/tsc -p tsconfig.json --noEmit && node node_modules/typescript-native/bin/tsc -p tsconfig.operator-ui.json --noEmit",
178
178
  "test": "vitest run",
179
179
  "test:browser:install": "playwright install chromium",
180
180
  "test:browser": "playwright test",
@@ -182,19 +182,20 @@
182
182
  "pretest:browser:snapshots": "pnpm run build:operator-ui",
183
183
  "test:node": "vitest run --config vitest.config.node.ts",
184
184
  "test:workers": "vitest run --project workers",
185
+ "check:node-shards": "node scripts/check-node-shards.mjs",
185
186
  "check:docs": "node scripts/check-doc-links.mjs",
186
187
  "check:lint": "oxlint -D correctness --report-unused-disable-directives .",
187
188
  "check:unused": "knip --include dependencies,unlisted,exports,nsExports,types,nsTypes",
188
- "check:examples": "tsc -p tsconfig.template.node.json && tsc -p tsconfig.examples.worker.json",
189
+ "check:examples": "node node_modules/typescript/bin/tsc -p tsconfig.template.node.json && node node_modules/typescript/bin/tsc -p tsconfig.examples.worker.json",
189
190
  "check:security": "pnpm audit --prod --audit-level moderate",
190
191
  "check:package": "node scripts/check-package.mjs",
191
192
  "check:declarations": "node scripts/check-declarations.mjs --dist .",
192
193
  "check:bundle": "node scripts/bundle-size.mjs",
193
194
  "providers:check": "tsx scripts/drift-check.mjs --specs --manual",
194
- "eval:selftest": "tsx eval/selftest.ts",
195
- "eval:agent": "tsx eval/run-agent.ts",
196
- "eval:smoke": "tsx eval/run-smoke.ts",
197
- "eval:outcomes": "tsx eval/run-outcomes.ts",
195
+ "eval:selftest": "node --import tsx scripts/eval-runtime.mjs selftest",
196
+ "eval:agent": "node --import tsx scripts/eval-runtime.mjs run-agent",
197
+ "eval:smoke": "node --import tsx scripts/eval-runtime.mjs run-smoke",
198
+ "eval:outcomes": "node --import tsx scripts/eval-runtime.mjs run-outcomes",
198
199
  "preeval:outcomes": "node scripts/generate-version.mjs && pnpm run build:operator-ui",
199
200
  "eval:perf": "tsx eval/run-perf.ts",
200
201
  "eval:report": "tsx eval/report.ts",
@@ -279,6 +280,7 @@
279
280
  "react-dom": "^19.3.1",
280
281
  "tsx": "^4.23.15",
281
282
  "typescript": "^6.0.3",
283
+ "typescript-native": "npm:typescript@7.0.2",
282
284
  "undici": "6.29.1",
283
285
  "vite": "^8.3.4",
284
286
  "vitest": "^5.0.4",
@@ -10,10 +10,10 @@ tokens, upgrading, and diagnosis with `connecta doctor` to their procedures.
10
10
 
11
11
  - Edit `src/connecta.config.ts` for connectors, authentication, storage, public
12
12
  URL, and optional modules. `src/index.ts` only starts it.
13
- - Keep `executor: quickJsExecutor()` for the prescribed six-tool code-first
14
- surface. Keep the required `readOnly` choice in the config: `false` lets
13
+ - Keep `executor: quickJsExecutor()` for the prescribed code-first
14
+ meta-tool surface. Keep the required `readOnly` choice in the config: `false` lets
15
15
  `call_destructive_tool` and programs write and annotates `execute_code` as
16
- a write; `true` omits write tools from search and describe and refuses every
16
+ a write, with `execute_read_code` listed for read-only programs at `/mcp`; `true` omits write tools from search and describe and refuses every
17
17
  write call. Named pools inherit it unless they set their own `readOnly`.
18
18
  Approval belongs to the MCP host. Do not configure the removed `trust` or
19
19
  `execute.approval`.
@@ -272,7 +272,7 @@ npm run typecheck
272
272
  CONNECTA_TOKEN='cta_REPLACE_WITH_RETURNED_SECRET' npm run doctor
273
273
  ```
274
274
 
275
- Doctor checks health, the executor, and the exact prescribed six-tool
275
+ Doctor checks health, the executor, and the exact prescribed meta-tool
276
276
  model-facing surface by running a harmless sandbox program. It reads the bearer
277
277
  from `CONNECTA_TOKEN`; it never accepts the secret as a command-line argument.
278
278
  Remote URLs must use HTTPS.
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@clerk/backend": "^3.12.0",
21
- "@zackbart/connecta": "0.40.0",
21
+ "@zackbart/connecta": "0.42.0",
22
22
  "quickjs-emscripten": "0.32.0",
23
23
  "undici": "6.29.1"
24
24
  },