@zackbart/connecta 0.28.1 → 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 (319) hide show
  1. package/CHANGELOG.md +788 -5
  2. package/README.md +62 -42
  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 +1584 -1580
  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 +93 -71
  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 +59 -7
  52. package/dist/connectors/api-connector.js +106 -19
  53. package/dist/connectors/api.js +4 -1
  54. package/dist/connectors/guarded-fetch.d.ts +144 -0
  55. package/dist/connectors/guarded-fetch.js +84 -35
  56. package/dist/connectors/negotiation-cache.js +46 -0
  57. package/dist/connectors/option-shapes.js +27 -0
  58. package/dist/connectors/remote-mcp.d.ts +30 -4
  59. package/dist/connectors/remote-mcp.js +1774 -320
  60. package/dist/connectors/resource-uri.js +335 -0
  61. package/dist/credential-contract.d.ts +10 -0
  62. package/dist/credential-rules.js +1 -3
  63. package/dist/credential-url.js +108 -0
  64. package/dist/credentials.d.ts +6 -1
  65. package/dist/credentials.js +27 -18
  66. package/dist/d1.d.ts +130 -0
  67. package/dist/d1.js +290 -0
  68. package/dist/describe-config.d.ts +165 -0
  69. package/dist/describe-config.js +315 -0
  70. package/dist/described.js +106 -0
  71. package/dist/downstream-input-context.js +119 -0
  72. package/dist/downstream-input.js +323 -0
  73. package/dist/errors.d.ts +97 -20
  74. package/dist/errors.js +158 -80
  75. package/dist/execute.js +453 -305
  76. package/dist/executor-admission.d.ts +1 -0
  77. package/dist/executor-admission.js +11 -15
  78. package/dist/executor-contract.d.ts +20 -0
  79. package/dist/executor-contract.js +48 -0
  80. package/dist/executor-result.js +24 -9
  81. package/dist/executors/quickjs-child.js +3 -4
  82. package/dist/executors/quickjs-runtime.js +147 -59
  83. package/dist/executors/quickjs.js +29 -35
  84. package/dist/favicon.js +1 -2
  85. package/dist/fix-prompt.js +1 -3
  86. package/dist/guest-runtime.js +188 -0
  87. package/dist/guest-types.d.ts +176 -0
  88. package/dist/guest-types.js +1 -0
  89. package/dist/html-security.js +24 -0
  90. package/dist/identity.js +1 -3
  91. package/dist/inbound-credential.js +52 -0
  92. package/dist/index.d.ts +24 -256
  93. package/dist/index.js +65 -478
  94. package/dist/invocation-auth.js +69 -0
  95. package/dist/invocation.js +230 -73
  96. package/dist/json-schema.d.ts +1 -1
  97. package/dist/mcp-client-context.js +35 -0
  98. package/dist/mcp-result.js +11 -7
  99. package/dist/meta-output.js +76 -0
  100. package/dist/meta-tool-names.d.ts +2 -0
  101. package/dist/meta-tool-names.js +3 -0
  102. package/dist/meta-tools.js +285 -209
  103. package/dist/module-contracts.d.ts +8 -23
  104. package/dist/node.d.ts +0 -2
  105. package/dist/node.js +2 -2
  106. package/dist/oauth-callback-outcome.js +1 -3
  107. package/dist/oauth-handoff.js +117 -0
  108. package/dist/oauth-sealing.js +20 -0
  109. package/dist/operator-record.d.ts +137 -0
  110. package/dist/operator-record.js +420 -0
  111. package/dist/operator-ui/assets.js +31 -0
  112. package/dist/operator-ui/contract.d.ts +72 -0
  113. package/dist/operator-ui/contract.js +1 -0
  114. package/dist/operator-ui/fix-prompts.d.ts +18 -0
  115. package/dist/operator-ui/generated.js +5 -4
  116. package/dist/operator-ui/model.d.ts +12 -87
  117. package/dist/operator-ui/model.js +2 -9
  118. package/dist/operator-ui/setup-commands.js +1 -3
  119. package/dist/operator-ui/view.d.ts +323 -0
  120. package/dist/operator-ui/view.js +62 -189
  121. package/dist/page-styles.js +2 -3
  122. package/dist/program-source.js +14 -2
  123. package/dist/{exempt-writes.js → program-writes.js} +55 -18
  124. package/dist/provider.d.ts +142 -0
  125. package/dist/provider.js +187 -0
  126. package/dist/providers/_shared/google/result-size.js +57 -0
  127. package/dist/providers/_shared/google/service-account.d.ts +58 -0
  128. package/dist/providers/_shared/google/service-account.js +500 -0
  129. package/dist/providers/_shared/google/workspace.d.ts +276 -0
  130. package/dist/providers/_shared/google/workspace.js +518 -0
  131. package/dist/providers/{basecamp.d.ts → basecamp/index.d.ts} +6 -28
  132. package/dist/providers/basecamp/index.js +997 -0
  133. package/dist/providers/basecamp/skill.generated.js +9 -0
  134. package/dist/providers/{breeze.d.ts → breeze/index.d.ts} +2 -2
  135. package/dist/providers/{breeze.js → breeze/index.js} +184 -140
  136. package/dist/providers/breeze/skill.generated.js +9 -0
  137. package/dist/providers/{ccb.d.ts → ccb/index.d.ts} +2 -2
  138. package/dist/providers/{ccb.js → ccb/index.js} +271 -116
  139. package/dist/providers/ccb/skill.generated.js +9 -0
  140. package/dist/providers/{cloudflare.d.ts → cloudflare/index.d.ts} +8 -7
  141. package/dist/providers/{cloudflare.js → cloudflare/index.js} +171 -738
  142. package/dist/providers/cloudflare/skill.generated.js +10 -0
  143. package/dist/providers/docs/index.d.ts +54 -0
  144. package/dist/providers/docs/index.js +1237 -0
  145. package/dist/providers/docs/skill.generated.js +9 -0
  146. package/dist/providers/drive/index.d.ts +53 -0
  147. package/dist/providers/drive/index.js +1523 -0
  148. package/dist/providers/drive/skill.generated.js +9 -0
  149. package/dist/providers/forms/index.d.ts +54 -0
  150. package/dist/providers/forms/index.js +1217 -0
  151. package/dist/providers/forms/skill.generated.js +11 -0
  152. package/dist/providers/github/auth.d.ts +32 -0
  153. package/dist/providers/github/auth.js +361 -0
  154. package/dist/providers/github/hosted.js +218 -0
  155. package/dist/providers/github/index.d.ts +13 -0
  156. package/dist/providers/github/index.js +140 -0
  157. package/dist/providers/github/key.js +100 -0
  158. package/dist/providers/github/rest.js +321 -0
  159. package/dist/providers/github/scope.d.ts +29 -0
  160. package/dist/providers/github/scope.js +124 -0
  161. package/dist/providers/github/skill.generated.js +8 -0
  162. package/dist/providers/gmail/index.d.ts +51 -0
  163. package/dist/providers/gmail/index.js +1436 -0
  164. package/dist/providers/gmail/skill.generated.js +9 -0
  165. package/dist/providers/{linear.d.ts → linear/index.d.ts} +11 -14
  166. package/dist/providers/linear/index.js +352 -0
  167. package/dist/providers/linear/skill.generated.js +8 -0
  168. package/dist/providers/{mixpanel.d.ts → mixpanel/index.d.ts} +5 -10
  169. package/dist/providers/mixpanel/index.js +416 -0
  170. package/dist/providers/mixpanel/skill.generated.js +9 -0
  171. package/dist/providers/{notion.d.ts → notion/index.d.ts} +8 -8
  172. package/dist/providers/{notion.js → notion/index.js} +226 -239
  173. package/dist/providers/notion/skill.generated.js +10 -0
  174. package/dist/providers/{overflow.d.ts → overflow/index.d.ts} +2 -2
  175. package/dist/providers/{overflow.js → overflow/index.js} +74 -111
  176. package/dist/providers/overflow/skill.generated.js +8 -0
  177. package/dist/providers/{planning-center.d.ts → planning-center/index.d.ts} +2 -2
  178. package/dist/providers/{planning-center.js → planning-center/index.js} +264 -104
  179. package/dist/providers/planning-center/skill.generated.js +10 -0
  180. package/dist/providers/{revenuecat.d.ts → revenuecat/index.d.ts} +5 -10
  181. package/dist/providers/revenuecat/index.js +557 -0
  182. package/dist/providers/revenuecat/skill.generated.js +11 -0
  183. package/dist/providers/sheets/index.d.ts +54 -0
  184. package/dist/providers/sheets/index.js +1237 -0
  185. package/dist/providers/sheets/skill.generated.js +10 -0
  186. package/dist/providers/slides/index.d.ts +53 -0
  187. package/dist/providers/slides/index.js +2645 -0
  188. package/dist/providers/slides/skill.generated.js +9 -0
  189. package/dist/providers/{stripe.d.ts → stripe/index.d.ts} +5 -12
  190. package/dist/providers/stripe/index.js +266 -0
  191. package/dist/providers/stripe/skill.generated.js +11 -0
  192. package/dist/providers/{tithely.d.ts → tithely/index.d.ts} +2 -2
  193. package/dist/providers/{tithely.js → tithely/index.js} +60 -91
  194. package/dist/providers/tithely/skill.generated.js +8 -0
  195. package/dist/providers/{vercel.d.ts → vercel/index.d.ts} +8 -8
  196. package/dist/providers/vercel/index.js +1038 -0
  197. package/dist/providers/vercel/mcp-ownership.js +212 -0
  198. package/dist/providers/vercel/skill.generated.js +11 -0
  199. package/dist/registry.d.ts +108 -171
  200. package/dist/registry.js +513 -925
  201. package/dist/request-state.js +21 -0
  202. package/dist/resource-read.js +100 -0
  203. package/dist/result-shapes.js +17 -49
  204. package/dist/retired-toolkits.js +1 -1
  205. package/dist/routes/access-tokens.js +3 -6
  206. package/dist/routes/activity-context.js +21 -0
  207. package/dist/routes/activity-disclosure.js +40 -0
  208. package/dist/routes/activity.js +59 -21
  209. package/dist/routes/actor-labels.js +3 -50
  210. package/dist/routes/connect.js +221 -0
  211. package/dist/routes/credentials.js +15 -27
  212. package/dist/routes/mcp.js +356 -130
  213. package/dist/routes/oauth-client-metadata.js +15 -0
  214. package/dist/routes/oauth-management.js +45 -107
  215. package/dist/routes/oauth.js +110 -57
  216. package/dist/routes/operator.js +3 -3
  217. package/dist/routes/shared.d.ts +25 -64
  218. package/dist/routes/shared.js +160 -80
  219. package/dist/routes/skills.js +30 -0
  220. package/dist/routes/ui-config.js +225 -0
  221. package/dist/routes/ui-data.js +40 -35
  222. package/dist/routes/ui.js +66 -56
  223. package/dist/runtime/admission.js +4 -2
  224. package/dist/runtime/call-admission.js +3 -1
  225. package/dist/runtime/connector-scope.js +1 -4
  226. package/dist/runtime/run.js +10 -39
  227. package/dist/runtime/services.js +12 -117
  228. package/dist/runtime/shared-read.js +1 -3
  229. package/dist/runtime/storage.js +8 -1
  230. package/dist/sent-secrets.d.ts +52 -0
  231. package/dist/sent-secrets.js +474 -0
  232. package/dist/server.js +28 -71
  233. package/dist/skills.js +406 -174
  234. package/dist/sqlite.d.ts +48 -0
  235. package/dist/sqlite.js +166 -0
  236. package/dist/storage/keys.js +428 -0
  237. package/dist/storage/memory.js +7 -0
  238. package/dist/storage/sql.d.ts +66 -0
  239. package/dist/storage/sql.js +534 -0
  240. package/dist/timeout.js +4 -2
  241. package/dist/tool-name.js +17 -0
  242. package/dist/tool-safety.d.ts +9 -35
  243. package/dist/tool-safety.js +20 -40
  244. package/dist/types.d.ts +320 -54
  245. package/dist/types.js +0 -1
  246. package/dist/ui.d.ts +7 -19
  247. package/dist/ui.js +76 -90
  248. package/dist/url-safety.js +3 -6
  249. package/dist/usage-guide.js +137 -0
  250. package/dist/validate.d.ts +7 -0
  251. package/dist/validate.js +309 -47
  252. package/dist/version.d.ts +1 -7
  253. package/dist/version.js +3 -7
  254. package/dist/worker.d.ts +11 -0
  255. package/dist/worker.js +434 -0
  256. package/documentation/architecture.md +664 -231
  257. package/documentation/auth.md +936 -546
  258. package/documentation/code-mode.md +501 -312
  259. package/documentation/meta-tools.md +449 -200
  260. package/documentation/operator-tests.md +93 -0
  261. package/documentation/provider-migration-0.29.md +60 -0
  262. package/examples/worker/AGENTS.md +34 -12
  263. package/examples/worker/README.md +286 -255
  264. package/examples/worker/kv-to-d1.wrangler.jsonc +26 -0
  265. package/examples/worker/scripts/copy-kv-to-d1.mjs +162 -0
  266. package/examples/worker/src/connecta.config.ts +151 -0
  267. package/examples/worker/src/index.ts +14 -197
  268. package/examples/worker/wrangler.jsonc +15 -35
  269. package/package.json +120 -54
  270. package/templates/node/.dockerignore +1 -2
  271. package/templates/node/.env.example +20 -21
  272. package/templates/node/AGENTS.md +21 -17
  273. package/templates/node/Dockerfile +3 -5
  274. package/templates/node/README.md +133 -58
  275. package/templates/node/docker-compose.yml +11 -12
  276. package/templates/node/package.json +4 -2
  277. package/templates/node/src/connecta.config.ts +119 -0
  278. package/templates/node/src/index.ts +9 -154
  279. package/templates/node/src/provision-token.ts +17 -0
  280. package/AGENTS.md +0 -170
  281. package/dist/artifacts/connector.d.ts +0 -58
  282. package/dist/artifacts/connector.js +0 -730
  283. package/dist/artifacts/document.js +0 -86
  284. package/dist/artifacts/guide.js +0 -140
  285. package/dist/artifacts/html-scan.js +0 -329
  286. package/dist/artifacts/json.js +0 -78
  287. package/dist/artifacts/kv-store.d.ts +0 -20
  288. package/dist/artifacts/kv-store.js +0 -140
  289. package/dist/artifacts/markdown.js +0 -478
  290. package/dist/artifacts/module.d.ts +0 -37
  291. package/dist/artifacts/module.js +0 -66
  292. package/dist/artifacts/operations.d.ts +0 -197
  293. package/dist/artifacts/operations.js +0 -1002
  294. package/dist/artifacts/refresh.d.ts +0 -55
  295. package/dist/artifacts/refresh.js +0 -236
  296. package/dist/artifacts/routes.js +0 -206
  297. package/dist/artifacts/types.d.ts +0 -214
  298. package/dist/artifacts/types.js +0 -22
  299. package/dist/artifacts/validate.d.ts +0 -62
  300. package/dist/artifacts/validate.js +0 -651
  301. package/dist/artifacts.d.ts +0 -6
  302. package/dist/artifacts.js +0 -9
  303. package/dist/auth/bearer.d.ts +0 -11
  304. package/dist/auth/bearer.js +0 -50
  305. package/dist/providers/basecamp.js +0 -445
  306. package/dist/providers/linear.js +0 -217
  307. package/dist/providers/mixpanel.js +0 -247
  308. package/dist/providers/revenuecat.js +0 -317
  309. package/dist/providers/stripe.js +0 -253
  310. package/dist/providers/vercel.js +0 -1253
  311. package/dist/storage/file.d.ts +0 -15
  312. package/dist/storage/file.js +0 -455
  313. package/ethos.md +0 -93
  314. package/examples/worker/src/cloudflare-kv.ts +0 -43
  315. package/examples/worker/src/d1-activity-row.ts +0 -155
  316. package/examples/worker/src/d1-activity.ts +0 -147
  317. package/examples/worker/src/d1-storage.ts +0 -138
  318. package/examples/worker/src/r2-artifact-blobs.ts +0 -29
  319. package/templates/node/src/file-activity.ts +0 -182
