@xano/developer-mcp 1.0.21 → 1.0.22
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 +100 -19
- package/dist/index.js +4 -242
- package/dist/meta_api_docs/format.d.ts +16 -1
- package/dist/meta_api_docs/format.js +24 -6
- package/dist/meta_api_docs/format.test.d.ts +1 -0
- package/dist/meta_api_docs/format.test.js +274 -0
- package/dist/meta_api_docs/index.test.d.ts +1 -0
- package/dist/meta_api_docs/index.test.js +128 -0
- package/dist/meta_api_docs/types.test.d.ts +1 -0
- package/dist/meta_api_docs/types.test.js +132 -0
- package/dist/run_api_docs/format.d.ts +1 -0
- package/dist/run_api_docs/format.js +3 -170
- package/dist/run_api_docs/format.test.d.ts +1 -0
- package/dist/run_api_docs/format.test.js +86 -0
- package/dist/run_api_docs/index.test.d.ts +1 -0
- package/dist/run_api_docs/index.test.js +127 -0
- package/dist/xanoscript.d.ts +41 -0
- package/dist/xanoscript.js +261 -0
- package/dist/xanoscript.test.d.ts +1 -0
- package/dist/xanoscript.test.js +303 -0
- package/dist/xanoscript_docs/README.md +2 -0
- package/dist/xanoscript_docs/agents.md +1 -1
- package/dist/xanoscript_docs/functions.md +4 -4
- package/dist/xanoscript_docs/integrations.md +43 -1
- package/dist/xanoscript_docs/performance.md +1 -1
- package/dist/xanoscript_docs/tasks.md +2 -2
- package/dist/xanoscript_docs/tools.md +2 -2
- package/dist/xanoscript_docs_auto/README.md +119 -0
- package/dist/xanoscript_docs_auto/agents.md +446 -0
- package/dist/xanoscript_docs_auto/apis.md +517 -0
- package/dist/xanoscript_docs_auto/control-flow.md +543 -0
- package/dist/xanoscript_docs_auto/database.md +551 -0
- package/dist/xanoscript_docs_auto/debugging.md +527 -0
- package/dist/xanoscript_docs_auto/filters.md +464 -0
- package/dist/xanoscript_docs_auto/functions.md +431 -0
- package/dist/xanoscript_docs_auto/integrations.md +657 -0
- package/dist/xanoscript_docs_auto/mcp-servers.md +408 -0
- package/dist/xanoscript_docs_auto/operators.md +368 -0
- package/dist/xanoscript_docs_auto/syntax.md +287 -0
- package/dist/xanoscript_docs_auto/tables.md +447 -0
- package/dist/xanoscript_docs_auto/tasks.md +479 -0
- package/dist/xanoscript_docs_auto/testing.md +574 -0
- package/dist/xanoscript_docs_auto/tools.md +485 -0
- package/dist/xanoscript_docs_auto/triggers.md +595 -0
- package/dist/xanoscript_docs_auto/types.md +323 -0
- package/dist/xanoscript_docs_auto/variables.md +462 -0
- package/dist/xanoscript_docs_auto/version.json +5 -0
- package/package.json +6 -2
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "tasks/*.xs"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Tasks
|
|
6
|
+
|
|
7
|
+
Scheduled and cron jobs for automated operations.
|
|
8
|
+
|
|
9
|
+
## Quick Reference
|
|
10
|
+
|
|
11
|
+
```xs
|
|
12
|
+
task "<name>" {
|
|
13
|
+
stack {
|
|
14
|
+
// Task logic
|
|
15
|
+
}
|
|
16
|
+
schedule {
|
|
17
|
+
events = [
|
|
18
|
+
{starts_on: 2025-01-01 00:00:00+0000, freq: 86400}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Task Definition
|
|
27
|
+
|
|
28
|
+
### Basic Task
|
|
29
|
+
|
|
30
|
+
```xs
|
|
31
|
+
task "daily_cleanup" {
|
|
32
|
+
stack {
|
|
33
|
+
// Delete old sessions
|
|
34
|
+
db.bulk.delete session {
|
|
35
|
+
where = $db.session.expires_at < now
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
debug.log { value = "Cleanup completed" }
|
|
39
|
+
}
|
|
40
|
+
schedule {
|
|
41
|
+
events = [
|
|
42
|
+
{starts_on: 2025-01-01 02:00:00+0000, freq: 86400}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Task with Logic
|
|
49
|
+
|
|
50
|
+
```xs
|
|
51
|
+
task "send_reminders" {
|
|
52
|
+
stack {
|
|
53
|
+
// Find users with pending items
|
|
54
|
+
db.query user {
|
|
55
|
+
where = $db.user.has_pending == true
|
|
56
|
+
&& $db.user.reminder_sent_at < now|transform_timestamp:"-1 day"
|
|
57
|
+
} as $users
|
|
58
|
+
|
|
59
|
+
foreach ($users) {
|
|
60
|
+
each as $user {
|
|
61
|
+
// Send reminder email
|
|
62
|
+
util.send_email {
|
|
63
|
+
to = $user.email
|
|
64
|
+
subject = "You have pending items"
|
|
65
|
+
body = "Please review your pending items."
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Update reminder timestamp
|
|
69
|
+
db.patch user {
|
|
70
|
+
field_name = "id"
|
|
71
|
+
field_value = $user.id
|
|
72
|
+
data = {reminder_sent_at: now}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
schedule {
|
|
78
|
+
events = [
|
|
79
|
+
{starts_on: 2025-01-01 09:00:00+0000, freq: 86400}
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Schedule Configuration
|
|
88
|
+
|
|
89
|
+
### Frequency Values (in seconds)
|
|
90
|
+
|
|
91
|
+
| Interval | Seconds | Example |
|
|
92
|
+
|----------|---------|---------|
|
|
93
|
+
| Every minute | 60 | `freq: 60` |
|
|
94
|
+
| Every 5 minutes | 300 | `freq: 300` |
|
|
95
|
+
| Every 15 minutes | 900 | `freq: 900` |
|
|
96
|
+
| Every hour | 3600 | `freq: 3600` |
|
|
97
|
+
| Every 6 hours | 21600 | `freq: 21600` |
|
|
98
|
+
| Every 12 hours | 43200 | `freq: 43200` |
|
|
99
|
+
| Daily | 86400 | `freq: 86400` |
|
|
100
|
+
| Weekly | 604800 | `freq: 604800` |
|
|
101
|
+
|
|
102
|
+
### Schedule Examples
|
|
103
|
+
|
|
104
|
+
```xs
|
|
105
|
+
// Run every minute
|
|
106
|
+
schedule {
|
|
107
|
+
events = [
|
|
108
|
+
{starts_on: 2025-01-01 00:00:00+0000, freq: 60}
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Run every hour
|
|
113
|
+
schedule {
|
|
114
|
+
events = [
|
|
115
|
+
{starts_on: 2025-01-01 00:00:00+0000, freq: 3600}
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Run daily at 3 AM UTC
|
|
120
|
+
schedule {
|
|
121
|
+
events = [
|
|
122
|
+
{starts_on: 2025-01-01 03:00:00+0000, freq: 86400}
|
|
123
|
+
]
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Run weekly on Mondays at 9 AM
|
|
127
|
+
schedule {
|
|
128
|
+
events = [
|
|
129
|
+
{starts_on: 2025-01-06 09:00:00+0000, freq: 604800}
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Multiple Schedules
|
|
135
|
+
|
|
136
|
+
Run at different times:
|
|
137
|
+
|
|
138
|
+
```xs
|
|
139
|
+
schedule {
|
|
140
|
+
events = [
|
|
141
|
+
{starts_on: 2025-01-01 09:00:00+0000, freq: 86400}, // 9 AM daily
|
|
142
|
+
{starts_on: 2025-01-01 17:00:00+0000, freq: 86400} // 5 PM daily
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### End Date
|
|
148
|
+
|
|
149
|
+
Schedule with an end date:
|
|
150
|
+
|
|
151
|
+
```xs
|
|
152
|
+
schedule {
|
|
153
|
+
events = [
|
|
154
|
+
{
|
|
155
|
+
starts_on: 2025-01-01 00:00:00+0000,
|
|
156
|
+
ends_on: 2025-12-31 23:59:59+0000,
|
|
157
|
+
freq: 86400
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Common Task Patterns
|
|
166
|
+
|
|
167
|
+
### Data Cleanup
|
|
168
|
+
|
|
169
|
+
```xs
|
|
170
|
+
task "cleanup_old_data" {
|
|
171
|
+
stack {
|
|
172
|
+
// Delete old logs
|
|
173
|
+
db.bulk.delete log {
|
|
174
|
+
where = $db.log.created_at < now|transform_timestamp:"-90 days"
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Delete expired tokens
|
|
178
|
+
db.bulk.delete token {
|
|
179
|
+
where = $db.token.expires_at < now
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Archive old orders
|
|
183
|
+
db.query order {
|
|
184
|
+
where = $db.order.status == "completed"
|
|
185
|
+
&& $db.order.created_at < now|transform_timestamp:"-1 year"
|
|
186
|
+
} as $old_orders
|
|
187
|
+
|
|
188
|
+
foreach ($old_orders) {
|
|
189
|
+
each as $order {
|
|
190
|
+
// Move to archive table
|
|
191
|
+
db.add order_archive {
|
|
192
|
+
data = $order
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Delete from main table
|
|
196
|
+
db.del order {
|
|
197
|
+
field_name = "id"
|
|
198
|
+
field_value = $order.id
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
schedule {
|
|
204
|
+
events = [
|
|
205
|
+
{starts_on: 2025-01-01 02:00:00+0000, freq: 86400}
|
|
206
|
+
]
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Report Generation
|
|
212
|
+
|
|
213
|
+
```xs
|
|
214
|
+
task "daily_sales_report" {
|
|
215
|
+
stack {
|
|
216
|
+
var $yesterday {
|
|
217
|
+
value = now|transform_timestamp:"-1 day"|format_timestamp:"Y-m-d":"UTC"
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Get sales data
|
|
221
|
+
db.query order {
|
|
222
|
+
where = $db.order.created_at|format_timestamp:"Y-m-d":"UTC" == $yesterday
|
|
223
|
+
&& $db.order.status == "completed"
|
|
224
|
+
} as $orders
|
|
225
|
+
|
|
226
|
+
// Calculate totals
|
|
227
|
+
var $total_revenue {
|
|
228
|
+
value = $orders|map:$$.total|sum
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
var $order_count {
|
|
232
|
+
value = $orders|count
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Save report
|
|
236
|
+
db.add daily_report {
|
|
237
|
+
data = {
|
|
238
|
+
date: $yesterday,
|
|
239
|
+
order_count: $order_count,
|
|
240
|
+
total_revenue: $total_revenue,
|
|
241
|
+
created_at: now
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Send email
|
|
246
|
+
util.send_email {
|
|
247
|
+
to = $env.ADMIN_EMAIL
|
|
248
|
+
subject = "Daily Sales Report - " ~ $yesterday
|
|
249
|
+
body = "Orders: " ~ $order_count ~ "\nRevenue: $" ~ $total_revenue
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
schedule {
|
|
253
|
+
events = [
|
|
254
|
+
{starts_on: 2025-01-01 06:00:00+0000, freq: 86400}
|
|
255
|
+
]
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### External API Sync
|
|
261
|
+
|
|
262
|
+
```xs
|
|
263
|
+
task "sync_inventory" {
|
|
264
|
+
stack {
|
|
265
|
+
// Fetch from external API
|
|
266
|
+
api.request {
|
|
267
|
+
url = $env.INVENTORY_API_URL
|
|
268
|
+
method = "GET"
|
|
269
|
+
headers = {
|
|
270
|
+
"Authorization": "Bearer " ~ $env.INVENTORY_API_KEY
|
|
271
|
+
}
|
|
272
|
+
} as $external_data
|
|
273
|
+
|
|
274
|
+
// Update local products
|
|
275
|
+
foreach ($external_data.products) {
|
|
276
|
+
each as $product {
|
|
277
|
+
db.add_or_edit product {
|
|
278
|
+
field_name = "sku"
|
|
279
|
+
field_value = $product.sku
|
|
280
|
+
data = {
|
|
281
|
+
sku: $product.sku,
|
|
282
|
+
stock: $product.quantity,
|
|
283
|
+
price: $product.price,
|
|
284
|
+
synced_at: now
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
debug.log {
|
|
291
|
+
value = "Synced " ~ ($external_data.products|count) ~ " products"
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
schedule {
|
|
295
|
+
events = [
|
|
296
|
+
{starts_on: 2025-01-01 00:00:00+0000, freq: 3600} // Hourly
|
|
297
|
+
]
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Send Notifications
|
|
303
|
+
|
|
304
|
+
```xs
|
|
305
|
+
task "send_scheduled_notifications" {
|
|
306
|
+
stack {
|
|
307
|
+
// Find pending notifications
|
|
308
|
+
db.query notification {
|
|
309
|
+
where = $db.notification.send_at <= now
|
|
310
|
+
&& $db.notification.sent == false
|
|
311
|
+
return = {type: "list", paging: {per_page: 100}}
|
|
312
|
+
} as $notifications
|
|
313
|
+
|
|
314
|
+
foreach ($notifications) {
|
|
315
|
+
each as $notification {
|
|
316
|
+
try_catch {
|
|
317
|
+
try {
|
|
318
|
+
util.send_email {
|
|
319
|
+
to = $notification.email
|
|
320
|
+
subject = $notification.subject
|
|
321
|
+
body = $notification.body
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Mark as sent
|
|
325
|
+
db.patch notification {
|
|
326
|
+
field_name = "id"
|
|
327
|
+
field_value = $notification.id
|
|
328
|
+
data = {sent: true, sent_at: now}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
catch {
|
|
332
|
+
// Mark failed
|
|
333
|
+
db.patch notification {
|
|
334
|
+
field_name = "id"
|
|
335
|
+
field_value = $notification.id
|
|
336
|
+
data = {
|
|
337
|
+
error: $error.message,
|
|
338
|
+
retry_count: $notification.retry_count + 1
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
schedule {
|
|
347
|
+
events = [
|
|
348
|
+
{starts_on: 2025-01-01 00:00:00+0000, freq: 60} // Every minute
|
|
349
|
+
]
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### Subscription Billing
|
|
355
|
+
|
|
356
|
+
```xs
|
|
357
|
+
task "process_subscriptions" {
|
|
358
|
+
stack {
|
|
359
|
+
// Find subscriptions due for billing
|
|
360
|
+
db.query subscription {
|
|
361
|
+
where = $db.subscription.next_billing_date <= now
|
|
362
|
+
&& $db.subscription.status == "active"
|
|
363
|
+
} as $subscriptions
|
|
364
|
+
|
|
365
|
+
foreach ($subscriptions) {
|
|
366
|
+
each as $sub {
|
|
367
|
+
try_catch {
|
|
368
|
+
try {
|
|
369
|
+
// Process payment
|
|
370
|
+
function.run "charge_subscription" {
|
|
371
|
+
input = {subscription_id: $sub.id}
|
|
372
|
+
} as $payment
|
|
373
|
+
|
|
374
|
+
// Update next billing date
|
|
375
|
+
db.patch subscription {
|
|
376
|
+
field_name = "id"
|
|
377
|
+
field_value = $sub.id
|
|
378
|
+
data = {
|
|
379
|
+
next_billing_date: $sub.next_billing_date|transform_timestamp:"+1 month",
|
|
380
|
+
last_billed_at: now
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
catch {
|
|
385
|
+
// Handle failed payment
|
|
386
|
+
db.patch subscription {
|
|
387
|
+
field_name = "id"
|
|
388
|
+
field_value = $sub.id
|
|
389
|
+
data = {
|
|
390
|
+
status: "past_due",
|
|
391
|
+
billing_error: $error.message
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
schedule {
|
|
400
|
+
events = [
|
|
401
|
+
{starts_on: 2025-01-01 00:00:00+0000, freq: 3600}
|
|
402
|
+
]
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
## Error Handling in Tasks
|
|
410
|
+
|
|
411
|
+
```xs
|
|
412
|
+
task "critical_task" {
|
|
413
|
+
stack {
|
|
414
|
+
try_catch {
|
|
415
|
+
try {
|
|
416
|
+
// Main task logic
|
|
417
|
+
function.run "important_operation" {} as $result
|
|
418
|
+
}
|
|
419
|
+
catch {
|
|
420
|
+
// Log error
|
|
421
|
+
db.add task_error {
|
|
422
|
+
data = {
|
|
423
|
+
task: "critical_task",
|
|
424
|
+
error: $error.message,
|
|
425
|
+
created_at: now
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// Alert admin
|
|
430
|
+
util.send_email {
|
|
431
|
+
to = $env.ADMIN_EMAIL
|
|
432
|
+
subject = "Task Failed: critical_task"
|
|
433
|
+
body = "Error: " ~ $error.message
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
schedule {
|
|
439
|
+
events = [
|
|
440
|
+
{starts_on: 2025-01-01 00:00:00+0000, freq: 3600}
|
|
441
|
+
]
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
## Testing Tasks
|
|
449
|
+
|
|
450
|
+
```xs
|
|
451
|
+
task "process_data" {
|
|
452
|
+
stack {
|
|
453
|
+
db.query data {} as $data
|
|
454
|
+
// Processing logic
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
test "processes empty data" {
|
|
458
|
+
task.call {
|
|
459
|
+
mock = {
|
|
460
|
+
"db.query data": []
|
|
461
|
+
}
|
|
462
|
+
} as $result
|
|
463
|
+
|
|
464
|
+
expect.to_be_true { input = true }
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
test "processes sample data" {
|
|
468
|
+
task.call {
|
|
469
|
+
mock = {
|
|
470
|
+
"db.query data": [{id: 1, value: 100}]
|
|
471
|
+
}
|
|
472
|
+
} as $result
|
|
473
|
+
|
|
474
|
+
expect.to_equal { input = $result.processed, value = 1 }
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
schedule { ... }
|
|
478
|
+
}
|
|
479
|
+
```
|