@xano/developer-mcp 1.0.36 → 1.0.38

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 CHANGED
@@ -346,7 +346,8 @@ Retrieves XanoScript programming language documentation with context-aware suppo
346
346
  | `agents` | AI agent configuration with LLM providers and tools |
347
347
  | `tools` | AI tools for agents and MCP servers |
348
348
  | `mcp-servers` | MCP server definitions exposing tools |
349
- | `testing` | Unit tests, mocks, and assertions |
349
+ | `unit-testing` | Unit tests, mocks, and assertions within functions, APIs, and middleware |
350
+ | `workflow-tests` | End-to-end workflow tests with data sources and tags |
350
351
  | `integrations` | External service integrations index |
351
352
  | `integrations/cloud-storage` | AWS S3, Azure Blob, and GCP Storage |
352
353
  | `integrations/search` | Elasticsearch, OpenSearch, and Algolia |
@@ -542,7 +543,8 @@ The server also exposes XanoScript documentation as MCP resources for direct acc
542
543
  | `xanoscript://docs/agents` | AI agent configuration |
543
544
  | `xanoscript://docs/tools` | AI tools for agents |
544
545
  | `xanoscript://docs/mcp-servers` | MCP server definitions |
545
- | `xanoscript://docs/testing` | Unit tests and mocks |
546
+ | `xanoscript://docs/unit-testing` | Unit tests and mocks |
547
+ | `xanoscript://docs/workflow-tests` | End-to-end workflow tests |
546
548
  | `xanoscript://docs/integrations` | External service integrations index |
547
549
  | `xanoscript://docs/integrations/cloud-storage` | AWS S3, Azure Blob, GCP Storage |
548
550
  | `xanoscript://docs/integrations/search` | Elasticsearch, OpenSearch, Algolia |
@@ -81,10 +81,15 @@ export const XANOSCRIPT_DOCS_V2 = {
81
81
  applyTo: ["mcp_servers/**/*.xs"],
82
82
  description: "MCP server definitions exposing tools",
83
83
  },