package/dist/server.js CHANGED
@@ -3,10 +3,11 @@ import { notFoundResponse } from "./branding.js";
3
3
  import { aggregateCallAdmissionSnapshots } from "./call-admission.js";
4
4
  import { isAdmittingExecutor } from "./executor-admission.js";
5
5
  import { createMcpRoute, MCP_CORS_HEADERS } from "./routes/mcp.js";
6
- import { routeOAuthCallback, } from "./routes/oauth.js";
6
+ import { routeOAuthCallback } from "./routes/oauth.js";
7
+ import { routeOAuthClientMetadata } from "./routes/oauth-client-metadata.js";
8
+ import { routeConnect } from "./routes/connect.js";
7
9
  import { runEdge } from "./runtime/run.js";
8
- import { withSecurityHeaders, } from "./routes/shared.js";
9
- const isArtifactPath = (path) => path === "/artifacts" || path.startsWith("/artifacts/");
10
+ import { authMetadata, withSecurityHeaders, } from "./routes/shared.js";
10
11
  /**
11
12
  * Build the Web-standard fetch handler.
12
13
  *
@@ -20,47 +21,24 @@ const isArtifactPath = (path) => path === "/artifacts" || path.startsWith("/arti
20
21
  * `close()` has disposed that runtime.
21
22
  */
