trip-test 0.1.0

Contract testing & regression safety for MCP servers
Documentation

Tripwire — Contract Testing for MCP Servers

Crates.io License: MIT Rust 1.70+

Contract testing and regression safety for Model Context Protocol (MCP) servers. Catch breaking changes before they ship.

The Problem

MCP servers expose tools that AI agents depend on. A schema change breaks every agent that depends on it — silently, with no build-time error or test failure. It surfaces later as a 500 error or refused tool call in production.

Example: Rename a required parameter from limit to max_results.

  • Old agents call: search(q="test", limit=10) → ❌ fails
  • No CI warning
  • No regression test catches it
  • Agents break in production

The Solution

Tripwire treats MCP server contracts like REST APIs. Record a baseline, detect breaking changes in CI, fail PRs automatically.

Think of it as Postman + Jest snapshots, but for MCP servers.

Quick Start

Installation

Via Cargo:

cargo install trip-test

Via Homebrew (coming soon):

brew install trip-test

From source:

git clone https://github.com/arjav1528/trip-test
cd trip-test
cargo install --path .

Basic Usage

1. Connect to your server and list tools:

trip-test connect --server "python -m my_mcp_server"

Output:

Connecting to: python -m my_mcp_server

Tools:
  - search (Search records)
    inputs: { q: string, limit: integer, }
  - fetch (Fetch a record)
    inputs: { id: string, }

2. Record a baseline snapshot:

trip-test record --server "python -m my_mcp_server" --out baseline.trip-test.json

Interactive prompts guide you to invoke a few tools. Captures tool schemas + responses.

3. Check for regressions:

trip-test check --snapshot baseline.trip-test.json --server "python -m my_mcp_server"

Replays recorded exchanges. Passes if behavior matches.

Results: 2 passed, 0 failed

4. Detect breaking changes:

trip-test diff --baseline baseline.trip-test.json --server "python -m my_mcp_server"

Compares contracts. Classifies changes.

🚨 BREAKING CHANGES:
  • search: Parameter 'limit' removed (was required: true)
  • search: Parameter 'max_results' added (required: true)

⚠️  NON-BREAKING CHANGES:
  • search: Description updated

Overall Verdict: BREAKING

CLI Commands

connect

List all tools and their schemas from a server.

trip-test connect --server "python -m my_server"

call

Invoke a single tool and see the exchange.

trip-test call \
  --server "python -m my_server" \
  --tool search \
  --args '{"q":"acme","limit":10}'

Output:

{
  "results": [...],
  "total": 42
}

record

Interactively record tool calls into a snapshot file.

trip-test record --server "python -m my_server" --out baseline.trip-test.json

Prompts you to select tools and invoke them. Captures input + output. Saves to JSON.

check

Replay a snapshot and verify the server still matches.

trip-test check --snapshot baseline.trip-test.json --server "python -m my_server"

Exit code: 0 if all pass, 1 if any fail.

diff

Compare baseline contract vs live server. Classify changes.

trip-test diff --baseline baseline.trip-test.json --server "python -m my_server"

Output: BREAKING, NON-BREAKING, or ADDITIVE changes.

Exit code: 0 if safe, 1 if breaking.

Global Flags

  • --verbose or -v — Enable debug output
  • --help or -h — Show usage
  • --version — Print version
  • --config <file> — Load settings from TOML file

Configuration

TOML Configuration File

Create trip-test.toml in your project root to avoid repeating flags:

[snapshot]
# Path to your baseline snapshot file (relative to repo root)
baseline = "contracts/baseline.trip-test.json"

[server]
# Command to start your MCP server
# Can be any command that spawns an MCP server:
#   - Python: "python -m my_package"
#   - Node.js: "node src/index.js"
#   - Rust: "./target/release/my-server"
#   - Docker: "docker run my-image"
command = "python -m my_mcp_server"

# Timeout for server operations (milliseconds)
timeout_ms = 5000

[diff]
# Whether to treat additive changes (new tools/params) as warnings
treat_additive_as_warning = false

# Whether to treat non-breaking changes (descriptions) as warnings
treat_non_breaking_as_warning = false

Then just run:

trip-test diff --config trip-test.toml

Configuration Examples

Python server with virtual environment:

