@zackbart/connecta 0.22.3 → 0.24.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 (94) hide show
  1. package/AGENTS.md +5 -0
  2. package/CHANGELOG.md +82 -0
  3. package/README.md +19 -11
  4. package/dist/activity-friction.d.ts +3 -0
  5. package/dist/activity-friction.js +19 -0
  6. package/dist/activity.d.ts +11 -2
  7. package/dist/activity.js +15 -19
  8. package/dist/auth/downstream-oauth.d.ts +2 -1
  9. package/dist/auth/downstream-oauth.js +10 -1
  10. package/dist/branding.d.ts +67 -0
  11. package/dist/branding.js +176 -0
  12. package/dist/catalog-service.d.ts +1 -6
  13. package/dist/catalog-service.js +3 -53
  14. package/dist/connectors/remote-mcp.js +3 -5
  15. package/dist/credential-contract.d.ts +24 -0
  16. package/dist/credential-contract.js +1 -0
  17. package/dist/credential-rules.d.ts +85 -0
  18. package/dist/credential-rules.js +107 -0
  19. package/dist/credentials.d.ts +4 -100
  20. package/dist/credentials.js +3 -107
  21. package/dist/errors.d.ts +1 -1
  22. package/dist/execute.d.ts +5 -52
  23. package/dist/execute.js +40 -347
  24. package/dist/executors/quickjs-protocol.d.ts +0 -7
  25. package/dist/executors/quickjs-protocol.js +2 -10
  26. package/dist/executors/quickjs.js +1 -1
  27. package/dist/index.d.ts +23 -56
  28. package/dist/index.js +30 -58
  29. package/dist/invocation.d.ts +0 -33
  30. package/dist/invocation.js +56 -124
  31. package/dist/meta-tools.d.ts +7 -6
  32. package/dist/meta-tools.js +14 -21
  33. package/dist/module-contracts.d.ts +19 -0
  34. package/dist/module-contracts.js +1 -0
  35. package/dist/operator-ui/generated.js +2 -2
  36. package/dist/operator-ui/model.d.ts +6 -3
  37. package/dist/operator-ui/view.d.ts +2 -18
  38. package/dist/operator-ui/view.js +3 -20
  39. package/dist/registry.d.ts +4 -1
  40. package/dist/registry.js +8 -6
  41. package/dist/routes/activity.js +1 -1
  42. package/dist/routes/credentials.js +5 -2
  43. package/dist/routes/mcp.js +7 -51
  44. package/dist/routes/oauth-management.d.ts +2 -0
  45. package/dist/routes/oauth-management.js +108 -0
  46. package/dist/routes/oauth.d.ts +0 -1
  47. package/dist/routes/oauth.js +21 -121
  48. package/dist/routes/shared.d.ts +19 -17
  49. package/dist/routes/shared.js +48 -44
  50. package/dist/routes/ui.js +36 -33
  51. package/dist/server.d.ts +1 -2
  52. package/dist/server.js +7 -45
  53. package/dist/skills.d.ts +1 -1
  54. package/dist/skills.js +55 -19
  55. package/dist/types.d.ts +3 -15
  56. package/dist/ui.d.ts +15 -70
  57. package/dist/ui.js +176 -317
  58. package/dist/version.d.ts +1 -1
  59. package/dist/version.js +1 -1
  60. package/documentation/architecture.md +31 -26
  61. package/documentation/auth.md +65 -111
  62. package/documentation/call-admission.md +10 -11
  63. package/documentation/cloudflare.md +1 -1
  64. package/documentation/code-mode.md +65 -260
  65. package/documentation/connectors.md +8 -6
  66. package/documentation/linear.md +1 -1
  67. package/documentation/meta-tools.md +37 -18
  68. package/documentation/mixpanel.md +1 -1
  69. package/documentation/notion.md +2 -2
  70. package/documentation/operations.md +19 -23
  71. package/documentation/operator-ui.md +82 -104
  72. package/documentation/optional-modules-upgrade.md +243 -0
  73. package/documentation/provider-conventions.md +7 -5
  74. package/documentation/revenuecat.md +1 -1
  75. package/documentation/storage-and-credentials.md +59 -40
  76. package/documentation/stripe.md +1 -1
  77. package/documentation/upgrading.md +83 -8
  78. package/ethos.md +36 -43
  79. package/examples/worker/AGENTS.md +3 -1
  80. package/examples/worker/README.md +68 -84
  81. package/examples/worker/src/d1-activity.ts +1 -1
  82. package/examples/worker/src/index.ts +11 -6
  83. package/package.json +18 -2
  84. package/templates/node/AGENTS.md +8 -6
  85. package/templates/node/README.md +56 -67
  86. package/templates/node/package.json +1 -1
  87. package/templates/node/src/file-activity.ts +1 -1
  88. package/templates/node/src/index.ts +11 -12
  89. package/dist/access-tokens.d.ts +0 -31
  90. package/dist/access-tokens.js +0 -236
  91. package/dist/apps-shell.d.ts +0 -37
  92. package/dist/apps-shell.js +0 -174
  93. package/dist/routes/access-tokens.d.ts +0 -6
  94. package/dist/routes/access-tokens.js +0 -83
