@zackbart/connecta 0.7.9 → 0.8.1

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 (199) hide show
  1. package/CHANGELOG.md +135 -0
  2. package/README.md +47 -148
  3. package/dist/activity.d.ts +0 -8
  4. package/dist/activity.d.ts.map +1 -1
  5. package/dist/activity.js +0 -1
  6. package/dist/activity.js.map +1 -1
  7. package/dist/auth/bearer.d.ts +1 -7
  8. package/dist/auth/bearer.d.ts.map +1 -1
  9. package/dist/auth/bearer.js +3 -24
  10. package/dist/auth/bearer.js.map +1 -1
  11. package/dist/auth/clerk.d.ts +2 -11
  12. package/dist/auth/clerk.d.ts.map +1 -1
  13. package/dist/auth/clerk.js +31 -46
  14. package/dist/auth/clerk.js.map +1 -1
  15. package/dist/call-admission.d.ts.map +1 -1
  16. package/dist/call-admission.js +9 -4
  17. package/dist/call-admission.js.map +1 -1
  18. package/dist/catalog-fingerprint.d.ts +20 -0
  19. package/dist/catalog-fingerprint.d.ts.map +1 -0
  20. package/dist/catalog-fingerprint.js +34 -0
  21. package/dist/catalog-fingerprint.js.map +1 -0
  22. package/dist/catalog-limits.d.ts +10 -0
  23. package/dist/catalog-limits.d.ts.map +1 -0
  24. package/dist/catalog-limits.js +10 -0
  25. package/dist/catalog-limits.js.map +1 -0
  26. package/dist/catalog-service.d.ts +137 -0
  27. package/dist/catalog-service.d.ts.map +1 -0
  28. package/dist/catalog-service.js +401 -0
  29. package/dist/catalog-service.js.map +1 -0
  30. package/dist/catalog.d.ts +6 -0
  31. package/dist/catalog.d.ts.map +1 -1
  32. package/dist/catalog.js +53 -2
  33. package/dist/catalog.js.map +1 -1
  34. package/dist/concurrency.d.ts +4 -0
  35. package/dist/concurrency.d.ts.map +1 -0
  36. package/dist/concurrency.js +31 -0
  37. package/dist/concurrency.js.map +1 -0
  38. package/dist/connectors/api.d.ts.map +1 -1
  39. package/dist/connectors/api.js +22 -12
  40. package/dist/connectors/api.js.map +1 -1
  41. package/dist/connectors/remote-mcp.d.ts.map +1 -1
  42. package/dist/connectors/remote-mcp.js +53 -41
  43. package/dist/connectors/remote-mcp.js.map +1 -1
  44. package/dist/credentials.d.ts +3 -2
  45. package/dist/credentials.d.ts.map +1 -1
  46. package/dist/errors.d.ts +19 -1
  47. package/dist/errors.d.ts.map +1 -1
  48. package/dist/errors.js.map +1 -1
  49. package/dist/execute.d.ts +10 -16
  50. package/dist/execute.d.ts.map +1 -1
  51. package/dist/execute.js +143 -330
  52. package/dist/execute.js.map +1 -1
  53. package/dist/executor-result.d.ts +0 -3
  54. package/dist/executor-result.d.ts.map +1 -1
  55. package/dist/executor-result.js +3 -3
  56. package/dist/executor-result.js.map +1 -1
  57. package/dist/executors/quickjs-child.js +3 -3
  58. package/dist/executors/quickjs-child.js.map +1 -1
  59. package/dist/executors/quickjs-protocol.d.ts +4 -1
  60. package/dist/executors/quickjs-protocol.d.ts.map +1 -1
  61. package/dist/executors/quickjs-runtime.d.ts.map +1 -1
  62. package/dist/executors/quickjs-runtime.js +7 -2
  63. package/dist/executors/quickjs-runtime.js.map +1 -1
  64. package/dist/executors/quickjs.d.ts.map +1 -1
  65. package/dist/executors/quickjs.js +4 -1
  66. package/dist/executors/quickjs.js.map +1 -1
  67. package/dist/favicon.js +2 -2
  68. package/dist/favicon.js.map +1 -1
  69. package/dist/index.d.ts +8 -82
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +58 -104
  72. package/dist/index.js.map +1 -1
  73. package/dist/invocation.d.ts +101 -0
  74. package/dist/invocation.d.ts.map +1 -0
  75. package/dist/invocation.js +405 -0
  76. package/dist/invocation.js.map +1 -0
  77. package/dist/meta-tools.d.ts +9 -95
  78. package/dist/meta-tools.d.ts.map +1 -1
  79. package/dist/meta-tools.js +235 -725
  80. package/dist/meta-tools.js.map +1 -1
  81. package/dist/operator-ui/generated.d.ts +3 -0
  82. package/dist/operator-ui/generated.d.ts.map +1 -0
  83. package/dist/operator-ui/generated.js +5 -0
  84. package/dist/operator-ui/generated.js.map +1 -0
  85. package/dist/operator-ui/model.d.ts +73 -0
  86. package/dist/operator-ui/model.d.ts.map +1 -0
  87. package/dist/operator-ui/model.js +28 -0
  88. package/dist/operator-ui/model.js.map +1 -0
  89. package/dist/registry.d.ts +33 -184
  90. package/dist/registry.d.ts.map +1 -1
  91. package/dist/registry.js +345 -330
  92. package/dist/registry.js.map +1 -1
  93. package/dist/retired-toolkits.d.ts +3 -0
  94. package/dist/retired-toolkits.d.ts.map +1 -0
  95. package/dist/retired-toolkits.js +9 -0
  96. package/dist/retired-toolkits.js.map +1 -0
  97. package/dist/routes/activity.d.ts +3 -0
  98. package/dist/routes/activity.d.ts.map +1 -0
  99. package/dist/routes/activity.js +170 -0
  100. package/dist/routes/activity.js.map +1 -0
  101. package/dist/routes/credentials.d.ts +3 -0
  102. package/dist/routes/credentials.d.ts.map +1 -0
  103. package/dist/routes/credentials.js +170 -0
  104. package/dist/routes/credentials.js.map +1 -0
  105. package/dist/routes/mcp.d.ts +8 -0
  106. package/dist/routes/mcp.d.ts.map +1 -0
  107. package/dist/routes/mcp.js +270 -0
  108. package/dist/routes/mcp.js.map +1 -0
  109. package/dist/routes/oauth.d.ts +4 -0
  110. package/dist/routes/oauth.d.ts.map +1 -0
  111. package/dist/routes/oauth.js +263 -0
  112. package/dist/routes/oauth.js.map +1 -0
  113. package/dist/routes/shared.d.ts +76 -0
  114. package/dist/routes/shared.d.ts.map +1 -0
  115. package/dist/routes/shared.js +140 -0
  116. package/dist/routes/shared.js.map +1 -0
  117. package/dist/routes/ui.d.ts +3 -0
  118. package/dist/routes/ui.d.ts.map +1 -0
  119. package/dist/routes/ui.js +116 -0
  120. package/dist/routes/ui.js.map +1 -0
  121. package/dist/server.d.ts +9 -40
  122. package/dist/server.d.ts.map +1 -1
  123. package/dist/server.js +62 -1322
  124. package/dist/server.js.map +1 -1
  125. package/dist/skills.d.ts +3 -21
  126. package/dist/skills.d.ts.map +1 -1
  127. package/dist/skills.js +15 -43
  128. package/dist/skills.js.map +1 -1
  129. package/dist/storage/file.d.ts.map +1 -1
  130. package/dist/storage/file.js +3 -1
  131. package/dist/storage/file.js.map +1 -1
  132. package/dist/storage/memory.d.ts.map +1 -1
  133. package/dist/storage/memory.js +3 -1
  134. package/dist/storage/memory.js.map +1 -1
  135. package/dist/timeout.d.ts.map +1 -1
  136. package/dist/timeout.js +2 -4
  137. package/dist/timeout.js.map +1 -1
  138. package/dist/types.d.ts +9 -59
  139. package/dist/types.d.ts.map +1 -1
  140. package/dist/ui.d.ts +3 -94
  141. package/dist/ui.d.ts.map +1 -1
  142. package/dist/ui.js +30 -1427
  143. package/dist/ui.js.map +1 -1
  144. package/dist/version.d.ts +1 -1
  145. package/dist/version.js +1 -1
  146. package/package.json +15 -8
  147. package/src/activity.ts +0 -9
  148. package/src/auth/bearer.ts +4 -33
  149. package/src/auth/clerk.ts +35 -48
  150. package/src/call-admission.ts +8 -6
  151. package/src/catalog-fingerprint.ts +52 -0
  152. package/src/catalog-limits.ts +11 -0
  153. package/src/catalog-service.ts +601 -0
  154. package/src/catalog.ts +57 -2
  155. package/src/concurrency.ts +39 -0
  156. package/src/connectors/api.ts +22 -12
  157. package/src/connectors/remote-mcp.ts +63 -45
  158. package/src/credentials.ts +2 -2
  159. package/src/errors.ts +21 -1
  160. package/src/execute.ts +193 -423
  161. package/src/executor-result.ts +3 -3
  162. package/src/executors/quickjs-child.ts +8 -4
  163. package/src/executors/quickjs-protocol.ts +1 -1
  164. package/src/executors/quickjs-runtime.ts +5 -1
  165. package/src/executors/quickjs.ts +11 -8
  166. package/src/favicon.ts +2 -2
  167. package/src/index.ts +70 -222
  168. package/src/invocation.ts +580 -0
  169. package/src/meta-tools.ts +393 -985
  170. package/src/operator-ui/browser.css +360 -0
  171. package/src/operator-ui/browser.ts +987 -0
  172. package/src/operator-ui/generated.ts +4 -0
  173. package/src/operator-ui/model.ts +105 -0
  174. package/src/registry.ts +459 -439
  175. package/src/retired-toolkits.ts +14 -0
  176. package/src/routes/activity.ts +215 -0
  177. package/src/routes/credentials.ts +254 -0
  178. package/src/routes/mcp.ts +339 -0
  179. package/src/routes/oauth.ts +322 -0
  180. package/src/routes/shared.ts +240 -0
  181. package/src/routes/ui.ts +143 -0
  182. package/src/server.ts +64 -1731
  183. package/src/skills.ts +15 -43
  184. package/src/storage/file.ts +3 -1
  185. package/src/storage/memory.ts +3 -1
  186. package/src/timeout.ts +2 -4
  187. package/src/types.ts +8 -60
  188. package/src/ui.ts +60 -1538
  189. package/src/version.ts +1 -1
  190. package/dist/credential-health.d.ts +0 -227
  191. package/dist/credential-health.d.ts.map +0 -1
  192. package/dist/credential-health.js +0 -606
  193. package/dist/credential-health.js.map +0 -1
  194. package/dist/toolkits.d.ts +0 -146
  195. package/dist/toolkits.d.ts.map +0 -1
  196. package/dist/toolkits.js +0 -322
  197. package/dist/toolkits.js.map +0 -1
  198. package/src/credential-health.ts +0 -832
  199. package/src/toolkits.ts +0 -461
