@xano/developer-mcp 1.0.34 → 1.0.36
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 +17 -2
- package/dist/tools/index.d.ts +2 -15
- package/dist/tools/index.js +2 -2
- package/dist/tools/validate_xanoscript.d.ts +84 -9
- package/dist/tools/validate_xanoscript.js +345 -31
- package/dist/xanoscript.js +31 -1
- package/dist/xanoscript.test.js +6 -0
- package/dist/xanoscript_docs/README.md +56 -43
- package/dist/xanoscript_docs/addons.md +10 -0
- package/dist/xanoscript_docs/agents.md +15 -0
- package/dist/xanoscript_docs/apis.md +45 -24
- package/dist/xanoscript_docs/cheatsheet.md +252 -0
- package/dist/xanoscript_docs/database.md +37 -0
- package/dist/xanoscript_docs/docs_index.json +236 -0
- package/dist/xanoscript_docs/frontend.md +10 -0
- package/dist/xanoscript_docs/functions.md +18 -0
- package/dist/xanoscript_docs/integrations/cloud-storage.md +142 -0
- package/dist/xanoscript_docs/integrations/external-apis.md +201 -0
- package/dist/xanoscript_docs/integrations/redis.md +194 -0
- package/dist/xanoscript_docs/integrations/search.md +242 -0
- package/dist/xanoscript_docs/integrations/utilities.md +331 -0
- package/dist/xanoscript_docs/integrations.md +55 -901
- package/dist/xanoscript_docs/mcp-servers.md +10 -0
- package/dist/xanoscript_docs/performance.md +15 -0
- package/dist/xanoscript_docs/quickstart.md +288 -41
- package/dist/xanoscript_docs/run.md +10 -0
- package/dist/xanoscript_docs/security.md +26 -0
- package/dist/xanoscript_docs/streaming.md +10 -0
- package/dist/xanoscript_docs/syntax.md +78 -0
- package/dist/xanoscript_docs/tables.md +15 -0
- package/dist/xanoscript_docs/tasks.md +11 -0
- package/dist/xanoscript_docs/tools.md +15 -0
- package/dist/xanoscript_docs/triggers.md +57 -192
- package/dist/xanoscript_docs/types.md +18 -0
- package/package.json +1 -1
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "function/**/*.xs, api/**/*.xs, task/**/*.xs"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Redis Integration
|
|
6
|
+
|
|
7
|
+
> **TL;DR:** `redis.*` for caching, counters, lists, and rate limiting. Key-value storage with TTL support.
|
|
8
|
+
|
|
9
|
+
## Quick Reference
|
|
10
|
+
|
|
11
|
+
| Operation | Purpose |
|
|
12
|
+
|-----------|---------|
|
|
13
|
+
| `redis.set` | Store value with optional TTL |
|
|
14
|
+
| `redis.get` | Retrieve value |
|
|
15
|
+
| `redis.has` | Check if key exists |
|
|
16
|
+
| `redis.del` | Delete key |
|
|
17
|
+
| `redis.incr` / `redis.decr` | Increment/decrement counters |
|
|
18
|
+
| `redis.push` / `redis.pop` | List operations (end) |
|
|
19
|
+
| `redis.unshift` / `redis.shift` | List operations (front) |
|
|
20
|
+
| `redis.range` | Get list range |
|
|
21
|
+
| `redis.count` | Get list length |
|
|
22
|
+
| `redis.ratelimit` | Rate limiting |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Key-Value Operations
|
|
27
|
+
|
|
28
|
+
```xs
|
|
29
|
+
// Set value
|
|
30
|
+
redis.set {
|
|
31
|
+
key = "user:123:session"
|
|
32
|
+
data = $session_data
|
|
33
|
+
ttl = 3600 // Expires in 1 hour
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Get value
|
|
37
|
+
redis.get { key = "user:123:session" } as $session
|
|
38
|
+
|
|
39
|
+
// Check exists
|
|
40
|
+
redis.has { key = "user:123:session" } as $exists
|
|
41
|
+
|
|
42
|
+
// Delete
|
|
43
|
+
redis.del { key = "user:123:session" }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Counters
|
|
49
|
+
|
|
50
|
+
```xs
|
|
51
|
+
# Increment
|
|
52
|
+
redis.incr {
|
|
53
|
+
key = "page_views"
|
|
54
|
+
by = 1
|
|
55
|
+
} as $new_count
|
|
56
|
+
|
|
57
|
+
# Decrement
|
|
58
|
+
redis.decr {
|
|
59
|
+
key = "inventory:item-123"
|
|
60
|
+
by = 1
|
|
61
|
+
} as $new_count
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Lists
|
|
67
|
+
|
|
68
|
+
```xs
|
|
69
|
+
# Push to end
|
|
70
|
+
redis.push {
|
|
71
|
+
key = "queue:tasks"
|
|
72
|
+
value = $task
|
|
73
|
+
} as $length
|
|
74
|
+
|
|
75
|
+
# Push to front
|
|
76
|
+
redis.unshift {
|
|
77
|
+
key = "queue:priority"
|
|
78
|
+
value = $urgent_task
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
# Pop from end
|
|
82
|
+
redis.pop { key = "queue:tasks" } as $task
|
|
83
|
+
|
|
84
|
+
# Pop from front
|
|
85
|
+
redis.shift { key = "queue:tasks" } as $task
|
|
86
|
+
|
|
87
|
+
# Get range
|
|
88
|
+
redis.range {
|
|
89
|
+
key = "recent:logs"
|
|
90
|
+
start = 0
|
|
91
|
+
stop = 9
|
|
92
|
+
} as $logs
|
|
93
|
+
|
|
94
|
+
# Count
|
|
95
|
+
redis.count { key = "queue:tasks" } as $count
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Rate Limiting
|
|
101
|
+
|
|
102
|
+
```xs
|
|
103
|
+
redis.ratelimit {
|
|
104
|
+
key = "api:" ~ $env.$remote_ip
|
|
105
|
+
max = 100
|
|
106
|
+
ttl = 60
|
|
107
|
+
error = "Rate limit exceeded"
|
|
108
|
+
} as $status
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Common Patterns
|
|
114
|
+
|
|
115
|
+
### Session Caching
|
|
116
|
+
|
|
117
|
+
```xs
|
|
118
|
+
// Store session
|
|
119
|
+
redis.set {
|
|
120
|
+
key = "session:" ~ $token
|
|
121
|
+
data = { user_id: $user.id, role: $user.role }
|
|
122
|
+
ttl = 86400 // 24 hours
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Retrieve session
|
|
126
|
+
redis.get { key = "session:" ~ $input.token } as $session
|
|
127
|
+
|
|
128
|
+
precondition ($session != null) {
|
|
129
|
+
error_type = "accessdenied"
|
|
130
|
+
error = "Invalid session"
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### API Response Caching
|
|
135
|
+
|
|
136
|
+
```xs
|
|
137
|
+
// Check cache first
|
|
138
|
+
redis.get { key = "cache:products:" ~ $input.category } as $cached
|
|
139
|
+
|
|
140
|
+
conditional {
|
|
141
|
+
if ($cached != null) {
|
|
142
|
+
var $products { value = $cached }
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
// Fetch from database
|
|
146
|
+
db.query "product" {
|
|
147
|
+
where = $db.product.category == $input.category
|
|
148
|
+
} as $products
|
|
149
|
+
|
|
150
|
+
// Cache for 5 minutes
|
|
151
|
+
redis.set {
|
|
152
|
+
key = "cache:products:" ~ $input.category
|
|
153
|
+
data = $products
|
|
154
|
+
ttl = 300
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Queue Processing
|
|
161
|
+
|
|
162
|
+
```xs
|
|
163
|
+
// Add to queue
|
|
164
|
+
redis.push {
|
|
165
|
+
key = "queue:emails"
|
|
166
|
+
value = { to: $user.email, subject: "Welcome", body: $message }
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Process queue (in a task)
|
|
170
|
+
redis.shift { key = "queue:emails" } as $email
|
|
171
|
+
|
|
172
|
+
conditional {
|
|
173
|
+
if ($email != null) {
|
|
174
|
+
util.send_email {
|
|
175
|
+
service_provider = "resend"
|
|
176
|
+
api_key = $env.RESEND_API_KEY
|
|
177
|
+
to = $email.to
|
|
178
|
+
from = "noreply@example.com"
|
|
179
|
+
subject = $email.subject
|
|
180
|
+
message = $email.body
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Related Topics
|
|
189
|
+
|
|
190
|
+
| Topic | Description |
|
|
191
|
+
|-------|-------------|
|
|
192
|
+
| `performance` | Caching strategies |
|
|
193
|
+
| `security` | Rate limiting patterns |
|
|
194
|
+
| `integrations` | All integrations index |
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "function/**/*.xs, api/**/*.xs, task/**/*.xs"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Search Integrations
|
|
6
|
+
|
|
7
|
+
> **TL;DR:** `cloud.elasticsearch.*` for Elasticsearch, `cloud.aws.opensearch.*` for AWS OpenSearch, `cloud.algolia.*` for Algolia. Full-text search, document operations, and bulk indexing.
|
|
8
|
+
|
|
9
|
+
## Quick Reference
|
|
10
|
+
|
|
11
|
+
| Provider | Prefix | Operations |
|
|
12
|
+
|----------|--------|------------|
|
|
13
|
+
| Elasticsearch | `cloud.elasticsearch.*` | query, document, bulk |
|
|
14
|
+
| AWS OpenSearch | `cloud.aws.opensearch.*` | query, document |
|
|
15
|
+
| Algolia | `cloud.algolia.*` | search, save_object, save_objects, delete_object, set_settings |
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Elasticsearch
|
|
20
|
+
|
|
21
|
+
### Search Query
|
|
22
|
+
|
|
23
|
+
```xs
|
|
24
|
+
cloud.elasticsearch.query {
|
|
25
|
+
auth_type = "API Key"
|
|
26
|
+
key_id = $env.ES_KEY_ID
|
|
27
|
+
access_key = $env.ES_ACCESS_KEY
|
|
28
|
+
base_url = "https://my-cluster.es.io"
|
|
29
|
+
index = "products"
|
|
30
|
+
return_type = "search"
|
|
31
|
+
expression = [{ field: "category", value: "electronics", op: "eq" }]
|
|
32
|
+
size = 10
|
|
33
|
+
sort = [{ field: "price", order: "asc" }]
|
|
34
|
+
} as $results
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Document Operations
|
|
38
|
+
|
|
39
|
+
```xs
|
|
40
|
+
// Get document
|
|
41
|
+
cloud.elasticsearch.document {
|
|
42
|
+
auth_type = "API Key"
|
|
43
|
+
key_id = $env.ES_KEY_ID
|
|
44
|
+
access_key = $env.ES_ACCESS_KEY
|
|
45
|
+
base_url = "https://my-cluster.es.io"
|
|
46
|
+
index = "products"
|
|
47
|
+
method = "GET"
|
|
48
|
+
doc_id = "product-123"
|
|
49
|
+
} as $doc
|
|
50
|
+
|
|
51
|
+
// Index document
|
|
52
|
+
cloud.elasticsearch.document {
|
|
53
|
+
auth_type = "API Key"
|
|
54
|
+
key_id = $env.ES_KEY_ID
|
|
55
|
+
access_key = $env.ES_ACCESS_KEY
|
|
56
|
+
base_url = "https://my-cluster.es.io"
|
|
57
|
+
index = "products"
|
|
58
|
+
method = "PUT"
|
|
59
|
+
doc_id = "product-123"
|
|
60
|
+
body = {
|
|
61
|
+
name: "Product Name",
|
|
62
|
+
category: "electronics",
|
|
63
|
+
price: 99.99
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Delete document
|
|
68
|
+
cloud.elasticsearch.document {
|
|
69
|
+
auth_type = "API Key"
|
|
70
|
+
key_id = $env.ES_KEY_ID
|
|
71
|
+
access_key = $env.ES_ACCESS_KEY
|
|
72
|
+
base_url = "https://my-cluster.es.io"
|
|
73
|
+
index = "products"
|
|
74
|
+
method = "DELETE"
|
|
75
|
+
doc_id = "product-123"
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Bulk Operations
|
|
80
|
+
|
|
81
|
+
```xs
|
|
82
|
+
cloud.elasticsearch.bulk {
|
|
83
|
+
auth_type = "API Key"
|
|
84
|
+
key_id = $env.ES_KEY_ID
|
|
85
|
+
access_key = $env.ES_ACCESS_KEY
|
|
86
|
+
base_url = "https://my-cluster.es.io"
|
|
87
|
+
index = "products"
|
|
88
|
+
operations = [
|
|
89
|
+
{ action: "index", id: "1", doc: { name: "Product 1" } },
|
|
90
|
+
{ action: "update", id: "2", doc: { price: 29.99 } },
|
|
91
|
+
{ action: "delete", id: "3" }
|
|
92
|
+
]
|
|
93
|
+
} as $result
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Advanced Search
|
|
97
|
+
|
|
98
|
+
```xs
|
|
99
|
+
cloud.elasticsearch.query {
|
|
100
|
+
auth_type = "API Key"
|
|
101
|
+
key_id = $env.ES_KEY_ID
|
|
102
|
+
access_key = $env.ES_ACCESS_KEY
|
|
103
|
+
base_url = "https://my-cluster.es.io"
|
|
104
|
+
index = "products"
|
|
105
|
+
return_type = "search"
|
|
106
|
+
query = {
|
|
107
|
+
bool: {
|
|
108
|
+
must: [
|
|
109
|
+
{ match: { name: $input.search } }
|
|
110
|
+
],
|
|
111
|
+
filter: [
|
|
112
|
+
{ range: { price: { gte: $input.min_price, lte: $input.max_price } } },
|
|
113
|
+
{ term: { is_active: true } }
|
|
114
|
+
]
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
aggregations = {
|
|
118
|
+
categories: { terms: { field: "category.keyword" } },
|
|
119
|
+
avg_price: { avg: { field: "price" } }
|
|
120
|
+
}
|
|
121
|
+
size = 20
|
|
122
|
+
from = $input.offset
|
|
123
|
+
} as $results
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## AWS OpenSearch
|
|
129
|
+
|
|
130
|
+
```xs
|
|
131
|
+
cloud.aws.opensearch.query {
|
|
132
|
+
region = "us-east-1"
|
|
133
|
+
access_key = $env.AWS_ACCESS_KEY
|
|
134
|
+
secret_key = $env.AWS_SECRET_KEY
|
|
135
|
+
endpoint = "https://search-domain.us-east-1.es.amazonaws.com"
|
|
136
|
+
index = "logs"
|
|
137
|
+
query = {
|
|
138
|
+
bool: {
|
|
139
|
+
must: [
|
|
140
|
+
{ match: { level: "error" } }
|
|
141
|
+
],
|
|
142
|
+
filter: [
|
|
143
|
+
{ range: { timestamp: { gte: "now-24h" } } }
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
size = 100
|
|
148
|
+
} as $logs
|
|
149
|
+
|
|
150
|
+
// Index document
|
|
151
|
+
cloud.aws.opensearch.document {
|
|
152
|
+
region = "us-east-1"
|
|
153
|
+
access_key = $env.AWS_ACCESS_KEY
|
|
154
|
+
secret_key = $env.AWS_SECRET_KEY
|
|
155
|
+
endpoint = "https://search-domain.us-east-1.es.amazonaws.com"
|
|
156
|
+
index = "logs"
|
|
157
|
+
method = "PUT"
|
|
158
|
+
doc_id = $log_id
|
|
159
|
+
body = $log_data
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Algolia
|
|
166
|
+
|
|
167
|
+
### Search
|
|
168
|
+
|
|
169
|
+
```xs
|
|
170
|
+
cloud.algolia.search {
|
|
171
|
+
app_id = $env.ALGOLIA_APP_ID
|
|
172
|
+
api_key = $env.ALGOLIA_API_KEY
|
|
173
|
+
index = "products"
|
|
174
|
+
query = $input.search
|
|
175
|
+
filters = "category:electronics AND price<100"
|
|
176
|
+
facets = ["category", "brand"]
|
|
177
|
+
hitsPerPage = 20
|
|
178
|
+
page = $input.page
|
|
179
|
+
} as $results
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Manage Records
|
|
183
|
+
|
|
184
|
+
```xs
|
|
185
|
+
// Add/update record
|
|
186
|
+
cloud.algolia.save_object {
|
|
187
|
+
app_id = $env.ALGOLIA_APP_ID
|
|
188
|
+
api_key = $env.ALGOLIA_ADMIN_KEY
|
|
189
|
+
index = "products"
|
|
190
|
+
object = {
|
|
191
|
+
objectID: $product.id|to_text,
|
|
192
|
+
name: $product.name,
|
|
193
|
+
category: $product.category,
|
|
194
|
+
price: $product.price
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Batch save
|
|
199
|
+
cloud.algolia.save_objects {
|
|
200
|
+
app_id = $env.ALGOLIA_APP_ID
|
|
201
|
+
api_key = $env.ALGOLIA_ADMIN_KEY
|
|
202
|
+
index = "products"
|
|
203
|
+
objects = $products|map:{
|
|
204
|
+
objectID: $$.id|to_text,
|
|
205
|
+
name: $$.name,
|
|
206
|
+
category: $$.category
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Delete record
|
|
211
|
+
cloud.algolia.delete_object {
|
|
212
|
+
app_id = $env.ALGOLIA_APP_ID
|
|
213
|
+
api_key = $env.ALGOLIA_ADMIN_KEY
|
|
214
|
+
index = "products"
|
|
215
|
+
objectID = $input.product_id|to_text
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Configure Index
|
|
220
|
+
|
|
221
|
+
```xs
|
|
222
|
+
cloud.algolia.set_settings {
|
|
223
|
+
app_id = $env.ALGOLIA_APP_ID
|
|
224
|
+
api_key = $env.ALGOLIA_ADMIN_KEY
|
|
225
|
+
index = "products"
|
|
226
|
+
settings = {
|
|
227
|
+
searchableAttributes: ["name", "description", "category"],
|
|
228
|
+
attributesForFaceting: ["category", "brand", "filterOnly(is_active)"],
|
|
229
|
+
ranking: ["typo", "geo", "words", "filters", "proximity", "attribute", "exact", "custom"]
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Related Topics
|
|
237
|
+
|
|
238
|
+
| Topic | Description |
|
|
239
|
+
|-------|-------------|
|
|
240
|
+
| `database` | Built-in database queries |
|
|
241
|
+
| `integrations` | All integrations index |
|
|
242
|
+
| `performance` | Caching search results |
|