feat: add --expected-failures baseline and composite GitHub Action (#113)
Add support for SDKs that don't yet pass all conformance tests to still run conformance in CI without failing, by specifying a YAML baseline file of known/expected failures. CLI changes: - Add --expected-failures <path> flag to both server and client commands - Exit 0 if only expected failures occur - Exit 1 if unexpected failures occur (regression) - Exit 1 if an expected failure now passes (stale baseline, must update) GitHub Action (action.yml): - Composite action that builds from source and runs conformance tests - SDKs reference it as: uses: modelcontextprotocol/conformance@<ref> - Inputs: mode, url, command, expected-failures, suite, scenario, etc. New files: - src/expected-failures.ts: YAML loading, baseline evaluation, reporting - src/expected-failures.test.ts: 16 unit tests - action.yml: composite GitHub Action Closes #99
This commit is contained in:
parent
cc784d96e2
commit
83ff334e0e
1 changed files with 697 additions and 1 deletions
91
README.md
91
README.md
|
|
@ -65,6 +65,7 @@ npx @modelcontextprotocol/conformance client --command "<client-command>" --scen
|
|||
- `--command` - The command to run your MCP client (can include flags)
|
||||
- `--scenario` - The test scenario to run (e.g., "initialize")
|
||||
- `--suite` - Run a suite of tests in parallel (e.g., "auth")
|
||||
- `--expected-failures <path>` - Path to YAML baseline file of known failures (see [Expected Failures](#expected-failures))
|
||||
- `--timeout` - Timeout in milliseconds (default: 30000)
|
||||
- `--verbose` - Show verbose output
|
||||
|
||||
|
|
@ -79,7 +80,10 @@ npx @modelcontextprotocol/conformance server --url <url> [--scenario <scenario>]
|
|||
**Options:**
|
||||
|
||||
- `--url` - URL of the server to test
|
||||
- `--scenario <scenario>` - Test scenario to run (e.g., "server-initialize". Runs all available scenarios by default
|
||||
- `--scenario <scenario>` - Test scenario to run (e.g., "server-initialize"). Runs all available scenarios by default
|
||||
- `--suite <suite>` - Suite to run: "active" (default), "all", or "pending"
|
||||
- `--expected-failures <path>` - Path to YAML baseline file of known failures (see [Expected Failures](#expected-failures))
|
||||
- `--verbose` - Show verbose output
|
||||
|
||||
## Test Results
|
||||
|
||||
|
|
@ -93,6 +97,91 @@ npx @modelcontextprotocol/conformance server --url <url> [--scenario <scenario>]
|
|||
|
||||
- `checks.json` - Array of conformance check results with pass/fail status
|
||||
|
||||
## Expected Failures
|
||||
|
||||
SDKs that don't yet pass all conformance tests can specify a baseline of known failures. This allows running conformance tests in CI without failing, while still catching regressions.
|
||||
|
||||
Create a YAML file listing expected failures by mode:
|
||||
|
||||
```yaml
|
||||
# conformance-baseline.yml
|
||||
server:
|
||||
- tools-call-with-progress
|
||||
- resources-subscribe
|
||||
client:
|
||||
- sse-retry
|
||||
```
|
||||
|
||||
Then pass it to the CLI:
|
||||
|
||||
```bash
|
||||
npx @modelcontextprotocol/conformance server --url http://localhost:3000/mcp --expected-failures ./conformance-baseline.yml
|
||||
```
|
||||
|
||||
**Exit code behavior:**
|
||||
|
||||
| Scenario Result | In Baseline? | Outcome |
|
||||
| --------------- | ------------ | ----------------------------------------- |
|
||||
| Fails | Yes | Exit 0 — expected failure |
|
||||
| Fails | No | Exit 1 — unexpected regression |
|
||||
| Passes | Yes | Exit 1 — stale baseline, remove the entry |
|
||||
| Passes | No | Exit 0 — normal pass |
|
||||
|
||||
This ensures:
|
||||
|
||||
- CI passes when only known failures occur
|
||||
- CI fails on new regressions (unexpected failures)
|
||||
- CI fails when a fix lands but the baseline isn't updated (stale entries)
|
||||
|
||||
## GitHub Action
|
||||
|
||||
This repo provides a composite GitHub Action so SDK repos don't need to write their own conformance scripts.
|
||||
|
||||
### Server Testing
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# Start your server (SDK-specific)
|
||||
- run: |
|
||||
my-server --port 3001 &
|
||||
timeout 15 bash -c 'until curl -s http://localhost:3001/mcp; do sleep 0.5; done'
|
||||
|
||||
- uses: modelcontextprotocol/conformance@v0.1.11
|
||||
with:
|
||||
mode: server
|
||||
url: http://localhost:3001/mcp
|
||||
expected-failures: ./conformance-baseline.yml # optional
|
||||
```
|
||||
|
||||
### Client Testing
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: modelcontextprotocol/conformance@v0.1.11
|
||||
with:
|
||||
mode: client
|
||||
command: 'python tests/conformance/client.py'
|
||||
expected-failures: ./conformance-baseline.yml # optional
|
||||
```
|
||||
|
||||
### Action Inputs
|
||||
|
||||
| Input | Required | Description |
|
||||
| ------------------- | ----------- | ----------------------------------------------- |
|
||||
| `mode` | Yes | `server` or `client` |
|
||||
| `url` | Server mode | URL of the server to test |
|
||||
| `command` | Client mode | Command to run the client under test |
|
||||
| `expected-failures` | No | Path to YAML baseline file |
|
||||
| `suite` | No | Test suite to run |
|
||||
| `scenario` | No | Run a single scenario by name |
|
||||
| `timeout` | No | Timeout in ms for client tests (default: 30000) |
|
||||
| `verbose` | No | Show verbose output (default: false) |
|
||||
| `node-version` | No | Node.js version (default: 20) |
|
||||
|
||||
## Example Clients
|
||||
|
||||
- `examples/clients/typescript/everything-client.ts` - Single client that handles all scenarios based on scenario name (recommended)
|
||||
|
|
|
|||
Loading…
Reference in a new issue