{"name":"moltline-shopify","description":"Shopify catalogue preparation over MCP. Free: product_csv_check, url_handle, variant_matrix, metafield_key_check. Premium (license): bulk_price_change, payout_estimate. Works on your file, not your store — no API key, no OAuth, no store access.","url":"https://mcp.moltlinestudio.com/shopify","transport":"streamable-http","homepage":"https://moltlinestudio.com/servers.html","serverInfo":{"name":"moltline-shopify","version":"1.1.0"},"toolCounts":{"total":6,"free":4,"premium":2},"protocolVersion":"2025-11-25","protocolVersions":["2024-11-05","2025-03-26","2025-06-18","2025-11-25"],"pricing":{"freeTier":{"tools":4,"price":"0","currency":"USD","description":"Free forever. No account, no registration and no credentials are required to call them."},"details":"https://moltlinestudio.com/.well-known/pricing","terms":"https://moltlinestudio.com/terms.html","agentPayment":{"protocol":"x402","resource":"https://moltlinestudio.com/api","network":"eip155:8453","asset":"USDC","amount":"19000000","discovery":"https://moltlinestudio.com/.well-known/x402","description":"GET or POST the resource to receive an HTTP 402 carrying a machine-readable payment demand; retry with the transaction hash in the X-PAYMENT header and the licence key is returned in the response."},"premium":{"tools":2,"plan":"All-Access","price":"19.00","currency":"USD","period":"month","description":"One licence key unlocks the premium tools on every Moltline server. Billed monthly, cancellable at any time.","purchaseUrl":"https://moltlinestudio.com/#allaccess"}},"authentication":{"required":false},"tools":[{"name":"product_csv_check","description":"Check a product CSV's header row against Shopify's current columns. FREE.\n\nCatches the failure that wastes the most time: a template copied from an\nout-of-date guide, using column names Shopify renamed. Typical input\n{\"header_row\": [\"Handle\", \"Title\", \"Body (HTML)\", \"Variant Price\"]}\nreturns {\"ok\": false, \"missing_required\": [], \"renamed\": [{\"found\":\n\"Handle\", \"use\": \"URL handle\"}, ...], \"unrecognised\": [], \"verdict\": \"...\"}.\n\nUse before an import, on the header row alone. Not for whether the values\nin the rows are valid — check a handle with url_handle and a metafield key\nwith metafield_key_check. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {\"error\": \"<what is wrong and how to fix it>\"} (for example {\"error\": \"header_row must contain at least one column name\"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.","tier":"free","inputSchema":{"additionalProperties":false,"properties":{"header_row":{"items":{"type":"string"},"type":"array","description":"The CSV's first row as a list of column names, exactly as\nwritten in the file, e.g. [\"Handle\", \"Title\", \"Variant Price\"]."},"mode":{"default":"new","pattern":"^(new|update)$","type":"string","description":"\"new\" when creating products, where Shopify requires only Title;\n\"update\" when changing existing ones, where it also requires URL\nhandle. Default \"new\"."}},"required":["header_row"],"type":"object"}},{"name":"url_handle","description":"Turn a product title into a valid, unique Shopify URL handle. FREE.\n\nShopify handles are lowercase, may contain letters, numbers and dashes,\nand may not contain spaces. Typical input {\"title\": \"Men's  Merino Wool\nSocks (2-Pack)\"} returns {\"handle\": \"mens-merino-wool-socks-2-pack\",\n\"valid\": true, \"changed\": true, \"collisions\": []}.\n\nUse when generating handles for an import, or checking one you already\nhave. Not for validating a whole header row — that is product_csv_check. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {\"error\": \"<what is wrong and how to fix it>\"} (for example {\"error\": \"title must not be empty\"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.","tier":"free","inputSchema":{"additionalProperties":false,"properties":{"title":{"type":"string","description":"The product title or a candidate handle, e.g. \"Men's Merino\nWool Socks\"."},"existing":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"default":null,"description":"Handles already used in the store or the file, so a\ncollision can be reported and a suffixed alternative suggested.\nOptional."}},"required":["title"],"type":"object"}},{"name":"variant_matrix","description":"Count the variants a set of options produces, and flag the ceilings. FREE.\n\nOption counts multiply, so three modest lists become a number nobody\nintended. Typical input {\"options\": {\"Size\": [\"S\", \"M\", \"L\"], \"Colour\":\n[\"Black\", \"Navy\"]}} returns {\"option_count\": 2, \"variant_count\": 6,\n\"within_limits\": true, \"per_option\": {\"Size\": 3, \"Colour\": 2}}.\n\nUse before building an import file, to find out whether the catalogue\nneeds splitting into several products. Not for validating the resulting\nCSV's columns — that is product_csv_check. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {\"error\": \"<what is wrong and how to fix it>\"} (for example {\"error\": \"options must contain at least one option\"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.","tier":"free","inputSchema":{"additionalProperties":false,"properties":{"options":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object","description":"Option names mapped to their values, e.g. {\"Size\": [\"S\",\n\"M\"], \"Colour\": [\"Black\"]}. Each list needs at least one value."},"max_variants":{"default":2048,"minimum":1,"type":"integer","description":"Ceiling to check against. Default 2048, which is the\nlimit Shopify announced on 15 October 2025, up from 100. Override\nit if your plan differs."},"max_options":{"default":3,"minimum":1,"type":"integer","description":"Ceiling on distinct option names. Default 3."},"list_rows":{"default":false,"type":"boolean","description":"When true, also return every variant combination. Off by\ndefault because the list can be very large."}},"required":["options"],"type":"object"}},{"name":"metafield_key_check","description":"Validate a metafield namespace and key before you define it. FREE.\n\nShopify metafield namespaces and keys are lowercase alphanumerics and\nunderscores; a capital letter or a dash is rejected at definition time,\nusually after the rest of the import has already run. Typical input\n{\"namespace\": \"custom\", \"key\": \"Care-Instructions\"} returns {\"ok\": false,\n\"problems\": [\"key: dashes and capitals are not allowed\"], \"suggested_key\":\n\"care_instructions\"}.\n\nUse when designing metafields. Not for the CSV column that carries them —\nthat is product_csv_check. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {\"error\": \"<what is wrong and how to fix it>\"}. Every call is read-only and idempotent, so after correcting the input it is always safe to retry.","tier":"free","inputSchema":{"additionalProperties":false,"properties":{"namespace":{"type":"string","description":"The metafield namespace, e.g. \"custom\"."},"key":{"type":"string","description":"The metafield key, e.g. \"care_instructions\"."},"value_type":{"default":"single_line_text_field","type":"string","description":"The intended metafield type, echoed back for your record,\ne.g. \"single_line_text_field\". Not validated against Shopify's\ntype list, which changes."}},"required":["namespace","key"],"type":"object"}},{"name":"bulk_price_change","description":"Apply one pricing rule across a list of prices and show the effect. PREMIUM (license).\n\nPercentage first, then the flat amount, then rounding — stated explicitly\nbecause the order changes the answer. Typical input {\"prices\": [19.99,\n24.5], \"change_pct\": 10, \"charm_ending\": \".99\"} returns {\"rows\":\n[{\"was\": 19.99, \"now\": 21.99}, {\"was\": 24.5, \"now\": 26.99}],\n\"total_was\": 44.49, \"total_now\": 48.98, \"uplift_pct\": 10.09}.\n\nUse when repricing a catalogue before export. Not for what a price nets\nyou after Shopify's fees — that is payout_estimate. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {\"error\": \"<what is wrong and how to fix it>\"} (for example {\"error\": \"prices must contain at least one price\"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.","tier":"premium","inputSchema":{"additionalProperties":false,"properties":{"prices":{"items":{"type":"number"},"type":"array","description":"Current prices, at least one, each greater than 0."},"change_pct":{"default":0,"type":"number","description":"Percentage change applied first, e.g. 10 to raise by 10%\nor -5 to cut by 5%. Default 0."},"change_flat":{"default":0,"type":"number","description":"Flat amount applied after the percentage. Default 0."},"round_to":{"default":0.01,"exclusiveMinimum":0,"type":"number","description":"Rounding increment applied last, e.g. 0.01 or 0.05.\nDefault 0.01."},"charm_ending":{"default":"","type":"string","description":"Force every price to end in these cents, e.g. \".99\" or\n\".95\". Applied after rounding. Empty by default."}},"required":["prices"],"type":"object"}},{"name":"payout_estimate","description":"Estimate what actually lands in the bank after processing fees. PREMIUM (license).\n\nTypical input {\"order_total\": 84.5, \"fee_pct\": 2.9, \"fee_fixed\": 0.3,\n\"orders\": 120, \"refund_rate_pct\": 4} returns {\"gross\": 10140.0, \"fees\":\n330.06, \"refunds\": 405.6, \"net_payout\": 9404.34, \"effective_fee_pct\":\n3.26}.\n\nUse for cash-flow planning. Not as an authoritative fee schedule: rates\ndepend on your plan, country and card mix, so pass your own. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {\"error\": \"<what is wrong and how to fix it>\"}. Every call is read-only and idempotent, so after correcting the input it is always safe to retry.","tier":"premium","inputSchema":{"additionalProperties":false,"properties":{"order_total":{"exclusiveMinimum":0,"type":"number","description":"Value of one order including anything the processor\ntakes a percentage of. Must be greater than 0."},"fee_pct":{"default":2.9,"minimum":0,"type":"number","description":"Percentage fee per transaction. Default 2.9 — a common\npublished rate, not a promise about your account."},"fee_fixed":{"default":0.3,"minimum":0,"type":"number","description":"Fixed fee per transaction. Default 0.30."},"refund_rate_pct":{"default":0,"maximum":100,"minimum":0,"type":"number","description":"Share of order value refunded, as a percentage.\nDefault 0."},"orders":{"default":1,"minimum":1,"type":"integer","description":"How many orders to model. Default 1."}},"required":["order_total"],"type":"object"}}],"resources":[],"prompts":[]}