Skip to content

[CHORE][TESTING]: Checklist for complete E2E validation testing #351

@crivetimihai

Description

@crivetimihai

📋 Overview

Complete comprehensive testing of input validation implementation across all MCP Gateway API endpoints, including both admin and non-admin APIs. Includes additional data validation steps to ensure all validation rules are working correctly and protecting against XSS, injection attacks, and data integrity issues.

Related PRs: #339 (admin endpoints), #340 (non-admin endpoints), #337 (UI escaping), #338 (lint fixes)

Copy/paste this checklist, and add [X] if a test passes, or ❌ if it failed, Add > why it failed info.

🚀 Pre-Test Setup

Setting up MCP Servers for Testing

  • cd mcp-servers/go/fast-time-server; make build # Build the fast-time-server
  • ./dist/fast-time-server -transport=dual --port 8101 # No auth /sse and /http endpoints
  • ./dist/fast-time-server -transport=dual --port 8102 -auth-token=secret123 # Auth /sse and /http endpoints
  • python3 -m mcpgateway.translate --stdio "uvx mcp-server-git" --port 8103 # Start the mcp-server-git via translate http://127.0.0.1:8103/sse

Environment Setup

  • cp .env .env.backup; cp .env.example .env # start with fresh .env
  • make compose-stop docker-stop # stop previous running containers
  • make venv install install-dev # install using a fresh venv
  • make serve # start a server using gunicorn
  • Verify server starts on http://localhost:4444

Testing and Linting

  • make test # All tests pass
  • make lint # No linting issues
  • make tomllint jsonlint yamllint # TOML, JSON and YAML validation passes
  • make smoketest # Container build based smoketest passes
  • make docker-run-ssl-host docker-logs # Start the container

Authentication Setup

  • curl -sk https://localhost:4444/version # Test auth prevents access. Expected: {"detail":"Not authenticated"}
  • export MCPGATEWAY_BEARER_TOKEN=$(python3 -m mcpgateway.utils.create_jwt_token -u admin --secret my-test-key)
  • curl -sk -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" https://localhost:4444/version # Test auth works

Health Checks

  • curl -sk https://localhost:4444/health # Returns healthy
  • curl -sk https://localhost:4444/ready # Returns ready
  • curl -sk -o /dev/null -w "%{http_code}" https://localhost:4444/health # Returns 200

Container Testing (Compose)

  • make docker-stop compose-down compose-rm compose-up # Stop single container with sqlite, start compose with Postgres and Redis. Database migration passes. Container is healthy.
  • make compose-logs # No errors in compose logs

🌟 Happy Path Testing - Normal Operations

1️⃣ Register MCP Gateways

Register No-Auth Time Server (port 8101)

  • Register gateway:

    curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
         -H "Content-Type: application/json" \
         -d '{"name":"time_server_noauth","url":"http://127.0.0.1:8101/sse","transport":"SSE"}' \
         https://localhost:4444/gateways | jq

    Expected: ✅ Success (201), returns gateway with ID

  • Verify gateway health:

    curl -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
         https://localhost:4444/gateways | jq '.items[] | select(.name=="time_server_noauth") | {name, health_status}'

    Expected: ✅ health_status: "healthy"

Register Auth Time Server (port 8102)

  • Register gateway with auth:
    curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
         -H "Content-Type: application/json" \
         -d '{
           "name":"time_server_auth",
           "url":"http://127.0.0.1:8102/sse",
           "transport":"SSE",
           "headers":{"Authorization":"Bearer secret123"}
         }' \
         https://localhost:4444/gateways | jq

    Expected: ✅ Success (201)

Register Git Server (port 8103)

  • Register git gateway:
    curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
         -H "Content-Type: application/json" \
         -d '{"name":"git_server","url":"http://127.0.0.1:8103/sse","transport":"SSE"}' \
         https://localhost:4444/gateways | jq

    Expected: ✅ Success (201)

2️⃣ Verify Tool Discovery

  • List all discovered tools:

    curl -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
         https://localhost:4444/tools | jq '.items[] | {name, description, gateway}'

    Expected: ✅ Should see tools like: get_system_time, convert_time, list_commits, etc.

  • Get specific tool details:

    curl -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
         https://localhost:4444/tools | jq '.items[] | select(.name=="get_system_time")'

    Expected: ✅ Full tool schema with inputSchema

