diff --git a/.github/agentics/large-payload-tester.md b/.github/agentics/large-payload-tester.md index b7d23018..70b54462 100644 --- a/.github/agentics/large-payload-tester.md +++ b/.github/agentics/large-payload-tester.md @@ -3,106 +3,31 @@ # Large MCP Payload Access Test -You are an AI agent testing the MCP Gateway's ability to handle large payloads and make them accessible to agents. +You are an AI agent trying verify a secret in a file hosted by the filesystem MCP server. ## Your Task -Test that when the MCP Gateway receives large responses from backend MCP servers: -1. It correctly stores payloads to disk with proper session isolation -2. It returns metadata including the payload file path -3. Agents can successfully read the payload files from their mounted session directory - -## Test Protocol - -This test uses a **secret-based verification approach** to ensure end-to-end correctness: - -1. A secret UUID is embedded in a large test file (~500KB) BEFORE the test runs -2. The large test file is stored in `/tmp/mcp-test-fs` on the runner (NOT accessible to gateway) -3. The payload directory `/tmp/jq-payloads` starts EMPTY (created on-demand by gateway) -4. You will use the filesystem MCP server to read the large file containing the secret -5. The gateway will intercept the large response, store it to `/tmp/jq-payloads`, and return metadata -6. You must then read the payload file from the stored location and extract the secret -7. Finally, report whether you successfully retrieved the secret from the payload - -**Key Architecture**: The test file is isolated from the gateway. The gateway can only access it by querying the filesystem MCP server through the MCP protocol, which properly tests the payload storage feature. - -## Test Steps - -### Step 1: Read the Test Secret -- Read `/workspace/test-data/test-secret.txt` to get the secret UUID that was generated for this test run -- This file contains ONLY the secret UUID (e.g., `abc123-def456-ghi789`) -- Store this secret - you'll need it to verify payload retrieval later - -### Step 2: Trigger a Large Payload Response -- Use the filesystem MCP server's `read_file` tool to read `/workspace/test-data/large-test-file.json` -- This file is ~500KB and contains the secret embedded in JSON data -- The gateway should intercept this response and store it to disk - -### Step 3: Extract Metadata from Gateway Response -The gateway's jqschema middleware should transform the response to include: -- `payloadPath`: Full path to the stored payload file -- `preview`: First 500 characters of the response -- `schema`: JSON schema showing structure -- `originalSize`: Size of the full payload -- `queryID`: Unique identifier for this tool call -- `truncated`: Boolean indicating if preview was truncated - -Extract and log: -- The `payloadPath` value -- The `queryID` value -- Whether `truncated` is `true` -- The `originalSize` value - -### Step 4: Read the Payload File -The payload path will be in the format: `/tmp/jq-payloads/{sessionID}/{queryID}/payload.json` - -**IMPORTANT**: The agent's payload directory is mounted to the agent's container. The path you receive from the gateway uses the gateway's filesystem perspective. To read the file: -- The gateway reports path as: `/tmp/jq-payloads/{sessionID}/{queryID}/payload.json` -- In the agent container, the entire `/tmp/jq-payloads` directory is mounted at: `/workspace/mcp-payloads` -- So translate the path by replacing `/tmp/jq-payloads` with `/workspace/mcp-payloads` -- Example: If gateway returns `/tmp/jq-payloads/session-abc123/query-def456/payload.json`, use `/workspace/mcp-payloads/session-abc123/query-def456/payload.json` -- The `{sessionID}` is the actual session identifier, not the literal word "session" -- Use the filesystem MCP server to read the translated path - -Use the filesystem MCP server's `read_file` tool to read the payload file at the translated path. - -### Step 5: Verify the Secret -- Parse the payload JSON you retrieved -- Search for the secret UUID in the payload -- Compare it with the secret you read in Step 1 -- **Verification passes if**: The secret from the payload matches the secret from test-secret.txt -- **Verification fails if**: The secret is missing, doesn't match, or you couldn't read the payload file - -### Step 6: Report Results -Create a summary of the test results including: -1. ✅ or ❌ for each test step -2. The secret value you expected (from test-secret.txt) -3. The secret value you found (from the payload file) -4. Whether secrets matched (PASS/FAIL) -5. Path information (gateway path and agent path used) -6. Any errors encountered +Use the filesystem MCP server to access a file called `large-test-file.json`, which contains a field `secret_reference`. Verify that the secret value matches the content of file `secret.txt` which should also be accessed from the filesystem MCP server. ## Important Notes - **Keep all outputs concise** - Use brief, factual statements -- **Log all key values** - Secret, paths, sizes, queryID +- **Log all key values** - Secret, paths, sizes - **Be explicit about failures** - State exactly what went wrong if any step fails -- **Path translation is critical** - The gateway and agent see different filesystem paths due to volume mounts ## Expected Behavior **Success scenario:** -1. Gateway receives large response from filesystem server -2. Gateway stores payload to: `/tmp/jq-payloads/{sessionID}/{queryID}/payload.json` -3. Gateway returns metadata with `payloadPath` and `truncated: true` -4. Agent reads payload from mounted path: `/workspace/mcp-payloads/session/{queryID}/payload.json` -5. Agent extracts secret from payload -6. Secret matches the expected value from test-secret.txt +1. Agent requests file `large-test-file.json` from filesystem MCP server. +2. MCP server response includes path to full payload. +3. Agent reads full payload from subdirectory of: `/tmp/gh-aw/mcp-payloads` +5. Agent extracts secret from full payload. +6. Agent requests file `secret.txt` from filesystem MCP server. +7. Secrets in `large-test-file.json` and `secret.txt` match. **Failure scenarios to detect:** -- Gateway doesn't intercept/store large payloads (no payloadPath in response) -- Gateway path is incorrect or inaccessible - Agent can't read payload file (permission/mount issues) +- MCP server does not return a payload path - Payload is corrupted or incomplete - Secret doesn't match (data integrity issue) @@ -121,22 +46,11 @@ After running all tests, create an issue with: ## Test Results -1. ✅/❌ Read test secret from control file -2. ✅/❌ Trigger large payload response (>1KB) -3. ✅/❌ Receive gateway metadata with payloadPath -4. ✅/❌ Translate and access payload file path -5. ✅/❌ Read payload file contents -6. ✅/❌ Extract and verify secret - -## Details - - **Expected Secret:** [UUID from test-secret.txt] - **Found Secret:** [UUID from payload] or "NOT FOUND" - **Secret Match:** [YES/NO] -- **Gateway Path:** [path from response] -- **Agent Path:** [translated path used] +- **Payload Path:** [path from response] - **Payload Size:** [originalSize from metadata] -- **Query ID:** [queryID from metadata] ## Conclusion diff --git a/.github/workflows/large-payload-tester.lock.yml b/.github/workflows/large-payload-tester.lock.yml index 2e051645..fb298128 100644 --- a/.github/workflows/large-payload-tester.lock.yml +++ b/.github/workflows/large-payload-tester.lock.yml @@ -19,9 +19,9 @@ # gh aw compile # For more information: https://github.com/github/gh-aw/blob/main/.github/aw/github-agentic-workflows.md # -# Test the MCP Gateway's ability to handle large payloads and provide agent access to stored payload files +# Test the MCP Gateway's ability to handle large payloads # -# frontmatter-hash: f7eecabc3339d0d9ca988eab8db9525c30f85459d0f085a9ef422d32511b9ffd +# frontmatter-hash: f71f2b56c15089813381f75d5f8648bc8622d9220ee73e2e81e87731876c095b name: "Large Payload Tester" "on": @@ -67,6 +67,7 @@ jobs: permissions: contents: read issues: read + pull-requests: read concurrency: group: "gh-aw-copilot-${{ github.workflow }}" env: @@ -97,7 +98,7 @@ jobs: - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - name: Setup Test Environment - run: "# Create test data directory (payload directory will be created by gateway on-demand)\nmkdir -p /tmp/mcp-test-fs\n\n# Generate a unique secret for this test run\n# Use uuidgen if available, otherwise use timestamp with nanoseconds for better entropy\nif command -v uuidgen >/dev/null 2>&1; then\n TEST_SECRET=\"test-secret-$(uuidgen)\"\nelse\n TEST_SECRET=\"test-secret-$(date +%s%N)-$$\"\nfi\necho \"$TEST_SECRET\" > /tmp/mcp-test-fs/test-secret.txt\n\n# Create a large test file (~500KB) with the secret embedded in JSON\n# This file will be read by the filesystem MCP server, causing a large payload\ncat > /tmp/mcp-test-fs/large-test-file.json <<'EOF'\n{\n \"test_run_id\": \"PLACEHOLDER_RUN_ID\",\n \"test_secret\": \"PLACEHOLDER_SECRET\",\n \"test_timestamp\": \"PLACEHOLDER_TIMESTAMP\",\n \"purpose\": \"Testing large MCP payload storage and retrieval\",\n \"data\": {\n \"large_array\": [],\n \"metadata\": {\n \"generated_by\": \"large-payload-tester workflow\",\n \"repository\": \"PLACEHOLDER_REPO\",\n \"workflow_run_url\": \"PLACEHOLDER_URL\"\n }\n },\n \"padding\": \"\"\n}\nEOF\n\n# Use jq to properly populate the JSON with dynamic values and generate large array\n# Generating 2000 items + 400KB padding to create ~500KB file\njq --arg secret \"$TEST_SECRET\" \\\n --arg run_id \"${{ github.run_id }}\" \\\n --arg timestamp \"$(date -Iseconds)\" \\\n --arg repo \"${{ github.repository }}\" \\\n --arg url \"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\" \\\n '.test_secret = $secret | \n .test_run_id = $run_id | \n .test_timestamp = $timestamp | \n .data.metadata.repository = $repo | \n .data.metadata.workflow_run_url = $url | \n .data.large_array = [range(2000) | {id: ., value: (\"item-\" + tostring), secret_reference: $secret, extra_data: (\"data-\" + tostring + \"-\" * 50)}] |\n .padding = (\"X\" * 400000)' \\\n /tmp/mcp-test-fs/large-test-file.json > /tmp/mcp-test-fs/large-test-file.json.tmp\n\nmv /tmp/mcp-test-fs/large-test-file.json.tmp /tmp/mcp-test-fs/large-test-file.json\n\n# Verify file was created and is large enough\nFILE_SIZE=$(wc -c < /tmp/mcp-test-fs/large-test-file.json)\necho \"Created large-test-file.json with size: $FILE_SIZE bytes (~$(($FILE_SIZE / 1024))KB)\"\nif [ \"$FILE_SIZE\" -lt 512000 ]; then\n echo \"WARNING: Test file is smaller than expected ($FILE_SIZE bytes < 500KB)\"\n echo \"Continuing with test anyway...\"\nfi\n\n# Verify secret file was created\nif [ ! -f /tmp/mcp-test-fs/test-secret.txt ]; then\n echo \"ERROR: Secret file was not created\"\n exit 1\nfi\n\necho \"Test environment setup complete\"\necho \"Secret stored in: /tmp/mcp-test-fs/test-secret.txt\"\necho \"Large file stored in: /tmp/mcp-test-fs/large-test-file.json\"\n" + run: "TEST_FS=\"/tmp/mcp-test-fs\"\nSECRET_FILE=\"secret.txt\"\nLARGE_PAYLOAD_FILE=\"large-test-file.json\"\n# Create test data directory (payload directory will be created by gateway on-demand)\nmkdir -p $TEST_FS\n\n# Generate a unique secret for this test run\n# Use uuidgen if available, otherwise use timestamp with nanoseconds for better entropy\nif command -v uuidgen >/dev/null 2>&1; then\n TEST_SECRET=\"test-secret-$(uuidgen)\"\nelse\n TEST_SECRET=\"test-secret-$(date +%s%N)-$$\"\nfi\necho $TEST_SECRET > $TEST_FS/$SECRET_FILE\n# Create a large test file (~500KB) with the secret embedded in JSON\n# This file will be read by the filesystem MCP server, causing a large payload\ncat > $TEST_FS/$LARGE_PAYLOAD_FILE <<'EOF'\n{\n \"test_run_id\": \"PLACEHOLDER_RUN_ID\",\n \"test_timestamp\": \"PLACEHOLDER_TIMESTAMP\",\n \"purpose\": \"Testing large MCP payload storage and retrieval\",\n \"data\": {\n \"large_array\": [],\n \"metadata\": {\n \"generated_by\": \"large-payload-tester workflow\",\n \"repository\": \"PLACEHOLDER_REPO\",\n \"workflow_run_url\": \"PLACEHOLDER_URL\"\n }\n },\n \"padding\": \"\"\n}\nEOF\n\n# Use jq to properly populate the JSON with dynamic values and generate large array\n# Generating 2000 items + 400KB padding to create ~500KB file\njq --arg secret \"$TEST_SECRET\" \\\n --arg run_id \"${{ github.run_id }}\" \\\n --arg timestamp \"$(date -Iseconds)\" \\\n --arg repo \"${{ github.repository }}\" \\\n --arg url \"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\" \\\n '.test_run_id = $run_id | \n .test_timestamp = $timestamp | \n .data.metadata.repository = $repo | \n .data.metadata.workflow_run_url = $url | \n .data.large_array = [range(2000) | {id: ., value: (\"item-\" + tostring), secret_reference: $secret, extra_data: (\"data-\" + tostring + \"-\" * 50)}] |\n .padding = (\"X\" * 400000)' \\\n $TEST_FS/$LARGE_PAYLOAD_FILE > $TEST_FS/$LARGE_PAYLOAD_FILE.tmp\n\nmv $TEST_FS/$LARGE_PAYLOAD_FILE.tmp $TEST_FS/$LARGE_PAYLOAD_FILE\n\n# Verify file was created and is large enough\nFILE_SIZE=$(wc -c < $TEST_FS/$LARGE_PAYLOAD_FILE)\necho \"Created $LARGE_PAYLOAD_FILE with size: $FILE_SIZE bytes (~$(($FILE_SIZE / 1024))KB)\"\nif [ \"$FILE_SIZE\" -lt 512000 ]; then\n echo \"WARNING: Test file is smaller than expected ($FILE_SIZE bytes < 500KB)\"\n echo \"Continuing with test anyway...\"\nfi\n\necho \"Test environment setup complete\"\necho \"Large file stored in: $TEST_FS/$LARGE_PAYLOAD_FILE\"\necho \"Secret stored in $TEST_FS/$SECRET_FILE\"\n" - name: Configure Git credentials env: @@ -407,7 +408,7 @@ jobs: "type": "stdio", "container": "mcp/filesystem", "mounts": [ - "/tmp/mcp-test-fs:/workspace/test-data:ro" + "/tmp/mcp-test-fs:/workspace:ro" ], "tools": [ "*" @@ -895,7 +896,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 env: WORKFLOW_NAME: "Large Payload Tester" - WORKFLOW_DESCRIPTION: "Test the MCP Gateway's ability to handle large payloads and provide agent access to stored payload files" + WORKFLOW_DESCRIPTION: "Test the MCP Gateway's ability to handle large payloads" HAS_PATCH: ${{ needs.agent.outputs.has_patch }} with: script: | diff --git a/.github/workflows/large-payload-tester.md b/.github/workflows/large-payload-tester.md index 924f65ed..8ba10f98 100644 --- a/.github/workflows/large-payload-tester.md +++ b/.github/workflows/large-payload-tester.md @@ -1,6 +1,6 @@ --- name: Large Payload Tester -description: Test the MCP Gateway's ability to handle large payloads and provide agent access to stored payload files +description: Test the MCP Gateway's ability to handle large payloads on: workflow_dispatch: schedule: daily @@ -8,7 +8,8 @@ on: permissions: contents: read issues: read - + pull-requests: read + roles: [admin, maintainer, write] network: @@ -25,7 +26,7 @@ mcp-servers: env: ALLOWED_PATHS: "/workspace" mounts: - - "/tmp/mcp-test-fs:/workspace/test-data:ro" + - "/tmp/mcp-test-fs:/workspace:ro" sandbox: mcp: @@ -41,8 +42,11 @@ safe-outputs: steps: - name: Setup Test Environment run: | + TEST_FS="/tmp/mcp-test-fs" + SECRET_FILE="secret.txt" + LARGE_PAYLOAD_FILE="large-test-file.json" # Create test data directory (payload directory will be created by gateway on-demand) - mkdir -p /tmp/mcp-test-fs + mkdir -p $TEST_FS # Generate a unique secret for this test run # Use uuidgen if available, otherwise use timestamp with nanoseconds for better entropy @@ -51,14 +55,12 @@ steps: else TEST_SECRET="test-secret-$(date +%s%N)-$$" fi - echo "$TEST_SECRET" > /tmp/mcp-test-fs/test-secret.txt - + echo $TEST_SECRET > $TEST_FS/$SECRET_FILE # Create a large test file (~500KB) with the secret embedded in JSON # This file will be read by the filesystem MCP server, causing a large payload - cat > /tmp/mcp-test-fs/large-test-file.json <<'EOF' + cat > $TEST_FS/$LARGE_PAYLOAD_FILE <<'EOF' { "test_run_id": "PLACEHOLDER_RUN_ID", - "test_secret": "PLACEHOLDER_SECRET", "test_timestamp": "PLACEHOLDER_TIMESTAMP", "purpose": "Testing large MCP payload storage and retrieval", "data": { @@ -80,34 +82,27 @@ steps: --arg timestamp "$(date -Iseconds)" \ --arg repo "${{ github.repository }}" \ --arg url "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ - '.test_secret = $secret | - .test_run_id = $run_id | + '.test_run_id = $run_id | .test_timestamp = $timestamp | .data.metadata.repository = $repo | .data.metadata.workflow_run_url = $url | .data.large_array = [range(2000) | {id: ., value: ("item-" + tostring), secret_reference: $secret, extra_data: ("data-" + tostring + "-" * 50)}] | .padding = ("X" * 400000)' \ - /tmp/mcp-test-fs/large-test-file.json > /tmp/mcp-test-fs/large-test-file.json.tmp + $TEST_FS/$LARGE_PAYLOAD_FILE > $TEST_FS/$LARGE_PAYLOAD_FILE.tmp - mv /tmp/mcp-test-fs/large-test-file.json.tmp /tmp/mcp-test-fs/large-test-file.json + mv $TEST_FS/$LARGE_PAYLOAD_FILE.tmp $TEST_FS/$LARGE_PAYLOAD_FILE # Verify file was created and is large enough - FILE_SIZE=$(wc -c < /tmp/mcp-test-fs/large-test-file.json) - echo "Created large-test-file.json with size: $FILE_SIZE bytes (~$(($FILE_SIZE / 1024))KB)" + FILE_SIZE=$(wc -c < $TEST_FS/$LARGE_PAYLOAD_FILE) + echo "Created $LARGE_PAYLOAD_FILE with size: $FILE_SIZE bytes (~$(($FILE_SIZE / 1024))KB)" if [ "$FILE_SIZE" -lt 512000 ]; then echo "WARNING: Test file is smaller than expected ($FILE_SIZE bytes < 500KB)" echo "Continuing with test anyway..." fi - # Verify secret file was created - if [ ! -f /tmp/mcp-test-fs/test-secret.txt ]; then - echo "ERROR: Secret file was not created" - exit 1 - fi - echo "Test environment setup complete" - echo "Secret stored in: /tmp/mcp-test-fs/test-secret.txt" - echo "Large file stored in: /tmp/mcp-test-fs/large-test-file.json" + echo "Large file stored in: $TEST_FS/$LARGE_PAYLOAD_FILE" + echo "Secret stored in $TEST_FS/$SECRET_FILE" timeout-minutes: 10 strict: true