@zackbart/connecta 0.15.0 → 0.16.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.
- package/AGENTS.md +28 -15
- package/CHANGELOG.md +493 -0
- package/README.md +19 -4
- package/bin/connecta.mjs +44 -3
- package/dist/access-tokens.d.ts +0 -1
- package/dist/access-tokens.js +0 -1
- package/dist/activity.d.ts +50 -2
- package/dist/activity.js +34 -1
- package/dist/apps-shell.d.ts +0 -1
- package/dist/apps-shell.js +0 -1
- package/dist/auth/bearer.d.ts +0 -1
- package/dist/auth/bearer.js +0 -1
- package/dist/auth/clerk.d.ts +0 -1
- package/dist/auth/clerk.js +45 -9
- package/dist/auth/downstream-oauth.d.ts +0 -1
- package/dist/auth/downstream-oauth.js +0 -1
- package/dist/call-admission.d.ts +0 -1
- package/dist/call-admission.js +0 -1
- package/dist/catalog-drift.d.ts +99 -0
- package/dist/catalog-drift.js +251 -0
- package/dist/catalog-fingerprint.d.ts +0 -1
- package/dist/catalog-fingerprint.js +0 -1
- package/dist/catalog-limits.d.ts +0 -1
- package/dist/catalog-limits.js +0 -1
- package/dist/catalog-service.d.ts +0 -1
- package/dist/catalog-service.js +0 -1
- package/dist/catalog.d.ts +0 -1
- package/dist/catalog.js +0 -1
- package/dist/concurrency.d.ts +0 -1
- package/dist/concurrency.js +0 -1
- package/dist/connector-scope.d.ts +0 -1
- package/dist/connector-scope.js +0 -1
- package/dist/connectors/api.d.ts +29 -21
- package/dist/connectors/api.js +45 -19
- package/dist/connectors/guarded-fetch.d.ts +106 -0
- package/dist/connectors/guarded-fetch.js +289 -0
- package/dist/connectors/remote-mcp.d.ts +0 -1
- package/dist/connectors/remote-mcp.js +0 -1
- package/dist/credentials.d.ts +0 -1
- package/dist/credentials.js +0 -1
- package/dist/errors.d.ts +0 -1
- package/dist/errors.js +0 -1
- package/dist/execute.d.ts +0 -1
- package/dist/execute.js +0 -1
- package/dist/executor-admission.d.ts +11 -1
- package/dist/executor-admission.js +28 -1
- package/dist/executor-result.d.ts +0 -1
- package/dist/executor-result.js +0 -1
- package/dist/executors/quickjs-child.d.ts +0 -1
- package/dist/executors/quickjs-child.js +0 -1
- package/dist/executors/quickjs-protocol.d.ts +0 -1
- package/dist/executors/quickjs-protocol.js +0 -1
- package/dist/executors/quickjs-runtime.d.ts +0 -1
- package/dist/executors/quickjs-runtime.js +0 -1
- package/dist/executors/quickjs.d.ts +0 -1
- package/dist/executors/quickjs.js +2 -1
- package/dist/favicon.d.ts +0 -1
- package/dist/favicon.js +0 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +24 -7
- package/dist/invocation.d.ts +0 -1
- package/dist/invocation.js +0 -1
- package/dist/json-schema.d.ts +0 -1
- package/dist/json-schema.js +0 -1
- package/dist/mcp-result.d.ts +0 -1
- package/dist/mcp-result.js +0 -1
- package/dist/meta-tools.d.ts +0 -1
- package/dist/meta-tools.js +0 -1
- package/dist/node.d.ts +0 -1
- package/dist/node.js +0 -1
- package/dist/operator-ui/generated.d.ts +2 -3
- package/dist/operator-ui/generated.js +3 -4
- package/dist/operator-ui/model.d.ts +10 -1
- package/dist/operator-ui/model.js +0 -1
- package/dist/operator-ui/view.d.ts +167 -0
- package/dist/operator-ui/view.js +270 -0
- package/dist/providers/cloudflare.d.ts +5 -2
- package/dist/providers/cloudflare.js +435 -328
- package/dist/providers/linear.d.ts +26 -5
- package/dist/providers/linear.js +32 -60
- package/dist/providers/mixpanel.d.ts +35 -4
- package/dist/providers/mixpanel.js +53 -78
- package/dist/providers/notion.d.ts +0 -1
- package/dist/providers/notion.js +87 -42
- package/dist/providers/stripe.d.ts +13 -1
- package/dist/providers/stripe.js +31 -59
- package/dist/registry.d.ts +34 -2
- package/dist/registry.js +85 -5
- package/dist/retired-toolkits.d.ts +0 -1
- package/dist/retired-toolkits.js +0 -1
- package/dist/routes/access-tokens.d.ts +0 -1
- package/dist/routes/access-tokens.js +0 -1
- package/dist/routes/activity.d.ts +0 -1
- package/dist/routes/activity.js +0 -1
- package/dist/routes/credentials.d.ts +0 -1
- package/dist/routes/credentials.js +0 -1
- package/dist/routes/mcp.d.ts +0 -1
- package/dist/routes/mcp.js +0 -1
- package/dist/routes/oauth.d.ts +0 -1
- package/dist/routes/oauth.js +0 -1
- package/dist/routes/shared.d.ts +2 -1
- package/dist/routes/shared.js +0 -1
- package/dist/routes/ui.d.ts +0 -1
- package/dist/routes/ui.js +0 -1
- package/dist/server.d.ts +0 -1
- package/dist/server.js +11 -1
- package/dist/skills.d.ts +0 -1
- package/dist/skills.js +0 -1
- package/dist/storage/file.d.ts +0 -1
- package/dist/storage/file.js +0 -1
- package/dist/storage/memory.d.ts +0 -1
- package/dist/storage/memory.js +0 -1
- package/dist/timeout.d.ts +0 -1
- package/dist/timeout.js +0 -1
- package/dist/tool-safety.d.ts +0 -1
- package/dist/tool-safety.js +0 -1
- package/dist/types.d.ts +45 -1
- package/dist/types.js +0 -1
- package/dist/ui.d.ts +0 -1
- package/dist/ui.js +13 -137
- package/dist/validate.d.ts +13 -15
- package/dist/validate.js +24 -11
- package/dist/version.d.ts +1 -2
- package/dist/version.js +1 -2
- package/documentation/architecture.md +186 -5
- package/documentation/auth.md +11 -0
- package/documentation/call-admission.md +142 -6
- package/documentation/cloudflare.md +95 -27
- package/documentation/code-mode.md +12 -12
- package/documentation/connector-guides.md +172 -5
- package/documentation/connectors.md +98 -7
- package/documentation/linear.md +26 -9
- package/documentation/mcp-ui-design.md +2 -2
- package/documentation/mixpanel.md +48 -16
- package/documentation/notion.md +16 -0
- package/documentation/operations.md +283 -5
- package/documentation/operator-ui.md +120 -5
- package/documentation/provider-audit.md +160 -0
- package/documentation/provider-conventions.md +631 -0
- package/documentation/request-admission.md +167 -5
- package/documentation/rich-output-design.md +1 -2
- package/documentation/stripe.md +27 -12
- package/ethos.md +14 -9
- package/examples/worker/README.md +96 -12
- package/examples/worker/src/index.ts +46 -1
- package/examples/worker/wrangler.jsonc +14 -1
- package/package.json +4 -5
- package/templates/node/.dockerignore +10 -0
- package/templates/node/.env.example +40 -3
- package/templates/node/AGENTS.md +11 -1
- package/templates/node/Dockerfile +49 -0
- package/templates/node/README.md +117 -2
- package/templates/node/docker-compose.yml +39 -0
- package/templates/node/package.json +1 -1
- package/templates/node/src/file-activity.ts +182 -0
- package/templates/node/src/index.ts +80 -4
- package/assets/connecta-clay-hero.png +0 -0
- package/dist/access-tokens.d.ts.map +0 -1
- package/dist/access-tokens.js.map +0 -1
- package/dist/activity.d.ts.map +0 -1
- package/dist/activity.js.map +0 -1
- package/dist/apps-shell.d.ts.map +0 -1
- package/dist/apps-shell.js.map +0 -1
- package/dist/auth/bearer.d.ts.map +0 -1
- package/dist/auth/bearer.js.map +0 -1
- package/dist/auth/clerk.d.ts.map +0 -1
- package/dist/auth/clerk.js.map +0 -1
- package/dist/auth/downstream-oauth.d.ts.map +0 -1
- package/dist/auth/downstream-oauth.js.map +0 -1
- package/dist/call-admission.d.ts.map +0 -1
- package/dist/call-admission.js.map +0 -1
- package/dist/catalog-fingerprint.d.ts.map +0 -1
- package/dist/catalog-fingerprint.js.map +0 -1
- package/dist/catalog-limits.d.ts.map +0 -1
- package/dist/catalog-limits.js.map +0 -1
- package/dist/catalog-service.d.ts.map +0 -1
- package/dist/catalog-service.js.map +0 -1
- package/dist/catalog.d.ts.map +0 -1
- package/dist/catalog.js.map +0 -1
- package/dist/concurrency.d.ts.map +0 -1
- package/dist/concurrency.js.map +0 -1
- package/dist/connector-scope.d.ts.map +0 -1
- package/dist/connector-scope.js.map +0 -1
- package/dist/connectors/api.d.ts.map +0 -1
- package/dist/connectors/api.js.map +0 -1
- package/dist/connectors/remote-mcp.d.ts.map +0 -1
- package/dist/connectors/remote-mcp.js.map +0 -1
- package/dist/credentials.d.ts.map +0 -1
- package/dist/credentials.js.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/execute.d.ts.map +0 -1
- package/dist/execute.js.map +0 -1
- package/dist/executor-admission.d.ts.map +0 -1
- package/dist/executor-admission.js.map +0 -1
- package/dist/executor-result.d.ts.map +0 -1
- package/dist/executor-result.js.map +0 -1
- package/dist/executors/quickjs-child.d.ts.map +0 -1
- package/dist/executors/quickjs-child.js.map +0 -1
- package/dist/executors/quickjs-protocol.d.ts.map +0 -1
- package/dist/executors/quickjs-protocol.js.map +0 -1
- package/dist/executors/quickjs-runtime.d.ts.map +0 -1
- package/dist/executors/quickjs-runtime.js.map +0 -1
- package/dist/executors/quickjs.d.ts.map +0 -1
- package/dist/executors/quickjs.js.map +0 -1
- package/dist/favicon.d.ts.map +0 -1
- package/dist/favicon.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/invocation.d.ts.map +0 -1
- package/dist/invocation.js.map +0 -1
- package/dist/json-schema.d.ts.map +0 -1
- package/dist/json-schema.js.map +0 -1
- package/dist/mcp-result.d.ts.map +0 -1
- package/dist/mcp-result.js.map +0 -1
- package/dist/meta-tools.d.ts.map +0 -1
- package/dist/meta-tools.js.map +0 -1
- package/dist/node.d.ts.map +0 -1
- package/dist/node.js.map +0 -1
- package/dist/operator-ui/generated.d.ts.map +0 -1
- package/dist/operator-ui/generated.js.map +0 -1
- package/dist/operator-ui/model.d.ts.map +0 -1
- package/dist/operator-ui/model.js.map +0 -1
- package/dist/providers/cloudflare.d.ts.map +0 -1
- package/dist/providers/cloudflare.js.map +0 -1
- package/dist/providers/linear.d.ts.map +0 -1
- package/dist/providers/linear.js.map +0 -1
- package/dist/providers/mixpanel.d.ts.map +0 -1
- package/dist/providers/mixpanel.js.map +0 -1
- package/dist/providers/notion.d.ts.map +0 -1
- package/dist/providers/notion.js.map +0 -1
- package/dist/providers/stripe.d.ts.map +0 -1
- package/dist/providers/stripe.js.map +0 -1
- package/dist/registry.d.ts.map +0 -1
- package/dist/registry.js.map +0 -1
- package/dist/retired-toolkits.d.ts.map +0 -1
- package/dist/retired-toolkits.js.map +0 -1
- package/dist/routes/access-tokens.d.ts.map +0 -1
- package/dist/routes/access-tokens.js.map +0 -1
- package/dist/routes/activity.d.ts.map +0 -1
- package/dist/routes/activity.js.map +0 -1
- package/dist/routes/credentials.d.ts.map +0 -1
- package/dist/routes/credentials.js.map +0 -1
- package/dist/routes/mcp.d.ts.map +0 -1
- package/dist/routes/mcp.js.map +0 -1
- package/dist/routes/oauth.d.ts.map +0 -1
- package/dist/routes/oauth.js.map +0 -1
- package/dist/routes/shared.d.ts.map +0 -1
- package/dist/routes/shared.js.map +0 -1
- package/dist/routes/ui.d.ts.map +0 -1
- package/dist/routes/ui.js.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/skills.d.ts.map +0 -1
- package/dist/skills.js.map +0 -1
- package/dist/storage/file.d.ts.map +0 -1
- package/dist/storage/file.js.map +0 -1
- package/dist/storage/memory.d.ts.map +0 -1
- package/dist/storage/memory.js.map +0 -1
- package/dist/timeout.d.ts.map +0 -1
- package/dist/timeout.js.map +0 -1
- package/dist/tool-safety.d.ts.map +0 -1
- package/dist/tool-safety.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/ui.d.ts.map +0 -1
- package/dist/ui.js.map +0 -1
- package/dist/validate.d.ts.map +0 -1
- package/dist/validate.js.map +0 -1
- package/dist/version.d.ts.map +0 -1
- package/dist/version.js.map +0 -1
- package/examples/node/README.md +0 -52
- package/examples/node/src/index.ts +0 -71
- package/src/access-tokens.ts +0 -289
- package/src/activity.ts +0 -234
- package/src/apps-shell.ts +0 -370
- package/src/auth/bearer.ts +0 -61
- package/src/auth/clerk.ts +0 -553
- package/src/auth/downstream-oauth.ts +0 -575
- package/src/call-admission.ts +0 -521
- package/src/catalog-fingerprint.ts +0 -52
- package/src/catalog-limits.ts +0 -11
- package/src/catalog-service.ts +0 -1153
- package/src/catalog.ts +0 -790
- package/src/concurrency.ts +0 -39
- package/src/connector-scope.ts +0 -66
- package/src/connectors/api.ts +0 -159
- package/src/connectors/remote-mcp.ts +0 -1090
- package/src/credentials.ts +0 -428
- package/src/errors.ts +0 -364
- package/src/execute.ts +0 -1406
- package/src/executor-admission.ts +0 -328
- package/src/executor-result.ts +0 -107
- package/src/executors/quickjs-child.ts +0 -172
- package/src/executors/quickjs-protocol.ts +0 -99
- package/src/executors/quickjs-runtime.ts +0 -470
- package/src/executors/quickjs.ts +0 -776
- package/src/favicon.ts +0 -53
- package/src/index.ts +0 -666
- package/src/invocation.ts +0 -655
- package/src/json-schema.ts +0 -11
- package/src/mcp-result.ts +0 -43
- package/src/meta-tools.ts +0 -1607
- package/src/node.ts +0 -206
- package/src/operator-ui/browser.css +0 -423
- package/src/operator-ui/browser.ts +0 -1281
- package/src/operator-ui/generated.ts +0 -4
- package/src/operator-ui/model.ts +0 -111
- package/src/providers/cloudflare.ts +0 -3803
- package/src/providers/linear.ts +0 -301
- package/src/providers/mixpanel.ts +0 -228
- package/src/providers/notion.ts +0 -1879
- package/src/providers/stripe.ts +0 -306
- package/src/registry.ts +0 -1085
- package/src/retired-toolkits.ts +0 -14
- package/src/routes/access-tokens.ts +0 -115
- package/src/routes/activity.ts +0 -215
- package/src/routes/credentials.ts +0 -254
- package/src/routes/mcp.ts +0 -429
- package/src/routes/oauth.ts +0 -322
- package/src/routes/shared.ts +0 -247
- package/src/routes/ui.ts +0 -152
- package/src/server.ts +0 -195
- package/src/skills.ts +0 -271
- package/src/storage/file.ts +0 -123
- package/src/storage/memory.ts +0 -44
- package/src/timeout.ts +0 -84
- package/src/tool-safety.ts +0 -15
- package/src/types.ts +0 -523
- package/src/ui.ts +0 -744
- package/src/validate.ts +0 -387
- package/src/version.ts +0 -7
package/AGENTS.md
CHANGED
|
@@ -42,18 +42,21 @@ exports.
|
|
|
42
42
|
before building something new; "we already decided not to" is a real answer
|
|
43
43
|
there, and its removed/provisional verdicts override anything staler.
|
|
44
44
|
- [`documentation/`](./documentation/) — per-subsystem guides for agents
|
|
45
|
-
working on the repo.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
working on the repo. All of them are written now
|
|
46
|
+
([#348](https://github.com/zackbart/connecta/issues/348)); the retired manual
|
|
47
|
+
(`docs/<name>.md`) survives only in git history, which is worth mining for
|
|
48
|
+
rationale a rewrite dropped and worth nothing where it disagrees with
|
|
49
|
+
`ethos.md`. Start with `architecture.md`, then the guide for the subsystem
|
|
50
|
+
you are changing.
|
|
50
51
|
- [`README.md`](./README.md) — the human-facing overview.
|
|
51
52
|
- [`templates/node/`](./templates/node/) — the one standalone Node deployment
|
|
52
|
-
shape copied by `connecta init
|
|
53
|
-
|
|
53
|
+
shape copied by `connecta init`, Docker-ready rather than Docker-only. Keep
|
|
54
|
+
it small and prescribed. There are exactly two deployment shapes, this one
|
|
55
|
+
and [`examples/worker/`](./examples/worker/); a third scaffold that is a
|
|
56
|
+
diff away from one of them is the shape
|
|
57
|
+
[#344](https://github.com/zackbart/connecta/issues/344) deleted.
|
|
54
58
|
|
|
55
|
-
**Read `ethos.md` and the subsystem's guide
|
|
56
|
-
before changing a subsystem.**
|
|
59
|
+
**Read `ethos.md` and the subsystem's guide before changing a subsystem.**
|
|
57
60
|
|
|
58
61
|
## Deployment setup
|
|
59
62
|
|
|
@@ -61,9 +64,12 @@ before changing a subsystem.**
|
|
|
61
64
|
pins the generated deployment to the CLI package's exact version, restores the
|
|
62
65
|
template `.gitignore`, and refuses to merge into an existing path.
|
|
63
66
|
`connecta doctor` verifies a running deployment's health, executor, and exact
|
|
64
|
-
seven-tool surface.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
seven-tool surface. The template carries its own `Dockerfile` and
|
|
68
|
+
`docker-compose.yml`, so the generated project is the container: setup changes
|
|
69
|
+
must keep the root README, the template (source, container files, and README),
|
|
70
|
+
and the `scripts/check-package.mjs` smoke — which builds and runs that
|
|
71
|
+
container when Docker is available — aligned. Do not add a second initializer,
|
|
72
|
+
a second container recipe, or another “recommended” project shape.
|
|
67
73
|
|
|
68
74
|
## Where new code goes
|
|
69
75
|
|
|
@@ -91,9 +97,9 @@ in `WORKERS_SUITES`, Node-bound suites in `NODE_ONLY_SUITES` with a reason. The
|
|
|
91
97
|
`node` project runs both lists; the `workers` project re-runs the portable list
|
|
92
98
|
inside workerd. `test/suite-partition.test.ts` walks the directory and fails on
|
|
93
99
|
an unclassified, double-classified, stale, or reasonless entry. New behavior
|
|
94
|
-
also gets a row in the test map in
|
|
95
|
-
|
|
96
|
-
|
|
100
|
+
also gets a row in the test map in `documentation/operations.md`, which
|
|
101
|
+
classifies every suite — one missing from it is either new and undocumented or
|
|
102
|
+
dead, and neither is a state to leave the repository in.
|
|
97
103
|
|
|
98
104
|
## Conventions
|
|
99
105
|
|
|
@@ -109,6 +115,13 @@ is rewritten; until then the row waits with the guide.
|
|
|
109
115
|
- **CHANGELOG.** Each release opens with a narrative paragraph — what this
|
|
110
116
|
release is, what breaks, what a deployment can ignore — then
|
|
111
117
|
`### Added` / `### Changed` / `### Fixed`.
|
|
118
|
+
- **Provider drift.** Before tagging a release, run `npm run drift:check` with
|
|
119
|
+
local provider credentials exported. It diffs each hosted-MCP catalog against
|
|
120
|
+
its vetted manifest and each hand-written provider's touched endpoints against
|
|
121
|
+
the provider's published OpenAPI document. Findings are read by a human and
|
|
122
|
+
become GitHub issues — no credential goes near CI, and nothing files itself.
|
|
123
|
+
See
|
|
124
|
+
[`documentation/provider-conventions.md`](./documentation/provider-conventions.md#the-maintainer-run-drift-check).
|
|
112
125
|
- **Releases.** `npm run release:check`, tag `v<version>` matching
|
|
113
126
|
`package.json` exactly (the publish workflow verifies this and fails
|
|
114
127
|
otherwise), and publishing fires on GitHub **Release publication**, not on the
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,499 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this package are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.16.0 — 2026-08-12
|
|
6
|
+
|
|
7
|
+
This is the agent-efficiency refocus. One release, sixteen merges, and a single
|
|
8
|
+
question asked of every tool description, schema, discovery result, and error
|
|
9
|
+
message in the package: what does this cost the model that has to read it?
|
|
10
|
+
Where operator convenience and agent cost disagreed, the agent-facing contract
|
|
11
|
+
won. The work lands on two pillars — excellent curated providers, and a
|
|
12
|
+
footgun-free path for everything else — plus an operator boundary that finally
|
|
13
|
+
describes the surface it guards, exactly two deployment shapes instead of four,
|
|
14
|
+
and an operator UI that is a component app rather than string-built HTML.
|
|
15
|
+
|
|
16
|
+
What breaks, breaks loudly, and mostly at construction rather than at 2 a.m.
|
|
17
|
+
`api()` now requires a `description` and an explicit
|
|
18
|
+
`annotations.readOnlyHint` on every tool and refuses an `inputSchema` it cannot
|
|
19
|
+
compile; `strictValidation` is gone because fail-closed is the only behavior
|
|
20
|
+
left for it to switch. `linear()` requires an explicit `access` mode.
|
|
21
|
+
`mixpanel()` no longer declares a call-admission budget. `cloudflare()` checks
|
|
22
|
+
an overridden `baseUrl` where it is written. The Cloudflare connection ships 52
|
|
23
|
+
named tools instead of 55, having been measured against its own escape hatches
|
|
24
|
+
rather than assumed to beat them. And Cloudflare and Notion now refuse a
|
|
25
|
+
redirect and cap the response they will read, which is visible only to a
|
|
26
|
+
deployment that was downloading something enormous through a tool call. Each
|
|
27
|
+
of those has a one-line migration, spelled out below.
|
|
28
|
+
|
|
29
|
+
A deployment that writes no `api()` connectors and runs none of the five
|
|
30
|
+
prebuilt connections can upgrade without editing anything. Nothing in the core
|
|
31
|
+
runtime surface moved: the seven meta-tools, the executor contract, the storage
|
|
32
|
+
interfaces, the route table, and the wire shapes are where they were. The
|
|
33
|
+
tarball is half the size, the guides are all written, and `connecta init` now
|
|
34
|
+
produces a project that runs under `docker compose up` without becoming a
|
|
35
|
+
second project shape.
|
|
36
|
+
|
|
37
|
+
`api()` stops being forgiving. A hand-written tool now declares what it does
|
|
38
|
+
and whether calling it needs a human, and any `inputSchema` it ships is one
|
|
39
|
+
Connecta can actually enforce — all three checked at construction, where a
|
|
40
|
+
deployment can still refuse to boot, rather than discovered by an agent at
|
|
41
|
+
2 a.m. The warn-once-then-pass-raw-arguments-through behavior behind an
|
|
42
|
+
unenforceable schema is gone, and with it the `strictValidation` option that
|
|
43
|
+
existed only to turn it off.
|
|
44
|
+
|
|
45
|
+
That construction contract breaks `api()` authors and nobody else. Migration is
|
|
46
|
+
mechanical: give every tool a non-empty `description` and an explicit
|
|
47
|
+
`annotations.readOnlyHint` — `true` for a read, `false` for work that should
|
|
48
|
+
cross `call_destructive_tool` — then delete `strictValidation`, which is now
|
|
49
|
+
the only behavior. A tool that used to ship unannotated becomes
|
|
50
|
+
`readOnlyHint: false`, which is exactly the routing it already got.
|
|
51
|
+
Hosted-MCP proxies are untouched: `remoteMcp()` relays a downstream's names,
|
|
52
|
+
descriptions, schemas, and annotations as they arrive, and an unannotated or
|
|
53
|
+
contradictory downstream tool still fails closed onto `call_destructive_tool`.
|
|
54
|
+
Connecta infers read-only behavior from nothing, anywhere.
|
|
55
|
+
|
|
56
|
+
The maintained Cloudflare connection ships the second break. Its named surface
|
|
57
|
+
was measured against its own escape hatches instead of being assumed to beat
|
|
58
|
+
them, and three tools came out. Every named tool now carries a recorded `keep`,
|
|
59
|
+
`prune`, or `improve` verdict backed by per-tool numbers: catalog tokens, rank
|
|
60
|
+
in a real `search_tools` call for a representative operator request, whether
|
|
61
|
+
classes of argument mistake are refused before the round trip, and whether the
|
|
62
|
+
handler projects Cloudflare's object or hands it back whole. The evidence, the
|
|
63
|
+
tasks, and the reason for every removal — including the one removed for pair
|
|
64
|
+
symmetry rather than for a measured defect — are in
|
|
65
|
+
[`eval/current-version/results/issue-350-evidence.md`](./eval/current-version/results/issue-350-evidence.md).
|
|
66
|
+
**A deployment that calls `set_r2_cors`, `delete_r2_cors`, or `get_r2_metrics`
|
|
67
|
+
has to change.** No capability is lost: `get_r2_cors` still reads a bucket's
|
|
68
|
+
policy, and the usage guide now names the replacement routes —
|
|
69
|
+
`cloudflare_api_mutate` at
|
|
70
|
+
`PUT`/`DELETE /accounts/{accountId}/r2/buckets/{bucketName}/cors`, and
|
|
71
|
+
`cloudflare_api_get` at `/accounts/{accountId}/r2/metrics`. Every other
|
|
72
|
+
Cloudflare tool, argument, projection, and annotation is unchanged.
|
|
73
|
+
|
|
74
|
+
All five maintained prebuilt connections have been audited against the written
|
|
75
|
+
provider conventions, one report per provider, with a verdict for every
|
|
76
|
+
applicable convention. Nineteen misses were found and fixed. Sixteen of them
|
|
77
|
+
were a guide, a title, or a schema description failing to say something the
|
|
78
|
+
implementation already did correctly — the conventions were mostly not asking
|
|
79
|
+
for different behavior, they were asking for the behavior to reach the agent.
|
|
80
|
+
|
|
81
|
+
Three of them did change behavior, and two of those break a deployment:
|
|
82
|
+
`linear()` now requires an `access` mode, and `mixpanel()` no longer declares a
|
|
83
|
+
call-admission budget. Both failures are loud — one at construction, one as an
|
|
84
|
+
absent ceiling an operator can restore in one option. Everything else is a
|
|
85
|
+
smaller catalog, a better summary, and a guide that says what it always meant.
|
|
86
|
+
|
|
87
|
+
Underneath all of that, the two hand-written providers stopped each keeping
|
|
88
|
+
their own copy of the same transport safety machinery. Cloudflare and Notion
|
|
89
|
+
now send every request through one guarded transport that owns URL
|
|
90
|
+
confinement, redirect refusal, bounded response reads, and network-failure
|
|
91
|
+
normalization, and owns no opinion at all about what a status code means.
|
|
92
|
+
|
|
93
|
+
Consolidating it was not free, and three of the differences are visible from
|
|
94
|
+
outside. A 3xx from either provider is refused now rather than followed, which
|
|
95
|
+
is what both used to do by default — a redirect is an instruction to re-send
|
|
96
|
+
the connector's credential to whatever origin `Location` names, and neither
|
|
97
|
+
API has a legitimate one to send. Both providers now cap what they will read,
|
|
98
|
+
at 8 MiB for Cloudflare and 4 MiB for Notion, so a `cloudflare_api_get`
|
|
99
|
+
downloading an R2 object or a Worker script larger than 8 MiB fails instead of
|
|
100
|
+
returning it. And `cloudflare()`'s optional `baseUrl` is checked where it is
|
|
101
|
+
written: a non-loopback plain-http origin, URL-embedded credentials, or a
|
|
102
|
+
query or fragment throws at construction, so a deployment pointed at an http
|
|
103
|
+
proxy stops booting rather than sending it a token.
|
|
104
|
+
|
|
105
|
+
The repository now models exactly the two deployments it actually has: a Node
|
|
106
|
+
one and a Worker one. `connecta init` still copies the same template, but that
|
|
107
|
+
template now carries its own `Dockerfile` and `docker-compose.yml`, so the
|
|
108
|
+
generated project runs from `npm start` locally and from `docker compose up`
|
|
109
|
+
in production without becoming a second project shape. The two near-identical
|
|
110
|
+
Node scaffolds that sat beside it — `examples/node` and `examples/docker`, the
|
|
111
|
+
latter of which built the Connecta repository rather than a consumer project —
|
|
112
|
+
are gone. Existing deployments can ignore all of this; nothing in the package's
|
|
113
|
+
runtime surface moved.
|
|
114
|
+
|
|
115
|
+
The three maintained hosted-MCP connections now notice when the catalog they
|
|
116
|
+
were reviewed against moves. Each ships a vetted manifest — the tool names and
|
|
117
|
+
classifications a release read, plus schema digests once a release records
|
|
118
|
+
them — and compares it with the live listing *inside* a catalog refresh the
|
|
119
|
+
deployment already asked for. Nothing new is requested: no scheduled job, no
|
|
120
|
+
background poll, no credential probe, which is the boundary that keeps this
|
|
121
|
+
from being the proactive liveness checking connecta removed. What comes out is
|
|
122
|
+
four counts — unclassified additions, names no longer served, explicit
|
|
123
|
+
annotation conflicts, schema changes — on connector status, on `/health`, and
|
|
124
|
+
in `connecta doctor`, plus one payload-free activity event per change in those
|
|
125
|
+
counts for stores that implement the new optional `recordCatalogDrift`. The
|
|
126
|
+
observation is per runtime and is not persisted, so status, `/health`, and
|
|
127
|
+
doctor answer for the isolate or process that served the refresh — an empty
|
|
128
|
+
report means that runtime has observed nothing, and the activity event is the
|
|
129
|
+
durable half. A deployment can ignore all of it: an unclassified tool already
|
|
130
|
+
failed closed onto `call_destructive_tool` before anyone counted it.
|
|
131
|
+
|
|
132
|
+
The other half of that story is a command, not a surface. `npm run drift:check`
|
|
133
|
+
is maintainer tooling — it ships nowhere, runs on a laptop before a release, and
|
|
134
|
+
answers the question the runtime counts deliberately cannot: *which* tool moved.
|
|
135
|
+
It diffs each hosted-MCP catalog against the same vetted manifest the connector
|
|
136
|
+
classifies from, using the maintainer's own credential, and it compares the
|
|
137
|
+
handful of endpoints Cloudflare and Notion actually call against those
|
|
138
|
+
providers' published OpenAPI documents — reporting a gone path, a gone method, a
|
|
139
|
+
new deprecation, or a changed contract, and ignoring the two thousand operations
|
|
140
|
+
connecta never touches. No credential goes near CI, nothing is scheduled,
|
|
141
|
+
nothing files itself, and a published specification is drift evidence only: it
|
|
142
|
+
never generates a tool and never becomes a runtime input.
|
|
143
|
+
|
|
144
|
+
Both deployment shapes now carry the operator feature set the operator pages
|
|
145
|
+
were built for. A fresh `connecta init` used to produce a deployment with a
|
|
146
|
+
Credentials page and no vault, a Tokens page and no issuance, and an Activity
|
|
147
|
+
page with nothing behind it — pages for things that deployment could not do.
|
|
148
|
+
The Node template now ships sign-in, vault, tokens, and activity as four
|
|
149
|
+
clearly-marked commented blocks in `src/index.ts`, each one an environment
|
|
150
|
+
variable and an uncommented block away, plus a deployment-owned
|
|
151
|
+
`src/file-activity.ts` that is compiled rather than commented. The Worker
|
|
152
|
+
example wires the first three outright and comments the fourth, which needs a
|
|
153
|
+
D1 database nobody can create for you. Existing deployments can ignore this
|
|
154
|
+
entirely: nothing in the package's runtime surface moved, and both READMEs
|
|
155
|
+
walk through the enablement.
|
|
156
|
+
|
|
157
|
+
Finally, the tarball is half of what it was, and nothing that left it was
|
|
158
|
+
reachable. `exports` resolves only into `dist/`, so the packed `src/` was
|
|
159
|
+
never imported by anything — it was there to back the source and declaration
|
|
160
|
+
maps, and all three went together. Out with them, and out with the 230 KB
|
|
161
|
+
README hero image, which npmjs.com renders from the repository anyway. An
|
|
162
|
+
install unpacks to 1.8 MB instead of 3.8 MB. The code, the types, the CLI, the
|
|
163
|
+
template, the Worker example, and every guide are exactly where they were —
|
|
164
|
+
and there are four more guides than there were mid-release, because the four
|
|
165
|
+
stubs `check:package` had been excluding got written instead.
|
|
166
|
+
|
|
167
|
+
Which is the quiet half of this release. The five prebuilt connections used to
|
|
168
|
+
encode five sets of private judgment about what a good provider surface looks
|
|
169
|
+
like; that judgment is now two written convention sets, H1–H14 for hand-written
|
|
170
|
+
`api()` surfaces and P1–P13 for `remoteMcp()` proxies, each rule carrying its
|
|
171
|
+
reason and the agent cost it reduces. The placeholder guides in
|
|
172
|
+
`documentation/` — which covered, with some irony, the load-bearing subsystems,
|
|
173
|
+
while the newest features had the best docs — are written against the code as
|
|
174
|
+
it is, and none is left. And the ethos bullet that promised
|
|
175
|
+
"observable, never administrable" was retired for one that is true: operator
|
|
176
|
+
routes manage authentication material for capabilities declared in deployment
|
|
177
|
+
configuration, and a suite now snapshots every declared structure and demands
|
|
178
|
+
it back byte-identical after each operator mutation.
|
|
179
|
+
|
|
180
|
+
### Added
|
|
181
|
+
|
|
182
|
+
- **Two written provider convention sets.**
|
|
183
|
+
[`documentation/provider-conventions.md`](./documentation/provider-conventions.md)
|
|
184
|
+
states H1–H14 for hand-written `api()` surfaces, where Connecta owns every
|
|
185
|
+
name, schema, projection, and error, and P1–P13 for `remoteMcp()` proxies,
|
|
186
|
+
where the downstream owns the catalog and Connecta owns the endpoint,
|
|
187
|
+
credential, classification, guide, and budget. Every convention carries its
|
|
188
|
+
rule, its reason, and which of the four agent costs it reduces — discovery
|
|
189
|
+
tokens, wrong-tool selection, argument retries, result size — and names the
|
|
190
|
+
budgets at which the surface itself starts dropping characters: 160 for a
|
|
191
|
+
tool description in search, 240 in describe, 1,024 bytes per compact schema,
|
|
192
|
+
120 for a guide summary. A description longer than its budget is written for
|
|
193
|
+
nobody (#339).
|
|
194
|
+
- **The core subsystem guides, written.** `architecture.md`,
|
|
195
|
+
`request-admission.md`, `call-admission.md`, and `operations.md` were
|
|
196
|
+
identical seven-line placeholders pointing at git history; they now describe
|
|
197
|
+
the code as it is — the two lifetimes, the ordered route table and why each position is
|
|
198
|
+
behavior rather than taste, the import-graph purity rule and what it actually
|
|
199
|
+
prevents, both admission pools and why `/mcp` admits before it authenticates,
|
|
200
|
+
and the connector-partitioned downstream policy. `operations.md` also carries
|
|
201
|
+
the test map AGENTS.md had been deferring since the docs restructure: all 61
|
|
202
|
+
suites plus the two browser specs, with each Node-only suite's reason for not
|
|
203
|
+
running in workerd, so "this suite exists" and "this suite is justified" are
|
|
204
|
+
one lookup. `connector-guides.md` gains the general authoring half #339 left
|
|
205
|
+
open, including the `required` flag in full. With no stubs left, the four
|
|
206
|
+
`!documentation/…` negations in `files` went too (#348).
|
|
207
|
+
- **A maintainer-run provider drift check.** `npm run drift:check` diffs the
|
|
208
|
+
live Linear, Stripe, and Mixpanel catalogs against their vetted manifests by
|
|
209
|
+
name — added, no longer served, annotation conflicts, and schema changes — and
|
|
210
|
+
cross-checks its totals against the runtime `detectCatalogDrift()`, because
|
|
211
|
+
two readings of one manifest that disagree mean one of them is lying. Its
|
|
212
|
+
second half compares committed touched-endpoint manifests
|
|
213
|
+
(`scripts/drift/cloudflare-endpoints.json`, `scripts/drift/notion-endpoints.json`:
|
|
214
|
+
method, path, reviewed spec revision, reviewed deprecation, contract digest)
|
|
215
|
+
with each provider's published OpenAPI document, and `--record` refreshes
|
|
216
|
+
them. Deprecation is reported as a transition in either direction, so a
|
|
217
|
+
reviewed one stops being news. A missing credential, an unreachable
|
|
218
|
+
specification, or a `--provider` the selected half does not check stops the
|
|
219
|
+
run and says which one.
|
|
220
|
+
Written up in
|
|
221
|
+
[`documentation/provider-conventions.md`](./documentation/provider-conventions.md#the-maintainer-run-drift-check)
|
|
222
|
+
(#351).
|
|
223
|
+
- **Hosted-provider drift detection at refresh.** Linear, Stripe, and Mixpanel
|
|
224
|
+
each ship a vetted manifest and compare it with the live catalog while
|
|
225
|
+
serving a refresh that was going to happen anyway. `ConnectorStatus` gains
|
|
226
|
+
`catalogDrift` (four counts and the time they were observed), `/health` gains
|
|
227
|
+
the same per connector, `connecta doctor` reports it without failing on it,
|
|
228
|
+
and `ActivitySink` gains an optional `recordCatalogDrift` that receives one
|
|
229
|
+
payload-free event per change in the counts. Both read surfaces report what
|
|
230
|
+
the answering runtime observed — the observation is isolate-local, not
|
|
231
|
+
persisted — and both project the counts rather than echo the connector seam.
|
|
232
|
+
The policy is written up in
|
|
233
|
+
[`documentation/provider-conventions.md`](./documentation/provider-conventions.md#the-runtime-drift-policy)
|
|
234
|
+
(#343).
|
|
235
|
+
- **The Node template is Docker-ready.** `Dockerfile`, `docker-compose.yml`,
|
|
236
|
+
and `.dockerignore` ship with `connecta init`. The image installs
|
|
237
|
+
`@zackbart/connecta` from the registry like any other consumer, runs as the
|
|
238
|
+
non-root `node` user with state on a named volume, probes the always-open
|
|
239
|
+
`/health` route, and keeps Node in the foreground so `compose down` stops it
|
|
240
|
+
promptly. `PUBLIC_URL` and `CONNECTA_STATE_FILE` now configure the generated
|
|
241
|
+
`src/index.ts`, which is what makes one source serve both run paths (#344).
|
|
242
|
+
- **The package smoke exercises the generated container.** `check:package`
|
|
243
|
+
builds and runs the initialized deployment through Compose and points
|
|
244
|
+
`connecta doctor` at it; it fails rather than skips when Docker is missing
|
|
245
|
+
in CI (#344).
|
|
246
|
+
- **A deterministic named-surface measurement lane.**
|
|
247
|
+
`npm --prefix eval/current-version run report:cloudflare-surface` measures the
|
|
248
|
+
maintained Cloudflare connection one tool at a time and writes a JSON and
|
|
249
|
+
Markdown artifact. It needs no model, no network, and no credential: the real
|
|
250
|
+
constructor, schemas, validation path, handlers, and catalog service run, and
|
|
251
|
+
only `fetch` is a probe that records the request (#350).
|
|
252
|
+
- **Five provider audit reports** in
|
|
253
|
+
[`documentation/provider-audit.md`](./documentation/provider-audit.md), with
|
|
254
|
+
a verdict per convention, the fix for every miss, and every accepted
|
|
255
|
+
exception recorded with its argument (#342).
|
|
256
|
+
- **A convention test over the shipped surface.**
|
|
257
|
+
`test/provider-conventions.test.ts` walks both `api()` providers on every run
|
|
258
|
+
and enforces the mechanically checkable bar — naming, description budgets,
|
|
259
|
+
closed schemas described at every depth, compact-render budgets, declared
|
|
260
|
+
outputs, structured guides, and credential tests — so a convention met once
|
|
261
|
+
stays met. The one accepted gap, the undescribed name/value members of
|
|
262
|
+
Cloudflare's escape-hatch request parts, is listed by path in the suite with
|
|
263
|
+
its argument rather than left for a shallower check to miss (#342).
|
|
264
|
+
- **Guide coverage the schemas cannot carry.** Stripe and Mixpanel guides now
|
|
265
|
+
name their id-resolution rules, say the hosted catalog is not a fixed set, and
|
|
266
|
+
give the `auth_required` → `authorize_connector` recovery route. Notion's
|
|
267
|
+
guide states that it deliberately has no raw-REST escape hatch (#342).
|
|
268
|
+
- **A guarded fetch transport for hand-written connectors.** One factory
|
|
269
|
+
supplies the machinery every `api()` HTTP surface was re-deriving: strict
|
|
270
|
+
base-origin and path confinement checked after URL normalization, encoded
|
|
271
|
+
query and JSON body construction, `ctx.signal` propagation, a required
|
|
272
|
+
response-byte ceiling enforced while reading, a flat refusal to follow a
|
|
273
|
+
redirect or to let a request header shadow an authentication one, and an
|
|
274
|
+
unreachable provider normalized to a retryable `unavailable`. Authentication
|
|
275
|
+
and status interpretation stay in provider callbacks — the helper never
|
|
276
|
+
guesses what a 403 means. Cloudflare and Notion both run on it; it is held
|
|
277
|
+
internal this release rather than exported, and
|
|
278
|
+
[`documentation/connectors.md`](./documentation/connectors.md#the-guarded-fetch-transport)
|
|
279
|
+
records why (#341).
|
|
280
|
+
- **The operator feature set in both deployment shapes.** The Node template
|
|
281
|
+
gains commented, documented configuration for Clerk operator sign-in, the
|
|
282
|
+
credential vault, access-token issuance, and payload-free activity, the four
|
|
283
|
+
environment variables they read (passed through Compose and defaulted in the
|
|
284
|
+
Dockerfile so the container works the moment a block is uncommented), and
|
|
285
|
+
`src/file-activity.ts` — a deployment-owned `ActivityStore` that appends one
|
|
286
|
+
JSON line per call and rewrites the log back down to the newest 5,000 once it
|
|
287
|
+
runs a slack window past that, repairing a torn trailing line on the way in
|
|
288
|
+
rather than appending onto it. The Worker example wires the credential vault
|
|
289
|
+
to a new `CREDENTIAL_ENCRYPTION_KEY` secret beside the Clerk and access-token
|
|
290
|
+
configuration it already had, and carries the D1 activity wiring and its
|
|
291
|
+
binding as commented lines rather than as README-only instructions. Both
|
|
292
|
+
READMEs walk through enabling each half — including the part neither vault
|
|
293
|
+
can supply, a connector that declares a `credential` slot, which is what puts
|
|
294
|
+
the Credentials page in the nav — and both say why `connecta doctor` reports
|
|
295
|
+
none of it: doctor holds a bearer, and a client key does not get to learn a
|
|
296
|
+
deployment's configuration topology (#345).
|
|
297
|
+
|
|
298
|
+
### Changed
|
|
299
|
+
|
|
300
|
+
- **The operator boundary is stated as authentication material.** "Observable,
|
|
301
|
+
never administrable" had stopped describing the surface — operator routes
|
|
302
|
+
rotate credentials, issue and revoke access tokens, and drive downstream
|
|
303
|
+
OAuth, each under its own accepted decision. The ethos bullet, the invariant,
|
|
304
|
+
and a new decisions row now say the true thing: operator routes may manage
|
|
305
|
+
authentication material for capabilities *declared* in deployment
|
|
306
|
+
configuration, and may never change the connector set, the declared tool
|
|
307
|
+
catalog or annotations, requested OAuth scopes, admission policy,
|
|
308
|
+
authorization rules, or caller tool scope. The word "declared" is doing work
|
|
309
|
+
twice over — a broader-scoped replacement token widens downstream reach and
|
|
310
|
+
no browser page can honestly promise otherwise, and a remote MCP server's
|
|
311
|
+
catalog is discovered rather than declared, so storing a credential can take
|
|
312
|
+
an `mcp()` connector from no tools to N. That is discovery arriving, which is
|
|
313
|
+
exactly why those routes call `invalidateStored()`.
|
|
314
|
+
`test/operator-boundary.test.ts` snapshots every declared structure, drives
|
|
315
|
+
each operator mutation route against both a static and a re-listing
|
|
316
|
+
connector, and requires the snapshot back byte-identical; a second case
|
|
317
|
+
proves the snapshot can fail. No runtime behavior changed (#338).
|
|
318
|
+
- **The operator UI is a component app.** The hand-written DOM layer is gone,
|
|
319
|
+
replaced by a small Preact app compiled by the same esbuild step and inlined
|
|
320
|
+
into a shell that is now a mount point rather than a page. Nothing builds
|
|
321
|
+
HTML from strings any more, so the escaping every rendered value used to
|
|
322
|
+
depend on is structural; the served markup is identical on all four pages and
|
|
323
|
+
still carries no operator data. Credential, token, and OAuth flows gained
|
|
324
|
+
deliberate loading, error, empty, and success states — a failed save keeps
|
|
325
|
+
the form and what was typed in it, a failed list offers a retry, and an empty
|
|
326
|
+
collection says what would fill it. Each connector card also reads the drift
|
|
327
|
+
the last catalog refresh saw (#343) as four category counts, with `clean`,
|
|
328
|
+
`warning`, and "not observed in this runtime" kept as three distinct answers
|
|
329
|
+
— no tool name, schema, or payload rides that panel. Preact rides in as a
|
|
330
|
+
`devDependency` inlined into the committed bundle and never reaches a
|
|
331
|
+
deployment's dependency tree (#347).
|
|
332
|
+
|
|
333
|
+
- **`api()` enforces its construction contract.** Every tool requires a
|
|
334
|
+
non-empty `description` and an explicit boolean `annotations.readOnlyHint`;
|
|
335
|
+
a missing or non-boolean classification throws with the address that needs
|
|
336
|
+
fixing. The classification is never inferred from a tool name, description,
|
|
337
|
+
schema, HTTP method, or the other annotations (#340).
|
|
338
|
+
- **An unenforceable `inputSchema` fails at construction.** A schema the
|
|
339
|
+
validator cannot compile throws when the connector is built, whether or not
|
|
340
|
+
`validateArgs` is on — opting out of enforcement is not opting out of the
|
|
341
|
+
schema being real. A schema that only reveals itself on first use, such as an
|
|
342
|
+
unresolvable `$ref`, now fails that call as non-retryable `invalid_args`
|
|
343
|
+
instead of forwarding raw arguments to the handler (#340).
|
|
344
|
+
- **`linear()` requires `access`.** There is no safe default between Linear's
|
|
345
|
+
two endpoints: `"read-write"` hands out writes nobody asked for, and
|
|
346
|
+
`"read-only"` breaks a writing deployment at Linear, at runtime, where no
|
|
347
|
+
agent can repair it. Construction now throws naming both options. Add
|
|
348
|
+
`access: "read-write"` to keep an existing deployment's behavior (#342).
|
|
349
|
+
- **`mixpanel()` declares no call-admission budget.** The old hardcoded 600
|
|
350
|
+
calls per hour transcribed a limit Mixpanel meters *per user*, which a
|
|
351
|
+
per-runtime counter cannot approximate in either direction. Supply
|
|
352
|
+
`callAdmission` explicitly if the account needs a ceiling, as Linear already
|
|
353
|
+
did (#342).
|
|
354
|
+
- **`mixpanel()` titles itself by region.** The default title is now
|
|
355
|
+
`Mixpanel (us)`, `(eu)`, or `(in)`, and the guide opens with the residency,
|
|
356
|
+
because a project lives in exactly one and search never shows a description.
|
|
357
|
+
An unknown region throws at construction (#342).
|
|
358
|
+
- **Provider guides are structured everywhere.** All five declare an explicit
|
|
359
|
+
`summary` instead of leaning on the guide's first line, which was truncating
|
|
360
|
+
the routing fact at 120 characters on three of them (#342).
|
|
361
|
+
- **Smaller discovery payloads.** Over-budget tool descriptions
|
|
362
|
+
(`cloudflare_api_get`, `cloudflare_api_mutate`, `create_dns_record`, Notion's
|
|
363
|
+
`search`) were trimmed to the 240-character describe budget, and shared
|
|
364
|
+
property descriptions were cut so `cloudflare_api_upload` and
|
|
365
|
+
`query_data_source` render inside the 1,024-byte compact budget instead of
|
|
366
|
+
degrading and costing a describe round trip (#342).
|
|
367
|
+
- **Cloudflare and Notion never follow a redirect.** Both used `fetch`'s
|
|
368
|
+
default `redirect: "follow"` and now send `redirect: "manual"`; a 3xx fails
|
|
369
|
+
as non-retryable `connector_call_failed` instead of re-sending the
|
|
370
|
+
connector's credential to whatever origin the `Location` names (#341).
|
|
371
|
+
- **Cloudflare and Notion bound the response they will read.** 8 MiB and
|
|
372
|
+
4 MiB respectively, enforced against a declared `Content-Length` before the
|
|
373
|
+
first byte and again while the body streams. Both are ceilings on absurdity
|
|
374
|
+
rather than quotas — anything near them was already past whatever
|
|
375
|
+
`maxResultBytes` the deployment set — but a `cloudflare_api_get` reading an
|
|
376
|
+
R2 object or Worker script past 8 MiB now fails as non-retryable instead of
|
|
377
|
+
returning it (#341).
|
|
378
|
+
- **`cloudflare()` checks its `baseUrl` at construction.** A non-loopback
|
|
379
|
+
plain-http origin, URL-embedded credentials, or a query or fragment throws
|
|
380
|
+
where the connector is written rather than on the first call. A deployment
|
|
381
|
+
overriding `baseUrl` with an http proxy must move it to https or bind it to
|
|
382
|
+
loopback; the default Cloudflare base is unaffected (#341).
|
|
383
|
+
|
|
384
|
+
### Fixed
|
|
385
|
+
|
|
386
|
+
- **`connecta doctor` names the sandbox that actually ran the program.** It
|
|
387
|
+
printed "QuickJS executed" at every deployment it had ever checked, including
|
|
388
|
+
the Worker example, whose sandbox is a Dynamic Worker — the one field the
|
|
389
|
+
Worker README says doctor confirms, reported wrong. The deployment now says
|
|
390
|
+
what its executor is: `/health` carries the configured executor's name when
|
|
391
|
+
it has one (an explicit `name`, else a class-shaped executor's constructor
|
|
392
|
+
name), sanitized and bounded because it lands in a public response body and
|
|
393
|
+
an operator's terminal. Doctor reports that name, and a deployment whose
|
|
394
|
+
executor identifies as nothing gets `code executed` rather than a guess. The
|
|
395
|
+
Node template still reads `QuickJS executed`; the Worker example now reads
|
|
396
|
+
`DynamicWorkerExecutor executed` (#368).
|
|
397
|
+
- **The Node template's `.env.example` ships an empty `CONNECTA_TOKEN`.**
|
|
398
|
+
`docker-compose.yml` has always promised to refuse a deployment with no
|
|
399
|
+
inbound auth, but its `${CONNECTA_TOKEN:?…}` guard only fires on unset or
|
|
400
|
+
empty — and the file it reads shipped `replace-me`, which is neither. Copying
|
|
401
|
+
`.env.example` and running the README's Docker block therefore produced a
|
|
402
|
+
healthy, port-published deployment whose bearer token was a string published
|
|
403
|
+
in this repository. The value is now empty, so both Compose and `npm start`
|
|
404
|
+
refuse until an operator sets one (#367).
|
|
405
|
+
- **The Worker example names the optional peer it imports.**
|
|
406
|
+
`examples/worker` wires `clerkAuth` by default and calls itself the starting
|
|
407
|
+
template for a deployment, but its README listed only `@cloudflare/codemode`
|
|
408
|
+
as an extra install. `@clerk/backend` is an optional peer that never installs
|
|
409
|
+
with Connecta, and `auth/clerk` imports it at the top level, so a copied
|
|
410
|
+
deployment following the README verbatim died at
|
|
411
|
+
`Could not resolve "@clerk/backend"` before it ever reached Cloudflare. The
|
|
412
|
+
deploy section now carries the whole install line for a copy in its own
|
|
413
|
+
repository (#367).
|
|
414
|
+
- **A malformed Clerk publishable key fails like a configuration mistake.**
|
|
415
|
+
`clerkAuth` derives its Frontend API origin by base64-decoding
|
|
416
|
+
`publishableKey` and used to hand a bad key straight to `atob`, so the
|
|
417
|
+
placeholder the Workers example ships raised a bare `InvalidCharacterError`
|
|
418
|
+
from inside the returned object — and, on a deployment that builds per
|
|
419
|
+
request, turned every route including `/health` into a 500 whose stack named
|
|
420
|
+
base64 instead of the environment variable. The key's shape is now checked
|
|
421
|
+
where `allowedDomains` is, at construction, and the throw names the option.
|
|
422
|
+
It does not quote the rejected value back: the usual way to land here is
|
|
423
|
+
pasting the secret key into the publishable slot (#366).
|
|
424
|
+
- **Notion declares the `required` lists it was missing.** `search`,
|
|
425
|
+
`list_users`, `get_self`, and `create_page` now say which arguments a call
|
|
426
|
+
must carry, so a malformed call is refused locally instead of at Notion. The
|
|
427
|
+
fail-closed schema handling those lists rely on is the package default as of
|
|
428
|
+
#340 (#342).
|
|
429
|
+
- **Cloudflare's cursor pagination says so in the schema.**
|
|
430
|
+
`list_zone_rulesets`, `list_kv_keys`, `list_r2_buckets`, and
|
|
431
|
+
`list_r2_objects` now state on both the `cursor` argument and the
|
|
432
|
+
`nextCursor` result that they page by cursor and return no `page` object —
|
|
433
|
+
previously only the usage guide said it (#342).
|
|
434
|
+
- **Nested schema properties describe themselves.** The six fields inside
|
|
435
|
+
`bulk_write_kv_values`'s `entries[]` — including the expiry pair, whose units
|
|
436
|
+
and 60-second floor were the entire question — and Notion's
|
|
437
|
+
`sorts[].direction` were shipping bare types, because H5's description rule
|
|
438
|
+
had only ever been read at the top level (#342).
|
|
439
|
+
|
|
440
|
+
### Removed
|
|
441
|
+
|
|
442
|
+
- **`ApiOptions.strictValidation`.** Fail-closed schema handling is the only
|
|
443
|
+
behavior, so the opt-in has nothing left to switch. Delete the option;
|
|
444
|
+
nothing else changes (#340).
|
|
445
|
+
- **Three Cloudflare named tools; the connection ships 52, down from 55.**
|
|
446
|
+
`set_r2_cors` declared a free-form rule body, so its schema validated the ids
|
|
447
|
+
and waved through the part of the call that fails, and `get_r2_metrics` put
|
|
448
|
+
one account id into a path and returned the response unprojected — both
|
|
449
|
+
measurably weaker than the raw call that replaces them. `delete_r2_cors`
|
|
450
|
+
measured clean and went anyway, to keep the CORS write pair together: with
|
|
451
|
+
the write unnamed, a named delete would leave half of policy management on
|
|
452
|
+
each route. All three are one raw call away, and the guide says which one
|
|
453
|
+
(#350).
|
|
454
|
+
- **`examples/node` and `examples/docker`.** Both were diffs from the
|
|
455
|
+
template. `examples/` is the Worker deployment now, and the root
|
|
456
|
+
`.dockerignore` that existed only for the repository-context Docker build
|
|
457
|
+
went with them (#344).
|
|
458
|
+
- **`src/`, `.js.map`, `.d.ts.map`, and `assets/` — from the tarball only.**
|
|
459
|
+
All of them are still in the repository; none of them ships. The published
|
|
460
|
+
package is 167 files and 550 KB, down from 357 and 1.1 MB. The stub guides
|
|
461
|
+
left with them and came back written (#348), which is why the file count is
|
|
462
|
+
four higher than the trim alone left it.
|
|
463
|
+
Stepping into Connecta's TypeScript from an installed copy no longer works;
|
|
464
|
+
the emitted JavaScript and the `.d.ts` files beside it do. `check:package`
|
|
465
|
+
now fails on a packed `src/`, `.map`, or `assets/` path, derives the shipped
|
|
466
|
+
guide list from which guides are still stubs, so filling one in ships it, and
|
|
467
|
+
refuses a packed document whose relative link lands on a guide the tarball
|
|
468
|
+
does not carry — the three that pointed at `operations.md` now name it
|
|
469
|
+
instead (#346).
|
|
470
|
+
|
|
471
|
+
## 0.15.1 — 2026-08-12
|
|
472
|
+
|
|
473
|
+
The Cloudflare connection now supports legacy user-scoped Global API Keys as
|
|
474
|
+
an explicit authentication mode. Scoped API tokens remain the default. The
|
|
475
|
+
three guarded raw tools still cover the full v4 path space without adding one
|
|
476
|
+
tool per endpoint, and ordinary JSON responses such as GraphQL results now
|
|
477
|
+
survive that path intact.
|
|
478
|
+
|
|
479
|
+
Nothing breaks for existing deployments. They keep their current API token,
|
|
480
|
+
credential form, verification tool, and 55-tool surface. A deployment that
|
|
481
|
+
needs the legacy scheme opts in and stores the Cloudflare user email and Global
|
|
482
|
+
API Key as separate encrypted fields.
|
|
483
|
+
|
|
484
|
+
### Added
|
|
485
|
+
|
|
486
|
+
- **Legacy Cloudflare Global API Key authentication.** Set
|
|
487
|
+
`authentication: "globalApiKey"` to send operator-managed `X-Auth-Email` and
|
|
488
|
+
`X-Auth-Key` headers. `verify_global_api_key` checks the pair through
|
|
489
|
+
Cloudflare's authenticated user endpoint, and raw calls cannot replace either
|
|
490
|
+
connector-owned header.
|
|
491
|
+
|
|
492
|
+
### Fixed
|
|
493
|
+
|
|
494
|
+
- **Raw Cloudflare calls preserve non-envelope JSON.** Endpoints such as
|
|
495
|
+
`/graphql` return their complete JSON document instead of an undefined
|
|
496
|
+
`result`.
|
|
497
|
+
|
|
5
498
|
## 0.15.0 — 2026-08-10
|
|
6
499
|
|
|
7
500
|
Discovery now keeps strong action/object near-matches visible beside complete
|
package/README.md
CHANGED
|
@@ -57,8 +57,12 @@ Point an MCP client at `http://localhost:8787/mcp` with
|
|
|
57
57
|
```text
|
|
58
58
|
my-connecta/
|
|
59
59
|
├── src/index.ts # connectors, auth, storage, public URL
|
|
60
|
+
├── src/file-activity.ts # deployment-owned activity store, wired on request
|
|
60
61
|
├── package.json # exact Connecta and QuickJS versions
|
|
61
62
|
├── tsconfig.json
|
|
63
|
+
├── Dockerfile # the same source, containerized
|
|
64
|
+
├── docker-compose.yml # one service, state on a named volume
|
|
65
|
+
├── .dockerignore
|
|
62
66
|
├── .env.example
|
|
63
67
|
├── .gitignore
|
|
64
68
|
├── AGENTS.md
|
|
@@ -66,6 +70,13 @@ my-connecta/
|
|
|
66
70
|
└── README.md
|
|
67
71
|
```
|
|
68
72
|
|
|
73
|
+
The same project runs as a long-lived container without changing a line of it:
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
cp .env.example .env # set CONNECTA_TOKEN
|
|
77
|
+
docker compose up -d --build
|
|
78
|
+
```
|
|
79
|
+
|
|
69
80
|
For an agent setting this up, the contract is:
|
|
70
81
|
|
|
71
82
|
1. Edit `src/index.ts`; do not copy Connecta internals into the deployment.
|
|
@@ -81,6 +92,12 @@ For an agent setting this up, the contract is:
|
|
|
81
92
|
the exact seven-tool model-facing surface, then executes a harmless sandbox
|
|
82
93
|
program. The bearer stays in the environment rather than command history.
|
|
83
94
|
|
|
95
|
+
The operator surface is the same in both shapes and off until you say so:
|
|
96
|
+
Clerk sign-in, the credential vault, access-token issuance, and payload-free
|
|
97
|
+
activity ship as commented configuration, each one a variable and an
|
|
98
|
+
uncommented block away. The generated `README.md` walks through all four, and
|
|
99
|
+
the [Worker example](./examples/worker/) does the same for KV and D1.
|
|
100
|
+
|
|
84
101
|
The template refuses to merge into an existing directory, so initialization
|
|
85
102
|
cannot overwrite another project. Its generated programs have no filesystem,
|
|
86
103
|
environment, arbitrary network, imports, or timers; only explicitly read-only
|
|
@@ -88,11 +105,9 @@ connector tools are reachable. Unannotated or write-capable calls stay
|
|
|
88
105
|
individual and cross `call_destructive_tool`, where the MCP host can ask the
|
|
89
106
|
operator for approval.
|
|
90
107
|
|
|
91
|
-
|
|
108
|
+
There are two deployment shapes and no others:
|
|
92
109
|
|
|
93
|
-
- [
|
|
94
|
-
- [Node repository example](./examples/node/)
|
|
95
|
-
- [Code-first Docker deployment (repository-only)](https://github.com/zackbart/connecta/tree/main/examples/docker)
|
|
110
|
+
- [Node, local or Docker](./templates/node/) — what `init` copies
|
|
96
111
|
- [Cloudflare Worker deployment](./examples/worker/)
|
|
97
112
|
- [Subsystem documentation](./documentation/)
|
|
98
113
|
|