3️⃣ Test Tool Invocation

Test Time Tool (No Auth)

  • Call get_system_time:
    curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
         -H "Content-Type: application/json" \
         -d '{
           "jsonrpc": "2.0",
           "method": "get_system_time",
           "params": {"timezone": "Europe/Dublin"},
           "id": 1
         }' \
         https://localhost:4444/rpc | jq

    Expected: ✅ Returns current time in Dublin timezone

Test Time Tool (With Auth)

  • Call convert_time:
    curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
         -H "Content-Type: application/json" \
         -d '{
           "jsonrpc": "2.0",
           "method": "convert_time",
           "params": {
             "time": "2025-01-10T12:00:00Z",
             "source_timezone": "UTC",
             "target_timezone": "America/New_York"
           },
           "id": 2
         }' \
         https://localhost:4444/rpc | jq

    Expected: ✅ Returns converted time

Test Git Tool

  • List commits:
    curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
         -H "Content-Type: application/json" \
         -d '{
           "jsonrpc": "2.0",
           "method": "list_commits",
           "params": {"repo": "https://github.com/modelcontextprotocol/servers", "max_count": 5},
           "id": 3
         }' \
         https://localhost:4444/rpc | jq

    Expected: ✅ Returns last 5 commits

4️⃣ Create Virtual Servers

  • Get tool IDs for virtual server:

    # Save tool IDs to variables
    TIME_TOOL_ID=$(curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      https://localhost:4444/tools | jq -r '.items[] | select(.name=="get_system_time") | .id')
    CONVERT_TOOL_ID=$(curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      https://localhost:4444/tools | jq -r '.items[] | select(.name=="convert_time") | .id')
    GIT_TOOL_ID=$(curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      https://localhost:4444/tools | jq -r '.items[] | select(.name=="list_commits") | .id')
    
    echo "Time Tool ID: $TIME_TOOL_ID"
    echo "Convert Tool ID: $CONVERT_TOOL_ID"
    echo "Git Tool ID: $GIT_TOOL_ID"
  • Create time utilities virtual server:

    curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
         -H "Content-Type: application/json" \
         -d "{
           \"name\": \"time_utilities\",
           \"description\": \"Time and timezone utilities\",
           \"associatedTools\": [\"$TIME_TOOL_ID\", \"$CONVERT_TOOL_ID\"]
         }" \
         https://localhost:4444/servers | jq

    Expected: ✅ Success (201), returns server with UUID

  • Create development tools virtual server:

    curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
         -H "Content-Type: application/json" \
         -d "{
           \"name\": \"dev_tools\",
           \"description\": \"Development and git tools\",
           \"associatedTools\": [\"$GIT_TOOL_ID\"]
         }" \
         https://localhost:4444/servers | jq

    Expected: ✅ Success (201)

5️⃣ Test Virtual Server SSE Endpoints

  • Get server UUIDs:

    TIME_SERVER_UUID=$(curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      https://localhost:4444/servers | jq -r '.items[] | select(.name=="time_utilities") | .id')
    DEV_SERVER_UUID=$(curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      https://localhost:4444/servers | jq -r '.items[] | select(.name=="dev_tools") | .id')
    
    echo "Time Server UUID: $TIME_SERVER_UUID"
    echo "Dev Server UUID: $DEV_SERVER_UUID"
  • Test SSE endpoint exists:

    curl -N -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
         "https://localhost:4444/servers/$TIME_SERVER_UUID/sse" \
         --max-time 2 2>&1 | head -5

    Expected: ✅ SSE stream starts (will see "data:" events)

6️⃣ Create Additional Resources and Prompts

Create Resources

  • Create README resource:

    curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
         -H "Content-Type: application/json" \
         -d '{
           "uri": "docs/readme",
           "name": "readme",
           "description": "Project README",
           "mimeType": "text/markdown",
           "content": "# MCP Gateway\n\nWelcome to the MCP Gateway!"
         }' \
         https://localhost:4444/resources | jq

    Expected: ✅ Success (201)

  • Create config resource:

    curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
         -H "Content-Type: application/json" \
         -d '{
           "uri": "config/app",
           "name": "app_config",
           "mimeType": "application/json",
           "content": "{\"version\": \"1.0.0\", \"debug\": false}"
         }' \
         https://localhost:4444/resources | jq

    Expected: ✅ Success (201)

Create Prompts

  • Create analysis prompt:
    curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
         -H "Content-Type: application/json" \
         -d '{
           "name": "code_analysis",
           "description": "Analyze code quality",
           "template": "Analyze the following {{ language }} code:\n\n{{ code }}\n\nFocus on: {{ focus_areas }}",
           "arguments": {
             "language": {"type": "string", "required": true},
             "code": {"type": "string", "required": true},
             "focus_areas": {"type": "string", "required": false}
           }
         }' \
         https://localhost:4444/prompts | jq

    Expected: ✅ Success (201)