22
23
  export function createFetchHandler(opts) {
23
- const { auth, publicUrl, registry } = opts;
24
+ const { registry } = opts;
25
+ const { auth, publicUrl } = opts.config;
24
26
  const routeMcp = createMcpRoute(opts);
25
- // The first provider's metadata answer for this request, if any has one.
26
- const metadata = (request, baseUrl) => Effect.gen(function* () {
27
- for (const provider of auth) {
28
- const handleMetadata = provider.handleMetadata?.bind(provider);
29
- if (handleMetadata) {
30
- const response = yield* Effect.promise(async () => handleMetadata(request, baseUrl));
31
- if (response)
32
- return response;
33
- }
34
- }
35
- return null;
36
- });
27
+ const metadata = (request, baseUrl) => Effect.promise(async () => (await authMetadata(request, baseUrl, auth))?.response ?? null);
37
28
  const health = async () => {
38
29
  // The executor is required, so code admission always has a shape to
39
30
  // report: either the executor's own pool or the fallback controller
40
31
  // wrapped around it at construction.
41
- const codeAdmission = isAdmittingExecutor(opts.executor)
42
- ? opts.executor.admissionSnapshot?.()
43
- : undefined;
32
+ const codeAdmission = isAdmittingExecutor(opts.executor) ? opts.executor.admissionSnapshot?.() : undefined;
44
33
  return Response.json({
45
34
  status: "ok",
46
35
  connectors: registry.listConnectors().length,
47
- server: opts.serverInfo,
36
+ server: opts.config.serverInfo,
48
37
  // Which sandbox, not how it is tuned: `connecta doctor` reports the
49
38
  // executor it just exercised rather than assuming one, and a
50
39
  // deployment whose executor identifies as nothing omits the key
51
40
  // instead of inviting a guess (#368).
52
- ...(opts.executorName !== undefined
53
- ? { executor: { name: opts.executorName } }
54
- : {}),
55
- // Counts only, from refreshes that already happened — the endpoint
56
- // asks no downstream anything, and `connecta doctor` reads it to
57
- // report a stale allowlist without a probe of its own (#343).
58
- // Stable 64-bit hashes preserve that shape without publishing ids.
59
- catalogDrift: Object.fromEntries(await Promise.all(Object.entries(registry.catalogDriftSnapshot()).map(async ([id, report]) => {
60
- const hash = new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(id)));
61
- const key = Array.from(hash.subarray(0, 8), byte => byte.toString(16).padStart(2, "0")).join("");
62
- return [key, report];
63
- }))),
41
+ ...(opts.executorName !== undefined ? { executor: { name: opts.executorName } } : {}),
64
42
  admission: {
65
43
  policy: "global-fifo",
66
44
  requests: opts.requestAdmission.snapshot(),
@@ -71,24 +49,32 @@ export function createFetchHandler(opts) {
71
49
  },
72
50
  reservedRoutes: [
73
51
  "/health",
74
- ...(opts.ui?.reservedPaths ?? []),
75
- ...(opts.ui && opts.activity?.list ? ["/activity"] : []),
76
- ...(opts.ui && opts.accessTokens ? ["/tokens"] : []),
77
- ...(opts.ui && opts.artifactsModule ? ["/artifacts", "/artifacts/*"] : []),
52
+ ...(opts.config.ui?.reservedPaths ?? []),
53
+ ...(opts.config.ui && opts.config.activity?.store.list ? ["/activity"] : []),
54
+ ...(opts.config.ui && opts.config.accessTokens ? ["/tokens"] : []),
78
55
  ],
79
56
  },
80
- ...(opts.deploymentInfo ? { deployment: opts.deploymentInfo } : {}),
57
+ ...(opts.config.deploymentInfo ? { deployment: opts.config.deploymentInfo } : {}),
81
58
  });
