Skip to content

chore: grader MCP follow-ups — op allowlist + rate-abuse subtest#620

Merged
bokelley merged 2 commits into
mainfrom
bokelley/grader-mcp-followups
Apr 19, 2026
Merged

chore: grader MCP follow-ups — op allowlist + rate-abuse subtest#620
bokelley merged 2 commits into
mainfrom
bokelley/grader-mcp-followups

Conversation

@bokelley

Copy link
Copy Markdown
Contributor

Summary

Closes the two deferred items from the #617 review thread (#617 (comment)).

  • Operation-name allowlist on extractOperationFromVectorUrl. Constrains the extracted operation to /^[a-z][a-z0-9_]*$/ (AdCP operation identifier shape per static/schemas/source/enums/operation.json). Throws with a clear diagnostic if a vector URL's last path segment doesn't match — defense in depth against a corrupted compliance cache. No exploit today; fixtures are spec-published.

  • MCP rate-abuse subtest. Spins up a dedicated MCP agent with ADCP_REPLAY_CAP=10 + grades with onlyVectors: ['020-rate-abuse'] / rateAbuseCap: 10 / allowLiveSideEffects: true / transport: 'mcp'. Validates the 11-request flood trips request_signature_rate_abuse under MCP transport. Previously the rate-abuse flow was only tested against the raw-HTTP reference verifier.

  • Adds ADCP_REPLAY_CAP env override to test-agents/seller-agent-signed-mcp.ts so tests can tune the cap without forking the agent.

Test plan

  • npx tsc --noEmit clean
  • npm run build:lib clean
  • npm run format:check clean
  • npm test — 3947/3949 pass, 0 fail, 2 skipped (pre-existing)
  • MCP tests: 5/5 pass (up from 4; added rate-abuse subtest)

🤖 Generated with Claude Code

bokelley and others added 2 commits April 19, 2026 10:12
Two follow-ups deferred from #617.

1. Operation-name allowlist in extractOperationFromVectorUrl. Throws if
   the vector URL's last path segment isn't an AdCP operation identifier
   (lowercase_snake_case). No exploit today — fixtures are spec-published
   — but blocks arbitrary bytes from reaching params.name if a compliance
   cache gets corrupted or swapped.

2. MCP rate-abuse subtest. Dedicated MCP agent with ADCP_REPLAY_CAP=10 +
   grader configured with matching cap + onlyVectors=['020-rate-abuse']
   + allowLiveSideEffects=true. Validates the 11-request flood trips
   request_signature_rate_abuse under MCP transport. Adds
   ADCP_REPLAY_CAP env override to seller-agent-signed-mcp.ts so tests
   can tune the cap without touching agent code.

All 5 MCP tests pass; full suite 3947/3949 (2 pre-existing skips). Refs
#617 review thread.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three low-severity items from the expert-review round:

1. NaN guard on ADCP_REPLAY_CAP. A typo (ADCP_REPLAY_CAP=abc) turns
   Number.parseInt into NaN; InMemoryReplayStore's `size >= NaN` check
   is always false, silently disabling the rate-abuse guard. Now falls
   back to the default on any non-positive int.

2. PORT clobber fix in startMcpAgent. Spread overrides BEFORE PORT so
   a caller passing { PORT: '9999' } in overrides can't override the
   explicit port argument. Prophylactic — no caller does this today.

3. Aspirational comment reference in builder.ts operation allowlist.
   The reviewer noted `static/schemas/source/enums/operation.json`
   isn't in the local sync (it lives in the adcp spec repo). Reworded
   to reference the actual observable source — task values in
   compliance/cache/{version}/protocols/**/*.yaml.

Bonus: documented the port-stride requirement (≥2) for parallel runs
of request-signing-grader-mcp.test.js, since the rate-abuse subtest
binds PORT+1.

All 5 MCP tests still pass. Refs #620 review thread.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bokelley bokelley merged commit 934eea2 into main Apr 19, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant