mcp-assert GitHub Action

April 25, 2026 · View on GitHub

Blackwell Systems mcp-assert: passing

Deterministic correctness testing for MCP servers in CI. One line to add assertion testing to any MCP server repo.

Usage

- uses: blackwell-systems/mcp-assert-action@v1
  with:
    suite: evals/
    server: "npx @modelcontextprotocol/server-filesystem ."
    fixture: test/fixtures/

Inputs

InputRequiredDefaultDescription
suiteYesDirectory containing assertion YAML files
serverNoOverride server command for all assertions
fixtureNoFixture directory ({{fixture}} substitution)
thresholdNo100Minimum pass percentage
timeoutNo30sPer-assertion timeout
versionNolatestmcp-assert version to install
baselineNoBaseline JSON for regression detection
fail-on-regressionNofalseFail if previously-passing assertions regress

Outputs

OutputDescription
passedNumber of assertions that passed
failedNumber of assertions that failed
totalTotal number of assertions

Examples

Basic: test a filesystem server

name: Test MCP Server
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install server
        run: npm install -g @modelcontextprotocol/server-filesystem

      - uses: blackwell-systems/mcp-assert-action@v1
        with:
          suite: evals/
          fixture: test/fixtures/

With threshold and server override

- uses: blackwell-systems/mcp-assert-action@v1
  with:
    suite: evals/
    server: "python -m my_mcp_server"
    threshold: 95
    timeout: 60s

Regression detection

- uses: blackwell-systems/mcp-assert-action@v1
  with:
    suite: evals/
    baseline: baseline.json
    fail-on-regression: true

What it does

  1. Downloads the mcp-assert binary from GitHub Releases
  2. Runs mcp-assert ci with your configuration
  3. Uploads JUnit XML results as an artifact
  4. Uploads shields.io badge JSON as an artifact
  5. Writes GitHub Step Summary automatically
  6. Fails the step if pass rate is below threshold

Add the badge

Once your assertions pass, add the badge to your server's README:

[![mcp-assert: passing](https://raw.githubusercontent.com/blackwell-systems/mcp-assert/main/assets/badge-passing.svg)](https://github.com/blackwell-systems/mcp-assert)

Three variants are available:

PreviewVariantMarkdown
passingPassing[![mcp-assert: passing](https://raw.githubusercontent.com/blackwell-systems/mcp-assert/main/assets/badge-passing.svg)](https://github.com/blackwell-systems/mcp-assert)
scoreScoreDownload SVG, edit the count, host in your repo
failingFailing[![mcp-assert: failing](https://raw.githubusercontent.com/blackwell-systems/mcp-assert/main/assets/badge-failing.svg)](https://github.com/blackwell-systems/mcp-assert)

For dynamic badges that reflect your CI pass rate, see the Badge guide.

Writing assertions

Each assertion is a YAML file that calls one MCP tool and checks the result:

# evals/read_file.yaml
name: read_file returns file contents
server:
  command: npx
  args: ["@modelcontextprotocol/server-filesystem", "{{fixture}}"]
assert:
  tool: read_file
  args:
    path: "{{fixture}}/hello.txt"
  expect:
    not_error: true
    contains: ["Hello, world!"]
timeout: 15s
  • server — how to start your MCP server (binary + args)
  • assert.tool — which MCP tool to call
  • assert.args — arguments passed to the tool
  • assert.expect — deterministic checks on the response (contains, not_error, equals, is_error, json_path, min_results, etc.)
  • {{fixture}} — replaced with the fixture input path at runtime
  • setup — optional list of tool calls to run before the assertion (for stateful tests)

See mcp-assert documentation for the full assertion format reference and example suites.

License

MIT