82
59
  };
83
60
  const route = (context) => Effect.gen(function* () {
84
61
  const { request, path, baseUrl } = context;
62
+ const clientMetadata = routeOAuthClientMetadata(context);
63
+ if (clientMetadata)
64
+ return clientMetadata;
85
65
  // Private mutations own OPTIONS so they never inherit wildcard CORS.
86
- const ui = opts.ui;
66
+ const ui = opts.config.ui;
87
67
  if (ui) {
88
68
  const uiResponse = yield* Effect.promise(() => ui.handle(context));
89
69
  if (uiResponse)
90
70
  return uiResponse;
91
71
  }
72
+ const connect = yield* routeConnect(context);
73
+ if (connect)
74
+ return connect;
75
+ const oauthCallback = yield* routeOAuthCallback(context);
76
+ if (oauthCallback)
77
+ return oauthCallback;
92
78
  if (request.method === "OPTIONS") {
93
79
  const preflight = yield* routeMcp.handle(context);
94
80
  if (preflight)
@@ -105,46 +91,20 @@ export function createFetchHandler(opts) {
105
91
  const response = yield* metadata(request, baseUrl);
106
92
  if (response)
107
93
  return response;
108
- return notFoundResponse(request, opts);
94
+ return notFoundResponse(request, opts.config);
109
95
  }
110
96
  if (path === "/health")
111
97
  return yield* Effect.promise(health);
112
- const oauthCallback = yield* routeOAuthCallback(context);
113
- if (oauthCallback)
114
- return oauthCallback;
115
98
  const mcp = yield* routeMcp.handle(context);
116
99
  if (mcp)
117
100
  return mcp;
118
- return notFoundResponse(request, opts);
101
+ return notFoundResponse(request, opts.config);
119
102
  });
120
103
  const serve = (request, runtimeContext) => Effect.suspend(() => {
121
104
  const url = new URL(request.url);
122
105
  const baseUrl = publicUrl ?? url.origin;
123
106
  const path = url.pathname;
124
- const defer = runtimeContext
125
- ? runtimeContext.waitUntil.bind(runtimeContext)
126
- : undefined;
127
- // The artifact hostname has no MCP, health, OAuth, or operator routes.
128
- // Dispatch before MCP origin checks so even a hostile /mcp gets the same
129
- // 404 as any other unserved path.
130
- if (opts.artifactOrigin && url.origin === new URL(opts.artifactOrigin).origin) {
131
- if (!isArtifactPath(path) || !opts.ui || !opts.artifactsModule) {
132
- return Effect.succeed(withSecurityHeaders(notFoundResponse(request, opts), url, path));
133
- }
134
- const context = {
135
- request, url, path, baseUrl: opts.artifactOrigin, opts, defer, runtimeContext,
136
- };
137
- return Effect.map(Effect.promise(() => opts.ui.handle(context)), response => withSecurityHeaders(response ?? notFoundResponse(request, opts), url, path));
138
- }
139
- if (opts.artifactOrigin && isArtifactPath(path) && opts.ui && opts.artifactsModule) {
140
- const target = new URL(opts.artifactOrigin);
141
- target.pathname = path;
142
- target.search = url.search;
143
- return Effect.succeed(withSecurityHeaders(new Response(null, {
144
- status: 308,
145
- headers: { Location: target.toString() },
146
- }), url, path));
147
- }
107
+ const defer = runtimeContext ? runtimeContext.waitUntil.bind(runtimeContext) : undefined;
148
108
  const originRefusal = routeMcp.rejectOrigin(request);
149
109
  if (originRefusal) {
150
110
  return Effect.succeed(withSecurityHeaders(originRefusal, url, path));
@@ -155,10 +115,7 @@ export function createFetchHandler(opts) {
155
115
  // external DNS, TLS, and the tunnel in front of connecta — so /health is
156
116
  // exempt. It is unauthenticated, returns no user data, and sets no
157
117
  // cookies, so forcing HTTPS on it protects nothing.
158
- if (publicUrl &&
159
- path !== "/health" &&
160
- new URL(publicUrl).protocol === "https:" &&
161
- url.protocol === "http:") {
118
+ if (publicUrl && path !== "/health" && new URL(publicUrl).protocol === "https:" && url.protocol === "http:") {
162
119
  // Assign the path and query onto the configured URL instead of resolving
163
120
  // attacker-controlled text against it. A pathname beginning with `//`
164
121
  // (including a backslash form normalized by URL parsing) is an authority