[server]
command = "python -m venv/bin/python -m my_server"

Node.js server with npm script:

[server]
command = "npm run start:mcp"

Rust server (local development):

[server]
command = "cargo run --release -- --stdio"

Docker container:

[server]
command = "docker run --rm my-mcp-server:latest"

With environment variables:

[server]
# Unix/Linux/Mac
command = "env RUST_LOG=debug ./target/release/server"

# Or use shell directly
command = "bash -c 'export RUST_LOG=debug && ./target/release/server'"

Multiple servers (use separate config files):

# test-server-v1.toml
trip-test diff --config test-server-v1.toml

# test-server-v2.toml
trip-test diff --config test-server-v2.toml

Snapshot File Format

Snapshots are JSON files that capture a contract baseline.

{
  "formatVersion": 1,
  "meta": {
    "name": "my-server-baseline",
    "recordedAt": "2026-08-09T12:00:00Z",
    "serverName": "my-server",
    "serverVersion": "1.0.0"
  },
  "toolCatalog": [
    {
      "name": "search",
      "description": "Search records",
      "inputSchema": {
        "type": "object",
        "properties": {
          "q": { "type": "string" },
          "limit": { "type": "integer" }
        },
        "required": ["q", "limit"]
      }
    }
  ],
  "exchanges": [
    {
      "id": "ex-001",
      "tool": "search",
      "input": { "q": "acme", "limit": 10 },
      "matchMode": "structural",
      "expected": {
        "isError": false,
        "content": [{ "type": "text", "text": "..." }]
      }
    }
  ]
}

Version-control this file. It's your regression baseline.

CI/CD Integration

This section shows how to integrate trip-test into your existing CI/CD pipeline.

GitHub Actions

Basic Setup

Create .github/workflows/trip-test.yml in any MCP server repository:

name: Tripwire Contract Check

on:
  pull_request:
    paths:
      - 'src/**'
      - 'Cargo.toml'
      - '.github/workflows/trip-test.yml'
  push:
    branches: [main]

jobs:
  contract-check:
    name: Check MCP Contract
    runs-on: ubuntu-latest
    
    steps:
      # 1. Checkout code
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      # 2. Setup Rust (if building Rust server)
      - uses: dtolnay/rust-toolchain@stable
      - uses: swatinem/rust-cache@v2

      # 3. Build server
      - name: Build MCP server
        run: cargo build --release

      # 4. Install trip-test
      - name: Install trip-test
        run: cargo install trip-test

      # 5. Run contract check
      - name: Check contract
        id: check
        run: |
          trip-test diff \
            --baseline contracts/baseline.trip-test.json \
            --server "./target/release/my-server" \
            --format json > report.json || true
          cat report.json

      # 6. Comment on PR
      - name: Post PR comment
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const fs = require('fs');
            const report = JSON.parse(fs.readFileSync('report.json'));
            
            let comment = '## 🔍 Tripwire Contract Check\n\n';
            
            if (report.overall_verdict === 'BREAKING') {
              comment += '### ❌ **Breaking Changes Detected**\n\n';
              comment += 'The following breaking changes were found:\n\n';
              comment += '| Tool | Change | Details |\n';
              comment += '|------|--------|----------|\n';
              report.breaking_changes.forEach(c => {
                comment += `| \`${c.tool_name}\` | ${c.change_type} | ${c.details} |\n`;
              });
            } else {
              comment += '### ✅ **Contract is Safe**\n\n';
              comment += 'No breaking changes detected.\n\n';
            }
            
            if (report.non_breaking_changes.length > 0) {
              comment += '\n### ⚠️ Non-Breaking Changes\n\n';
              comment += '| Tool | Change | Details |\n';
              comment += '|------|--------|----------|\n';
              report.non_breaking_changes.forEach(c => {
                comment += `| \`${c.tool_name}\` | ${c.change_type} | ${c.details} |\n`;
              });
            }
            
            if (report.additive_changes.length > 0) {
              comment += '\n### ✨ Additive Changes\n\n';
              comment += '| Tool | Change | Details |\n';
              comment += '|------|--------|----------|\n';
              report.additive_changes.forEach(c => {
                comment += `| \`${c.tool_name}\` | ${c.change_type} | ${c.details} |\n`;
              });
            }
            
            comment += '\n---\n';
            comment += `**Verdict:** \`${report.overall_verdict}\`\n`;
            
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: comment
            });

      # 7. Fail if breaking changes
      - name: Enforce contract safety
        if: always()
        run: |
          if grep -q '"overall_verdict": "BREAKING"' report.json; then
            echo "❌ Breaking changes detected! PR check failed."
            exit 1
          fi

