* chore(deps): consolidate dependabot updates Bumps all pending dependency updates into one commit: Root package: - zod 3.25.76 → 4.3.6 (major) - @types/node 22 → 25 (major) - @modelcontextprotocol/sdk 1.26.0 → 1.27.1 - tsdown 0.15.12 → 0.21.4 - prettier 3.6.2 → 3.8.1 - typescript-eslint 8.48.0 → 8.57.1 - lefthook 2.0.2 → 2.1.4 - eslint/@eslint/js → 9.39.4 (kept at v9, typescript-eslint lacks v10 support) - Regenerated lockfile to pick up transitive security fixes (hono, @hono/node-server, express-rate-limit, flatted, rollup, minimatch, ajv, qs, undici) examples/servers/typescript: - @modelcontextprotocol/sdk → 1.27.1 - Removed zod-to-json-schema (broken with zod v4) - Added zod ^4 as direct dep - Regenerated lockfile GitHub Actions: - actions/setup-node v4 → v6 in action.yml Code changes for zod v4: - ZodError.errors → ZodError.issues (src/index.ts) - .refine() callback signature updated (src/schemas.ts) - everything-server: replaced zodToJsonSchema with SDK's toJsonSchemaCompat helper (handles zod v3/v4/v4-mini) Build fix for tsdown 0.21: - Added --no-fixed-extension to preserve dist/index.js output (tsdown 0.21 defaults to .mjs for type:module packages) * fix: include all platform binaries in lockfile The lockfile was generated on macOS which caused npm to only resolve darwin-arm64 entries for platform-specific optional dependencies (esbuild, rolldown bindings). This broke npm ci on Linux CI runners. Regenerated from a clean state to include all 26 esbuild platforms and all 15 rolldown platform bindings.
97 lines
3 KiB
YAML
97 lines
3 KiB
YAML
name: 'MCP Conformance Tests'
|
|
description: 'Run MCP conformance tests against a server or client implementation'
|
|
inputs:
|
|
mode:
|
|
description: 'Test mode: "server" or "client"'
|
|
required: true
|
|
url:
|
|
description: 'Server URL to test against (required for server mode)'
|
|
required: false
|
|
command:
|
|
description: 'Command to run the client under test (required for client mode)'
|
|
required: false
|
|
expected-failures:
|
|
description: 'Path to YAML file listing expected failures (baseline)'
|
|
required: false
|
|
suite:
|
|
description: 'Test suite to run (server: "active"|"all"|"pending", client: "all"|"auth"|"metadata"|"sep-835")'
|
|
required: false
|
|
scenario:
|
|
description: 'Run a single scenario by name'
|
|
required: false
|
|
timeout:
|
|
description: 'Timeout in milliseconds for client tests (default: 30000)'
|
|
required: false
|
|
default: '30000'
|
|
verbose:
|
|
description: 'Show verbose output (default: false)'
|
|
required: false
|
|
default: 'false'
|
|
node-version:
|
|
description: 'Node.js version to use (default: 22)'
|
|
required: false
|
|
default: '22'
|
|
runs:
|
|
using: 'composite'
|
|
steps:
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v6
|
|
with:
|
|
node-version: ${{ inputs.node-version }}
|
|
|
|
- name: Build conformance tests
|
|
shell: bash
|
|
run: |
|
|
cd "${{ github.action_path }}"
|
|
npm ci
|
|
npm run build
|
|
|
|
- name: Run conformance tests
|
|
shell: bash
|
|
run: |
|
|
CONFORMANCE="${{ github.action_path }}/dist/index.js"
|
|
|
|
# Build the command arguments
|
|
ARGS="${{ inputs.mode }}"
|
|
|
|
# Mode-specific required options
|
|
if [ "${{ inputs.mode }}" = "server" ]; then
|
|
if [ -z "${{ inputs.url }}" ]; then
|
|
echo "::error::The 'url' input is required for server mode"
|
|
exit 1
|
|
fi
|
|
ARGS="${ARGS} --url ${{ inputs.url }}"
|
|
elif [ "${{ inputs.mode }}" = "client" ]; then
|
|
if [ -z "${{ inputs.command }}" ]; then
|
|
echo "::error::The 'command' input is required for client mode"
|
|
exit 1
|
|
fi
|
|
ARGS="${ARGS} --command '${{ inputs.command }}'"
|
|
else
|
|
echo "::error::Invalid mode '${{ inputs.mode }}'. Must be 'server' or 'client'."
|
|
exit 1
|
|
fi
|
|
|
|
# Optional arguments
|
|
if [ -n "${{ inputs.expected-failures }}" ]; then
|
|
ARGS="${ARGS} --expected-failures ${{ inputs.expected-failures }}"
|
|
fi
|
|
|
|
if [ -n "${{ inputs.suite }}" ]; then
|
|
ARGS="${ARGS} --suite ${{ inputs.suite }}"
|
|
fi
|
|
|
|
if [ -n "${{ inputs.scenario }}" ]; then
|
|
ARGS="${ARGS} --scenario ${{ inputs.scenario }}"
|
|
fi
|
|
|
|
if [ "${{ inputs.mode }}" = "client" ]; then
|
|
ARGS="${ARGS} --timeout ${{ inputs.timeout }}"
|
|
fi
|
|
|
|
if [ "${{ inputs.verbose }}" = "true" ]; then
|
|
ARGS="${ARGS} --verbose"
|
|
fi
|
|
|
|
echo "Running: node ${CONFORMANCE} ${ARGS}"
|
|
eval "node ${CONFORMANCE} ${ARGS}"
|