@zackbart/connecta 0.15.1 → 0.16.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 (335) hide show
  1. package/AGENTS.md +40 -20
  2. package/CHANGELOG.md +653 -0
  3. package/README.md +25 -5
  4. package/bin/connecta.mjs +44 -3
  5. package/dist/access-tokens.d.ts +0 -1
  6. package/dist/access-tokens.js +0 -1
  7. package/dist/activity.d.ts +50 -2
  8. package/dist/activity.js +34 -1
  9. package/dist/apps-shell.d.ts +0 -1
  10. package/dist/apps-shell.js +0 -1
  11. package/dist/auth/bearer.d.ts +0 -1
  12. package/dist/auth/bearer.js +0 -1
  13. package/dist/auth/clerk.d.ts +0 -1
  14. package/dist/auth/clerk.js +45 -9
  15. package/dist/auth/downstream-oauth.d.ts +0 -1
  16. package/dist/auth/downstream-oauth.js +0 -1
  17. package/dist/call-admission.d.ts +0 -1
  18. package/dist/call-admission.js +0 -1
  19. package/dist/catalog-drift.d.ts +99 -0
  20. package/dist/catalog-drift.js +251 -0
  21. package/dist/catalog-fingerprint.d.ts +0 -1
  22. package/dist/catalog-fingerprint.js +0 -1
  23. package/dist/catalog-limits.d.ts +0 -1
  24. package/dist/catalog-limits.js +0 -1
  25. package/dist/catalog-service.d.ts +0 -1
  26. package/dist/catalog-service.js +41 -5
  27. package/dist/catalog.d.ts +11 -1
  28. package/dist/catalog.js +20 -1
  29. package/dist/concurrency.d.ts +0 -1
  30. package/dist/concurrency.js +0 -1
  31. package/dist/connector-scope.d.ts +0 -1
  32. package/dist/connector-scope.js +0 -1
  33. package/dist/connectors/api.d.ts +29 -21
  34. package/dist/connectors/api.js +45 -19
  35. package/dist/connectors/guarded-fetch.d.ts +106 -0
  36. package/dist/connectors/guarded-fetch.js +289 -0
  37. package/dist/connectors/remote-mcp.d.ts +0 -1
  38. package/dist/connectors/remote-mcp.js +0 -1
  39. package/dist/credentials.d.ts +0 -1
  40. package/dist/credentials.js +0 -1
  41. package/dist/errors.d.ts +30 -3
  42. package/dist/errors.js +1 -1
  43. package/dist/execute.d.ts +0 -1
  44. package/dist/execute.js +0 -1
  45. package/dist/executor-admission.d.ts +11 -1
  46. package/dist/executor-admission.js +28 -1
  47. package/dist/executor-result.d.ts +0 -1
  48. package/dist/executor-result.js +0 -1
  49. package/dist/executors/quickjs-child.d.ts +0 -1
  50. package/dist/executors/quickjs-child.js +0 -1
  51. package/dist/executors/quickjs-protocol.d.ts +0 -1
  52. package/dist/executors/quickjs-protocol.js +0 -1
  53. package/dist/executors/quickjs-runtime.d.ts +0 -1
  54. package/dist/executors/quickjs-runtime.js +0 -1
  55. package/dist/executors/quickjs.d.ts +0 -1
  56. package/dist/executors/quickjs.js +2 -1
  57. package/dist/favicon.d.ts +0 -1
  58. package/dist/favicon.js +0 -1
  59. package/dist/index.d.ts +2 -3
  60. package/dist/index.js +24 -7
  61. package/dist/invocation.d.ts +0 -1
  62. package/dist/invocation.js +0 -1
  63. package/dist/json-schema.d.ts +0 -1
  64. package/dist/json-schema.js +0 -1
  65. package/dist/mcp-result.d.ts +0 -1
  66. package/dist/mcp-result.js +0 -1
  67. package/dist/meta-tools.d.ts +0 -1
  68. package/dist/meta-tools.js +0 -1
  69. package/dist/node.d.ts +0 -1
  70. package/dist/node.js +0 -1
  71. package/dist/operator-ui/generated.d.ts +2 -3
  72. package/dist/operator-ui/generated.js +3 -4
  73. package/dist/operator-ui/model.d.ts +10 -1
  74. package/dist/operator-ui/model.js +0 -1
  75. package/dist/operator-ui/view.d.ts +167 -0
  76. package/dist/operator-ui/view.js +270 -0
  77. package/dist/providers/cloudflare.d.ts +0 -1
  78. package/dist/providers/cloudflare.js +261 -299
  79. package/dist/providers/linear.d.ts +26 -5
  80. package/dist/providers/linear.js +32 -61
  81. package/dist/providers/mixpanel.d.ts +35 -4
  82. package/dist/providers/mixpanel.js +53 -79
  83. package/dist/providers/notion.d.ts +0 -1
  84. package/dist/providers/notion.js +87 -42
  85. package/dist/providers/stripe.d.ts +13 -1
  86. package/dist/providers/stripe.js +31 -60
  87. package/dist/registry.d.ts +34 -2
  88. package/dist/registry.js +85 -5
  89. package/dist/retired-toolkits.d.ts +0 -1
  90. package/dist/retired-toolkits.js +0 -1
  91. package/dist/routes/access-tokens.d.ts +0 -1
  92. package/dist/routes/access-tokens.js +0 -1
  93. package/dist/routes/activity.d.ts +0 -1
  94. package/dist/routes/activity.js +0 -1
  95. package/dist/routes/credentials.d.ts +0 -1
  96. package/dist/routes/credentials.js +0 -1
  97. package/dist/routes/mcp.d.ts +0 -1
  98. package/dist/routes/mcp.js +0 -1
  99. package/dist/routes/oauth.d.ts +0 -1
  100. package/dist/routes/oauth.js +0 -1
  101. package/dist/routes/shared.d.ts +2 -1
  102. package/dist/routes/shared.js +0 -1
  103. package/dist/routes/ui.d.ts +0 -1
  104. package/dist/routes/ui.js +0 -1
  105. package/dist/server.d.ts +0 -1
  106. package/dist/server.js +11 -1
  107. package/dist/skills.d.ts +0 -1
  108. package/dist/skills.js +0 -1
  109. package/dist/storage/file.d.ts +0 -1
  110. package/dist/storage/file.js +0 -1
  111. package/dist/storage/memory.d.ts +0 -1
  112. package/dist/storage/memory.js +0 -1
  113. package/dist/timeout.d.ts +0 -1
  114. package/dist/timeout.js +0 -1
  115. package/dist/tool-safety.d.ts +0 -1
  116. package/dist/tool-safety.js +0 -1
  117. package/dist/types.d.ts +45 -1
  118. package/dist/types.js +0 -1
  119. package/dist/ui.d.ts +0 -1
  120. package/dist/ui.js +13 -137
  121. package/dist/validate.d.ts +13 -15
  122. package/dist/validate.js +24 -11
  123. package/dist/version.d.ts +1 -2
  124. package/dist/version.js +1 -2
  125. package/documentation/architecture.md +186 -5
  126. package/documentation/auth.md +11 -0
  127. package/documentation/call-admission.md +142 -6
  128. package/documentation/cloudflare.md +92 -10
  129. package/documentation/code-first-exploration.md +2 -2
  130. package/documentation/code-mode.md +14 -14
  131. package/documentation/connector-guides.md +172 -5
  132. package/documentation/connectors.md +89 -0
  133. package/documentation/linear.md +20 -2
  134. package/documentation/mcp-ui-design.md +2 -2
  135. package/documentation/meta-tools.md +7 -1
  136. package/documentation/mixpanel.md +42 -9
  137. package/documentation/notion.md +23 -2
  138. package/documentation/operations.md +325 -5
  139. package/documentation/operator-ui.md +120 -5
  140. package/documentation/provider-audit.md +160 -0
  141. package/documentation/provider-conventions.md +667 -0
  142. package/documentation/request-admission.md +167 -5
  143. package/documentation/rich-output-design.md +1 -2
  144. package/documentation/stripe.md +15 -0
  145. package/documentation/upgrading.md +454 -0
  146. package/ethos.md +14 -9
  147. package/examples/worker/README.md +102 -12
  148. package/examples/worker/src/index.ts +46 -1
  149. package/examples/worker/wrangler.jsonc +14 -1
  150. package/package.json +10 -6
  151. package/templates/node/.dockerignore +10 -0
  152. package/templates/node/.env.example +40 -3
  153. package/templates/node/AGENTS.md +16 -1
  154. package/templates/node/Dockerfile +49 -0
  155. package/templates/node/README.md +117 -2
  156. package/templates/node/docker-compose.yml +39 -0
  157. package/templates/node/package.json +1 -1
  158. package/templates/node/src/file-activity.ts +182 -0
  159. package/templates/node/src/index.ts +80 -4
  160. package/assets/connecta-clay-hero.png +0 -0
  161. package/dist/access-tokens.d.ts.map +0 -1
  162. package/dist/access-tokens.js.map +0 -1
  163. package/dist/activity.d.ts.map +0 -1
  164. package/dist/activity.js.map +0 -1
  165. package/dist/apps-shell.d.ts.map +0 -1
  166. package/dist/apps-shell.js.map +0 -1
  167. package/dist/auth/bearer.d.ts.map +0 -1
  168. package/dist/auth/bearer.js.map +0 -1
  169. package/dist/auth/clerk.d.ts.map +0 -1
  170. package/dist/auth/clerk.js.map +0 -1
  171. package/dist/auth/downstream-oauth.d.ts.map +0 -1
  172. package/dist/auth/downstream-oauth.js.map +0 -1
  173. package/dist/call-admission.d.ts.map +0 -1
  174. package/dist/call-admission.js.map +0 -1
  175. package/dist/catalog-fingerprint.d.ts.map +0 -1
  176. package/dist/catalog-fingerprint.js.map +0 -1
  177. package/dist/catalog-limits.d.ts.map +0 -1
  178. package/dist/catalog-limits.js.map +0 -1
  179. package/dist/catalog-service.d.ts.map +0 -1
  180. package/dist/catalog-service.js.map +0 -1
  181. package/dist/catalog.d.ts.map +0 -1
  182. package/dist/catalog.js.map +0 -1
  183. package/dist/concurrency.d.ts.map +0 -1
  184. package/dist/concurrency.js.map +0 -1
  185. package/dist/connector-scope.d.ts.map +0 -1
  186. package/dist/connector-scope.js.map +0 -1
  187. package/dist/connectors/api.d.ts.map +0 -1
  188. package/dist/connectors/api.js.map +0 -1
  189. package/dist/connectors/remote-mcp.d.ts.map +0 -1
  190. package/dist/connectors/remote-mcp.js.map +0 -1
  191. package/dist/credentials.d.ts.map +0 -1
  192. package/dist/credentials.js.map +0 -1
  193. package/dist/errors.d.ts.map +0 -1
  194. package/dist/errors.js.map +0 -1
  195. package/dist/execute.d.ts.map +0 -1
  196. package/dist/execute.js.map +0 -1
  197. package/dist/executor-admission.d.ts.map +0 -1
  198. package/dist/executor-admission.js.map +0 -1
  199. package/dist/executor-result.d.ts.map +0 -1
  200. package/dist/executor-result.js.map +0 -1
  201. package/dist/executors/quickjs-child.d.ts.map +0 -1
  202. package/dist/executors/quickjs-child.js.map +0 -1
  203. package/dist/executors/quickjs-protocol.d.ts.map +0 -1
  204. package/dist/executors/quickjs-protocol.js.map +0 -1
  205. package/dist/executors/quickjs-runtime.d.ts.map +0 -1
  206. package/dist/executors/quickjs-runtime.js.map +0 -1
  207. package/dist/executors/quickjs.d.ts.map +0 -1
  208. package/dist/executors/quickjs.js.map +0 -1
  209. package/dist/favicon.d.ts.map +0 -1
  210. package/dist/favicon.js.map +0 -1
  211. package/dist/index.d.ts.map +0 -1
  212. package/dist/index.js.map +0 -1
  213. package/dist/invocation.d.ts.map +0 -1
  214. package/dist/invocation.js.map +0 -1
  215. package/dist/json-schema.d.ts.map +0 -1
  216. package/dist/json-schema.js.map +0 -1
  217. package/dist/mcp-result.d.ts.map +0 -1
  218. package/dist/mcp-result.js.map +0 -1
  219. package/dist/meta-tools.d.ts.map +0 -1
  220. package/dist/meta-tools.js.map +0 -1
  221. package/dist/node.d.ts.map +0 -1
  222. package/dist/node.js.map +0 -1
  223. package/dist/operator-ui/generated.d.ts.map +0 -1
  224. package/dist/operator-ui/generated.js.map +0 -1
  225. package/dist/operator-ui/model.d.ts.map +0 -1
  226. package/dist/operator-ui/model.js.map +0 -1
  227. package/dist/providers/cloudflare.d.ts.map +0 -1
  228. package/dist/providers/cloudflare.js.map +0 -1
  229. package/dist/providers/linear.d.ts.map +0 -1
  230. package/dist/providers/linear.js.map +0 -1
  231. package/dist/providers/mixpanel.d.ts.map +0 -1
  232. package/dist/providers/mixpanel.js.map +0 -1
  233. package/dist/providers/notion.d.ts.map +0 -1
  234. package/dist/providers/notion.js.map +0 -1
  235. package/dist/providers/stripe.d.ts.map +0 -1
  236. package/dist/providers/stripe.js.map +0 -1
  237. package/dist/registry.d.ts.map +0 -1
  238. package/dist/registry.js.map +0 -1
  239. package/dist/retired-toolkits.d.ts.map +0 -1
  240. package/dist/retired-toolkits.js.map +0 -1
  241. package/dist/routes/access-tokens.d.ts.map +0 -1
  242. package/dist/routes/access-tokens.js.map +0 -1
  243. package/dist/routes/activity.d.ts.map +0 -1
  244. package/dist/routes/activity.js.map +0 -1
  245. package/dist/routes/credentials.d.ts.map +0 -1
  246. package/dist/routes/credentials.js.map +0 -1
  247. package/dist/routes/mcp.d.ts.map +0 -1
  248. package/dist/routes/mcp.js.map +0 -1
  249. package/dist/routes/oauth.d.ts.map +0 -1
  250. package/dist/routes/oauth.js.map +0 -1
  251. package/dist/routes/shared.d.ts.map +0 -1
  252. package/dist/routes/shared.js.map +0 -1
  253. package/dist/routes/ui.d.ts.map +0 -1
  254. package/dist/routes/ui.js.map +0 -1
  255. package/dist/server.d.ts.map +0 -1
  256. package/dist/server.js.map +0 -1
  257. package/dist/skills.d.ts.map +0 -1
  258. package/dist/skills.js.map +0 -1
  259. package/dist/storage/file.d.ts.map +0 -1
  260. package/dist/storage/file.js.map +0 -1
  261. package/dist/storage/memory.d.ts.map +0 -1
  262. package/dist/storage/memory.js.map +0 -1
  263. package/dist/timeout.d.ts.map +0 -1
  264. package/dist/timeout.js.map +0 -1
  265. package/dist/tool-safety.d.ts.map +0 -1
  266. package/dist/tool-safety.js.map +0 -1
  267. package/dist/types.d.ts.map +0 -1
  268. package/dist/types.js.map +0 -1
  269. package/dist/ui.d.ts.map +0 -1
  270. package/dist/ui.js.map +0 -1
  271. package/dist/validate.d.ts.map +0 -1
  272. package/dist/validate.js.map +0 -1
  273. package/dist/version.d.ts.map +0 -1
  274. package/dist/version.js.map +0 -1
  275. package/examples/node/README.md +0 -52
  276. package/examples/node/src/index.ts +0 -71
  277. package/src/access-tokens.ts +0 -289
  278. package/src/activity.ts +0 -234
  279. package/src/apps-shell.ts +0 -370
  280. package/src/auth/bearer.ts +0 -61
  281. package/src/auth/clerk.ts +0 -553
  282. package/src/auth/downstream-oauth.ts +0 -575
  283. package/src/call-admission.ts +0 -521
  284. package/src/catalog-fingerprint.ts +0 -52
  285. package/src/catalog-limits.ts +0 -11
  286. package/src/catalog-service.ts +0 -1153
  287. package/src/catalog.ts +0 -790
  288. package/src/concurrency.ts +0 -39
  289. package/src/connector-scope.ts +0 -66
  290. package/src/connectors/api.ts +0 -159
  291. package/src/connectors/remote-mcp.ts +0 -1090
  292. package/src/credentials.ts +0 -428
  293. package/src/errors.ts +0 -364
  294. package/src/execute.ts +0 -1406
  295. package/src/executor-admission.ts +0 -328
  296. package/src/executor-result.ts +0 -107
  297. package/src/executors/quickjs-child.ts +0 -172
  298. package/src/executors/quickjs-protocol.ts +0 -99
  299. package/src/executors/quickjs-runtime.ts +0 -470
  300. package/src/executors/quickjs.ts +0 -776
  301. package/src/favicon.ts +0 -53
  302. package/src/index.ts +0 -666
  303. package/src/invocation.ts +0 -655
  304. package/src/json-schema.ts +0 -11
  305. package/src/mcp-result.ts +0 -43
  306. package/src/meta-tools.ts +0 -1607
  307. package/src/node.ts +0 -206
  308. package/src/operator-ui/browser.css +0 -423
  309. package/src/operator-ui/browser.ts +0 -1281
  310. package/src/operator-ui/generated.ts +0 -4
  311. package/src/operator-ui/model.ts +0 -111
  312. package/src/providers/cloudflare.ts +0 -3999
  313. package/src/providers/linear.ts +0 -302
  314. package/src/providers/mixpanel.ts +0 -229
  315. package/src/providers/notion.ts +0 -1879
  316. package/src/providers/stripe.ts +0 -307
  317. package/src/registry.ts +0 -1085
  318. package/src/retired-toolkits.ts +0 -14
  319. package/src/routes/access-tokens.ts +0 -115
  320. package/src/routes/activity.ts +0 -215
  321. package/src/routes/credentials.ts +0 -254
  322. package/src/routes/mcp.ts +0 -429
  323. package/src/routes/oauth.ts +0 -322
  324. package/src/routes/shared.ts +0 -247
  325. package/src/routes/ui.ts +0 -152
  326. package/src/server.ts +0 -195
  327. package/src/skills.ts +0 -271
  328. package/src/storage/file.ts +0 -123
  329. package/src/storage/memory.ts +0 -44
  330. package/src/timeout.ts +0 -84
  331. package/src/tool-safety.ts +0 -15
  332. package/src/types.ts +0 -523
  333. package/src/ui.ts +0 -744
  334. package/src/validate.ts +0 -387
  335. package/src/version.ts +0 -7
@@ -1,39 +0,0 @@
1
- const DEFAULT_DISCOVERY_CONCURRENCY = 4;
2
-
3
- export function resolveDiscoveryConcurrency(
4
- value: number | undefined,
5
- ): number {
6
- return value !== undefined && Number.isInteger(value) && value > 0
7
- ? value
8
- : DEFAULT_DISCOVERY_CONCURRENCY;
9
- }
10
-
11
- /** Run `fn` over `items` with at most `limit` operations in flight. */
12
- export async function mapSettledWithConcurrency<T, R>(
13
- items: readonly T[],
14
- limit: number,
15
- fn: (item: T, index: number) => Promise<R>,
16
- ): Promise<PromiseSettledResult<R>[]> {
17
- const settled = Array<PromiseSettledResult<R>>(items.length);
18
- const remaining = items.entries();
19
- const workers = Array.from(
20
- { length: Math.min(limit, items.length) },
21
- async () => {
22
- for (;;) {
23
- const next = remaining.next();
24
- if (next.done) return;
25
- const [index, item] = next.value;
26
- try {
27
- settled[index] = {
28
- status: "fulfilled",
29
- value: await fn(item, index),
30
- };
31
- } catch (reason) {
32
- settled[index] = { status: "rejected", reason };
33
- }
34
- }
35
- },
36
- );
37
- await Promise.all(workers);
38
- return settled;
39
- }
@@ -1,66 +0,0 @@
1
- import type { Connector, ConnectorContext } from "./types.js";
2
-
3
- /** Enough for local transport abort/close without letting cleanup own latency. */
4
- const CONNECTOR_SCOPE_CLOSE_BUDGET_MS = 100;
5
-
6
- /**
7
- * Bound on cleanup continued after the caller-facing window expires.
8
- *
9
- * `remoteMcp` spends at most one second asking the downstream to terminate its
10
- * session, leaving another second for the local close. Custom hooks still get a
11
- * finite background window: handing a never-settling promise to a Worker's
12
- * `waitUntil` would otherwise keep the invocation alive until the platform cap.
13
- */
14
- const CONNECTOR_SCOPE_DEFER_BUDGET_MS = 2_000;
15
-
16
- /** Runtime hook for work that may safely continue after a response is ready. */
17
- export type DeferredWork = (promise: Promise<unknown>) => void;
18
-
19
- /** Resolve when `work` settles or `budgetMs` expires; never reject. */
20
- function waitAtMost(work: Promise<void>, budgetMs: number): Promise<void> {
21
- return new Promise((resolve) => {
22
- const timer = setTimeout(resolve, budgetMs);
23
- work.then(() => {
24
- clearTimeout(timer);
25
- resolve();
26
- });
27
- });
28
- }
29
-
30
- /**
31
- * Tell a connector that a scope owned by the core has ended.
32
- *
33
- * Scope teardown is deliberately best-effort: a missing hook is a no-op and a
34
- * rejected hook is swallowed so cleanup can never replace the probe result that
35
- * caused it. The hook gets a small, fixed completion window so edge runtimes do
36
- * not cut off a real close as the response ends. When the runtime supplies
37
- * `defer`, the bounded tail is handed to it without extending the caller-facing
38
- * window. Callers own the at-most-once guarantee and must not use the scope
39
- * again after this returns.
40
- */
41
- export async function closeConnectorScope(
42
- connector: Connector,
43
- ctx: ConnectorContext,
44
- defer?: DeferredWork,
45
- ): Promise<void> {
46
- try {
47
- const closing = connector.closeScope?.(ctx);
48
- if (!closing) return;
49
- // Attach both handlers before either timer can win, so a late rejection is
50
- // consumed rather than becoming an unhandled rejection.
51
- const settled = closing.then(
52
- () => {},
53
- () => {},
54
- );
55
- if (defer) {
56
- try {
57
- defer(waitAtMost(settled, CONNECTOR_SCOPE_DEFER_BUDGET_MS));
58
- } catch {
59
- // A runtime hook is best-effort too; the caller cap still applies.
60
- }
61
- }
62
- await waitAtMost(settled, CONNECTOR_SCOPE_CLOSE_BUDGET_MS);
63
- } catch {
64
- // The scope is over whether or not the connector managed to clean it up.
65
- }
66
- }
@@ -1,159 +0,0 @@
1
- import { precompileValidator, validateToolInput } from "../validate.js";
2
- import type {
3
- Connector,
4
- ConnectorCallAdmissionPolicy,
5
- ConnectorCredentialConfig,
6
- ConnectorCredentialValues,
7
- ConnectorContext,
8
- ConnectorUsageGuide,
9
- CredentialTestResult,
10
- JsonSchema,
11
- ToolAnnotations,
12
- ToolDef,
13
- } from "../types.js";
14
-
15
- export interface ApiTool {
16
- name: string;
17
- description?: string;
18
- /** A plain JSON Schema object describing the tool input. */
19
- inputSchema?: JsonSchema;
20
- /** A plain JSON Schema object describing the tool's structured output. */
21
- outputSchema?: JsonSchema;
22
- /**
23
- * Standard MCP-style behavior hints. Only an explicit readOnlyHint: true
24
- * admits the tool to call_tool and execute_code.
25
- */
26
- annotations?: ToolAnnotations;
27
- handler: (args: any, ctx: ConnectorContext) => Promise<unknown> | unknown;
28
- }
29
-
30
- export interface ApiOptions {
31
- /** Human-readable display name; the connector id remains the address prefix. */
32
- title?: string;
33
- description?: string;
34
- /**
35
- * Max inline result size (bytes) for this connector's tools before
36
- * call_tool truncates and stashes the full text for get_result
37
- * paging. Overrides the deployment's `calls.maxResultBytes`; omit to inherit
38
- * it. Must be a whole number of bytes >= 1; anything else warns at startup
39
- * and is ignored.
40
- */
41
- maxResultBytes?: number;
42
- /** Optional per-runtime downstream call-admission policy. */
43
- callAdmission?: ConnectorCallAdmissionPolicy;
44
- /**
45
- * Optional agent-facing usage guide served by `skills` as
46
- * `connector:<id>`. A string is markdown; the structured form adds bounded
47
- * discovery metadata. See `Connector.usageGuide`.
48
- */
49
- usageGuide?: string | ConnectorUsageGuide;
50
- /** Optional operator-managed credential exposed through ctx.credential and /credentials. */
51
- credential?: ConnectorCredentialConfig;
52
- /** Optional validation behind /credentials' Test action. */
53
- testCredential?: (
54
- value: string,
55
- ctx: ConnectorContext,
56
- ) => Promise<CredentialTestResult>;
57
- /** Optional validation for named multi-field credentials. */
58
- testCredentials?: (
59
- values: ConnectorCredentialValues,
60
- ctx: ConnectorContext,
61
- ) => Promise<CredentialTestResult>;
62
- /**
63
- * Validate call arguments against each tool's `inputSchema` before invoking
64
- * the handler (default true). Mismatches fail with a non-retryable
65
- * `invalid_args` ConnectorCallError instead of reaching the handler. Set
66
- * false to restore the pre-validation pass-through for deployments relying
67
- * on loose coercion.
68
- */
69
- validateArgs?: boolean;
70
- /**
71
- * Fail-closed on a tool whose `inputSchema` the validator cannot evaluate
72
- * (default false). The default surfaces such a schema as a one-time warning
73
- * and then passes the raw arguments through, so a broken schema never breaks
74
- * an otherwise working tool. Set true to instead reject those calls with a
75
- * non-retryable `invalid_args` ConnectorCallError, so a schema that cannot be
76
- * enforced never silently admits unvalidated input. Only consulted when
77
- * `validateArgs` is not false.
78
- */
79
- strictValidation?: boolean;
80
- tools: ApiTool[];
81
- }
82
-
83
- /**
84
- * A connector defined entirely in code: static tool defs + fetch handlers.
85
- * Tool inputs are plain JSON Schema objects (bring your own zod-to-json-schema
86
- * conversion if you prefer zod). call_tool JSON-wraps the handler's return.
87
- *
88
- * Arguments are validated against `inputSchema` before the handler runs
89
- * (disable with `validateArgs: false`). Remote MCP inputs are also validated,
90
- * but in the shared invocation path against the request-local downstream
91
- * catalog. These API-only controls stay here because hand-written handlers may
92
- * deliberately accept loose coercion or choose fail-closed schema handling.
93
- */
94
- export function api(id: string, opts: ApiOptions): Connector {
95
- const defs: ToolDef[] = opts.tools.map((t) => ({
96
- name: t.name,
97
- ...(t.description !== undefined ? { description: t.description } : {}),
98
- ...(t.inputSchema !== undefined ? { inputSchema: t.inputSchema } : {}),
99
- ...(t.outputSchema !== undefined ? { outputSchema: t.outputSchema } : {}),
100
- ...(t.annotations !== undefined ? { annotations: t.annotations } : {}),
101
- }));
102
- const byName = new Map(opts.tools.map((t) => [t.name, t]));
103
- const validateArgs = opts.validateArgs ?? true;
104
- const strictValidation = opts.strictValidation ?? false;
105
- if (validateArgs) {
106
- // Compile each schema now so a validator-hostile inputSchema surfaces once
107
- // here rather than silently on its first call. Warning-only; never throws.
108
- for (const t of opts.tools) {
109
- if (t.inputSchema)
110
- precompileValidator(t.inputSchema, { address: `${id}.${t.name}` });
111
- }
112
- }
113
- return {
114
- id,
115
- ...(opts.title !== undefined ? { title: opts.title } : {}),
116
- kind: "api",
117
- ...(opts.description !== undefined
118
- ? { description: opts.description }
119
- : {}),
120
- ...(opts.maxResultBytes !== undefined
121
- ? { maxResultBytes: opts.maxResultBytes }
122
- : {}),
123
- ...(opts.callAdmission !== undefined
124
- ? { callAdmission: opts.callAdmission }
125
- : {}),
126
- ...(opts.usageGuide !== undefined ? { usageGuide: opts.usageGuide } : {}),
127
- ...(opts.credential !== undefined ? { credential: opts.credential } : {}),
128
- ...(opts.testCredential !== undefined
129
- ? { testCredential: opts.testCredential }
130
- : {}),
131
- ...(opts.testCredentials !== undefined
132
- ? { testCredentials: opts.testCredentials }
133
- : {}),
134
- staticTools: defs,
135
- async listTools() {
136
- return defs;
137
- },
138
- async callTool(name, args, ctx) {
139
- const tool = byName.get(name);
140
- if (!tool) {
141
- throw new Error(`Unknown tool "${name}" on connector "${id}"`);
142
- }
143
- const input = args ?? {};
144
- if (validateArgs && tool.inputSchema) {
145
- const invalid = validateToolInput(tool.inputSchema, input, {
146
- address: `${id}.${name}`,
147
- logger: ctx.logger,
148
- failClosed: strictValidation,
149
- });
150
- if (invalid) throw invalid;
151
- }
152
- // `await` (not a bare promise return) so a handler that throws before
153
- // its first await never sits handler-less for the thenable-adoption
154
- // microtask — workerd and vitest both report that gap as an unhandled
155
- // rejection even though the caller catches the failure.
156
- return await tool.handler(input, ctx);
157
- },
158
- };
159
- }