For Python Servers

name: Tripwire Contract Check (Python)

on: [pull_request, push]

jobs:
  contract-check:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.11'
          cache: 'pip'
      
      - name: Install dependencies
        run: |
          pip install -e .
          pip install mcp
      
      - name: Install trip-test
        run: cargo install trip-test
      
      - name: Check contract
        run: |
          trip-test diff \
            --config trip-test.toml \
            --format json > report.json || true
      
      - name: Post result
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const report = JSON.parse(fs.readFileSync('report.json'));
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## Tripwire Check\n\nVerdict: **${report.overall_verdict}**`
            });
      
      - name: Enforce safety
        run: |
          if grep -q '"overall_verdict": "BREAKING"' report.json; then
            exit 1
          fi

For Node.js Servers

name: Tripwire Contract Check (Node.js)

on: [pull_request, push]

jobs:
  contract-check:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Set up Node
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Build
        run: npm run build
      
      - name: Install trip-test
        run: cargo install trip-test
      
      - name: Check contract
        run: |
          trip-test diff \
            --config trip-test.toml \
            --format json > report.json || true
      
      - name: Post result
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const report = JSON.parse(fs.readFileSync('report.json'));
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## Tripwire Check\n\nVerdict: **${report.overall_verdict}**`
            });
      
      - name: Enforce safety
        run: |
          if grep -q '"overall_verdict": "BREAKING"' report.json; then
            exit 1
          fi

GitLab CI

contract-check:
  image: rust:latest
  
  before_script:
    - apt-get update && apt-get install -y python3
    - cargo install trip-test
  
  script:
    # Build your server (adjust for your build system)
    - cargo build --release
    
    # Run contract check
    - trip-test diff --config trip-test.toml --format json > report.json || true
    
    # Check for breaking changes
    - |
      if grep -q '"overall_verdict": "BREAKING"' report.json; then
        echo "❌ Breaking changes detected!"
        cat report.json
        exit 1
      else
        echo "✅ Contract is safe"
      fi
  
  artifacts:
    paths:
      - report.json
    expire_in: 30 days

Generic CI (Jenkins, CircleCI, etc.)

The core pattern is:

# 1. Build server
<your-build-command>

# 2. Install trip-test (if not cached)
cargo install trip-test

# 3. Run check
trip-test diff --config trip-test.toml --format json > report.json || true

# 4. Parse report
if grep -q '"overall_verdict": "BREAKING"' report.json; then
  echo "❌ Contract violation!"
  cat report.json
  exit 1
fi

# 5. Optional: upload report
<your-artifact-upload>

Integration Checklist

When adding trip-test to an existing MCP server:

  • Create trip-test.toml with correct server command
  • Create contracts/ directory
  • Record baseline: trip-test record --server "..." --out contracts/baseline.trip-test.json
  • Commit contracts/baseline.trip-test.json and trip-test.toml
  • Add CI workflow (GitHub Actions / GitLab CI / etc.)
  • Test locally: trip-test diff --config trip-test.toml
  • Open a test PR with intentional breaking change
  • Verify CI fails and posts comment
  • Revert test change
  • Merge and ship ✅

Example: Adding Tripwire to Existing Showpad MCP Server

# 1. Clone server
git clone https://github.com/showpad/mcp-showql
cd mcp-showql

# 2. Install trip-test
cargo install trip-test

# 3. Create config
cat > trip-test.toml << 'EOF'
[snapshot]
baseline = "contracts/baseline.trip-test.json"

[server]
command = "cargo run --release -- --stdio"
timeout_ms = 5000
EOF

# 4. Create contracts directory
mkdir -p contracts

# 5. Record baseline (interactively)
trip-test record --server "cargo run --release -- --stdio" --out contracts/baseline.trip-test.json

# 6. Verify
trip-test diff --config trip-test.toml

# 7. Commit
git add trip-test.toml contracts/baseline.trip-test.json
git commit -m "chore: add MCP contract testing with trip-test"

# 8. Add GitHub Actions
cat > .github/workflows/contract-check.yml << 'EOF'
name: Tripwire Contract Check
on: [pull_request]
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - run: cargo install trip-test
      - run: trip-test diff --config trip-test.toml --format json > report.json || true
      - run: |
          if grep -q '"overall_verdict": "BREAKING"' report.json; then
            exit 1
          fi
EOF

# 9. Push and open PR
git push origin add-trip-test

Troubleshooting CI Integration

CI fails to build server:

  • Check that build command in trip-test.toml works locally
  • Ensure all build dependencies are in CI environment
  • For Python: verify venv/dependencies
  • For Node.js: verify npm install runs
  • For Rust: verify Cargo.toml exists

CI fails to install trip-test:

  • Add rustup if not present: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  • Or pre-build trip-test as a cached artifact
  • Or use: pip install trip-test (if available)

Report not found:

  • Check that server command in config works
  • Verify baseline snapshot exists: contracts/baseline.trip-test.json
  • Run locally first: trip-test diff --config trip-test.toml

PR comment not posting:

  • Ensure GitHub token has issues:write permission
  • Check that issue/PR number is correct
  • Verify repository is not private (or token has private repo access)

Testing Your MCP Server

Complete Testing Workflow

This section walks you through a complete testing setup from scratch.

Step 1: Installation

# Clone your MCP server repository
git clone https://github.com/your-org/my-mcp-server
cd my-mcp-server

# Install trip-test
cargo install trip-test

# Or, if you have Homebrew:
brew install trip-test

Step 2: Create Project Structure

# Create a contracts directory for snapshots
mkdir -p contracts

# Create initial trip-test config
cat > trip-test.toml << 'EOF'
[snapshot]
baseline = "contracts/baseline.trip-test.json"

[server]
command = "python -m my_mcp_server"
timeout_ms = 5000

[diff]
treat_additive_as_warning = false
treat_non_breaking_as_warning = false
EOF

Step 3: Test Server Connection

Verify your server works:

# List all tools exposed by your server
trip-test connect --server "python -m my_mcp_server"

Expected output:

Connecting to: python -m my_mcp_server

Tools:
  - search (Search records)
    inputs: { q: string, limit: integer, }
  - fetch (Fetch a record by ID)
    inputs: { id: string, }
  - create (Create a new record)
    inputs: { title: string, content: string, }

If this fails, check:

  • Is your server command correct? (Try running it manually)
  • Does your server implement the MCP initialize handshake?
  • Are tools properly advertised with inputSchema?

Step 4: Test Individual Tool Calls

Before recording, test each tool manually:

# Test the search tool
trip-test call \
  --server "python -m my_mcp_server" \
  --tool search \
  --args '{"q":"acme","limit":10}'

# Test the fetch tool
trip-test call \
  --server "python -m my_mcp_server" \
  --tool fetch \
  --args '{"id":"123"}'

This verifies:

  • Tools are callable
  • Arguments are accepted
  • Responses are valid JSON
  • No runtime errors

Step 5: Record Baseline Snapshot

Once individual tools work, record the baseline:

# Interactively record exchanges
trip-test record --server "python -m my_mcp_server" --out contracts/baseline.trip-test.json

The tool will:

  1. Connect to your server
  2. List all tools
  3. Prompt you to select tools to test
  4. Ask for input arguments for each
  5. Record the request and response
  6. Save everything to baseline.trip-test.json

Example session:

Connected to: python -m my_mcp_server
Tools available:
 1. search (Search records)
 2. fetch (Fetch a record by ID)

Enter tool number to record (or 0 to finish): 1
Enter arguments as JSON: {"q":"test","limit":5}
Calling search...
Result: {"results":[...],"total":42}
✓ Exchange recorded!

Enter tool number to record (or 0 to finish): 2
Enter arguments as JSON: {"id":"123"}
Calling fetch...
Result: {"id":"123","title":"...","content":"..."}
✓ Exchange recorded!

Enter tool number to record (or 0 to finish): 0
Snapshot saved to: contracts/baseline.trip-test.json

