@rainfall-devkit/sdk 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pragma Digital
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,467 @@
1
+ # Rainfall SDK
2
+
3
+ Official SDK for the Rainfall API - 200+ tools for building AI-powered applications.
4
+ Utilities to leverage the backend tools we use for our own applications like [Harmonic](https://harmonic.iswork.in) to bootstrap your own projects.
5
+
6
+ [![npm version](https://badge.fury.io/js/@rainfall%2Fsdk.svg)](https://www.npmjs.com/package/@rainfall/sdk)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+
9
+ ## Features
10
+
11
+ - **200+ Tools** - GitHub, Notion, Linear, Slack, Figma, Stripe, and more
12
+ - **Semantic Memory** - Store and recall information with vector search
13
+ - **Web Search** - Exa and Perplexity integration
14
+ - **AI Tools** - Embeddings, image generation, OCR, vision, chat
15
+ - **Data Processing** - CSV, scripts, similarity search
16
+ - **Developer Friendly** - TypeScript, retry logic, error handling
17
+ - **MCP Support** - Use with Claude, Cursor, and other AI assistants
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install @rainfall/sdk
23
+ # or
24
+ yarn add @rainfall/sdk
25
+ # or
26
+ bun add @rainfall/sdk
27
+ ```
28
+
29
+ ## Quick Start
30
+
31
+ ```typescript
32
+ import { Rainfall } from '@rainfall/sdk';
33
+
34
+ const rainfall = new Rainfall({
35
+ apiKey: process.env.RAINFALL_API_KEY!
36
+ });
37
+
38
+ // Search the web
39
+ const results = await rainfall.web.search.exa({
40
+ query: 'latest AI breakthroughs'
41
+ });
42
+
43
+ // Create a GitHub issue
44
+ await rainfall.integrations.github.issues.create({
45
+ owner: 'facebook',
46
+ repo: 'react',
47
+ title: 'Bug: Something is broken',
48
+ body: 'Detailed description...'
49
+ });
50
+
51
+ // Store and recall memories
52
+ await rainfall.memory.create({
53
+ content: 'User prefers dark mode',
54
+ keywords: ['preference', 'ui']
55
+ });
56
+
57
+ const memories = await rainfall.memory.recall({
58
+ query: 'user preferences',
59
+ topK: 5
60
+ });
61
+ ```
62
+
63
+ ## CLI
64
+
65
+ Install globally to use the CLI:
66
+
67
+ ```bash
68
+ npm install -g @rainfall/sdk
69
+ ```
70
+
71
+ ### Authentication
72
+
73
+ ```bash
74
+ rainfall auth login <your-api-key>
75
+ ```
76
+
77
+ ### List Tools
78
+
79
+ ```bash
80
+ rainfall tools list
81
+ ```
82
+
83
+ ### Execute a Tool
84
+
85
+ ```bash
86
+ rainfall run exa-web-search -p '{"query": "AI news"}'
87
+ ```
88
+
89
+ ### Piping Support
90
+
91
+ ```bash
92
+ echo '{"query": "hello"}' | rainfall run exa-web-search
93
+ ```
94
+
95
+ ## Namespaces
96
+
97
+ ### Integrations
98
+
99
+ ```typescript
100
+ // GitHub
101
+ await rainfall.integrations.github.issues.create({ owner, repo, title });
102
+ await rainfall.integrations.github.repos.get({ owner, repo });
103
+
104
+ // Notion
105
+ await rainfall.integrations.notion.pages.create({ parent, properties });
106
+ await rainfall.integrations.notion.databases.query({ databaseId });
107
+
108
+ // Linear
109
+ await rainfall.integrations.linear.issues.create({ title, teamId });
110
+ await rainfall.integrations.linear.teams.list();
111
+
112
+ // Slack
113
+ await rainfall.integrations.slack.messages.send({ channelId, text });
114
+ await rainfall.integrations.slack.channels.list();
115
+
116
+ // Figma
117
+ await rainfall.integrations.figma.files.get({ fileKey });
118
+ await rainfall.integrations.figma.files.getImages({ fileKey, nodeIds });
119
+
120
+ // Stripe
121
+ await rainfall.integrations.stripe.customers.create({ email });
122
+ await rainfall.integrations.stripe.paymentIntents.create({ amount, currency });
123
+ ```
124
+
125
+ ### Memory
126
+
127
+ ```typescript
128
+ // Create memory
129
+ await rainfall.memory.create({
130
+ content: 'Important information',
131
+ keywords: ['key', 'info'],
132
+ metadata: { source: 'user' }
133
+ });
134
+
135
+ // Recall by similarity
136
+ const memories = await rainfall.memory.recall({
137
+ query: 'important information',
138
+ topK: 10
139
+ });
140
+
141
+ // CRUD operations
142
+ await rainfall.memory.get({ memoryId: '...' });
143
+ await rainfall.memory.update({ memoryId: '...', content: 'Updated' });
144
+ await rainfall.memory.delete({ memoryId: '...' });
145
+ await rainfall.memory.list();
146
+ ```
147
+
148
+ ### Articles
149
+
150
+ ```typescript
151
+ // Search news
152
+ const articles = await rainfall.articles.search({
153
+ query: 'artificial intelligence',
154
+ limit: 10
155
+ });
156
+
157
+ // Create from URL
158
+ const article = await rainfall.articles.createFromUrl({ url });
159
+
160
+ // Summarize
161
+ const summary = await rainfall.articles.summarize({
162
+ text: article.content,
163
+ length: 'medium'
164
+ });
165
+
166
+ // Extract topics
167
+ const topics = await rainfall.articles.extractTopics({ text });
168
+ ```
169
+
170
+ ### Web
171
+
172
+ ```typescript
173
+ // Search
174
+ const exaResults = await rainfall.web.search.exa({ query: '...' });
175
+ const perplexityResults = await rainfall.web.search.perplexity({ query: '...' });
176
+
177
+ // Fetch and convert
178
+ const html = await rainfall.web.fetch({ url: 'https://example.com' });
179
+ const markdown = await rainfall.web.htmlToMarkdown({ html });
180
+
181
+ // Extract elements
182
+ const links = await rainfall.web.extractHtml({
183
+ html,
184
+ selector: 'a[href]'
185
+ });
186
+ ```
187
+
188
+ ### AI
189
+
190
+ ```typescript
191
+ // Embeddings
192
+ const docEmbedding = await rainfall.ai.embeddings.document({ text });
193
+ const queryEmbedding = await rainfall.ai.embeddings.query({ text });
194
+ const imageEmbedding = await rainfall.ai.embeddings.image({ imageBase64 });
195
+
196
+ // Image generation
197
+ const image = await rainfall.ai.image.generate({
198
+ prompt: 'A serene mountain landscape',
199
+ size: '1024x1024'
200
+ });
201
+
202
+ // OCR and Vision
203
+ const text = await rainfall.ai.ocr({ imageBase64 });
204
+ const analysis = await rainfall.ai.vision({
205
+ imageBase64,
206
+ prompt: 'Describe this image'
207
+ });
208
+
209
+ // Chat and completion
210
+ const response = await rainfall.ai.chat({
211
+ messages: [{ role: 'user', content: 'Hello!' }],
212
+ model: 'grok-2'
213
+ });
214
+
215
+ const completion = await rainfall.ai.complete({
216
+ prompt: 'The quick brown',
217
+ suffix: 'jumps over the lazy dog'
218
+ });
219
+
220
+ // Classification and segmentation
221
+ const classification = await rainfall.ai.classify({
222
+ text: 'This is great!',
223
+ labels: ['positive', 'negative', 'neutral']
224
+ });
225
+
226
+ const segments = await rainfall.ai.segment({
227
+ text: longText,
228
+ maxLength: 500
229
+ });
230
+ ```
231
+
232
+ ### Data
233
+
234
+ ```typescript
235
+ // CSV operations
236
+ const results = await rainfall.data.csv.query({
237
+ sql: 'SELECT * FROM data WHERE value > 100'
238
+ });
239
+
240
+ await rainfall.data.csv.convert({
241
+ data: csvData,
242
+ fromFormat: 'csv',
243
+ toFormat: 'json'
244
+ });
245
+
246
+ // Scripts
247
+ await rainfall.data.scripts.create({
248
+ name: 'process-data',
249
+ code: 'return input.map(x => x * 2);',
250
+ language: 'javascript'
251
+ });
252
+
253
+ const result = await rainfall.data.scripts.execute({
254
+ name: 'process-data',
255
+ params: { input: [1, 2, 3] }
256
+ });
257
+
258
+ await rainfall.data.scripts.list();
259
+ await rainfall.data.scripts.update({ name, code });
260
+ await rainfall.data.scripts.delete({ name });
261
+
262
+ // Similarity search
263
+ const matches = await rainfall.data.similarity.search({
264
+ query: embedding,
265
+ embeddings: corpus,
266
+ topK: 5
267
+ });
268
+ ```
269
+
270
+ ### Utils
271
+
272
+ ```typescript
273
+ // Mermaid diagrams
274
+ const diagram = await rainfall.utils.mermaid({
275
+ diagram: `
276
+ graph TD
277
+ A[Start] --> B{Decision}
278
+ B -->|Yes| C[Action 1]
279
+ B -->|No| D[Action 2]
280
+ `
281
+ });
282
+
283
+ // Document conversion
284
+ const pdf = await rainfall.utils.documentConvert({
285
+ document: markdownContent,
286
+ mimeType: 'text/markdown',
287
+ format: 'pdf'
288
+ });
289
+
290
+ // Regex
291
+ const matches = await rainfall.utils.regex.match({
292
+ text: 'Hello 123 world',
293
+ pattern: '\\d+',
294
+ flags: 'g'
295
+ });
296
+
297
+ const replaced = await rainfall.utils.regex.replace({
298
+ text: 'Hello world',
299
+ pattern: 'world',
300
+ replacement: 'universe'
301
+ });
302
+
303
+ // JSON extraction
304
+ const json = await rainfall.utils.jsonExtract({
305
+ text: 'Data: {"key": "value"}'
306
+ });
307
+
308
+ // Digest
309
+ const hash = await rainfall.utils.digest({ data: 'text to hash' });
310
+
311
+ // Monte Carlo simulation
312
+ const simulation = await rainfall.utils.monteCarlo({
313
+ iterations: 10000,
314
+ formula: 'price * (1 + return)',
315
+ variables: {
316
+ return: { mean: 0.08, stdDev: 0.16 }
317
+ }
318
+ });
319
+ ```
320
+
321
+ ## Error Handling
322
+
323
+ ```typescript
324
+ import { Rainfall, RateLimitError, AuthenticationError, NotFoundError } from '@rainfall/sdk';
325
+
326
+ try {
327
+ await rainfall.integrations.github.issues.get({ owner, repo, issue_number: 999999 });
328
+ } catch (error) {
329
+ if (error instanceof RateLimitError) {
330
+ console.log(`Rate limited. Retry after ${error.retryAfter}s`);
331
+ console.log(`Remaining: ${error.remaining}/${error.limit}`);
332
+ } else if (error instanceof AuthenticationError) {
333
+ console.log('Invalid API key');
334
+ } else if (error instanceof NotFoundError) {
335
+ console.log(`Resource not found: ${error.message}`);
336
+ } else {
337
+ console.log('Unexpected error:', error);
338
+ }
339
+ }
340
+ ```
341
+
342
+ ## MCP Server
343
+
344
+ Use Rainfall with Claude, Cursor, and other MCP-compatible assistants:
345
+
346
+ ```typescript
347
+ import { createRainfallMCPServer } from '@rainfall/sdk/mcp';
348
+
349
+ const server = createRainfallMCPServer({
350
+ apiKey: process.env.RAINFALL_API_KEY!
351
+ });
352
+
353
+ await server.start();
354
+ ```
355
+
356
+ Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):
357
+
358
+ ```json
359
+ {
360
+ "mcpServers": {
361
+ "rainfall": {
362
+ "command": "npx",
363
+ "args": ["-y", "@rainfall/sdk/mcp"],
364
+ "env": {
365
+ "RAINFALL_API_KEY": "your-api-key"
366
+ }
367
+ }
368
+ }
369
+ }
370
+ ```
371
+
372
+ ## Configuration
373
+
374
+ ```typescript
375
+ const rainfall = new Rainfall({
376
+ apiKey: 'your-api-key',
377
+ baseUrl: 'https://custom-endpoint.com/v1', // Optional
378
+ timeout: 60000, // Request timeout in ms (default: 30000)
379
+ retries: 5, // Number of retries (default: 3)
380
+ retryDelay: 2000 // Initial retry delay in ms (default: 1000)
381
+ });
382
+ ```
383
+
384
+ ## Rate Limiting
385
+
386
+ The SDK automatically handles rate limiting with exponential backoff:
387
+
388
+ ```typescript
389
+ // Check rate limit info
390
+ const info = rainfall.getRateLimitInfo();
391
+ console.log(info);
392
+ // { limit: 1000, remaining: 950, resetAt: Date }
393
+ ```
394
+
395
+ ## Examples
396
+
397
+ ### GitHub to Notion Sync
398
+
399
+ ```typescript
400
+ // Get GitHub issues
401
+ const issues = await rainfall.integrations.github.issues.list({
402
+ owner: 'myorg',
403
+ repo: 'myrepo',
404
+ state: 'open'
405
+ });
406
+
407
+ // Create Notion pages for each issue
408
+ for (const issue of issues) {
409
+ await rainfall.integrations.notion.pages.create({
410
+ parent: { database_id: 'my-database-id' },
411
+ properties: {
412
+ Name: { title: [{ text: { content: issue.title } }] },
413
+ 'Issue URL': { url: issue.html_url },
414
+ Status: { select: { name: issue.state } }
415
+ }
416
+ });
417
+ }
418
+ ```
419
+
420
+ ### PDF to Estimate
421
+
422
+ ```typescript
423
+ // Fetch PDF
424
+ const response = await fetch('https://example.com/quote.pdf');
425
+ const buffer = await response.arrayBuffer();
426
+ const base64 = Buffer.from(buffer).toString('base64');
427
+
428
+ // Extract text with OCR
429
+ const { text } = await rainfall.ai.ocr({ imageBase64: base64 });
430
+
431
+ // Extract structured data
432
+ const estimate = await rainfall.ai.complete({
433
+ prompt: `Extract line items from this quote:\n\n${text}\n\nJSON format:`,
434
+ suffix: ''
435
+ });
436
+
437
+ console.log(JSON.parse(estimate));
438
+ ```
439
+
440
+ ### Memory Agent
441
+
442
+ ```typescript
443
+ // Store conversation context
444
+ await rainfall.memory.create({
445
+ content: `User asked about pricing. Explained $9/mo for 100k calls.`,
446
+ keywords: ['pricing', 'conversation'],
447
+ metadata: { userId: 'user-123', timestamp: Date.now() }
448
+ });
449
+
450
+ // Later, recall relevant context
451
+ const context = await rainfall.memory.recall({
452
+ query: 'What did I tell the user about pricing?',
453
+ topK: 3
454
+ });
455
+
456
+ // Use context in response
457
+ const response = await rainfall.ai.chat({
458
+ messages: [
459
+ { role: 'system', content: 'Previous context: ' + JSON.stringify(context) },
460
+ { role: 'user', content: 'What was our pricing again?' }
461
+ ]
462
+ });
463
+ ```
464
+
465
+ ## License
466
+
467
+ MIT © Pragma Digital