84
- testing: {
85
- file: "testing.md",
86
- applyTo: ["functions/**/*.xs", "apis/**/*.xs"],
87
- description: "Unit tests, mocks, and assertions",
84
+ "unit-testing": {
85
+ file: "unit-testing.md",
86
+ applyTo: ["functions/**/*.xs", "apis/**/*.xs", "middleware/**/*.xs"],
87
+ description: "Unit tests, mocks, and assertions within functions, APIs, and middleware",
88
+ },
89
+ "workflow-tests": {
90
+ file: "workflow-tests.md",
91
+ applyTo: ["workflow_test/**/*.xs"],
92
+ description: "End-to-end workflow tests with data source selection and tags",
88
93
  },
89
94
  integrations: {
90
95
  file: "integrations.md",
@@ -23,7 +23,8 @@ describe("xanoscript module", () => {
23
23
  "agents",
24
24
  "tools",
25
25
  "mcp-servers",
26
- "testing",
26
+ "unit-testing",
27
+ "workflow-tests",
27
28
  "integrations",
28
29
  "integrations/cloud-storage",
29
30
  "integrations/search",
@@ -68,7 +69,7 @@ describe("xanoscript module", () => {
68
69
  expect(result).toContain("apis");
69
70
  expect(result).toContain("types");
70
71
  expect(result).toContain("database");
71
- expect(result).toContain("testing");
72
+ expect(result).toContain("unit-testing");
72
73
  expect(result).toContain("addons");
73
74
  });
74
75
  it("should match functions files", () => {
@@ -19,6 +19,7 @@ XanoScript is the declarative scripting language for [Xano](https://xano.com), a
19
19
  | `tool` | `tool/{name}.xs` | Tools for AI agents |
20
20
  | `mcp_server` | `mcp_server/{name}.xs` | MCP server definitions |
21
21
  | `mcp_server_trigger`| `mcp_server/trigger/{name}.xs` | MCP server event handlers |
22
+ | `workflow_test` | `workflow_test/{name}.xs` | End-to-end workflow tests |
22
23
  | `addon` | `addon/{name}.xs` | Subqueries for related data |
23
24
  | `middleware` | `middleware/{name}.xs` | Request/response interceptors |
24
25
  | `branch` | `branch.xs` | Branch-level configuration |
@@ -65,6 +66,8 @@ project/
65
66
  │ ├── my_server.xs # MCP server definitions
66
67
  │ └── trigger/
67
68
  │ └── on_connect.xs # MCP server triggers
69
+ ├── workflow_test/
70
+ │ └── checkout_flow.xs # End-to-end workflow tests
68
71
  ├── middleware/
69
72
  │ └── auth_check.xs # Request/response interceptors
70
73
  ├── addon/
@@ -229,7 +232,8 @@ Use `xanoscript_docs({ topic: "<topic>" })` to retrieve documentation.
229
232
 
230
233
  | Topic | Description | Key Sections |
231
234
  | ----------- | ---------------------------------------------------------- | ------------ |
232
- | `testing` | Unit tests, mocks, and assertions | Test Syntax, Assertions |
235
+ | `unit-testing` | Unit tests, mocks, and assertions within functions, APIs, and middleware | Test Syntax, Assertions, Mocking |
236
+ | `workflow-tests` | End-to-end workflow tests with data sources and tags | Data Sources, Tags, Common Patterns |
233
237
  | `debugging` | Logging, inspecting, and debugging XanoScript execution | debug.log, Inspection |
234
238
  | `frontend` | Static frontend development and deployment | File Structure |
235
239
  | `run` | Run job and service configurations for the Xano Job Runner | Jobs, Services |
@@ -128,10 +128,15 @@
128
128
  "purpose": "Request interceptors",
129
129
  "aliases": ["interceptors", "hooks"]
130
130
  },
131
- "testing": {
132
- "file": "testing.md",
133
- "purpose": "Unit testing",
134
- "aliases": ["tests", "unit-tests"]
131
+ "unit-testing": {
132
+ "file": "unit-testing.md",
133
+ "purpose": "Unit tests, mocks, and assertions",
134
+ "aliases": ["tests", "unit-tests", "mocks", "assertions"]
135
+ },
136
+ "workflow-tests": {
137
+ "file": "workflow-tests.md",
138
+ "purpose": "End-to-end workflow tests",
139
+ "aliases": ["e2e", "workflow", "integration-tests"]
135
140
  },
136
141
  "debugging": {
137
142
  "file": "debugging.md",
@@ -185,7 +190,7 @@
185
190
 
186
191
  "constructs": {
187
192
  "table": { "file": "tables.md", "triggers": "triggers.md" },
188
- "function": { "file": "functions.md", "testing": "testing.md" },
193
+ "function": { "file": "functions.md", "testing": "unit-testing.md" },
189
194
  "query": { "file": "apis.md", "auth": "security.md" },
190
195
  "api_group": { "file": "apis.md" },
191
196
  "task": { "file": "tasks.md" },
@@ -166,6 +166,15 @@ The `size` parameter specifies the vector dimensions (must match your embedding
166
166
 
167
167
  ## Indexes
168
168
 
169
+ Each index field supports an optional `op` property to control sort order or operator class:
170
+
171
+ | Index Type | `op` Values | Default | Description |
172
+ |------------|-------------|---------|-------------|
173
+ | `btree` | `asc`, `desc` | `asc` | Sort direction |
174
+ | `gin` | `jsonb_path_op` | — | Operator class for JSON containment queries |
175
+ | `search` | `A`, `B`, `C`, `D` | — | Weight category (A = highest relevance) |
176
+ | `vector` | `vector_cosine_ops` | — | Distance function for similarity search |
177
+
169
178
  ### Primary Key
170
179
 
171
180
  ```xs
@@ -1,10 +1,10 @@
1
1
  ---
2
- applyTo: "function/**/*.xs, api/**/*.xs"
2
+ applyTo: "function/**/*.xs, api/**/*.xs, middleware/**/*.xs"
3
3
  ---
4
4
 
5
- # Testing
5
+ # Unit Testing
6
6
 
7
- Unit tests and mocking in XanoScript.
7
+ Unit tests, mocks, and assertions defined inline within functions, API endpoints, and middleware. Unit tests validate individual construct behavior in isolation — for end-to-end workflow testing across multiple constructs, see `workflow-tests`.
8
8
 
9
9
  ## Quick Reference
10
10
 
@@ -330,3 +330,15 @@ function "calculate_discount" {
330
330
  3. **Descriptive test names** - Explain what's being tested
331
331
  4. **One assertion focus** - Each test verifies one behavior
332
332
  5. **Keep tests independent** - No shared state between tests
333
+
334
+ ---
335
+
336
+ ## Related Topics
337
+
338
+ | Topic | Description |
339
+ | ----------------- | -------------------------------------------------- |
340
+ | `workflow-tests` | End-to-end workflow tests across multiple constructs |
341
+ | `functions` | Reusable function stacks (where unit tests live) |
342
+ | `apis` | API endpoints (where unit tests live) |
343
+ | `middleware` | Request/response interceptors (where unit tests live) |
344
+ | `debugging` | Logging and debugging test execution |
@@ -0,0 +1,333 @@
1
+ ---
2
+ applyTo: "workflow_test/**/*.xs"
3
+ ---
4
+
5
+ # Workflow Tests
6
+
7
+ End-to-end workflow tests that call Xano constructs (APIs, functions, tasks, etc.) and validate results with assertions. The `stack` block supports all standard XanoScript statements (variables, conditionals, loops, database operations, etc.) in addition to the call functions and assertions documented below.
8
+
9
+ ## Quick Reference
10
+
11
+ ```xs
12
+ workflow_test "<name>" {
13
+ datasource = "live"
14
+ stack { ... }
15
+ tags = ["tag1", "tag2"]
16
+ }
17
+ ```
18
+
19
+ | Property | Required | Default | Description |
20
+ | ------------ | -------- | ------- | ------------------------------------------------ |
21
+ | `datasource` | No | (empty) | Data source to run against: custom name or `"live"` (not recommended — clones entire datasource) |
22
+ | `stack` | Yes | — | Test execution logic using call functions and assertions |
23
+ | `tags` | No | `[]` | Tags for organizing and filtering workflow tests |
24
+
25
+ ---
26
+
27
+ ## Call Functions
28
+
29
+ Call functions invoke Xano constructs and capture their results. Each returns a result that can be stored with `as $variable`.
30
+
31
+ | Call Function | Description | Required Properties |
32
+ | ----------------- | ------------------------------ | ------------------------------------ |
33
+ | `api.call` | Call an API endpoint | `api_group`, `verb` (on call), optional `headers` |
34
+ | `addon.call` | Call an addon | — |
35
+ | `function.call` | Call a function | optional `input` |
36
+ | `middleware.call` | Call a middleware | `input` with `vars` and `type` |
37
+ | `task.call` | Call a task | — |
38
+ | `tool.call` | Call a tool | — |
39
+ | `trigger.call` | Call a trigger | `input` with `new`, `old`, `action`, `datasource` |
40
+
41
+ ### api.call
42
+
43
+ ```xs
44
+ api.call "<endpoint_name>" verb=GET {
45
+ api_group = "<group_name>"
46
+ headers = '["Content-Type: application/json"]'
47
+ } as $result
48
+ ```
49
+
50
+ ### addon.call
51
+
52
+ ```xs
53
+ addon.call "<addon_name>" as $result
54
+ ```
55
+
56
+ ### function.call
57
+
58
+ ```xs
59
+ function.call "<function_name>" {
60
+ input = { key: "value" }
61
+ } as $result
62
+ ```
63
+
64
+ ### middleware.call
65
+
66
+ ```xs
67
+ middleware.call "<middleware_name>" {
68
+ input = {vars: {}, type: "pre"}
69
+ } as $result
70
+ ```
71
+
72
+ ### task.call
73
+
74
+ ```xs
75
+ task.call "<task_name>" as $result
76
+ ```
77
+
78
+ ### tool.call
79
+
80
+ ```xs
81
+ tool.call "<tool_name>" as $result
82
+ ```
83
+
84
+ ### trigger.call
85
+
86
+ ```xs
87
+ trigger.call "<trigger_name>" {
88
+ input = {new: {}, old: {}, action: "", datasource: ""}
89
+ } as $result
90
+ ```
91
+
92
+ ---
93
+
94
+ ## Assertions
95
+
96
+ Assertions validate results within the workflow test stack. Each takes a variable reference as the target.
97
+
98
+ ### Quick Reference
99
+
100
+ | Assertion | Purpose | Properties |
101
+ | -------------------------- | ----------------------- | ------------------- |
102
+ | `expect.to_be_defined` | Value is defined | — |
103
+ | `expect.to_not_be_defined` | Value is not defined | — |
104
+ | `expect.to_be_empty` | Value is empty | — |
105
+ | `expect.to_be_true` | Value is true | — |
106
+ | `expect.to_be_false` | Value is false | — |
107
+ | `expect.to_be_null` | Value is null | — |
108
+ | `expect.to_not_be_null` | Value is not null | — |
109
+ | `expect.to_be_in_the_past` | Timestamp is in the past| — |
110
+ | `expect.to_be_in_the_future`| Timestamp is in the future| — |
111
+ | `expect.to_equal` | Exact match | `value` |
112
+ | `expect.to_not_equal` | Not equal | `value` |
113
+ | `expect.to_be_greater_than`| Greater than | `value` |
114
+ | `expect.to_be_less_than` | Less than | `value` |
115
+ | `expect.to_be_within` | Within range | `min`, `max` |
116
+ | `expect.to_contain` | Contains value | `value` |
117
+ | `expect.to_start_with` | Starts with string | `value` |
118
+ | `expect.to_end_with` | Ends with string | `value` |
119
+ | `expect.to_match` | Regex match | `value` (pattern) |
120
+ | `expect.to_throw` | Stack throws error | `stack`, `exception` |
121
+
122
+ ### No-Property Assertions
123
+
124
+ These take only the target variable:
125
+
126
+ ```xs
127
+ expect.to_be_defined ($var)
128
+ expect.to_not_be_defined ($var)
129
+ expect.to_be_empty ($var)
130
+ expect.to_be_true ($var)
131
+ expect.to_be_false ($var)
132
+ expect.to_be_null ($var)
133
+ expect.to_not_be_null ($var)
134
+ expect.to_be_in_the_past ($var)
135
+ expect.to_be_in_the_future ($var)
136
+ ```
137
+
138
+ ### Value Assertions
139
+
140
+ These take a `value` property for comparison. The value can be a literal or a variable reference:
141
+
142
+ ```xs
143
+ expect.to_equal ($var) { value = "expected" }
144
+ expect.to_not_equal ($var) { value = $other_var }
145
+ expect.to_be_greater_than ($var) { value = 3 }
146
+ expect.to_be_less_than ($var) { value = $other_var }
147
+ expect.to_contain ($var) { value = "substring" }
148
+ expect.to_start_with ($var) { value = "prefix" }
149
+ expect.to_end_with ($var) { value = "suffix" }
150
+
151
+ // Regex pattern
152
+ expect.to_match ($var) { value = "^\\d+$" }
153
+ ```
154
+
155
+ ### Range Assertion
156
+
157
+ ```xs
158
+ expect.to_be_within ($var) {
159
+ min = 1
160
+ max = 100
161
+ }
162
+ ```
163
+
164
+ ### Error Assertion
165
+
166
+ `expect.to_throw` wraps a `stack` block and checks that it throws a matching exception:
167
+
168
+ ```xs
169
+ expect.to_throw {
170
+ stack {
171
+ security.create_uuid as $x1
172
+ }
173
+
174
+ exception = "error"
175
+ }
176
+ ```
177
+
178
+ ---
179
+
180
+ ## Data Sources
181
+
182
+ The `datasource` property controls which data source the test runs against.
183
+
184
+ **Avoid using `datasource = "live"`.** When a workflow test runs, the entire datasource is cloned so that real data is not modified. This cloning step can be slow, especially for large datasources. Prefer running without a datasource or using a smaller custom datasource instead.
185
+
186
+ ### Default (No Data Source) — Recommended
187
+
188
+ ```xs
189
+ workflow_test "basic_check" {
190
+ stack {
191
+ function.call "health_check" as $result
192
+ expect.to_be_defined ($result)
193
+ }
194
+ }
195
+ ```
196
+
197
+ ### Custom Data Source
198
+
199
+ ```xs
200
+ workflow_test "staging_data_check" {
201
+ datasource = "staging"
202
+ stack {
203
+ function.call "get_products" as $products
204
+ expect.to_be_defined ($products)
205
+ }
206
+ }
207
+ ```
208
+
209
+ ### Live Data Source (Not Recommended)
210
+
211
+ Using `datasource = "live"` clones the entire live datasource before running the test. Only use this when you specifically need to validate against production data.
212
+
213
+ ```xs
214
+ workflow_test "live_data_check" {
215
+ datasource = "live"
216
+ stack {
217
+ function.call "get_active_users" as $users
218
+ expect.to_be_defined ($users)
219
+ }
220
+ }
221
+ ```
222
+
223
+ ---
224
+
225
+ ## Tags
226
+
227
+ Use tags to organize and filter workflow tests:
228
+
229
+ ```xs
230
+ workflow_test "checkout_flow" {
231
+ tags = ["checkout", "critical", "e2e"]
232
+ stack {
233
+ function.call "create_cart" as $cart
234
+ expect.to_be_defined ($cart)
235
+ }
236
+ }
237
+ ```
238
+
239
+ ---
240
+
241
+ ## Complete Example
242
+
243
+ This example demonstrates all call functions and all assertion types:
244
+
245
+ ```xs
246
+ workflow_test "comprehensive_test" {
247
+ datasource = "live"
248
+
249
+ stack {
250
+ // Call functions
251
+ api.call "test" verb=GET {
252
+ api_group = "test"
253
+ headers = '["Content-Type: application/json"]'
254
+ } as $endpoint1
255
+
256
+ addon.call "my_addon" as $addon1
257
+ function.call "my_function" {
258
+ input = {name: "Justin"}
259
+ } as $function1
260
+
261
+ middleware.call "my_middleware" {
262
+ input = {vars: {}, type: "pre"}
263
+ } as $middleware1
264
+
265
+ task.call "my_task" as $task1
266
+ tool.call "my_tool" as $tool1
267
+ trigger.call "my_trigger" {
268
+ input = {new: {}, old: {}, action: "", datasource: ""}
269
+ } as $trigger1
270
+
271
+ // No-property assertions
272
+ expect.to_be_defined ($endpoint1)
273
+ expect.to_be_empty ($addon1)
274
+ expect.to_be_false ($endpoint1)
275
+ expect.to_be_true ($addon1)
276
+ expect.to_be_null ($middleware1)
277
+ expect.to_not_be_null ($endpoint1)
278
+ expect.to_not_be_defined ($function1)
279
+ expect.to_be_in_the_past ($endpoint1)
280
+ expect.to_be_in_the_future ($endpoint1)
281
+
282
+ // Value assertions
283
+ expect.to_equal ($endpoint1) { value = $endpoint1 }
284
+ expect.to_not_equal ($endpoint1) { value = $addon1 }
285
+ expect.to_be_greater_than ($endpoint1) { value = 3 }
286
+ expect.to_be_less_than ($addon1) { value = $task1 }
287
+ expect.to_contain ($endpoint1) { value = "asdf" }
288
+ expect.to_start_with ($addon1) { value = "f" }
289
+ expect.to_end_with ($addon1) { value = "asdf" }
290
+
291
+ // Regex pattern
292
+ expect.to_match ($endpoint1) { value = ".*" }
293
+
294
+ // Range assertion
295
+ expect.to_be_within ($endpoint1) {
296
+ min = 1
297
+ max = 4
298
+ }
299
+
300
+ // Error assertion
301
+ expect.to_throw {
302
+ stack {
303
+ security.create_uuid as $x1
304
+ }
305
+
306
+ exception = "error"
307
+ }
308
+ }
309
+
310
+ tags = ["a", "b"]
311
+ }
312
+ ```
313
+
314
+ ---
315
+
316
+ ## Best Practices
317
+
318
+ 1. **Use descriptive names** — Name tests after the workflow being tested: `user_signup_flow`, `checkout_process`
319
+ 2. **Tag for filtering** — Use tags like `critical`, `e2e`, `smoke` to organize test suites
320
+ 3. **Avoid `datasource = "live"`** — The entire datasource is cloned before each test run, which can be slow. Use no datasource or a smaller custom datasource instead
321
+ 4. **Keep tests independent** — Each workflow test should be self-contained and not depend on other tests
322
+ 5. **Use assertions over preconditions** — Prefer `expect.*` assertions for clearer test intent
323
+
324
+ ---
325
+
326
+ ## Related Topics
327
+
328
+ | Topic | Description |
329
+ | -------------- | ------------------------------------------ |
330
+ | `unit-testing` | Unit tests and assertions within functions |
331
+ | `functions` | Reusable function stacks called in tests |
332
+ | `database` | Database operations used in test stacks |
333
+ | `debugging` | Logging and debugging test execution |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xano/developer-mcp",
3
- "version": "1.0.36",
3
+ "version": "1.0.38",
4
4
  "description": "MCP server and library for Xano development - XanoScript validation, Meta API, Run API, and CLI documentation",
5
5
  "type": "module",
6
6
  "main": "dist/lib.js",