@zackbart/connecta 0.23.0 → 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.
- package/AGENTS.md +5 -0
- package/CHANGELOG.md +40 -0
- package/README.md +18 -10
- package/dist/activity-friction.d.ts +3 -0
- package/dist/activity-friction.js +19 -0
- package/dist/activity.d.ts +11 -2
- package/dist/activity.js +15 -19
- package/dist/auth/downstream-oauth.d.ts +2 -1
- package/dist/auth/downstream-oauth.js +10 -1
- package/dist/branding.d.ts +67 -0
- package/dist/branding.js +176 -0
- package/dist/connectors/remote-mcp.js +3 -5
- package/dist/credential-contract.d.ts +24 -0
- package/dist/credential-contract.js +1 -0
- package/dist/credential-rules.d.ts +85 -0
- package/dist/credential-rules.js +107 -0
- package/dist/credentials.d.ts +4 -100
- package/dist/credentials.js +3 -107
- package/dist/index.d.ts +22 -55
- package/dist/index.js +30 -58
- package/dist/invocation.js +2 -3
- package/dist/meta-tools.d.ts +4 -0
- package/dist/meta-tools.js +8 -4
- package/dist/module-contracts.d.ts +19 -0
- package/dist/module-contracts.js +1 -0
- package/dist/operator-ui/generated.js +2 -2
- package/dist/operator-ui/model.d.ts +6 -3
- package/dist/operator-ui/view.d.ts +2 -18
- package/dist/operator-ui/view.js +3 -20
- package/dist/registry.d.ts +4 -1
- package/dist/registry.js +4 -6
- package/dist/routes/activity.js +1 -1
- package/dist/routes/credentials.js +5 -2
- package/dist/routes/mcp.js +7 -3
- package/dist/routes/oauth-management.d.ts +2 -0
- package/dist/routes/oauth-management.js +108 -0
- package/dist/routes/oauth.d.ts +0 -1
- package/dist/routes/oauth.js +21 -121
- package/dist/routes/shared.d.ts +19 -17
- package/dist/routes/shared.js +48 -44
- package/dist/routes/ui.js +36 -33
- package/dist/server.js +6 -26
- package/dist/types.d.ts +2 -0
- package/dist/ui.d.ts +15 -70
- package/dist/ui.js +176 -317
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/documentation/architecture.md +26 -17
- package/documentation/auth.md +61 -106
- package/documentation/cloudflare.md +1 -1
- package/documentation/connectors.md +1 -1
- package/documentation/linear.md +1 -1
- package/documentation/meta-tools.md +6 -4
- package/documentation/mixpanel.md +1 -1
- package/documentation/notion.md +2 -2
- package/documentation/operations.md +12 -14
- package/documentation/operator-ui.md +82 -104
- package/documentation/optional-modules-upgrade.md +243 -0
- package/documentation/provider-conventions.md +5 -3
- package/documentation/revenuecat.md +1 -1
- package/documentation/storage-and-credentials.md +59 -40
- package/documentation/stripe.md +1 -1
- package/documentation/upgrading.md +29 -4
- package/ethos.md +22 -30
- package/examples/worker/AGENTS.md +3 -1
- package/examples/worker/README.md +68 -84
- package/examples/worker/src/d1-activity.ts +1 -1
- package/examples/worker/src/index.ts +11 -6
- package/package.json +18 -2
- package/templates/node/AGENTS.md +8 -6
- package/templates/node/README.md +56 -67
- package/templates/node/package.json +1 -1
- package/templates/node/src/file-activity.ts +1 -1
- package/templates/node/src/index.ts +11 -12
- package/dist/access-tokens.d.ts +0 -31
- package/dist/access-tokens.js +0 -236
- package/dist/routes/access-tokens.d.ts +0 -6
- package/dist/routes/access-tokens.js +0 -83
|
@@ -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
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
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
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
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`,
|
|
299
|
-
field on `Env`, and the `activity`
|
|
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
|
|
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
|
-
//
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
|
-
"description": "One MCP to rule them all
|
|
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": {
|
package/templates/node/AGENTS.md
CHANGED
|
@@ -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
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
package/templates/node/README.md
CHANGED
|
@@ -44,79 +44,72 @@ So commit the `package-lock.json` that the `npm install` above wrote on this
|
|
|
44
44
|
machine: from then on the build context carries it and every build takes the
|
|
45
45
|
reproducible `npm ci` path.
|
|
46
46
|
|
|
47
|
-
##
|
|
47
|
+
## Select optional modules
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
in `.env`, restart. Do them in this order; the last two lean on the first, and
|
|
54
|
-
Credentials wants one thing more than a block, called out in step 2.
|
|
49
|
+
The template explicitly enables `ui: operatorUi()` from
|
|
50
|
+
`@zackbart/connecta/ui`. Open `http://localhost:8787/` and supply the configured
|
|
51
|
+
bearer to inspect Connections. Omit that option and import for an API-only
|
|
52
|
+
server. OAuth callbacks remain in core even with no UI.
|
|
55
53
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
access token — that would make one shared secret a deployment-admin key. An
|
|
59
|
-
interactive identity is what unlocks the actionable half:
|
|
54
|
+
Connection management needs an interactive identity. A configured bearer is a
|
|
55
|
+
client key and never authorizes browser credential mutations. To enable Clerk:
|
|
60
56
|
|
|
61
57
|
```sh
|
|
62
|
-
npm install @clerk/backend
|
|
58
|
+
npm install @clerk/backend
|
|
63
59
|
```
|
|
64
60
|
|
|
65
|
-
Set `CLERK_PUBLISHABLE_KEY` and `CLERK_SECRET_KEY`,
|
|
66
|
-
import
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
61
|
+
Set `CLERK_PUBLISHABLE_KEY` and `CLERK_SECRET_KEY`, enable the corresponding
|
|
62
|
+
`clerkAuth` import and auth entry in `src/index.ts`, and set `PUBLIC_URL`.
|
|
63
|
+
Enable Dynamic Client Registration on the Clerk instance if MCP clients should
|
|
64
|
+
sign in with OAuth. Connecta no longer issues named client access tokens; keep
|
|
65
|
+
the configured bearer only for clients that need it.
|
|
70
66
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
`authScope: "personal"`
|
|
75
|
-
|
|
76
|
-
|
|
67
|
+
Set the code-owned identity resolvers deliberately. `connectorAccess` governs
|
|
68
|
+
use; `credentialAdministration` permits shared-auth changes, and
|
|
69
|
+
`personalConnection` permits the signed-in principal's personal-auth changes.
|
|
70
|
+
Both management permissions default to none. Use `authScope: "personal"` for a
|
|
71
|
+
connector where each person should connect their own downstream account.
|
|
72
|
+
`activityAccess` separately selects readers of global activity.
|
|
77
73
|
|
|
78
|
-
|
|
74
|
+
### Credential vault
|
|
75
|
+
|
|
76
|
+
Import `encryptedCredentialVault` from `@zackbart/connecta/credentials`, then
|
|
77
|
+
set `vault: encryptedCredentialVault(storage, credentialKey)`. Set
|
|
79
78
|
`CONNECTA_CREDENTIAL_KEY` to a base64 32-byte AES key:
|
|
80
79
|
|
|
81
80
|
```sh
|
|
82
81
|
node -e "console.log(crypto.randomBytes(32).toString('base64'))"
|
|
83
82
|
```
|
|
84
83
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
the state file.
|
|
115
|
-
|
|
116
|
-
None of this changes what agents can reach. Operator pages manage the
|
|
117
|
-
authentication material behind capabilities this file already declares; the
|
|
118
|
-
connector set, the tool catalog, and its annotations are `src/index.ts`'s
|
|
119
|
-
business and stay that way.
|
|
84
|
+
Keep this key outside the state file. Losing it makes saved values unreadable;
|
|
85
|
+
upgrades must reuse it. The shipped `time` connector declares no credential
|
|
86
|
+
slot. Add `credential: { label: "API token" }` to an `api()` connector and read
|
|
87
|
+
it through `await ctx.credential?.get()`, or use a provider such as `notion()`
|
|
88
|
+
that declares its own slot. Authorized humans manage the slot inside that
|
|
89
|
+
connection on `/`; there is no separate Credentials tab.
|
|
90
|
+
|
|
91
|
+
A saved replacement takes effect on the next call. Connecta tests credentials
|
|
92
|
+
only on an explicit action and otherwise fails at use. Without a vault or UI,
|
|
93
|
+
static credential recovery reports unavailable instead of offering a dead link.
|
|
94
|
+
|
|
95
|
+
### Activity history and diagnostics
|
|
96
|
+
|
|
97
|
+
Import `activityHistory` from `@zackbart/connecta/activity` and wire the template's
|
|
98
|
+
`fileActivityStore` through `activity: activityHistory({ store })`. The Activity
|
|
99
|
+
tab appears for authorized readers when the store supports listing. Omit this
|
|
100
|
+
option and its store wiring to record no activity.
|
|
101
|
+
|
|
102
|
+
`src/file-activity.ts` belongs to the deployment. It appends payload-free events
|
|
103
|
+
and periodically retains the newest 5,000, allowing a small slack window between
|
|
104
|
+
rewrites. Docker stores the log on the state volume. It records no arguments,
|
|
105
|
+
results, generated code, or raw errors. Adjust retention in that file if needed.
|
|
106
|
+
|
|
107
|
+
Diagnostics are independent. Keep the default logger or provide your own;
|
|
108
|
+
`logger: "silent"` suppresses diagnostic output explicitly.
|
|
109
|
+
|
|
110
|
+
The UI displays connections and current permissions. Configuration still owns
|
|
111
|
+
the connector set, tool definitions, and access rules. There is no token tab,
|
|
112
|
+
team roster, or policy editor.
|
|
120
113
|
|
|
121
114
|
## Deployment contract
|
|
122
115
|
|
|
@@ -153,11 +146,7 @@ Connecta doctor passed: 1 connector(s), QuickJS executed, prescribed seven-tool
|
|
|
153
146
|
`QuickJS` is this deployment's sandbox, reported by the deployment itself —
|
|
154
147
|
swap the executor and doctor names the one that actually ran the program.
|
|
155
148
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
sign in at `/` and check that the pages you turned on are there: Tokens and
|
|
161
|
-
Activity once their blocks are uncommented, and Credentials once the vault has
|
|
162
|
-
a connector credential slot to show. The nav lists a page only when this
|
|
163
|
-
deployment can serve it, so an absent page is a report, not a fault.
|
|
149
|
+
Doctor verifies the MCP contract. Verify UI behavior separately: sign in at `/`,
|
|
150
|
+
confirm the visible connections and their permitted auth controls, and check
|
|
151
|
+
Activity only when you enabled a readable history store. A missing optional
|
|
152
|
+
feature should not leave a tab behind.
|
|
@@ -27,7 +27,7 @@ import type {
|
|
|
27
27
|
ActivityStore,
|
|
28
28
|
ToolCallActivityEvent,
|
|
29
29
|
} from "@zackbart/connecta";
|
|
30
|
-
import { InvalidActivityCursorError } from "@zackbart/connecta";
|
|
30
|
+
import { InvalidActivityCursorError } from "@zackbart/connecta/activity";
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* Events allowed past `maxEvents` before the log is rewritten. Trimming on the
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { bearerToken } from "@zackbart/connecta/auth/bearer";
|
|
2
|
+
import { operatorUi } from "@zackbart/connecta/ui";
|
|
3
|
+
// import { encryptedCredentialVault } from "@zackbart/connecta/credentials";
|
|
4
|
+
// import { activityHistory } from "@zackbart/connecta/activity";
|
|
1
5
|
/**
|
|
2
6
|
* Prescribed Connecta deployment.
|
|
3
7
|
*
|
|
@@ -20,7 +24,7 @@
|
|
|
20
24
|
* CONNECTA_CREDENTIAL_KEY vault key, once the credentials block is on
|
|
21
25
|
* CONNECTA_ACTIVITY_FILE activity log, once the activity block is on
|
|
22
26
|
*/
|
|
23
|
-
import { api,
|
|
27
|
+
import { api, createConnecta } from "@zackbart/connecta";
|
|
24
28
|
import { fileStorage, listen } from "@zackbart/connecta/node";
|
|
25
29
|
import { quickJsExecutor } from "@zackbart/connecta/quickjs";
|
|
26
30
|
// Operator sign-in. Needs `npm install @clerk/backend` — it is an optional
|
|
@@ -74,7 +78,7 @@ const connecta = createConnecta({
|
|
|
74
78
|
// identity: {
|
|
75
79
|
// connectorAccess: ({ principal }) =>
|
|
76
80
|
// principal?.id === "user_admin" ? "all" : ["time"],
|
|
77
|
-
//
|
|
81
|
+
// activityAccess: ({ id }) => id === "user_admin",
|
|
78
82
|
// },
|
|
79
83
|
publicUrl,
|
|
80
84
|
// Required: model-written programs run in a bounded QuickJS child.
|
|
@@ -84,24 +88,19 @@ const connecta = createConnecta({
|
|
|
84
88
|
// with this key — so keep the key out of that file and out of source:
|
|
85
89
|
// node -e "console.log(crypto.randomBytes(32).toString('base64'))"
|
|
86
90
|
// Rotating a credential takes effect on the next call; no restart.
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
// Named, revocable Bearer tokens for MCP clients, issued at /tokens by a
|
|
90
|
-
// signed-in operator. Secrets are shown once; only their hashes are stored.
|
|
91
|
-
// Requires the Clerk block above — there is nobody to authorize issuance
|
|
92
|
-
// otherwise.
|
|
93
|
-
// accessTokens: {},
|
|
94
|
-
//
|
|
91
|
+
// vault: encryptedCredentialVault(storage, process.env.CONNECTA_CREDENTIAL_KEY!),
|
|
95
92
|
// Payload-free activity history at /activity: who called what, when, how
|
|
96
93
|
// long it took, and whether it worked. Never arguments, results, generated
|
|
97
94
|
// code, or raw error messages. Commented because retention is yours to
|
|
98
95
|
// choose — see src/file-activity.ts.
|
|
99
|
-
// activity: {
|
|
96
|
+
// activity: activityHistory({
|
|
100
97
|
// store: fileActivityStore(
|
|
101
98
|
// process.env.CONNECTA_ACTIVITY_FILE || "./.connecta-activity.jsonl",
|
|
102
99
|
// ),
|
|
103
100
|
// deploymentId: "production",
|
|
104
|
-
// },
|
|
101
|
+
// }),
|
|
102
|
+
ui: operatorUi(),
|
|
103
|
+
identity: { credentialAdministration: () => "all", personalConnection: () => "all" },
|
|
105
104
|
connectors: [
|
|
106
105
|
api("time", {
|
|
107
106
|
description: "Time — current timestamp",
|
package/dist/access-tokens.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import type { IdentityReference, InboundAuth, KVStorage } from "./types.js";
|
|
2
|
-
export interface AccessTokenMetadata {
|
|
3
|
-
id: string;
|
|
4
|
-
name: string;
|
|
5
|
-
tokenPrefix: string;
|
|
6
|
-
createdAt: string;
|
|
7
|
-
revokedAt?: string;
|
|
8
|
-
}
|
|
9
|
-
export interface CreatedAccessToken {
|
|
10
|
-
token: string;
|
|
11
|
-
accessToken: AccessTokenMetadata;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Deployment-scoped personal access tokens. Secret material is never
|
|
15
|
-
* recoverable: authentication indexes a SHA-256 digest of a random 256-bit
|
|
16
|
-
* token, while separately enumerable metadata powers operator management.
|
|
17
|
-
*/
|
|
18
|
-
export declare class AccessTokenManager {
|
|
19
|
-
private readonly storage;
|
|
20
|
-
readonly auth: InboundAuth;
|
|
21
|
-
private readonly maxActive;
|
|
22
|
-
constructor(storage: KVStorage, options?: {
|
|
23
|
-
maxActive?: number;
|
|
24
|
-
});
|
|
25
|
-
private read;
|
|
26
|
-
list(): Promise<AccessTokenMetadata[]>;
|
|
27
|
-
create(name: unknown, createdBy: string | IdentityReference): Promise<CreatedAccessToken>;
|
|
28
|
-
rename(id: string, name: unknown): Promise<AccessTokenMetadata | null>;
|
|
29
|
-
revoke(id: string, revokedBy: string): Promise<AccessTokenMetadata | null>;
|
|
30
|
-
private authorize;
|
|
31
|
-
}
|