7️⃣ Test REST Tool Creation

  • Create a REST API tool:
    curl -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
         -H "Content-Type: application/json" \
         -d '{
           "name": "weather_api",
           "url": "https://api.openweathermap.org/data/2.5/weather",
           "description": "Get current weather data",
           "integrationType": "REST",
           "requestType": "GET",
           "headers": {"X-API-Key": "demo-key"},
           "inputSchema": {
             "type": "object",
             "properties": {
               "q": {"type": "string", "description": "City name"},
               "units": {"type": "string", "enum": ["metric", "imperial"]}
             },
             "required": ["q"]
           }
         }' \
         https://localhost:4444/tools | jq

    Expected: ✅ Success (201)

8️⃣ Test Wrapper Integration

  • Export server catalog URL:

    export MCP_SERVER_CATALOG_URLS="https://localhost:4444/servers/$TIME_SERVER_UUID"
    export MCP_AUTH_TOKEN=$MCPGATEWAY_BEARER_TOKEN
  • Test wrapper initialization:

    echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | \
      python3 -m mcpgateway.wrapper 2>/dev/null | jq

    Expected: ✅ Returns capabilities including tools

9️⃣ Verify Everything Works

  • Summary check:
    echo "=== System Status ==="
    echo "Gateways: $(curl -sk -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" https://localhost:4444/gateways | jq '.total')"
    echo "Tools: $(curl -sk -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" https://localhost:4444/tools | jq '.total')"
    echo "Resources: $(curl -sk -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" https://localhost:4444/resources | jq '.total')"
    echo "Prompts: $(curl -sk -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" https://localhost:4444/prompts | jq '.total')"
    echo "Servers: $(curl -sk -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" https://localhost:4444/servers | jq '.total')"

    Expected: ✅ All counts > 0