Step 6: Inspect the Snapshot

View what was recorded:

# Pretty-print the snapshot
cat contracts/baseline.trip-test.json | jq .

# Or use your editor
code contracts/baseline.trip-test.json

The snapshot captures:

  • Tool schemas (names, descriptions, input parameters)
  • Recorded exchanges (what you called, what you got back)
  • Metadata (when recorded, server version)

Step 7: Commit Baseline

Lock in your contract:

git add contracts/baseline.trip-test.json trip-test.toml
git commit -m "baseline: record MCP contract v1.0"
git push

Testing Workflow Scenarios

Scenario 1: Developer Makes Safe Change

# Developer adds an optional parameter (safe)
# Edits server code and rebuilds
python -m build

# Run contract check
trip-test check --config trip-test.toml

# Output:
# Replaying ex-001: search
#   Input: {"q": "test", "limit": 5}
#   ✓ PASS
#
# Results: 1 passed, 0 failed

CI will pass

Scenario 2: Developer Makes Breaking Change

# Developer renames a required parameter
# Before: search(q, limit)
# After: search(q, max_results)

# Developer commits and opens PR
git commit -m "api: rename limit → max_results"
git push origin feature-branch

# CI automatically runs
trip-test diff --config trip-test.toml

# Output:
# 🚨 BREAKING CHANGES:
#   • search: Parameter 'limit' removed (was required: true)
#   • search: Parameter 'max_results' added (required: true)
#
# Overall Verdict: BREAKING

CI will fail ❌ and block the PR

Resolution options:

Option A: Fix the breaking change

# Revert to old parameter name
git revert HEAD
git push

# CI passes on new commit

Option B: Intentionally break the contract

# Update baseline to reflect new contract
trip-test record --server "python -m my_mcp_server" --out contracts/baseline.trip-test.json

# Commit the new baseline
git add contracts/baseline.trip-test.json
git commit -m "api: rename limit → max_results (breaking change)"

# New baseline is now locked in
# Future PRs will compare against this

Scenario 3: Detect Non-Breaking Change

# Developer improves tool descriptions
# Before: "Search records"
# After: "Search records by query (case-insensitive)"

trip-test diff --config trip-test.toml

# Output:
# ⚠️  NON-BREAKING CHANGES:
#   • search: Description changed
#
# Overall Verdict: SAFE (no breaking changes)

CI will pass

Real Server Examples

Python MCP Server (with venv)

# Create venv
python -m venv venv
source venv/bin/activate
pip install mcp

# Test connection
trip-test connect --server "python -m my_mcp_server"

# Config file
cat > trip-test.toml << 'EOF'
[server]
command = "python -m my_mcp_server"
EOF

Node.js MCP Server

# Install dependencies
npm install

# Build if needed
npm run build

# Test connection
trip-test connect --server "node dist/index.js"

# Config file
cat > trip-test.toml << 'EOF'
[server]
command = "node dist/index.js"
EOF

Rust MCP Server

# Build in release mode for performance
cargo build --release

# Test connection
trip-test connect --server "./target/release/my-server"

# Config file with proper invocation
cat > trip-test.toml << 'EOF'
[server]
command = "./target/release/my-server --stdio"
EOF

Docker Container

# Build your MCP server image
docker build -t my-mcp-server .

# Test connection
trip-test connect --server "docker run --rm my-mcp-server"

# Config file
cat > trip-test.toml << 'EOF'
[server]
command = "docker run --rm my-mcp-server"
EOF

Testing Multiple Versions

Keep separate configs for different versions:

# test-v1.toml
cat > test-v1.toml << 'EOF'
[snapshot]
baseline = "contracts/baseline-v1.trip-test.json"

[server]
command = "git checkout v1.0.0 && cargo build --release && ./target/release/server"
EOF

# test-v2.toml
cat > test-v2.toml << 'EOF'
[snapshot]
baseline = "contracts/baseline-v2.trip-test.json"

[server]
command = "git checkout main && cargo build --release && ./target/release/server"
EOF

# Test both
trip-test diff --config test-v1.toml
trip-test diff --config test-v2.toml

Testing Against Example Servers

Tripwire ships with example MCP servers for learning:

# Clone trip-test
git clone https://github.com/arjav1528/trip-test
cd trip-test

