v0.9.0 — a YAML tool that contradicts itself no longer loads
Breaking. A YAML tool whose declaration contradicts its own query no longer loads. A server carrying one will refuse to start instead of running it wrongly, and the message names the tool, the file and the field.
The line this release deletes
convertInputType ended in default: z.string(), so any type: the loader did not implement quietly became a string.
type: integerloaded fine, then rejected5and accepted"5"— sending Shopify text where the schema wanted a number, with the error blaming the caller's argument rather than the declaration.- It is the same line that made
arraylook supported before 0.8.0 implemented it:type: arrayloaded, then failed at call time withExpected string, received array.
The vocabulary is now exactly string, number, boolean, enum, array, object. A missing type: is refused too, and a nested field is named by path:
YAML tool "my_tool" at "./my-tools/thing.yaml": input "lines.items.quantity" has unknown
type "integer". Valid types: string, number, boolean, enum, array, object
input: and your GraphQL variables must be the same set
A YAML tool has no handler — the engine runs shopify.query(tool.graphql, validatedInput) and nothing else — so the declared input is the variable set. Either half of a mismatch is silent at runtime:
- a variable no
input:declares can never be supplied, and GraphQL reads an absent optional variable as "not specified"; - an
input:no variable uses is validated and then dropped, so the tool advertises a parameter it ignores.
One typo produces both, which is how it gets caught. A $ inside a string literal, a # comment or a """ block is not counted, so query: "price:>$100" still loads.
What that check found on its first run
complete_draft_order, shipped in custom-tools/ since it was added, declared payment_pending while its mutation used $paymentPending. The caller's value was validated, sent under a name the mutation did not reference, and $paymentPending arrived null — which Shopify reads as false.
Asking for a pending payment completed the draft order as paid. No error, anywhere. The mutation now uses $payment_pending; the tool's input schema is unchanged, so callers need no edit.
Upgrading
If a tool stops loading, the message names the exact field. There are only two shapes: a type: that is not in the list, and an input:/$variable set that does not match.
Every YAML tool reachable from the release machine — the 2 shipped here and 12 in the reference consumer — was loaded through the new loader before release. One failed: complete_draft_order, above.
Full changelog: https://github.com/callobuzz/cob-shopify-mcp/blob/main/CHANGELOG.md