@zackbart/connecta 0.28.0 → 0.29.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 (320) hide show
  1. package/CHANGELOG.md +961 -5
  2. package/README.md +62 -39
  3. package/bin/connecta.mjs +110 -139
  4. package/bin/meta-tool-names.d.mts +2 -0
  5. package/bin/meta-tool-names.mjs +9 -0
  6. package/bin/version.mjs +3 -0
  7. package/dist/access-tokens.js +53 -63
  8. package/dist/activity-request.js +8 -0
  9. package/dist/activity.d.ts +76 -42
  10. package/dist/activity.js +110 -42
  11. package/dist/auth/clerk-sdk/client.d.ts +65 -0
  12. package/dist/auth/clerk-sdk/client.js +5 -0
  13. package/dist/auth/clerk-sdk/generated.js +1845 -0
  14. package/dist/auth/clerk-transport.js +19 -0
  15. package/dist/auth/clerk.d.ts +17 -7
  16. package/dist/auth/clerk.js +189 -107
  17. package/dist/auth/cloudflare-access.js +25 -26
  18. package/dist/auth/downstream-client-metadata.d.ts +29 -0
  19. package/dist/auth/downstream-client-metadata.js +133 -0
  20. package/dist/auth/downstream-oauth.js +1632 -1509
  21. package/dist/auth/downstream-revocation.js +106 -0
  22. package/dist/auth/oauth-token-response.js +231 -0
  23. package/dist/auth/oauth-v2-migration.js +116 -0
  24. package/dist/auth/static-oauth.js +526 -0
  25. package/dist/auth-elicitation.js +283 -0
  26. package/dist/branding.d.ts +8 -16
  27. package/dist/branding.js +26 -59
  28. package/dist/byte-read-response.js +39 -0
  29. package/dist/call-admission.js +12 -16
  30. package/dist/catalog-cache.js +739 -0
  31. package/dist/catalog-drift.d.ts +50 -15
  32. package/dist/catalog-drift.js +365 -128
  33. package/dist/catalog-fingerprint.js +2 -4
  34. package/dist/catalog-freshness.js +13 -0
  35. package/dist/catalog-limits.js +2 -2
  36. package/dist/catalog-service.js +368 -224
  37. package/dist/catalog.js +43 -84
  38. package/dist/concurrency.js +3 -4
  39. package/dist/config-defaults.d.ts +39 -0
  40. package/dist/config-defaults.js +46 -0
  41. package/dist/config-schema.d.ts +181 -0
  42. package/dist/config-schema.js +435 -0
  43. package/dist/config-value-sources.js +102 -0
  44. package/dist/config.d.ts +631 -0
  45. package/dist/config.js +503 -0
  46. package/dist/connector-access.d.ts +1 -0
  47. package/dist/connector-access.js +13 -15
  48. package/dist/connector-caller.d.ts +8 -0
  49. package/dist/connector-caller.js +15 -6
  50. package/dist/connector-scope.js +1 -1
  51. package/dist/connectors/api-connector.d.ts +220 -0
  52. package/dist/connectors/api-connector.js +214 -0
  53. package/dist/connectors/api.d.ts +8 -71
  54. package/dist/connectors/api.js +13 -99
  55. package/dist/connectors/guarded-fetch.d.ts +144 -0
  56. package/dist/connectors/guarded-fetch.js +108 -25
  57. package/dist/connectors/negotiation-cache.js +46 -0
  58. package/dist/connectors/option-shapes.js +27 -0
  59. package/dist/connectors/remote-mcp.d.ts +30 -4
  60. package/dist/connectors/remote-mcp.js +1780 -351
  61. package/dist/connectors/resource-uri.js +335 -0
  62. package/dist/credential-contract.d.ts +10 -0
  63. package/dist/credential-rules.js +1 -3
  64. package/dist/credential-url.js +108 -0
  65. package/dist/credentials.d.ts +6 -1
  66. package/dist/credentials.js +27 -18
  67. package/dist/d1.d.ts +130 -0
  68. package/dist/d1.js +290 -0
  69. package/dist/describe-config.d.ts +165 -0
  70. package/dist/describe-config.js +315 -0
  71. package/dist/described.js +106 -0
  72. package/dist/downstream-input-context.js +119 -0
  73. package/dist/downstream-input.js +323 -0
  74. package/dist/errors.d.ts +97 -20
  75. package/dist/errors.js +158 -80
  76. package/dist/execute.js +453 -305
  77. package/dist/executor-admission.d.ts +1 -0
  78. package/dist/executor-admission.js +11 -15
  79. package/dist/executor-contract.d.ts +20 -0
  80. package/dist/executor-contract.js +48 -0
  81. package/dist/executor-result.js +24 -9
  82. package/dist/executors/quickjs-child.js +3 -4
  83. package/dist/executors/quickjs-runtime.js +147 -59
  84. package/dist/executors/quickjs.js +29 -35
  85. package/dist/favicon.js +1 -2
  86. package/dist/fix-prompt.js +1 -3
  87. package/dist/guest-runtime.js +188 -0
  88. package/dist/guest-types.d.ts +176 -0
  89. package/dist/guest-types.js +1 -0
  90. package/dist/html-security.js +24 -0
  91. package/dist/identity.js +1 -3
  92. package/dist/inbound-credential.js +52 -0
  93. package/dist/index.d.ts +25 -257
  94. package/dist/index.js +65 -478
  95. package/dist/invocation-auth.js +69 -0
  96. package/dist/invocation.js +230 -73
  97. package/dist/json-schema.d.ts +1 -1
  98. package/dist/mcp-client-context.js +35 -0
  99. package/dist/mcp-result.js +11 -7
  100. package/dist/meta-output.js +76 -0
  101. package/dist/meta-tool-names.d.ts +2 -0
  102. package/dist/meta-tool-names.js +3 -0
  103. package/dist/meta-tools.js +285 -209
  104. package/dist/module-contracts.d.ts +8 -23
  105. package/dist/node.d.ts +0 -2
  106. package/dist/node.js +2 -2
  107. package/dist/oauth-callback-outcome.js +1 -3
  108. package/dist/oauth-handoff.js +117 -0
  109. package/dist/oauth-partition.js +17 -0
  110. package/dist/oauth-sealing.js +20 -0
  111. package/dist/operator-record.d.ts +137 -0
  112. package/dist/operator-record.js +420 -0
  113. package/dist/operator-ui/assets.js +31 -0
  114. package/dist/operator-ui/contract.d.ts +72 -0
  115. package/dist/operator-ui/contract.js +1 -0
  116. package/dist/operator-ui/fix-prompts.d.ts +18 -0
  117. package/dist/operator-ui/generated.js +5 -4
  118. package/dist/operator-ui/model.d.ts +12 -87
  119. package/dist/operator-ui/model.js +2 -9
  120. package/dist/operator-ui/setup-commands.js +1 -3
  121. package/dist/operator-ui/view.d.ts +323 -0
  122. package/dist/operator-ui/view.js +62 -189
  123. package/dist/page-styles.js +2 -3
  124. package/dist/program-source.js +14 -2
  125. package/dist/{exempt-writes.js → program-writes.js} +55 -18
  126. package/dist/provider.d.ts +142 -0
  127. package/dist/provider.js +187 -0
  128. package/dist/providers/_shared/google/result-size.js +57 -0
  129. package/dist/providers/_shared/google/service-account.d.ts +58 -0
  130. package/dist/providers/_shared/google/service-account.js +500 -0
  131. package/dist/providers/_shared/google/workspace.d.ts +276 -0
  132. package/dist/providers/_shared/google/workspace.js +518 -0
  133. package/dist/providers/basecamp/index.d.ts +43 -0
  134. package/dist/providers/basecamp/index.js +997 -0
  135. package/dist/providers/basecamp/skill.generated.js +9 -0
  136. package/dist/providers/breeze/index.d.ts +34 -0
  137. package/dist/providers/breeze/index.js +1446 -0
  138. package/dist/providers/breeze/skill.generated.js +9 -0
  139. package/dist/providers/ccb/index.d.ts +103 -0
  140. package/dist/providers/ccb/index.js +1725 -0
  141. package/dist/providers/ccb/skill.generated.js +9 -0
  142. package/dist/providers/{cloudflare.d.ts → cloudflare/index.d.ts} +8 -7
  143. package/dist/providers/{cloudflare.js → cloudflare/index.js} +171 -738
  144. package/dist/providers/cloudflare/skill.generated.js +10 -0
  145. package/dist/providers/docs/index.d.ts +54 -0
  146. package/dist/providers/docs/index.js +1237 -0
  147. package/dist/providers/docs/skill.generated.js +9 -0
  148. package/dist/providers/drive/index.d.ts +53 -0
  149. package/dist/providers/drive/index.js +1523 -0
  150. package/dist/providers/drive/skill.generated.js +9 -0
  151. package/dist/providers/forms/index.d.ts +54 -0
  152. package/dist/providers/forms/index.js +1217 -0
  153. package/dist/providers/forms/skill.generated.js +11 -0
  154. package/dist/providers/github/auth.d.ts +32 -0
  155. package/dist/providers/github/auth.js +361 -0
  156. package/dist/providers/github/hosted.js +218 -0
  157. package/dist/providers/github/index.d.ts +13 -0
  158. package/dist/providers/github/index.js +140 -0
  159. package/dist/providers/github/key.js +100 -0
  160. package/dist/providers/github/rest.js +321 -0
  161. package/dist/providers/github/scope.d.ts +29 -0
  162. package/dist/providers/github/scope.js +124 -0
  163. package/dist/providers/github/skill.generated.js +8 -0
  164. package/dist/providers/gmail/index.d.ts +51 -0
  165. package/dist/providers/gmail/index.js +1436 -0
  166. package/dist/providers/gmail/skill.generated.js +9 -0
  167. package/dist/providers/{linear.d.ts → linear/index.d.ts} +11 -14
  168. package/dist/providers/linear/index.js +352 -0
  169. package/dist/providers/linear/skill.generated.js +8 -0
  170. package/dist/providers/{mixpanel.d.ts → mixpanel/index.d.ts} +5 -10
  171. package/dist/providers/mixpanel/index.js +416 -0
  172. package/dist/providers/mixpanel/skill.generated.js +9 -0
  173. package/dist/providers/{notion.d.ts → notion/index.d.ts} +8 -8
  174. package/dist/providers/{notion.js → notion/index.js} +226 -239
  175. package/dist/providers/notion/skill.generated.js +10 -0
  176. package/dist/providers/overflow/index.d.ts +60 -0
  177. package/dist/providers/overflow/index.js +1535 -0
  178. package/dist/providers/overflow/skill.generated.js +8 -0
  179. package/dist/providers/planning-center/index.d.ts +59 -0
  180. package/dist/providers/planning-center/index.js +2199 -0
  181. package/dist/providers/planning-center/skill.generated.js +10 -0
  182. package/dist/providers/{revenuecat.d.ts → revenuecat/index.d.ts} +5 -10
  183. package/dist/providers/revenuecat/index.js +557 -0
  184. package/dist/providers/revenuecat/skill.generated.js +11 -0
  185. package/dist/providers/sheets/index.d.ts +54 -0
  186. package/dist/providers/sheets/index.js +1237 -0
  187. package/dist/providers/sheets/skill.generated.js +10 -0
  188. package/dist/providers/slides/index.d.ts +53 -0
  189. package/dist/providers/slides/index.js +2645 -0
  190. package/dist/providers/slides/skill.generated.js +9 -0
  191. package/dist/providers/{stripe.d.ts → stripe/index.d.ts} +5 -12
  192. package/dist/providers/stripe/index.js +266 -0
  193. package/dist/providers/stripe/skill.generated.js +11 -0
  194. package/dist/providers/tithely/index.d.ts +49 -0
  195. package/dist/providers/tithely/index.js +1003 -0
  196. package/dist/providers/tithely/skill.generated.js +8 -0
  197. package/dist/providers/{vercel.d.ts → vercel/index.d.ts} +8 -8
  198. package/dist/providers/vercel/index.js +1038 -0
  199. package/dist/providers/vercel/mcp-ownership.js +212 -0
  200. package/dist/providers/vercel/skill.generated.js +11 -0
  201. package/dist/registry.d.ts +108 -171
  202. package/dist/registry.js +513 -925
  203. package/dist/request-state.js +21 -0
  204. package/dist/resource-read.js +100 -0
  205. package/dist/result-shapes.js +17 -49
  206. package/dist/retired-toolkits.js +1 -1
  207. package/dist/routes/access-tokens.js +3 -6
  208. package/dist/routes/activity-context.js +21 -0
  209. package/dist/routes/activity-disclosure.js +40 -0
  210. package/dist/routes/activity.js +59 -21
  211. package/dist/routes/actor-labels.js +3 -50
  212. package/dist/routes/connect.js +221 -0
  213. package/dist/routes/credentials.js +15 -27
  214. package/dist/routes/mcp.js +356 -130
  215. package/dist/routes/oauth-client-metadata.js +15 -0
  216. package/dist/routes/oauth-management.js +45 -107
  217. package/dist/routes/oauth.js +136 -57
  218. package/dist/routes/operator.js +3 -3
  219. package/dist/routes/shared.d.ts +25 -64
  220. package/dist/routes/shared.js +160 -80
  221. package/dist/routes/skills.js +30 -0
  222. package/dist/routes/ui-config.js +225 -0
  223. package/dist/routes/ui-data.js +40 -35
  224. package/dist/routes/ui.js +66 -56
  225. package/dist/runtime/admission.js +4 -2
  226. package/dist/runtime/call-admission.js +3 -1
  227. package/dist/runtime/connector-scope.js +1 -4
  228. package/dist/runtime/run.js +10 -39
  229. package/dist/runtime/services.js +12 -117
  230. package/dist/runtime/shared-read.js +1 -3
  231. package/dist/runtime/storage.js +8 -1
  232. package/dist/sent-secrets.d.ts +52 -0
  233. package/dist/sent-secrets.js +474 -0
  234. package/dist/server.js +28 -71
  235. package/dist/skills.js +406 -174
  236. package/dist/sqlite.d.ts +48 -0
  237. package/dist/sqlite.js +166 -0
  238. package/dist/storage/keys.js +428 -0
  239. package/dist/storage/memory.js +7 -0
  240. package/dist/storage/sql.d.ts +66 -0
  241. package/dist/storage/sql.js +534 -0
  242. package/dist/timeout.js +4 -2
  243. package/dist/tool-name.js +17 -0
  244. package/dist/tool-safety.d.ts +9 -35
  245. package/dist/tool-safety.js +20 -40
  246. package/dist/types.d.ts +320 -54
  247. package/dist/types.js +0 -1
  248. package/dist/ui.d.ts +7 -19
  249. package/dist/ui.js +76 -90
  250. package/dist/url-safety.js +3 -6
  251. package/dist/usage-guide.js +137 -0
  252. package/dist/validate.d.ts +7 -0
  253. package/dist/validate.js +309 -47
  254. package/dist/version.d.ts +1 -7
  255. package/dist/version.js +3 -7
  256. package/dist/worker.d.ts +11 -0
  257. package/dist/worker.js +434 -0
  258. package/documentation/architecture.md +665 -230
  259. package/documentation/auth.md +962 -458
  260. package/documentation/code-mode.md +501 -312
  261. package/documentation/meta-tools.md +449 -200
  262. package/documentation/operator-tests.md +93 -0
  263. package/documentation/provider-migration-0.29.md +60 -0
  264. package/examples/worker/AGENTS.md +34 -12
  265. package/examples/worker/README.md +286 -255
  266. package/examples/worker/kv-to-d1.wrangler.jsonc +26 -0
  267. package/examples/worker/scripts/copy-kv-to-d1.mjs +162 -0
  268. package/examples/worker/src/connecta.config.ts +151 -0
  269. package/examples/worker/src/index.ts +14 -197
  270. package/examples/worker/wrangler.jsonc +15 -35
  271. package/package.json +125 -35
  272. package/templates/node/.dockerignore +1 -2
  273. package/templates/node/.env.example +20 -21
  274. package/templates/node/AGENTS.md +21 -17
  275. package/templates/node/Dockerfile +3 -5
  276. package/templates/node/README.md +133 -58
  277. package/templates/node/docker-compose.yml +11 -12
  278. package/templates/node/package.json +4 -2
  279. package/templates/node/src/connecta.config.ts +119 -0
  280. package/templates/node/src/index.ts +9 -154
  281. package/templates/node/src/provision-token.ts +17 -0
  282. package/AGENTS.md +0 -170
  283. package/dist/artifacts/connector.d.ts +0 -58
  284. package/dist/artifacts/connector.js +0 -730
  285. package/dist/artifacts/document.js +0 -86
  286. package/dist/artifacts/guide.js +0 -140
  287. package/dist/artifacts/html-scan.js +0 -329
  288. package/dist/artifacts/json.js +0 -78
  289. package/dist/artifacts/kv-store.d.ts +0 -20
  290. package/dist/artifacts/kv-store.js +0 -140
  291. package/dist/artifacts/markdown.js +0 -478
  292. package/dist/artifacts/module.d.ts +0 -37
  293. package/dist/artifacts/module.js +0 -66
  294. package/dist/artifacts/operations.d.ts +0 -197
  295. package/dist/artifacts/operations.js +0 -1002
  296. package/dist/artifacts/refresh.d.ts +0 -55
  297. package/dist/artifacts/refresh.js +0 -236
  298. package/dist/artifacts/routes.js +0 -206
  299. package/dist/artifacts/types.d.ts +0 -214
  300. package/dist/artifacts/types.js +0 -22
  301. package/dist/artifacts/validate.d.ts +0 -62
  302. package/dist/artifacts/validate.js +0 -651
  303. package/dist/artifacts.d.ts +0 -6
  304. package/dist/artifacts.js +0 -9
  305. package/dist/auth/bearer.d.ts +0 -11
  306. package/dist/auth/bearer.js +0 -50
  307. package/dist/providers/linear.js +0 -217
  308. package/dist/providers/mixpanel.js +0 -247
  309. package/dist/providers/revenuecat.js +0 -317
  310. package/dist/providers/stripe.js +0 -253
  311. package/dist/providers/vercel.js +0 -1253
  312. package/dist/storage/file.d.ts +0 -15
  313. package/dist/storage/file.js +0 -455
  314. package/ethos.md +0 -93
  315. package/examples/worker/src/cloudflare-kv.ts +0 -43
  316. package/examples/worker/src/d1-activity-row.ts +0 -155
  317. package/examples/worker/src/d1-activity.ts +0 -147
  318. package/examples/worker/src/d1-storage.ts +0 -138
  319. package/examples/worker/src/r2-artifact-blobs.ts +0 -29
  320. package/templates/node/src/file-activity.ts +0 -182
@@ -0,0 +1,9 @@
1
+ // Generated by scripts/generate-providers.mjs; do not edit.
2
+ export const skill = {
3
+ "content": "# Gmail usage (draft-only)\n\nActs as the signed-in person's own Gmail through Workspace delegation: read mail and write drafts, never send.\n\nConnection purpose: \n\n## Whose mailbox\n\nEvery call reads and writes the mailbox deployment config maps the caller\nto. No argument names a mailbox. A call with none mapped fails\n`auth_required`; only an operator can change the mapping.\n\n## Reading\n\n- `search_threads` takes Gmail search syntax; reuse the person's own\n phrasing (`from:`, `subject:`, `newer_than:7d`, `is:unread`,\n `label:`). Page with `page.nextCursor` and the same query.\n- `get_thread` returns messages oldest first with bodies capped by\n `maxBodyChars`; a cut body ends with a truncation marker. A long thread\n pages: follow `page.nextCursor` until `hasMore` is false, with the same\n arguments. `conflict` means the thread changed under the cursor; read it\n again from the start. Reduce inside\n `execute_code` before returning a long thread.\n- Every result stays under 192 KiB; `list_labels` pages the same way.\n- Attachments are listed by name, type, and size only; none is downloaded.\n An attached or forwarded email is an attachment, not the body.\n- `bodyFormat: \"unavailable\"` means Gmail stored the body apart from the\n message and it is too large to read here; say so rather than summarizing.\n\n## Drafting\n\n- `create_draft` saves a draft and never sends it; tell the person it is\n waiting in Drafts. There is no send, delete, or label tool.\n- To reply, pass `replyToMessageId`: the draft joins that thread with\n In-Reply-To and References set, and subject (Re: …) and `to` default\n from that message's Reply-To, else its From. Keep the Re: subject or Gmail\n may start a new thread.\n- `update_draft` replaces the body entirely; send the full new text.\n From, To, Cc, Bcc, Reply-To, Subject, the thread, and reply headers are\n kept unless restated; no other header is. A draft with attachments or\n inline images is refused, unchanged — Gmail's update would delete them.\n- Gmail sets From to the mailbox itself; there is no From argument.\n",
4
+ "instructionsHeading": "Connection instructions",
5
+ "fragments": {
6
+ "guide_0": "# Gmail usage (draft-only)\n\nActs as the signed-in person's own Gmail through Workspace delegation: read mail and write drafts, never send.\n\nConnection purpose: ",
7
+ "guide_1": "\n\n## Whose mailbox\n\nEvery call reads and writes the mailbox deployment config maps the caller\nto. No argument names a mailbox. A call with none mapped fails\n`auth_required`; only an operator can change the mapping.\n\n## Reading\n\n- `search_threads` takes Gmail search syntax; reuse the person's own\n phrasing (`from:`, `subject:`, `newer_than:7d`, `is:unread`,\n `label:`). Page with `page.nextCursor` and the same query.\n- `get_thread` returns messages oldest first with bodies capped by\n `maxBodyChars`; a cut body ends with a truncation marker. A long thread\n pages: follow `page.nextCursor` until `hasMore` is false, with the same\n arguments. `conflict` means the thread changed under the cursor; read it\n again from the start. Reduce inside\n `execute_code` before returning a long thread.\n- Every result stays under 192 KiB; `list_labels` pages the same way.\n- Attachments are listed by name, type, and size only; none is downloaded.\n An attached or forwarded email is an attachment, not the body.\n- `bodyFormat: \"unavailable\"` means Gmail stored the body apart from the\n message and it is too large to read here; say so rather than summarizing.\n\n## Drafting\n\n- `create_draft` saves a draft and never sends it; tell the person it is\n waiting in Drafts. There is no send, delete, or label tool.\n- To reply, pass `replyToMessageId`: the draft joins that thread with\n In-Reply-To and References set, and subject (Re: …) and `to` default\n from that message's Reply-To, else its From. Keep the Re: subject or Gmail\n may start a new thread.\n- `update_draft` replaces the body entirely; send the full new text.\n From, To, Cc, Bcc, Reply-To, Subject, the thread, and reply headers are\n kept unless restated; no other header is. A draft with attachments or\n inline images is refused, unchanged — Gmail's update would delete them.\n- Gmail sets From to the mailbox itself; there is no From argument.\n"
8
+ }
9
+ };
@@ -1,5 +1,6 @@
1
- import { type RemoteMcpAuth } from "../connectors/remote-mcp.js";
2
- import type { Connector, ConnectorCallAdmissionPolicy } from "../types.js";
1
+ import { type RemoteMcpAuth } from "../../connectors/remote-mcp.js";
2
+ import { type ProviderOptions } from "../../provider.js";
3
+ import type { ConnectorCallAdmissionPolicy } from "../../types.js";
3
4
  /** Which of Linear's two hosted MCP endpoints this connection is bound to. */
