From 31dc2044479bfd577beebba6471ceddb5900b329 Mon Sep 17 00:00:00 2001 From: Vladyslav Sikailo Date: Thu, 24 Jul 2025 14:35:45 +0200 Subject: [PATCH 1/2] Implement Guest Checkout flow --- mcp-server.js | 243 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) diff --git a/mcp-server.js b/mcp-server.js index 40e79f7..d23c6c7 100755 --- a/mcp-server.js +++ b/mcp-server.js @@ -1383,6 +1383,249 @@ server.tool( } ); + +// Guest Order Placement Tools (Complete Adobe Commerce REST API Workflow) + +server.tool( + "create_guest_cart", + "Create a new guest cart and return the cart ID for subsequent operations", + {}, + async () => { + try { + const cartId = await callMagentoApi("/guest-carts", "POST"); + + return { + content: [ + { + type: "text", + text: JSON.stringify( + { + success: true, + cartId: cartId, + message: "Guest cart created successfully" + }, + null, + 2 + ) + } + ] + }; + } catch (error) { + return { + content: [ + { + type: "text", + text: `Error creating guest cart: ${error.response?.data?.message || error.message}` + } + ], + isError: true + }; + } + } +); + +server.tool( + "add_item_to_guest_cart", + "Add products to the guest cart by SKU and quantity", + { + cartId: z.string().describe("Guest cart ID"), + sku: z.string().describe("Product SKU"), + qty: z.number().min(1).describe("Quantity") + }, + async ({ cartId, sku, qty }) => { + try { + const requestData = { + cartItem: { + sku: sku, + qty: qty, + quote_id: cartId + } + }; + + const result = await callMagentoApi(`/guest-carts/${cartId}/items`, "POST", requestData); + + return { + content: [ + { + type: "text", + text: JSON.stringify( + { + success: true, + cartId: cartId, + addedItem: result, + message: "Item added to guest cart successfully" + }, + null, + 2 + ) + } + ] + }; + } catch (error) { + return { + content: [ + { + type: "text", + text: `Error adding item to guest cart: ${error.response?.data?.message || error.message}` + } + ], + isError: true + }; + } + } +); + +server.tool( + "set_guest_cart_shipping_information", + "Set shipping and billing addresses with shipping method (required before order placement)", + { + cartId: z.string().describe("Guest cart ID"), + shippingAddress: z.object({ + firstname: z.string().describe("First name"), + lastname: z.string().describe("Last name"), + street: z.array(z.string()).describe("Street address lines"), + city: z.string().describe("City"), + region: z.string().describe("Region/State"), + region_id: z.number().optional().describe("Region ID (optional)"), + region_code: z.string().optional().describe("Region code (optional)"), + country_id: z.string().describe("Country code (e.g., US, CA, GB)"), + postcode: z.string().describe("Postal/ZIP code"), + telephone: z.string().describe("Phone number"), + email: z.string().email().describe("Email address") + }).describe("Shipping address"), + billingAddress: z.object({ + firstname: z.string().describe("First name"), + lastname: z.string().describe("Last name"), + street: z.array(z.string()).describe("Street address lines"), + city: z.string().describe("City"), + region: z.string().describe("Region/State"), + region_id: z.number().optional().describe("Region ID (optional)"), + region_code: z.string().optional().describe("Region code (optional)"), + country_id: z.string().describe("Country code (e.g., US, CA, GB)"), + postcode: z.string().describe("Postal/ZIP code"), + telephone: z.string().describe("Phone number"), + email: z.string().email().describe("Email address") + }).optional().describe("Billing address (defaults to shipping address if not provided)"), + shippingCarrierCode: z.string().optional().describe("Shipping carrier code (defaults to flatrate)"), + shippingMethodCode: z.string().optional().describe("Shipping method code (defaults to flatrate)") + }, + async ({ cartId, shippingAddress, billingAddress, shippingCarrierCode = "flatrate", shippingMethodCode = "flatrate" }) => { + try { + const finalBillingAddress = billingAddress || shippingAddress; + + const addressData = { + addressInformation: { + shipping_address: shippingAddress, + billing_address: finalBillingAddress, + shipping_carrier_code: shippingCarrierCode, + shipping_method_code: shippingMethodCode + } + }; + + const result = await callMagentoApi(`/guest-carts/${cartId}/shipping-information`, "POST", addressData); + + return { + content: [ + { + type: "text", + text: JSON.stringify( + { + success: true, + cartId: cartId, + shippingInfo: result, + message: "Shipping and billing information set successfully" + }, + null, + 2 + ) + } + ] + }; + } catch (error) { + return { + content: [ + { + type: "text", + text: `Error setting shipping information: ${error.response?.data?.message || error.message}` + } + ], + isError: true + }; + } + } +); + +server.tool( + "place_guest_order", + "Set payment information and place the guest order (must call set_guest_cart_shipping_information first)", + { + cartId: z.string().describe("Guest cart ID"), + email: z.string().email().describe("Guest email address"), + paymentMethod: z.string().optional().describe("Payment method code (defaults to checkmo for check/money order)"), + billingAddress: z.object({ + firstname: z.string().describe("First name"), + lastname: z.string().describe("Last name"), + street: z.array(z.string()).describe("Street address lines"), + city: z.string().describe("City"), + region: z.string().describe("Region/State"), + region_id: z.number().optional().describe("Region ID (optional)"), + region_code: z.string().optional().describe("Region code (optional)"), + country_id: z.string().describe("Country code (e.g., US, CA, GB)"), + postcode: z.string().describe("Postal/ZIP code"), + telephone: z.string().describe("Phone number") + }).optional().describe("Billing address (if different from shipping address set in previous step)") + }, + async ({ cartId, email, paymentMethod = "checkmo", billingAddress }) => { + try { + const paymentData = { + email: email, + paymentMethod: { + method: paymentMethod + } + }; + + if (billingAddress) { + paymentData.billing_address = { + ...billingAddress, + email: email + }; + } + + const orderId = await callMagentoApi(`/guest-carts/${cartId}/payment-information`, "POST", paymentData); + + return { + content: [ + { + type: "text", + text: JSON.stringify( + { + success: true, + cartId: cartId, + orderId: orderId, + email: email, + paymentMethod: paymentMethod, + message: "Guest order placed successfully" + }, + null, + 2 + ) + } + ] + }; + } catch (error) { + return { + content: [ + { + type: "text", + text: `Error placing guest order: ${error.response?.data?.message || error.message}` + } + ], + isError: true + }; + } + } +); + // Start the MCP server with stdio transport async function main() { try { From f1f26760bac3da59fb058fe11fd387dd2714cb48 Mon Sep 17 00:00:00 2001 From: Vladyslav Sikailo Date: Thu, 24 Jul 2025 14:40:26 +0200 Subject: [PATCH 2/2] Implement Guest Checkout flow --- package-lock.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/package-lock.json b/package-lock.json index 6ee299a..b81fb79 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@modelcontextprotocol/sdk": "^1.6.1", "axios": "^1.8.1", "body-parser": "^1.20.3", + "date-fns": "^3.6.0", "dotenv": "^16.4.7", "express": "^4.21.2", "zod": "^3.24.2" @@ -591,6 +592,15 @@ "node": ">= 0.10" } }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1969,6 +1979,11 @@ "vary": "^1" } }, + "date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==" + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",