mcprigor 1.0.0-rc.1

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 (164) hide show
  1. package/LICENSE +17 -0
  2. package/README.md +233 -0
  3. package/dist/assertions.d.ts +4 -0
  4. package/dist/assertions.d.ts.map +1 -0
  5. package/dist/assertions.js +101 -0
  6. package/dist/assertions.js.map +1 -0
  7. package/dist/author.d.ts +57 -0
  8. package/dist/author.d.ts.map +1 -0
  9. package/dist/author.js +134 -0
  10. package/dist/author.js.map +1 -0
  11. package/dist/canonical.d.ts +4 -0
  12. package/dist/canonical.d.ts.map +1 -0
  13. package/dist/canonical.js +17 -0
  14. package/dist/canonical.js.map +1 -0
  15. package/dist/cli.d.ts +3 -0
  16. package/dist/cli.d.ts.map +1 -0
  17. package/dist/cli.js +265 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/contract.d.ts +28 -0
  20. package/dist/contract.d.ts.map +1 -0
  21. package/dist/contract.js +138 -0
  22. package/dist/contract.js.map +1 -0
  23. package/dist/data.d.ts +24 -0
  24. package/dist/data.d.ts.map +1 -0
  25. package/dist/data.js +367 -0
  26. package/dist/data.js.map +1 -0
  27. package/dist/discovery.d.ts +6 -0
  28. package/dist/discovery.d.ts.map +1 -0
  29. package/dist/discovery.js +82 -0
  30. package/dist/discovery.js.map +1 -0
  31. package/dist/errors.d.ts +19 -0
  32. package/dist/errors.d.ts.map +1 -0
  33. package/dist/errors.js +40 -0
  34. package/dist/errors.js.map +1 -0
  35. package/dist/extension-host.d.ts +20 -0
  36. package/dist/extension-host.d.ts.map +1 -0
  37. package/dist/extension-host.js +52 -0
  38. package/dist/extension-host.js.map +1 -0
  39. package/dist/extension-sdk.d.ts +22 -0
  40. package/dist/extension-sdk.d.ts.map +1 -0
  41. package/dist/extension-sdk.js +3 -0
  42. package/dist/extension-sdk.js.map +1 -0
  43. package/dist/extension-worker.d.ts +2 -0
  44. package/dist/extension-worker.d.ts.map +1 -0
  45. package/dist/extension-worker.js +27 -0
  46. package/dist/extension-worker.js.map +1 -0
  47. package/dist/extensions.d.ts +15 -0
  48. package/dist/extensions.d.ts.map +1 -0
  49. package/dist/extensions.js +60 -0
  50. package/dist/extensions.js.map +1 -0
  51. package/dist/imports.d.ts +7 -0
  52. package/dist/imports.d.ts.map +1 -0
  53. package/dist/imports.js +41 -0
  54. package/dist/imports.js.map +1 -0
  55. package/dist/index.d.ts +29 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +28 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/language.d.ts +34 -0
  60. package/dist/language.d.ts.map +1 -0
  61. package/dist/language.js +102 -0
  62. package/dist/language.js.map +1 -0
  63. package/dist/loader.d.ts +4 -0
  64. package/dist/loader.d.ts.map +1 -0
  65. package/dist/loader.js +51 -0
  66. package/dist/loader.js.map +1 -0
  67. package/dist/parity.d.ts +23 -0
  68. package/dist/parity.d.ts.map +1 -0
  69. package/dist/parity.js +77 -0
  70. package/dist/parity.js.map +1 -0
  71. package/dist/path.d.ts +3 -0
  72. package/dist/path.d.ts.map +1 -0
  73. package/dist/path.js +71 -0
  74. package/dist/path.js.map +1 -0
  75. package/dist/qa-advanced.d.ts +8 -0
  76. package/dist/qa-advanced.d.ts.map +1 -0
  77. package/dist/qa-advanced.js +239 -0
  78. package/dist/qa-advanced.js.map +1 -0
  79. package/dist/qa-language.d.ts +4 -0
  80. package/dist/qa-language.d.ts.map +1 -0
  81. package/dist/qa-language.js +385 -0
  82. package/dist/qa-language.js.map +1 -0
  83. package/dist/qa-loader.d.ts +4 -0
  84. package/dist/qa-loader.d.ts.map +1 -0
  85. package/dist/qa-loader.js +22 -0
  86. package/dist/qa-loader.js.map +1 -0
  87. package/dist/redact.d.ts +7 -0
  88. package/dist/redact.d.ts.map +1 -0
  89. package/dist/redact.js +63 -0
  90. package/dist/redact.js.map +1 -0
  91. package/dist/replay.d.ts +17 -0
  92. package/dist/replay.d.ts.map +1 -0
  93. package/dist/replay.js +48 -0
  94. package/dist/replay.js.map +1 -0
  95. package/dist/reporters.d.ts +6 -0
  96. package/dist/reporters.d.ts.map +1 -0
  97. package/dist/reporters.js +52 -0
  98. package/dist/reporters.js.map +1 -0
  99. package/dist/runner.d.ts +16 -0
  100. package/dist/runner.d.ts.map +1 -0
  101. package/dist/runner.js +304 -0
  102. package/dist/runner.js.map +1 -0
  103. package/dist/schema.d.ts +446 -0
  104. package/dist/schema.d.ts.map +1 -0
  105. package/dist/schema.js +117 -0
  106. package/dist/schema.js.map +1 -0
  107. package/dist/session.d.ts +5 -0
  108. package/dist/session.d.ts.map +1 -0
  109. package/dist/session.js +111 -0
  110. package/dist/session.js.map +1 -0
  111. package/dist/snapshots.d.ts +28 -0
  112. package/dist/snapshots.d.ts.map +1 -0
  113. package/dist/snapshots.js +87 -0
  114. package/dist/snapshots.js.map +1 -0
  115. package/dist/starter.d.ts +3 -0
  116. package/dist/starter.d.ts.map +1 -0
  117. package/dist/starter.js +34 -0
  118. package/dist/starter.js.map +1 -0
  119. package/dist/state.d.ts +13 -0
  120. package/dist/state.d.ts.map +1 -0
  121. package/dist/state.js +29 -0
  122. package/dist/state.js.map +1 -0
  123. package/dist/trace.d.ts +57 -0
  124. package/dist/trace.d.ts.map +1 -0
  125. package/dist/trace.js +94 -0
  126. package/dist/trace.js.map +1 -0
  127. package/dist/types.d.ts +245 -0
  128. package/dist/types.d.ts.map +1 -0
  129. package/dist/types.js +2 -0
  130. package/dist/types.js.map +1 -0
  131. package/dist/workspace.d.ts +10 -0
  132. package/dist/workspace.d.ts.map +1 -0
  133. package/dist/workspace.js +144 -0
  134. package/dist/workspace.js.map +1 -0
  135. package/docs/CLI-REFERENCE.md +167 -0
  136. package/docs/COMPATIBILITY.md +42 -0
  137. package/docs/CONTRACT-DRIFT.md +42 -0
  138. package/docs/DATA-AND-REUSE.md +213 -0
  139. package/docs/DATA-ENGINEERING.md +96 -0
  140. package/docs/ENGINEER-SETUP.md +176 -0
  141. package/docs/ERROR-MODEL.md +24 -0
  142. package/docs/EVIDENCE.md +58 -0
  143. package/docs/EXTENSION-SDK.md +76 -0
  144. package/docs/FILE-EXTENSION.md +52 -0
  145. package/docs/GETTING-STARTED.md +126 -0
  146. package/docs/GUIDED-AUTHORING.md +80 -0
  147. package/docs/LANDSCAPE.md +81 -0
  148. package/docs/LANGUAGE-SPEC.md +317 -0
  149. package/docs/MCP-NATIVE.md +111 -0
  150. package/docs/PLAIN-LANGUAGE-COOKBOOK.md +219 -0
  151. package/docs/QA-GUIDE.md +128 -0
  152. package/docs/QA-WORKSPACE.md +78 -0
  153. package/docs/README.md +55 -0
  154. package/docs/SECURITY-AND-RETENTION.md +37 -0
  155. package/docs/SNAPSHOTS-AND-REPLAY.md +85 -0
  156. package/docs/SPECIFICATION.md +178 -0
  157. package/docs/STATE-AND-DEPENDENCIES.md +106 -0
  158. package/docs/TRANSPORT-PARITY.md +98 -0
  159. package/docs/TROUBLESHOOTING.md +199 -0
  160. package/editors/mcpr-language.json +16 -0
  161. package/package.json +70 -0
  162. package/workspace-assets/app.js +1 -0
  163. package/workspace-assets/index.html +1 -0
  164. package/workspace-assets/style.css +1 -0
@@ -0,0 +1,52 @@
1
+ # MCP Rigor file extension
2
+
3
+ MCP Rigor plain-language tests use:
4
+
5
+ ```text
6
+ .mcpr
7
+ ```
8
+
9
+ Examples:
10
+
11
+ ```text
12
+ smoke.mcpr
13
+ customer-regression.mcpr
14
+ transport-parity.mcpr
15
+ ```
16
+
17
+ ## Why not `.mcp`?
18
+
19
+ The `.mcp` suffix predates Model Context Protocol and is already associated with other software, including Metrowerks CodeWarrior project files. Reusing it would create ambiguous editor, operating-system, MIME, and tooling associations.
20
+
21
+ MCP Rigor therefore uses the product-specific `.mcpr` suffix: **MCP Rigor**.
22
+
23
+ References checked during the decision:
24
+
25
+ - [FileInfo: MCP file extension](https://fileinfo.com/extension/mcp)
26
+ - [ReviverSoft file-extension registry](https://www.reviversoft.com/file-extensions/mcp)
27
+
28
+ File-extension registries are not global standards authorities, but existing use is sufficient reason to avoid the collision.
29
+
30
+ ## Migration
31
+
32
+ Rename files without changing their contents:
33
+
34
+ ```bash
35
+ mv tests/smoke.mcp tests/smoke.mcpr
36
+ mv tests/shared-flows.mcp tests/shared-flows.mcpr
37
+ ```
38
+
39
+ Update flow imports:
40
+
41
+ ```text
42
+ Import flows from "./shared-flows.mcpr"
43
+ ```
44
+
45
+ Update scripts and CI:
46
+
47
+ ```bash
48
+ mcprigor check tests/smoke.mcpr
49
+ mcprigor test tests/smoke.mcpr
50
+ ```
51
+
52
+ MCP Rigor now rejects `.mcp` files with an actionable rename message. YAML and JSON suite support is unchanged.
@@ -0,0 +1,126 @@
1
+ # Getting started
2
+
3
+ This guide takes you from installation to one passing MCP test.
4
+
5
+ ## 1. Install MCP Rigor
6
+
7
+ You need Node.js 20 or 22.
8
+
9
+ ```bash
10
+ mkdir mcp-acceptance-tests
11
+ cd mcp-acceptance-tests
12
+ npm init -y
13
+ npm install --save-dev mcprigor
14
+ ```
15
+
16
+ ## 2. Create a test file
17
+
18
+ Create `calculator.mcpr`:
19
+
20
+ ```text
21
+ MCP Test 1
22
+
23
+ Suite: "Calculator acceptance tests"
24
+ Server: node ../calculator-server/dist/server.js
25
+
26
+ Test: "Adding 20 and 22 gives 42"
27
+ Call tool "add" with:
28
+ a: 20
29
+ b: 22
30
+
31
+ Expect "structuredContent.sum" equals 42
32
+ ```
33
+
34
+ Change the `Server` command to the command that starts your MCP server.
35
+
36
+ For a deployed Streamable HTTP server, use:
37
+
38
+ ```text
39
+ MCP URL: https://qa.example.com/mcp
40
+ ```
41
+
42
+ ## 3. Check the wording
43
+
44
+ ```bash
45
+ npx mcprigor check calculator.mcpr
46
+ ```
47
+
48
+ A valid file prints:
49
+
50
+ ```text
51
+ ✓ calculator.mcpr looks good and is ready to run
52
+ ```
53
+
54
+ `check` does not connect to the server.
55
+
56
+ ## 4. Run the test
57
+
58
+ ```bash
59
+ npx mcprigor test calculator.mcpr
60
+ ```
61
+
62
+ A passing result looks like:
63
+
64
+ ```text
65
+ MCP Rigor — Calculator acceptance tests
66
+ ✓ Adding 20 and 22 gives 42
67
+
68
+ 1 passed, 0 failed, 0 skipped, 0 blocked
69
+ ```
70
+
71
+ ## 5. Create a shareable report
72
+
73
+ ```bash
74
+ npx mcprigor test calculator.mcpr --html report.html
75
+ ```
76
+
77
+ Open `report.html` or attach it to a ticket.
78
+
79
+ ## 6. Try the browser workspace
80
+
81
+ ```bash
82
+ npx mcprigor workspace .
83
+ ```
84
+
85
+ Open the printed local URL. Select `calculator.mcpr`, edit it, choose **Validate**, then **Run tests**.
86
+
87
+ ## If you do not know tool names
88
+
89
+ Create a small target file such as `server.mcpr`:
90
+
91
+ ```text
92
+ MCP Test 1
93
+ Suite: "Server target"
94
+ Server: node ../calculator-server/dist/server.js
95
+ Test: "Connection"
96
+ Send "ping"
97
+ ```
98
+
99
+ Start guided authoring:
100
+
101
+ ```bash
102
+ npx mcprigor author server.mcpr --out calculator.mcpr
103
+ ```
104
+
105
+ MCP Rigor discovers tools, resources, and prompts and asks what you want to verify.
106
+
107
+ ## Recommended project layout
108
+
109
+ ```text
110
+ mcp-acceptance-tests/
111
+ package.json
112
+ tests/
113
+ smoke.mcpr
114
+ regression.mcpr
115
+ data/
116
+ customers.csv
117
+ .mcprigor/
118
+ # generated evidence; normally ignored or stored as CI artifacts
119
+ ```
120
+
121
+ ## Next steps
122
+
123
+ - [Plain-language cookbook](PLAIN-LANGUAGE-COOKBOOK.md)
124
+ - [QA workspace](QA-WORKSPACE.md)
125
+ - [Engineer setup and CI](ENGINEER-SETUP.md)
126
+ - [Troubleshooting](TROUBLESHOOTING.md)
@@ -0,0 +1,80 @@
1
+ # Guided test authoring
2
+
3
+ Use this when you know the behavior to test but do not know the server's tool, resource, prompt, or response field names.
4
+
5
+ The `author` command creates a plain-language test by connecting to a live MCP server and asking QA-friendly questions.
6
+
7
+ ```bash
8
+ mcprigor author server.mcpr --out tests/search-customer.mcpr
9
+ ```
10
+
11
+ `server.mcpr` can be an existing minimal target file:
12
+
13
+ ```text
14
+ MCP Test 1
15
+ Suite: "QA target"
16
+ Server: node dist/server.js
17
+ Test: "placeholder"
18
+ Send "ping"
19
+ ```
20
+
21
+ ## Authoring flow
22
+
23
+ 1. MCP Rigor connects and discovers tools, resources, and prompts.
24
+ 2. Choose whether to call a tool, read a resource, or get a prompt.
25
+ 3. Select the operation by its name and description.
26
+ 4. Enter required inputs derived from the tool JSON Schema or prompt arguments.
27
+ 5. Review and run the request.
28
+ 6. Select returned fields to verify.
29
+ 7. Choose equality, containment, or existence checks.
30
+ 8. Name the test and review the generated source.
31
+ 9. Confirm the output file.
32
+ 10. Run it normally with `mcprigor test`.
33
+
34
+ Generated files are deterministic:
35
+
36
+ - `MCP Test 1` language header
37
+ - sorted input object keys
38
+ - sorted assertions
39
+ - two-space indentation
40
+ - one trailing newline
41
+ - no timestamps or random identifiers
42
+
43
+ The output is an ordinary `.mcpr` file. It can be edited, reviewed in a pull request, copied, and run without the authoring wizard.
44
+
45
+ ## Input behavior
46
+
47
+ The wizard understands common JSON Schema input types:
48
+
49
+ - required and optional object properties
50
+ - strings
51
+ - numbers and integers
52
+ - booleans
53
+ - arrays and objects entered as JSON
54
+ - property defaults
55
+
56
+ Unsupported or highly dynamic schemas can still be tested by editing the generated `.mcpr` file afterward. Secret values should be represented through environment variables in the target or generated file; never paste reusable credentials into assertions.
57
+
58
+ ## Response field selection
59
+
60
+ Responses are flattened into stable paths such as:
61
+
62
+ ```text
63
+ $.structuredContent.id
64
+ $.content[0].text
65
+ $.messages[0].content.text
66
+ ```
67
+
68
+ Object keys are sorted and array order is retained. Display previews are capped. Select only stable business fields; prefer `exists` for generated IDs and avoid equality checks on timestamps, tokens, or volatile metadata.
69
+
70
+ ## Automation API
71
+
72
+ The authoring engine accepts an injected `PromptAdapter`. The included `ScriptedPromptAdapter` lets CI and framework tests run the entire wizard without terminal input. Programmatic APIs are exported from `mcprigor`:
73
+
74
+ - `authorTest`
75
+ - `renderAuthoredTest`
76
+ - `flattenResponse`
77
+ - `createReadlinePromptAdapter`
78
+ - `ScriptedPromptAdapter`
79
+
80
+ This separation keeps discovery, prompting, execution, rendering, and file writing independently testable.
@@ -0,0 +1,81 @@
1
+ # Background: MCP testing landscape
2
+
3
+ > Non-normative research. This page explains product positioning; it is not needed to use MCP Rigor.
4
+
5
+ ## Executive summary
6
+
7
+ MCP testing tools currently fall into five categories: interactive inspectors, scriptable probes, official protocol conformance, SDK/framework-local tests, and semantic or security evaluators. The strongest opening for MCP Rigor is a transport-neutral, deterministic, black-box application test runner: **“Playwright for MCP.”**
8
+
9
+ MCP Rigor should complement the Inspector and official Conformance project rather than suggest it replaces either.
10
+
11
+ ## Landscape
12
+
13
+ | Tool | Primary role | What it does well | Gap relative to MCP Rigor |
14
+ |---|---|---|---|
15
+ | [MCP Inspector](https://github.com/modelcontextprotocol/inspector) | Official interactive debugger | Explore connections, capabilities, tools, resources, prompts, notifications, and logs | Primarily manual exploration rather than a scenario/assertion/reporting framework |
16
+ | [MCP Inspector CLI](https://github.com/modelcontextprotocol/inspector#cli-mode) | Scriptable probe | Programmatic one-shot MCP interactions | Tests, fixtures, captures, deterministic assertion semantics, and CI reports remain limited or external |
17
+ | [Official MCP Conformance](https://github.com/modelcontextprotocol/conformance) | Protocol compliance/interoperability | Repeatable client/server protocol checks | Evolving protocol suite rather than application-domain regression testing |
18
+ | [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) | SDK and in-memory testing | Typed clients and in-process transport testing | Language/repository coupled; in-memory tests do not cover deployed transport boundaries |
19
+ | [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk) | SDK and in-memory testing | Python integration tests and memory helpers | Language/repository coupled rather than a universal black-box suite |
20
+ | [FastMCP testing](https://gofastmcp.com/patterns/testing) | Python framework testing | Convenient deterministic pytest/in-process testing | Framework-specific and can bypass subprocess, HTTP, auth, proxy, and deployment behavior |
21
+ | [mcptools](https://github.com/f/mcptools) | CLI probing | Shell-friendly list/call/read operations | Assertion model, scenarios, reports, fixtures, and coverage are external |
22
+ | [Promptfoo MCP provider](https://www.promptfoo.dev/docs/providers/mcp/) | Behavioral/agentic evaluation | Tool selection and response-quality evaluation with reports | LLM/model behavior can be probabilistic; not wire or deterministic application testing |
23
+ | [mcp-vibetest](https://github.com/ComposioHQ/mcp-vibetest) | Agentic semantic evaluation | Realistic task-completion checks | Probabilistic and complementary to hard deterministic gates |
24
+ | [mcp-scan](https://github.com/invariantlabs-ai/mcp-scan) | Security scanning | Tool-poisoning and prompt/config risk detection | Specialized security gate, not functional regression testing |
25
+ | [Cisco MCP Scanner](https://github.com/cisco-ai-defense/mcp-scanner) | Security scanning | MCP-focused security analysis | Specialized scanner rather than behavior/protocol test runner |
26
+ | [MCPJam Inspector](https://github.com/MCPJam/inspector) | Interactive workbench | Friendly exploratory MCP development | Primarily interactive; deterministic CI should not be assumed without specific current support |
27
+
28
+ Project details and release status change quickly. Pin versions and verify current primary documentation before making compatibility claims.
29
+
30
+ ## Positioning
31
+
32
+ ### Category
33
+
34
+ **Deterministic MCP application testing.**
35
+
36
+ ### One-line message
37
+
38
+ > MCP Rigor is the open-source test runner for repeatable MCP server behavior across stdio and Streamable HTTP.
39
+
40
+ ### Memorable message
41
+
42
+ > Playwright for MCP: author once, run the same scenarios locally and in CI.
43
+
44
+ ### Naming rationale
45
+
46
+ “MCP Rigor” uses established developer-tool terminology, clearly describes the project’s scope, and remains independent from any specific MCP server or vendor brand. Registry and trademark availability should still be verified before publication.
47
+
48
+ ## Durable differentiation
49
+
50
+ 1. **Application workflows, not only probes:** multi-step scenarios, captures, fixtures, setup/teardown, and side-effect verification.
51
+ 2. **Real boundaries:** subprocess lifecycle, stdio framing, Streamable HTTP, auth, TLS/proxy, reconnect, and cleanup.
52
+ 3. **Stable CI contract:** deterministic exit codes, JSON/JUnit/SARIF, traces, artifacts, filtering, and policy-controlled retries.
53
+ 4. **MCP-aware assertions:** tools/resources/prompts, errors, notifications, progress, pagination, cancellation, capability/version matrices, and subscriptions.
54
+ 5. **Declarative and programmable:** safe YAML/JSON for most cases plus a typed API and explicit plugin model for advanced projects.
55
+ 6. **Layered oracles:** deterministic assertions as hard gates; optional semantic/LLM evaluation as a clearly labeled soft layer.
56
+ 7. **Record to regression:** capture an exploratory interaction, sanitize secrets/dynamic values, and generate a checked-in test.
57
+ 8. **Evidence, not certification:** run or aggregate exact official conformance profiles without making blanket compliance claims.
58
+
59
+ ## What not to become
60
+
61
+ - another generic MCP chat client
62
+ - another Inspector UI as the first product
63
+ - an unofficial certification authority
64
+ - a Python- or TypeScript-framework-specific helper
65
+ - an LLM evaluation platform whose core results are nondeterministic
66
+ - a broad security scanner that dilutes functional testing
67
+
68
+ ## Launch wedge
69
+
70
+ Target teams that have one or more MCP servers in CI and currently use shell scripts, Inspector screenshots, ad hoc SDK tests, or manual checks. The first compelling demo should:
71
+
72
+ 1. run the same calculator test against stdio and HTTP targets;
73
+ 2. show a clear structural diff for a broken tool response;
74
+ 3. capture a value and reuse it in a later step;
75
+ 4. verify a protocol error and timeout;
76
+ 5. export JUnit in GitHub Actions;
77
+ 6. prove the child process is cleaned up after failure.
78
+
79
+ ## Suggested public narrative
80
+
81
+ “The MCP ecosystem already has excellent tools to inspect a server and increasingly strong official protocol conformance checks. MCP Rigor addresses a different question: does your server still perform the domain behaviors your users depend on? It turns those behaviors into deterministic scenarios that run over real transports on every pull request.”
@@ -0,0 +1,317 @@
1
+ # MCP Test Language 1
2
+
3
+ Status: compatibility-stable frontend for MCP Rigor 0.12.
4
+
5
+ The `.mcpr` language and YAML compile to the same `Suite` runtime model. Every user-authored YAML capability has a deterministic plain-language equivalent; YAML remains available for generated files and programmatic integrations rather than being a more powerful test format.
6
+
7
+ ## Design goals
8
+
9
+ - Readable by QA professionals without programming experience
10
+ - Deterministic: no LLM or fuzzy interpretation
11
+ - Two-space indentation and precise file/line/column diagnostics
12
+ - Safe data blocks delegated to YAML after the outer statement is recognized
13
+ - Backward-compatible with MCP Rigor 0.5 `.mcpr` files
14
+
15
+ A file may begin with:
16
+
17
+ ```text
18
+ MCP Test 1
19
+ ```
20
+
21
+ Unknown language versions are rejected.
22
+
23
+ ## Lexical rules
24
+
25
+ - UTF-8 text; LF and CRLF accepted
26
+ - Tabs are rejected
27
+ - Indentation must be a multiple of two spaces
28
+ - `#` starts a comment on a standalone line
29
+ - Declaration keywords are case-insensitive for compatibility
30
+ - Tool, flow, test, variable, and ID values retain their case
31
+ - Strings may use single or double quotes
32
+ - Indented `with:` blocks use safe YAML values
33
+
34
+ The formal frontend emits located nodes with UTF-16 offsets, line, column, semantic span, indentation, and declaration kind. Compilation currently lowers this document through the compatibility compiler so runtime behavior remains stable.
35
+
36
+ ## Document declarations
37
+
38
+ ```text
39
+ MCP Test 1
40
+ Suite: "Customer tests"
41
+ Server: node dist/server.js
42
+ ```
43
+
44
+ HTTP:
45
+
46
+ ```text
47
+ MCP URL: https://qa.example.com/mcp
48
+ ```
49
+
50
+ Target options use a readable settings block:
51
+
52
+ ```text
53
+ Server options:
54
+ cwd: ./server
55
+ env:
56
+ MODE: test
57
+ ```
58
+
59
+ ```text
60
+ Server options:
61
+ headers:
62
+ Authorization: "Bearer ${env.QA_TOKEN}"
63
+ ```
64
+
65
+ Parity targets use the same connection grammar:
66
+
67
+ ```text
68
+ Compare target "Local": node server.js
69
+ Compare target "QA": https://qa.example.com/mcp
70
+
71
+ Target options for "QA":
72
+ headers:
73
+ Authorization: "Bearer ${env.QA_TOKEN}"
74
+ ```
75
+
76
+ Suite-level YAML fields have direct equivalents:
77
+
78
+ ```text
79
+ Default timeout: 10 seconds
80
+ Redact: "secret-value", "token-value"
81
+ Snapshots: snapshots.json
82
+ Ignore snapshot paths: "$.createdAt", "$.requestId"
83
+
84
+ Client behavior:
85
+ roots:
86
+ - uri: file:///workspace
87
+ name: Workspace
88
+ sampling:
89
+ model: fixture
90
+ text: deterministic response
91
+ elicitation:
92
+ action: accept
93
+ content:
94
+ approved: true
95
+ ```
96
+
97
+ ## Imports
98
+
99
+ ```text
100
+ Import flows from "./shared/customer-flows.mcpr"
101
+ ```
102
+
103
+ Only `Flow:` declarations are imported. Imported tests, server declarations, data sources, and top-level configuration never execute. Paths resolve relative to the importer. Canonical path cycles are rejected.
104
+
105
+ ## Flows
106
+
107
+ ```text
108
+ Flow: "Verify addition"
109
+ Inputs: a, b=1, expected
110
+
111
+ Call tool "add" with:
112
+ a: "${a}"
113
+ b: "${b}"
114
+
115
+ Expect "structuredContent.sum" equals "${expected}"
116
+ ```
117
+
118
+ Inputs without `=` are required. Inputs with defaults are optional. Unknown supplied inputs and missing required inputs are compilation errors. Recursive flows are rejected.
119
+
120
+ Use a flow:
121
+
122
+ ```text
123
+ Use flow "Verify addition" with:
124
+ a: 4
125
+ expected: 5
126
+ ```
127
+
128
+ Flow invocations receive isolated prefixed variables. Caller values are available only when passed through declared inputs.
129
+
130
+ ## Tests and dependencies
131
+
132
+ ```text
133
+ Test: "Create customer"
134
+ Id: create-customer
135
+ Require: tools
136
+ ```
137
+
138
+ ```text
139
+ Test: "Retrieve customer"
140
+ Depends on: create-customer
141
+ ```
142
+
143
+ Additional test settings:
144
+
145
+ ```text
146
+ Skip: "Not enabled in this environment"
147
+
148
+ Variables:
149
+ tenant: acme
150
+ retryCount: 3
151
+
152
+ Require protocol: "2025-06-18"
153
+ ```
154
+
155
+ `Skip` without a reason maps to `skip: true`. IDs are unique. Dependencies form an acyclic graph and must pass before the consumer opens a session.
156
+
157
+ ## Actions
158
+
159
+ ```text
160
+ Call tool "search" with:
161
+ query: "red shoes"
162
+
163
+ Read resource "catalog://status"
164
+
165
+ Get prompt "review" with:
166
+ topic: "release"
167
+
168
+ Send "ping"
169
+ ```
170
+
171
+ ## Expectations and values
172
+
173
+ ```text
174
+ Expect it succeeds
175
+ Expect an error
176
+ Expect "structuredContent.total" equals 2
177
+ Expect "content[0].text" contains "complete"
178
+ Expect "items" exists
179
+ Expect "items" has 3 items
180
+ ```
181
+
182
+ Full assertion vocabulary:
183
+
184
+ ```text
185
+ Expect "status" does not equal "deleted"
186
+ Expect "count" is a number
187
+ Expect "customerId" matches "^C-[0-9]+$"
188
+ Expect error code -32602
189
+ Expect error message matches "invalid input"
190
+ Expect "structuredContent" matches schema:
191
+ type: object
192
+ required: [customerId]
193
+ Expect "structuredContent" matches snapshot "customer" ignoring "$.createdAt"
194
+ ```
195
+
196
+ Equality is type-sensitive. No implicit text/number coercion occurs. Schema blocks use safe YAML only after the deterministic outer statement is recognized.
197
+
198
+ ## Variables, exports, and utilities
199
+
200
+ ```text
201
+ Save "structuredContent.id" as "localId"
202
+ Export "structuredContent.id" as "customerId"
203
+ ```
204
+
205
+ Local values use `${localId}`. Dependency outputs use `${deps.create-customer.customerId}`. Persisted state uses `${state.create-customer.customerId}`.
206
+
207
+ ```text
208
+ Set "normalized" using "lowercase" with:
209
+ value: "${row.Email}"
210
+ ```
211
+
212
+ ## Data iteration
213
+
214
+ ```text
215
+ For each row:
216
+ | caseId | input | expected |
217
+ | first | 2 | 4 |
218
+ ```
219
+
220
+ Plain-language engineered sources:
221
+
222
+ ```text
223
+ Data source: "customers"
224
+ From CSV "customers.csv"
225
+ Column "customerId" is string required
226
+ Column "spend" is number required
227
+ Column "tier" is string one of gold, silver, bronze
228
+ Derive "label" as "${customerId}:${tier}"
229
+ Keep rows where "spend" is greater than 100
230
+ Sample 25 rows with seed 2025
231
+ Cache this source
232
+
233
+ Test: "Active customer"
234
+ For each row from "customers"
235
+ Call tool "find_customer" with:
236
+ customerId: "${row.customerId}"
237
+ ```
238
+
239
+ File forms are `From CSV`, `From JSON`, `From YAML`, and `From Excel ... sheet ...`. Remote sources use `From REST`. Existing structured settings remain accepted inside a `Data source` block for Google Sheets, SQL, custom plugins, joins, and uncommon provider-specific options, so there is no capability gap with YAML. Remote and custom-code safety flags remain mandatory.
240
+
241
+ See `DATA-AND-REUSE.md` and `DATA-ENGINEERING.md`.
242
+
243
+ ## Setup and cleanup
244
+
245
+ ```text
246
+ Setup:
247
+ Call tool "prepare"
248
+
249
+ Steps:
250
+ Call tool "execute"
251
+
252
+ Cleanup:
253
+ Call tool "remove"
254
+ ```
255
+
256
+ Cleanup actions are attempted even after an earlier failure. Cleanup should be idempotent.
257
+
258
+ ## MCP-native actions
259
+
260
+ ```text
261
+ Subscribe to resource "customer://updates"
262
+ Wait for notification "notifications/resources/updated" within 5 seconds
263
+ Unsubscribe from resource "customer://updates"
264
+ Set log level to "debug"
265
+ List all tools
266
+ List all resources
267
+ List all prompts
268
+ List all resource templates
269
+ Get task "task-1"
270
+ List tasks
271
+ Cancel task "task-1"
272
+ ```
273
+
274
+ Progress and cancellation:
275
+
276
+ ```text
277
+ Call tool "import" with progress and cancel after 500 ms with:
278
+ source: catalog.csv
279
+ ```
280
+
281
+ These compile to the same `native` step objects accepted by YAML.
282
+
283
+ ## Diagnostics
284
+
285
+ A diagnostic includes a stable code, source location, original line, caret, explanation, and correction:
286
+
287
+ ```text
288
+ MCPLANG102 tests/customer.mcpr:8:1
289
+
290
+ Call tool "create"
291
+ ^
292
+
293
+ Indentation must use multiples of two spaces.
294
+ Try: use 0, 2, 4, or 6 leading spaces
295
+ ```
296
+
297
+ Current namespaces:
298
+
299
+ - `MCPLANG1xx`: lexical/version errors
300
+ - `MCPLANG2xx`: structural errors
301
+ - `MCPLANG3xx`: import errors
302
+ - `MCPLANG4xx`: symbol, flow, and reference errors
303
+ - `MCP-DEP-*`: dependency graph errors
304
+ - `QA-DATA-*` / `MCP-DATA-*`: data compilation/provider errors
305
+
306
+ ## Grammar summary
307
+
308
+ ```ebnf
309
+ document = version? declaration* ;
310
+ declaration = suite | server | import | flow | dataSource | test ;
311
+ flow = "Flow:" name flowProperty* statement* ;
312
+ test = "Test:" name testProperty* statement* ;
313
+ statement = callTool | readResource | getPrompt | send | expect
314
+ | save | export | wait | set | useFlow | forEach | section ;
315
+ ```
316
+
317
+ The vocabulary is closed. New behavior requires a documented language-version-compatible statement rather than fuzzy natural-language interpretation.