@xano/developer-mcp 1.0.1 → 1.0.2

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.
Files changed (42) hide show
  1. package/README.md +96 -31
  2. package/dist/index.js +248 -180
  3. package/package.json +4 -2
  4. package/xanoscript_docs/README.md +107 -1
  5. package/xanoscript_docs/agents.md +329 -0
  6. package/xanoscript_docs/apis.md +343 -0
  7. package/xanoscript_docs/database.md +417 -0
  8. package/xanoscript_docs/ephemeral.md +333 -0
  9. package/xanoscript_docs/frontend.md +291 -0
  10. package/xanoscript_docs/functions.md +232 -2035
  11. package/xanoscript_docs/integrations.md +439 -0
  12. package/xanoscript_docs/mcp-servers.md +190 -0
  13. package/xanoscript_docs/plan.md +192 -0
  14. package/xanoscript_docs/syntax.md +314 -0
  15. package/xanoscript_docs/tables.md +270 -0
  16. package/xanoscript_docs/tasks.md +254 -0
  17. package/xanoscript_docs/testing.md +335 -0
  18. package/xanoscript_docs/tools.md +305 -0
  19. package/xanoscript_docs/types.md +297 -0
  20. package/xanoscript_docs/version.json +2 -1
  21. package/xanoscript_docs/api_query_examples.md +0 -1255
  22. package/xanoscript_docs/api_query_guideline.md +0 -129
  23. package/xanoscript_docs/build_from_lovable.md +0 -715
  24. package/xanoscript_docs/db_query_guideline.md +0 -427
  25. package/xanoscript_docs/ephemeral_environment_guideline.md +0 -529
  26. package/xanoscript_docs/expression_guideline.md +0 -1086
  27. package/xanoscript_docs/frontend_guideline.md +0 -67
  28. package/xanoscript_docs/function_examples.md +0 -1406
  29. package/xanoscript_docs/function_guideline.md +0 -130
  30. package/xanoscript_docs/input_guideline.md +0 -227
  31. package/xanoscript_docs/mcp_server_examples.md +0 -36
  32. package/xanoscript_docs/mcp_server_guideline.md +0 -69
  33. package/xanoscript_docs/query_filter.md +0 -489
  34. package/xanoscript_docs/table_examples.md +0 -586
  35. package/xanoscript_docs/table_guideline.md +0 -137
  36. package/xanoscript_docs/task_examples.md +0 -511
  37. package/xanoscript_docs/task_guideline.md +0 -103
  38. package/xanoscript_docs/tips_and_tricks.md +0 -144
  39. package/xanoscript_docs/tool_examples.md +0 -69
  40. package/xanoscript_docs/tool_guideline.md +0 -139
  41. package/xanoscript_docs/unit_testing_guideline.md +0 -328
  42. package/xanoscript_docs/workspace.md +0 -17
