fix: #2105 add example values to MCP workflow-call OpenAPI 200 schemas - #2275
fix: #2105 add example values to MCP workflow-call OpenAPI 200 schemas#2275tenk-earn wants to merge 1 commit into
Conversation
About the
|
suisuss
left a comment
There was a problem hiding this comment.
Welcome, and thanks for this - the contributing guide is in CONTRIBUTING.md, and ISSUES.md covers when a change needs an issue first.
What this changes
app/api/openapi/route.ts gains a static example on each of the two hardcoded 200-response schemas in buildPathEntry - the write branch's calldata shape and the read branch's executionId/status shape. One unit test pins both. No runtime path is touched.
Does it match the description
Matches, including the choices it makes - the description says outright that the read example is the timeout fallback and that to is deliberately not a live contract.
Scope also matches #2105, whose plan asks for exactly this: a static example on both hardcoded schemas.
Blocking
-
app/api/openapi/route.ts:290-"exec_example_000000000000000000000001"is not a shape this system mints.workflowExecutions.iddefaults togenerateId()(lib/db/schema.ts:674-676), which iscustomAlphabet("0123456789abcdefghijklmnopqrstuvwxyz", 21)- a 21-character lowercase nanoid with no prefix and no underscores. -> An SDK generator infers a Stripe-style prefixed id and writes astartsWith("exec_")check that rejects every real execution id; a caller using the literal against the feedback route passes validation and fails at the row lookup with "not found" rather than a format error. -> Use a 21-character lowercase-alphanumeric literal, and considerpattern: "^[0-9a-z]{21}$"on the property so the format is stated rather than implied. -
app/api/openapi/route.ts:269-270- the calldata example cannot be broadcast.datais the bare 4-bytetransfer(address,uint256)selector, but the field carriesiface.encodeFunctionData(...)output (lib/mcp/calldata.ts:194), which is the selector plus 64 bytes of ABI-encoded arguments - never 4 bytes.tocarries the workflow'scontractAddress(:216), and0x...0001is the ecrecover precompile. -> The write endpoint's entire contract is "here is calldata for you to sign and broadcast"; a client or test fixture templated on this example builds a transaction to a precompile with a truncated selector. -> Selector plus a 32-byte padded recipient and a 32-byte padded amount, and an ordinary contract-shaped address.value: "0"is correct as it stands -calldata.ts:216and:322both emit wei as a decimal string.
Mechanical - actionable as-is
app/api/openapi/route.ts:267, 289- the document declaresopenapi: "3.1.0", and the file's one pre-existing sample (ERROR_SCHEMA.error:88) uses the 2020-12 pluralexamples. The singularexampleis deprecated inside Schema Objects in 3.1, so the file now carries both spellings and a strict renderer ignores the new one.examples: [...]matches what is already there.
With the team
- Whether the read branch's 200 should model the response union rather than illustrate one arm of it.
buildCallCompletionResponsereturnssuccesswithoutputandfeedback,error, orrunningon a 25s timeout (lib/payments/x402/execution-wait.ts:227-249), and the schema declares onlyconst: "running"- so the document's ownx-guidanceat:419tells readers to expectstatus: "success"withoutputwhile the schema says otherwise. I'm weighing aoneOfover the three arms with the example on the success arm against leaving the schema alone and pointing the example atsuccess- the first is more correct and outside what #2105 accepted, the second is one literal. The schema being wrong predates you, and #2105's plan inherited it, so this is not a miss on your part. I'll come back with a verdict shortly.
Verdict
Changes requested - both new literals misdescribe the fields they illustrate, which is the one thing an example has to get right.
The two examples sit in mutually exclusive branches and have no shared state, so the write half can land while the read half waits on the question above; the single test asserting both is the only thing coupling them.
Closes #2105.
Adds a static
exampleon both hardcoded/api/mcp/workflows/{slug}/call200-response schemas inbuildPathEntry:{ type: "calldata", to, data, value }matchinghandleWriteWorkflow/PaymentDeliverableinapp/api/mcp/workflows/[slug]/call/route.ts{ executionId, status: "running" }matching the fire-and-forget timeout fallback documented oncreateAndStartExecutiondata: "0xa9059cbb"is the public ERC-20transfer(address,uint256)selector (first 4 bytes of keccak256 of that signature).value: "0"is a string because the schema typesvalueas string (wei).tois the all-zero-but-one address so the example is a 20-byte hex string without pointing at a live contract.No runtime behaviour change. Unit test pins both examples.
Hackathon note: KeeperHub Agent Economy OSS bounty track; author tenk-earn. Not a cash claim.