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.
- package/LICENSE +17 -0
- package/README.md +233 -0
- package/dist/assertions.d.ts +4 -0
- package/dist/assertions.d.ts.map +1 -0
- package/dist/assertions.js +101 -0
- package/dist/assertions.js.map +1 -0
- package/dist/author.d.ts +57 -0
- package/dist/author.d.ts.map +1 -0
- package/dist/author.js +134 -0
- package/dist/author.js.map +1 -0
- package/dist/canonical.d.ts +4 -0
- package/dist/canonical.d.ts.map +1 -0
- package/dist/canonical.js +17 -0
- package/dist/canonical.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +265 -0
- package/dist/cli.js.map +1 -0
- package/dist/contract.d.ts +28 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +138 -0
- package/dist/contract.js.map +1 -0
- package/dist/data.d.ts +24 -0
- package/dist/data.d.ts.map +1 -0
- package/dist/data.js +367 -0
- package/dist/data.js.map +1 -0
- package/dist/discovery.d.ts +6 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +82 -0
- package/dist/discovery.js.map +1 -0
- package/dist/errors.d.ts +19 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +40 -0
- package/dist/errors.js.map +1 -0
- package/dist/extension-host.d.ts +20 -0
- package/dist/extension-host.d.ts.map +1 -0
- package/dist/extension-host.js +52 -0
- package/dist/extension-host.js.map +1 -0
- package/dist/extension-sdk.d.ts +22 -0
- package/dist/extension-sdk.d.ts.map +1 -0
- package/dist/extension-sdk.js +3 -0
- package/dist/extension-sdk.js.map +1 -0
- package/dist/extension-worker.d.ts +2 -0
- package/dist/extension-worker.d.ts.map +1 -0
- package/dist/extension-worker.js +27 -0
- package/dist/extension-worker.js.map +1 -0
- package/dist/extensions.d.ts +15 -0
- package/dist/extensions.d.ts.map +1 -0
- package/dist/extensions.js +60 -0
- package/dist/extensions.js.map +1 -0
- package/dist/imports.d.ts +7 -0
- package/dist/imports.d.ts.map +1 -0
- package/dist/imports.js +41 -0
- package/dist/imports.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/language.d.ts +34 -0
- package/dist/language.d.ts.map +1 -0
- package/dist/language.js +102 -0
- package/dist/language.js.map +1 -0
- package/dist/loader.d.ts +4 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +51 -0
- package/dist/loader.js.map +1 -0
- package/dist/parity.d.ts +23 -0
- package/dist/parity.d.ts.map +1 -0
- package/dist/parity.js +77 -0
- package/dist/parity.js.map +1 -0
- package/dist/path.d.ts +3 -0
- package/dist/path.d.ts.map +1 -0
- package/dist/path.js +71 -0
- package/dist/path.js.map +1 -0
- package/dist/qa-advanced.d.ts +8 -0
- package/dist/qa-advanced.d.ts.map +1 -0
- package/dist/qa-advanced.js +239 -0
- package/dist/qa-advanced.js.map +1 -0
- package/dist/qa-language.d.ts +4 -0
- package/dist/qa-language.d.ts.map +1 -0
- package/dist/qa-language.js +385 -0
- package/dist/qa-language.js.map +1 -0
- package/dist/qa-loader.d.ts +4 -0
- package/dist/qa-loader.d.ts.map +1 -0
- package/dist/qa-loader.js +22 -0
- package/dist/qa-loader.js.map +1 -0
- package/dist/redact.d.ts +7 -0
- package/dist/redact.d.ts.map +1 -0
- package/dist/redact.js +63 -0
- package/dist/redact.js.map +1 -0
- package/dist/replay.d.ts +17 -0
- package/dist/replay.d.ts.map +1 -0
- package/dist/replay.js +48 -0
- package/dist/replay.js.map +1 -0
- package/dist/reporters.d.ts +6 -0
- package/dist/reporters.d.ts.map +1 -0
- package/dist/reporters.js +52 -0
- package/dist/reporters.js.map +1 -0
- package/dist/runner.d.ts +16 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +304 -0
- package/dist/runner.js.map +1 -0
- package/dist/schema.d.ts +446 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +117 -0
- package/dist/schema.js.map +1 -0
- package/dist/session.d.ts +5 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +111 -0
- package/dist/session.js.map +1 -0
- package/dist/snapshots.d.ts +28 -0
- package/dist/snapshots.d.ts.map +1 -0
- package/dist/snapshots.js +87 -0
- package/dist/snapshots.js.map +1 -0
- package/dist/starter.d.ts +3 -0
- package/dist/starter.d.ts.map +1 -0
- package/dist/starter.js +34 -0
- package/dist/starter.js.map +1 -0
- package/dist/state.d.ts +13 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +29 -0
- package/dist/state.js.map +1 -0
- package/dist/trace.d.ts +57 -0
- package/dist/trace.d.ts.map +1 -0
- package/dist/trace.js +94 -0
- package/dist/trace.js.map +1 -0
- package/dist/types.d.ts +245 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/workspace.d.ts +10 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +144 -0
- package/dist/workspace.js.map +1 -0
- package/docs/CLI-REFERENCE.md +167 -0
- package/docs/COMPATIBILITY.md +42 -0
- package/docs/CONTRACT-DRIFT.md +42 -0
- package/docs/DATA-AND-REUSE.md +213 -0
- package/docs/DATA-ENGINEERING.md +96 -0
- package/docs/ENGINEER-SETUP.md +176 -0
- package/docs/ERROR-MODEL.md +24 -0
- package/docs/EVIDENCE.md +58 -0
- package/docs/EXTENSION-SDK.md +76 -0
- package/docs/FILE-EXTENSION.md +52 -0
- package/docs/GETTING-STARTED.md +126 -0
- package/docs/GUIDED-AUTHORING.md +80 -0
- package/docs/LANDSCAPE.md +81 -0
- package/docs/LANGUAGE-SPEC.md +317 -0
- package/docs/MCP-NATIVE.md +111 -0
- package/docs/PLAIN-LANGUAGE-COOKBOOK.md +219 -0
- package/docs/QA-GUIDE.md +128 -0
- package/docs/QA-WORKSPACE.md +78 -0
- package/docs/README.md +55 -0
- package/docs/SECURITY-AND-RETENTION.md +37 -0
- package/docs/SNAPSHOTS-AND-REPLAY.md +85 -0
- package/docs/SPECIFICATION.md +178 -0
- package/docs/STATE-AND-DEPENDENCIES.md +106 -0
- package/docs/TRANSPORT-PARITY.md +98 -0
- package/docs/TROUBLESHOOTING.md +199 -0
- package/editors/mcpr-language.json +16 -0
- package/package.json +70 -0
- package/workspace-assets/app.js +1 -0
- package/workspace-assets/index.html +1 -0
- package/workspace-assets/style.css +1 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# MCP-Native Behavior Testing
|
|
2
|
+
|
|
3
|
+
MCP Rigor 0.10 extends deterministic request/response testing to asynchronous and client-side MCP behavior.
|
|
4
|
+
|
|
5
|
+
## Notifications
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
Wait for notification "notifications/resources/updated" within 5 seconds
|
|
9
|
+
Expect "params.uri" equals "fixture://status"
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Supported official notification handlers include:
|
|
13
|
+
|
|
14
|
+
- progress
|
|
15
|
+
- resource updated and resource list changed
|
|
16
|
+
- tool and prompt list changed
|
|
17
|
+
- logging messages
|
|
18
|
+
- task status
|
|
19
|
+
|
|
20
|
+
Events receive deterministic session-local sequence numbers and are available to the evidence recorder.
|
|
21
|
+
|
|
22
|
+
## Resource subscriptions
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
Subscribe to resource "fixture://status"
|
|
26
|
+
Call tool "change_status"
|
|
27
|
+
Wait for notification "notifications/resources/updated" within 5 seconds
|
|
28
|
+
|
|
29
|
+
Cleanup:
|
|
30
|
+
Unsubscribe from resource "fixture://status"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The server must declare resource subscription capability.
|
|
34
|
+
|
|
35
|
+
## Progress and cancellation
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
Call tool "import_catalog" with progress with:
|
|
39
|
+
file: "catalog.csv"
|
|
40
|
+
|
|
41
|
+
Expect "progress" has 2 items
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Cancellation can be configured in YAML/JSON native steps with `cancelAfterMs`. Cancellation uses `AbortSignal`, distinguishing it from request timeout.
|
|
45
|
+
|
|
46
|
+
## Pagination
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
List all tools
|
|
50
|
+
Expect "items" has 20 items
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Equivalent statements exist for resources, prompts, and resource templates. MCP Rigor follows `nextCursor` until absent and fails on repeated cursors.
|
|
54
|
+
|
|
55
|
+
## Logging
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
Set log level to "debug"
|
|
59
|
+
Wait for notification "notifications/message" within 5 seconds
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Roots, sampling, and elicitation
|
|
63
|
+
|
|
64
|
+
YAML/JSON suites can configure deterministic client behavior:
|
|
65
|
+
|
|
66
|
+
```yaml
|
|
67
|
+
client:
|
|
68
|
+
roots:
|
|
69
|
+
- uri: file:///workspace
|
|
70
|
+
name: Workspace
|
|
71
|
+
sampling:
|
|
72
|
+
model: fixture-model
|
|
73
|
+
text: deterministic response
|
|
74
|
+
elicitation:
|
|
75
|
+
action: accept
|
|
76
|
+
content:
|
|
77
|
+
approved: true
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The SDK client advertises roots, sampling, and elicitation capabilities and installs handlers using official schemas. No real model is called and no human UI is invoked during deterministic runs.
|
|
81
|
+
|
|
82
|
+
## Experimental tasks
|
|
83
|
+
|
|
84
|
+
Native requests can stream task-aware tool calls through the SDK experimental task API. Generic task operations are also available:
|
|
85
|
+
|
|
86
|
+
- `tasks/get`
|
|
87
|
+
- `tasks/list`
|
|
88
|
+
- `tasks/cancel`
|
|
89
|
+
|
|
90
|
+
Task support remains explicitly experimental and SDK-version-sensitive. MCP Rigor records intermediate task events but does not claim to validate persistence or recovery across separate server processes.
|
|
91
|
+
|
|
92
|
+
## Boundary of coverage
|
|
93
|
+
|
|
94
|
+
Fully testable at the SDK boundary:
|
|
95
|
+
|
|
96
|
+
- notification registration and delivery
|
|
97
|
+
- progress callbacks
|
|
98
|
+
- AbortSignal cancellation
|
|
99
|
+
- subscriptions
|
|
100
|
+
- logging level and messages
|
|
101
|
+
- roots requests
|
|
102
|
+
- deterministic sampling responses
|
|
103
|
+
- form elicitation responses
|
|
104
|
+
- cursor pagination
|
|
105
|
+
|
|
106
|
+
Not claimed:
|
|
107
|
+
|
|
108
|
+
- actual LLM response quality
|
|
109
|
+
- human elicitation UI behavior
|
|
110
|
+
- task durability across infrastructure failures
|
|
111
|
+
- raw transport framing or reconnect behavior
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# Plain-language cookbook
|
|
2
|
+
|
|
3
|
+
Copy a pattern, replace the names and values, then run `mcprigor check FILE`.
|
|
4
|
+
|
|
5
|
+
## Basic file
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
MCP Test 1
|
|
9
|
+
Suite: "Customer service"
|
|
10
|
+
Server: node dist/server.js
|
|
11
|
+
|
|
12
|
+
Test: "The server responds"
|
|
13
|
+
Send "ping"
|
|
14
|
+
Expect it succeeds
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Call a tool
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
Test: "An active customer can be found"
|
|
21
|
+
Call tool "find_customer" with:
|
|
22
|
+
customerId: "C-100"
|
|
23
|
+
|
|
24
|
+
Expect "structuredContent.customerId" equals "C-100"
|
|
25
|
+
Expect "structuredContent.status" equals "active"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Read a resource
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
Test: "The catalog is ready"
|
|
32
|
+
Read resource "catalog://status"
|
|
33
|
+
Expect "contents[0].text" contains "ready"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Get a prompt
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
Test: "A review prompt can be created"
|
|
40
|
+
Get prompt "review_release" with:
|
|
41
|
+
release: "1.2.0"
|
|
42
|
+
|
|
43
|
+
Expect "messages" has 1 item
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Check result types and patterns
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
Expect "structuredContent.total" is a number
|
|
50
|
+
Expect "structuredContent.customerId" matches "^C-[0-9]+$"
|
|
51
|
+
Expect "structuredContent.status" does not equal "deleted"
|
|
52
|
+
Expect "structuredContent.items" exists
|
|
53
|
+
Expect "structuredContent.items" has 3 items
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Expect an MCP error
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
Test: "A missing customer returns an error"
|
|
60
|
+
Call tool "find_customer" with:
|
|
61
|
+
customerId: "DOES-NOT-EXIST"
|
|
62
|
+
|
|
63
|
+
Expect an error
|
|
64
|
+
Expect error code -32602
|
|
65
|
+
Expect error message matches "not found"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Save and reuse a value
|
|
69
|
+
|
|
70
|
+
```text
|
|
71
|
+
Test: "Create and retrieve a customer"
|
|
72
|
+
Call tool "create_customer" with:
|
|
73
|
+
email: "qa@example.com"
|
|
74
|
+
|
|
75
|
+
Save "structuredContent.customerId" as "customerId"
|
|
76
|
+
|
|
77
|
+
Call tool "find_customer" with:
|
|
78
|
+
customerId: "${customerId}"
|
|
79
|
+
|
|
80
|
+
Expect "structuredContent.customerId" equals "${customerId}"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Always clean up
|
|
84
|
+
|
|
85
|
+
```text
|
|
86
|
+
Test: "A temporary customer can be used"
|
|
87
|
+
Setup:
|
|
88
|
+
Call tool "create_customer" with:
|
|
89
|
+
email: "temporary@example.com"
|
|
90
|
+
Save "structuredContent.customerId" as "customerId"
|
|
91
|
+
|
|
92
|
+
Steps:
|
|
93
|
+
Call tool "find_customer" with:
|
|
94
|
+
customerId: "${customerId}"
|
|
95
|
+
Expect it succeeds
|
|
96
|
+
|
|
97
|
+
Cleanup:
|
|
98
|
+
Call tool "delete_customer" with:
|
|
99
|
+
customerId: "${customerId}"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Cleanup runs even if an earlier test action fails. Make cleanup actions safe to repeat.
|
|
103
|
+
|
|
104
|
+
## Reuse a flow
|
|
105
|
+
|
|
106
|
+
```text
|
|
107
|
+
Flow: "Verify addition"
|
|
108
|
+
Inputs: a, b, expected
|
|
109
|
+
|
|
110
|
+
Call tool "add" with:
|
|
111
|
+
a: "${a}"
|
|
112
|
+
b: "${b}"
|
|
113
|
+
|
|
114
|
+
Expect "structuredContent.sum" equals "${expected}"
|
|
115
|
+
|
|
116
|
+
Test: "Common addition cases"
|
|
117
|
+
Use flow "Verify addition" with:
|
|
118
|
+
a: 20
|
|
119
|
+
b: 22
|
|
120
|
+
expected: 42
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Run a table of examples
|
|
124
|
+
|
|
125
|
+
```text
|
|
126
|
+
Test: "Calculator examples"
|
|
127
|
+
For each row:
|
|
128
|
+
| caseId | a | b | expected |
|
|
129
|
+
| zero | 0 | 0 | 0 |
|
|
130
|
+
| basic | 2 | 3 | 5 |
|
|
131
|
+
| larger | 20 | 22 | 42 |
|
|
132
|
+
|
|
133
|
+
Call tool "add" with:
|
|
134
|
+
a: "${row.a}"
|
|
135
|
+
b: "${row.b}"
|
|
136
|
+
|
|
137
|
+
Expect "structuredContent.sum" equals "${row.expected}"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Use CSV data
|
|
141
|
+
|
|
142
|
+
```text
|
|
143
|
+
Data source: "customers"
|
|
144
|
+
From CSV "data/customers.csv"
|
|
145
|
+
Column "customerId" is string required
|
|
146
|
+
Column "active" is boolean
|
|
147
|
+
Keep rows where "active" equals true
|
|
148
|
+
Sample 25 rows with seed 2025
|
|
149
|
+
|
|
150
|
+
Test: "Active customers are available"
|
|
151
|
+
For each row from "customers"
|
|
152
|
+
Call tool "find_customer" with:
|
|
153
|
+
customerId: "${row.customerId}"
|
|
154
|
+
Expect it succeeds
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Share an output with another test
|
|
158
|
+
|
|
159
|
+
```text
|
|
160
|
+
Test: "Create a customer"
|
|
161
|
+
Id: create-customer
|
|
162
|
+
Call tool "create_customer" with:
|
|
163
|
+
email: "qa@example.com"
|
|
164
|
+
Export "structuredContent.customerId" as "customerId"
|
|
165
|
+
|
|
166
|
+
Test: "Retrieve the created customer"
|
|
167
|
+
Id: retrieve-customer
|
|
168
|
+
Depends on: create-customer
|
|
169
|
+
Call tool "find_customer" with:
|
|
170
|
+
customerId: "${deps.create-customer.customerId}"
|
|
171
|
+
Expect it succeeds
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Compare two transports
|
|
175
|
+
|
|
176
|
+
```text
|
|
177
|
+
Compare target "Local": node dist/server.js
|
|
178
|
+
Compare target "QA": https://qa.example.com/mcp
|
|
179
|
+
|
|
180
|
+
Test: "Search behaves the same"
|
|
181
|
+
Call tool "search" with:
|
|
182
|
+
query: "red shoes"
|
|
183
|
+
Expect "structuredContent.total" equals 2
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Run with `mcprigor parity FILE`.
|
|
187
|
+
|
|
188
|
+
## Match a snapshot
|
|
189
|
+
|
|
190
|
+
```text
|
|
191
|
+
Expect "structuredContent" matches snapshot "customer" ignoring "$.generatedAt"
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Create or approve the snapshot explicitly:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
mcprigor test customer.mcpr --snapshot customer.snap.json --update-snapshots
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Notifications and progress
|
|
201
|
+
|
|
202
|
+
```text
|
|
203
|
+
Subscribe to resource "catalog://updates"
|
|
204
|
+
Wait for notification "notifications/resources/updated" within 5 seconds
|
|
205
|
+
Unsubscribe from resource "catalog://updates"
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
```text
|
|
209
|
+
Call tool "import_catalog" with progress and cancel after 500 ms with:
|
|
210
|
+
file: "catalog.csv"
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Validate before running
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
mcprigor check tests/acceptance.mcpr
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
For every supported statement and rule, see the [language reference](LANGUAGE-SPEC.md).
|
package/docs/QA-GUIDE.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# QA guide
|
|
2
|
+
|
|
3
|
+
Use this page as a short everyday checklist. For examples, open the [plain-language cookbook](PLAIN-LANGUAGE-COOKBOOK.md).
|
|
4
|
+
|
|
5
|
+
## Everyday workflow
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
mcprigor check tests/acceptance.mcpr
|
|
9
|
+
mcprigor test tests/acceptance.mcpr
|
|
10
|
+
mcprigor test tests/acceptance.mcpr --html report.html
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or use the browser:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
mcprigor workspace .
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Test structure
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
MCP Test 1
|
|
23
|
+
Suite: "Customer service"
|
|
24
|
+
Server: node dist/server.js
|
|
25
|
+
|
|
26
|
+
Test: "An active customer can be found"
|
|
27
|
+
Call tool "find_customer" with:
|
|
28
|
+
customerId: "C-100"
|
|
29
|
+
|
|
30
|
+
Expect "structuredContent.status" equals "active"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
A file needs:
|
|
34
|
+
|
|
35
|
+
1. A suite name
|
|
36
|
+
2. A `Server` command or `MCP URL`
|
|
37
|
+
3. One or more named tests
|
|
38
|
+
4. At least one action in each test
|
|
39
|
+
|
|
40
|
+
## Actions
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
Call tool "name" with:
|
|
44
|
+
input: value
|
|
45
|
+
|
|
46
|
+
Read resource "scheme://resource"
|
|
47
|
+
|
|
48
|
+
Get prompt "name" with:
|
|
49
|
+
argument: value
|
|
50
|
+
|
|
51
|
+
Send "ping"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Expectations
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
Expect it succeeds
|
|
58
|
+
Expect an error
|
|
59
|
+
Expect "field" equals value
|
|
60
|
+
Expect "field" does not equal value
|
|
61
|
+
Expect "field" contains value
|
|
62
|
+
Expect "field" exists
|
|
63
|
+
Expect "items" has 3 items
|
|
64
|
+
Expect "field" is a string
|
|
65
|
+
Expect "field" matches "pattern"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Arrays use indexes such as `items[0].name`.
|
|
69
|
+
|
|
70
|
+
## Variables
|
|
71
|
+
|
|
72
|
+
```text
|
|
73
|
+
Save "structuredContent.id" as "createdId"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Use it later:
|
|
77
|
+
|
|
78
|
+
```text
|
|
79
|
+
Call tool "get_item" with:
|
|
80
|
+
id: "${createdId}"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Setup and cleanup
|
|
84
|
+
|
|
85
|
+
```text
|
|
86
|
+
Setup:
|
|
87
|
+
Call tool "create_fixture"
|
|
88
|
+
|
|
89
|
+
Steps:
|
|
90
|
+
Call tool "verify_fixture"
|
|
91
|
+
|
|
92
|
+
Cleanup:
|
|
93
|
+
Call tool "delete_fixture"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Cleanup is attempted even after a failed step. Keep it safe to repeat.
|
|
97
|
+
|
|
98
|
+
## Data tables
|
|
99
|
+
|
|
100
|
+
```text
|
|
101
|
+
For each row:
|
|
102
|
+
| caseId | input | expected |
|
|
103
|
+
| first | 2 | 4 |
|
|
104
|
+
| second | 3 | 6 |
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Use values as `${row.input}` and `${row.expected}`.
|
|
108
|
+
|
|
109
|
+
## Good QA practices
|
|
110
|
+
|
|
111
|
+
- Assert stable business fields, not entire responses.
|
|
112
|
+
- Use `exists` for generated IDs.
|
|
113
|
+
- Avoid exact timestamp and token assertions.
|
|
114
|
+
- Give tests behavior-focused names.
|
|
115
|
+
- Keep each test independently repeatable.
|
|
116
|
+
- Add cleanup for created data.
|
|
117
|
+
- Validate with `check` before running.
|
|
118
|
+
- Review snapshots and contract updates in pull requests.
|
|
119
|
+
- Keep credentials in environment variables.
|
|
120
|
+
|
|
121
|
+
## Where to go next
|
|
122
|
+
|
|
123
|
+
- [Getting started](GETTING-STARTED.md)
|
|
124
|
+
- [Plain-language cookbook](PLAIN-LANGUAGE-COOKBOOK.md)
|
|
125
|
+
- [Guided authoring](GUIDED-AUTHORING.md)
|
|
126
|
+
- [Data and reusable flows](DATA-AND-REUSE.md)
|
|
127
|
+
- [Troubleshooting](TROUBLESHOOTING.md)
|
|
128
|
+
- [Complete language reference](LANGUAGE-SPEC.md)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# QA workspace
|
|
2
|
+
|
|
3
|
+
Use MCP Rigor in a browser to edit, validate, and run saved tests.
|
|
4
|
+
|
|
5
|
+
## Start it
|
|
6
|
+
|
|
7
|
+
From your test directory:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
mcprigor workspace .
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Choose a port if needed:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
mcprigor workspace . --port 4173
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Open the printed local URL, for example `http://127.0.0.1:4173`.
|
|
20
|
+
|
|
21
|
+
## Daily workflow
|
|
22
|
+
|
|
23
|
+
1. Select a `.mcpr` suite in the left panel.
|
|
24
|
+
2. Edit the plain-language scenario.
|
|
25
|
+
3. Choose **Validate**.
|
|
26
|
+
4. Fix any diagnostic shown below the editor.
|
|
27
|
+
5. Choose **Run tests** or **Run parity**.
|
|
28
|
+
6. Review the result panel.
|
|
29
|
+
7. Save the file.
|
|
30
|
+
|
|
31
|
+
The editor marks unsaved changes. If the file changed elsewhere after you opened it, the workspace refuses to overwrite it and asks you to reload.
|
|
32
|
+
|
|
33
|
+
## What is available
|
|
34
|
+
|
|
35
|
+
- Saved `.mcpr`, YAML, and JSON suites
|
|
36
|
+
- Plain-language editing
|
|
37
|
+
- Validation without server execution
|
|
38
|
+
- Test execution
|
|
39
|
+
- Transport parity execution
|
|
40
|
+
- Terminal-style results
|
|
41
|
+
- Local evidence indexing
|
|
42
|
+
|
|
43
|
+
## Current candidate limits
|
|
44
|
+
|
|
45
|
+
The browser currently focuses on the core edit/validate/run/parity loop. Use the CLI for:
|
|
46
|
+
|
|
47
|
+
- guided test generation;
|
|
48
|
+
- contract discovery and drift updates;
|
|
49
|
+
- detailed evidence comparison;
|
|
50
|
+
- snapshot acceptance;
|
|
51
|
+
- replay;
|
|
52
|
+
- cancellation and streaming run progress.
|
|
53
|
+
|
|
54
|
+
See the [CLI reference](CLI-REFERENCE.md).
|
|
55
|
+
|
|
56
|
+
## Security
|
|
57
|
+
|
|
58
|
+
The workspace:
|
|
59
|
+
|
|
60
|
+
- listens only on the local machine;
|
|
61
|
+
- requires same-origin, CSRF-protected changes;
|
|
62
|
+
- reads targets from saved suites;
|
|
63
|
+
- does not accept arbitrary commands from browser requests;
|
|
64
|
+
- restricts file paths and types;
|
|
65
|
+
- uses atomic saves and content fingerprints;
|
|
66
|
+
- limits files and requests to 1 MiB.
|
|
67
|
+
|
|
68
|
+
Do not expose the workspace through a public proxy. Stop it with `Ctrl+C` when finished.
|
|
69
|
+
|
|
70
|
+
## Problems
|
|
71
|
+
|
|
72
|
+
If a suite does not appear, confirm that:
|
|
73
|
+
|
|
74
|
+
- it is under the selected workspace directory;
|
|
75
|
+
- its extension is `.mcpr`, `.yaml`, `.yml`, or `.json`;
|
|
76
|
+
- it is not inside `node_modules`, `.git`, or `dist`.
|
|
77
|
+
|
|
78
|
+
For server and test failures, see [troubleshooting](TROUBLESHOOTING.md).
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# MCP Rigor documentation
|
|
2
|
+
|
|
3
|
+
Choose the path that matches your role.
|
|
4
|
+
|
|
5
|
+
## QA authors
|
|
6
|
+
|
|
7
|
+
1. [Getting started](GETTING-STARTED.md) — install, connect, and run your first test.
|
|
8
|
+
2. [Plain-language cookbook](PLAIN-LANGUAGE-COOKBOOK.md) — copy-ready scenarios and assertions.
|
|
9
|
+
3. [QA workspace](QA-WORKSPACE.md) — edit and run tests in a browser.
|
|
10
|
+
4. [Data and reusable flows](DATA-AND-REUSE.md) — tables, files, functions, and shared flows.
|
|
11
|
+
5. [Troubleshooting](TROUBLESHOOTING.md) — understand errors and fix common failures.
|
|
12
|
+
|
|
13
|
+
## Test and platform engineers
|
|
14
|
+
|
|
15
|
+
- [Engineer setup](ENGINEER-SETUP.md) — targets, credentials, project layout, and CI.
|
|
16
|
+
- [CLI reference](CLI-REFERENCE.md) — commands, options, outputs, and exit codes.
|
|
17
|
+
- [Language reference](LANGUAGE-SPEC.md) — complete deterministic `.mcpr` syntax.
|
|
18
|
+
- [File extension and migration](FILE-EXTENSION.md) — why MCP Rigor uses `.mcpr`.
|
|
19
|
+
- [State and dependencies](STATE-AND-DEPENDENCIES.md) — share outputs across tests and runs.
|
|
20
|
+
- [Data engineering](DATA-ENGINEERING.md) — types, filters, joins, samples, and caches.
|
|
21
|
+
- [Transport parity](TRANSPORT-PARITY.md) — compare stdio and Streamable HTTP.
|
|
22
|
+
|
|
23
|
+
## Contracts and evidence
|
|
24
|
+
|
|
25
|
+
- [Contract drift](CONTRACT-DRIFT.md)
|
|
26
|
+
- [Protocol evidence](EVIDENCE.md)
|
|
27
|
+
- [Snapshots and replay](SNAPSHOTS-AND-REPLAY.md)
|
|
28
|
+
- [MCP-native behavior](MCP-NATIVE.md)
|
|
29
|
+
|
|
30
|
+
## Extensions and operations
|
|
31
|
+
|
|
32
|
+
- [Extension SDK](EXTENSION-SDK.md)
|
|
33
|
+
- [Stable error model](ERROR-MODEL.md)
|
|
34
|
+
- [Security and retention](SECURITY-AND-RETENTION.md)
|
|
35
|
+
- [Compatibility policy](COMPATIBILITY.md)
|
|
36
|
+
|
|
37
|
+
## Project background
|
|
38
|
+
|
|
39
|
+
These documents explain product design and research rather than everyday usage:
|
|
40
|
+
|
|
41
|
+
- [Specification](SPECIFICATION.md)
|
|
42
|
+
- [Competitive landscape](LANDSCAPE.md)
|
|
43
|
+
|
|
44
|
+
## Fastest adoption path
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
install → create .mcpr test → check → test → add CI → enable evidence
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm install --save-dev mcprigor
|
|
52
|
+
npx mcprigor init tests/acceptance.mcpr
|
|
53
|
+
npx mcprigor check tests/acceptance.mcpr
|
|
54
|
+
npx mcprigor test tests/acceptance.mcpr --html report.html
|
|
55
|
+
```
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Security and evidence retention
|
|
2
|
+
|
|
3
|
+
> Production required: review this page before enabling remote data, custom extensions, or persistent CI evidence.
|
|
4
|
+
|
|
5
|
+
## Implemented controls
|
|
6
|
+
|
|
7
|
+
- URI userinfo and sensitive query/fragment fields are redacted.
|
|
8
|
+
- Known secrets are redacted in raw, percent-encoded, double-encoded, base64, and base64url forms.
|
|
9
|
+
- Terminal reports remove ANSI/CSI/OSC/DCS/APC/PM and unsafe C0/C1 controls.
|
|
10
|
+
- Remote data requires explicit opt-in, credential-free HTTP(S), public DNS/IP destinations, at most three manually checked redirects, ten-second deadlines, and 10 MiB bodies.
|
|
11
|
+
- Remote redirects are revalidated and private/link-local/loopback destinations are rejected.
|
|
12
|
+
- YAML data uses the core schema, duplicate-key detection, alias limits, depth/node limits, and unsafe-key rejection.
|
|
13
|
+
- CSV input caps fields at 1 MiB, rows at 1,000 columns, and total rows at one million; source files remain capped at 10 MiB.
|
|
14
|
+
- XLSX input is capped at 25 MiB compressed and signature-checked before ExcelJS parsing.
|
|
15
|
+
- Extension paths can be restricted with exact `extensions.allowlist` entries.
|
|
16
|
+
- Server stderr is capped per chunk and per session.
|
|
17
|
+
|
|
18
|
+
## Residual risks
|
|
19
|
+
|
|
20
|
+
DNS validation followed by the platform `fetch` still has a rebinding window because the current implementation does not yet pin the resolved address through a custom dispatcher. ExcelJS preflight does not fully inspect ZIP central-directory expansion ratios. Use trusted QA data endpoints and files until strict broker/container backends are available.
|
|
21
|
+
|
|
22
|
+
Worker threads are not a hard sandbox for hostile plugins.
|
|
23
|
+
|
|
24
|
+
## Retention recommendation
|
|
25
|
+
|
|
26
|
+
By default, do not retain raw authorization headers, environment variables, URI queries, downloaded data files, or full sensitive MCP payloads.
|
|
27
|
+
|
|
28
|
+
Suggested policy:
|
|
29
|
+
|
|
30
|
+
- run metadata and sanitized reports: 7–30 days;
|
|
31
|
+
- contract baselines: for the supported release lifetime;
|
|
32
|
+
- normalized traces: 7–14 days unless needed for audit;
|
|
33
|
+
- raw trace payloads: opt-in, restricted, and 24–72 hours;
|
|
34
|
+
- malicious parser samples: encrypted quarantine, audited access, and 24–72 hours;
|
|
35
|
+
- debug logging: time-bounded with automatic expiry.
|
|
36
|
+
|
|
37
|
+
Deletion procedures should cover CI artifacts, object storage, developer workstations, backups, caches, and third-party telemetry. Incident holds need an owner, reason, scope, and expiry.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Semantic Snapshots, Diffs, and Replay
|
|
2
|
+
|
|
3
|
+
## Snapshots
|
|
4
|
+
|
|
5
|
+
Add a plain-language snapshot assertion to the latest action:
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
Call tool "get_customer" with:
|
|
9
|
+
id: "123"
|
|
10
|
+
|
|
11
|
+
Expect "structuredContent" matches snapshot "customer"
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Create or explicitly update snapshots:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
mcprigor test customer.mcpr --snapshot customer.snap.json --update-snapshots
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Verify without modifying the file:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
mcprigor test customer.mcpr --snapshot customer.snap.json
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Missing or changed snapshots fail unless `--update-snapshots` is present. Snapshot names are namespaced by test ID.
|
|
27
|
+
|
|
28
|
+
YAML/JSON suites may ignore volatile paths:
|
|
29
|
+
|
|
30
|
+
```yaml
|
|
31
|
+
snapshots:
|
|
32
|
+
file: customer.snap.json
|
|
33
|
+
ignore:
|
|
34
|
+
- $.generatedAt
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Or on one assertion:
|
|
38
|
+
|
|
39
|
+
```yaml
|
|
40
|
+
snapshot:
|
|
41
|
+
name: customer
|
|
42
|
+
ignore: [$.id, $.createdAt]
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Ignored array positions are removed from the owned snapshot copy; application fields are never ignored automatically.
|
|
46
|
+
|
|
47
|
+
## Semantic diffs
|
|
48
|
+
|
|
49
|
+
Snapshot failures report path-level additions, removals, and replacements:
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
- $.status: "created"
|
|
53
|
+
+ $.status: "pending"
|
|
54
|
+
+ $.metadata.region: "us-east"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Compare two JSON artifacts directly:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
mcprigor snapshot-diff expected.json actual.json
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Objects are compared by sorted keys and arrays by index. Equality remains type-sensitive.
|
|
64
|
+
|
|
65
|
+
## Replay
|
|
66
|
+
|
|
67
|
+
Replay request events from an MCP Rigor trace against a trusted target configuration:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
mcprigor replay .mcprigor/run-1/trace.normalized.jsonl --target server.mcpr
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Replay always creates a fresh MCP connection and initialization handshake. It never executes commands or URLs from the trace.
|
|
74
|
+
|
|
75
|
+
Safe read/list methods are allowed by default. Tool calls are denied unless each exact tool is approved:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
mcprigor replay trace.normalized.jsonl \
|
|
79
|
+
--target server.mcpr \
|
|
80
|
+
--allow-tool get_customer
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Requests execute sequentially. Responses are compared semantically with their recorded correlated response. Changed responses return a path-level diff and exit status `1`.
|
|
84
|
+
|
|
85
|
+
Replay is an API-boundary semantic check, not a simulation of original timing, concurrency, transport bytes, notifications, or external system state.
|