@@ -0,0 +1,343 @@
1
+ ---
2
+ applyTo: "apis/**/*.xs"
3
+ ---
4
+
5
+ # APIs
6
+
7
+ HTTP endpoint definitions in XanoScript.
8
+
9
+ ## Quick Reference
10
+
11
+ ```xs
12
+ query "<path>" verb=<METHOD> {
13
+ description = "What this endpoint does"
14
+ auth = "<table>" # Optional: require authentication
15
+ input { ... }
16
+ stack { ... }
17
+ response = $result
18
+ }
19
+ ```
20
+
21
+ ### HTTP Methods
22
+ `GET`, `POST`, `PUT`, `PATCH`, `DELETE`
23
+
24
+ ### File Structure
25
+ ```
26
+ apis/
27
+ ├── users/ # API group
28
+ │ ├── list.xs # GET /users
29
+ │ ├── create.xs # POST /users
30
+ │ └── {id}.xs # GET/PATCH/DELETE /users/{id}
31
+ └── products/
32
+ └── search.xs
33
+ ```
34
+
35
+ ---
36
+
37
+ ## Basic Structure
38
+
39
+ ```xs
40
+ query "products" verb=GET {
41
+ description = "List all products"
42
+ input {
43
+ int page?=1 filters=min:1
44
+ int per_page?=20 filters=min:1|max:100
45
+ }
46
+ stack {
47
+ db.query "product" {
48
+ return = { type: "list", paging: { page: $input.page, per_page: $input.per_page } }
49
+ } as $products
50
+ }
51
+ response = $products
52
+ }
53
+ ```
54
+
55
+ ---
56
+
57
+ ## Authentication
58
+
59
+ ### Public Endpoint (default)
60
+ ```xs
61
+ query "status" verb=GET {
62
+ stack { }
63
+ response = { status: "ok" }
64
+ }
65
+ ```
66
+
67
+ ### Authenticated Endpoint
68
+ ```xs
69
+ query "profile" verb=GET {
70
+ auth = "user" # Requires valid JWT
71
+ stack {
72
+ db.get "user" {
73
+ field_name = "id"
74
+ field_value = $auth.id # User ID from token
75
+ } as $user
76
+ }
77
+ response = $user
78
+ }
79
+ ```
80
+
81
+ When `auth` is set:
82
+ - Endpoint requires Bearer token in `Authorization` header
83
+ - `$auth.id` contains authenticated user's ID
84
+ - Invalid/missing token returns 401
85
+
86
+ ---
87
+
88
+ ## Path Parameters
89
+
90
+ Use `{param}` in the path:
91
+
92
+ ```xs
93
+ query "users/{user_id}" verb=GET {
94
+ auth = "user"
95
+ input {
96
+ int user_id { table = "user" }
97
+ }
98
+ stack {
99
+ db.get "user" {
100
+ field_name = "id"
101
+ field_value = $input.user_id
102
+ } as $user
103
+ }
104
+ response = $user
105
+ }
106
+ ```
107
+
108
+ ---
109
+
110
+ ## CRUD Examples
111
+
112
+ ### List (GET)
113
+ ```xs
114
+ query "products" verb=GET {
115
+ input {
116
+ text category? filters=trim|lower
117
+ int page?=1
118
+ int per_page?=20
119
+ }
120
+ stack {
121
+ db.query "product" {
122
+ where = $db.product.category ==? $input.category
123
+ sort = { created_at: "desc" }
124
+ return = { type: "list", paging: { page: $input.page, per_page: $input.per_page } }
125
+ } as $products
126
+ }
127
+ response = $products
128
+ }
129
+ ```
130
+
131
+ ### Create (POST)
132
+ ```xs
133
+ query "products" verb=POST {
134
+ auth = "user"
135
+ input {
136
+ text name filters=trim
137
+ text description? filters=trim
138
+ decimal price filters=min:0
139
+ int category_id { table = "category" }
140
+ }
141
+ stack {
142
+ db.add "product" {
143
+ data = {
144
+ name: $input.name,
145
+ description: $input.description,
146
+ price: $input.price,
147
+ category_id: $input.category_id,
148
+ created_by: $auth.id
149
+ }
150
+ } as $product
151
+ }
152
+ response = $product
153
+ }
154
+ ```
155
+
156
+ ### Read (GET with ID)
157
+ ```xs
158
+ query "products/{product_id}" verb=GET {
159
+ input {
160
+ int product_id { table = "product" }
161
+ }
162
+ stack {
163
+ db.get "product" {
164
+ field_name = "id"
165
+ field_value = $input.product_id
166
+ } as $product
167
+
168
+ precondition ($product != null) {
169
+ error_type = "notfound"
170
+ error = "Product not found"
171
+ }
172
+ }
173
+ response = $product
174
+ }
175
+ ```
176
+
177
+ ### Update (PATCH)
178
+ ```xs
179
+ query "products/{product_id}" verb=PATCH {
180
+ auth = "user"
181
+ input {
182
+ int product_id { table = "product" }
183
+ text name? filters=trim
184
+ text description? filters=trim
185
+ decimal price? filters=min:0
186
+ }
187
+ stack {
188
+ var $updates { value = {} }
189
+
190
+ conditional {
191
+ if ($input.name != null) {
192
+ var.update $updates { value = $updates|set:"name":$input.name }
193
+ }
194
+ }
195
+ conditional {
196
+ if ($input.price != null) {
197
+ var.update $updates { value = $updates|set:"price":$input.price }
198
+ }
199
+ }
200
+
201
+ db.patch "product" {
202
+ field_name = "id"
203
+ field_value = $input.product_id
204
+ data = $updates
205
+ } as $product
206
+ }
207
+ response = $product
208
+ }
209
+ ```
210
+
211
+ ### Delete (DELETE)
212
+ ```xs
213
+ query "products/{product_id}" verb=DELETE {
214
+ auth = "user"
215
+ input {
216
+ int product_id { table = "product" }
217
+ }
218
+ stack {
219
+ db.del "product" {
220
+ field_name = "id"
221
+ field_value = $input.product_id
222
+ }
223
+ }
224
+ response = { success: true }
225
+ }
226
+ ```
227
+
228
+ ---
229
+
230
+ ## Response Types
231
+
232
+ ### JSON (default)
233
+ ```xs
234
+ response = $data
235
+ ```
236
+
237
+ ### HTML
238
+ ```xs
239
+ stack {
240
+ util.set_header {
241
+ value = "Content-Type: text/html; charset=utf-8"
242
+ duplicates = "replace"
243
+ }
244
+
245
+ util.template_engine {
246
+ value = """
247
+ <html>
248
+ <body><h1>{{ $var.title }}</h1></body>
249
+ </html>
250
+ """
251
+ } as $html
252
+ }
253
+ response = $html
254
+ ```
255
+
256
+ ### Streaming
257
+ ```xs
258
+ stack {
259
+ api.stream { value = $processed_data }
260
+ }
261
+ response = null
262
+ ```
263
+
264
+ ---
265
+
266
+ ## Custom Headers
267
+
268
+ ```xs
269
+ stack {
270
+ util.set_header {
271
+ value = "X-Custom-Header: value"
272
+ duplicates = "replace"
273
+ }
274
+
275
+ util.set_header {
276
+ value = "Set-Cookie: session=abc123; HttpOnly; Secure"
277
+ duplicates = "add"
278
+ }
279
+ }
280
+ ```
281
+
282
+ ---
283
+
284
+ ## Error Handling
285
+
286
+ ### Preconditions
287
+ ```xs
288
+ stack {
289
+ precondition ($input.amount > 0) {
290
+ error_type = "inputerror"
291
+ error = "Amount must be positive"
292
+ }
293
+
294
+ precondition ($user != null) {
295
+ error_type = "notfound"
296
+ error = "User not found"
297
+ }
298
+
299
+ precondition ($user.id == $auth.id) {
300
+ error_type = "accessdenied"
301
+ error = "Not authorized"
302
+ }
303
+ }
304
+ ```
305
+
306
+ ### Error Types
307
+ | Type | HTTP Status |
308
+ |------|-------------|
309
+ | `inputerror` | 400 Bad Request |
310
+ | `accessdenied` | 403 Forbidden |
311
+ | `notfound` | 404 Not Found |
312
+ | `standard` | 500 Internal Server Error |
313
+
314
+ ---
315
+
316
+ ## Pagination Response Format
317
+
318
+ When using `return = { type: "list", paging: {...} }`:
319
+
320
+ ```json
321
+ {
322
+ "itemsReceived": 20,
323
+ "curPage": 1,
324
+ "nextPage": 2,
325
+ "prevPage": null,
326
+ "offset": 0,
327
+ "perPage": 20,
328
+ "items": [...]
329
+ }
330
+ ```
331
+
332
+ ---
333
+
334
+ ## Best Practices
335
+
336
+ 1. **RESTful design** - Use appropriate HTTP methods
337
+ 2. **Consistent naming** - Use lowercase, hyphens for multi-word paths
338
+ 3. **Authenticate sensitive operations** - Always auth for writes
339
+ 4. **Validate inputs** - Use filters and preconditions
340
+ 5. **Return appropriate errors** - Use correct error types
341
+ 6. **Paginate lists** - Never return unbounded lists
342
+ 7. **Document with description** - Explain what endpoint does
343
+ 8. **Group related endpoints** - Organize by resource in api groups