package/CHANGELOG.md CHANGED
@@ -2,6 +2,141 @@
2
2
 
3
3
  All notable changes to this package are documented here.
4
4
 
5
+ ## 0.8.1 — 2026-07-29
6
+
7
+ 0.8.1 hardens agent routing, response efficiency, and credential recovery while
8
+ making deployment boundaries the audience-scoping model. It removes toolkits
9
+ and proactive credential liveness probing: deployments still using either
10
+ retired configuration must migrate, and stale configuration fails at startup
11
+ instead of silently widening access. Deployments that use neither retired
12
+ feature need no configuration or storage migration; orphaned credential-health
13
+ records and old toolkit columns can remain unused.
14
+
15
+ Against the pre-0.8.1 release-audit baseline, all 21 task scenarios still pass,
16
+ discovery remains at 89.7% top-1 accuracy and 100% positive/default-page recall,
17
+ and discovery mean precision improves from 46.4% to 73.5%. The same 55 round
18
+ trips take 225.6 ms versus 228.4 ms of summed local-call latency (effectively
19
+ flat). Definition tokens move from 2,164 to 2,174 and request tokens from 1,144
20
+ to 1,145, while response tokens fall from 68,765 to 16,343 (-76.2%) and the
21
+ complete measured surface falls from 72,073 to 19,662 tokens (-72.7%).
22
+
23
+ ### Added
24
+
25
+ - **A current-version release audit and independently authored discovery
26
+ holdout** (#189). It exercises every meta-tool, destructive routing, OAuth
27
+ and static-credential recovery, result paging, client compatibility, and the
28
+ payload-free activity invariant on Node 20 and 22. Its evidence stays under
29
+ `eval/` and is excluded from the published package.
30
+
31
+ ### Changed
32
+
33
+ - **Lexical discovery ignores conservative conversational framing and defaults
34
+ to eight results instead of 25** (#190). Action terms such as `get`, `list`,
35
+ `search`, `find`, and `create` remain significant; cleanup that removes every
36
+ term falls back to the original query. Explicit `limit` still supports up to
37
+ 100 results, and `total`, `hasMore`, and `nextOffset` preserve complete
38
+ pagination. On the holdout, mean results fall from 14.0 to 2.853 and negative
39
+ false positives from 80% to 20%, without losing positive or default-page
40
+ recall.
41
+ - **`execute_code` is advertised only with a configured live executor** (#193).
42
+ The existing capability boundary is now explicit in instructions,
43
+ documentation, and regression coverage: deployments without code mode expose
44
+ the nine base meta-tools; deployments with it expose ten.
45
+ - **The `usage` guide is slimmer and fetched on demand** (#194). The
46
+ `skills` meta-tool and per-connector guide delivery remain unchanged, while
47
+ the generic guide drops redundant examples and keeps only routing, probe,
48
+ recovery, and code-mode rules. Server instructions now recommend fetching it
49
+ when the routing workflow is unfamiliar instead of once per task.
50
+ - **Structured results now serialize compactly in text compatibility content**
51
+ (#191). `structuredContent` remains the canonical full-fidelity object and
52
+ `content` remains complete JSON for text-only clients, but indentation no
53
+ longer inflates discovery, call, paging, batch, authorization, or code-mode
54
+ responses. Replacing the compatibility copy with a summary remains deferred
55
+ until host-forwarding measurements justify departing from MCP's compatibility
56
+ guidance.
57
+ - **Credential recovery has one agent-facing route** (#192).
58
+ `auth_required` errors now name the connector, failed operation, recovery
59
+ class, `authorize_connector` call, operator handoff, and retry. Calling
60
+ `authorize_connector` returns `recovery: "oauth"`, `"operator_config"`, or
61
+ `"unavailable"`; static handoffs expose only declared field names and
62
+ guidance plus the Clerk-protected `/credentials` URL, never credential
63
+ values. A missing `credentials.encryptionKey` now boots with an explicit
64
+ unavailable recovery state instead of preventing the deployment from
65
+ explaining the problem.
66
+ - **Toolkits are removed** (#178). `ConnectaConfig.toolkits`, toolkit bindings
67
+ on `bearerToken` and `clerkAuth`, `?toolkit=` routing, scoped registries, and
68
+ the operator UI's toolkit projection no longer exist. Passing `toolkits` or
69
+ `unscoped` to any of those construction surfaces throws instead of silently
70
+ widening access, and an `/mcp` request still carrying `?toolkit=` — a URL
71
+ minted before the retirement — gets an explicit 404 naming #178, never a
72
+ silent widening to the full registry.
73
+ - **Activity events no longer carry `toolkitId`.** The Worker D1 example drops
74
+ its `toolkit_id` column; existing columns may be left in place unused.
75
+ - **Proactive credential liveness is removed** (#179), reverting the feature
76
+ introduced in #24. `credentials.health`, legacy `credentialHealth`,
77
+ `Connecta.checkCredentials`, scheduled sweep wiring, persisted verdict reads
78
+ and writes, and `credentialCheck` response/UI fields no longer exist.
79
+ Operator-triggered credential tests and local stored-shape drift detection
80
+ remain. A drifted connector now reports `auth_required` directly from the
81
+ drift check — `list_connectors` with `probe: true` and `/ui/data` no longer
82
+ live-probe a connector whose stored credential cannot be consumed anyway.
83
+ Existing `credhealth:*` KV records are harmless orphaned data: they are
84
+ never read or rewritten, and no cleanup migration runs.
85
+
86
+ ### Fixed
87
+
88
+ - **Missing credential-vault configuration now fails at use with a typed,
89
+ actionable recovery envelope** (#192) instead of preventing the deployment
90
+ from starting before an agent or operator can diagnose it.
91
+
92
+ ## 0.8.0 — 2026-07-28
93
+
94
+ 0.8.0 is consolidation before capability growth (#157): the semantics that were
95
+ independently implemented across call paths — invocation, catalog access,
96
+ discovery bounds, timeouts — now live in shared services, the oversized modules
97
+ (`server.ts`, the operator UI) are split into typed, tested units, and the dev
98
+ loop gained correctness-only linting, an unused-code gate, strict indexed and
99
+ optional property checks, and an automated Workers test-partition guard. A
100
+ deployment can take this release without touching its config: entrypoints,
101
+ options, storage formats, and the tool surface are unchanged. The docs were
102
+ restructured — the old numbered manual is retired in favor of a terse
103
+ [`ethos.md`](./ethos.md) and stub guides in `documentation/` — and the
104
+ temporary `@hono/node-server` override is gone now that the SDK (1.30.0)
105
+ depends on a patched version upstream.
106
+
107
+ ### Added
108
+
109
+ - **`ethos.md`** — what connecta is, what it refuses to be, a decisions table,
110
+ and the invariants, each enforced or reviewer-owned (#175, PR #180). CI caps
111
+ its length; terseness is the point.
112
+ - **Route-contract and operator-UI browser tests** pinning server behavior
113
+ before extraction (#148 PR #168, #149 PR #169).
114
+ - **Automated Workers test-partition guard** — every suite must be classified
115
+ portable or Node-bound, with a reason (#150, PR #161).
116
+
117
+ ### Changed
118
+
119
+ - **Tool invocation and catalog access are shared services** used by direct,
120
+ batch, and code-mode paths alike (#144, PR #162); code-mode dispatch is lazy
121
+ (#145, PR #163); catalog discovery is deduplicated and bounded (#146,
122
+ PR #164); persisted catalogs are chunked with bounded I/O (#147/#167,
123
+ PRs #166/#172).
124
+ - **`server.ts` is a composition root** over extracted route modules (#148,
125
+ PR #170); the operator UI is typed, bundled browser source (#149, PR #169).
126
+ - **Strict indexed access and exact optional property types** are on across
127
+ src and tests (#151, PR #181); Oxlint correctness and Knip unused-code gates
128
+ run in `npm run check` (#155, PR #171).
129
+ - **`@modelcontextprotocol/sdk` 1.30.0** with the `@hono/node-server` override
130
+ removed (#40, PR #174).
131
+ - **Docs restructure** — `docs/` retired; `README.md` is a short overview and
132
+ per-subsystem guides will be rewritten in `documentation/` (#175, PR #180).
133
+ Toolkits (#178) and proactive credential liveness (#179) are recorded as
134
+ retired decisions; their code remains in this release pending removal.
135
+
136
+ ### Fixed
137
+
138
+ - Nothing user-visible; behavior-preserving consolidation throughout.
139
+
5
140
  ## 0.7.9 — 2026-07-28
6
141
 
7
142
  0.7.9 adds opt-in, connector-scoped admission for downstream tool calls. Direct
package/README.md CHANGED
@@ -2,130 +2,44 @@
2
2
 
3
3
  ![A monochrome clay Connecta hub joining many tools](./assets/connecta-clay-hero.png)
4
4
 
5
- One MCP endpoint in front of all your connectors. Agents see nine tools instead
6
- of hundreds, and each client is configured once instead of once per integration.
7
-
8
- ## The problem
9
-
10
- An agent connected to N MCP servers pays for all N before it does anything. Every
11
- server's tool list is injected into the context window at connect time — hundreds
12
- of definitions and their schemas, nearly all irrelevant to the task actually at
13
- hand. That budget is spent whether the model calls one of them or none, and it
14
- comes out of the same window the work needs.
15
-
16
- The second cost is configuration. Every client — Claude, Cursor, whatever comes
17
- next — has to be pointed at each server separately, with its own auth for each.
18
- Adding an integration means touching every client; rotating one token means
19
- finding every place it was pasted.
5
+ One MCP endpoint in front of every integration you've deliberately chosen.
6
+ Agents see a handful of meta-tools instead of hundreds of definitions, and each
7
+ client is configured once instead of once per integration.
20
8
 
21
9
  ## What connecta is
22
10
 
23
- One MCP endpoint you deploy Cloudflare Worker, Node, or Docker that
24
- aggregates your downstream connectors behind a fixed set of **nine meta-tools**.
25
- A connector is either a remote MCP server that connecta proxies, or a plain HTTP
26
- API with hand-written tool definitions and a fetch handler.
11
+ An agent connected to N MCP servers pays for all N before it does anything:
12
+ every server's full tool list lands in the context window at connect time, and
13
+ every client is pointed at every server separately, each with its own auth.
14
+ Connecta is one endpoint you deploy instead — a Cloudflare Worker or a Node
15
+ process, same code either way — aggregating your connectors behind nine
16
+ meta-tools. A connector is a remote MCP server connecta proxies or a plain
17
+ HTTP API with hand-written tool definitions; both come out identical,
18
+ addressed as `<connectorId>.<toolName>`.
27
19
 
28
20
  ```
29
21
  ┌── remoteMcp("notion") → mcp.notion.com
30
22
  Claude / Cursor ── MCP ──▶ connecta ───┼── remoteMcp("linear") → mcp.linear.app
31
- sees 9 tools /mcp ├── api("resend") → fetch(...)
23
+ sees 9 tools /mcp ├── api("resend") → fetch(...)
32
24
  └── api("internal") → fetch(...)
33
25
  ```
34
26
 
35
- Rather than receiving every tool up front, the agent discovers what it needs.
36
- `search_tools` returns ranked matches for a query and `describe_tools` returns
37
- schemas compact by default, raw JSON Schema on request — for only the
38
- addresses it is about to call. `call_tool`,
39
- `batch_call`, and `call_destructive_tool` invoke them by address
40
- (`<connectorId>.<toolName>`). `list_connectors` reports what exists and whether
41
- it is reachable, `authorize_connector` starts a downstream OAuth flow,
42
- `get_result` pages through a result too large to return inline, and `skills`
43
- hands the model a short guide to choosing among the rest.
44
-
45
- That is the entire surface. The agent's context holds nine tool definitions
46
- whether ten tools sit behind them or a thousand — and the client holds one URL
47
- and one credential, no matter how many services that URL fans out to.
48
-
49
- An optional tenth meta-tool, `execute_code`, runs model-written async JavaScript
50
- in a sandbox with no network, filesystem, or environment access — only the
51
- explicitly read-only tools as callable globals — turning a loop, a join across
52
- connectors, or a filter over a large response into one round trip instead of a
53
- dozen. The built-in Node executor runs QuickJS in bounded, replaceable child
54
- processes so guest CPU never occupies the HTTP event loop. Configure no
55
- `executor` and connecta is exactly the nine-tool server.
56
-
57
- ## Why it's shaped this way
58
-
59
- **Config as code, one deployment per tenant.** Connectors are declared in
60
- TypeScript. Adding one is a code change and a deploy — no database of
61
- integrations, no registration API, no runtime admin. A deployment is a small
62
- config file you can read in one sitting and review in a pull request, not a
63
- platform to administer.
64
-
65
- **Credentials stay server-side.** Downstream tokens live in an AES-GCM encrypted
66
- vault over the deployment's own storage, with the key held outside it. A
67
- connector reaches its own credential through `ctx.credential`; the operator
68
- pages, meta-tools, and code sandbox never expose a secret value. Rotating a token
69
- at `/credentials` is an operator action rather than a redeploy — though writing
70
- to the vault is deliberately narrower than everything else, requiring a
71
- Clerk-authenticated operator on a same-origin request, so a bearer-only
72
- deployment cannot administer credentials from the browser. Which tools exist
73
- is still code either way.
74
-
75
- **Read-only is fail-closed.** Only tools explicitly annotated `readOnlyHint:
76
- true` are reachable through `call_tool`, `batch_call`, and the sandbox. Missing,
77
- false, or contradictory annotations do not get the benefit of the doubt: they
78
- require `call_destructive_tool`, which is itself annotated so the MCP host can
79
- put the question to a human. Connecta makes the boundary visible; approval is
80
- the host's job.
81
-
82
- **Toolkits scope what a team sees.** A deployment belongs to an org; a toolkit
83
- is a named view over its registry for one group inside that org — support sees
84
- Zendesk and Notion, exec also sees Gmail. A client selects one with
85
- `?toolkit=support` on the MCP URL, and a credential can be bound so it opens
86
- that view and nothing else. Inside a scoped session an out-of-scope address
87
- fails exactly as a nonexistent one does. Two teams, one deployment. Who gets in
88
- at all is the prior question: a static bearer token, or Clerk — where
89
- `allowedDomains: ["acme.com"]` admits anyone whose verified primary email is on
90
- your domain without enumerating users, and a `gate` hook handles what a domain
91
- rule cannot express. Both fail closed, and each one configured must pass.
92
-
93
- **Activity records the fact, not the payload.** The optional activity store logs
94
- which resolved tool ran, for whom, and how it went — never arguments, results,
95
- generated code, search text, or raw error messages. The exclusion is structural
96
- rather than a redaction pass: the event type has nowhere to put a payload, which
97
- is what keeps an operations log from becoming something worth stealing.
98
-
99
- **Operator pages that cannot administer the deployment.** Connections at `GET /`
100
- shows connector health, tool counts, downstream authorization links, and a
101
- read-only map of the toolkit views declared in deployment config;
102
- `/credentials` rotates stored secrets; and `/activity` shows the optional
103
- payload-free ledger. They share one data-free shell with no build step and use
104
- authenticated private APIs for deployment data. They cannot add a connector,
105
- change policy, or alter what an agent may call. Credentials connecta stores are
106
- also probed for liveness
107
- proactively — using each connector's own test or status hook, never a downstream
108
- tool call — so a dead token surfaces as `auth_required` with the URL to open on
109
- Connections and in `list_connectors` before an agent's real call trips over it.
110
-
111
- ## When not to use it
112
-
113
- Connecta is deliberately small, and declines several tempting shapes.
114
- It is **not multi-tenant** — one deployment is one tenant, with one registry and
115
- one credential store, and toolkits are scoped views rather than tenants. There
116
- is **no policy engine**, no approvals, and no pauses — access decisions are
117
- fixed ones connecta already knows how to answer (is this tool read-only, may
118
- this credential open this toolkit), not rules you author. There is **no runtime
119
- administration** — you cannot add a connector from a browser or an API. It
120
- aggregates **tools only**, not MCP resources or prompts, and it will not ingest
121
- a **GraphQL** schema, because generating hundreds of low-quality tool
122
- definitions is the problem the nine meta-tools exist to solve. OpenAPI is a
123
- softer no: not built in today, not refused either, and tracked as
124
- [issue #26](https://github.com/zackbart/connecta/issues/26). If you want a
125
- hosted multi-tenant integration platform with an approval workflow, this is the
126
- wrong shape; the
127
- [non-goals](https://github.com/zackbart/connecta/blob/main/docs/decisions.md#non-goals)
128
- say so at more length.
27
+ The agent discovers instead of preloading: `search_tools` ranks matches,
28
+ `describe_tools` returns schemas for only the addresses about to be called,
29
+ `call_tool` / `batch_call` / `call_destructive_tool` invoke them, and
30
+ `list_connectors`, `authorize_connector`, `get_result`, and `skills` round out
31
+ the nine. An optional tenth, `execute_code`, runs model-written JavaScript in
32
+ a sandbox with no network, filesystem, or environment access — only the
33
+ read-only tools in scope. Context holds nine definitions whether ten tools sit
34
+ behind them or a thousand.
35
+
36
+ Three properties are load-bearing enough to name here; the rest live in the
37
+ [ethos](./ethos.md). **Read-only is fail-closed**: anything not explicitly
38
+ annotated read-only crosses `call_destructive_tool`, which is annotated so the
39
+ MCP host can ask a human. **Credentials stay server-side**: an encrypted
40
+ vault, rotated from an operator page, and no surface ever returns a secret.
41
+ **Config is code**: adding a connector is an edit and a deploy you can review
42
+ in a pull request.
129
43
 
130
44
  ## Getting started
131
45
 
@@ -164,42 +78,27 @@ listen(connecta, 8787); // MCP at /mcp; Connections at http://localhost:8787/
164
78
  ```
165
79
 
166
80
  Point an MCP client at `http://localhost:8787/mcp` with an
167
- `Authorization: Bearer` header and it will see the nine meta-tools, with
168
- `time.get_now` discoverable through `search_tools`.
81
+ `Authorization: Bearer` header and `time.get_now` is discoverable through
82
+ `search_tools`.
169
83
 
170
84
  Runnable deployments live in
171
- [`examples/`](https://github.com/zackbart/connecta/tree/main/examples):
172
- [`worker/`](https://github.com/zackbart/connecta/tree/main/examples/worker) is a
173
- free-tier-compatible Cloudflare Worker with KV and D1 adapters, and the template
174
- to copy for a real deployment; adding one Worker Loader binding opts it into
175
- paid Dynamic Worker code mode without changing its TypeScript;
176
- [`node/`](https://github.com/zackbart/connecta/tree/main/examples/node) adds
177
- toolkits and code mode to the server above;
178
- [`docker/`](https://github.com/zackbart/connecta/tree/main/examples/docker) is a
179
- single-service compose stack. Anything beyond the core is installed only by the
180
- deployments that use it: `@clerk/backend` and `quickjs-emscripten` are optional
181
- peer dependencies, reached through the `/auth/clerk` and `/quickjs` subpaths,
182
- and a Worker using code mode brings its own `@cloudflare/codemode`. Connecta
183
- ships no service-specific connectors:
184
- endpoint, credential, and tool choices stay in your project, declared with
185
- `remoteMcp()` and `api()`.
85
+ [`examples/`](https://github.com/zackbart/connecta/tree/main/examples): a
86
+ free-tier-compatible Cloudflare Worker with KV and D1 adapters, a Node server
87
+ extending the one above, and a single-service Docker compose stack.
88
+ Heavyweight extras are optional peers behind subpaths (`/auth/clerk`,
89
+ `/quickjs`), and connecta ships no service-specific connectors endpoint,
90
+ credential, and tool choices stay in your project.
91
+
92
+ A candid note on maturity: connecta is built for its author's deployments
93
+ first and published openly. Breaking changes are cheap and the version number
94
+ signals change, not stability the [ethos](./ethos.md) says so on purpose.
186
95
 
187
96
  ## Learn more
188
97
 
189
- - **[Documentation](https://github.com/zackbart/connecta/blob/main/docs/documentation.md)**
190
- the reference index for architecture, connectors, inbound auth and
191
- downstream OAuth, storage, Clerk setup, testing, and troubleshooting. Start
192
- with the [meta-tools reference](https://github.com/zackbart/connecta/blob/main/docs/meta-tools.md#meta-tools-reference),
193
- the [config options](https://github.com/zackbart/connecta/blob/main/docs/operations.md#running-it),
194
- [request admission](https://github.com/zackbart/connecta/blob/main/docs/request-admission.md#request-admission-and-backpressure),
195
- [code mode](https://github.com/zackbart/connecta/blob/main/docs/code-mode.md#code-mode-execute_code),
196
- [toolkits](https://github.com/zackbart/connecta/blob/main/docs/toolkits.md#toolkits-scoped-views),
197
- [operator pages](https://github.com/zackbart/connecta/blob/main/docs/operator-ui.md#status-ui),
198
- or [credential health](https://github.com/zackbart/connecta/blob/main/docs/storage-and-credentials.md#credential-health-proactive-liveness-checks).
199
- - **[Decisions](https://github.com/zackbart/connecta/blob/main/docs/decisions.md)**
200
- — what connecta refuses to be, which alternatives lost and why, and the
201
- invariants a change must preserve.
202
- - **[CHANGELOG](https://github.com/zackbart/connecta/blob/main/CHANGELOG.md)** —
203
- what changed in each release.
204
- - **[SECURITY](https://github.com/zackbart/connecta/blob/main/SECURITY.md)** —
205
- supported versions and how to report a vulnerability.
98
+ - **[ethos.md](./ethos.md)** — what this is, what it refuses to be, the
99
+ decisions table, and the invariants. Read it before proposing anything.
100
+ - **[documentation/](./documentation/)** per-subsystem guides (currently
101
+ stubs; the prior manual lives in git history).
102
+ - **[CHANGELOG](./CHANGELOG.md)** — what changed in each release.
103
+ - **[SECURITY](./SECURITY.md)** — supported versions and how to report a
104
+ vulnerability.
@@ -40,12 +40,6 @@ export interface ToolCallActivityEvent {
40
40
  serverName: string;
41
41
  serverVersion: string;
42
42
  deploymentId?: string;
43
- /**
44
- * Name of the toolkit this connection selected with `?toolkit=`, when it
45
- * selected one. Calls are recorded the same way with or without it; this only
46
- * says which scoped view the call came through.
47
- */
48
- toolkitId?: string;
49
43
  }
50
44
  export interface ActivityPage {
51
45
  events: ToolCallActivityEvent[];
@@ -92,8 +86,6 @@ export interface ActivityRequestContext {
92
86
  version: string;
93
87
  };
94
88
  deploymentId?: string;
95
- /** Toolkit this connection is scoped to, when `?toolkit=` selected one. */
96
- toolkitId?: string;
97
89
  defer?: (promise: Promise<unknown>) => void;
98
90
  logger: Logger;
99
91
  }
@@ -1 +1 @@
1
- {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,MAAM,kBAAkB,GAC1B,WAAW,GACX,uBAAuB,GACvB,YAAY,GACZ,cAAc,CAAC;AAEnB,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,OAAO,GACP,SAAS,GACT,WAAW,CAAC;AAEhB;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,CAAC,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,OAAO,EAAE,eAAe,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,qBAAqB,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,0EAA0E;AAC1E,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,qBAAqB,EAAE,OAAO,CAAC,GAAG;IACrE,KAAK,EAAE,iBAAiB,CAAC;CAC1B,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,iFAAiF;AACjF,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAED,uEAAuE;AACvE,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,OAAO,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC1E;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,IAAI,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;CAC/B;AAED,iFAAiF;AACjF,qBAAa,0BAA2B,SAAQ,KAAK;IAC1C,IAAI,SAAgC;;CAK9C;AAED,MAAM,MAAM,gBAAgB,GAAG,CAC7B,KAAK,EAAE,aAAa,KACjB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC,gFAAgF;AAChF,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,qBAAqB,EACnB,aAAa,GACb,UAAU,GACV,SAAS,GACT,QAAQ,GACR,SAAS,GACT,YAAY,GACZ,UAAU,GACV,WAAW,CACd,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,sBAAsB,GAAG,SAAS,EAC3C,KAAK,EAAE,kBAAkB,GACxB,IAAI,CAmCN"}
1
+ {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"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"}
package/dist/activity.js CHANGED
@@ -32,7 +32,6 @@ export function recordToolActivity(context, input) {
32
32
  ...(context.deploymentId
33
33
  ? { deploymentId: context.deploymentId }
34
34
  : {}),
35
- ...(context.toolkitId ? { toolkitId: context.toolkitId } : {}),
36
35
  };
37
36
  try {
38
37
  const result = context.sink.record(event);
@@ -1 +1 @@
1
- {"version":3,"file":"activity.js","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"AA+FA,iFAAiF;AACjF,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IAC1C,IAAI,GAAG,4BAA4B,CAAC;IAE7C;QACE,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACnC,CAAC;CACF;AA+BD;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAA2C,EAC3C,KAAyB;IAEzB,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,MAAM,KAAK,GAA0B;QACnC,aAAa,EAAE,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACrD,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACjD,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI;QACnC,aAAa,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO;QACzC,GAAG,CAAC,OAAO,CAAC,YAAY;YACtB,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE;YACxC,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/D,CAAC;IACF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,IAAI,OAAQ,MAA2B,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACvE,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACtD,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,KAAK;YAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;IAClE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"activity.js","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"AAyFA,iFAAiF;AACjF,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IAC1C,IAAI,GAAG,4BAA4B,CAAC;IAE7C;QACE,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACnC,CAAC;CACF;AA6BD;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAA2C,EAC3C,KAAyB;IAEzB,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,MAAM,KAAK,GAA0B;QACnC,aAAa,EAAE,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACrD,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACjD,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI;QACnC,aAAa,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO;QACzC,GAAG,CAAC,OAAO,CAAC,YAAY;YACtB,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE;YACxC,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;IACF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,IAAI,OAAQ,MAA2B,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACvE,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACtD,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,KAAK;YAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;IAClE,CAAC;AACH,CAAC"}
@@ -1,6 +1,5 @@
1
- import { type ToolkitBindingOptions } from "../toolkits.js";
2
1
  import type { InboundAuth } from "../types.js";
3
- export interface BearerTokenOptions extends ToolkitBindingOptions {
2
+ export interface BearerTokenOptions {
4
3
  /** Stable identity for this credential, used on activity events. */
5
4
  subjectId?: string;
6
5
  }
@@ -8,11 +7,6 @@ export interface BearerTokenOptions extends ToolkitBindingOptions {
8
7
  * Static bearer-token inbound auth. Constant-time compares the Bearer token
9
8
  * against `secret`. Checked BEFORE the Clerk gate in the server; a mismatch
10
9
  * falls through so a co-configured Clerk provider can still admit the request.
11
- *
12
- * `toolkits` binds the token to named toolkits (docs/toolkits.md): one
13
- * `bearerToken(...)` per team credential, each naming the view that team may
14
- * open. Omit it and the token stays unbound — every declared toolkit plus the
15
- * full registry.
16
10
  */
17
11
  export declare function bearerToken(secret: string, options?: BearerTokenOptions): InboundAuth;
18
12
  //# sourceMappingURL=bearer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bearer.d.ts","sourceRoot":"","sources":["../../src/auth/bearer.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,aAAa,CAAC;AAiB3D,MAAM,WAAW,kBAAmB,SAAQ,qBAAqB;IAC/D,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,kBAAuB,GAC/B,WAAW,CAkDb"}
1
+ {"version":3,"file":"bearer.d.ts","sourceRoot":"","sources":["../../src/auth/bearer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,aAAa,CAAC;AAiB3D,MAAM,WAAW,kBAAkB;IACjC,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,kBAAuB,GAC/B,WAAW,CA6Bb"}
@@ -1,4 +1,4 @@
1
- import { resolveToolkitBinding, } from "../toolkits.js";
1
+ import { assertNoRetiredToolkitOptions } from "../retired-toolkits.js";
2
2
  const encoder = new TextEncoder();
3
3
  /** Constant-time byte comparison. Differing lengths still iterate to reduce leak. */
4
4
  function timingSafeEqual(a, b) {
@@ -11,40 +11,19 @@ function timingSafeEqual(a, b) {
11
11
  }
12
12
  let r = 0;
13
13
  for (let i = 0; i < a.length; i++)
14
- r |= a[i] ^ b[i];
14
+ r |= (a[i] ?? 0) ^ (b[i] ?? 0);
15
15
  return r === 0;
16
16
  }
17
17
  /**
18
18
  * Static bearer-token inbound auth. Constant-time compares the Bearer token
19
19
  * against `secret`. Checked BEFORE the Clerk gate in the server; a mismatch
20
20
  * falls through so a co-configured Clerk provider can still admit the request.
21
- *
22
- * `toolkits` binds the token to named toolkits (docs/toolkits.md): one
23
- * `bearerToken(...)` per team credential, each naming the view that team may
24
- * open. Omit it and the token stays unbound — every declared toolkit plus the
25
- * full registry.
26
21
  */
27
22
  export function bearerToken(secret, options = {}) {
23
+ assertNoRetiredToolkitOptions("bearerToken", options);
28
24
  const secretBytes = encoder.encode(secret);
29
- const toolkitBinding = resolveToolkitBinding(options.subjectId
30
- ? `bearerToken (subjectId "${options.subjectId}")`
31
- : "bearerToken", options);
32
- if (toolkitBinding && !options.subjectId) {
33
- // A bound token stands for one team, and both surfaces that report on it —
34
- // the 403 refusal log (docs/toolkits.md) and activity events
35
- // (docs/operator-ui.md) — can only say "bearer" without a subjectId. With
36
- // several bound tokens that makes an operator unable to tell which
37
- // credential was refused, or whose call succeeded. console.warn (as the
38
- // Clerk adapter does) because an adapter is constructed before
39
- // `createConnecta` has a logger to hand it.
40
- console.warn("[connecta] bearerToken is bound to toolkits " +
41
- `(${toolkitBinding.toolkits.join(", ") || "unscoped only"}) but has no ` +
42
- "subjectId: refusal logs and activity events cannot say which " +
43
- "credential they came from. Pass { subjectId: \"<team>\" }.");
44
- }
45
25
  return {
46
26
  kind: "bearer",
47
- ...(toolkitBinding ? { toolkitBinding } : {}),
48
27
  authorize(request) {
49
28
  const header = request.headers.get("authorization") ?? "";
50
29
  const match = /^Bearer\s+(.+)$/i.exec(header);
@@ -1 +1 @@
1
- {"version":3,"file":"bearer.js","sourceRoot":"","sources":["../../src/auth/bearer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bearer.js","sourceRoot":"","sources":["../../src/auth/bearer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,wBAAwB,CAAC;AAGvE,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAElC,qFAAqF;AACrF,SAAS,eAAe,CAAC,CAAa,EAAE,CAAa;IACnD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;QACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3D,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,KAAK,CAAC,CAAC;AACjB,CAAC;AAOD;;;;GAIG;AACH,MAAM,UAAU,WAAW,CACzB,MAAc,EACd,UAA8B,EAAE;IAEhC,6BAA6B,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACtD,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3C,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,SAAS,CAAC,OAAO;YACf,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;YAC1D,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC9C,IAAI,KAAK,IAAI,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC;gBACpE,OAAO;oBACL,EAAE,EAAE,IAAI;oBACR,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC/D,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,QAAQ,EAAE,IAAI,QAAQ,CACpB,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,EACzC;oBACE,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE;wBACP,cAAc,EAAE,kBAAkB;wBAClC,kBAAkB,EAAE,QAAQ;qBAC7B;iBACF,CACF;aACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,8 +1,7 @@
1
1
  import { createClerkClient } from "@clerk/backend";
2
- import { type ToolkitBindingOptions } from "../toolkits.js";
3
2
  import type { InboundAuth } from "../types.js";
4
3
  type ClerkClient = ReturnType<typeof createClerkClient>;
5
- export interface ClerkAuthOptions extends ToolkitBindingOptions {
4
+ export interface ClerkAuthOptions {
6
5
  publishableKey: string;
7
6
  secretKey: string;
8
7
  /** Public base URL of this deployment. Defaults to the request origin. */
@@ -31,15 +30,7 @@ export interface ClerkAuthOptions extends ToolkitBindingOptions {
31
30
  /**
32
31
  * Clerk inbound auth.
33
32
  *
34
- * `allowedDomains` and `gate` decide WHO is admitted (both must pass);
35
- * `toolkits` decides WHICH view the admitted user gets.
36
- *
37
- * `toolkits` binds every user this provider admits to those toolkits
38
- * (docs/toolkits.md). For a per-team split, configure one `clerkAuth(...)` per
39
- * team — the same keys, a `gate` naming that team's users, and that team's
40
- * `toolkits`. The server tries providers in order and the first that admits the
41
- * user supplies the binding, so a user one gate rejects falls through to the
42
- * next.
33
+ * `allowedDomains` and `gate` decide who is admitted; both must pass.
43
34
  */
44
35
  export declare function clerkAuth(opts: ClerkAuthOptions): InboundAuth;
45
36
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"clerk.d.ts","sourceRoot":"","sources":["../../src/auth/clerk.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,aAAa,CAAC;AAE3D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAGxD,MAAM,WAAW,gBAAiB,SAAQ,qBAAqB;IAC7D,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;OAUG;IACH,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,8EAA8E;IAC9E,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1E,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,0FAA0F;IAC1F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0FAA0F;IAC1F,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8KD;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,WAAW,CAmV7D"}
1
+ {"version":3,"file":"clerk.d.ts","sourceRoot":"","sources":["../../src/auth/clerk.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,aAAa,CAAC;AAE3D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAGxD,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;OAUG;IACH,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,8EAA8E;IAC9E,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1E,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,0FAA0F;IAC1F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0FAA0F;IAC1F,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsMD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,WAAW,CAyT7D"}