package/ethos.md CHANGED
@@ -1,48 +1,33 @@
1
1
  # connecta — ethos
2
2
 
3
- What connecta is, what it refuses to be, and the invariants every change must
4
- preserve. A contradiction needs a design decision, not a drive-by edit.
3
+ Connecta’s scope, refusals, and invariants. Contradictions require a design decision.
5
4
 
6
5
  ## What this is
7
6
 
8
- - **One MCP endpoint, one programmable surface.** Every integration you chose
9
- sits behind a capability catalog that agents reach by writing JavaScript,
10
- ringed by a few explicit tools for the boundaries code must not cross.
11
- - **A deployment is config-as-code.** One tenant and connector set; principals
12
- receive config-derived views.
13
- - **Curated when available, open when not.** Prefer a maintained prebuilt
14
- connection; `remoteMcp()` and `api()` stay first-class for everything else.
15
- Every path yields the same `Connector` with the same rules.
16
- - **Seven tools, an executor required.** The primary surface is a program, so
17
- every deployment runs an executor and one without refuses to boot. A
18
- capability earns a top-level tool only by being inexpressible as a program.
19
- - **Safe by default.** Only tools explicitly annotated read-only run without
20
- crossing `call_destructive_tool`, where the host can ask a human. Approval is
21
- the host's job; connecta makes the question visible.
22
- - **One fetch-native core, two runtimes.** Web APIs only in the core; Node
23
- touches live behind explicit subpaths. Cloudflare Worker or Docker, your pick.
24
- - **Observable, actionable only over authentication material.** Operator pages
25
- show status and payload-free activity and may rotate credentials, issue
26
- tokens, and run OAuth. Declared capability they cannot touch.
7
+ - **One MCP endpoint.** Agents reach configured connectors through JavaScript
8
+ and seven meta-tools. Every deployment requires an executor.
9
+ - **Config-as-code.** One tenant and connector set; identities receive
10
+ config-derived views. Maintained providers, `remoteMcp()`, and `api()` obey
11
+ the same connector contract.
12
+ - **Safe by default.** Only explicitly read-only tools run inside a program.
13
+ Others cross `call_destructive_tool`; the host owns human approval.
14
+ - **One fetch-native core.** Web APIs support Node and Workers. Platform code
15
+ and optional features use explicit subpath imports.
16
+ - **Human auth management.** Optional pages show status and payload-free history.
17
+ Explicit permissions allow credential changes and OAuth. Capabilities stay in code.
27
18
 
28
19
  ## What this isn't
29
20
 
30
- - **Not a platform.** No runtime registration, admin-editable capability,
31
- policy engine, approvals, or pauses.
32
- - **Not a schema ingester.** No OpenAPI or GraphQL tools.
33
- - **Not multi-tenant.** No accounts, groups, or sessions. Inbound auth owns
34
- identity; personal state stays within one tenant.
35
- - **Not stateful.** No protocol sessions, no server push; scope resolves per
36
- request.
37
- - **Not a nanny.** Credentials fail loudly at use; nothing probes one.
38
- - **Not a promise to strangers — yet.** Breaking changes are cheap; the version
39
- number signals change, not stability.
21
+ No runtime registration, admin-editable capabilities, policy engine, approvals,
22
+ or pauses. No schema ingestion, accounts, groups, protocol sessions, or server
23
+ push. Inbound providers own identity; personal state remains within one tenant.
24
+ Credentials fail at use, without background probes. Breaking changes remain
25
+ acceptable; version numbers signal change, not stability.
40
26
 
