@zackbart/connecta 0.7.8 → 0.8.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 (187) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/README.md +67 -144
  3. package/dist/activity.d.ts +1 -1
  4. package/dist/activity.d.ts.map +1 -1
  5. package/dist/activity.js.map +1 -1
  6. package/dist/auth/bearer.d.ts +1 -1
  7. package/dist/auth/bearer.js +4 -4
  8. package/dist/auth/bearer.js.map +1 -1
  9. package/dist/auth/clerk.d.ts +1 -1
  10. package/dist/auth/clerk.js +1 -1
  11. package/dist/call-admission.d.ts +81 -0
  12. package/dist/call-admission.d.ts.map +1 -0
  13. package/dist/call-admission.js +345 -0
  14. package/dist/call-admission.js.map +1 -0
  15. package/dist/catalog-fingerprint.d.ts +20 -0
  16. package/dist/catalog-fingerprint.d.ts.map +1 -0
  17. package/dist/catalog-fingerprint.js +34 -0
  18. package/dist/catalog-fingerprint.js.map +1 -0
  19. package/dist/catalog-limits.d.ts +10 -0
  20. package/dist/catalog-limits.d.ts.map +1 -0
  21. package/dist/catalog-limits.js +10 -0
  22. package/dist/catalog-limits.js.map +1 -0
  23. package/dist/catalog-service.d.ts +138 -0
  24. package/dist/catalog-service.d.ts.map +1 -0
  25. package/dist/catalog-service.js +407 -0
  26. package/dist/catalog-service.js.map +1 -0
  27. package/dist/catalog.js +2 -2
  28. package/dist/catalog.js.map +1 -1
  29. package/dist/concurrency.d.ts +4 -0
  30. package/dist/concurrency.d.ts.map +1 -0
  31. package/dist/concurrency.js +31 -0
  32. package/dist/concurrency.js.map +1 -0
  33. package/dist/connectors/api.d.ts +3 -1
  34. package/dist/connectors/api.d.ts.map +1 -1
  35. package/dist/connectors/api.js +22 -11
  36. package/dist/connectors/api.js.map +1 -1
  37. package/dist/connectors/remote-mcp.d.ts +3 -1
  38. package/dist/connectors/remote-mcp.d.ts.map +1 -1
  39. package/dist/connectors/remote-mcp.js +44 -18
  40. package/dist/connectors/remote-mcp.js.map +1 -1
  41. package/dist/credential-health.d.ts +0 -22
  42. package/dist/credential-health.d.ts.map +1 -1
  43. package/dist/credential-health.js +14 -10
  44. package/dist/credential-health.js.map +1 -1
  45. package/dist/credentials.d.ts +3 -2
  46. package/dist/credentials.d.ts.map +1 -1
  47. package/dist/errors.d.ts +1 -1
  48. package/dist/errors.d.ts.map +1 -1
  49. package/dist/errors.js.map +1 -1
  50. package/dist/execute.d.ts +9 -8
  51. package/dist/execute.d.ts.map +1 -1
  52. package/dist/execute.js +144 -291
  53. package/dist/execute.js.map +1 -1
  54. package/dist/executor-result.d.ts +0 -3
  55. package/dist/executor-result.d.ts.map +1 -1
  56. package/dist/executor-result.js +2 -2
  57. package/dist/executor-result.js.map +1 -1
  58. package/dist/executors/quickjs-child.js +3 -3
  59. package/dist/executors/quickjs-child.js.map +1 -1
  60. package/dist/executors/quickjs-protocol.d.ts +4 -1
  61. package/dist/executors/quickjs-protocol.d.ts.map +1 -1
  62. package/dist/executors/quickjs-runtime.d.ts.map +1 -1
  63. package/dist/executors/quickjs-runtime.js +7 -2
  64. package/dist/executors/quickjs-runtime.js.map +1 -1
  65. package/dist/executors/quickjs.d.ts.map +1 -1
  66. package/dist/executors/quickjs.js +4 -1
  67. package/dist/executors/quickjs.js.map +1 -1
  68. package/dist/favicon.js +2 -2
  69. package/dist/favicon.js.map +1 -1
  70. package/dist/index.d.ts +6 -1
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +45 -17
  73. package/dist/index.js.map +1 -1
  74. package/dist/invocation.d.ts +96 -0
  75. package/dist/invocation.d.ts.map +1 -0
  76. package/dist/invocation.js +369 -0
  77. package/dist/invocation.js.map +1 -0
  78. package/dist/meta-tools.d.ts +11 -86
  79. package/dist/meta-tools.d.ts.map +1 -1
  80. package/dist/meta-tools.js +145 -485
  81. package/dist/meta-tools.js.map +1 -1
  82. package/dist/operator-ui/generated.d.ts +3 -0
  83. package/dist/operator-ui/generated.d.ts.map +1 -0
  84. package/dist/operator-ui/generated.js +5 -0
  85. package/dist/operator-ui/generated.js.map +1 -0
  86. package/dist/operator-ui/model.d.ts +94 -0
  87. package/dist/operator-ui/model.d.ts.map +1 -0
  88. package/dist/operator-ui/model.js +28 -0
  89. package/dist/operator-ui/model.js.map +1 -0
  90. package/dist/registry.d.ts +47 -6
  91. package/dist/registry.d.ts.map +1 -1
  92. package/dist/registry.js +356 -35
  93. package/dist/registry.js.map +1 -1
  94. package/dist/routes/activity.d.ts +3 -0
  95. package/dist/routes/activity.d.ts.map +1 -0
  96. package/dist/routes/activity.js +173 -0
  97. package/dist/routes/activity.js.map +1 -0
  98. package/dist/routes/credentials.d.ts +3 -0
  99. package/dist/routes/credentials.d.ts.map +1 -0
  100. package/dist/routes/credentials.js +181 -0
  101. package/dist/routes/credentials.js.map +1 -0
  102. package/dist/routes/mcp.d.ts +8 -0
  103. package/dist/routes/mcp.d.ts.map +1 -0
  104. package/dist/routes/mcp.js +383 -0
  105. package/dist/routes/mcp.js.map +1 -0
  106. package/dist/routes/oauth.d.ts +4 -0
  107. package/dist/routes/oauth.d.ts.map +1 -0
  108. package/dist/routes/oauth.js +268 -0
  109. package/dist/routes/oauth.js.map +1 -0
  110. package/dist/routes/shared.d.ts +97 -0
  111. package/dist/routes/shared.d.ts.map +1 -0
  112. package/dist/routes/shared.js +199 -0
  113. package/dist/routes/shared.js.map +1 -0
  114. package/dist/routes/ui.d.ts +3 -0
  115. package/dist/routes/ui.d.ts.map +1 -0
  116. package/dist/routes/ui.js +122 -0
  117. package/dist/routes/ui.js.map +1 -0
  118. package/dist/server.d.ts +9 -40
  119. package/dist/server.d.ts.map +1 -1
  120. package/dist/server.js +67 -1292
  121. package/dist/server.js.map +1 -1
  122. package/dist/skills.d.ts +0 -15
  123. package/dist/skills.d.ts.map +1 -1
  124. package/dist/skills.js +6 -5
  125. package/dist/skills.js.map +1 -1
  126. package/dist/storage/file.d.ts.map +1 -1
  127. package/dist/storage/file.js +3 -1
  128. package/dist/storage/file.js.map +1 -1
  129. package/dist/storage/memory.d.ts.map +1 -1
  130. package/dist/storage/memory.js +3 -1
  131. package/dist/storage/memory.js.map +1 -1
  132. package/dist/toolkits.d.ts +0 -22
  133. package/dist/toolkits.d.ts.map +1 -1
  134. package/dist/toolkits.js +2 -2
  135. package/dist/toolkits.js.map +1 -1
  136. package/dist/types.d.ts +64 -2
  137. package/dist/types.d.ts.map +1 -1
  138. package/dist/ui.d.ts +3 -93
  139. package/dist/ui.d.ts.map +1 -1
  140. package/dist/ui.js +26 -1389
  141. package/dist/ui.js.map +1 -1
  142. package/dist/version.d.ts +1 -1
  143. package/dist/version.js +1 -1
  144. package/package.json +15 -8
  145. package/src/activity.ts +5 -1
  146. package/src/auth/bearer.ts +4 -4
  147. package/src/auth/clerk.ts +1 -1
  148. package/src/call-admission.ts +522 -0
  149. package/src/catalog-fingerprint.ts +52 -0
  150. package/src/catalog-limits.ts +11 -0
  151. package/src/catalog-service.ts +601 -0
  152. package/src/catalog.ts +2 -2
  153. package/src/concurrency.ts +39 -0
  154. package/src/connectors/api.ts +25 -11
  155. package/src/connectors/remote-mcp.ts +55 -21
  156. package/src/credential-health.ts +13 -10
  157. package/src/credentials.ts +2 -2
  158. package/src/errors.ts +1 -1
  159. package/src/execute.ts +194 -377
  160. package/src/executor-result.ts +2 -2
  161. package/src/executors/quickjs-child.ts +8 -4
  162. package/src/executors/quickjs-protocol.ts +1 -1
  163. package/src/executors/quickjs-runtime.ts +5 -1
  164. package/src/executors/quickjs.ts +11 -8
  165. package/src/favicon.ts +2 -2
  166. package/src/index.ts +54 -17
  167. package/src/invocation.ts +527 -0
  168. package/src/meta-tools.ts +369 -797
  169. package/src/operator-ui/browser.css +413 -0
  170. package/src/operator-ui/browser.ts +1121 -0
  171. package/src/operator-ui/generated.ts +4 -0
  172. package/src/operator-ui/model.ts +127 -0
  173. package/src/registry.ts +489 -44
  174. package/src/routes/activity.ts +220 -0
  175. package/src/routes/credentials.ts +266 -0
  176. package/src/routes/mcp.ts +485 -0
  177. package/src/routes/oauth.ts +328 -0
  178. package/src/routes/shared.ts +330 -0
  179. package/src/routes/ui.ts +153 -0
  180. package/src/server.ts +70 -1702
  181. package/src/skills.ts +6 -5
  182. package/src/storage/file.ts +3 -1
  183. package/src/storage/memory.ts +3 -1
  184. package/src/toolkits.ts +2 -2
  185. package/src/types.ts +70 -2
  186. package/src/ui.ts +52 -1489
  187. package/src/version.ts +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,100 @@