📊 Admin API Validation Testing (/admin/*)

Tools - Admin Endpoints

Valid Input Tests

  • Create MCP tool with valid data:

    curl -X POST http://localhost:4444/admin/tools \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "valid_mcp_tool",
        "url": "https://example.com/mcp",
        "description": "Valid MCP tool for testing",
        "integrationType": "MCP",
        "requestType": "SSE",
        "headers": {"Content-Type": "application/json"},
        "inputSchema": {"type": "object", "properties": {"input": {"type": "string"}}}
      }'

    Expected: ✅ Success (201)

  • Create REST tool with valid data:

    curl -X POST http://localhost:4444/admin/tools \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "valid_rest_tool",
        "url": "https://api.example.com/v1/endpoint",
        "description": "Valid REST API tool",
        "integrationType": "REST",
        "requestType": "POST",
        "headers": {"Authorization": "Bearer token"}
      }'

    Expected: ✅ Success (201)

Invalid Input Tests

  • XSS attempt in name:

    curl -X POST http://localhost:4444/admin/tools \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"name": "<script>alert(1)</script>", "url": "https://example.com"}'

    Expected: ❌ 422 - "Tool name cannot contain HTML special characters"

  • SQL injection pattern:

    curl -X POST http://localhost:4444/admin/tools \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"name": "tool\"; DROP TABLE tools; --", "url": "https://example.com"}'

    Expected: ❌ 422 - "Special characters not allowed"

  • Invalid URL scheme:

    curl -X POST http://localhost:4444/admin/tools \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"name": "test_tool", "url": "javascript:alert(1)"}'

    Expected: ❌ 422 - "URL contains unsupported or potentially dangerous protocol"

  • Name too long (>255 chars):

    curl -X POST http://localhost:4444/admin/tools \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"name": "'"$(printf 'a%.0s' {1..300})"'", "url": "https://example.com"}'

    Expected: ❌ 422 - "Tool name exceeds maximum length of 255"

  • Wrong request type for MCP:

    curl -X POST http://localhost:4444/admin/tools \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "test_tool",
        "url": "https://example.com",
        "integrationType": "MCP",
        "requestType": "POST"
      }'

    Expected: ❌ 422 - "Request type 'POST' not allowed for MCP integration"

Resources - Admin Endpoints

Valid Input Tests

  • Create markdown resource:

    curl -X POST http://localhost:4444/admin/resources \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "uri": "docs/guide",
        "name": "user_guide",
        "description": "Comprehensive user guide",
        "mimeType": "text/markdown",
        "content": "# User Guide\n\nWelcome to our application!"
      }'

    Expected: ✅ Success (201)

  • Create JSON resource:

    curl -X POST http://localhost:4444/admin/resources \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "uri": "config/settings",
        "name": "app_config",
        "description": "Application configuration",
        "mimeType": "application/json",
        "content": "{\"version\": \"1.0.0\", \"features\": {\"auth\": true}}"
      }'

    Expected: ✅ Success (201)

Invalid Input Tests

  • Directory traversal in URI:

    curl -X POST http://localhost:4444/admin/resources \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"uri": "../../etc/passwd", "name": "test", "content": "data"}'

    Expected: ❌ 422 - "directory traversal"

  • HTML injection in content:

    curl -X POST http://localhost:4444/admin/resources \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "uri": "test",
        "name": "test",
        "content": "<iframe src=\"evil.com\"></iframe>"
      }'

    Expected: ❌ 422 - "contains HTML tags"

  • Invalid MIME type:

    curl -X POST http://localhost:4444/admin/resources \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "uri": "test",
        "name": "test",
        "mimeType": "not/a/mime"
      }'

    Expected: ❌ 422 - "Invalid MIME type format"

Prompts - Admin Endpoints

Valid Input Tests

  • Create prompt with arguments:
    curl -X POST http://localhost:4444/admin/prompts \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "greeting_prompt",
        "description": "Personalized greeting template",
        "template": "Hello {{ name }}, welcome to {{ company }}!",
        "arguments": {
          "name": {"type": "string", "required": true},
          "company": {"type": "string", "required": true}
        }
      }'

    Expected: ✅ Success (201)

Invalid Input Tests

  • Script tag in template:

    curl -X POST http://localhost:4444/admin/prompts \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "test_prompt",
        "template": "<script>alert(1)</script>"
      }'

    Expected: ❌ 422 - "Template contains HTML tags"

  • Event handler in template:

    curl -X POST http://localhost:4444/admin/prompts \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "test_prompt",
        "template": "<div onclick=\"alert(1)\">Click me</div>"
      }'

    Expected: ❌ 422 - "Template contains event handlers"

Gateways - Admin Endpoints

Valid Input Tests

  • Create SSE gateway:
    curl -X POST http://localhost:4444/admin/gateways \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "time_server",
        "url": "http://127.0.0.1:8002/sse",
        "description": "Time server gateway",
        "transport": "SSE"
      }'

    Expected: ✅ Success (201)

Invalid Input Tests

  • Invalid transport type:
    curl -X POST http://localhost:4444/admin/gateways \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "test_gateway",
        "url": "http://example.com",
        "transport": "INVALID"
      }'

    Expected: ❌ 422 - "Invalid transport type"

Servers - Admin Endpoints

Valid Input Tests

  • Create server with associations:
    curl -X POST http://localhost:4444/admin/servers \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "github_server",
        "description": "GitHub integration server",
        "icon": "https://github.githubassets.com/assets/GitHub-Mark-ea2971cee799.png",
        "associatedTools": ["valid_mcp_tool"],
        "associatedResources": ["user_guide"],
        "associatedPrompts": ["greeting_prompt"]
      }'

    Expected: ✅ Success (201)

Invalid Input Tests

  • Invalid icon URL:
    curl -X POST http://localhost:4444/admin/servers \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "test_server",
        "icon": "javascript:alert(1)"
      }'

    Expected: ❌ 422 - "Icon URL contains unsupported protocol"

🌐 Non-Admin API Validation Testing

Tools - Public Endpoints

  • Test POST /tools with XSS:

    curl -X POST http://localhost:4444/tools \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "<script>",
        "url": "hello_world",
        "integration_type": "REST",
        "request_type": "GET"
      }'

    Expected: ❌ 422 - Validation error

  • Test PUT /tools/{tool_id} with valid update:

    curl -X PUT http://localhost:4444/tools/valid_rest_tool \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"description": "Updated description"}'

    Expected: ✅ Success

Resources - Public Endpoints

  • Test POST /resources with same valid/invalid payloads as admin
  • Test PUT /resources/{uri:path} with path traversal:
    curl -X PUT "http://localhost:4444/resources/../../etc/passwd" \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"content": "hacked"}'

    Expected: ❌ 400 - "Invalid URI"

Prompts - Public Endpoints

  • Test prompt execution with args:

    curl -X POST http://localhost:4444/prompts/greeting_prompt \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "args": {
          "name": "Alice",
          "company": "Acme Corp"
        }
      }'

    Expected: ✅ "Hello Alice, welcome to Acme Corp!"

  • Test with XSS in args:

    curl -X POST http://localhost:4444/prompts/greeting_prompt \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "args": {
          "name": "Alice<script>alert(1)</script>",
          "company": "Acme Corp"
        }
      }'

    Expected: ❌ 422 - Args should be sanitized

Gateways - Public Endpoints

  • Test POST /gateways with invalid name (from your test):

    curl -X POST http://localhost:4444/gateways \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "<script>",
        "url": "hello_world",
        "transport_type": "SSE"
      }'

    Expected: ❌ 422 - Validation error

  • Test with invalid URL:

    curl -X POST http://localhost:4444/gateways \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "test",
        "url": "hello_world",
        "transport_type": "SSE"
      }'

    Expected: ❌ 422 - Invalid URL format

  • Test with excessively long name (from your test):

    curl -X POST http://localhost:4444/gateways \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "g7@LaPX#8qcz2MUEYwK(0R^4tnJZidBb+ol5DFVeN[Wpm93A1hI{O*}xG6vCTHsSQkfj!ry]-u=|>L8Z`$aXz(mY+B#R5c92nPUVW%Jd0MEhxA>oGwfqNevKg3s^F[Ht@L1bC)!=j4}TDQpIMlSZuNKOGm7~yRxJ9Bv+W>XizCkf(nlY&82#oqr5PA$JU}a*M-Z=@wEgphdL3VKI]CtNYX^69bmfT{+es0!u7~FWrOHv1LRydGC2qx]jz#n<BkDMU@8V(PZ&%)aA$T5hXowmiEgYl!J^bfM=NQcu7StdKCrx{4I}-vO3p9Bn+LzWYkjPQe@Hm%NXI!ow2^vTuCc5z#RYg9Bh(03LdaP=F&bZUJ-E+n4x$NKrsK{1t)V8MyidGLqj7AQhCmWR^pOs6ewXF2nlUYz!#@g0}93b&dT5K+%vH=[INBOMZra)*yLqxEJpCWfUhoR7twYnm+VX*ikgtUZP@#LAd1&cw29H^qOjbs5eyR~KlFC63MVnXpG%uWTdN(B!m+=rzJY4{aoE}-x7I9lf^UQKT5Xyw3C$gBAOHpN0RJqEk7dPGn4vztMbXCl%V!&L[uWYrosTI@9j=1ZKh3fxca}+-5NOM^PYUgFEG!bpLXqHd7Am]T#o*KWn{u0CJrszv2yt&934VXUIljMC",
        "url": "http://localhost:8000/sse",
        "transport_type": "SSE"
      }'

    Expected: ❌ 422 - Name too long

RPC Endpoint

  • Valid RPC request:

    curl -X POST http://localhost:4444/rpc \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "jsonrpc": "2.0",
        "method": "tools.list",
        "params": {},
        "id": 1
      }'

    Expected: ✅ Success

  • Invalid method name:

    curl -X POST http://localhost:4444/rpc \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "jsonrpc": "2.0",
        "method": "<script>alert(1)</script>",
        "id": 1
      }'

    Expected: ❌ 422 - "Invalid method name format"

📊 API Verification from Post-Deployment Checklist

  • curl -sk https://localhost:4444/tools | jq '.total' # Lists tools
  • curl -sk https://localhost:4444/resources | jq '.total' # Lists resources
  • curl -sk https://localhost:4444/prompts | jq '.total' # Lists prompts
  • curl -sk https://localhost:4444/gateways | jq '.total' # Lists gateways
  • curl -sk https://localhost:4444/servers | jq '.total' # Lists servers
  • curl -sk https://localhost:4444/admin/tools | jq '.total' # Admin tools endpoint
  • curl -sk https://localhost:4444/admin/resources | jq '.total' # Admin resources endpoint
  • curl -sk https://localhost:4444/admin/prompts | jq '.total' # Admin prompts endpoint

📚 OpenAPI & Documentation

  • curl -sk https://localhost:4444/openapi.json | jq '.info.title' # Returns "MCP Gateway"
  • curl -sk https://localhost:4444/docs | grep -q "MCP Gateway" && echo "✓ Swagger UI loads"
  • curl -sk https://localhost:4444/redoc | grep -q "ReDoc" && echo "✓ ReDoc loads"

🔍 Edge Case Testing

Empty/Whitespace Values

  • Empty string for required field:

    curl -X POST http://localhost:4444/tools \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"name": "", "url": "https://example.com"}'

    Expected: ❌ 422 - "cannot be empty"

  • Only whitespace:

    curl -X POST http://localhost:4444/tools \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"name": "   ", "url": "https://example.com"}'

    Expected: ❌ 422 - Should be stripped and fail

Unicode Characters

  • Unicode in name:
    curl -X POST http://localhost:4444/tools \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"name": "test_tool_🚀", "url": "https://example.com"}'

    Expected: ❌ 422 - Non-alphanumeric characters

JSON Depth Limits

  • Deeply nested JSON (>10 levels):
    DEEP_JSON='{"a":{"b":{"c":{"d":{"e":{"f":{"g":{"h":{"i":{"j":{"k":"too deep"}}}}}}}}}}}'
    curl -X POST http://localhost:4444/tools \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d "{
        \"name\": \"test_tool\",
        \"url\": \"https://example.com\",
        \"inputSchema\": $DEEP_JSON
      }"

Error Handling Verification

  • curl -sk https://localhost:4444/tools/nonexistent | jq '.detail' # Returns 404 "Tool not found"
  • curl -sk -X POST https://localhost:4444/tools -H "Content-Type: application/json" -d '{}' | jq '.detail[0].msg' # 422 validation error
  • curl -sk https://localhost:4444/invalid-endpoint | jq '.detail' # 404 "Not Found"

🗄️ Database & Migrations

  • make db-current # Shows current revision (no pending migrations)
  • sqlite3 data/mcpgateway.db ".tables" | grep -E "(tools|resources|prompts)" | wc -l # Should show 3+ tables
  • sqlite3 data/mcpgateway.db "SELECT COUNT(*) FROM tools;" | grep -E "[0-9]+" # Has tools

📝 Log Verification

  • tail -n 20 logs/mcpgateway.log | grep -c ERROR # Should be 0
  • grep "Application startup complete" logs/mcpgateway.log | tail -1 # Startup logged
  • grep "Created.*tool.*valid_mcp_tool" logs/mcpgateway.log # Tool creation logged

🔍 Process & Port Checks

  • lsof -i :4444 | grep LISTEN | wc -l # Port 4444 is listening (should be ≥1)
  • ps aux | grep "[m]cpgateway.server" | wc -l # Process running (should be ≥1)
  • netstat -tuln | grep 4444 # Shows listening on port 4444

🐳 Container Health (if using Docker)

  • docker ps --filter name=mcpgateway --format "table {{.Names}}\t{{.Status}}" | grep healthy # Container healthy
  • docker logs mcpgateway 2>&1 | tail -10 | grep -c ERROR # Should be 0
  • docker exec mcpgateway curl -s localhost:8000/health | jq '.status' # Internal health "healthy"
  • docker inspect mcpgateway | jq '.[0].State.Health.Status' # Should be "healthy"

🎭 UI Verification (Admin Interface)

  • Navigate to http://localhost:4444/admin/
  • Verify all existing data displays correctly (no broken layouts)
  • Create entities through UI with special characters
  • Verify HTML entities are escaped in display: <>&"'/
  • Check browser console for JavaScript errors
  • Test "Test Server Connectivity" feature # Note: Currently has issue "Error: Invalid URL: URL is required"

✅ Final Integration Test

  • List all created entities:
    echo "=== Created Entities ==="
    echo "Tools: $(curl -sk https://localhost:4444/tools | jq -r '.items[] | select(.name | test("valid_mcp_tool|valid_rest_tool|weather_api")) | .name' | tr '\n' ', ')"
    echo "Resources: $(curl -sk https://localhost:4444/resources | jq -r '.items[] | select(.name | test("readme|app_config|user_guide")) | .name' | tr '\n' ', ')"
    echo "Prompts: $(curl -sk https://localhost:4444/prompts | jq -r '.items[] | select(.name | test("code_analysis|greeting_prompt")) | .name' | tr '\n' ', ')"
    echo "Gateways: $(curl -sk https://localhost:4444/gateways | jq -r '.items[] | select(.name | test("time_server|git_server")) | .name' | tr '\n' ', ')"
    echo "Servers: $(curl -sk https://localhost:4444/servers | jq -r '.items[] | select(.name | test("time_utilities|dev_tools|github_server")) | .name' | tr '\n' ', ')"
  • All entities should be listed and active

🧹 Cleanup (Optional)

  • Delete test data if needed:
    # Delete validation test entities
    curl -sk -X DELETE https://localhost:4444/tools/valid_mcp_tool
    curl -sk -X DELETE https://localhost:4444/tools/valid_rest_tool
    curl -sk -X DELETE https://localhost:4444/tools/weather_api
    curl -sk -X DELETE https://localhost:4444/prompts/greeting_prompt
    curl -sk -X DELETE https://localhost:4444/servers/github_server
    
    # Delete happy path entities
    curl -sk -X DELETE https://localhost:4444/gateways/time_server_noauth
    curl -sk -X DELETE https://localhost:4444/gateways/time_server_auth
    curl -sk -X DELETE https://localhost:4444/gateways/git_server
    curl -sk -X DELETE https://localhost:4444/resources/docs/readme
    curl -sk -X DELETE https://localhost:4444/resources/config/app
    curl -sk -X DELETE https://localhost:4444/prompts/code_analysis
    curl -sk -X DELETE https://localhost:4444/servers/time_utilities
    curl -sk -X DELETE https://localhost:4444/servers/dev_tools

🚀 Performance Testing

  • Measure response time for validation (should be < 10ms):
    time curl -X POST http://localhost:4444/tools \
      -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"name": "perf_test", "url": "https://example.com"}'

🏁 Final Steps

  • make pre-commit # All pre-commit hooks pass
  • make ci # Full CI pipeline passes locally
  • make clean build # Can build fresh from scratch
  • Test with both make serve and make serve-prod

✅ Sign-off Criteria

  • All validation rules working as expected
  • No XSS or injection vulnerabilities
  • Error messages helpful for users
  • Performance within acceptable limits (<10ms)
  • UI displays all data safely # Note: "Test Server Connectivity" has known issue
  • No regression in existing functionality
  • All test scenarios pass

Metadata

Metadata

Labels

choreLinting, formatting, dependency hygiene, or project maintenance chorescicdIssue with CI/CD process (GitHub Actions, scaffolding)devopsDevOps activities (containers, automation, deployment, makefiles, etc)testingTesting (unit, e2e, manual, automated, etc)

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions