mmt-mcp 1.44.5 → 1.45.0-pre

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 (34) hide show
  1. package/dist/examples/basic/05_api_test_suite/echo.mmt +2 -2
  2. package/dist/examples/examples-index.json +82 -0
  3. package/dist/examples/intermediate/01_api_inputs_outputs/post_regex_outputs.mmt +1 -1
  4. package/dist/examples/intermediate/05_api_documentation/api/get_users.mmt +1 -1
  5. package/dist/examples/intermediate/05_api_documentation/api/post_create_user.mmt +1 -1
  6. package/dist/examples/intermediate/05_api_documentation/api/ws_notifications.mmt +1 -1
  7. package/dist/examples/intermediate/06_imports/README.md +1 -1
  8. package/dist/examples/intermediate/09_csv_data_driven_test/README.md +2 -3
  9. package/dist/examples/intermediate/22_omit_keyword/omit_keyword.mmt +1 -1
  10. package/dist/examples/intermediate/25_convert_to_mmt/postman/converted/api/ping.mmt +1 -1
  11. package/dist/examples/intermediate/31_setenv_chain/README.md +24 -0
  12. package/dist/examples/intermediate/31_setenv_chain/api/login.mmt +11 -0
  13. package/dist/examples/intermediate/31_setenv_chain/api/whoami.mmt +10 -0
  14. package/dist/examples/intermediate/31_setenv_chain/env.mmt +4 -0
  15. package/dist/examples/intermediate/31_setenv_chain/server/auth_server.mmt +34 -0
  16. package/dist/examples/intermediate/31_setenv_chain/suite.mmt +12 -0
  17. package/dist/examples/intermediate/31_setenv_chain/test/login_test.mmt +24 -0
  18. package/dist/examples/intermediate/31_setenv_chain/test/prepare_test.mmt +6 -0
  19. package/dist/examples/intermediate/31_setenv_chain/test/whoami_test.mmt +11 -0
  20. package/dist/examples/intermediate/32_environment_live_variables/README.md +63 -0
  21. package/dist/examples/intermediate/32_environment_live_variables/consume_session_api.mmt +10 -0
  22. package/dist/examples/intermediate/32_environment_live_variables/consume_session_test.mmt +9 -0
  23. package/dist/examples/intermediate/32_environment_live_variables/create_session_api.mmt +11 -0
  24. package/dist/examples/intermediate/32_environment_live_variables/create_session_test.mmt +9 -0
  25. package/dist/examples/intermediate/32_environment_live_variables/multimeter.mmt +4 -0
  26. package/dist/examples/intermediate/32_environment_live_variables/suite.mmt +7 -0
  27. package/dist/examples/professional/04_convert_to_mmt/openapi/converted/api/bearer-auth-check.mmt +1 -1
  28. package/dist/examples/professional/04_convert_to_mmt/postman/converted/api/samples/get-sample-json.mmt +1 -1
  29. package/dist/examples/professional/11_token_resolution/api/current_header.mmt +1 -1
  30. package/dist/examples/professional/11_token_resolution/api/env_header.mmt +1 -1
  31. package/dist/guides/generate-test.md +1 -5
  32. package/dist/server.cjs +721 -114
  33. package/dist/server.js +721 -114
  34. package/package.json +1 -1
@@ -1,9 +1,9 @@
1
1
  type: api
2
2
  title: Echo status
3
- url: https://test.mmt.dev/json
4
- method: get
5
3
  outputs:
6
4
  status_code: status
5
+ url: https://test.mmt.dev/json
6
+ method: get
7
7
  examples:
8
8
  - id: ok
9
9
  title: Happy path
@@ -1063,6 +1063,88 @@
1063
1063
  "category": "intermediate",
1064
1064
  "title": "\"Suite memory stress\""
1065
1065
  },
