@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.
- package/AGENTS.md +40 -20
- package/CHANGELOG.md +653 -0
- package/README.md +25 -5
- package/bin/connecta.mjs +44 -3
- package/dist/access-tokens.d.ts +0 -1
- package/dist/access-tokens.js +0 -1
- package/dist/activity.d.ts +50 -2
- package/dist/activity.js +34 -1
- package/dist/apps-shell.d.ts +0 -1
- package/dist/apps-shell.js +0 -1
- package/dist/auth/bearer.d.ts +0 -1
- package/dist/auth/bearer.js +0 -1
- package/dist/auth/clerk.d.ts +0 -1
- package/dist/auth/clerk.js +45 -9
- package/dist/auth/downstream-oauth.d.ts +0 -1
- package/dist/auth/downstream-oauth.js +0 -1
- package/dist/call-admission.d.ts +0 -1
- package/dist/call-admission.js +0 -1
- package/dist/catalog-drift.d.ts +99 -0
- package/dist/catalog-drift.js +251 -0
- package/dist/catalog-fingerprint.d.ts +0 -1
- package/dist/catalog-fingerprint.js +0 -1
- package/dist/catalog-limits.d.ts +0 -1
- package/dist/catalog-limits.js +0 -1
- package/dist/catalog-service.d.ts +0 -1
- package/dist/catalog-service.js +41 -5
- package/dist/catalog.d.ts +11 -1
- package/dist/catalog.js +20 -1
- package/dist/concurrency.d.ts +0 -1
- package/dist/concurrency.js +0 -1
- package/dist/connector-scope.d.ts +0 -1
- package/dist/connector-scope.js +0 -1
- package/dist/connectors/api.d.ts +29 -21
- package/dist/connectors/api.js +45 -19
- package/dist/connectors/guarded-fetch.d.ts +106 -0
- package/dist/connectors/guarded-fetch.js +289 -0
- package/dist/connectors/remote-mcp.d.ts +0 -1
- package/dist/connectors/remote-mcp.js +0 -1
- package/dist/credentials.d.ts +0 -1
- package/dist/credentials.js +0 -1
- package/dist/errors.d.ts +30 -3
- package/dist/errors.js +1 -1
- package/dist/execute.d.ts +0 -1
- package/dist/execute.js +0 -1
- package/dist/executor-admission.d.ts +11 -1
- package/dist/executor-admission.js +28 -1
- package/dist/executor-result.d.ts +0 -1
- package/dist/executor-result.js +0 -1
- package/dist/executors/quickjs-child.d.ts +0 -1
- package/dist/executors/quickjs-child.js +0 -1
- package/dist/executors/quickjs-protocol.d.ts +0 -1
- package/dist/executors/quickjs-protocol.js +0 -1
- package/dist/executors/quickjs-runtime.d.ts +0 -1
- package/dist/executors/quickjs-runtime.js +0 -1
- package/dist/executors/quickjs.d.ts +0 -1
- package/dist/executors/quickjs.js +2 -1
- package/dist/favicon.d.ts +0 -1
- package/dist/favicon.js +0 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +24 -7
- package/dist/invocation.d.ts +0 -1
- package/dist/invocation.js +0 -1
- package/dist/json-schema.d.ts +0 -1
- package/dist/json-schema.js +0 -1
- package/dist/mcp-result.d.ts +0 -1
- package/dist/mcp-result.js +0 -1
- package/dist/meta-tools.d.ts +0 -1
- package/dist/meta-tools.js +0 -1
- package/dist/node.d.ts +0 -1
- package/dist/node.js +0 -1
- package/dist/operator-ui/generated.d.ts +2 -3
- package/dist/operator-ui/generated.js +3 -4
- package/dist/operator-ui/model.d.ts +10 -1
- package/dist/operator-ui/model.js +0 -1
- package/dist/operator-ui/view.d.ts +167 -0
- package/dist/operator-ui/view.js +270 -0
- package/dist/providers/cloudflare.d.ts +0 -1
- package/dist/providers/cloudflare.js +261 -299
- package/dist/providers/linear.d.ts +26 -5
- package/dist/providers/linear.js +32 -61
- package/dist/providers/mixpanel.d.ts +35 -4
- package/dist/providers/mixpanel.js +53 -79
- package/dist/providers/notion.d.ts +0 -1
- package/dist/providers/notion.js +87 -42
- package/dist/providers/stripe.d.ts +13 -1
- package/dist/providers/stripe.js +31 -60
- package/dist/registry.d.ts +34 -2
- package/dist/registry.js +85 -5
- package/dist/retired-toolkits.d.ts +0 -1
- package/dist/retired-toolkits.js +0 -1
- package/dist/routes/access-tokens.d.ts +0 -1
- package/dist/routes/access-tokens.js +0 -1
- package/dist/routes/activity.d.ts +0 -1
- package/dist/routes/activity.js +0 -1
- package/dist/routes/credentials.d.ts +0 -1
- package/dist/routes/credentials.js +0 -1
- package/dist/routes/mcp.d.ts +0 -1
- package/dist/routes/mcp.js +0 -1
- package/dist/routes/oauth.d.ts +0 -1
- package/dist/routes/oauth.js +0 -1
- package/dist/routes/shared.d.ts +2 -1
- package/dist/routes/shared.js +0 -1
- package/dist/routes/ui.d.ts +0 -1
- package/dist/routes/ui.js +0 -1
- package/dist/server.d.ts +0 -1
- package/dist/server.js +11 -1
- package/dist/skills.d.ts +0 -1
- package/dist/skills.js +0 -1
- package/dist/storage/file.d.ts +0 -1
- package/dist/storage/file.js +0 -1
- package/dist/storage/memory.d.ts +0 -1
- package/dist/storage/memory.js +0 -1
- package/dist/timeout.d.ts +0 -1
- package/dist/timeout.js +0 -1
- package/dist/tool-safety.d.ts +0 -1
- package/dist/tool-safety.js +0 -1
- package/dist/types.d.ts +45 -1
- package/dist/types.js +0 -1
- package/dist/ui.d.ts +0 -1
- package/dist/ui.js +13 -137
- package/dist/validate.d.ts +13 -15
- package/dist/validate.js +24 -11
- package/dist/version.d.ts +1 -2
- package/dist/version.js +1 -2
- package/documentation/architecture.md +186 -5
- package/documentation/auth.md +11 -0
- package/documentation/call-admission.md +142 -6
- package/documentation/cloudflare.md +92 -10
- package/documentation/code-first-exploration.md +2 -2
- package/documentation/code-mode.md +14 -14
- package/documentation/connector-guides.md +172 -5
- package/documentation/connectors.md +89 -0
- package/documentation/linear.md +20 -2
- package/documentation/mcp-ui-design.md +2 -2
- package/documentation/meta-tools.md +7 -1
- package/documentation/mixpanel.md +42 -9
- package/documentation/notion.md +23 -2
- package/documentation/operations.md +325 -5
- package/documentation/operator-ui.md +120 -5
- package/documentation/provider-audit.md +160 -0
- package/documentation/provider-conventions.md +667 -0
- package/documentation/request-admission.md +167 -5
- package/documentation/rich-output-design.md +1 -2
- package/documentation/stripe.md +15 -0
- package/documentation/upgrading.md +454 -0
- package/ethos.md +14 -9
- package/examples/worker/README.md +102 -12
- package/examples/worker/src/index.ts +46 -1
- package/examples/worker/wrangler.jsonc +14 -1
- package/package.json +10 -6
- package/templates/node/.dockerignore +10 -0
- package/templates/node/.env.example +40 -3
- package/templates/node/AGENTS.md +16 -1
- package/templates/node/Dockerfile +49 -0
- package/templates/node/README.md +117 -2
- package/templates/node/docker-compose.yml +39 -0
- package/templates/node/package.json +1 -1
- package/templates/node/src/file-activity.ts +182 -0
- package/templates/node/src/index.ts +80 -4
- package/assets/connecta-clay-hero.png +0 -0
- package/dist/access-tokens.d.ts.map +0 -1
- package/dist/access-tokens.js.map +0 -1
- package/dist/activity.d.ts.map +0 -1
- package/dist/activity.js.map +0 -1
- package/dist/apps-shell.d.ts.map +0 -1
- package/dist/apps-shell.js.map +0 -1
- package/dist/auth/bearer.d.ts.map +0 -1
- package/dist/auth/bearer.js.map +0 -1
- package/dist/auth/clerk.d.ts.map +0 -1
- package/dist/auth/clerk.js.map +0 -1
- package/dist/auth/downstream-oauth.d.ts.map +0 -1
- package/dist/auth/downstream-oauth.js.map +0 -1
- package/dist/call-admission.d.ts.map +0 -1
- package/dist/call-admission.js.map +0 -1
- package/dist/catalog-fingerprint.d.ts.map +0 -1
- package/dist/catalog-fingerprint.js.map +0 -1
- package/dist/catalog-limits.d.ts.map +0 -1
- package/dist/catalog-limits.js.map +0 -1
- package/dist/catalog-service.d.ts.map +0 -1
- package/dist/catalog-service.js.map +0 -1
- package/dist/catalog.d.ts.map +0 -1
- package/dist/catalog.js.map +0 -1
- package/dist/concurrency.d.ts.map +0 -1
- package/dist/concurrency.js.map +0 -1
- package/dist/connector-scope.d.ts.map +0 -1
- package/dist/connector-scope.js.map +0 -1
- package/dist/connectors/api.d.ts.map +0 -1
- package/dist/connectors/api.js.map +0 -1
- package/dist/connectors/remote-mcp.d.ts.map +0 -1
- package/dist/connectors/remote-mcp.js.map +0 -1
- package/dist/credentials.d.ts.map +0 -1
- package/dist/credentials.js.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/execute.d.ts.map +0 -1
- package/dist/execute.js.map +0 -1
- package/dist/executor-admission.d.ts.map +0 -1
- package/dist/executor-admission.js.map +0 -1
- package/dist/executor-result.d.ts.map +0 -1
- package/dist/executor-result.js.map +0 -1
- package/dist/executors/quickjs-child.d.ts.map +0 -1
- package/dist/executors/quickjs-child.js.map +0 -1
- package/dist/executors/quickjs-protocol.d.ts.map +0 -1
- package/dist/executors/quickjs-protocol.js.map +0 -1
- package/dist/executors/quickjs-runtime.d.ts.map +0 -1
- package/dist/executors/quickjs-runtime.js.map +0 -1
- package/dist/executors/quickjs.d.ts.map +0 -1
- package/dist/executors/quickjs.js.map +0 -1
- package/dist/favicon.d.ts.map +0 -1
- package/dist/favicon.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/invocation.d.ts.map +0 -1
- package/dist/invocation.js.map +0 -1
- package/dist/json-schema.d.ts.map +0 -1
- package/dist/json-schema.js.map +0 -1
- package/dist/mcp-result.d.ts.map +0 -1
- package/dist/mcp-result.js.map +0 -1
- package/dist/meta-tools.d.ts.map +0 -1
- package/dist/meta-tools.js.map +0 -1
- package/dist/node.d.ts.map +0 -1
- package/dist/node.js.map +0 -1
- package/dist/operator-ui/generated.d.ts.map +0 -1
- package/dist/operator-ui/generated.js.map +0 -1
- package/dist/operator-ui/model.d.ts.map +0 -1
- package/dist/operator-ui/model.js.map +0 -1
- package/dist/providers/cloudflare.d.ts.map +0 -1
- package/dist/providers/cloudflare.js.map +0 -1
- package/dist/providers/linear.d.ts.map +0 -1
- package/dist/providers/linear.js.map +0 -1
- package/dist/providers/mixpanel.d.ts.map +0 -1
- package/dist/providers/mixpanel.js.map +0 -1
- package/dist/providers/notion.d.ts.map +0 -1
- package/dist/providers/notion.js.map +0 -1
- package/dist/providers/stripe.d.ts.map +0 -1
- package/dist/providers/stripe.js.map +0 -1
- package/dist/registry.d.ts.map +0 -1
- package/dist/registry.js.map +0 -1
- package/dist/retired-toolkits.d.ts.map +0 -1
- package/dist/retired-toolkits.js.map +0 -1
- package/dist/routes/access-tokens.d.ts.map +0 -1
- package/dist/routes/access-tokens.js.map +0 -1
- package/dist/routes/activity.d.ts.map +0 -1
- package/dist/routes/activity.js.map +0 -1
- package/dist/routes/credentials.d.ts.map +0 -1
- package/dist/routes/credentials.js.map +0 -1
- package/dist/routes/mcp.d.ts.map +0 -1
- package/dist/routes/mcp.js.map +0 -1
- package/dist/routes/oauth.d.ts.map +0 -1
- package/dist/routes/oauth.js.map +0 -1
- package/dist/routes/shared.d.ts.map +0 -1
- package/dist/routes/shared.js.map +0 -1
- package/dist/routes/ui.d.ts.map +0 -1
- package/dist/routes/ui.js.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/skills.d.ts.map +0 -1
- package/dist/skills.js.map +0 -1
- package/dist/storage/file.d.ts.map +0 -1
- package/dist/storage/file.js.map +0 -1
- package/dist/storage/memory.d.ts.map +0 -1
- package/dist/storage/memory.js.map +0 -1
- package/dist/timeout.d.ts.map +0 -1
- package/dist/timeout.js.map +0 -1
- package/dist/tool-safety.d.ts.map +0 -1
- package/dist/tool-safety.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/ui.d.ts.map +0 -1
- package/dist/ui.js.map +0 -1
- package/dist/validate.d.ts.map +0 -1
- package/dist/validate.js.map +0 -1
- package/dist/version.d.ts.map +0 -1
- package/dist/version.js.map +0 -1
- package/examples/node/README.md +0 -52
- package/examples/node/src/index.ts +0 -71
- package/src/access-tokens.ts +0 -289
- package/src/activity.ts +0 -234
- package/src/apps-shell.ts +0 -370
- package/src/auth/bearer.ts +0 -61
- package/src/auth/clerk.ts +0 -553
- package/src/auth/downstream-oauth.ts +0 -575
- package/src/call-admission.ts +0 -521
- package/src/catalog-fingerprint.ts +0 -52
- package/src/catalog-limits.ts +0 -11
- package/src/catalog-service.ts +0 -1153
- package/src/catalog.ts +0 -790
- package/src/concurrency.ts +0 -39
- package/src/connector-scope.ts +0 -66
- package/src/connectors/api.ts +0 -159
- package/src/connectors/remote-mcp.ts +0 -1090
- package/src/credentials.ts +0 -428
- package/src/errors.ts +0 -364
- package/src/execute.ts +0 -1406
- package/src/executor-admission.ts +0 -328
- package/src/executor-result.ts +0 -107
- package/src/executors/quickjs-child.ts +0 -172
- package/src/executors/quickjs-protocol.ts +0 -99
- package/src/executors/quickjs-runtime.ts +0 -470
- package/src/executors/quickjs.ts +0 -776
- package/src/favicon.ts +0 -53
- package/src/index.ts +0 -666
- package/src/invocation.ts +0 -655
- package/src/json-schema.ts +0 -11
- package/src/mcp-result.ts +0 -43
- package/src/meta-tools.ts +0 -1607
- package/src/node.ts +0 -206
- package/src/operator-ui/browser.css +0 -423
- package/src/operator-ui/browser.ts +0 -1281
- package/src/operator-ui/generated.ts +0 -4
- package/src/operator-ui/model.ts +0 -111
- package/src/providers/cloudflare.ts +0 -3999
- package/src/providers/linear.ts +0 -302
- package/src/providers/mixpanel.ts +0 -229
- package/src/providers/notion.ts +0 -1879
- package/src/providers/stripe.ts +0 -307
- package/src/registry.ts +0 -1085
- package/src/retired-toolkits.ts +0 -14
- package/src/routes/access-tokens.ts +0 -115
- package/src/routes/activity.ts +0 -215
- package/src/routes/credentials.ts +0 -254
- package/src/routes/mcp.ts +0 -429
- package/src/routes/oauth.ts +0 -322
- package/src/routes/shared.ts +0 -247
- package/src/routes/ui.ts +0 -152
- package/src/server.ts +0 -195
- package/src/skills.ts +0 -271
- package/src/storage/file.ts +0 -123
- package/src/storage/memory.ts +0 -44
- package/src/timeout.ts +0 -84
- package/src/tool-safety.ts +0 -15
- package/src/types.ts +0 -523
- package/src/ui.ts +0 -744
- package/src/validate.ts +0 -387
- package/src/version.ts +0 -7
package/dist/ui.js
CHANGED
|
@@ -369,6 +369,11 @@ export async function buildUiData(registry, baseUrl, serverInfo, credentialVault
|
|
|
369
369
|
: {}),
|
|
370
370
|
toolCount: tools.length,
|
|
371
371
|
tools,
|
|
372
|
+
// Counts only, and only when a refresh in this runtime produced them.
|
|
373
|
+
// `Registry.statusFor` already rebuilt the report through
|
|
374
|
+
// `boundedCatalogDrift`, so what lands here cannot carry a name or a
|
|
375
|
+
// schema even if the plugin seam returned one.
|
|
376
|
+
...(status.catalogDrift ? { catalogDrift: status.catalogDrift } : {}),
|
|
372
377
|
...(c.disconnectAuth && c.startAuth ? { oauth: true } : {}),
|
|
373
378
|
...(credential ? { credential } : {}),
|
|
374
379
|
};
|
|
@@ -477,147 +482,18 @@ ${clerkScript}
|
|
|
477
482
|
${owner}
|
|
478
483
|
<div class="mast-nav">
|
|
479
484
|
${product}
|
|
480
|
-
<div id="
|
|
481
|
-
<nav class="page-nav" aria-label="Operator pages">
|
|
482
|
-
<a id="connectionsNav" class="navlink" href="/"
|
|
483
|
-
data-operator-page="connections"${page === "connections" ? ' aria-current="page"' : ""}>Connections</a>
|
|
484
|
-
<a id="credentialsNav" class="navlink hidden" href="/credentials"
|
|
485
|
-
data-operator-page="credentials"${page === "credentials" ? ' aria-current="page"' : ""}>Credentials</a>
|
|
486
|
-
<a id="tokensNav" class="navlink hidden" href="/tokens"
|
|
487
|
-
data-operator-page="tokens"${page === "tokens" ? ' aria-current="page"' : ""}>Access tokens</a>
|
|
488
|
-
<a id="activityNav" class="navlink hidden" href="/activity"
|
|
489
|
-
data-operator-page="activity"${page === "activity" ? ' aria-current="page"' : ""}>Activity</a>
|
|
490
|
-
</nav>
|
|
491
|
-
<div class="session-actions" aria-label="Session actions">
|
|
492
|
-
<button id="change" class="navlink hidden" type="button">Change token</button>
|
|
493
|
-
<button id="signout" class="navlink hidden" type="button">Sign out</button>
|
|
494
|
-
</div>
|
|
495
|
-
</div>
|
|
485
|
+
<div id="operatorNav"></div>
|
|
496
486
|
</div>
|
|
497
487
|
</header>
|
|
498
488
|
|
|
499
489
|
<main id="operatorContent" class="page shell" tabindex="-1">
|
|
500
|
-
<
|
|
501
|
-
<
|
|
502
|
-
|
|
503
|
-
<
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
<div id="tokenGate" class="row gate-actions hidden">
|
|
507
|
-
<input id="token" type="password" placeholder="Bearer token" autocomplete="off"
|
|
508
|
-
aria-label="Bearer token">
|
|
509
|
-
<button id="save" class="linklike" type="button">Open operator pages</button>
|
|
510
|
-
</div>
|
|
511
|
-
<div id="clerkGate" class="actions gate-actions hidden">
|
|
512
|
-
<button id="signin" class="linklike" type="button">Team sign in</button>
|
|
513
|
-
<button id="gateSignout" class="linklike hidden" type="button">Sign out</button>
|
|
514
|
-
</div>
|
|
515
|
-
<p id="err" role="alert"></p>
|
|
516
|
-
</div>
|
|
517
|
-
</div>
|
|
518
|
-
</section>
|
|
519
|
-
|
|
520
|
-
<div id="app" class="hidden">
|
|
521
|
-
<section id="connectionsView"${page === "connections" ? "" : ' class="hidden"'}>
|
|
522
|
-
<div class="lead pgrid">
|
|
523
|
-
<h1 id="connectionsHeading" class="pcap" tabindex="-1">Connections</h1>
|
|
524
|
-
<div class="pbody lead-copy">
|
|
525
|
-
<p>Use this endpoint to give an MCP client access to the tools below.</p>
|
|
526
|
-
<div class="endpoint">
|
|
527
|
-
<div class="endpoint-row">
|
|
528
|
-
<code id="mcpUrl" class="mono"></code>
|
|
529
|
-
<button id="copyMcpUrl" class="linklike" type="button">Copy URL</button>
|
|
530
|
-
</div>
|
|
531
|
-
</div>
|
|
532
|
-
<p class="cap" id="serverInfo">${escapeHtmlAttr(brand.productName)} operator</p>
|
|
533
|
-
<p id="oauthNotice" class="meta" role="status" aria-live="polite" tabindex="-1"></p>
|
|
534
|
-
</div>
|
|
535
|
-
</div>
|
|
536
|
-
<section class="section pgrid" aria-labelledby="connectorLedgerHeading">
|
|
537
|
-
<h2 class="pcap" id="connectorLedgerHeading">Connectors</h2>
|
|
538
|
-
<div class="pbody">
|
|
539
|
-
<div class="row toolbar">
|
|
540
|
-
<input id="filter" type="search" placeholder="Filter connectors or tools…"
|
|
541
|
-
aria-label="Filter connectors or tools">
|
|
542
|
-
</div>
|
|
543
|
-
<div id="list" class="connector-tools" aria-busy="false"></div>
|
|
544
|
-
</div>
|
|
545
|
-
</section>
|
|
546
|
-
</section>
|
|
547
|
-
|
|
548
|
-
<section id="credentialsView"${page === "credentials" ? "" : ' class="hidden"'}>
|
|
549
|
-
<div class="lead pgrid">
|
|
550
|
-
<h1 id="credentialsHeading" class="pcap" tabindex="-1">Credentials</h1>
|
|
551
|
-
<div class="pbody">
|
|
552
|
-
<p class="activity-copy">Rotate operator-managed connector credentials. Stored values are never returned or displayed.</p>
|
|
553
|
-
<p id="credentialNotice" class="meta" role="status" aria-live="polite"
|
|
554
|
-
tabindex="-1"></p>
|
|
555
|
-
<div id="credentialUnavailable" class="unavailable hidden"></div>
|
|
556
|
-
<div id="credentialList" class="credential-ledger" aria-busy="false"></div>
|
|
557
|
-
</div>
|
|
558
|
-
</div>
|
|
559
|
-
</section>
|
|
560
|
-
|
|
561
|
-
<section id="tokensView"${page === "tokens" ? "" : ' class="hidden"'}>
|
|
562
|
-
<div class="lead pgrid">
|
|
563
|
-
<h1 id="tokensHeading" class="pcap" tabindex="-1">Access tokens</h1>
|
|
564
|
-
<div class="pbody">
|
|
565
|
-
<p class="activity-copy">Create named Bearer tokens for MCP clients. Each secret is shown once; revoke it when that client should lose access.</p>
|
|
566
|
-
<p id="tokenNotice" class="meta" role="status" aria-live="polite"
|
|
567
|
-
tabindex="-1"></p>
|
|
568
|
-
<div id="tokenUnavailable" class="unavailable hidden"></div>
|
|
569
|
-
<div id="tokenAvailable" class="hidden">
|
|
570
|
-
<form id="tokenCreateForm" class="token-create">
|
|
571
|
-
<label for="tokenName">Client name</label>
|
|
572
|
-
<div class="row">
|
|
573
|
-
<input id="tokenName" type="text" maxlength="80"
|
|
574
|
-
placeholder="Claude desktop, ChatGPT production…"
|
|
575
|
-
autocomplete="off">
|
|
576
|
-
<button id="createToken" class="linklike" type="submit">Create token</button>
|
|
577
|
-
</div>
|
|
578
|
-
</form>
|
|
579
|
-
<section id="tokenReveal" class="token-reveal hidden"
|
|
580
|
-
aria-labelledby="tokenRevealHeading">
|
|
581
|
-
<div class="token-reveal-head">
|
|
582
|
-
<h2 id="tokenRevealHeading" tabindex="-1">Copy this token now</h2>
|
|
583
|
-
<span class="cap">Shown once</span>
|
|
584
|
-
</div>
|
|
585
|
-
<p class="meta">Store it in the MCP client before leaving this page. It cannot be displayed again.</p>
|
|
586
|
-
<div class="endpoint-row token-secret">
|
|
587
|
-
<code id="createdToken" class="mono"></code>
|
|
588
|
-
<button id="copyCreatedToken" class="linklike" type="button">Copy token</button>
|
|
589
|
-
</div>
|
|
590
|
-
<button id="dismissCreatedToken" class="linklike" type="button">I stored it</button>
|
|
591
|
-
</section>
|
|
592
|
-
<div id="tokenList" class="token-ledger" aria-busy="false"></div>
|
|
593
|
-
</div>
|
|
594
|
-
</div>
|
|
595
|
-
</div>
|
|
596
|
-
</section>
|
|
597
|
-
|
|
598
|
-
<section id="activityView"${page === "activity" ? "" : ' class="hidden"'}>
|
|
599
|
-
<div class="lead pgrid">
|
|
600
|
-
<h1 id="activityHeading" class="pcap" tabindex="-1">Activity</h1>
|
|
601
|
-
<div class="pbody">
|
|
602
|
-
<p class="activity-copy" id="activitySummary">Arguments and results are never stored.</p>
|
|
603
|
-
<div id="activityUnavailable" class="unavailable hidden">
|
|
604
|
-
Activity history is not configured. Add an <span class="mono">activity.store</span>
|
|
605
|
-
with a list reader to enable this page.
|
|
606
|
-
</div>
|
|
607
|
-
<div id="activityAvailable">
|
|
608
|
-
<div class="row activity-controls">
|
|
609
|
-
<input id="activitySearch" type="search"
|
|
610
|
-
placeholder="Search user, tool, or outcome…"
|
|
611
|
-
aria-label="Search loaded activity">
|
|
612
|
-
<button id="refreshActivity" class="linklike" type="button">Refresh</button>
|
|
613
|
-
</div>
|
|
614
|
-
<p id="activityNotice" class="meta" role="status" aria-live="polite"></p>
|
|
615
|
-
<div id="activityList" class="activity-ledger" aria-busy="false"></div>
|
|
616
|
-
<button id="moreActivity" class="linklike activity-more hidden" type="button">Load older</button>
|
|
617
|
-
</div>
|
|
618
|
-
</div>
|
|
490
|
+
<div class="lead pgrid">
|
|
491
|
+
<h1 class="pcap">${OPERATOR_PAGE_LABELS[page]}</h1>
|
|
492
|
+
<div class="pbody lead-copy">
|
|
493
|
+
<p>${escapeHtmlAttr(brand.description)}</p>
|
|
494
|
+
<noscript><p class="msg">The operator pages need JavaScript. Nothing else here
|
|
495
|
+
does — agents reach this deployment through <span class="mono">/mcp</span>.</p></noscript>
|
|
619
496
|
</div>
|
|
620
|
-
</section>
|
|
621
497
|
</div>
|
|
622
498
|
</main>
|
|
623
499
|
|
|
@@ -627,9 +503,9 @@ const MCP_URL = ${jsonForInlineScript(mcpUrl)};
|
|
|
627
503
|
const INITIAL_PAGE = ${jsonForInlineScript(page)};
|
|
628
504
|
const TITLE_SUFFIX = ${jsonForInlineScript(brand.pageTitle)};
|
|
629
505
|
const PRODUCT_NAME = ${stringForInlineScript(brand.productName)};
|
|
506
|
+
const PRODUCT_DESCRIPTION = ${stringForInlineScript(brand.description)};
|
|
630
507
|
const PRODUCT_OPERATOR_LABEL = ${stringForInlineScript(brand.productName + " operator")};
|
|
631
508
|
${OPERATOR_UI_SCRIPT}</script>
|
|
632
509
|
</body>
|
|
633
510
|
</html>`;
|
|
634
511
|
}
|
|
635
|
-
//# sourceMappingURL=ui.js.map
|
package/dist/validate.d.ts
CHANGED
|
@@ -21,17 +21,12 @@ export interface ValidateToolInputOptions {
|
|
|
21
21
|
*/
|
|
22
22
|
failClosed?: boolean;
|
|
23
23
|
}
|
|
24
|
-
export interface
|
|
24
|
+
export interface CompileValidatorOptions {
|
|
25
25
|
/**
|
|
26
|
-
* Tool address used in the
|
|
26
|
+
* Tool address used in the error text, conventionally
|
|
27
27
|
* `"connectorId.toolName"`.
|
|
28
28
|
*/
|
|
29
29
|
address: string;
|
|
30
|
-
/**
|
|
31
|
-
* Destination for the warning emitted when the schema cannot be compiled.
|
|
32
|
-
* Default console.
|
|
33
|
-
*/
|
|
34
|
-
logger?: Logger;
|
|
35
30
|
}
|
|
36
31
|
/**
|
|
37
32
|
* Validate call arguments against a tool's JSON Schema.
|
|
@@ -60,12 +55,15 @@ export interface PrecompileValidatorOptions {
|
|
|
60
55
|
*/
|
|
61
56
|
export declare function validateToolInput(schema: JsonSchema, args: unknown, opts: ValidateToolInputOptions): ConnectorCallError | null;
|
|
62
57
|
/**
|
|
63
|
-
* Eagerly compile and cache a tool's inputSchema
|
|
64
|
-
* cannot use
|
|
65
|
-
* the
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
58
|
+
* Eagerly compile and cache a tool's inputSchema, throwing when the validator
|
|
59
|
+
* cannot use it. Reuses the same module-level cache `validateToolInput` reads,
|
|
60
|
+
* so the runtime path hits the cache.
|
|
61
|
+
*
|
|
62
|
+
* This is the construction-time half of the contract hand-written tools sign:
|
|
63
|
+
* a schema connecta cannot enforce is the author's bug, and a deployment that
|
|
64
|
+
* boots with one is a deployment quietly promising validation it will not do.
|
|
65
|
+
* A schema that only fails on first `validate()` (an unresolvable `$ref`, say)
|
|
66
|
+
* still slips through here — the validator resolves those lazily — and is
|
|
67
|
+
* caught at call time by the caller's `failClosed`.
|
|
69
68
|
*/
|
|
70
|
-
export declare function
|
|
71
|
-
//# sourceMappingURL=validate.d.ts.map
|
|
69
|
+
export declare function compileValidator(schema: JsonSchema, opts: CompileValidatorOptions): void;
|
package/dist/validate.js
CHANGED
|
@@ -186,6 +186,11 @@ function validationDetails(schema, units) {
|
|
|
186
186
|
function unevaluableSchema(address) {
|
|
187
187
|
return new ConnectorCallError("invalid_args", `Cannot validate arguments for "${address}": its inputSchema could not be evaluated`);
|
|
188
188
|
}
|
|
189
|
+
function unusableSchema(address, detail) {
|
|
190
|
+
return new Error(`Tool "${address}" has an inputSchema the validator cannot use ` +
|
|
191
|
+
`(${detail}) — fix the schema or drop it; a schema that cannot be ` +
|
|
192
|
+
"enforced must not ship as one that can.");
|
|
193
|
+
}
|
|
189
194
|
function disableValidation(schema, address, logger, err) {
|
|
190
195
|
validators.set(schema, null);
|
|
191
196
|
logger.warn(`[connecta] tool "${address}" has an inputSchema the validator cannot use (${err instanceof Error ? err.message : String(err)}) — arguments are not validated`);
|
|
@@ -254,22 +259,30 @@ export function validateToolInput(schema, args, opts) {
|
|
|
254
259
|
return null;
|
|
255
260
|
}
|
|
256
261
|
/**
|
|
257
|
-
* Eagerly compile and cache a tool's inputSchema
|
|
258
|
-
* cannot use
|
|
259
|
-
* the
|
|
260
|
-
*
|
|
261
|
-
*
|
|
262
|
-
*
|
|
262
|
+
* Eagerly compile and cache a tool's inputSchema, throwing when the validator
|
|
263
|
+
* cannot use it. Reuses the same module-level cache `validateToolInput` reads,
|
|
264
|
+
* so the runtime path hits the cache.
|
|
265
|
+
*
|
|
266
|
+
* This is the construction-time half of the contract hand-written tools sign:
|
|
267
|
+
* a schema connecta cannot enforce is the author's bug, and a deployment that
|
|
268
|
+
* boots with one is a deployment quietly promising validation it will not do.
|
|
269
|
+
* A schema that only fails on first `validate()` (an unresolvable `$ref`, say)
|
|
270
|
+
* still slips through here — the validator resolves those lazily — and is
|
|
271
|
+
* caught at call time by the caller's `failClosed`.
|
|
263
272
|
*/
|
|
264
|
-
export function
|
|
265
|
-
|
|
273
|
+
export function compileValidator(schema, opts) {
|
|
274
|
+
const cached = validators.get(schema);
|
|
275
|
+
if (cached)
|
|
266
276
|
return;
|
|
267
|
-
|
|
277
|
+
// null marks a schema an earlier call already found unusable; recompiling it
|
|
278
|
+
// into a working validator would be the fail-open behavior wearing a hat.
|
|
279
|
+
if (cached === null) {
|
|
280
|
+
throw unusableSchema(opts.address, "an earlier call could not evaluate it");
|
|
281
|
+
}
|
|
268
282
|
try {
|
|
269
283
|
validators.set(schema, new Validator(schema, "2020-12", false));
|
|
270
284
|
}
|
|
271
285
|
catch (err) {
|
|
272
|
-
|
|
286
|
+
throw unusableSchema(opts.address, err instanceof Error ? err.message : String(err));
|
|
273
287
|
}
|
|
274
288
|
}
|
|
275
|
-
//# sourceMappingURL=validate.js.map
|
package/dist/version.d.ts
CHANGED
|
@@ -4,5 +4,4 @@
|
|
|
4
4
|
* a bump that forgets this file fails the build rather than shipping a stale
|
|
5
5
|
* version to `/health` and to downstream MCP handshakes.
|
|
6
6
|
*/
|
|
7
|
-
export declare const CONNECTA_VERSION = "0.
|
|
8
|
-
//# sourceMappingURL=version.d.ts.map
|
|
7
|
+
export declare const CONNECTA_VERSION = "0.16.1";
|
package/dist/version.js
CHANGED
|
@@ -1,7 +1,188 @@
|
|
|
1
1
|
# Architecture
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
One Web-standard `fetch(request) => Promise<Response>` handler, a long-lived
|
|
4
|
+
registry behind it, and a strict rule about what may be imported. Everything
|
|
5
|
+
else in this repository is a detail of those three things.
|
|
6
|
+
|
|
7
|
+
Read [`ethos.md`](../ethos.md) first. This guide says how the shape it
|
|
8
|
+
describes is actually assembled, and where a change is likely to break it.
|
|
9
|
+
|
|
10
|
+
## The two lifetimes
|
|
11
|
+
|
|
12
|
+
Almost every bug in this codebase is a lifetime mistake, so the split is worth
|
|
13
|
+
stating before anything else.
|
|
14
|
+
|
|
15
|
+
**Per isolate, built once.** `createConnecta(config)` returns
|
|
16
|
+
`{ fetch, registry, close }`. The `Registry` owns the connector set, address
|
|
17
|
+
resolution, catalog caches, connector health, and the per-connector call
|
|
18
|
+
limiters. It is constructed once and lives as long as the isolate or process —
|
|
19
|
+
on Workers that means a lazy module-scope singleton, which is why both
|
|
20
|
+
deployment shapes build it outside the request handler.
|
|
21
|
+
|
|
22
|
+
**Per request, and no longer.** The MCP server, its transport, downstream MCP
|
|
23
|
+
clients, abort signals, and the connector scope a probe opens all belong to the
|
|
24
|
+
request that created them. `Nothing request-bound survives a request` is an
|
|
25
|
+
ethos invariant, not a style preference: a client retained across requests on
|
|
26
|
+
Workers is a cross-request capability leak, and a promise awaited after the
|
|
27
|
+
response is work the runtime may have already torn down. Deferred work has one
|
|
28
|
+
sanctioned channel — `ctx.waitUntil`, threaded through `fetch(request, env,
|
|
29
|
+
ctx)` and used for best-effort activity writes.
|
|
30
|
+
|
|
31
|
+
The registry is deliberately on the long side of that line and the MCP server
|
|
32
|
+
deliberately on the short side. A fresh `McpServer` per request is what makes
|
|
33
|
+
the deployment stateless: no sessions, no server push, no resumability, and
|
|
34
|
+
scope resolved from the request rather than remembered.
|
|
35
|
+
|
|
36
|
+
## Request lifecycle
|
|
37
|
+
|
|
38
|
+
`src/server.ts` is the composition root. It does three things in order: upgrade
|
|
39
|
+
the scheme when it must, run the route table, then wrap whatever came back in
|
|
40
|
+
security headers. Route *order* is the contract — several routes would behave
|
|
41
|
+
differently if they were reachable in another order — so the table below is
|
|
42
|
+
read top to bottom.
|
|
43
|
+
|
|
44
|
+
| Order | Route | Notes |
|
|
45
|
+
| --- | --- | --- |
|
|
46
|
+
| 0 | HTTPS upgrade | 308 to `publicUrl` when it is HTTPS and the request arrived over HTTP. Path and query are *assigned* onto the configured URL, never resolved against it, so a `//host` pathname cannot replace the deployment origin. `/health` is exempt: a loopback container probe must not depend on public DNS and TLS. `/ui` is canonicalized to `/` while upgrading. |
|
|
47
|
+
| 1 | `/ui/access-tokens[/<id>]`, `/ui/credentials/<id>[/<action>]`, `/ui/oauth/<id>` | Private mutation routes, matched **first** so nothing can shadow them and so they own their own `OPTIONS` — they answer it with a refusal rather than inheriting the wildcard CORS preflight. |
|
|
48
|
+
| 2 | `OPTIONS` | Each auth provider's `handleMetadata` gets a chance (CORS preflight for browser MCP clients); otherwise 204 with MCP CORS. |
|
|
49
|
+
| 3 | `/.well-known/*` | Auth providers' `handleMetadata`, open. 404 when none handles it. |
|
|
50
|
+
| 4 | `/health` | Open JSON: status, connector count, `serverInfo`, the configured executor's sanitized name when it has one, catalog-drift counts, admission snapshots, reserved route names, and `deployment` when `deploymentInfo` is set. Payload-free by construction, and it never joins the MCP queue. |
|
|
51
|
+
| 5 | `/oauth/callback/<connectorId>` | Downstream-OAuth completion, open, `verifyState` before `finishAuth`. |
|
|
52
|
+
| 6 | `/favicon.*`, `/ui` → `/`, the operator shells, `/ui/data` | The operator surface ([operator UI](./operator-ui.md)). The shells are open and data-free; `/ui/data` behind them is gated. Built-ins are matched before connector routes, so a connector cannot shadow a page. |
|
|
53
|
+
| 7 | `/ui/activity` | Gated, plus the optional `activity.readGate`. `GET` only; 404 with no `activity.store.list`. |
|
|
54
|
+
| 8 | `/mcp` | **Admission before auth**, then the auth gate, then a fresh MCP server. |
|
|
55
|
+
| 9 | connector `handleRequest` | Registration order, open. Dispatched only after every built-in misses, so a connector can *add* a route and never shadow one of connecta's. First non-null response wins; a throw is a 500, not a fall-through. |
|
|
56
|
+
| 10 | — | 404. |
|
|
57
|
+
|
|
58
|
+
Every response leaves through `withSecurityHeaders`: `nosniff`, a no-referrer
|
|
59
|
+
policy, HSTS on HTTPS, and — on the operator shells — a nonce-based script CSP
|
|
60
|
+
and framing denial. `test/server-route-contracts.test.ts` pins this ordering
|
|
61
|
+
and the exact refusal bodies; it exists because the ordering is invisible in
|
|
62
|
+
any one file and a reordering reads like a harmless refactor.
|
|
63
|
+
|
|
64
|
+
`/mcp` itself is four steps, in this order and for these reasons:
|
|
65
|
+
|
|
66
|
+
1. **Admit.** One permit from the deployment-wide FIFO pool, taken before auth
|
|
67
|
+
so an unauthenticated flood costs a permit rather than a Clerk lookup
|
|
68
|
+
([request admission](./request-admission.md)). The permit is held until the
|
|
69
|
+
response *body* completes, not until the handler returns.
|
|
70
|
+
2. **Authorize.** Each `InboundAuth` provider's `authorize` in order, bearer
|
|
71
|
+
before Clerk. First `ok` admits; if all fail, the last provider's challenge
|
|
72
|
+
response is returned. No providers configured means open — development
|
|
73
|
+
only, and it warns at construction.
|
|
74
|
+
3. **Refuse `?toolkit=`.** Toolkits were removed ([#178](https://github.com/zackbart/connecta/issues/178))
|
|
75
|
+
but the URLs naming them were handed out, so the parameter is a 404 rather
|
|
76
|
+
than silently serving the full registry. Retiring a scoping boundary into
|
|
77
|
+
fail-open is the one outcome worse than the 404.
|
|
78
|
+
4. **Serve.** A fresh `McpServer` per request, the seven meta-tools registered
|
|
79
|
+
against the registry, the Apps shell resource registered (and
|
|
80
|
+
`resources/list` deliberately answering with nothing), and the response
|
|
81
|
+
handed back.
|
|
82
|
+
|
|
83
|
+
## Layers below the meta-tools
|
|
84
|
+
|
|
85
|
+
The meta-tool handlers are thin. The work sits in four services the registry
|
|
86
|
+
owns or hands out, and a change usually belongs in exactly one of them:
|
|
87
|
+
|
|
88
|
+
| Module | Owns |
|
|
89
|
+
| --- | --- |
|
|
90
|
+
| `src/registry.ts` | The connector set, id validation, address resolution, connector health, per-connector call limiters, and the drift snapshot. Construction-time refusal of structural mistakes lives here. |
|
|
91
|
+
| `src/catalog-service.ts` | Tool listing: cold-load coalescing, TTL, persistence as manifest plus revision-addressed chunks, stale fallback, and the completeness rule — a partial catalog is a failure, never a cache write. |
|
|
92
|
+
| `src/invocation.ts` | One tool call: argument validation, call admission, per-attempt timeout, retry with the connector's own `Retry-After` honoured exactly or declined, result unwrapping, size capping, and the activity record. |
|
|
93
|
+
| `src/catalog.ts` | Ranking, description summarizing, and the compact schema renderer discovery shows. |
|
|
94
|
+
|
|
95
|
+
`src/meta-tools.ts` and `src/execute.ts` are two front doors onto the same
|
|
96
|
+
three services. That is the point: a program's `connecta.call` and a top-level
|
|
97
|
+
`call_tool` reach `InvocationService.invoke` by different routes and get the
|
|
98
|
+
same admission, the same credential resolution, and the same fail-closed
|
|
99
|
+
read-only check. `test/execute.test.ts` asserts that parity directly, because
|
|
100
|
+
the alternative — a sandbox path that quietly diverges — is how generated code
|
|
101
|
+
would mint a capability.
|
|
102
|
+
|
|
103
|
+
## Import-graph purity
|
|
104
|
+
|
|
105
|
+
Nothing reachable from `src/index.ts` may import a `node:` builtin. The core is
|
|
106
|
+
Web-API only so the same code runs unchanged in workerd and in Node.
|
|
107
|
+
|
|
108
|
+
The Node-touching paths are `src/node.ts` (the `node:http` adapter),
|
|
109
|
+
`src/storage/file.ts`, and the QuickJS process pool
|
|
110
|
+
(`src/executors/quickjs.ts` and its child entry). Each lives behind an explicit
|
|
111
|
+
subpath export — `@zackbart/connecta/node`, `@zackbart/connecta/quickjs` — and
|
|
112
|
+
must stay unreachable from the root entry. The optional Clerk adapter is behind
|
|
113
|
+
`./auth/clerk` for the adjacent reason: `@clerk/backend` is an optional peer,
|
|
114
|
+
not a dependency.
|
|
115
|
+
|
|
116
|
+
`test/purity.test.ts` walks the relative-import graph from `src/index.ts` and
|
|
117
|
+
fails on (a) any `node:` specifier in a reachable file and (b) the Node
|
|
118
|
+
adapter, file storage, QuickJS parent or child, or the Clerk adapter being
|
|
119
|
+
reachable at all. `test/package-surface.test.ts` and
|
|
120
|
+
`scripts/check-package.mjs` guard the other half — that the published tarball
|
|
121
|
+
matches the same boundary.
|
|
122
|
+
|
|
123
|
+
The failure mode this prevents is not theoretical: a single convenience import
|
|
124
|
+
of `node:crypto` in a shared helper makes the whole Worker deployment shape
|
|
125
|
+
stop building, and it will do so in someone else's repository rather than
|
|
126
|
+
this one.
|
|
127
|
+
|
|
128
|
+
## Where things live
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
src/
|
|
132
|
+
index.ts createConnecta + the public re-exports (Workers-clean)
|
|
133
|
+
server.ts route ordering, HTTPS upgrade, security wrapper
|
|
134
|
+
routes/ one file per surface; shared.ts holds the auth gate
|
|
135
|
+
meta-tools.ts the six non-execute meta-tools over the registry
|
|
136
|
+
execute.ts execute_code, the sandbox host bridge, emit and ui
|
|
137
|
+
apps-shell.ts the one build-time MCP Apps template
|
|
138
|
+
skills.ts MCP instructions, the usage skill, connector guides
|
|
139
|
+
registry.ts connector set, addresses, health, call limiters
|
|
140
|
+
catalog-service.ts catalog loading, caching, persistence, stale fallback
|
|
141
|
+
catalog.ts ranking, summaries, compact schema rendering
|
|
142
|
+
invocation.ts one tool call, end to end
|
|
143
|
+
catalog-drift.ts vetted manifests and the counts a refresh produces
|
|
144
|
+
credentials.ts the AES-GCM connector vault over KVStorage
|
|
145
|
+
access-tokens.ts operator-issued MCP bearer tokens
|
|
146
|
+
activity.ts payload-free event contracts + best-effort recorder
|
|
147
|
+
call-admission.ts connector-partitioned downstream permits and budgets
|
|
148
|
+
executor-admission.ts the portable bounded queue both pools use
|
|
149
|
+
ui.ts the served operator shell and /ui/data payload
|
|
150
|
+
operator-ui/ the Preact app, its pure rules, and the built bundle
|
|
151
|
+
connectors/ remote-mcp.ts, api.ts, guarded-fetch.ts
|
|
152
|
+
providers/ the maintained prebuilt connections
|
|
153
|
+
auth/ bearer, clerk (optional peer), downstream OAuth
|
|
154
|
+
executors/ the QuickJS pool and child (Node only)
|
|
155
|
+
storage/ memory.ts, file.ts (Node only)
|
|
156
|
+
node.ts listen() + fileStorage re-export (Node only)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Sharp edges
|
|
160
|
+
|
|
161
|
+
- **The registry is shared; the request is not.** Anything you cache on the
|
|
162
|
+
registry is visible to every later request in that isolate. Anything you
|
|
163
|
+
cache per request dies with it. Putting a downstream client on the wrong side
|
|
164
|
+
of that line is the highest-severity mistake available here.
|
|
165
|
+
- **Route order is behavior.** Moving a built-in below the connector dispatch
|
|
166
|
+
hands a connector the ability to shadow it. Moving a mutation route below the
|
|
167
|
+
wildcard `OPTIONS` opts it into CORS preflight.
|
|
168
|
+
- **Admission runs before auth, on purpose.** Reordering them to "authenticate
|
|
169
|
+
first" makes the cheapest possible attack the most expensive request.
|
|
170
|
+
- **`close()` is idempotent and ordered.** It closes both admission pools and
|
|
171
|
+
the connector limiters, then the executor. Node's `listen()` calls it on
|
|
172
|
+
SIGTERM/SIGINT.
|
|
173
|
+
- **Structural mistakes throw at construction.** A duplicate connector id, an
|
|
174
|
+
invalid admission rule, `accessTokens` without a Clerk provider, a missing
|
|
175
|
+
executor: all refuse to boot. A deployment that starts in the wrong shape is
|
|
176
|
+
worse than one that does not start.
|
|
177
|
+
|
|
178
|
+
## Tests that enforce this
|
|
179
|
+
|
|
180
|
+
| Invariant | Suite |
|
|
181
|
+
| --- | --- |
|
|
182
|
+
| The core imports no `node:` builtin and reaches no Node-only module | `test/purity.test.ts` |
|
|
183
|
+
| The published surface matches the same boundary | `test/package-surface.test.ts`, `scripts/check-package.mjs` |
|
|
184
|
+
| Route order, per-route auth, and byte-exact refusals | `test/server-route-contracts.test.ts` |
|
|
185
|
+
| `/mcp` end to end, the open routes, exactly seven tools | `test/server.test.ts`, `test/code-first-surface.test.ts` |
|
|
186
|
+
| Construction-time refusals and the grouped config boundary | `test/config.test.ts`, `test/registry.test.ts` |
|
|
187
|
+
| Program and top-level calls take the same enforced path | `test/execute.test.ts` |
|
|
188
|
+
| Both deployment shapes still compile and configure the real thing | `test/deployment-shapes.test.ts`, `npm run check:examples` |
|
package/documentation/auth.md
CHANGED
|
@@ -4,6 +4,17 @@ Inbound auth decides who may reach the MCP endpoint. A deployment may admit a
|
|
|
4
4
|
static bearer, operator-issued access tokens, Clerk identities, or a mixture.
|
|
5
5
|
Static bearers are checked first.
|
|
6
6
|
|
|
7
|
+
## Clerk configuration is checked at construction
|
|
8
|
+
|
|
9
|
+
`clerkAuth` reads its Frontend API origin out of `publishableKey`, so a key that
|
|
10
|
+
is not `pk_test_`/`pk_live_` followed by the base64-encoded domain cannot
|
|
11
|
+
produce one. That throws where `allowedDomains` throws — when `clerkAuth` is
|
|
12
|
+
called — with a message naming the option, never quoting the rejected value
|
|
13
|
+
back: the usual way to land here is pasting the *secret* key into the
|
|
14
|
+
publishable slot, and a startup error is a log line. A deployment that builds
|
|
15
|
+
per request, as the Workers shape does, sees the same error on its first
|
|
16
|
+
request instead of a base64 stack on every route.
|
|
17
|
+
|
|
7
18
|
## Operator-issued access tokens
|
|
8
19
|
|
|
9
20
|
Set `accessTokens: {}` to let eligible Clerk operators create named Bearer
|