4
5
  export type LinearAccess = "read-write" | "read-only";
5
6
  /**
@@ -9,14 +10,12 @@ export type LinearAccess = "read-write" | "read-only";
9
10
  * deliberately absent — it now answers 404.
10
11
  */
11
12
  export declare const LINEAR_MCP_ENDPOINTS: Readonly<Record<LinearAccess, string>>;
12
- export interface LinearOptions {
13
+ export interface LinearOptions extends ProviderOptions {
13
14
  /**
14
15
  * Human-readable display name; defaults to "Linear", or
15
16
  * "Linear (read-only)" when `access` is `"read-only"`.
16
17
  */
17
18
  title?: string;
18
- /** Downstream auth ownership. Defaults to one shared deployment grant. */
19
- authScope?: "shared" | "personal";
20
19
  /** Which workspace this is and what decisions it answers. */
21
20
  purpose: string;
22
21
  /**
@@ -37,8 +36,6 @@ export interface LinearOptions {
37
36
  auth?: RemoteMcpAuth;
38
37
  /** Workspace-specific conventions appended to the maintained provider guide. */
39
38
  instructions?: string;
40
- /** Connector-specific inline result limit; omit to inherit the deployment. */
41
- maxResultBytes?: number;
42
39
  /**
43
40
  * Optional per-runtime policy. There is no default: Linear documents no
44
41
  * MCP-specific limit, the GraphQL limits it rides are metered per user per
@@ -47,12 +44,12 @@ export interface LinearOptions {
47
44
  */
48
45
  callAdmission?: ConnectorCallAdmissionPolicy;
49
46
  }
47
+ /** A maintained Linear hosted-MCP connection. */
48
+ export declare const linear: import("../../provider.js").ProviderFactory<LinearOptions>;
50
49
  /**
51
- * One release-reviewed manifest, used both to classify a live tool and as the
52
- * baseline the drift check compares against, so the annotation a caller gets
53
- * and the verdict a check reads can never disagree. Drift must surface as an
54
- * unclassified tool on the approval path (P5), never a quiet re-guess.
50
+ * The reviewed classification in the legacy manifest form.
51
+ *
52
+ * @deprecated Read `linear.definition.classify` instead. This alias is derived
53
+ * from it and retained for existing public imports.
55
54
  */
56
- export declare const LINEAR_VETTED_CATALOG: import("../catalog-drift.js").VettedCatalog;
57
- /** A maintained Linear hosted-MCP connection. */
58
- export declare function linear(id: string, options: LinearOptions): Connector;
55
+ export declare const LINEAR_VETTED_CATALOG: import("../../catalog-drift.js").VettedCatalog;
@@ -0,0 +1,352 @@
1
+ import { skill } from "./skill.generated.js";
2
+ import { remoteMcp, withCredentialDefaults } from "../../connectors/remote-mcp.js";
3
+ import { keys, optionsOf } from "../../config-schema.js";
4
+ import { REMOTE_MCP_AUTH } from "../../connectors/option-shapes.js";
5
+ import { reviewedCatalog } from "../../catalog-drift.js";
6
+ import { defineProvider, PROVIDER_COMMON } from "../../provider.js";
7
+ /**
8
+ * Linear publishes two hosted endpoints. `read-only` is not a client-side
9
+ * filter: it advertises the `read` scope alone, so the token minted for it
10
+ * cannot reach Linear's write APIs at all. The deprecated `/sse` transport is
11
+ * deliberately absent — it now answers 404.
12
+ */
13
+ export const LINEAR_MCP_ENDPOINTS = {
14
+ "read-write": "https://mcp.linear.app/mcp",
15
+ "read-only": "https://mcp.linear.app/mcp/readonly",
16
+ };
17
+ /**
18
+ * Every `save_*` is destructive because Linear's `save_*` tools are upserts:
19
+ * omitting a record id creates, supplying one overwrites in place, and the
20
+ * schema cannot tell them apart.
21
+ */
22
+ const UPSERT = "An upsert: supplying a record id overwrites that record in place, and the schema cannot tell a create from an update.";
23
+ /**
24
+ * The release-reviewed classification (P5), used both to classify a live tool
25
+ * and as the record the drift check compares against, so the annotation a
26
+ * caller gets and the verdict a check reads can never disagree. It is a
27
+ * superset: Linear's hosted `tools/list` varies by plan and enabled features,
28
+ * so a name this workspace never returns costs nothing, while an unlisted new
29
+ * one fails closed. The genuine creates — the `create_*_label` and attachment
30
+ * tools — are plain writes rather than destructive.
31
+ */
32
+ const LINEAR_CLASSIFICATION = {
33
+ tools: {
34
+ // Issues
35
+ list_issues: {
36
+ "verdict": "read",
37
+ "reason": "Reads existing Linear list issues data without changing workspace state.",
38
+ },
39
+ get_issue: {
40
+ "verdict": "read",
41
+ "reason": "Reads existing Linear get issue data without changing workspace state.",
42
+ },
43
+ list_issue_statuses: {
44
+ "verdict": "read",
45
+ "reason": "Reads existing Linear list issue statuses data without changing workspace state.",
46
+ },
47
+ get_issue_status: {
48
+ "verdict": "read",
49
+ "reason": "Reads existing Linear get issue status data without changing workspace state.",
50
+ },
51
+ list_issue_labels: {
52
+ "verdict": "read",
53
+ "reason": "Reads existing Linear list issue labels data without changing workspace state.",
54
+ },
55
+ save_issue: { verdict: "destructive", reason: UPSERT },
56
+ create_issue_label: {
57
+ "verdict": "write",
58
+ "reason": "Creates Linear state through create_issue_label; the reviewed operation only appends.",
59
+ },
60
+ // Projects
61
+ list_projects: {
62
+ "verdict": "read",
63
+ "reason": "Reads existing Linear list projects data without changing workspace state.",
64
+ },
65
+ get_project: {
66
+ "verdict": "read",
67
+ "reason": "Reads existing Linear get project data without changing workspace state.",
68
+ },
69
+ list_project_labels: {
70
+ "verdict": "read",
71
+ "reason": "Reads existing Linear list project labels data without changing workspace state.",
72
+ },
73
+ save_project: { verdict: "destructive", reason: UPSERT },
74
+ // Milestones
75
+ list_milestones: {
76
+ "verdict": "read",
77
+ "reason": "Reads existing Linear list milestones data without changing workspace state.",
78
+ },
79
+ get_milestone: {
80
+ "verdict": "read",
81
+ "reason": "Reads existing Linear get milestone data without changing workspace state.",
82
+ },
83
+ save_milestone: { verdict: "destructive", reason: UPSERT },
84
+ // Initiatives
85
+ list_initiatives: {
86
+ "verdict": "read",
87
+ "reason": "Reads existing Linear list initiatives data without changing workspace state.",
88
+ },
89
+ get_initiative: {
90
+ "verdict": "read",
91
+ "reason": "Reads existing Linear get initiative data without changing workspace state.",
92
+ },
93
+ list_initiative_labels: {
94
+ "verdict": "read",
95
+ "reason": "Reads existing Linear list initiative labels data without changing workspace state.",
96
+ },
97
+ save_initiative: { verdict: "destructive", reason: UPSERT },
98
+ create_initiative_label: {
99
+ "verdict": "write",
100
+ "reason": "Creates Linear state through create_initiative_label; the reviewed operation only appends.",
101
+ },
102
+ // Cycles
103
+ list_cycles: {
104
+ "verdict": "read",
105
+ "reason": "Reads existing Linear list cycles data without changing workspace state.",
106
+ },
107
+ // Comments
108
+ list_comments: {
109
+ "verdict": "read",
110
+ "reason": "Reads existing Linear list comments data without changing workspace state.",
111
+ },
112
+ save_comment: { verdict: "destructive", reason: UPSERT },
113
+ delete_comment: {
114
+ "verdict": "destructive",
115
+ "reason": "Changes or removes existing Linear state through delete_comment.",
116
+ },
117
+ // Documents
118
+ list_documents: {
119
+ "verdict": "read",
120
+ "reason": "Reads existing Linear list documents data without changing workspace state.",
121
+ },
122
+ get_document: {
123
+ "verdict": "read",
124
+ "reason": "Reads existing Linear get document data without changing workspace state.",
125
+ },
126
+ save_document: { verdict: "destructive", reason: UPSERT },
127
+ // Teams and users
128
+ list_teams: {
129
+ "verdict": "read",
130
+ "reason": "Reads existing Linear list teams data without changing workspace state.",
131
+ },
132
+ get_team: { "verdict": "read", "reason": "Reads existing Linear get team data without changing workspace state." },
133
+ list_users: {
134
+ "verdict": "read",
135
+ "reason": "Reads existing Linear list users data without changing workspace state.",
136
+ },
137
+ get_user: { "verdict": "read", "reason": "Reads existing Linear get user data without changing workspace state." },
138
+ get_workspace: {
139
+ "verdict": "read",
140
+ "reason": "Reads existing Linear get workspace data without changing workspace state.",
141
+ },
142
+ // Templates
143
+ list_templates: {
144
+ "verdict": "read",
145
+ "reason": "Reads existing Linear list templates data without changing workspace state.",
146
+ },
147
+ get_template: {
148
+ "verdict": "read",
149
+ "reason": "Reads existing Linear get template data without changing workspace state.",
150
+ },
151
+ // Status updates
152
+ get_status_updates: {
153
+ "verdict": "read",
154
+ "reason": "Reads existing Linear get status updates data without changing workspace state.",
155
+ },
156
+ save_status_update: { verdict: "destructive", reason: UPSERT },
157
+ delete_status_update: {
158
+ "verdict": "destructive",
159
+ "reason": "Changes or removes existing Linear state through delete_status_update.",
160
+ },
161
+ // Releases
162
+ list_release_pipelines: {
163
+ "verdict": "read",
164
+ "reason": "Reads existing Linear list release pipelines data without changing workspace state.",
165
+ },
166
+ list_releases: {
167
+ "verdict": "read",
168
+ "reason": "Reads existing Linear list releases data without changing workspace state.",
169
+ },
170
+ get_release: {
171
+ "verdict": "read",
172
+ "reason": "Reads existing Linear get release data without changing workspace state.",
173
+ },
174
+ list_release_notes: {
175
+ "verdict": "read",
176
+ "reason": "Reads existing Linear list release notes data without changing workspace state.",
177
+ },
178
+ get_release_note: {
179
+ "verdict": "read",
180
+ "reason": "Reads existing Linear get release note data without changing workspace state.",
181
+ },
182
+ save_release: { verdict: "destructive", reason: UPSERT },
183
+ save_release_note: { verdict: "destructive", reason: UPSERT },
184
+ // Code review
185
+ list_diffs: {
186
+ "verdict": "read",
187
+ "reason": "Reads existing Linear list diffs data without changing workspace state.",
188
+ },
189
+ get_diff: { "verdict": "read", "reason": "Reads existing Linear get diff data without changing workspace state." },
190
+ get_diff_threads: {
191
+ "verdict": "read",
192
+ "reason": "Reads existing Linear get diff threads data without changing workspace state.",
193
+ },
194
+ save_diff_comment: { verdict: "destructive", reason: UPSERT },
195
+ resolve_diff_thread: {
196
+ "verdict": "destructive",
197
+ "reason": "Changes or removes existing Linear state through resolve_diff_thread.",
198
+ },
199
+ delete_diff_comment: {
200
+ "verdict": "destructive",
201
+ "reason": "Changes or removes existing Linear state through delete_diff_comment.",
202
+ },
203
+ submit_diff_review: {
204
+ "verdict": "destructive",
205
+ "reason": "Changes or removes existing Linear state through submit_diff_review.",
206
+ },
207
+ merge_diff: { "verdict": "destructive", "reason": "Changes or removes existing Linear state through merge_diff." },
208
+ // Attachments
209
+ get_attachment: {
210
+ "verdict": "read",
211
+ "reason": "Reads existing Linear get attachment data without changing workspace state.",
212
+ },
213
+ prepare_attachment_upload: {
214
+ verdict: "write",
215
+ reason: "Mints an upload URL: a side effect, but it changes no existing record.",
216
+ },
217
+ create_attachment_from_upload: {
218
+ "verdict": "write",
219
+ "reason": "Creates Linear state through create_attachment_from_upload; the reviewed operation only appends.",
220
+ },
221
+ create_attachment: {
222
+ "verdict": "write",
223
+ "reason": "Creates Linear state through create_attachment; the reviewed operation only appends.",
224
+ },
225
+ delete_attachment: {
226
+ "verdict": "destructive",
227
+ "reason": "Changes or removes existing Linear state through delete_attachment.",
228
+ },
229
+ // Explicit issue access.
230
+ share_issue: {
231
+ verdict: "destructive",
232
+ reason: "Changes who can see an existing issue.",
233
+ },
234
+ unshare_issue: {
235
+ verdict: "destructive",
236
+ reason: "Changes who can see an existing issue.",
237
+ },
238
+ // Agent skills
239
+ list_agent_skills: {
240
+ "verdict": "read",
241
+ "reason": "Reads existing Linear list agent skills data without changing workspace state.",
242
+ },
243
+ get_agent_skill: {
244
+ "verdict": "read",
245
+ "reason": "Reads existing Linear get agent skill data without changing workspace state.",
246
+ },
247
+ // Documentation search
248
+ search_documentation: {
249
+ "verdict": "read",
250
+ "reason": "Reads existing Linear search documentation data without changing workspace state.",
251
+ },
252
+ // Customer requests (plan-gated)
253
+ list_customers: {
254
+ "verdict": "read",
255
+ "reason": "Reads existing Linear list customers data without changing workspace state.",
256
+ },
257
+ save_customer: { verdict: "destructive", reason: UPSERT },
258
+ delete_customer: {
259
+ "verdict": "destructive",
260
+ "reason": "Changes or removes existing Linear state through delete_customer.",
261
+ },
262
+ save_customer_need: { verdict: "destructive", reason: UPSERT },
263
+ delete_customer_need: {
264
+ "verdict": "destructive",
265
+ "reason": "Changes or removes existing Linear state through delete_customer_need.",
266
+ },
267
+ // Markdown helper.
268
+ extract_images: {
269
+ verdict: "read",
270
+ reason: "Reads images out of content it is handed and touches no workspace state; the hosted server ships it annotated readOnlyHint: true and idempotentHint: true.",
271
+ },
272
+ },
273
+ };
274
+ /**
275
+ * Connection-independent conventions. The access note and purpose lead the
276
+ * rendered guide; deployment instructions follow it.
277
+ */
278
+ /** The closed options linear() accepts, checked against LinearOptions. */
279
+ const LINEAR_OPTIONS = optionsOf()({
280
+ ...PROVIDER_COMMON,
281
+ ...keys("access"),
282
+ auth: REMOTE_MCP_AUTH,
283
+ });
284
+ /** A maintained Linear hosted-MCP connection. */
285
+ export const linear = defineProvider({
286
+ name: "linear",
287
+ title: "Linear",
288
+ kind: "mcp",
289
+ readme: "Linear",
290
+ bundle: { "baselineGzip": 127244, "maxGzip": 187244 },
291
+ skill,
292
+ options: LINEAR_OPTIONS,
293
+ classify: LINEAR_CLASSIFICATION,
294
+ create(id, options, provider) {
295
+ const access = options.access;
296
+ if (access !== "read-write" && access !== "read-only") {
297
+ throw new Error(`linear("${id}") requires access "read-write" or "read-only".`);
298
+ }
299
+ // Leads the guide because discovery summarizes a connector by its first
300
+ // content line: whether this connection can write at all is the one thing
301
+ // an agent must know before it opens the guide, and `search_tools` shows
302
+ // the summary without the description.
303
+ const accessNote = access === "read-only"
304
+ ? "Read-only connection: bound to Linear's read-only endpoint, whose token is scope-limited downstream, so every write fails at Linear regardless of arguments. Route writes to a connector configured for read-write access."
305
+ : "Read-write connection: treat every `save_`, `create_`, `delete_`, `resolve_`, `submit_`, and `merge_` operation as a write. Connecta classifies the maintained writes explicitly and enforces the configured pool trust policy. Unknown tools without an explicit, uncontradicted read annotation fail closed.";
306
+ return remoteMcp(id, {
307
+ url: LINEAR_MCP_ENDPOINTS[access],
308
+ ...provider.connectorOptions,
309
+ // The title is what browse-time discovery renders; a read-only
310
+ // connection says so there rather than only in a description the caller
311
+ // may not see.
312
+ title: options.title ?? (access === "read-only" ? "Linear (read-only)" : "Linear"),
313
+ description: access === "read-only"
314
+ ? `Linear issue tracking and project planning (read-only) — ${options.purpose}`
315
+ : `Linear issue tracking and project planning — ${options.purpose}`,
316
+ // Linear's MCP endpoint takes an API key the same way it takes an OAuth
317
+ // token — `Authorization: Bearer <yourtoken>` — so only the slot copy is
318
+ // provider-specific and the bearer framing default stands. The
319
+ // bare-header convention belongs to Linear's GraphQL API, not to this
320
+ // endpoint.
321
+ auth: withCredentialDefaults(options.auth ?? { type: "oauth" }, {
322
+ credential: {
323
+ label: "Personal API key",
324
+ description: "A Linear personal API key. It carries the issuing user's full workspace access and is stored encrypted; the read-only endpoint still limits what it can reach.",
325
+ placeholder: "lin_api_…",
326
+ },
327
+ }),
328
+ requireHttps: true,
329
+ classify: provider.classify,
330
+ usageGuide: provider.usageGuide({
331
+ context: [accessNote, `Workspace purpose: ${options.purpose}`],
332
+ // Explicit rather than derived. The derived summary would truncate the
333
+ // access note mid-sentence at 120 characters, and the one thing a
334
+ // browsing agent must not get wrong is whether this connection can
335
+ // write at all ([#342](https://github.com/zackbart/connecta/issues/342)).
336
+ // Not `required`: Linear's own schemas describe each call correctly;
337
+ // the guide adds cross-tool sequence advice worth reading before a
338
+ // write, not before every read.
339
+ summary: access === "read-only"
340
+ ? "Read-only: every write fails at Linear. Id resolution, upsert semantics, and cursor paging."
341
+ : "Read-write. Id resolution, `save_*` upsert semantics, plan-gated areas, and cursor paging.",
342
+ }),
343
+ });
344
+ },
345
+ });
346
+ /**
347
+ * The reviewed classification in the legacy manifest form.
348
+ *
349
+ * @deprecated Read `linear.definition.classify` instead. This alias is derived
350
+ * from it and retained for existing public imports.
351
+ */
352
+ export const LINEAR_VETTED_CATALOG = reviewedCatalog(linear.definition.classify, 'defineProvider("linear")');
@@ -0,0 +1,8 @@
1
+ // Generated by scripts/generate-providers.mjs; do not edit.
2
+ export const skill = {
3
+ "content": "- Issue arguments use `state`, not `status`. Resolve team-specific states through `list_issue_statuses` and use the value format required by the live input schema.\n- Resolve identity before acting. `list_teams`, `list_users`, `list_projects`, `list_issue_statuses`, and `list_issue_labels` return the ids that create and update arguments expect; do not guess a team, status, label, or assignee id.\n- Issues carry a human identifier like `ENG-123` — team key, dash, number — alongside a UUID. Use the identifier the request gave you and resolve it with `get_issue` or `list_issues` when a tool wants an id; never fabricate an identifier or renumber one.\n- `save_*` tools are upserts: omit the record id to create, supply it to update in place. Read the record first when you mean to update, and send only the fields you intend to change — an upsert overwrites what you restate.\n- Labels are the exception to that naming: `create_issue_label` and `create_initiative_label` only ever create.\n- Projects, milestones, and initiatives nest: initiatives contain projects, projects contain milestones and issues, and cycles are per-team time boxes. Scope a search by team or project rather than listing the workspace and filtering afterwards.\n- List tools paginate with a cursor. Thread the returned cursor for the next page instead of raising the page size, and reduce pages inside `execute_code` before returning them.\n- This workspace's catalog is not the whole product. Customer requests, releases, and code review are plan- and feature-gated, so search the catalog for what this connector actually exposes rather than assuming a tool exists.\n- Linear meters the underlying API per user per hour, shared with everything else that credential does. Reuse discovery results within a run and avoid speculative fan-out.\n- An `auth_required` failure means this connector's Linear authorization is missing or expired: run `authorize_connector` for this connector id, then retry the same call unchanged.",
4
+ "instructionsHeading": "Workspace instructions",
5
+ "fragments": {
6
+ "content": "- Issue arguments use `state`, not `status`. Resolve team-specific states through `list_issue_statuses` and use the value format required by the live input schema.\n- Resolve identity before acting. `list_teams`, `list_users`, `list_projects`, `list_issue_statuses`, and `list_issue_labels` return the ids that create and update arguments expect; do not guess a team, status, label, or assignee id.\n- Issues carry a human identifier like `ENG-123` — team key, dash, number — alongside a UUID. Use the identifier the request gave you and resolve it with `get_issue` or `list_issues` when a tool wants an id; never fabricate an identifier or renumber one.\n- `save_*` tools are upserts: omit the record id to create, supply it to update in place. Read the record first when you mean to update, and send only the fields you intend to change — an upsert overwrites what you restate.\n- Labels are the exception to that naming: `create_issue_label` and `create_initiative_label` only ever create.\n- Projects, milestones, and initiatives nest: initiatives contain projects, projects contain milestones and issues, and cycles are per-team time boxes. Scope a search by team or project rather than listing the workspace and filtering afterwards.\n- List tools paginate with a cursor. Thread the returned cursor for the next page instead of raising the page size, and reduce pages inside `execute_code` before returning them.\n- This workspace's catalog is not the whole product. Customer requests, releases, and code review are plan- and feature-gated, so search the catalog for what this connector actually exposes rather than assuming a tool exists.\n- Linear meters the underlying API per user per hour, shared with everything else that credential does. Reuse discovery results within a run and avoid speculative fan-out.\n- An `auth_required` failure means this connector's Linear authorization is missing or expired: run `authorize_connector` for this connector id, then retry the same call unchanged."
7
+ }
8
+ };
@@ -1,5 +1,5 @@
1
- import { type RemoteMcpAuth } from "../connectors/remote-mcp.js";
2
- import type { Connector, ConnectorCallAdmissionPolicy } from "../types.js";
1
+ import { type RemoteMcpAuth } from "../../connectors/remote-mcp.js";
2
+ import type { ConnectorCallAdmissionPolicy } from "../../types.js";
3
3
  export type MixpanelRegion = "us" | "eu" | "in";
4
4
  export declare const MIXPANEL_MCP_ENDPOINTS: Readonly<Record<MixpanelRegion, string>>;
5
5
  export interface MixpanelOptions {
@@ -36,12 +36,7 @@ export interface MixpanelOptions {
36
36
  */
37
37
  callAdmission?: ConnectorCallAdmissionPolicy;
38
38
  }
39
- /**
40
- * One release-reviewed manifest, used both to classify a live tool and as the
41
- * baseline the drift check compares against, so the annotation a caller gets
42
- * and the verdict a check reads can never disagree. Drift must surface as an
43
- * unclassified tool on the approval path (P5), never a quiet re-guess.
44
- */
45
- export declare const MIXPANEL_VETTED_CATALOG: import("../catalog-drift.js").VettedCatalog;
46
39
  /** A maintained Mixpanel hosted-MCP connection. */
47
- export declare function mixpanel(id: string, options: MixpanelOptions): Connector;
40
+ export declare const mixpanel: import("../../provider.js").ProviderFactory<MixpanelOptions>;
41
+ /** @deprecated Read `mixpanel.definition.classify` instead. Kept for existing imports. */
42
+ export declare const MIXPANEL_VETTED_CATALOG: import("../../catalog-drift.js").VettedCatalog;