# Build example servers
cargo build --examples

# Test against basic example
trip-test connect --server "./target/debug/examples/test-server"

# Record baseline from example
trip-test record \
  --server "./target/debug/examples/test-server" \
  --out example-baseline.trip-test.json

# Test against modified example
trip-test diff \
  --baseline example-baseline.trip-test.json \
  --server "./target/debug/examples/test-server-modified"

# Expected output: BREAKING changes detected ❌

How It Works

Architecture

┌──────────────────┐
│   Your CLI       │
│  (trip-test)      │
└────────┬─────────┘
         │ JSON-RPC (stdio)
         │
┌────────▼─────────┐
│  Your MCP Server │
│  (any language)  │
└──────────────────┘
  1. Connect: Spawn your MCP server as a subprocess
  2. Handshake: Perform MCP initialize protocol
  3. List: Fetch all tools + input schemas
  4. Call: Invoke tools with your args
  5. Record: Save exchanges to snapshot JSON
  6. Diff: Compare baseline schema vs live schema
  7. Classify: Mark each change as breaking/non-breaking/additive

Change Classification Rules

Change Class Example
Tool removed BREAKING search tool deleted
Tool added ADDITIVE New fetch tool added
Required param removed BREAKING limit param removed
Required param added BREAKING New required max_results
Optional param added ADDITIVE Optional sort param added
Type narrowed BREAKING stringenum
Type widened NON-BREAKING enumstring
Enum value removed BREAKING Removed option "asc"
Enum value added NON-BREAKING Added option "desc"
Description changed NON-BREAKING Help text updated

Output Formats

Pretty (default)

trip-test diff --baseline baseline.trip-test.json --server "python -m my_server"

Human-readable terminal output with colors.

JSON (for CI)

trip-test diff --baseline baseline.trip-test.json --server "python -m my_server" --format json

Machine-readable JSON:

{
  "overall_verdict": "BREAKING",
  "breaking_changes": [
    {
      "tool_name": "search",
      "change_type": "Parameter removed",
      "details": "Parameter 'limit' was removed (was required: true)",
      "class": "BREAKING"
    }
  ],
  "non_breaking_changes": [...],
  "additive_changes": [...]
}

Limitations & Known Issues

MVP Scope (current):

  • Supports stdio transport only (spawn subprocess)
  • Flat + one level of nested schema changes (handles most cases)
  • No $ref resolution (document workaround)
  • No credential management (pass headers via --header flag planned)
  • No output schema validation (input schemas only)

Planned (Phase 2+):

  • HTTP transport (remote servers)
  • Web UI (interactive tool browser)
  • Watch mode (alert on drift)
  • Snapshot registry (share baselines)
  • Test generation (auto-generate snapshots from schemas)

Contributing

We welcome contributions! See CONTRIBUTING.md for guidelines.

Local Development

# Clone repo
git clone https://github.com/arjav1528/trip-test
cd trip-test

# Build
cargo build

# Test against example server
cargo build --example test-server
cargo run -- connect --server "./target/debug/examples/test-server"

# Run tests
cargo test

# Lint
cargo clippy

# Format
cargo fmt

Project Structure

trip-test/
├── src/
│   ├── main.rs           # CLI entry point
│   ├── lib.rs            # Public API
│   ├── mcp.rs            # MCP protocol client
│   ├── snapshot.rs       # Snapshot file format
│   ├── diff.rs           # Diff engine & classification
│   ├── config.rs         # TOML configuration
│   └── logger.rs         # Logging utilities
├── examples/
│   ├── test-server.rs    # Dummy MCP server for testing
│   └── test-server-modified.rs
├── .github/workflows/
│   └── trip-test.yml      # CI workflow
├── Cargo.toml
├── LICENSE
└── README.md

License

MIT License — see LICENSE for details.

Acknowledgments

Inspired by:

Support

Roadmap

  • Core MVP (snapshot + diff + CI)
  • GitHub Actions integration
  • JSON output for CI/CD
  • Configuration file support
  • Published on crates.io
  • HTTP transport support
  • Web UI dashboard
  • Watch mode & alerts
  • Snapshot registry
  • Test generation

Made with ❤️ for MCP developers

Questions? Open an issue or discussion.