1 ---
2 name: integrations
3 description: Search and manage Replit integrations including blueprints, connectors, and connections. Use for authentication, databases, payments, and third-party API integrations.
4 ---
5
6 # Integrations Skill
7
8 Integrations allow first-class usage of Third-Party (and some First-party) technologies. If the integration exists, you can ask user to "connect" their account (Google, Linear, GitHub, Stripe, etc) to their Replit account, which critically gives you, the Replit Agent, access to new capabilities (e.g. view their Google Sheets, read their Linear issues, setup & access payment systems, etc). You must follow the steps outlined here to successfully make these "connections".
9
10 **Before asking the user for any API key, secret, or credential, always search for a Replit integration first.** Replit integrations handle OAuth and secrets securely, and many common services (Google Sheets, Linear, Stripe, GitHub, OpenAI, etc.) are already supported. Asking the user for credentials when an integration exists adds a lot of unnecessary friction. Users typically do not know about our integration system, you must proactive in suggesting it when it (and only when) it is relevant.
11
12 Integrations include blueprints (code templates), connectors (OAuth/API integrations + templates), and connections (already established integrations).
13
14 ## When to Use
15
16 Use this skill when:
17
18 - User needs authentication (login, signup, OAuth)
19 - User needs database connections (PostgreSQL, MongoDB, etc.)
20 - User needs payment processing (Stripe, etc.)
21 - User needs third-party API integrations (OpenAI, Notion, GitHub, Linear, etc.)
22 - User asks about Replit-specific features and capabilities
23
24 ## When NOT to Use
25
26 As a web search (use web-search skill if available), searching files within the project, media generation (use media-generation skill, including image generation APIs), fetching data to respond to a user's question (use query-integration-data skill).
27
28 ---
29
30 ## Integration Lifecycle
31
32 There are three types of integrations, and they represent different stages of a lifecycle:
33
34 ```text
35 connector (not_setup)
36 → user completes OAuth via proposeIntegration
37 → connection (not_added)
38 → addIntegration ← code-side wiring (npm packages, scaffolds, project registration)
39 → proposeIntegration ← platform-side binding (registers this Repl with connectors so the credential proxy will serve secrets)
40 → now it is a functioning connection (added + authorized, ready to use)
41
42 blueprint (not_installed)
43 → addIntegration or proposeIntegration
44 → blueprint (installed, code + packages added to project), ready to use
45 ```
46
47 ### Connectors
48
49 - An available OAuth/API integration that has **not yet been authorized** by the user
50 - Status: `not_setup`
51 - Cannot be added directly — must use `proposeIntegration` which allows the user through the OAuth flow
52 - Example ID: `connector:ccfg_google-sheet_E42A9F6DA6...`
53
54 ### Connections
55
56 - A connector that has **already been authorized** at the account level
57 - Status: `not_added` (authorized at account level but not bound to this Repl) or `added` (active in this Repl)
58 - Both `addIntegration` AND `proposeIntegration` are required on first setup — they do orthogonal things:
59 - `addIntegration` does code-side wiring (npm install, scaffolds, project registration). It does NOT touch the platform's connection-state backend.
60 - `proposeIntegration` does platform-side binding (registers this Repl with connectors-v2 as a permitted consumer). Without it the credential proxy at `connectors.replit.com/api/v2/connection` returns nothing for this Repl, even though the underlying credentials exist at the account level.
61 - Example ID: `connection:conn_linear_01MG99PAJR6MQ5...`
62
63 NOTE: You must not delay calling proposeIntegration even if it waits for the user. You will be blocked and not have access to test the feature you build because you don't have access to real data, real APIs, etc, which is even more inefficient than reaching out to the user as soon as you know you need the integration to get accepted.
64
65 ### Blueprints
66
67 - These are just code templates that install packages and scaffold integration boilerplate
68 - Status: `not_installed` or `previously_installed`
69 - Use `addIntegration` directly; if `requiresConfirmation` is True, use `proposeIntegration` instead
70 - Example ID: `blueprint:javascript_openai`
71
72 ---
73
74 ## Available Functions
75
76 All functions are available directly in the `code_execution` sandbox. **Always use `console.log()` on return values** — functions execute silently with no output if you don't.
77
78 ### searchIntegrations(query)
79
80 Search for available integrations. **Always run this first.** Try a few different query terms if the first search returns nothing — results depend on keyword matching.
81
82 **Returns:** Dict with:
83
84 - `integrations`: list of integration objects, each with `id`, `displayName`, `description`, `integrationType`, `status`
85 - `askForBlueprintConfirmation`: boolean — if True, blueprint additions in this environment will require user confirmation; expect `requiresConfirmation: True` back from `addIntegration` and be ready to call `proposeIntegration` instead
86
87 ```javascript
88 const results = await searchIntegrations("Google Sheets");
89 console.log(results);
90 // { integrations: [{ id: 'connector:ccfg_google-sheet_...', displayName: 'Google Sheets',
91 // description: '...', integrationType: 'connector', status: 'not_setup' }], ... }
92
93 // Always log — calling without console.log produces no visible output!
94 for (const item of results.integrations) {
95 console.log(`${item.id} type=${item.integrationType} status=${item.status}`);
96 }
97 ```
98
99 **Notes:**
100
101 - When the user has not explicitly requested a specific provider, at least search with a generic, capability-focused query to ensure all relevant options are returned. For example, when user asks "build an icon generating app", prefer `searchIntegrations("image generation")` instead of `searchIntegrations("OpenAI image generation")`
102 - If a connector has already been authorized by the user or a teammate, it will appear as a `connection` (not a `connector`) in results
103 - Try multiple queries if needed: `"stripe"`, `"payments"`, `"stripe payment processing"` may return different results
104 - The `id` field is the exact string to pass to subsequent functions
105
106 ---
107
108 ### viewIntegration(integrationId)
109
110 Fetch full details and the code snippet for an integration without adding it to the project.
111
112 **Returns:** Dict with `integrationType`, `integrationId`, `displayName`, `renderedContent`
113
114 **Note:** `addIntegration` returns the exact same `renderedContent` blob, so in most cases you don't need to call this separately — just read the result of `addIntegration`. The main reason to call `viewIntegration` first is if you want to inspect the package name, code snippet, or documentation URL before committing to the install.
115
116 ```javascript
117 const info = await viewIntegration("connection:conn_linear_01KG10PAJR6MQ525SQSWEB8QHC");
118 console.log(info.renderedContent); // Same blob you'd get from addIntegration
119 ```
120
121 ---
122
123 ### addIntegration(integrationId)
124
125 Add a blueprint or connection to the current project. **Do not use for connectors** (those with `integrationType: connector` and `status: not_setup`) — use `proposeIntegration` for those.
126
127 **Returns:** Dict with:
128
129 - `success`: boolean
130 - `requiresConfirmation`: boolean — if True, call `proposeIntegration` instead
131 - `connectionAlreadyAdded`: boolean — if True, the connection is already wired to this project; skip addIntegration but still call proposeIntegration to ensure the platform binding is current (tokens expire, bindings can be stale)
132 - `renderedContent`: same XML blob as `viewIntegration`
133 - `observations`: list of stringified observation objects (verbose; contains npm install output)
134
135 **Side effect:** Automatically installs required packages. This will restart or crash a running dev server — be aware if calling mid-session while the workflow is running.
136
137 ```javascript
138 const result = await addIntegration("connection:conn_linear_01KG10PAJR6MQ525SQSWEB8QHC");
139 console.log(result.success); // true
140 console.log(result.observations); // Contains package installation output as stringified objects
141
142 // Handle confirmation requirement
143 if (!result.success && result.requiresConfirmation) {
144 proposeIntegration("connection:conn_linear_01KG10PAJR6MQ525SQSWEB8QHC");
145 }
146 ```
147
148 **After calling addIntegration:**
149
150 - Read `renderedContent` to get the code snippet
151 - The snippet handles token refresh and expiry — use it as-is, don't simplify it
152 - Never cache the client object the snippet creates — tokens expire
153
154 ---
155
156 ### proposeIntegration(integrationId)
157
158 Propose a connector to the user. This is a **control-flow operation** — it exits the agent loop immediately and waits for the user to complete OAuth or confirm setup. Nothing after this call will execute in the current loop.
159
160 **Returns:** Dict with `success`, `displayName`, `exitLoop` (always True)
161
162 **Use for:**
163
164 - Connectors with `status: not_setup` (drives OAuth + binding)
165 - Connections with `status: not_added` after calling `addIntegration` (drives the binding only)
166 - Connections with `status: added` if runtime fails with "not connected" (re-binds / refreshes)
167 - Blueprints where `addIntegration` returns `requiresConfirmation: True`
168
169 ```javascript
170 // Always explain to the user what is about to happen before calling this
171 // The agent loop exits after this — no further code runs
172 const result = await proposeIntegration("connector:ccfg_google-sheet_E42A9F6CA62546F68A1FECA0E8");
173 ```
174
175 **Notes:**
176
177 - After the user completes OAuth, the connector becomes a `connection`
178 - On the next agent loop, call `addIntegration` with the new `connection:...` ID
179 - There is no user-visible message automatically shown when this exits — explain what you're doing in your chat response before calling it
180
181 ---
182
183 ## Using the Code Snippet
184
185 After `addIntegration` or `viewIntegration`, the `renderedContent` contains a code snippet. Key things to know:
186
187 1. **It is not on the filesystem.** Copy it into a new file in your project (e.g., `server/googleSheets.ts`)
188 2. **Never cache the client.** Tokens expire. The snippet exports a `getUncachable___Client()` function — call it fresh on every request
189 3. **The token refresh logic is correct as-is.** Don't simplify or remove the expiry check
190 4. **The snippet uses environment variables** (`REPLIT_CONNECTORS_HOSTNAME`, `REPL_IDENTITY`, `WEB_REPL_RENEWAL`) that Replit injects automatically — no setup needed
191
192 ---
193
194 ## Databricks
195
196 When the user wants to connect to Databricks, use the `databricks-m2m` connector (not the plain `databricks` connector). The `databricks-m2m` connector provides machine-to-machine access and works in all contexts. Inside a Databricks App, prefer the `databricks` (U2M) connector when available — see the `databricks-app` skill for details.
197
198 ## Common Pitfalls
199
200 - **Not logging results:** `searchIntegrations` and all other functions return silently unless you `console.log()` the output
201 - **Calling addIntegration on a connector:** Will fail or behave unexpectedly. Check `integrationType` first
202 - **Asking for API keys when a connection exists:** If `searchIntegrations` returns a `connection`, the user is already authenticated at the account level — use `addIntegration` to wire the project, then `proposeIntegration` to bind this Repl to the connection. Both steps are always required.
203 - **Caching the client:** The boilerplate snippet is explicit about this. Tokens expire. Always call `getUncachable___Client()` fresh
204 - **Package install side effects:** `addIntegration` runs package installation (e.g. npm, uv), which can crash a running dev server. Restart the workflow after adding integrations
205 - **Connection added but runtime still fails:** If `addIntegration` succeeds for a `connection` but the app throws "not connected" at runtime, the token may be expired or missing. Call `proposeIntegration` with the same connection ID to trigger re-authorization, then restart the workflow