Order parts from code, or let your agent do it.
Everything you can do on the website works for AI agents and code: upload a file, configure it, see prices and ship dates for every speed, and order. Pick the way you want to connect.
Claude, ChatGPT, Hermes or OpenClaw. Quote in the chat, pay on our website. No code.
Claude Code, Cursor, VS Code or any MCP client, signed in to your account or an agent account.
Upload, quote and order from your own code. Pay by card link or in USDC with no human.
Use it in a chat app
Add Make Parts Now to your AI app and ask for a quote. Quotes don't need an account. Nothing is charged in the chat: you get a link to review the order and pay on makepartsnow.com. Each file gets random ids that stay in your chat. Where the app tells us who you are (ChatGPT) or runs on your computer, they work only for you. Claude doesn't, so there they work like a private link, and only the answer to the upload itself shows a picture of the part. Deleting a file needs the delete token from that upload, unless the file is in your signed-in account.
In Settings, open Connectors, choose Add custom connector, and paste this URL. Ask for a quote, then drop your CAD file into the upload box that appears in the chat.
https://makepartsnow.com/mcp/assistant
In Settings, under Apps & Connectors, add a custom connector with this URL. Custom connectors need developer mode turned on. Attach your CAD file to the message and ask for a quote.
https://makepartsnow.com/mcp/assistant
Install the Make Parts Now plugin from Cursor Directory, or add this MCP server. Ask the agent to quote a CAD file in your project; it uploads the file itself.
https://makepartsnow.com/mcp/assistant?client=cursor
Install our extension, then ask for a quote or run /make-parts-now:quote ./bracket.step 25. Gemini uploads the file itself after you confirm the command.
gemini extensions install https://github.com/makepartsnow/makepartsnow-gemini
Install our plugin from the Hermes plugin catalog: hermes plugins install make-parts-now, then hermes plugins enable make-parts-now. It adds the server and our quoting skill. Hermes can upload a CAD file from your computer itself, or give you an upload link. Without the plugin, add this to ~/.hermes/config.yaml and run hermes mcp test makepartsnow:
mcp_servers:
makepartsnow:
url: "https://makepartsnow.com/mcp/assistant?client=hermes"
tools:
exclude: [get_order_status]Install our plugin from ClawHub and approve what it adds (one skill and one MCP server, no code), then start a new session. If the install stops asking for capability consent, add --accept-capabilities. OpenClaw can upload a CAD file from your computer itself, or give you an upload link.
openclaw plugins install clawhub:@makepartsnow/make-parts-now
Try “Quote 25 of this bracket in black nylon,” “Change that to 50 pieces,” “I'll take Standard, send me the checkout link,” or “Where is my order?” One part per quote; STL, STEP, 3MF or OBJ up to 95 MB.
Checking an order needs your Make Parts Now account: Claude, ChatGPT, Cursor and Gemini CLI ask you to sign in when you ask. Hermes and OpenClaw connect without an account and point you to your orders page; OpenClaw can add a signed-in connection, see the plugin's README. See how we handle your files in the privacy policy.
get_manufacturing_optionscreate_upload_linkanalyze_partquote_partupdate_quotecreate_checkout_linkget_order_statusdelete_uploaded_partConnect a coding agent or MCP client
Coding tools and agents that work on their own use our full MCP server (Streamable HTTP). It can do everything the REST API can, so it needs a signed-in account. Chat apps use the simpler /mcp/assistant above instead: it quotes without an account, and paying always happens on our website.
https://makepartsnow.com/mcp
Sign in with your website account (OAuth)
Add the server, and your client opens a sign-in page. The agent acts for your account and creates payment links you approve.
claude mcp add --transport http makepartsnow https://makepartsnow.com/mcp
Add to Cursor in one click, or add "makepartsnow": { "url": "https://makepartsnow.com/mcp" } under mcpServers in .cursor/mcp.json.
Add "makepartsnow": { "type": "http", "url": "https://makepartsnow.com/mcp" } under servers in .vscode/mcp.json.
Or use an agent account key
For an agent with no person behind it, create an agent account and send its key as a Bearer token. The agent can then pay in USDC itself.
{
"mcpServers": {
"makepartsnow": {
"url": "https://makepartsnow.com/mcp",
"headers": { "Authorization": "Bearer mpn_agent_..." }
}
}
}get_capabilitiescreate_agent_accountget_accountupdate_accountupload_partget_upload_urlget_partcreate_quoteget_quotelist_quotesupdate_quotediscard_quotecreate_checkout_linkpay_with_cryptoget_orderlist_ordersset_refund_preferencerequest_order_cancellationEvery tool returns structuredContent. create_quote, get_quote and update_quote declare a typed outputSchema (QuoteView), the same quote the REST API returns and the OpenAPI spec describes.
/mcp and /api/agent/v1 change additively within v1: new tools, endpoints and optional fields can appear, and nothing is removed or renamed.
Listed in the official MCP Registry as com.makepartsnow/manufacturing and on Smithery.
No MCP setup? Install our agent skill. It teaches Claude Code, Codex, Cursor, Gemini CLI and other coding agents to export your CAD, quote it, compare quantities and open checkout through the REST API below.
npx skills add makepartsnow/skills
Build on the REST API
Base URL https://makepartsnow.com/api/agent/v1, authenticated with your agent key as a Bearer token. Full reference in the interactive docs. Agents pay one of two ways:
The agent builds the quote and gets a Stripe Checkout link. A person pays by card. Best for assistants working for someone.
The agent creates its own account and pays in USDC on Base using the x402 protocol. Orders are placed fully autonomously.
1. Create an agent account
No human sign-up needed. The key is shown once.
curl -X POST https://makepartsnow.com/api/agent/v1/accounts \
-H 'content-type: application/json' \
-d '{"name":"PartsBot","email":"[email protected]","accept_terms":true,
"ship_to":{"name":"Receiving","line1":"100 Main St","city":"Austin",
"state":"TX","postal_code":"78701","country":"US"}}'
# => {"account_id":"agt_...","api_key":"mpn_agent_...","webhook_secret":"..."}2. Upload a part
Send the file as multipart, a public https URL, or base64. Every upload must confirm the file has no controlled data (policy).
curl -X POST https://makepartsnow.com/api/agent/v1/uploads \ -H "Authorization: Bearer $MPN_KEY" \ -F [email protected] -F no_controlled_data=true curl "https://makepartsnow.com/api/agent/v1/parts/prt_...?wait=20" -H "Authorization: Bearer $MPN_KEY" # waits up to 20 s (max 30) for "status": "ready" or "failed"; poll again while it is still pending. # Once ready, the response lists capable_processes
3. Quote it
Valid ids for processes, materials, colors, finishes, and services come from GET /api/agent/v1/capabilities.
curl -X POST https://makepartsnow.com/api/agent/v1/quotes \
-H "Authorization: Bearer $MPN_KEY" -H 'content-type: application/json' \
-H 'Idempotency-Key: 7f1c...' \
-d '{"items":[{"part_id":"prt_...","quantity":20,
"config":{"units":"mm","process":"sls","material":"sls_pa12",
"finishes":["sls_black_dye"],
"services":[{"id":"heat_set_inserts","count":4,"size":"M3"}]}}],
"speed":"fast"}'The response includes per-part prices, a tiers list with the price, ship date and arrival date for each speed, shipping options, totals, design warnings on each item (items[].pricing.warnings), next_steps written for agents, and share_url, the quote's page for a person to see. If an option is wrong, ready is false and blocking names the field and the allowed values.
4a. Send a payment link
curl -X POST https://makepartsnow.com/api/agent/v1/quotes/qt_.../checkout -H "Authorization: Bearer $MPN_KEY"
# => {"checkout_url":"https://checkout.stripe.com/...","expires_at":...}4b. Or pay in USDC (x402)
Call /pay. You get HTTP 402 with x402 payment requirements (exact USDC amount, network, and pay-to address) in the body and the PAYMENT-REQUIRED header. Sign the payment with any x402 client and retry with PAYMENT-SIGNATURE. Account credit is applied first. If credit covers the whole total, you get HTTP 409 with credit_confirmation_required and a credit_confirmation token instead, and nothing is charged. Call /pay?confirm_credit=<token> to place the order.
# pip install "x402[evm,httpx]" eth-account
from eth_account import Account
from x402 import x402Client
from x402.http.clients import x402HttpxClient
from x402.mechanisms.evm.exact.register import register_exact_evm_client
client = x402Client()
register_exact_evm_client(client, Account.from_key(PRIVATE_KEY))
client.set_spend_controls({"max_amount_per_payment": "$1500"}) # the library refuses over $1 by default
async with x402HttpxClient(client, base_url="https://makepartsnow.com") as c:
r = await c.post("/api/agent/v1/quotes/qt_.../pay",
headers={"Authorization": f"Bearer {MPN_KEY}"})
print(r.json()["order"])Webhooks
Set callback_url on your account and we POST these events for your parts, quotes and orders, signed with your webhook secret:
part.analyzedquote.readyquote.needs_revieworder.paidorder.status_changedorder.shippedorder.delayedorder.canceledorder.refunded{"event": "order.shipped", "data": {...}, "id": "evt_123", "created": 1760000000}
X-MPN-Signature: t=1760000000,v1=<hex HMAC-SHA256(secret, "t." + raw_body)>Any answer other than 2xx is a failure. We retry up to 5 times, after 10 s, 60 s, 5 min, 15 min and 1 h. A retry keeps the same id, so dedupe on it.
Check the signature against the raw body and accept the request when any v1 matches. For 24 hours after you rotate the secret the header carries two, v1=<previous>,v1=<new>, so your receiver can switch without missing events.
import hashlib, hmac, time
def verify(secret: str, header: str, raw_body: bytes, tolerance: int = 300) -> bool:
# X-MPN-Signature holds two v1 values during a secret rotation: accept any that matches.
fields = [p.split("=", 1) for p in header.split(",") if "=" in p]
ts = next((v for k, v in fields if k == "t"), "")
if not ts.isdigit() or abs(time.time() - int(ts)) > tolerance:
return False
mac = hmac.new(secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256).hexdigest()
return any(k == "v1" and hmac.compare_digest(v, mac) for k, v in fields)
const crypto = require("node:crypto");
// rawBody: the request body as a Buffer, before any JSON parsing. Accepts any v1 (two during a secret rotation).
function verify(secret, header, rawBody, toleranceS = 300) {
const fields = header.split(",").map((p) => p.split("="));
const ts = (fields.find(([k]) => k === "t") || [])[1] || "";
if (!/^[0-9]+$/.test(ts) || Math.abs(Date.now() / 1000 - Number(ts)) > toleranceS) return false;
const mac = crypto.createHmac("sha256", secret).update(ts + ".").update(rawBody).digest();
return fields.some(([k, v]) => k === "v1" && /^[0-9a-f]{64}$/.test(v) && crypto.timingSafeEqual(Buffer.from(v, "hex"), mac));
}
Rotate the secret (the new one is shown once, and the account email is told, at most once a day), send a webhook.test event, see your deliveries from the last 30 days, and send one again with the same id:
curl -X POST https://makepartsnow.com/api/agent/v1/account/webhook-secret/rotate -H "Authorization: Bearer $MPN_KEY"
# => {"webhook_secret":"...","previous_valid_until":"...","note":"..."}
curl -X POST https://makepartsnow.com/api/agent/v1/account/webhooks/test -H "Authorization: Bearer $MPN_KEY"
curl "https://makepartsnow.com/api/agent/v1/account/webhooks/deliveries?limit=20" -H "Authorization: Bearer $MPN_KEY"
# => {"deliveries":[{"id":"evt_123","event":"webhook.test","status":"delivered","response_status":200,...}],...}
curl -X POST https://makepartsnow.com/api/agent/v1/account/webhooks/deliveries/evt_123/redeliver -H "Authorization: Bearer $MPN_KEY"Errors
Errors are JSON with a stable code to branch on, plus retry_after_s when you should wait. MCP tool errors read Error executing tool <name>: <status>: <CODE>: <message>. Every response has an X-Request-Id header, also in error bodies as request_id; quote it when you report a problem. Codes are only ever added:
{"message": "Too many open quotes (limit 50). Discard quotes you no longer need, or order them.",
"next_steps": ["List your open quotes: GET /quotes?status=open (MCP: list_quotes).", "..."],
"error": true, "status": 429, "code": "OPEN_QUOTE_LIMIT", "request_id": "3f2c0a1e-..."}INVALID_ARGUMENTINVALID_CONFIGAUTH_REQUIREDPAYMENT_REQUIREDFORBIDDENSPENDING_LIMITNOT_FOUNDCONFLICTQUOTE_CLOSEDQUOTE_NOT_READYCREDIT_CONFIRMATION_REQUIREDIDEMPOTENCY_IN_PROGRESSEXPIREDFILE_TOO_LARGEUNSUPPORTED_FILE_TYPERATE_LIMITEDOPEN_QUOTE_LIMITUPLOAD_QUOTASERVICE_UNAVAILABLEAGENTS_PAUSEDINTERNAL_ERRORLimits and rules
- 60 requests per minute per key. Responses include clear errors with the allowed values.
- The current numbers, including upload quotas, body sizes and spending limits, are in
limitsfromGET /api/agent/v1/capabilities(MCP:get_capabilities). - Files up to 95 MB; STEP, STL, 3MF, OBJ. CNC needs STEP.
- US shipping only. Quotes hold their price for 30 days.
- Up to 50 open quotes per account. List them with
GET /api/agent/v1/quotes(MCP:list_quotes) and close the ones you no longer need withPOST /api/agent/v1/quotes/qt_.../discard(discard_quote). - Retry safely: send an
Idempotency-Keyheader onPOST /quotes,/items,/checkoutand/uploads(MCP:idempotency_keyoncreate_quote,create_checkout_linkandupload_part). For 7 days the same key returns the first result instead of creating another quote, part or payment link; a checkout link that stopped working is replaced. - Some parts need a quick human review; the quote says so and you get a webhook when it's priced.
- USDC refunds go back to the paying wallet or to account credit, your choice:
POST /orders/{id}/refund-preference. - Ask to cancel an order that hasn't shipped with
POST /orders/{id}/cancel-request(MCP:request_order_cancellation); a person reviews it, and asking again within 24 hours doesn't notify us twice. - Change your account's email, ship_to or
callback_urlwithPATCH /api/agent/v1/account(MCP:update_account). A new email or callback URL is emailed to the previous account email. Rotating the API key is REST-only (POST /account/rotate-key), so a new key never lands in a chat transcript.
