@jskit-ai/connectors-catalog 0.1.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/README.md +192 -0
- package/docs/ai-upstream-notices.md +51 -0
- package/docs/ai.md +191 -0
- package/docs/airtable.md +130 -0
- package/docs/algolia.md +190 -0
- package/docs/amazon-redshift.md +229 -0
- package/docs/amplitude.md +210 -0
- package/docs/apify.md +162 -0
- package/docs/apollo-io.md +200 -0
- package/docs/asana.md +126 -0
- package/docs/ashby.md +188 -0
- package/docs/atlassian.md +224 -0
- package/docs/attention.md +162 -0
- package/docs/aws-athena.md +150 -0
- package/docs/aws-credentials.md +75 -0
- package/docs/aws-s3.md +193 -0
- package/docs/bigquery.md +146 -0
- package/docs/brevo.md +122 -0
- package/docs/calendly.md +158 -0
- package/docs/canva.md +191 -0
- package/docs/chargebee.md +192 -0
- package/docs/clay.md +194 -0
- package/docs/clickhouse.md +242 -0
- package/docs/confidence-exp.md +74 -0
- package/docs/confidence-flags.md +75 -0
- package/docs/confidence-oauth.md +137 -0
- package/docs/contentful.md +123 -0
- package/docs/databricks.md +180 -0
- package/docs/dbt-semantic-layer.md +175 -0
- package/docs/elevenlabs.md +102 -0
- package/docs/figma.md +132 -0
- package/docs/firebase-cloud-messaging.md +262 -0
- package/docs/firecrawl.md +137 -0
- package/docs/fireflies.md +95 -0
- package/docs/fireworks-ai.md +53 -0
- package/docs/gatewayapi.md +113 -0
- package/docs/gemini-enterprise.md +224 -0
- package/docs/github-api.md +133 -0
- package/docs/gitlab-api.md +138 -0
- package/docs/gmail.md +133 -0
- package/docs/gong.md +205 -0
- package/docs/google-ads.md +156 -0
- package/docs/google-analytics.md +202 -0
- package/docs/google-docs.md +105 -0
- package/docs/google-drive.md +108 -0
- package/docs/google-maps-platform.md +208 -0
- package/docs/google-oauth.md +123 -0
- package/docs/google-search-console.md +124 -0
- package/docs/google-sheets.md +94 -0
- package/docs/google-slides.md +95 -0
- package/docs/granola.md +178 -0
- package/docs/hex.md +161 -0
- package/docs/heygen.md +124 -0
- package/docs/hubspot.md +142 -0
- package/docs/incident-io.md +118 -0
- package/docs/inngest.md +178 -0
- package/docs/klipy.md +149 -0
- package/docs/lexware.md +144 -0
- package/docs/lightspeed.md +193 -0
- package/docs/linear.md +137 -0
- package/docs/linkedin.md +196 -0
- package/docs/logo-dev.md +152 -0
- package/docs/mailgun.md +153 -0
- package/docs/mapbox.md +174 -0
- package/docs/microsoft-excel.md +97 -0
- package/docs/microsoft-fabric.md +249 -0
- package/docs/microsoft-oauth.md +143 -0
- package/docs/microsoft-onedrive.md +76 -0
- package/docs/microsoft-onenote.md +75 -0
- package/docs/microsoft-outlook.md +90 -0
- package/docs/microsoft-powerpoint.md +119 -0
- package/docs/microsoft-sharepoint.md +75 -0
- package/docs/microsoft-teams.md +72 -0
- package/docs/microsoft-word.md +119 -0
- package/docs/miro.md +117 -0
- package/docs/n8n.md +169 -0
- package/docs/notion.md +137 -0
- package/docs/oura.md +161 -0
- package/docs/paddle.md +168 -0
- package/docs/perplexity.md +85 -0
- package/docs/pipedrive.md +120 -0
- package/docs/polar.md +63 -0
- package/docs/posthog.md +227 -0
- package/docs/prestashop.md +151 -0
- package/docs/replicate.md +60 -0
- package/docs/resend.md +153 -0
- package/docs/salesforce.md +234 -0
- package/docs/sanity.md +122 -0
- package/docs/semrush.md +276 -0
- package/docs/sentry.md +112 -0
- package/docs/sevdesk.md +107 -0
- package/docs/shopify.md +206 -0
- package/docs/slack.md +257 -0
- package/docs/snowflake.md +271 -0
- package/docs/storyblok.md +130 -0
- package/docs/stripe.md +77 -0
- package/docs/supabase.md +51 -0
- package/docs/tally.md +105 -0
- package/docs/telegram.md +165 -0
- package/docs/tiktok.md +201 -0
- package/docs/twilio.md +284 -0
- package/docs/twitch.md +428 -0
- package/docs/wave.md +440 -0
- package/docs/wix.md +1249 -0
- package/docs/wiz.md +177 -0
- package/docs/woocommerce.md +400 -0
- package/docs/wordpress-com.md +358 -0
- package/docs/wordpress-self-hosted.md +252 -0
- package/docs/workday.md +292 -0
- package/docs/x-twitter.md +188 -0
- package/docs/xero.md +429 -0
- package/docs/zoho-books.md +214 -0
- package/docs/zoho-crm.md +192 -0
- package/package.json +153 -0
- package/patterns/ai-connections/PATTERN.md +84 -0
- package/patterns/ai-connections/example/ai-model.js +11 -0
- package/patterns/ai-connections/example/perplexity-answer.js +29 -0
- package/patterns/api-key-connection/PATTERN.md +368 -0
- package/patterns/api-key-connection/example/connections.js +18 -0
- package/patterns/api-key-connection/example/integrations.json +19 -0
- package/patterns/assistant-mcp/PATTERN.md +110 -0
- package/patterns/assistant-mcp/example/integrations.json +13 -0
- package/patterns/assistant-mcp-oauth/PATTERN.md +235 -0
- package/patterns/assistant-mcp-oauth/example/integrations.json +102 -0
- package/patterns/aws-storage-queries/PATTERN.md +169 -0
- package/patterns/aws-storage-queries/example/formats/data-formats.js +35 -0
- package/patterns/aws-storage-queries/example/formats/package-lock.json +49 -0
- package/patterns/aws-storage-queries/example/formats/package.json +12 -0
- package/patterns/aws-storage-queries/example/formats/verify-formats.mjs +37 -0
- package/patterns/aws-storage-queries/example/integrations.json +38 -0
- package/patterns/aws-storage-queries/example/s3-transfer.js +34 -0
- package/patterns/event-delivery/PATTERN.md +151 -0
- package/patterns/event-delivery/example/integrations.json +17 -0
- package/patterns/firebase-messaging/PATTERN.md +156 -0
- package/patterns/firebase-messaging/example/server/notifications.js +23 -0
- package/patterns/google-ads-search/PATTERN.md +92 -0
- package/patterns/google-ads-search/example/ads-setup.js +25 -0
- package/patterns/oauth-connection/PATTERN.md +724 -0
- package/patterns/oauth-connection/example/integrations.json +20 -0
- package/patterns/paddle-catalogue/PATTERN.md +78 -0
- package/patterns/paddle-catalogue/example/create-products.js +38 -0
- package/patterns/public-image/PATTERN.md +84 -0
- package/patterns/public-image/example/integrations.json +13 -0
- package/patterns/public-image/example/logo-url.js +16 -0
- package/patterns/redshift-queries/PATTERN.md +150 -0
- package/patterns/redshift-queries/example/integrations.json +33 -0
- package/patterns/source-scanning/PATTERN.md +83 -0
- package/patterns/source-scanning/example/source-scanner.js +13 -0
- package/src/client/firebase-cloud-messaging.js +10 -0
- package/src/client/google-analytics.js +72 -0
- package/src/client/google-maps-platform.js +39 -0
- package/src/client/logo-dev.js +36 -0
- package/src/server/ai.js +46 -0
- package/src/server/airtable.js +67 -0
- package/src/server/algolia.js +63 -0
- package/src/server/amazon-redshift.js +96 -0
- package/src/server/amplitude.js +31 -0
- package/src/server/apify.js +68 -0
- package/src/server/apollo-io.js +85 -0
- package/src/server/asana.js +64 -0
- package/src/server/ashby.js +61 -0
- package/src/server/atlassian.js +32 -0
- package/src/server/attention.js +93 -0
- package/src/server/aws-athena.js +82 -0
- package/src/server/aws-s3.js +49 -0
- package/src/server/awsTransport.js +75 -0
- package/src/server/bigquery.js +97 -0
- package/src/server/brevo.js +97 -0
- package/src/server/calendly.js +77 -0
- package/src/server/canva.js +13 -0
- package/src/server/chargebee.js +88 -0
- package/src/server/clay.js +78 -0
- package/src/server/clickhouse.js +66 -0
- package/src/server/confidence.js +29 -0
- package/src/server/contentful.js +40 -0
- package/src/server/databricks.js +55 -0
- package/src/server/dbt-semantic-layer.js +95 -0
- package/src/server/elevenlabs.js +81 -0
- package/src/server/figma.js +24 -0
- package/src/server/firebase-cloud-messaging.js +111 -0
- package/src/server/firecrawl.js +70 -0
- package/src/server/fireflies.js +31 -0
- package/src/server/fireworks-ai.js +16 -0
- package/src/server/gatewayapi.js +48 -0
- package/src/server/gemini-enterprise.js +47 -0
- package/src/server/github-api.js +90 -0
- package/src/server/gitlab-api.js +67 -0
- package/src/server/gmail.js +60 -0
- package/src/server/gong.js +52 -0
- package/src/server/google-ads-search.js +134 -0
- package/src/server/google-ads.js +80 -0
- package/src/server/google-docs.js +36 -0
- package/src/server/google-drive.js +71 -0
- package/src/server/google-maps-platform.js +90 -0
- package/src/server/google-search-console.js +31 -0
- package/src/server/google-sheets.js +60 -0
- package/src/server/google-slides.js +36 -0
- package/src/server/google.js +61 -0
- package/src/server/granola.js +115 -0
- package/src/server/graphqlOperation.js +15 -0
- package/src/server/hex.js +29 -0
- package/src/server/heygen.js +54 -0
- package/src/server/hubspot.js +85 -0
- package/src/server/incident-io.js +68 -0
- package/src/server/inngest.js +86 -0
- package/src/server/jsonOperation.js +34 -0
- package/src/server/klipy.js +34 -0
- package/src/server/lexware.js +59 -0
- package/src/server/lightspeed.js +82 -0
- package/src/server/linear.js +52 -0
- package/src/server/linkedin.js +74 -0
- package/src/server/mailgun.js +76 -0
- package/src/server/mapbox.js +46 -0
- package/src/server/mcpRegistration.js +41 -0
- package/src/server/mcpTransport.js +60 -0
- package/src/server/microsoft-excel.js +67 -0
- package/src/server/microsoft-fabric.js +81 -0
- package/src/server/microsoft-onedrive.js +58 -0
- package/src/server/microsoft-onenote.js +52 -0
- package/src/server/microsoft-outlook.js +58 -0
- package/src/server/microsoft-powerpoint.js +5 -0
- package/src/server/microsoft-sharepoint.js +46 -0
- package/src/server/microsoft-teams.js +29 -0
- package/src/server/microsoft-word.js +5 -0
- package/src/server/microsoft.js +88 -0
- package/src/server/miro.js +29 -0
- package/src/server/n8n.js +78 -0
- package/src/server/notion.js +76 -0
- package/src/server/oura.js +48 -0
- package/src/server/paddle.js +83 -0
- package/src/server/perplexity.js +15 -0
- package/src/server/pipedrive.js +95 -0
- package/src/server/polar.js +20 -0
- package/src/server/posthog.js +44 -0
- package/src/server/prestashop.js +42 -0
- package/src/server/replicate.js +42 -0
- package/src/server/resend.js +93 -0
- package/src/server/salesforce.js +84 -0
- package/src/server/sanity.js +31 -0
- package/src/server/semrush.js +359 -0
- package/src/server/sentry.js +30 -0
- package/src/server/sevdesk.js +20 -0
- package/src/server/shopify.js +99 -0
- package/src/server/slack.js +143 -0
- package/src/server/snowflake.js +139 -0
- package/src/server/storyblok.js +49 -0
- package/src/server/stripe.js +13 -0
- package/src/server/supabase.js +13 -0
- package/src/server/tally.js +78 -0
- package/src/server/telegram.js +55 -0
- package/src/server/tiktok.js +86 -0
- package/src/server/twilio.js +90 -0
- package/src/server/twitch.js +409 -0
- package/src/server/wave.js +520 -0
- package/src/server/wix.js +1048 -0
- package/src/server/wiz.js +117 -0
- package/src/server/woocommerce.js +412 -0
- package/src/server/wordpress-com.js +236 -0
- package/src/server/wordpress-self-hosted.js +134 -0
- package/src/server/workday.js +136 -0
- package/src/server/x-twitter.js +110 -0
- package/src/server/xero.js +397 -0
- package/src/server/zoho-books.js +90 -0
- package/src/server/zoho-crm.js +89 -0
- package/src/server/zohoOAuth.js +21 -0
- package/src/shared/ai-models.json +8049 -0
- package/src/shared/ai.js +63 -0
- package/src/shared/algolia.js +29 -0
- package/src/shared/amazon-redshift.js +51 -0
- package/src/shared/amplitude.js +28 -0
- package/src/shared/atlassian.js +43 -0
- package/src/shared/aws.js +72 -0
- package/src/shared/canva.js +66 -0
- package/src/shared/chargebee.js +26 -0
- package/src/shared/clickhouse.js +38 -0
- package/src/shared/confidence.js +28 -0
- package/src/shared/databricks.js +33 -0
- package/src/shared/dbt-semantic-layer.js +32 -0
- package/src/shared/definitions.js +140 -0
- package/src/shared/figma.js +21 -0
- package/src/shared/firebase-cloud-messaging.js +45 -0
- package/src/shared/gemini-enterprise.js +33 -0
- package/src/shared/gong.js +33 -0
- package/src/shared/google-ads-search.js +31 -0
- package/src/shared/google-ads.js +28 -0
- package/src/shared/google-maps-platform.js +28 -0
- package/src/shared/google.js +133 -0
- package/src/shared/granola.js +25 -0
- package/src/shared/hex.js +28 -0
- package/src/shared/inngest.js +35 -0
- package/src/shared/lightspeed.js +75 -0
- package/src/shared/linkedin.js +27 -0
- package/src/shared/logo-dev.js +21 -0
- package/src/shared/mapbox.js +38 -0
- package/src/shared/mcp.js +92 -0
- package/src/shared/microsoft-fabric.js +47 -0
- package/src/shared/microsoft.js +231 -0
- package/src/shared/miro.js +27 -0
- package/src/shared/oura.js +23 -0
- package/src/shared/posthog.js +33 -0
- package/src/shared/prestashop.js +23 -0
- package/src/shared/salesforce.js +36 -0
- package/src/shared/semrush.js +24 -0
- package/src/shared/shopify.js +51 -0
- package/src/shared/siteUrl.js +12 -0
- package/src/shared/slack.js +88 -0
- package/src/shared/snowflake.js +55 -0
- package/src/shared/tiktok.js +22 -0
- package/src/shared/tokens.js +747 -0
- package/src/shared/twilio.js +41 -0
- package/src/shared/twitch.js +49 -0
- package/src/shared/wave.js +52 -0
- package/src/shared/wix.js +40 -0
- package/src/shared/wiz.js +41 -0
- package/src/shared/wordpress-com.js +30 -0
- package/src/shared/wordpress.js +69 -0
- package/src/shared/workday.js +50 -0
- package/src/shared/x-twitter.js +19 -0
- package/src/shared/xero.js +46 -0
- package/src/shared/zoho-books.js +39 -0
- package/src/shared/zoho-crm.js +43 -0
- package/src/shared/zoho-regions.js +12 -0
- package/test/ai.test.js +136 -0
- package/test/airtable.test.js +125 -0
- package/test/algolia.test.js +207 -0
- package/test/amazon-redshift.test.js +272 -0
- package/test/amplitude.test.js +239 -0
- package/test/apify.test.js +93 -0
- package/test/apollo-io.test.js +125 -0
- package/test/asana.test.js +99 -0
- package/test/ashby.test.js +97 -0
- package/test/atlassian.test.js +249 -0
- package/test/attention.test.js +79 -0
- package/test/aws.test.js +405 -0
- package/test/brevo.test.js +71 -0
- package/test/calendly.test.js +136 -0
- package/test/canva.test.js +258 -0
- package/test/chargebee.test.js +195 -0
- package/test/clickhouse.test.js +278 -0
- package/test/confidence.test.js +205 -0
- package/test/databricks.test.js +253 -0
- package/test/dbt-semantic-layer.test.js +221 -0
- package/test/designMcp.test.js +336 -0
- package/test/elevenlabs.test.js +52 -0
- package/test/firebase-cloud-messaging.test.js +242 -0
- package/test/firecrawl.test.js +66 -0
- package/test/gemini-enterprise.test.js +218 -0
- package/test/github-api.test.js +167 -0
- package/test/gitlab-api.test.js +160 -0
- package/test/gong.test.js +192 -0
- package/test/google-ads.test.js +350 -0
- package/test/google-maps-platform.test.js +191 -0
- package/test/google.test.js +710 -0
- package/test/granola.test.js +240 -0
- package/test/hex.test.js +253 -0
- package/test/heygen.test.js +121 -0
- package/test/hubspot.test.js +103 -0
- package/test/inngest.test.js +219 -0
- package/test/lightspeed.test.js +250 -0
- package/test/linear.test.js +146 -0
- package/test/linkedin.test.js +243 -0
- package/test/logo-dev.test.js +79 -0
- package/test/mailgun.test.js +107 -0
- package/test/mapbox.test.js +181 -0
- package/test/mcp.test.js +227 -0
- package/test/microsoft-fabric.test.js +258 -0
- package/test/microsoft.test.js +554 -0
- package/test/n8nOAuth.test.js +188 -0
- package/test/notionOAuth.test.js +183 -0
- package/test/oura.test.js +211 -0
- package/test/paddleCatalogue.test.js +51 -0
- package/test/paddlePermissions.test.js +101 -0
- package/test/perplexityComposition.test.js +39 -0
- package/test/pipedriveOAuth.test.js +140 -0
- package/test/posthog.test.js +200 -0
- package/test/prestashop.test.js +207 -0
- package/test/resend.test.js +163 -0
- package/test/salesforce.test.js +276 -0
- package/test/semrush.test.js +479 -0
- package/test/sentry.test.js +35 -0
- package/test/shopify.test.js +247 -0
- package/test/slack.test.js +320 -0
- package/test/snowflake.test.js +391 -0
- package/test/tally.test.js +75 -0
- package/test/telegram.test.js +58 -0
- package/test/tiktok.test.js +243 -0
- package/test/tokens.test.js +1079 -0
- package/test/twilio.test.js +221 -0
- package/test/twitch.test.js +573 -0
- package/test/wave.test.js +678 -0
- package/test/wix.test.js +1099 -0
- package/test/wiz.test.js +185 -0
- package/test/wordpress-com.test.js +469 -0
- package/test/wordpress.test.js +660 -0
- package/test/workday.test.js +314 -0
- package/test/x-twitter.test.js +256 -0
- package/test/xero.test.js +700 -0
- package/test/zoho-books.test.js +253 -0
- package/test/zoho-crm.test.js +223 -0
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: connectors/api-key-connection
|
|
3
|
+
title: API-key connections with portable JSON configuration
|
|
4
|
+
summary: Compose provider operations, authorization and encrypted file storage from a CLI or application server.
|
|
5
|
+
keywords: connectors, integrations, api-key, resend, firecrawl, clay, prestashop, clickhouse, semrush, granola, dbt, semantic-layer, metrics, x-twitter, cli, files
|
|
6
|
+
requires: @jskit-ai/connectors-core, @jskit-ai/connectors-catalog
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# API-key connections with portable JSON configuration
|
|
10
|
+
|
|
11
|
+
## Use when
|
|
12
|
+
|
|
13
|
+
Use for an API-key provider in the connector catalogue, owned by an application
|
|
14
|
+
or explicitly authorized assistant. Resend and Firecrawl illustrate the wiring
|
|
15
|
+
below; select other providers through their individual exports and setup guides.
|
|
16
|
+
The runtime is imported library code. Configuration and
|
|
17
|
+
connection state can both use text files; no database or app generator is
|
|
18
|
+
required.
|
|
19
|
+
|
|
20
|
+
## Do not use when
|
|
21
|
+
|
|
22
|
+
Do not apply a single shared API key to individual users while claiming they
|
|
23
|
+
have connected separate provider accounts. Do not use a local operator's
|
|
24
|
+
identity policy in a web API. Provider account/subscription provisioning is an
|
|
25
|
+
application-owner task, not something this pattern automatically activates. Logo.dev public
|
|
26
|
+
images use the separate public-image pattern, without server verification.
|
|
27
|
+
|
|
28
|
+
## Product decisions
|
|
29
|
+
|
|
30
|
+
Choose the named integration slots, private environment, durable runtime
|
|
31
|
+
location and authenticated authorization policy. The runtime directory belongs
|
|
32
|
+
outside exported application source. Keep its encryption key stable across
|
|
33
|
+
restarts and backups. A key rotation changes the environment binding; it does
|
|
34
|
+
not require putting credentials into source.
|
|
35
|
+
|
|
36
|
+
## Invariants
|
|
37
|
+
|
|
38
|
+
- CLI and editor read and edit the same `integrations.json`.
|
|
39
|
+
- Configuration contains references, never raw API keys.
|
|
40
|
+
- Runtime connection state uses encrypted JSON outside source when using the file store.
|
|
41
|
+
- Access is checked before credential resolution and every operation.
|
|
42
|
+
- A successful provider read precedes Connected; saving fields does not.
|
|
43
|
+
- ClickHouse accepts a database username and optional password reference. Only
|
|
44
|
+
omit that reference when an empty password is intended. For no Authorization
|
|
45
|
+
header, use `authentication: { method: "none" }`, omit `settings.username`,
|
|
46
|
+
and call `connectWithoutCredentials`; authorization and file storage still
|
|
47
|
+
apply. A missing explicit binding is always an error. Use the fixed
|
|
48
|
+
`tables.list`, `columns.list` and `rows.list` operations with typed parameters;
|
|
49
|
+
never interpolate SQL or assume verification grants access to every table.
|
|
50
|
+
See the [ClickHouse guide](https://github.com/mobily-enterprises/jskit-ai/blob/main/packages/connectors-catalog/docs/clickhouse.md) for settings constraints,
|
|
51
|
+
administrator setup, pagination and the absence of an OAuth callback.
|
|
52
|
+
- Provider settings use the provider's shared schema. Save the normalized
|
|
53
|
+
configuration returned by validation so CLI and UI defaults agree.
|
|
54
|
+
- Changing a setting such as region or environment requires verification again.
|
|
55
|
+
- Providers such as Algolia also require an application ID. Use their settings
|
|
56
|
+
schema and guide; never infer the request host from user operation input.
|
|
57
|
+
- Twilio requires an Account SID and regional API Key SID in settings; its
|
|
58
|
+
primary secret reference resolves the API key secret. Do not substitute an
|
|
59
|
+
account Auth Token or construct credentials from the Account SID.
|
|
60
|
+
- PostHog uses a public project token in a JSON body. Its `connectApiKey` call
|
|
61
|
+
needs `verificationInput: { distinct_id: "your-explicit-subject" }` to evaluate
|
|
62
|
+
flags; never invent a subject or send an event just to verify configuration.
|
|
63
|
+
The token cannot read private analytics or establish a login. Its guide
|
|
64
|
+
explains HTTP-200 quota failures and event acceptance versus ingestion.
|
|
65
|
+
- Chargebee requires a site name without `.chargebee.com` and a key that can
|
|
66
|
+
read transactional data. Test/live sites have different keys; a second key
|
|
67
|
+
on one site does not create separate rate-limit capacity.
|
|
68
|
+
- Ashby job reads use POST and can fail inside an HTTP-200 reply. Keep cursor
|
|
69
|
+
and incremental-sync checkpoints in application-owned state for the specific
|
|
70
|
+
connection; the adapter does not reset or advance them automatically.
|
|
71
|
+
- Lexware's Public API key remains private. Sevdesk uses its token directly
|
|
72
|
+
in Authorization and includes people with `depth: 1` by default. Import the
|
|
73
|
+
respective provider; do not infer authentication or pagination from form labels.
|
|
74
|
+
- Apollo searches already saved company accounts. Prospect search/enrichment
|
|
75
|
+
uses different endpoints and is not implemented by `accounts.search`.
|
|
76
|
+
- Clay uses its Public API key and verifies identity before any search. Import
|
|
77
|
+
`clayProvider` from `@jskit-ai/connectors-catalog/server/clay`. Its guide supplies
|
|
78
|
+
the portable configuration. Authorize `searches.create` with a valid Clay
|
|
79
|
+
query, retain its `search_id` under that connection, then explicitly invoke
|
|
80
|
+
`searches.next` with `{ searchId, limit }`. Each POST advances an iterator;
|
|
81
|
+
do not replay interrupted requests or automatically consume remaining pages.
|
|
82
|
+
Verification does not prove search quota. Shared keys do not implement login.
|
|
83
|
+
- Attention conversation results can contain transcript content even with
|
|
84
|
+
detailed transcripts disabled. Its documented key-provisioning API belongs
|
|
85
|
+
in an operator workflow, not the application's conversation-reading actions.
|
|
86
|
+
- Telegram verification reads bot identity, never the update queue. Its token
|
|
87
|
+
identifies a bot, not an application user. Webhook reads do not set a webhook.
|
|
88
|
+
- KLIPY verifies trending clips and supports explicit clip search. It defaults
|
|
89
|
+
to the high content filter and never invents a customer identifier.
|
|
90
|
+
- Telegram and KLIPY credentials appear in the request path. Redact paths in
|
|
91
|
+
HTTP tracing; configuration and connection records retain only references.
|
|
92
|
+
- Google Maps Platform requires `verificationInput: { address: "an explicit address" }`.
|
|
93
|
+
Verification makes a geocoding request and can incur provider usage charges.
|
|
94
|
+
Its optional browser-key reference is never resolved by the server adapter.
|
|
95
|
+
`ZERO_RESULTS` is a valid lookup; billing, quota and permission failures are not.
|
|
96
|
+
- Mapbox token verification rejects HTTP-200 invalid-token replies. An active
|
|
97
|
+
token does not prove geocoding entitlement or validate its separate browser key.
|
|
98
|
+
- WooCommerce and self-hosted WordPress require an operator-chosen HTTPS site
|
|
99
|
+
URL with its installation path. Configuration editors control where Basic
|
|
100
|
+
credentials go; private hosts are allowed, so the host owns network policy.
|
|
101
|
+
WooCommerce pairs its consumer key with a secret reference and verifies
|
|
102
|
+
product reads. WordPress pairs its username with an Application Password
|
|
103
|
+
reference and verifies users/me; public post reads alone cannot verify it.
|
|
104
|
+
Neither flow needs a global OAuth registration or a callback. Separate
|
|
105
|
+
application keys on the same site do not establish separate hosting capacity.
|
|
106
|
+
- PrestaShop uses its Webservice API key as the Basic-auth username with an
|
|
107
|
+
empty password, preserving the store's installation subdirectory before
|
|
108
|
+
`/api`. It requests JSON product/order pages with explicit offset and limit.
|
|
109
|
+
Product verification does not establish order permission. Preserve the
|
|
110
|
+
provider's empty `[]` result, multilingual values and decimal strings; do
|
|
111
|
+
not invent OAuth credentials, automatic pagination or XML writes.
|
|
112
|
+
- An optional frontend key reference is distinct from the primary backend key.
|
|
113
|
+
Only the application may deliberately expose a suitable search-only key;
|
|
114
|
+
successful backend verification does not verify that frontend key's restrictions.
|
|
115
|
+
|
|
116
|
+
## Framework APIs
|
|
117
|
+
|
|
118
|
+
Import configuration validation from connectors-core/shared/configuration,
|
|
119
|
+
connection service and environment references from connectors-core/server,
|
|
120
|
+
and the file store and credential protection from connectors-core/server/file-storage.
|
|
121
|
+
Import the selected provider through its individual connectors-catalog/server export.
|
|
122
|
+
Each provider guide names its useful operations, accepted inputs, credential
|
|
123
|
+
bootstrap and current limits. Some keys allow sending or management beyond the
|
|
124
|
+
implemented read operation; this pattern does not grant those extra operations.
|
|
125
|
+
|
|
126
|
+
## Example files
|
|
127
|
+
|
|
128
|
+
The application owns `integrations.json`:
|
|
129
|
+
|
|
130
|
+
```json
|
|
131
|
+
{
|
|
132
|
+
"schemaVersion": 1,
|
|
133
|
+
"registrations": {},
|
|
134
|
+
"integrations": {
|
|
135
|
+
"mail": {
|
|
136
|
+
"provider": "resend",
|
|
137
|
+
"displayName": "Sending domains",
|
|
138
|
+
"accountMode": "shared",
|
|
139
|
+
"scopes": [],
|
|
140
|
+
"authentication": { "method": "api-key", "secretRef": "env:RESEND_API_KEY" }
|
|
141
|
+
},
|
|
142
|
+
"web": {
|
|
143
|
+
"provider": "firecrawl",
|
|
144
|
+
"accountMode": "assistant",
|
|
145
|
+
"scopes": [],
|
|
146
|
+
"authentication": { "method": "api-key", "secretRef": "env:FIRECRAWL_API_KEY" }
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
A server module or manually written CLI composes the same library calls:
|
|
153
|
+
|
|
154
|
+
```js
|
|
155
|
+
import { readFile } from "node:fs/promises";
|
|
156
|
+
import { parseIntegrationConfiguration } from "@jskit-ai/connectors-core/shared/configuration";
|
|
157
|
+
import { createConnectionService, createEnvironmentReferenceResolver } from "@jskit-ai/connectors-core/server";
|
|
158
|
+
import { createFileConnectionStore, createCredentialProtection } from "@jskit-ai/connectors-core/server/file-storage";
|
|
159
|
+
import { resendProvider } from "@jskit-ai/connectors-catalog/server/resend";
|
|
160
|
+
import { firecrawlProvider } from "@jskit-ai/connectors-catalog/server/firecrawl";
|
|
161
|
+
|
|
162
|
+
const providers = [resendProvider, firecrawlProvider];
|
|
163
|
+
const configuration = parseIntegrationConfiguration(await readFile("integrations.json", "utf8"), { providers });
|
|
164
|
+
const protection = createCredentialProtection({
|
|
165
|
+
keys: { current: Buffer.from(process.env.CONNECTOR_STORAGE_KEY, "base64") },
|
|
166
|
+
activeKeyId: "current"
|
|
167
|
+
});
|
|
168
|
+
const store = createFileConnectionStore({ directory: process.env.CONNECTOR_STATE_DIRECTORY, protection });
|
|
169
|
+
const connections = createConnectionService({
|
|
170
|
+
configuration, providers, store,
|
|
171
|
+
resolveReference: createEnvironmentReferenceResolver(),
|
|
172
|
+
authorize: applicationConnectionPolicy
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// context comes from the existing application's authentication or local operator policy.
|
|
176
|
+
await connections.connectApiKey({ context, integrationId: "mail" });
|
|
177
|
+
const domains = await connections.invoke({ context, integrationId: "mail", operation: "domains.list", input: { limit: 10 } });
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
`applicationConnectionPolicy` receives the context, slot, operation and account
|
|
181
|
+
mode. It returns `{ applicationId, subjectId }` only after checking that the
|
|
182
|
+
caller can perform that operation. Shared connections use a stable shared
|
|
183
|
+
subject after membership checks. An operator-only CLI can identify the trusted
|
|
184
|
+
OS process owner; web routes must derive identity from the authenticated
|
|
185
|
+
session, not request parameters.
|
|
186
|
+
|
|
187
|
+
## Semrush composition
|
|
188
|
+
|
|
189
|
+
Import `semrushProvider` from `@jskit-ai/connectors-catalog/server/semrush` and
|
|
190
|
+
supply the configuration in the [Semrush guide](https://github.com/mobily-enterprises/jskit-ai/blob/main/packages/connectors-catalog/docs/semrush.md). Reuse
|
|
191
|
+
`createConnectionService`, the file store and the host policy shown above:
|
|
192
|
+
|
|
193
|
+
```js
|
|
194
|
+
await connections.connectApiKey({ context, integrationId: "seo" });
|
|
195
|
+
const page = await connections.invoke({
|
|
196
|
+
context, integrationId: "seo", operation: "projects.list",
|
|
197
|
+
input: { scope: "OWN", limit: 25, offset: 0 }
|
|
198
|
+
});
|
|
199
|
+
// Authorize the chosen project for this application before reading it.
|
|
200
|
+
const project = await connections.invoke({
|
|
201
|
+
context, integrationId: "seo", operation: "projects.get",
|
|
202
|
+
input: { projectId: authorizedProjectId }
|
|
203
|
+
});
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Use a V4 API-key reference, never a V3 key or an OAuth token. Preserve the
|
|
207
|
+
returned pagination and provider permissions; do not enumerate later pages
|
|
208
|
+
without an explicit application request. `connector_quota_limited` requires
|
|
209
|
+
account-capacity handling, not a retry loop. Separate keys on one account do
|
|
210
|
+
not create independent capacity. The captured OAuth scopes, provider onboarding
|
|
211
|
+
and individual app-user connections remain separate unfinished work.
|
|
212
|
+
|
|
213
|
+
## Verification
|
|
214
|
+
|
|
215
|
+
Focused library tests use simulated HTTP responses and actual temporary JSON
|
|
216
|
+
storage. They verify validation, provider requests, result shapes, isolation,
|
|
217
|
+
rotation, rejected credentials, pagination, atomic replacement and restart.
|
|
218
|
+
Automated editor tests verify portable file edits and field errors. No real
|
|
219
|
+
provider use or generated sample application is needed for these checks.
|
|
220
|
+
|
|
221
|
+
For future live acceptance, follow each provider's setup guide and invoke its
|
|
222
|
+
read-only check explicitly. Resend lists domains; Firecrawl reads credits.
|
|
223
|
+
`pages.scrape` is a separate, authorized operation that consumes credits.
|
|
224
|
+
|
|
225
|
+
## Variation points
|
|
226
|
+
|
|
227
|
+
Use `googleCalendarProvider` and OAuth lifecycle methods with the same file
|
|
228
|
+
store for a Calendar connection. Use the optional Knex store only when the
|
|
229
|
+
application explicitly owns a SQL database. Hosts with an established shared
|
|
230
|
+
filesystem identity may set `directoryMode` and `fileMode` at store creation;
|
|
231
|
+
the library creates files with those modes and never recursively repairs a tree.
|
|
232
|
+
|
|
233
|
+
Expose the ordinary `createConnectorsFeature` status, verifyApiKey and disconnect
|
|
234
|
+
actions, or compose the service inside an existing Feature. Business operations
|
|
235
|
+
remain named application actions. The UI uses `IntegrationConfigurationFields`
|
|
236
|
+
with the matching browser-safe definition; a host credential slot can write
|
|
237
|
+
values through its existing secret-entry service while keeping references in
|
|
238
|
+
configuration.
|
|
239
|
+
|
|
240
|
+
## Avoid
|
|
241
|
+
|
|
242
|
+
Do not turn provider metadata into arbitrary authenticated URL forwarding.
|
|
243
|
+
Do not retry a paid or mutating request automatically. Do not mark an untested
|
|
244
|
+
managed mode or an unimplemented provider operation available.
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
## Granola meeting data
|
|
248
|
+
|
|
249
|
+
Import `granolaProvider` from `@jskit-ai/connectors-catalog/server/granola` and
|
|
250
|
+
compose the same API-key connection service and encrypted file store. The
|
|
251
|
+
packaged `docs/granola.md` explains personal/workspace keys and ownership.
|
|
252
|
+
Use a `grn_` key through a secret reference; no OAuth registration is required
|
|
253
|
+
for this API-key mode. Personal notes access does not create per-user app login.
|
|
254
|
+
|
|
255
|
+
```js
|
|
256
|
+
const result = await connections.invoke({
|
|
257
|
+
context: authenticatedOwner, integrationId: "meetings", operation: "notes.list",
|
|
258
|
+
input: { created_after: "2026-09-01", page_size: 10 }
|
|
259
|
+
});
|
|
260
|
+
const note = await connections.invoke({
|
|
261
|
+
context: authenticatedOwner, integrationId: "meetings", operation: "notes.get",
|
|
262
|
+
input: { note_id: selectedNoteId }
|
|
263
|
+
});
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Use the provider's `not_` note IDs and `fol_` folder IDs, not UUIDs from browser
|
|
267
|
+
URLs. `folders.list` supplies folder IDs; `transcripts.list` reads transcript
|
|
268
|
+
pages. Keep cursors with the same connection and filters, and request each page
|
|
269
|
+
explicitly. `notes.get` omits transcripts by default; `include: "transcript"`
|
|
270
|
+
requests inline data, but a 413 asks the host to use paginated transcripts.
|
|
271
|
+
Do not automatically retry or fetch every page.
|
|
272
|
+
|
|
273
|
+
The host owns note selection and access policy, especially for a shared key.
|
|
274
|
+
Preserve null private-note fields and optional speaker attribution; do not infer
|
|
275
|
+
speaker identity from microphone/speaker source. Render provider text safely.
|
|
276
|
+
A valid empty note list may mean no accessible processed notes. Saved configuration
|
|
277
|
+
is not proof of key validity. Sharing a personal key shares its permitted data.
|
|
278
|
+
The separate Granola MCP browser OAuth/DCR flow is not implemented by this adapter;
|
|
279
|
+
do not send API keys to the MCP server or invent managed client credentials.
|
|
280
|
+
|
|
281
|
+
## dbt Semantic Layer metadata
|
|
282
|
+
|
|
283
|
+
Import `dbtSemanticLayerProvider` from
|
|
284
|
+
`@jskit-ai/connectors-catalog/server/dbt-semantic-layer` and include it in the
|
|
285
|
+
same `providers` array passed to both `parseIntegrationConfiguration` and
|
|
286
|
+
`createConnectionService`. Use the ordinary file store and reference resolver
|
|
287
|
+
shown above; no database, template generation or alternate transport is needed.
|
|
288
|
+
|
|
289
|
+
Create a `dbt-semantic-layer` integration with `settings.host` and
|
|
290
|
+
`settings.environmentId`. The latter must remain a decimal string, even in a
|
|
291
|
+
CLI: converting it to a number can round large IDs. Store the service token in
|
|
292
|
+
`authentication.secretRef`; permissions and warehouse credentials are configured
|
|
293
|
+
in dbt. Use the guide's actual JSON, not an invented OAuth registration.
|
|
294
|
+
|
|
295
|
+
The host authenticates callers and authorizes the application, integration and
|
|
296
|
+
subject before every call. For an assistant, explicitly bind that identity to
|
|
297
|
+
the allowed shared connection. A token's metadata access is not application
|
|
298
|
+
login and does not make every user an authorized reader of that warehouse.
|
|
299
|
+
|
|
300
|
+
After the operator supplies a token, call `connectApiKey` explicitly. Successful
|
|
301
|
+
verification reads only `environmentInfo.dialect`. Keep configuration saving
|
|
302
|
+
separate from connection verification. Display the returned connection status,
|
|
303
|
+
and handle denied access or reconnection through the existing host UI.
|
|
304
|
+
|
|
305
|
+
Use `metrics.list` to select metric names, `dimensions.list` with
|
|
306
|
+
`metrics: [{ name: "order_total" }]` to discover compatible dimensions, and
|
|
307
|
+
`savedQueries.list` to browse saved-query metadata. Do not silently select the
|
|
308
|
+
first metric. All page operations accept `pageNum`, `pageSize` and optional
|
|
309
|
+
`search`; keep paging user-driven and inspect the returned totals. One invoke
|
|
310
|
+
makes one HTTP request. Empty lists and null descriptions are ordinary states.
|
|
311
|
+
|
|
312
|
+
Inputs cannot override the configured host or environment. Preserve returned
|
|
313
|
+
metadata as data, and escape it in UI rendering. Use `AbortSignal` when leaving
|
|
314
|
+
a screen, avoid replaying failed requests automatically, and resolve rotated
|
|
315
|
+
credentials through the original secret reference. Changing that reference,
|
|
316
|
+
host or environment requires fresh verification. Disconnect only removes local
|
|
317
|
+
state; the operator revokes tokens in dbt.
|
|
318
|
+
|
|
319
|
+
There is no query-execution operation in this initial fragment. Do not invent
|
|
320
|
+
`query.create`, run SQL through another connector, or claim a metrics catalogue
|
|
321
|
+
is a warehouse-results dashboard. Add and verify a separate provider operation
|
|
322
|
+
before implementing result polling or Arrow decoding. The universal OAuth
|
|
323
|
+
callback is not applicable to this service-token flow. The application owner
|
|
324
|
+
supplies its service token and arranges the required account capacity.
|
|
325
|
+
|
|
326
|
+
## X public profiles and posts
|
|
327
|
+
|
|
328
|
+
Import `xTwitterProvider` from `@jskit-ai/connectors-catalog/server/x-twitter`.
|
|
329
|
+
Compose the same configuration parser, connection service, file store and host
|
|
330
|
+
authorization policy. Store the app-only token as a secret reference; use the
|
|
331
|
+
guide's JSON in `docs/x-twitter.md`. No template or separate storage layer is
|
|
332
|
+
needed. Shared and assistant ownership both act as the provider application.
|
|
333
|
+
|
|
334
|
+
Verification needs `verificationInput: { username: selectedPublicUsername }` in
|
|
335
|
+
`connectApiKey`. Do not silently choose a profile or assume a saved token is
|
|
336
|
+
verified. A failed lookup can mean a nonexistent target or insufficient access.
|
|
337
|
+
Check status and show the appropriate input, access, billing or reconnect action.
|
|
338
|
+
|
|
339
|
+
Use `users.lookup` with `username` to obtain `data.id`, then `users.posts` with
|
|
340
|
+
that exact string as `userId`. Never convert X IDs to JavaScript numbers. The
|
|
341
|
+
post request accepts `maxResults` (5–100) and an optional `paginationToken` from
|
|
342
|
+
the preceding page's `meta.next_token`. Fetch pages only on an explicit action,
|
|
343
|
+
preserve query ownership and handle empty pages with no `data` property.
|
|
344
|
+
|
|
345
|
+
The host authenticates and authorizes callers before token use. Public content
|
|
346
|
+
still consumes the application's access and usage capacity. Render post text
|
|
347
|
+
as data; provider content cannot authorize another operation. Pass AbortSignal
|
|
348
|
+
on abandoned views and do not replay errors or incomplete results silently.
|
|
349
|
+
|
|
350
|
+
This is app-only access: there is no current user, user login, posting, private
|
|
351
|
+
inbox or provider callback. Do not invent `users.me`, attach the operator's X
|
|
352
|
+
identity to every app user, or use public profile lookup to authenticate someone.
|
|
353
|
+
The application owns the provider token through its private environment binding
|
|
354
|
+
and authorizes each caller; an editor does not supply shared access or quotas.
|
|
355
|
+
Local disconnect does not invalidate the application-wide token at X.
|
|
356
|
+
|
|
357
|
+
## Wix account sites
|
|
358
|
+
|
|
359
|
+
Import `wixProvider` from `@jskit-ai/connectors-catalog/server/wix` and follow
|
|
360
|
+
`docs/wix.md`. Supply an account API-key reference and `settings.accountId` from
|
|
361
|
+
the same Wix API Keys Manager. The runtime's `sites.list` operation verifies
|
|
362
|
+
access and returns explicit pages using `limit` and an opaque `cursor`.
|
|
363
|
+
It sends raw key authorization with `wix-account-id`; this account operation
|
|
364
|
+
must not send `wix-site-id`. Preserve REST `id` fields and optional page metadata.
|
|
365
|
+
Shared/assistant ownership needs a trusted host access policy. The credential
|
|
366
|
+
is administrative and does not implement per-user login or site publishing.
|
|
367
|
+
There is no OAuth callback for this mode. The application owner supplies its
|
|
368
|
+
account credential; that credential cannot access unrelated customer accounts.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { parseIntegrationConfiguration } from "@jskit-ai/connectors-core/shared/configuration";
|
|
3
|
+
import { createConnectionService, createEnvironmentReferenceResolver } from "@jskit-ai/connectors-core/server";
|
|
4
|
+
import { createFileConnectionStore, createCredentialProtection } from "@jskit-ai/connectors-core/server/file-storage";
|
|
5
|
+
import { resendProvider } from "@jskit-ai/connectors-catalog/server/resend";
|
|
6
|
+
import { firecrawlProvider } from "@jskit-ai/connectors-catalog/server/firecrawl";
|
|
7
|
+
|
|
8
|
+
// Both a manually written CLI and a server can compose this application-owned module.
|
|
9
|
+
// The application supplies its existing identity and permission policy.
|
|
10
|
+
export async function applicationConnections({ authorize, env = process.env, configFile = "integrations.json" }) {
|
|
11
|
+
const providers = [resendProvider, firecrawlProvider];
|
|
12
|
+
const configuration = parseIntegrationConfiguration(await readFile(configFile, "utf8"), { providers });
|
|
13
|
+
const protection = createCredentialProtection({
|
|
14
|
+
keys: { current: Buffer.from(env.CONNECTOR_STORAGE_KEY, "base64") }, activeKeyId: "current"
|
|
15
|
+
});
|
|
16
|
+
const store = createFileConnectionStore({ directory: env.CONNECTOR_STATE_DIRECTORY, protection });
|
|
17
|
+
return createConnectionService({ configuration, providers, store, authorize, resolveReference: createEnvironmentReferenceResolver(env) });
|
|
18
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"registrations": {},
|
|
4
|
+
"integrations": {
|
|
5
|
+
"mail": {
|
|
6
|
+
"provider": "resend",
|
|
7
|
+
"displayName": "Sending domains",
|
|
8
|
+
"accountMode": "shared",
|
|
9
|
+
"scopes": [],
|
|
10
|
+
"authentication": { "method": "api-key", "secretRef": "env:RESEND_API_KEY" }
|
|
11
|
+
},
|
|
12
|
+
"web": {
|
|
13
|
+
"provider": "firecrawl",
|
|
14
|
+
"accountMode": "assistant",
|
|
15
|
+
"scopes": [],
|
|
16
|
+
"authentication": { "method": "api-key", "secretRef": "env:FIRECRAWL_API_KEY" }
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: connectors/assistant-mcp
|
|
3
|
+
title: Assistant MCP connections with portable files
|
|
4
|
+
summary: Compose token-based MCP discovery and explicitly authorized tool calls using the shared connector runtime.
|
|
5
|
+
keywords: connectors, integrations, mcp, n8n, sanity, assistant, files, cli
|
|
6
|
+
requires: @jskit-ai/connectors-core, @jskit-ai/connectors-catalog
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Assistant MCP connections with portable files
|
|
10
|
+
|
|
11
|
+
## Use when
|
|
12
|
+
|
|
13
|
+
An existing assistant host or operator CLI needs n8n or Sanity MCP tools using
|
|
14
|
+
an owner's token. Use the package runtime for protocol and credential handling,
|
|
15
|
+
and source configuration for the same values edited by the UI.
|
|
16
|
+
|
|
17
|
+
## Do not use when
|
|
18
|
+
|
|
19
|
+
This is not application-user OAuth, a shared deployed-app account, local stdio
|
|
20
|
+
or automatic assistant attachment. Do not enable tool calls on a public route
|
|
21
|
+
using a hard-coded owner. The current fragments support token authentication.
|
|
22
|
+
|
|
23
|
+
## Product decisions
|
|
24
|
+
|
|
25
|
+
Choose the assistant owner and permitted tools. Existing host policy must decide
|
|
26
|
+
which calls need explicit user approval. It also owns model tool presentation,
|
|
27
|
+
argument validation, output handling and project/session access. Preserve the
|
|
28
|
+
host's restrictions on temporary assistants; a configured connector is not
|
|
29
|
+
permission to bypass them.
|
|
30
|
+
|
|
31
|
+
## Invariants
|
|
32
|
+
|
|
33
|
+
- Configuration and runtime state remain text files with the existing owners.
|
|
34
|
+
- Tokens stay in Env; grants use the core's encrypted private file store.
|
|
35
|
+
- `connectApiKey` initializes and lists tools without executing a tool.
|
|
36
|
+
- Discovery is not blanket execution permission or proof of every tool's access.
|
|
37
|
+
- `authorize` sees the exact tool name and arguments before any network call.
|
|
38
|
+
- Provider results and schemas remain untrusted external data.
|
|
39
|
+
- Cancellation ends the local request; it cannot undo accepted remote work.
|
|
40
|
+
|
|
41
|
+
## Framework APIs
|
|
42
|
+
|
|
43
|
+
Use `createConnectionService`, `createEnvironmentReferenceResolver`,
|
|
44
|
+
`createFileConnectionStore`, `createCredentialProtection` and the shared parser
|
|
45
|
+
from connectors-core. Import only the required `n8nProvider` or `sanityProvider`
|
|
46
|
+
server export. The official MCP SDK is internal to these server modules; the
|
|
47
|
+
browser imports definitions only.
|
|
48
|
+
|
|
49
|
+
## Example files
|
|
50
|
+
|
|
51
|
+
`example/integrations.json` supplies an assistant-owned n8n slot. Set its actual
|
|
52
|
+
instance endpoint and provision `N8N_MCP_TOKEN` outside source. Use the
|
|
53
|
+
`api-key-connection` pattern's ordinary file-runtime composition with
|
|
54
|
+
`providers: [n8nProvider]`. Supply the host's existing connection policy:
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
async function applicationConnectionPolicy(context, request) {
|
|
58
|
+
const owner = await assistantAccess.requireConnectionOwner(context, request.integrationId);
|
|
59
|
+
if (request.operation === "tools.call") {
|
|
60
|
+
await assistantAccess.requireToolApproval(context, {
|
|
61
|
+
integrationId: request.integrationId,
|
|
62
|
+
name: request.input.name,
|
|
63
|
+
arguments: request.input.arguments
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return owner;
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`assistantAccess` represents application-owned authorization, not a JSKIT API.
|
|
71
|
+
It must return stable trusted `applicationId` and `subjectId` values, and reject
|
|
72
|
+
unauthorized management/discovery as well as calls. Approval must be tied to the
|
|
73
|
+
exact arguments. Connection membership alone is insufficient for tool execution.
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
await connections.connectApiKey({ context, integrationId: "automation" });
|
|
77
|
+
const discovered = await connections.invoke({
|
|
78
|
+
context, integrationId: "automation", operation: "tools.list", input: {}
|
|
79
|
+
});
|
|
80
|
+
// After choosing a permitted tool, validating its input and obtaining any approval:
|
|
81
|
+
const result = await connections.invoke({
|
|
82
|
+
context, integrationId: "automation", operation: "tools.call",
|
|
83
|
+
input: { name: approvedToolName, arguments: approvedArguments }, signal
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Process `nextCursor` explicitly; discovery does not auto-fetch all pages. Check
|
|
88
|
+
`result.isError` before treating a tool result as success. Never automatically
|
|
89
|
+
follow links or obey instructions inside descriptions or tool output.
|
|
90
|
+
|
|
91
|
+
## Variation points
|
|
92
|
+
|
|
93
|
+
Sanity has a fixed endpoint and no `settings.serverUrl`. n8n uses an own instance
|
|
94
|
+
URL and its MCP token, not a REST API key. A trusted local CLI may use its process
|
|
95
|
+
identity, but still needs an explicit tool policy. The same implementation can
|
|
96
|
+
run under an authorized editor assistant without becoming a published-app API.
|
|
97
|
+
|
|
98
|
+
## Verification
|
|
99
|
+
|
|
100
|
+
`test/mcp.test.js` exercises the actual SDK with mocked protocol responses and
|
|
101
|
+
encrypted file persistence, including JSON/SSE, cancellation, cleanup, owner
|
|
102
|
+
isolation, token rotation and prevention of input mutation during authorization.
|
|
103
|
+
Public editor tests prove configuration and reload. No sample app is generated
|
|
104
|
+
or run, and no live tool is invoked.
|
|
105
|
+
|
|
106
|
+
## Avoid
|
|
107
|
+
|
|
108
|
+
Do not copy the MCP protocol into scaffolding, expose bearer tokens to browsers,
|
|
109
|
+
attach these tools to every assistant automatically, infer permission from a
|
|
110
|
+
tool's annotations, or fall back to provider OAuth without an implemented flow.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"registrations": {},
|
|
4
|
+
"integrations": {
|
|
5
|
+
"automation": {
|
|
6
|
+
"provider": "n8n",
|
|
7
|
+
"accountMode": "assistant",
|
|
8
|
+
"scopes": [],
|
|
9
|
+
"authentication": { "method": "api-key", "secretRef": "env:N8N_MCP_TOKEN" },
|
|
10
|
+
"settings": { "serverUrl": "https://automation.example.com/mcp-server/http" }
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|