1066
+ {
1067
+ "path": "intermediate/31_setenv_chain/api/login.mmt",
1068
+ "type": "api",
1069
+ "category": "intermediate",
1070
+ "title": "Login"
1071
+ },
1072
+ {
1073
+ "path": "intermediate/31_setenv_chain/api/whoami.mmt",
1074
+ "type": "api",
1075
+ "category": "intermediate",
1076
+ "title": "Who am I"
1077
+ },
1078
+ {
1079
+ "path": "intermediate/31_setenv_chain/env.mmt",
1080
+ "type": "env",
1081
+ "category": "intermediate"
1082
+ },
1083
+ {
1084
+ "path": "intermediate/31_setenv_chain/server/auth_server.mmt",
1085
+ "type": "server",
1086
+ "category": "intermediate",
1087
+ "title": "Setenv chain mock server"
1088
+ },
1089
+ {
1090
+ "path": "intermediate/31_setenv_chain/suite.mmt",
1091
+ "type": "suite",
1092
+ "category": "intermediate",
1093
+ "title": "Setenv across suite items"
1094
+ },
1095
+ {
1096
+ "path": "intermediate/31_setenv_chain/test/login_test.mmt",
1097
+ "type": "test",
1098
+ "category": "intermediate",
1099
+ "title": "Login then use the token"
1100
+ },
1101
+ {
1102
+ "path": "intermediate/31_setenv_chain/test/prepare_test.mmt",
1103
+ "type": "test",
1104
+ "category": "intermediate",
1105
+ "title": "Prepare environment"
1106
+ },
1107
+ {
1108
+ "path": "intermediate/31_setenv_chain/test/whoami_test.mmt",
1109
+ "type": "test",
1110
+ "category": "intermediate",
1111
+ "title": "Reuse the token in a later suite item"
1112
+ },
1113
+ {
1114
+ "path": "intermediate/32_environment_live_variables/consume_session_api.mmt",
1115
+ "type": "api",
1116
+ "category": "intermediate",
1117
+ "title": "Echo both live sessions"
1118
+ },
1119
+ {
1120
+ "path": "intermediate/32_environment_live_variables/consume_session_test.mmt",
1121
+ "type": "test",
1122
+ "category": "intermediate",
1123
+ "title": "Read live env from a test"
1124
+ },
1125
+ {
1126
+ "path": "intermediate/32_environment_live_variables/create_session_api.mmt",
1127
+ "type": "api",
1128
+ "category": "intermediate",
1129
+ "title": "Create session (API)"
1130
+ },
1131
+ {
1132
+ "path": "intermediate/32_environment_live_variables/create_session_test.mmt",
1133
+ "type": "test",
1134
+ "category": "intermediate",
1135
+ "title": "Create session (test)"
1136
+ },
1137
+ {
1138
+ "path": "intermediate/32_environment_live_variables/multimeter.mmt",
1139
+ "type": "env",
1140
+ "category": "intermediate"
1141
+ },
1142
+ {
1143
+ "path": "intermediate/32_environment_live_variables/suite.mmt",
1144
+ "type": "suite",
1145
+ "category": "intermediate",
1146
+ "title": "Live env consumers"
1147
+ },
1066
1148
  {
1067
1149
  "path": "professional/01_report_generation/api/echo.mmt",
1068
1150
  "type": "api",
@@ -1,6 +1,6 @@
1
1
  type: api
2
2
  title: Extract with regex
3
- description: |
3
+ description: |-
4
4
  Extract values from the response using regular expressions.
5
5
  Use `body[/pattern/]` or `body./pattern/` to extract from the body.
6
6
  Use `headers[/pattern/]` or `headers./pattern/` to extract from headers.
@@ -1,6 +1,6 @@
1
1
  type: api
2
2
  title: List users
3
- description: |
3
+ description: |-
4
4
  Returns a list of all users in the system.
5
5
 
6
6
  <<o:name>> The user's display name
@@ -1,6 +1,6 @@
1
1
  type: api
2
2
  title: Create user
3
- description: |
3
+ description: |-
4
4
  Create a new user account with the given details.
5
5
 
6
6
  <<i:username>> The desired username (3-20 characters)
@@ -1,6 +1,6 @@
1
1
  type: api
2
2
  title: Notification stream
3
- description: |
3
+ description: |-
4
4
  Subscribe to real-time notifications via WebSocket.
5
5
  Send a JSON message to start receiving events.
6
6
 
@@ -44,7 +44,7 @@ import:
44
44
  |---|---|---|
45
45
  | API definition | `.mmt` (`type: api`) | `call` step |
46
46
  | Test flow | `.mmt` (`type: test`) | `call` step (runs as a nested test) |
47
- | CSV data | `.csv` | `data` + `for` steps |
47
+ | CSV data | `.csv` | `for` steps |
48
48
  | JavaScript module | `.js` / `.cjs` / `.mjs` | `js` steps |
49
49
  | Mock server | `.mmt` (`type: server`) | `run` step |
50
50
 
@@ -39,7 +39,7 @@ test 123,POST
39
39
  - Unquoted numbers are auto-coerced (`"42"` → `42`); `true`/`false` become booleans.
40
40
  - Quoted values stay as strings (e.g. `"00123"` stays `"00123"`).
41
41
 
42
- ### 2. Import the CSV and bind it with `data`
42
+ ### 2. Import the CSV and use it
43
43
 
44
44
  ```yaml
45
45
  import:
@@ -48,7 +48,7 @@ steps:
48
48
  - for: message of messages
49
49
  ```
50
50
 
51
- The `data` step binds the imported CSV alias into scope so it can be used in loops and expressions.
51
+ The imported CSV alias is available in loops and expressions.
52
52
 
53
53
  ### 3. Loop with `for`
54
54
 
@@ -77,4 +77,3 @@ The `for` expression is standard JavaScript — `const row of messages` iterates
77
77
  - See [Simple Test](../../basic/02_simple_test/) for a basic test without CSV.
78
78
  - See [API Inputs & Outputs](../01_api_inputs_outputs/) for more input/output patterns.
79
79
  - See [Test docs — for/repeat](../../../docs/files/test/steps/control-flow.md#for-repeat) for the full `for`/`repeat` reference.
80
- - See [Test docs — data](../../../docs/files/test/steps/variables.md#data) for more on the `data` step.
@@ -30,4 +30,4 @@ body:
30
30
  middleName: i:middle_name
31
31
  nickname: i:nickname
32
32
  bio: i:bio
33
- bioText: i:bio_text
33
+ bioText: i:bio_text
@@ -13,7 +13,7 @@ headers:
13
13
  Accept: application/json
14
14
  examples:
15
15
  - name: sample json
16
- outputs:
16
+ expect:
17
17
  status: 200
18
18
  statusCode: 200
19
19
  id: 1
@@ -0,0 +1,24 @@
1
+ # setenv chain
2
+
3
+ `setenv` values are usable by the very next step, imported test, or suite item. They live in memory for the run and are never written to env files.
4
+
5
+ | File | Purpose |
6
+ |---|---|
7
+ | `server/auth_server.mmt` | Local mock: `POST /login` returns a token, `GET /whoami` requires it |
8
+ | `api/login.mmt` | API-level `setenv: session_token` |
9
+ | `api/whoami.mmt` | Sends `Bearer <<e:session_token>>` |
10
+ | `test/prepare_test.mmt` | Imported test with a `setenv` step |
11
+ | `test/login_test.mmt` | Calls login, then whoami, in one run |
12
+ | `test/whoami_test.mmt` | Calls whoami only; relies on an earlier suite item |
13
+ | `suite.mmt` | Runs login test, then whoami test |
14
+
15
+ ## Run
16
+
17
+ From the repo root:
18
+
19
+ ```sh
20
+ npx testlight run examples/intermediate/31_setenv_chain/suite.mmt \
21
+ --env-file examples/intermediate/31_setenv_chain/env.mmt
22
+ ```
23
+
24
+ The suite starts the mock server itself. To run a single test, start `server/auth_server.mmt` first.
@@ -0,0 +1,11 @@
1
+ type: api
2
+ title: Login
3
+ description: Logs in and promotes the token to `session_token` with `setenv`
4
+ protocol: http
5
+ method: post
6
+ url: <<e:base_url>>/login
7
+ outputs:
8
+ token: body.token
9
+ setenv:
10
+ session_token: body.token
11
+ body: ""
@@ -0,0 +1,10 @@
1
+ type: api
2
+ title: Who am I
3
+ description: Reads the current user using the token stored by `setenv`
4
+ protocol: http
5
+ method: get
6
+ url: <<e:base_url>>/whoami
7
+ headers:
8
+ Authorization: Bearer <<e:session_token>>
9
+ outputs:
10
+ user: body.user
@@ -0,0 +1,4 @@
1
+ type: env
2
+ variables:
3
+ base_url: http://localhost:9131
4
+ session_token: ""
@@ -0,0 +1,34 @@
1
+ type: server
2
+ title: Setenv chain mock server
3
+ description: Issues a session token and only accepts requests that carry it
4
+ port: 9131
5
+ cors: true
6
+ endpoints:
7
+ - method: post
8
+ path: /login
9
+ status: 200
10
+ format: json
11
+ body:
12
+ token: session-abc123
13
+ - method: get
14
+ path: /whoami
15
+ match:
16
+ headers:
17
+ Authorization: Bearer session-abc123
18
+ status: 200
19
+ format: json
20
+ body:
21
+ authenticated: true
22
+ user: alice
23
+ - method: get
24
+ path: /whoami
25
+ status: 401
26
+ format: json
27
+ body:
28
+ authenticated: false
29
+ fallback:
30
+ status: 404
31
+ format: json
32
+ body:
33
+ errors:
34
+ - path not found
@@ -0,0 +1,12 @@
1
+ type: suite
2
+ title: Setenv across suite items
3
+ description: The first item sets `session_token`; the second item consumes it without logging in
4
+ tags:
5
+ - example
6
+ - setenv
7
+ servers:
8
+ - server/auth_server.mmt
9
+ items:
10
+ - test/login_test.mmt
11
+ - then
12
+ - test/whoami_test.mmt
@@ -0,0 +1,24 @@
1
+ type: test
2
+ title: Login then use the token
3
+ description: |-
4
+ The API-level `setenv` (login) and a test-level `setenv` step are both read
5
+ by the very next step in the same run.
6
+ import:
7
+ login: ../api/login.mmt
8
+ whoami: ../api/whoami.mmt
9
+ prepare: ./prepare_test.mmt
10
+ steps:
11
+ - call: login
12
+ expect:
13
+ status: 200
14
+ - call: whoami
15
+ expect:
16
+ status: 200
17
+ user: alice
18
+ report: all
19
+ - call: prepare
20
+ - check:
21
+ title: Setenv from an imported test is visible
22
+ actual: e:greeting
23
+ operator: ==
24
+ expected: hello-from-import
@@ -0,0 +1,6 @@
1
+ type: test
2
+ title: Prepare environment
3
+ description: Imported by another test; its setenv step must still reach the caller
4
+ steps:
5
+ - setenv:
6
+ greeting: hello-from-import
@@ -0,0 +1,11 @@
1
+ type: test
2
+ title: Reuse the token in a later suite item
3
+ description: Does not log in; relies on `session_token` set by an earlier suite item
4
+ import:
5
+ whoami: ../api/whoami.mmt
6
+ steps:
7
+ - call: whoami
8
+ expect:
9
+ status: 200
10
+ user: alice
11
+ report: all
@@ -0,0 +1,63 @@
1
+ # Environment live variables (`./…mmt`)
2
+
3
+ Env values that start with `./` and end with `.mmt` are **file-backed**. At run
4
+ start each such path becomes a getter in the process env store. Reading
5
+ `e:name` runs that file (default inputs) and uses the **first key** under its
6
+ `outputs:` (YAML order). The target’s `cache:` controls reuse. A later
7
+ `setenv` of `./x.mmt` stays a plain string — only the original env copy turns
8
+ paths into getters.
9
+
10
+ Works for any runnable type with `outputs:` (typically `api` or `test`).
11
+
12
+ API files in this example call [https://test.mmt.dev/echo](https://test.mmt.dev/echo)
13
+ (needs network).
14
+
15
+ ## Structure
16
+
17
+ ```
18
+ 32_environment_live_variables/
19
+ ├── multimeter.mmt # session_api / session_test → ./create_*.mmt
20
+ ├── create_session_api.mmt # API → outputs.session (uuid)
21
+ ├── create_session_test.mmt # Test → outputs.session (uuid), cache: 2s
22
+ ├── consume_session_test.mmt # Asserts both e: values look like UUIDs
23
+ ├── consume_session_api.mmt # Optional: post both e: values to echo (Send)
24
+ ├── suite.mmt # Runs consume_session_test
25
+ └── README.md
26
+ ```
27
+
28
+ ## Files
29
+
30
+ | File | Role |
31
+ |---|---|
32
+ | `multimeter.mmt` | Env with file-backed `session_api` and `session_test` |
33
+ | `create_session_api.mmt` | API that posts `r:uuid` to test.mmt.dev/echo and exposes `session` |
34
+ | `create_session_test.mmt` | Test that sets `o:session` to `r:uuid` |
35
+ | `consume_session_test.mmt` | Checks `e:session_*` with `=*` UUID regex |
36
+ | `consume_session_api.mmt` | Optional API Send demo — body uses `e:session_*` |
37
+ | `suite.mmt` | Runs `consume_session_test.mmt` |
38
+
39
+ ## Try it
40
+
41
+ From the repo root:
42
+
43
+ ```sh
44
+ npx testlight run examples/intermediate/32_environment_live_variables/suite.mmt \
45
+ --env-file examples/intermediate/32_environment_live_variables/multimeter.mmt
46
+
47
+ # Or the test directly
48
+ npx testlight run examples/intermediate/32_environment_live_variables/consume_session_test.mmt \
49
+ --env-file examples/intermediate/32_environment_live_variables/multimeter.mmt
50
+ ```
51
+
52
+ ### In VS Code
53
+
54
+ 1. Open this folder (or the repo) so `multimeter.mmt` is the workspace env.
55
+ 2. Reload the Environment panel if needed — file-backed values show a **file**
56
+ icon and an underlined, Ctrl/Cmd+clickable path.
57
+ 3. Run `suite.mmt` or `consume_session_test.mmt`. Optionally Send
58
+ `consume_session_api.mmt` to see both UUIDs in the echo body.
59
+
60
+ ## Notes
61
+
62
+ - Checks use `=*` (regex), not `== xxx`, so random UUIDs still pass.
63
+ - `cache: 2s` on the test target: two `e:session_test` reads in one run match.
@@ -0,0 +1,10 @@
1
+ type: api
2
+ title: Echo both live sessions
3
+ description: |-
4
+ Whole-field e: tokens stay unresolved until Send/run so file-backed getters can run. The echo body should contain two UUIDs, not ./…mmt paths.
5
+ url: https://test.mmt.dev/echo
6
+ method: post
7
+ format: json
8
+ body:
9
+ session_api: e:session_api
10
+ session_test: e:session_test
@@ -0,0 +1,9 @@
1
+ type: test
2
+ title: Read live env from a test
3
+ description: |
4
+ e:session_* runs the linked .mmt files and yields their first output (a UUID). Assert shape with the regex operator (=*).
5
+ steps:
6
+ - check: <<e:session_test>> =* ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$
7
+ - check: <<e:session_api>> =* ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$
8
+ # Within cache: 2s, a second read of session_test returns the same UUID.
9
+ - check: <<e:session_test>> == <<e:session_test>>
@@ -0,0 +1,11 @@
1
+ type: api
2
+ title: Create session (API)
3
+ description: |-
4
+ File-backed env target. First outputs key (`session`) becomes the env value. Optional cache: reuses the result across e: reads within the window.
5
+ outputs:
6
+ session: body.body.uuid
7
+ url: https://test.mmt.dev/echo
8
+ method: post
9
+ format: json
10
+ body:
11
+ uuid: r:uuid
@@ -0,0 +1,9 @@
1
+ type: test
2
+ title: Create session (test)
3
+ description: File-backed env target with a short cache window.
4
+ outputs:
5
+ session: ''
6
+ cache: 2s
7
+ steps:
8
+ - set:
9
+ o:session: r:uuid
@@ -0,0 +1,4 @@
1
+ type: env
2
+ variables:
3
+ session_api: ./create_session_api.mmt
4
+ session_test: ./create_session_test.mmt
@@ -0,0 +1,7 @@
1
+ type: suite
2
+ title: Live env consumers
3
+ description: >
4
+ Runs the test consumer. Needs network access to test.mmt.dev for
5
+ e:session_api (create_session_api.mmt).
6
+ items:
7
+ - ./consume_session_test.mmt
@@ -1,6 +1,6 @@
1
1
  type: api
2
2
  title: Bearer auth check
3
- description: |
3
+ description: |-
4
4
  Requires `Authorization: Bearer testtoken`. Any other token fails.
5
5
  url: https://test.mmt.dev/auth/bearer
6
6
  protocol: http
@@ -14,7 +14,7 @@ headers:
14
14
  Accept: application/json
15
15
  examples:
16
16
  - name: sample json
17
- outputs:
17
+ expect:
18
18
  status: 200
19
19
  statusCode: 200
20
20
  id: 1
@@ -34,7 +34,7 @@ headers:
34
34
  X-Angle-Both: "asda<<c:day>>asas"
35
35
  X-Quoted-Curly: "{{c:day}}"
36
36
  X-Curly-Whole: {{c:city}}
37
- X-Text-Slice: <<c:city[0:1]>>
37
+ X-Text-Slice: c:city[0:1]
38
38
  X-Missing-Embed: "x<<c:not_a_token>>y"
39
39
  examples:
40
40
  - id: defaults
@@ -35,7 +35,7 @@ headers:
35
35
  X-Quoted-Angle: "<<e:account_age>>"
36
36
  X-Angle-Prefix: "asda<<e:account_age>>"
37
37
  X-Angle-Suffix: "<<e:account_age>>asas"
38
- X-Angle-Both: "asda<<e:feature_enabled>>asas"
38
+ X-Angle-Both: asda<<e:feature_enabled>>asas
39
39
  X-Quoted-Curly: "{{e:account_age}}"
40
40
  X-Curly-Whole: {{e:plan_label}}
41
41
  X-Text-Slice: <<e:service_url[0:8]>>
@@ -121,10 +121,7 @@ Supported step forms:
121
121
  - let:
122
122
  <name>: <value>
123
123
 
124
- # 13) data: bind CSV alias (from import)
125
- - data: <alias>
126
-
127
- # 14) setenv: promote values into environment variables
124
+ # 13) setenv: promote values into environment variables
128
125
  - setenv:
129
126
  <env_name>: <value> # e.g. token: ${loginStep.token}
130
127
  ```
@@ -291,7 +288,6 @@ import:
291
288
  login: ./login.mmt
292
289
 
293
290
  steps:
294
- - data: users
295
291
  - for: const user of users
296
292
  steps:
297
293
  - call: login