2
2
 
3
3
  All notable changes to this package are documented here.
4
4
 
5
+ ## 0.8.0 — 2026-07-28
6
+
7
+ 0.8.0 is consolidation before capability growth (#157): the semantics that were
8
+ independently implemented across call paths — invocation, catalog access,
9
+ discovery bounds, timeouts — now live in shared services, the oversized modules
10
+ (`server.ts`, the operator UI) are split into typed, tested units, and the dev
11
+ loop gained correctness-only linting, an unused-code gate, strict indexed and
12
+ optional property checks, and an automated Workers test-partition guard. A
13
+ deployment can take this release without touching its config: entrypoints,
14
+ options, storage formats, and the tool surface are unchanged. The docs were
15
+ restructured — the old numbered manual is retired in favor of a terse
16
+ [`ethos.md`](./ethos.md) and stub guides in `documentation/` — and the
17
+ temporary `@hono/node-server` override is gone now that the SDK (1.30.0)
18
+ depends on a patched version upstream.
19
+
20
+ ### Added
21
+
22
+ - **`ethos.md`** — what connecta is, what it refuses to be, a decisions table,
23
+ and the invariants, each enforced or reviewer-owned (#175, PR #180). CI caps
24
+ its length; terseness is the point.
25
+ - **Route-contract and operator-UI browser tests** pinning server behavior
26
+ before extraction (#148 PR #168, #149 PR #169).
27
+ - **Automated Workers test-partition guard** — every suite must be classified
28
+ portable or Node-bound, with a reason (#150, PR #161).
29
+
30
+ ### Changed
31
+
32
+ - **Tool invocation and catalog access are shared services** used by direct,
33
+ batch, and code-mode paths alike (#144, PR #162); code-mode dispatch is lazy
34
+ (#145, PR #163); catalog discovery is deduplicated and bounded (#146,
35
+ PR #164); persisted catalogs are chunked with bounded I/O (#147/#167,
36
+ PRs #166/#172).
37
+ - **`server.ts` is a composition root** over extracted route modules (#148,
38
+ PR #170); the operator UI is typed, bundled browser source (#149, PR #169).
39
+ - **Strict indexed access and exact optional property types** are on across
40
+ src and tests (#151, PR #181); Oxlint correctness and Knip unused-code gates
41
+ run in `npm run check` (#155, PR #171).
42
+ - **`@modelcontextprotocol/sdk` 1.30.0** with the `@hono/node-server` override
43
+ removed (#40, PR #174).
44
+ - **Docs restructure** — `docs/` retired; `README.md` is a short overview and
45
+ per-subsystem guides will be rewritten in `documentation/` (#175, PR #180).
46
+ Toolkits (#178) and proactive credential liveness (#179) are recorded as
47
+ retired decisions; their code remains in this release pending removal.
48
+
49
+ ### Fixed
50
+
51
+ - Nothing user-visible; behavior-preserving consolidation throughout.
52
+
53
+ ## 0.7.9 — 2026-07-28
54
+
55
+ 0.7.9 adds opt-in, connector-scoped admission for downstream tool calls. Direct
56
+ calls, batch children, and code-mode host calls to the same connector now share
57
+ one per-runtime limiter, including through toolkit-scoped views. Connectors
58
+ without a `callAdmission` policy behave as before. Dependencies, storage
59
+ formats, and package entrypoints are unchanged.
60
+
61
+ The policy is exact within one Node process or Worker isolate. Concurrency
62
+ limits fully contain one request's fan-out; rolling budgets remain best-effort
63
+ across multiple isolates, replicas, or restarts. This release deliberately
64
+ does not add a distributed coordinator.
65
+
66
+ ### Added
67
+
68
+ - **Connector-scoped downstream admission** (issue #138, PR #143).
69
+ `api()`, `remoteMcp()`, and custom connectors accept a plural-ready
70
+ `callAdmission.rules` policy. The single rule supported today can bound
71
+ concurrency, queue size and wait, and rolling-window calls, optionally
72
+ partitioned by a bounded operator-derived key.
73
+ - **Payload-free admission telemetry.** `/health` reports connector aggregates
74
+ for live partitions, active and queued calls, admission outcomes, and queue
75
+ waits without exposing partition keys, arguments, or results.
76
+ - **Explicit cancelled Activity outcomes.** Caller cancellation is represented
77
+ separately from provider errors and timeouts in the public Activity event
78
+ union, the operator UI, and the Worker D1 example.
79
+
80
+ ### Changed
81
+
82
+ - **Retries reacquire admission per attempt.** Backoff does not retain a
83
+ concurrency permit, and each actual retry consumes a fresh rolling-budget
84
+ entry. Short proactive `rate_limited` windows continue to use the existing
85
+ safe retry contract.
86
+ - **Queue and connector deadlines are separate.** `queueTimeoutMs` bounds only
87
+ permit wait; the per-attempt tool deadline begins after admission.
88
+ `diagnostics: true` reports the phases separately as `admissionMs` and
89
+ `connectorMs`.
90
+
91
+ ### Fixed
92
+
93
+ - **Caller cancellation no longer retries an abandoned attempt or degrades
94
+ connector health.** A call already cancelled avoids connector dispatch.
95
+ Queued cancellation still releases its place without spending a
96
+ rolling-budget entry, while active cancellation releases its permit and
97
+ records a non-retryable `cancelled` result.
98
+
5
99
  ## 0.7.8 — 2026-07-28
6
100
 
7
101
  0.7.8 makes dependency-free tool discovery recover from natural-language
package/README.md CHANGED
@@ -2,130 +2,59 @@
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.
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.
7
8
 
8
9
  ## The problem
9
10
 
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.
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,
13
+ nearly all of it irrelevant to the task at hand. The second cost is
14
+ configuration every client has to be pointed at every server separately,
15
+ each with its own auth, and rotating one token means finding every place it
16
+ was pasted.
20
17
 
21
18
  ## What connecta is
22
19
 
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.
20
+ One MCP endpoint you deploy — a Cloudflare Worker or a Node process in a
21
+ Docker stack, same code either way aggregating your downstream connectors
22
+ behind a small, fixed set of meta-tools. A connector is either a remote MCP
23
+ server that connecta proxies, or a plain HTTP API with hand-written tool
24
+ definitions and a fetch handler. Both come out identical: same two-segment
25
+ addresses (`<connectorId>.<toolName>`), same catalog, same safety rules.
27
26
 
28
27
  ```
29
28
  ┌── remoteMcp("notion") → mcp.notion.com
30
29
  Claude / Cursor ── MCP ──▶ connecta ───┼── remoteMcp("linear") → mcp.linear.app
31
- sees 9 tools /mcp ├── api("resend") → fetch(...)
30
+ sees 9 tools /mcp ├── api("resend") → fetch(...)
32
31
  └── api("internal") → fetch(...)
33
32
  ```
34
33
 
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.
34
+ Rather than receiving every tool up front, the agent discovers what it needs:
35
+ `search_tools` ranks matches, `describe_tools` returns schemas for only the
36
+ addresses about to be called, and `call_tool` / `batch_call` /
37
+ `call_destructive_tool` invoke them by address. `list_connectors` reports what
38
+ exists, `authorize_connector` starts a downstream OAuth flow, `get_result`
39
+ pages through oversized results, and `skills` hands the model a short guide to
40
+ the rest. The agent's context holds nine tool definitions whether ten tools
41
+ sit behind them or a thousand.
42
+
43
+ An optional tenth, `execute_code`, runs model-written JavaScript in a sandbox
44
+ with no network, filesystem, or environment access only the explicitly
45
+ read-only tools as callable globals turning a loop or a cross-connector join
46
+ into one round trip. Configure no executor and connecta is exactly the
47
+ nine-tool server.
48
+
49
+ Three properties are load-bearing enough to name here; the rest live in the
50
+ [ethos](./ethos.md). **Read-only is fail-closed**: only tools explicitly
51
+ annotated read-only are reachable through `call_tool`, `batch_call`, and the
52
+ sandbox everything else crosses `call_destructive_tool`, which is annotated
53
+ so the MCP host can ask a human. **Credentials stay server-side**: downstream
54
+ tokens live in an encrypted vault, rotated from an operator page rather than a
55
+ redeploy, and no surface ever returns a secret. **Config is code**: adding a
56
+ connector is an edit and a deploy — no registration API, no admin UI, one
57
+ small file you can review in a pull request.
129
58
 
130
59
  ## Getting started
131
60
 
@@ -164,42 +93,36 @@ listen(connecta, 8787); // MCP at /mcp; Connections at http://localhost:8787/
164
93
  ```
165
94
 
166
95
  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`.
96
+ `Authorization: Bearer` header and `time.get_now` is discoverable through
97
+ `search_tools`.
169
98
 
170
99
  Runnable deployments live in
171
100
  [`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()`.
101
+ [`worker/`](https://github.com/zackbart/connecta/tree/main/examples/worker) is
102
+ a free-tier-compatible Cloudflare Worker with KV and D1 adapters and the
103
+ template to copy for a real deployment;
104
+ [`node/`](https://github.com/zackbart/connecta/tree/main/examples/node) extends
105
+ the server above;
106
+ [`docker/`](https://github.com/zackbart/connecta/tree/main/examples/docker) is
107
+ a single-service compose stack. Anything beyond the core is installed only by
108
+ the deployments that use it `@clerk/backend` and `quickjs-emscripten` are
109
+ optional peers behind the `/auth/clerk` and `/quickjs` subpaths — and connecta
110
+ ships no service-specific connectors: endpoint, credential, and tool choices
111
+ stay in your project, declared with `remoteMcp()` and `api()`.
112
+
113
+ A candid note on maturity: connecta is built for its author's deployments
114
+ first and published openly. Breaking changes are cheap and the version number
115
+ signals change, not stability — the [ethos](./ethos.md) says so on purpose.
186
116
 
187
117
  ## Learn more
188
118
 
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.
119
+ - **[ethos.md](./ethos.md)** — what this is, what it refuses to be, the
120
+ decisions table, and the invariants every change must preserve. Read this
121
+ before proposing anything.
122
+ - **[documentation/](./documentation/)** — per-subsystem guides. Currently
123
+ stubs: the old manual was retired during the phase-1 docs restructure and
124
+ each guide is being rewritten as the ideas settle; prior text lives in git
125
+ history.
126
+ - **[CHANGELOG](./CHANGELOG.md)** — what changed in each release.
127
+ - **[SECURITY](./SECURITY.md)** — supported versions and how to report a
128
+ vulnerability.
@@ -1,6 +1,6 @@
1
1
  import type { Logger } from "./types.js";
2
2
  export type ActivityCallSource = "call_tool" | "call_destructive_tool" | "batch_call" | "execute_code";
3
- export type ActivityOutcome = "success" | "error" | "timeout";
3
+ export type ActivityOutcome = "success" | "error" | "timeout" | "cancelled";
4
4
  /**
5
5
  * Authenticated identity attached to an activity event. `id` is intentionally
6
6
  * optional: open deployments and shared bearer tokens cannot honestly identify
@@ -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,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE9D;;;;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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"}
@@ -1 +1 @@
1
- {"version":3,"file":"activity.js","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"AA2FA,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":"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"}
@@ -9,7 +9,7 @@ export interface BearerTokenOptions extends ToolkitBindingOptions {
9
9
  * against `secret`. Checked BEFORE the Clerk gate in the server; a mismatch
10
10
  * falls through so a co-configured Clerk provider can still admit the request.
11
11
  *
12
- * `toolkits` binds the token to named toolkits (docs/toolkits.md): one
12
+ * `toolkits` binds the token to named toolkits (documentation/toolkits.md): one
13
13
  * `bearerToken(...)` per team credential, each naming the view that team may
14
14
  * open. Omit it and the token stays unbound — every declared toolkit plus the
15
15
  * full registry.
@@ -11,7 +11,7 @@ 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
  /**
@@ -19,7 +19,7 @@ function timingSafeEqual(a, b) {
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
21
  *
22
- * `toolkits` binds the token to named toolkits (docs/toolkits.md): one
22
+ * `toolkits` binds the token to named toolkits (documentation/toolkits.md): one
23
23
  * `bearerToken(...)` per team credential, each naming the view that team may
24
24
  * open. Omit it and the token stays unbound — every declared toolkit plus the
25
25
  * full registry.
@@ -31,8 +31,8 @@ export function bearerToken(secret, options = {}) {
31
31
  : "bearerToken", options);
32
32
  if (toolkitBinding && !options.subjectId) {
33
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
34
+ // the 403 refusal log (documentation/toolkits.md) and activity events
35
+ // (documentation/operator-ui.md) — can only say "bearer" without a subjectId. With
36
36
  // several bound tokens that makes an operator unable to tell which
37
37
  // credential was refused, or whose call succeeded. console.warn (as the
38
38
  // Clerk adapter does) because an adapter is constructed before
@@ -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":"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"}
@@ -35,7 +35,7 @@ export interface ClerkAuthOptions extends ToolkitBindingOptions {
35
35
  * `toolkits` decides WHICH view the admitted user gets.
36
36
  *
37
37
  * `toolkits` binds every user this provider admits to those toolkits
38
- * (docs/toolkits.md). For a per-team split, configure one `clerkAuth(...)` per
38
+ * (documentation/toolkits.md). For a per-team split, configure one `clerkAuth(...)` per
39
39
  * team — the same keys, a `gate` naming that team's users, and that team's
40
40
  * `toolkits`. The server tries providers in order and the first that admits the
41
41
  * user supplies the binding, so a user one gate rejects falls through to the
@@ -156,7 +156,7 @@ function emailDomain(email) {
156
156
  * `toolkits` decides WHICH view the admitted user gets.
157
157
  *
158
158
  * `toolkits` binds every user this provider admits to those toolkits
159
- * (docs/toolkits.md). For a per-team split, configure one `clerkAuth(...)` per
159
+ * (documentation/toolkits.md). For a per-team split, configure one `clerkAuth(...)` per
160
160
  * team — the same keys, a `gate` naming that team's users, and that team's
161
161
  * `toolkits`. The server tries providers in order and the first that admits the
162
162
  * user supplies the binding, so a user one gate rejects falls through to the
@@ -0,0 +1,81 @@
1
+ import { ConnectorCallError } from "./errors.js";
2
+ import type { ConnectorCallAdmissionInput, ConnectorCallAdmissionPolicy } from "./types.js";
3
+ export type CallAdmissionFailureKind = "concurrency" | "budget" | "cancelled" | "closed" | "partition";
4
+ /**
5
+ * A locally-produced connector-call failure. Extending ConnectorCallError
6
+ * preserves the public error envelope while letting call paths avoid recording
7
+ * a refusal as evidence that the downstream provider is unhealthy.
8
+ */
9
+ export declare class CallAdmissionError extends ConnectorCallError {
10
+ readonly admissionKind: CallAdmissionFailureKind;
11
+ constructor(admissionKind: CallAdmissionFailureKind, code: ConstructorParameters<typeof ConnectorCallError>[0], message: string, opts?: ConstructorParameters<typeof ConnectorCallError>[2]);
12
+ }
13
+ export declare function isCallAdmissionError(error: unknown): error is CallAdmissionError;
14
+ export interface CallAdmissionPermit {
15
+ /** Time spent in the concurrency queue. Zero for immediate admission. */
16
+ readonly waitMs: number;
17
+ /** Idempotent. */
18
+ release(): void;
19
+ }
20
+ export interface ConnectorCallAdmissionSnapshot {
21
+ rules: number;
22
+ partitions: number;
23
+ active: number;
24
+ queued: number;
25
+ closed: boolean;
26
+ totals: {
27
+ admitted: number;
28
+ queued: number;
29
+ rejected: number;
30
+ rateLimited: number;
31
+ cancelled: number;
32
+ };
33
+ queueWaitMs: {
34
+ count: number;
35
+ total: number;
36
+ max: number;
37
+ };
38
+ }
39
+ /**
40
+ * Per-runtime, per-connector call admission. State contains only bounded
41
+ * partition keys, counters, timestamps, signals, and promise continuations;
42
+ * tool arguments never enter the controller.
43
+ */
44
+ export declare class ConnectorCallAdmissionController {
45
+ readonly connectorId: string;
46
+ private readonly maxConcurrency;
47
+ private readonly maxQueueSize;
48
+ private readonly queueTimeoutMs;
49
+ private readonly retryAfterMs;
50
+ private readonly maxPartitions;
51
+ private readonly budget;
52
+ private readonly partitionKey;
53
+ private readonly partitions;
54
+ private closed;
55
+ private admittedTotal;
56
+ private queuedTotal;
57
+ private rejectedTotal;
58
+ private rateLimitedTotal;
59
+ private cancelledTotal;
60
+ private queueWaitCount;
61
+ private queueWaitTotalMs;
62
+ private queueWaitMaxMs;
63
+ constructor(connectorId: string, policy: ConnectorCallAdmissionPolicy);
64
+ acquire(input: Readonly<ConnectorCallAdmissionInput> & {
65
+ signal?: AbortSignal;
66
+ }): Promise<CallAdmissionPermit>;
67
+ snapshot(): ConnectorCallAdmissionSnapshot;
68
+ close(): void;
69
+ private admit;
70
+ private pump;
71
+ private pruneBudget;
72
+ private budgetRetryAfterMs;
73
+ private evictIdlePartitions;
74
+ private maybeDeletePartition;
75
+ private removeWaiter;
76
+ private cleanupWaiter;
77
+ private concurrencyLimited;
78
+ private budgetLimited;
79
+ private cancelled;
80
+ }
81
+ //# sourceMappingURL=call-admission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call-admission.d.ts","sourceRoot":"","sources":["../src/call-admission.ts"],"names":[],"mappings":"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"}