41
27
  ## Decisions
42
28
 
43
- Shapes considered and turned down. Proposing one again without a new argument
44
- is not allowed. Accepted designs live in their subsystem guide and the
45
- CHANGELOG, not here.
29
+ Revisiting a verdict requires a new argument. Accepted designs live in
30
+ subsystem guides and the CHANGELOG.
46
31
 
47
32
  | Decision | Verdict | Why |
48
33
  | --- | --- | --- |
@@ -50,10 +35,13 @@ CHANGELOG, not here.
50
35
  | Multi-tenancy / account model | refused | one deployment per tenant; inbound auth owns identity |
51
36
  | Policy engine, approvals, pauses | refused | the host asks the human; connecta only annotates |
52
37
  | Runtime connector registration | refused | config-as-code is the security model |
38
+ | Optional deployment modules | accepted | explicit imports and typed config slots select UI, activity history, credential vault, and inbound auth; discovery, execution, invocation, and enforcement stay in core |
39
+ | Generic plugin lifecycle or marketplace | refused | modules organize deployment code; runtime installation and discovery add no required behavior |
40
+ | Connecta-issued access tokens | removed | inbound identity providers own client authentication; configured bearer auth remains an optional adapter |
53
41
  | Provider registry / marketplace | refused | prebuilt connections are imports; discovery happens in docs ([#297](https://github.com/zackbart/connecta/issues/297)) |
54
42
  | Expanded Notion page create/update options | refused | different workflows, not missing fields; use `api()` ([#408](https://github.com/zackbart/connecta/issues/408)) |
55
43
  | Protocol sessions & server push | refused | stateless per request |
56
- | Resources & prompts aggregation | refused | tools only; the Apps shell is the one `resources/read` carve-out ([#266](https://github.com/zackbart/connecta/issues/266)) |
44
+ | Resources & prompts aggregation | refused | tools only; clients own presentation ([#266](https://github.com/zackbart/connecta/issues/266)) |
57
45
  | Elicitation passthrough | refused | no route through a stateless aggregator |
58
46
  | Repository formatter | refused | style is authored, not enforced |
59
47
  | Host-side projection of program results | refused | a program projects; a heuristic drops fields invisibly ([#223](https://github.com/zackbart/connecta/issues/223)) |
@@ -67,6 +55,11 @@ CHANGELOG, not here.
67
55
  | Legacy embedded `UIResource` delivery | refused | superseded upstream, rendered by no client we face ([#266](https://github.com/zackbart/connecta/issues/266)) |
68
56
  | Effect as the core effect system | refused | −4% of the core for +75 KB gzip and a second async paradigm; re-measure at v4 stable ([#470](https://github.com/zackbart/connecta/issues/470)) |
69
57
  | Shared bounded queue under both admission controllers | refused | built and measured −17 lines for a hook-parameterised abstraction ([#453](https://github.com/zackbart/connecta/issues/453)) |
58
+ | MCP Apps rendering and `connecta.ui` | removed | clients render returned data |
59
+ | Connector shortcut globals | removed | canonical addresses need no sanitization |
60
+ | `connecta.batch` | removed | JavaScript promises suffice |
61
+ | Automatic direct-call retries | removed | callers own retry timing |
62
+ | Connector HTTP routes | removed | deployments own custom routes |
70
63
  | Caller-selected toolkits | removed | only config may derive an identity's connector view ([#178](https://github.com/zackbart/connecta/issues/178)) |
71
64
  | Proactive credential liveness | removed | fail-at-use is enough ([#179](https://github.com/zackbart/connecta/issues/179)) |
72
65
  | Classic (executor-free) surface | removed | an executor is mandatory ([#273](https://github.com/zackbart/connecta/issues/273)) |
@@ -75,14 +68,14 @@ CHANGELOG, not here.
75
68
  | Semantic tool search | gated | keyword search has not been shown to fail ([#27](https://github.com/zackbart/connecta/issues/27)) |
76
69
  | MRTR / `input_required` passthrough | gated | relayable statelessly; no host or downstream emits it yet ([#176](https://github.com/zackbart/connecta/issues/176)) |
77
70
  | Downstream `ttlMs` cache hints | gated | needs refresh-churn evidence ([#206](https://github.com/zackbart/connecta/issues/206)) |
78
- | Downstream MCP Apps template passthrough | gated | needs a downstream that ships one ([#266](https://github.com/zackbart/connecta/issues/266)) |
71
+ | Downstream MCP Apps template passthrough | refused | clients own presentation; Connecta serves tools and data |
79
72
  | Worker Access inbound auth | provisional | Managed OAuth and Clerk migration need production evidence ([#506](https://github.com/zackbart/connecta/issues/506)) |
80
- | Program UI tool calls | removed | the read bridge added a second contract without improving agent data retrieval; views are display-only again ([#287](https://github.com/zackbart/connecta/issues/287), [#484](https://github.com/zackbart/connecta/issues/484)) |
73
+ | Program UI tool calls | removed | duplicated calls without improving retrieval ([#287](https://github.com/zackbart/connecta/issues/287), [#484](https://github.com/zackbart/connecta/issues/484)) |
81
74
 
82
75
  ## Invariants
83
76
 
84
- One line each; the enforcing tests live beside the subsystem documentation.
85
- Breaking one is a design change wearing a disguise.
77
+ Tests beside subsystem documentation enforce these invariants. Breaking one
78
+ requires a design decision.
86
79
 
87
80
  - **Fail-closed read-only.** A missing, false, or contradictory annotation never gets the benefit of the doubt.
88
81
  - **Generated code cannot mint capabilities.** Admission, credentials, and classification are enforced below the sandbox.
@@ -94,9 +87,9 @@ Breaking one is a design change wearing a disguise.
94
87
  - **Credentials never leave the host.** Encrypted at rest, readable only by the owning connector and, for personal auth, its owning principal; rendered by nothing.
95
88
  - **Import-graph purity.** Nothing reachable from the root entry imports a `node:` builtin.
96
89
  - **The published surface is a boundary.** Heavyweight or platform-bound code goes behind an optional-peer subpath.
97
- - **Human routes manage auth, never capability.** Signed-in humans manage auth for visible connectors; operators also manage tokens and global activity.
90
+ - **Human routes manage auth, never capability.** Visibility grants use, not credential administration. Shared and personal auth mutations require separate config-derived permissions, both denied by default. Activity has its own read permission.
91
+ - **Omitted modules do no work.** Core imports no UI bundle, encrypted vault implementation, activity implementation, or bearer adapter. OAuth callbacks remain available without UI.
92
+ - **Status reads do not start authorization.** OAuth starts through an explicit authorized action; loading the UI never creates a consent flow.
98
93
  - **Structural mistakes throw at construction.** Booting into the wrong shape is worse than not booting.
99
94
 
100
- Connecta began as a radical simplification of
101
- [executor](https://github.com/UsefulSoftwareCo/executor); this file is the
102
- record of that simplification holding.
95
+ Connecta simplifies [executor](https://github.com/UsefulSoftwareCo/executor).
@@ -34,7 +34,9 @@ This repository is deployment configuration, not a copy of Connecta itself.
34
34
  - Prefer `api()` when the agent must see an exact reviewed capability set;
35
35
  `remoteMcp()` follows the downstream server's evolving tool catalog.
36
36
  - Use Access service credentials for `connecta doctor` and unattended clients.
37
- A `cta_` token or static Connecta bearer cannot cross the Access edge alone.
37
+ A configured Connecta bearer cannot cross the Access edge alone. Connecta-issued
38
+ tokens are removed. UI, vault, and activity use explicit optional imports;
39
+ auth changes require code-derived shared or personal management permissions.
38
40
  - Run the repository's `npm run check:examples` after configuration changes.
39
41
  After deployment, connect both Claude and ChatGPT to `<PUBLIC_URL>/mcp` and
40
42
  complete their browser authorization flows before calling setup complete.
@@ -120,96 +120,80 @@ discover the skew in production ([#376](https://github.com/zackbart/connecta/iss
120
120
  no Clerk import, secret, package, or fallback provider. Docker deployments keep
121
121
  the Clerk path in the Node template.
122
122
 
123
- Then point an MCP client at `<PUBLIC_URL>/mcp`, and open `<PUBLIC_URL>/` for
124
- Connections. Credentials is at `/credentials`, named MCP access tokens are at
125
- `/tokens`, Activity is at `/activity`, and legacy `/ui` redirects to `/`. Each
126
- of those three appears in the nav only when this deployment can serve it — see
127
- the next section for what turns each one on.
128
-
129
- ## The operator surface
130
-
131
- This example ships the whole operator feature set. Three quarters of it is on
132
- as deployed; the fourth needs a database, so it is commented in place.
133
-
134
- **Operator sign-in** is the `cloudflareAccessAuth()` entry in `src/index.ts`.
135
- Access authenticates before the Worker runs. A human Access identity can use
136
- MCP and human-management pages; a service-token identity can use MCP but cannot
137
- write a credential, run downstream OAuth, or issue a connecta token. Cloudflare
138
- still owns the outer application admission policy, but Connecta's user roster,
139
- connector access, and deployment roles stay in `src/index.ts`.
140
-
141
- **Several users** need no second auth system or Connecta account dashboard.
142
- Uncomment the `identity` block in `src/index.ts` to derive connector ids and
143
- deployment-operator membership from the Access principal. Connectors remain
144
- visible to everyone and every human remains an operator when that block is
145
- absent. A signed-in human may edit auth for every connector their view includes.
146
- Add `authScope: "personal"` when each user should connect a different downstream
147
- account; leave it shared only when any user with connector access may rotate the
148
- deployment-wide grant. Static headers stay shared because their value lives in
149
- deployment configuration. See [inbound identity](../../documentation/auth.md#principals-visibility-and-operators)
150
- for the resolver contract.
151
-
152
- **The credential vault** is `credentials: { encryptionKey: … }`, backed by the
153
- same KV namespace as everything else and encrypted with the
154
- `CREDENTIAL_ENCRYPTION_KEY` secret before a value reaches it. Generate one with:
123
+ Then point an MCP client at `<PUBLIC_URL>/mcp`. The example explicitly enables
124
+ `ui: operatorUi()`; open `<PUBLIC_URL>/` for Connections and each connection's
125
+ authentication controls. There is no separate Credentials or Tokens tab.
126
+
127
+ ## Select optional modules
128
+
129
+ `cloudflareAccessAuth()` reads trusted identity after Access admits the Worker
130
+ request. Humans may use their code-derived connector view; service identities
131
+ can use MCP but cannot manage personal or shared auth as an interactive human.
132
+ Keep users, groups, and admission in Access. Connector visibility and management
133
+ permissions belong in `src/index.ts`.
134
+
135
+ `identity.connectorAccess` selects discoverable and callable connectors.
136
+ `credentialAdministration` separately allows shared credential and OAuth
137
+ management, while `personalConnection` allows a human to connect their own
138
+ account. Both management permissions default to none. Grant the intended
139
+ owner's shared permissions explicitly, and grant users personal permissions
140
+ only for connectors configured with `authScope: "personal"`. Static headers
141
+ remain deployment configuration. `activityAccess` governs global history reads.
142
+ See [inbound identity](../../documentation/auth.md#principals-visibility-and-operators).
143
+
144
+ ### UI and encrypted credentials
145
+
146
+ Import `operatorUi` from `@zackbart/connecta/ui` and set `ui: operatorUi()`.
147
+ Branding belongs in `operatorUi({ branding })`. Omit the import and option to
148
+ serve no UI routes; OAuth callbacks still work in core for authorized
149
+ interactive MCP callers.
150
+
151
+ Import `encryptedCredentialVault` from `@zackbart/connecta/credentials` and set
152
+ `vault: encryptedCredentialVault(storage, env.CREDENTIAL_ENCRYPTION_KEY)` when
153
+ the secret is configured. Keep this base64 32-byte key in Worker secrets:
155
154
 
156
155
  ```sh
157
156
  node -e "console.log(crypto.randomBytes(32).toString('base64'))"
158
157
  ```
159
158
 
160
- Leave the secret unset and the deployment still runs `/credentials` stays
161
- read-only and connecta says so at startup. Keep the key in Worker secrets and
162
- nowhere near KV: it is the only thing that makes a copied namespace useless.
163
- Rotation takes effect on the next call, with no redeploy and no liveness probe,
164
- because credentials fail at use.
165
-
166
- The vault is ready here, and the Credentials page is still hidden, because that
167
- page lists connector credential slots rather than deployments. Neither
168
- connector in `src/index.ts` declares one Notion carries a deployment-owned
169
- static header and echo has no secret — so nothing would be on the page. Add
170
- `credential: { label: "API token" }` to an `api()` connector (the commented
171
- shape on `echo` is exactly it) or use a provider connector such as `notion()`,
172
- which declares its own, and Credentials appears for a signed-in operator on the
173
- next load.
174
-
175
- **Access tokens** are `accessTokens: {}`. A signed-in human operator mints named,
176
- revocable Bearer tokens at `/tokens` for header-capable clients that will not do
177
- OAuth. Secrets are shown once and only their hashes enter KV; a lost token is
178
- reissued, never recovered. Note the KV caveat above — revocation is visible
179
- everywhere only as fast as the namespace converges.
180
-
181
- Worker-level Access still runs before these tokens. A `cta_…` token therefore
182
- does not reach connecta by itself; retain the feature as a rollback path or for
183
- a caller that already supplies separate Access service-token headers. Normal
184
- interactive MCP clients should use Managed OAuth, and unattended clients should
185
- use Access service tokens.
186
-
187
- **Activity** is the commented block in `src/index.ts` and the commented
188
- `d1_databases` binding in `wrangler.jsonc`; the section below creates the
189
- database and applies the schema.
190
-
191
- None of these change what agents can reach. Operator routes manage the
192
- authentication material behind capabilities `src/index.ts` already declares —
193
- never the connector set, the tool catalog, or its annotations.
194
-
195
- `connecta doctor` reports the same line here as for a deployment with none of
196
- this on: connector count, executor, seven tools. The executor it names is this
197
- one — `DynamicWorkerExecutor executed`, not the Node template's QuickJS, which
198
- is what doctor used to claim everywhere
199
- ([#368](https://github.com/zackbart/connecta/issues/368)). Against Access it
200
- carries `CF_ACCESS_CLIENT_ID` and `CF_ACCESS_CLIENT_SECRET`, and the service
201
- identity learns the model-facing surface rather than deployment topology:
159
+ Reuse the same key and KV namespace during upgrades. Without the secret, omit
160
+ the vault; declared credential slots remain unmanageable. Keep the key outside
161
+ KV because it protects a copied namespace. Credential replacement takes effect
162
+ on the next call without redeploying; no liveness probe runs in the background.
163
+
164
+ The shipped Notion connector uses a deployment-owned static header and echo
165
+ needs no secret. To exercise vault controls, declare a `credential` slot on an
166
+ `api()` connector or use a provider such as `notion()` that declares its own.
167
+ Authorized users manage that slot inside the connection. Configuring a vault
168
+ does not create credentials or permissions by itself.
169
+
170
+ ### Client authentication and activity
171
+
172
+ Interactive MCP clients use Access Managed OAuth. Unattended clients use Access
173
+ service tokens when needed. Connecta-issued `cta_` tokens and their management
174
+ routes are removed; a configured Connecta bearer cannot cross the Access edge
175
+ alone. See the [migration guide](../../documentation/upgrading.md#0240-optional-modules)
176
+ if an older deployment still issues tokens.
177
+
178
+ Activity uses `activityHistory({ store: d1ActivityStore(env.ACTIVITY_DB) })`
179
+ from `@zackbart/connecta/activity`. Enable the database and bindings described
180
+ below. Omit the module and store wiring to record no history and show no
181
+ Activity tab. Diagnostics remain independent; `logger: "silent"` suppresses
182
+ them explicitly.
183
+
184
+ Verify MCP health and the exact seven tools with:
202
185
 
203
186
  ```sh
204
187
  CF_ACCESS_CLIENT_ID=… CF_ACCESS_CLIENT_SECRET=… \
205
188
  npx connecta doctor --url "$PUBLIC_URL"
206
189
  ```
207
190
 
208
- Confirm the operator surface the way an operator will: sign in at
209
- `<PUBLIC_URL>/` and check that Tokens is live. Credentials joins it
210
- once a connector declares a `credential` slot, and Activity once the D1 wiring
211
- below is on the nav shows a page when the deployment can actually serve it,
212
- so a missing page is the honest report that its half is still off.
191
+ Doctor reports the configured `DynamicWorkerExecutor`, not a presumed Node
192
+ executor. Verify the UI separately as a human: check visible connections,
193
+ explicit shared and personal auth permissions, and Activity only when enabled.
194
+ The configured list loads before live connector checks; a slow provider must
195
+ not prevent other connections from appearing. All capability and access changes
196
+ still require a deployment-code change.
213
197
 
214
198
  ## Code mode
215
199
 
@@ -295,19 +279,19 @@ To enable it:
295
279
  the failure and returns the tool result unharmed — so the symptom is not an
296
280
  error your agent sees, it is an activity log that quietly stops recording.
297
281
 
298
- 3. In `src/index.ts`, uncomment the `d1ActivityStore` import, the `ACTIVITY_DB`
299
- field on `Env`, and the `activity` block — the three commented fragments
300
- that together read:
282
+ 3. In `src/index.ts`, enable the `activityHistory` and `d1ActivityStore` imports,
283
+ the `ACTIVITY_DB` field on `Env`, and the `activity` option:
301
284
 
302
285
  ```ts
286
+ import { activityHistory } from "@zackbart/connecta/activity";
303
287
  import { d1ActivityStore } from "./d1-activity.js";
304
288
 
305
289
  createConnecta({
306
290
  // …
307
- activity: {
291
+ activity: activityHistory({
308
292
  store: d1ActivityStore(env.ACTIVITY_DB),
309
293
  deploymentId: "production",
310
- },
294
+ }),
311
295
  });
312
296
  ```
313
297
 
@@ -2,7 +2,7 @@ import type {
2
2
  ActivityPage,
3
3
  ActivityStore,
4
4
  } from "@zackbart/connecta";
5
- import { InvalidActivityCursorError } from "@zackbart/connecta";
5
+ import { InvalidActivityCursorError } from "@zackbart/connecta/activity";
6
6
  import {
7
7
  activityEventToRow,
8
8
  activityRowToEvent,
@@ -1,3 +1,6 @@
1
+ import { operatorUi } from "@zackbart/connecta/ui";
2
+ // import { activityHistory } from "@zackbart/connecta/activity";
3
+ import { encryptedCredentialVault } from "@zackbart/connecta/credentials";
1
4
  /**
2
5
  * connecta on Cloudflare Workers.
3
6
  *
@@ -63,9 +66,10 @@ interface Env {
63
66
  }
64
67
 
65
68
  function build(env: Env) {
69
+ const storage = cloudflareKvStorage(env.CONNECTA_KV);
66
70
  return createConnecta({
67
71
  publicUrl: env.PUBLIC_URL,
68
- storage: cloudflareKvStorage(env.CONNECTA_KV),
72
+ storage,
69
73
  executor: new DynamicWorkerExecutor({ loader: env.LOADER }),
70
74
  auth: [
71
75
  // Access owns admission policy. A human identity may use MCP and the
@@ -83,7 +87,7 @@ function build(env: Env) {
83
87
  // principal?.id === "ACCESS_USER_UUID"
84
88
  // ? ["notion", "echo"]
85
89
  // : ["echo"],
86
- // operatorAccess: ({ id }) => id === "ACCESS_USER_UUID",
90
+ // activityAccess: ({ id }) => id === "ACCESS_USER_UUID",
87
91
  // },
88
92
  // Connectors that declare a `credential` slot become editable by every
89
93
  // signed-in human who can see that connector at /credentials, encrypted
@@ -98,19 +102,20 @@ function build(env: Env) {
98
102
  // ready and the page empty. Declare a slot (see the commented shape on
99
103
  // `echo`, or use a provider connector like `notion()`, which declares its
100
104
  // own) and the page appears on the next load.
101
- credentials: { encryptionKey: env.CREDENTIAL_ENCRYPTION_KEY },
105
+ vault: encryptedCredentialVault(storage, env.CREDENTIAL_ENCRYPTION_KEY),
102
106
  // Eligible human operators can create named, revocable MCP Bearer tokens
103
107
  // at /tokens. Under Worker-level Access those tokens are a rollback tool,
104
108
  // not standalone edge credentials: Access still runs before connecta.
105
- accessTokens: {},
109
+ ui: operatorUi(),
110
+ identity: { credentialAdministration: () => "all", personalConnection: () => "all" },
106
111
  // Payload-free activity at /activity, off until a database exists to hold
107
112
  // it. Uncomment the `d1_databases` binding in wrangler.jsonc, apply the
108
113
  // schema in README.md § "Activity history", then these three lines and the
109
114
  // import above.
110
- // activity: {
115
+ // activity: activityHistory({
111
116
  // store: d1ActivityStore(env.ACTIVITY_DB),
112
117
  // deploymentId: "production",
113
- // },
118
+ // }),
114
119
  connectors: [
115
120
  remoteMcp("notion", {
116
121
  url: "https://mcp.notion.com/mcp",
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@zackbart/connecta",
3
- "version": "0.22.3",
3
+ "version": "0.24.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
- "description": "One MCP to rule them all a single MCP endpoint aggregating many downstream connectors behind a code-first surface of seven meta-tools.",
6
+ "description": "One MCP to rule them all \u2014 a single MCP endpoint aggregating many downstream connectors behind a code-first surface of seven meta-tools.",
7
7
  "license": "MIT",
8
8
  "engines": {
9
9
  "node": ">=22.0.0"
@@ -94,6 +94,22 @@
94
94
  "./providers/vercel": {
95
95
  "types": "./dist/providers/vercel.d.ts",
96
96
  "import": "./dist/providers/vercel.js"
97
+ },
98
+ "./ui": {
99
+ "types": "./dist/ui.d.ts",
100
+ "import": "./dist/ui.js"
101
+ },
102
+ "./credentials": {
103
+ "types": "./dist/credentials.d.ts",
104
+ "import": "./dist/credentials.js"
105
+ },
106
+ "./activity": {
107
+ "types": "./dist/activity.d.ts",
108
+ "import": "./dist/activity.js"
109
+ },
110
+ "./auth/bearer": {
111
+ "types": "./dist/auth/bearer.d.ts",
112
+ "import": "./dist/auth/bearer.js"
97
113
  }
98
114
  },
99
115
  "scripts": {
@@ -12,12 +12,14 @@ This repository is deployment configuration, not a copy of Connecta itself.
12
12
  Do not copy or modify Connecta package internals here.
13
13
  - Prefer `api()` when the agent must see an exact reviewed capability surface;
14
14
  `remoteMcp()` follows the downstream server's evolving tool catalog.
15
- - The operator surface — Clerk sign-in, credential vault, access tokens,
16
- activity ships as commented blocks in `src/index.ts`. Enable one by
17
- uncommenting it and setting the variables it names in `.env`, never by
18
- inventing a parallel configuration path. `README.md` § "Turn on the operator
19
- surface" is the walkthrough; `src/file-activity.ts` is the deployment-owned
20
- activity store the activity block wires.
15
+ - The UI, encrypted credential vault, and activity history use explicit module
16
+ imports and typed `ui`, `vault`, and `activity` options in `src/index.ts`.
17
+ Follow README "Select optional modules". Auth management requires explicit
18
+ `credentialAdministration` or `personalConnection` permissions; visibility
19
+ alone never grants it. Configured bearer auth is a client option, not a human
20
+ management identity. Connecta-issued access tokens are removed.
21
+ `src/file-activity.ts` remains the deployment-owned history store.
22
+
21
23
  - Run `npm run typecheck` after configuration changes. With the server running,
22
24
  run `CONNECTA_TOKEN=... npm run doctor` before calling setup complete.
23
25
  - `Dockerfile` and `docker-compose.yml` containerize *this* source; they are