{
  "ok": true,
  "resource": {
    "id": "RES_828ADF804FBA",
    "resource_type": "mcp_server",
    "canonical_url": "https://registry.modelcontextprotocol.io/v0.1/servers/ai.agenticfabricationnetwork%2Fufp/versions/0.1.1",
    "name": "Agentic Fabrication Network (AFN)",
    "summary_en": "Turn designs into shipped parts: quote 3D printing, CNC, and decals, then check out.",
    "summary_zh": "将设计转化为已发货的零件：获取3D打印、CNC和贴纸的报价，然后结账。",
    "description_en": "Agentic Fabrication Network (AFN) is an MCP server that provides a unified fabrication quoting and ordering service. It accepts design files (e.g., STL, STEP, DXF, images) and returns ranked, purchasable offers from multiple vendors across processes like FDM printing, CNC machining, sheet metal, laser cutting, decals, and more. Users can refine quotes with constraints (budget, deadline, materials, shipping origin), compare scenarios, create checkouts with hosted payment, track orders, and leave verified reviews. The server also offers material guidance and a live network capabilities catalog.",
    "description_zh": "Agentic Fabrication Network (AFN) 是一个 MCP 服务器，提供统一的制造报价和订购服务。它接受设计文件（如 STL、STEP、DXF、图像），并返回来自多个供应商的、按价格和交期排序的可购买报价，涵盖 FDM 打印、CNC 加工、钣金、激光切割、贴纸等工艺。用户可以添加约束（预算、截止日期、材料、发货地）来优化报价，比较不同方案，创建托管支付链接的结账，跟踪订单，并留下经过验证的评论。该服务器还提供材料指南和实时网络能力目录。",
    "provider_name": "ai.agenticfabricationnetwork",
    "homepage_url": "https://agenticfabricationnetwork.ai/mcp",
    "endpoint_url": "https://agenticfabricationnetwork.ai/mcp",
    "source_url": "https://registry.modelcontextprotocol.io/v0.1/servers/ai.agenticfabricationnetwork%2Fufp/versions/0.1.1",
    "icon_url": null,
    "cover_image_url": null,
    "capabilities": [
      "design.quote",
      "commerce.checkout",
      "commerce.order-management",
      "agent-orchestration.refine",
      "data.retrieve"
    ],
    "categories": [
      "commerce"
    ],
    "industries": [
      "industrial",
      "commerce",
      "general"
    ],
    "protocols": [
      "mcp"
    ],
    "auth": {
      "type": "unknown"
    },
    "pricing": {
      "model": "unknown"
    },
    "input_schema": {},
    "output_schema": {},
    "metadata": {
      "content_language": "en",
      "translation_status": "original-only",
      "official_registry": {
        "version": "0.1.1",
        "packages": [],
        "remotes": []
      },
      "review_gate": {
        "passed": true,
        "reasons": [],
        "policy_version": "review-gate-v1",
        "evaluated_at": "2026-09-03T06:07:41.224Z"
      }
    },
    "latest_version": "0.1.1",
    "status": "listed",
    "health_status": "healthy",
    "source_kind": "imported",
    "source_agent": "registry.modelcontextprotocol.io",
    "trust": {
      "signal": "none",
      "reason": "No suspicious or malicious evidence found.",
      "signals": {
        "yellow": 0,
        "red": 0
      }
    },
    "review_summary": {
      "method_version": "capability-evidence-v2",
      "capability_definition": "strong",
      "contract_completeness": "strong",
      "access_friction": "low",
      "operational_transparency": "partial",
      "evidence_strength": "protocol_inspected",
      "use_readiness": "guided_use",
      "reviewed_at": "2026-09-03T06:31:04.718Z"
    },
    "experience_count": 0,
    "verified_experience_count": 0,
    "usage_count": 0,
    "success_rate": null,
    "first_seen_at": "2026-09-03T02:49:27.244Z",
    "last_seen_at": "2026-09-03T06:31:03.868Z",
    "published_at": "2026-09-03T06:31:03.868Z",
    "created_at": "2026-09-03T02:49:27.244Z",
    "updated_at": "2026-09-03T06:31:04.718Z",
    "api_url": "https://aiworkshub.io/api/v1/resources/RES_828ADF804FBA",
    "reviews_url": "https://aiworkshub.io/api/v1/resources/RES_828ADF804FBA/reviews",
    "public_url": "https://aiworkshub.io/resources/RES_828ADF804FBA",
    "distribution": {
      "canonical_identity": "https://registry.modelcontextprotocol.io/v0.1/servers/ai.agenticfabricationnetwork%2Fufp/versions/0.1.1",
      "syndicatable": true,
      "origins": [
        {
          "registry_url": "https://registry.modelcontextprotocol.io/",
          "upstream_resource_id": "ai.agenticfabricationnetwork/ufp@0.1.1",
          "upstream_record_url": "https://registry.modelcontextprotocol.io/v0.1/servers/ai.agenticfabricationnetwork%2Fufp/versions/0.1.1",
          "relation": "syndicated",
          "metadata": {
            "source": "official-mcp-registry"
          },
          "first_seen_at": "2026-09-03T02:49:27.244Z",
          "last_seen_at": "2026-09-03T06:31:03.868Z"
        }
      ]
    },
    "tools": [
      {
        "name": "create_checkout",
        "title_en": "Create checkout",
        "title_zh": "创建结账",
        "description_en": "Create the order and get a hosted payment link for a chosen offer. Collects shipping address on the payment page.",
        "description_zh": "为所选报价创建订单并获取托管支付链接。在支付页面收集收货地址。",
        "input_schema": {
          "type": "object",
          "properties": {
            "offer_id": {
              "type": "string"
            },
            "shipping_option_id": {
              "type": "string",
              "description": "One of the offer's shipping option ids"
            },
            "name": {
              "type": "string",
              "description": "Recipient full name (only if the user provided it)"
            },
            "street1": {
              "type": "string",
              "description": "Street address (only if the user provided it)"
            },
            "street2": {
              "type": "string"
            },
            "city": {
              "type": "string"
            },
            "state": {
              "type": "string",
              "minLength": 2,
              "maxLength": 2,
              "description": "Two-letter US state"
            },
            "zip": {
              "type": "string"
            },
            "email": {
              "type": "string",
              "format": "email",
              "description": "Buyer email (only if the user provided it)"
            },
            "phone": {
              "type": "string"
            },
            "billing_name": {
              "type": "string",
              "description": "Billing address, only when the buyer answered the billing question (e.g. said it differs from shipping, or a checkout UI's 'same as shipping' checkbox — then send the shipping values verbatim). Never ask for it; omit and the payment page handles billing."
            },
            "billing_street1": {
              "type": "string"
            },
            "billing_street2": {
              "type": "string"
            },
            "billing_city": {
              "type": "string"
            },
            "billing_state": {
              "type": "string",
              "minLength": 2,
              "maxLength": 2,
              "description": "Two-letter US state"
            },
            "billing_zip": {
              "type": "string"
            },
            "return_url": {
              "type": "string",
              "format": "uri",
              "description": "Exact URL of the page the user is on right now, IF the client application knows it (a web app embedding this tool passes its own page URL). The post-payment page shows a 'Return to <site>' button pointing here. Omit when unknown — never invent one."
            },
            "coupon_code": {
              "type": "string",
              "description": "Coupon code, only if the user provided one (early-adopter codes from the AFN team). Case-insensitive. The discount appears on the payment page; a 100%-off code makes the total $0 with no card required. Never invent or guess a code."
            }
          },
          "required": [
            "offer_id",
            "shipping_option_id"
          ],
          "additionalProperties": false,
          "$schema": "http://json-schema.org/draft-07/schema#"
        },
        "output_schema": {},
        "unit_kind": "mcp_tool",
        "effect": "unknown",
        "open_world": false,
        "idempotency": "unknown",
        "confirmation": "explicit policy",
        "evidence_ids": [
          "protocol-tools"
        ],
        "runtime_auth": {},
        "pricing": {},
        "metadata": {}
      },
      {
        "name": "finalize_quote",
        "title_en": "Finalize quote (wait for remaining vendors)",
        "title_zh": "完成报价（等待剩余供应商）",
        "description_en": "Waits for vendors to answer (up to ~40s) and returns offers as a full board. Only for empty board responses.",
        "description_zh": "等待供应商回复（最多约 40 秒）并返回完整报价板。仅用于空板响应。",
        "input_schema": {
          "type": "object",
          "properties": {
            "quote_id": {
              "type": "string",
              "description": "Quote id from the still-quoting response"
            }
          },
          "required": [
            "quote_id"
          ],
          "additionalProperties": false,
          "$schema": "http://json-schema.org/draft-07/schema#"
        },
        "output_schema": {},
        "unit_kind": "mcp_tool",
        "effect": "read",
        "open_world": false,
        "idempotency": "unknown",
        "confirmation": "explicit policy",
        "evidence_ids": [
          "protocol-tools"
        ],
        "runtime_auth": {},
        "pricing": {},
        "metadata": {}
      },
      {
        "name": "get_fabrication_quote",
        "title_en": "Get fabrication quote",
        "title_zh": "获取制造报价",
        "description_en": "Get ranked, purchasable offers (price, ETA, preview image) for fabricating a physical item from a design file. Supports processes like FDM print, CNC, sheet metal, decal, and more. Accepts design files or a UFP part number for reorders.",
        "description_zh": "根据设计文件获取可购买的排名报价（价格、预计时间、预览图）。支持 FDM 打印、CNC、钣金、贴纸等工艺。接受设计文件或 UFP 零件号以进行重新订购。",
        "input_schema": {
          "type": "object",
          "properties": {
            "process": {
              "type": "string",
              "enum": [
                "fdm_print",
                "resin_print",
                "powder_print",
                "metal_print",
                "elastomer_print",
                "cnc",
                "sheetmetal",
                "laser_cut",
                "decal",
                "print",
                "apparel"
              ],
              "description": "What to fabricate. If the user just drops a file and asks for a price, OMIT this — UFP detects the file type (artwork, mesh — STL/OBJ/PLY/3MF/AMF, BREP — STEP/IGES, DXF) and routes it to every process that can make it; the response's routing.also_possible lists processes UFP can't quote yet"
            },
            "part_number": {
              "type": "string",
              "description": "UFP part number from a previous paid order (UFP-… or part_…). Reorders: replaces design_file/file_url entirely; any other fields provided override the stored spec"
            },
            "share_key": {
              "type": "string",
              "description": "Share key for a LOCKED part — the k=… value from the owner's share link (…/part/UFP-…?k=KEY). Required with part_number when the part is locked; omit otherwise"
            },
            "design_file": {
              "anyOf": [
                {
                  "type": "object",
                  "properties": {
                    "file_id": {
                      "type": "string"
                    },
                    "download_url": {
                      "type": "string"
                    },
                    "mime_type": {
                      "type": "string"
                    },
                    "file_name": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "file_id",
                    "download_url"
                  ],
                  "additionalProperties": false
                },
                {
                  "type": "string"
                }
              ],
              "description": "The design file itself (user-attached or generated image/STL). ChatGPT supplies the file reference automatically when the user attached a file — just bind the attachment here. Other clients may pass a data: URL (base64) or a public https URL string. Preferred over file_url."
            },
            "file_url": {
              "type": "string",
              "format": "uri",
              "description": "Public URL of the design file — only when the design lives at a URL"
            },
            "attachment_urls": {
              "type": "array",
              "items": {
                "type": "string",
                "format": "uri"
              },
              "maxItems": 10,
              "description": "Additional files for the SAME part — the PDF drawing next to the STEP, spec sheets, BOMs. Pass everything the user gave you; UFP works out which file is the part and which are supporting documents."
            },
            "ship_to_zip": {
              "type": "string",
              "pattern": "^\\d{5}(-\\d{4})?$",
              "description": "Destination US ZIP code, exactly as the user stated it. OMIT if the user has not given one — NEVER guess or invent a ZIP. Without it, prices come back all-in with shipping to an assumed central-US destination, flagged on routing.ship_to"
            },
            "quantities": {
              "type": "array",
              "items": {
                "type": "integer",
                "exclusiveMinimum": 0
              },
              "maxItems": 5,
              "description": "Quantities the user actually wants — pass [1] or [2] if that's the ask. Vendors with a higher minimum quote AT their minimum and the offer notes it (requested_quantity). Default: 25 for decals, 1 for prints; a part_number reorder defaults to the quantity last purchased"
            },
            "material": {
              "type": "string",
              "description": "ONLY a material the user actually asked for — NEVER guess or default one (a silent \"pla\" on a bare file drop prunes every maker that does not stock it; OMIT instead and each process quotes across its stocked materials so every maker can bid). fdm_print: pla|petg|asa (free-form — \"abs\", \"polycarbonate\" asks resolve to the closest stocked filament with a substitution note); resin_print: standard|tough|high_temp|high_detail resin (free-form asks resolve to the closest supported resin); powder_print: Powder-bed nylon: nylon_12|nylon_12_smooth|nylon_11|nylon_12_gf|nylon_12_esd|nylon_12_white|nylon_pa2200|nylon_12_sls|tpu (free-form — \"PA12\", \"glass filled\" resolve to the closest stocked powder); elastomer_print: Jetted elastomer: tepu_30a|tepu_50a (free-form — \"TPU\", \"soft rubber\" resolve to the closest stocked durometer); cnc: aluminum_6061|aluminum_7075|stainless_304|titanium|brass|acetal|delrin|abs|nylon_pa6|peek|acrylic (free-form asks resolve to the closest supported stock); sheetmetal: mild_steel|aluminum_5052|stainless_304 (free-form — \"steel\", \"5052\", \"stainless\" resolve; unknown asks get closest-match offers). Omit to compare the defaults; laser_cut: acrylic|plywood|mdf|delrin|uhmw|hdpe|g10|carbon_fiber|mild_steel|aluminum_5052|stainless_304 (free-form — \"plexiglass\", \"birch\" resolve; unknown asks get closest-match offers); decal: vinyl|holographic|transparent|glitter (free-form — \"chrome\" etc. gets closest matches)"
            },
            "color": {
              "type": "string",
              "description": "ONLY a color the user actually asked for — NEVER pick one for them. fdm_print: Filament color for fdm_print (e.g. black, red); resin_print: Resin color for resin_print (e.g. gray, white, black); powder_print: Powder part color: raw gray/white, or a dye (\"black\", \"dark blue\") — vendor-resolved; elastomer_print: Elastomer part color — VCJ parts ship raw; asks resolve with an honest substitution note; print: Print color ask (\"full color\", \"black and white\"). Vendors that only price full color note the substitution; apparel: Garment color for apparel (\"black\", \"heather gray\") — vendor-resolved"
            },
            "powder_technology": {
              "type": "string",
              "description": "Powder process: mjf (HP Multi Jet Fusion) | sls (laser sintering). Omit to let the vendor pick its default lane for the material"
            },
            "powder_finish": {
              "type": "string",
              "description": "Powder post-processing: as_printed (raw powder surface) | vapor_polished | polished"
            },
            "metal_alloy": {
              "type": "string",
              "description": "Metal AM alloy: stainless_316l|stainless_17_4ph|titanium_ti64|aluminum_alsi10mg|inconel_718|cobalt_chrome|tool_steel_h13|copper (free-form asks like \"Ti-6Al-4V\" resolve to the closest stocked powder)"
            },
            "metal_technology": {
              "type": "string",
              "description": "Metal AM process: laser_powder_bed (SLM/DMLS/LPBF)|binder_jet|ebm. Omit to let the vendor pick its default for the alloy"
            },
            "metal_finish": {
              "type": "string",
              "description": "Metal AM post-processing: as_printed|bead_blast|machined_critical|polished|heat_treated (as_printed keeps support witness marks)"
            },
            "elastomer_technology": {
              "type": "string",
              "description": "Elastomer process: vapor_cure_jetting (VCJ). Omit to let the vendor pick its default lane for the material"
            },
            "elastomer_finish": {
              "type": "string",
              "description": "Elastomer post-processing: as_printed (VCJ parts ship raw — the whole lane today)"
            },
            "shore_a": {
              "type": "number",
              "exclusiveMinimum": 0,
              "description": "Numeric Shore A durometer ask (10-95, e.g. 40). Resolved to the NEAREST stocked durometer with a substitution note — never a silent swap"
            },
            "finish": {
              "type": "string",
              "description": "cnc: CNC surface finish: standard|anodized|polished|bead_blasted (default standard); sheetmetal: as_cut (default) | deburred | anodized | powder_coat — anodized is aluminum-only; powder coat protects mild steel for outdoor use"
            },
            "thickness_in": {
              "type": "number",
              "exclusiveMinimum": 0,
              "description": "sheetmetal: Sheet thickness in inches (e.g. 0.063 = 14 ga aluminum). Quoted at the nearest stocked thickness; omit for ~16 ga default; laser_cut: Nominal thickness in inches; quoted at the vendor's nearest stocked thickness. Omit for the material's common stock"
            },
            "bend_count": {
              "type": "number",
              "exclusiveMinimum": 0,
              "description": "Number of bends in the design (bend lines must be in the file). Prices CNC bending; omit for flat parts"
            },
            "units": {
              "type": "string",
              "description": "sheetmetal: DXF drawing units: \"mm\" (default) or \"in\". STEP files carry their own units; laser_cut: DXF drawing units: \"mm\" (default) or \"in\""
            },
            "width_in": {
              "type": "number",
              "exclusiveMinimum": 0,
              "description": "Decal width in inches (default 3)"
            },
            "height_in": {
              "type": "number",
              "exclusiveMinimum": 0,
              "description": "Decal height in inches (default 3)"
            },
            "cut": {
              "type": "string",
              "description": "Decal cut style — pass the user's words verbatim (\"triangle\", \"die cut\", \"circle\"). Known: contour|square|oval|kiss_cut; anything else gets closest-match offers with a substitution note. Omit to compare the main options"
            },
            "product": {
              "type": "string",
              "description": "print: Print product kind: business_cards|flyers|posters. Omit to quote every kind the artwork fits; apparel: apparel: t_shirt|hoodie|long_sleeve|tank_top (free-form — \"tee\", \"crewneck\" resolve to the closest product)"
            },
            "size": {
              "type": "string",
              "description": "Print size — pass the user's words verbatim (\"letter\", \"24x36\", \"half letter\"). Cards are 3.5x2; flyers 8.5x5.5|8.5x11|11x17; posters 12x18 through 36x48. Unknown sizes get closest-match offers"
            },
            "paper": {
              "type": "string",
              "description": "Paper stock — free-form (\"matte\", \"glossy\", \"recycled\", \"14pt\"). Resolved to the closest stock the vendor runs"
            },
            "sides": {
              "type": "string",
              "description": "single|double sided printing (defaults: cards double, flyers/posters single)"
            },
            "placement": {
              "type": "string",
              "description": "Print placement for apparel: front (default) | back | front_back"
            },
            "bends": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 32
                  },
                  "line": {
                    "type": "object",
                    "properties": {
                      "p1": {
                        "type": "array",
                        "minItems": 3,
                        "maxItems": 3,
                        "items": [
                          {
                            "type": "number"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "number"
                          }
                        ]
                      },
                      "p2": {
                        "type": "array",
                        "minItems": 3,
                        "maxItems": 3,
                        "items": [
                          {
                            "type": "number"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "number"
                          }
                        ]
                      }
                    },
                    "required": [
                      "p1",
                      "p2"
                    ],
                    "additionalProperties": false
                  },
                  "angle_deg": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "exclusiveMaximum": 180
                  },
                  "direction": {
                    "type": "string",
                    "enum": [
                      "up",
                      "down"
                    ]
                  },
                  "radius_mm": {
                    "type": "number",
                    "exclusiveMinimum": 0
                  },
                  "face_id": {
                    "type": "integer"
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "detected",
                      "user"
                    ]
                  }
                },
                "required": [
                  "line",
                  "angle_deg",
                  "direction"
                ],
                "additionalProperties": false
              },
              "maxItems": 50,
              "description": "Sheet-metal bend lines, each as TWO POINTS in the part's own mm frame (flat DXF parts use z=0: a bend from (0,12.7) to (76.2,12.7) is p1 [0,12.7,0], p2 [76.2,12.7,0]). angle_deg is the target bend angle (90 = a right-angle flange), direction \"up\"/\"down\" is the fold direction relative to the flat pattern, radius_mm the requested inside radius (omit it — the shop resolves to its tooling and reports what it used). Pass these when the user articulates WHERE the bends go; a bare \"it has 2 bends\" is bend_count, not this."
            },
            "tapping": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "hole": {
                    "type": "integer",
                    "minimum": 1
                  },
                  "thread": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 32
                  },
                  "face_id": {
                    "type": "integer"
                  },
                  "drilled_diameter_mm": {
                    "type": "number",
                    "exclusiveMinimum": 0
                  },
                  "located_at_mm": {
                    "type": "object",
                    "properties": {
                      "x": {
                        "type": "number"
                      },
                      "y": {
                        "type": "number"
                      },
                      "z": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "x",
                      "y",
                      "z"
                    ],
                    "additionalProperties": false
                  },
                  "axis": {
                    "type": "array",
                    "minItems": 3,
                    "maxItems": 3,
                    "items": [
                      {
                        "type": "number"
                      },
                      {
                        "type": "number"
                      },
                      {
                        "type": "number"
                      }
                    ]
                  },
                  "depth_mm": {
                    "type": "number",
                    "exclusiveMinimum": 0
                  }
                },
                "required": [
                  "thread"
                ],
                "additionalProperties": false
              },
              "maxItems": 200,
              "description": "Tapped (threaded) holes for a sheet-metal part — one record per hole the user wants threads cut into. `thread` is the callout in the user's words (\"M6\", \"M4 x 0.7\", \"1/4-20\") and is all that's required; when known, add the hole's center in the part's own mm frame (located_at_mm), its unit axis, the pre-tap drilled diameter, and depth_mm so the shop taps the right hole. Pass these when the user asks for threaded/tapped holes; vendors with a tapping service price them."
            },
            "inserts": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "hole": {
                    "type": "integer",
                    "minimum": 1
                  },
                  "insert": {
                    "type": "string",
                    "enum": [
                      "nut",
                      "flush_nut",
                      "standoff",
                      "blind_standoff",
                      "stud"
                    ]
                  },
                  "thread": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 32
                  },
                  "face_id": {
                    "type": "integer"
                  },
                  "points": {
                    "type": "array",
                    "minItems": 3,
                    "maxItems": 3,
                    "items": [
                      {
                        "type": "number"
                      },
                      {
                        "type": "number"
                      },
                      {
                        "type": "number"
                      }
                    ]
                  },
                  "length_mm": {
                    "type": "number",
                    "exclusiveMinimum": 0
                  },
                  "drilled_diameter_mm": {
                    "type": "number",
                    "exclusiveMinimum": 0
                  },
                  "located_at_mm": {
                    "type": "object",
                    "properties": {
                      "x": {
                        "type": "number"
                      },
                      "y": {
                        "type": "number"
                      },
                      "z": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "x",
                      "y",
                      "z"
                    ],
                    "additionalProperties": false
                  },
                  "axis": {
                    "type": "array",
                    "minItems": 3,
                    "maxItems": 3,
                    "items": [
                      {
                        "type": "number"
                      },
                      {
                        "type": "number"
                      },
                      {
                        "type": "number"
                      }
                    ]
                  },
                  "depth_mm": {
                    "type": "number",
                    "exclusiveMinimum": 0
                  }
                },
                "required": [
                  "insert",
                  "thread"
                ],
                "additionalProperties": false
              },
              "maxItems": 200,
              "description": "PEM-style hardware inserts pressed into holes of a sheet-metal part — one record per hole. `insert` is the species (nut | flush_nut | standoff | blind_standoff | stud) and `thread` its size (\"M4\", \"1/4-20\"); both are required. When known, add length_mm (standoff/stud post length), the hole's center (located_at_mm, part's own mm frame), its axis, the drilled diameter, and `points` — the signed unit vector the insert's functional side faces (flip = negate). Pass these when the user asks for press-in nuts/standoffs/studs; vendors with a hardware service price them."
            },
            "processes": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "maxItems": 8,
              "description": "Only quote these fabrication processes — a constraint that narrows the auto-routing fan. Friendly terms accepted (\"sheet metal\", \"3d printing\", \"cnc\", \"laser\"); unmappable terms are reported, never an error. Usually OMIT: auto-routing quotes every process that can make the file. Pass it only when the user explicitly limits the process"
            },
            "ships_from": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "maxItems": 8,
              "description": "Only vendors that ship from these countries/regions (\"only US vendors\", \"keep it domestic\") — an INCLUDE list. Friendly terms accepted (\"US\", \"Europe\", \"Germany\", \"China\", \"UK\"); unmappable terms are reported, never an error. Vendors whose origin is unknown or whose network is worldwide (origin not guaranteed) are excluded, each with a note saying why. Usually OMIT: pass it only when the user explicitly limits where vendors ship from"
            },
            "vendors": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "maxItems": 16,
              "description": "Only these specific vendors/makers (\"just quote Slant 3D\") — an INCLUDE list of vendor names as they appear on offers. Friendly names accepted (\"A3D\", \"slant 3d\"); unmatched names are reported, never an error. Usually OMIT: pass it only when the user explicitly names the vendors they want"
            },
            "deadline": {
              "type": "string",
              "description": "Latest acceptable delivery date, ISO YYYY-MM-DD"
            },
            "outdoor_rated": {
              "type": "boolean",
              "description": "Must survive outdoor exposure"
            },
            "submersible": {
              "type": "boolean",
              "description": "Must survive submersion in water"
            },
            "high_temp": {
              "type": "boolean",
              "description": "Must tolerate sustained heat (vendor heat-resistance claim)"
            },
            "food_safe": {
              "type": "boolean",
              "description": "Must be vendor-certified food safe"
            },
            "requirements": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120
              },
              "maxItems": 20,
              "description": "Verbatim context terms from the user — materials, finishes, certifications, tolerances (\"UV resistant\", \"anodized: red\", \"iso 13485\", \"tolerance: 0.1mm\"). UFP applies what it can and reports what it could not; unresolvable terms are logged for vendor sourcing. Do not interrogate the user to fill this — pass what they said."
            },
            "callouts": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "value": {
                    "type": "number"
                  },
                  "unit": {
                    "type": "string",
                    "enum": [
                      "mm",
                      "in"
                    ]
                  },
                  "tolerance_mm": {
                    "type": "number",
                    "exclusiveMinimum": 0
                  },
                  "critical": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "name",
                  "value",
                  "unit"
                ],
                "additionalProperties": false
              },
              "maxItems": 50,
              "description": "Dimensions you read off the user's drawing that matter (\"hole_diameter 6.5mm ±0.1\"). The tightest tolerance prunes vendors that cannot hold it."
            },
            "max_budget_usd": {
              "type": "number",
              "exclusiveMinimum": 0,
              "description": "Hard budget cap in USD, all-in"
            },
            "min_vendor_stars": {
              "type": "number",
              "minimum": 1,
              "maximum": 5,
              "description": "Only vendors whose displayed review rating is at least this many stars (1-5). Vendors with no reviews yet are excluded — the filter demands demonstrated quality"
            },
            "min_vendor_reviews": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "description": "Only vendors with at least this many verified-purchase reviews"
            },
            "proven_spec_orders": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "description": "Only vendors with at least N completed orders for this exact process+material — \"a vendor that prints PC reliably\""
            }
          },
          "additionalProperties": false,
          "$schema": "http://json-schema.org/draft-07/schema#"
        },
        "output_schema": {},
        "unit_kind": "mcp_tool",
        "effect": "unknown",
        "open_world": false,
        "idempotency": "unknown",
        "confirmation": "explicit policy",
        "evidence_ids": [
          "protocol-tools"
        ],
        "runtime_auth": {},
        "pricing": {},
        "metadata": {}
      },
      {
        "name": "get_material_guide",
        "title_en": "Get material guide",
        "title_zh": "获取材料指南",
        "description_en": "Honest, cited material intelligence for material-choice questions.",
        "description_zh": "为材料选择问题提供诚实、有引用的材料情报。",
        "input_schema": {
          "type": "object",
          "properties": {
            "material": {
              "type": "string",
              "description": "A material the user named or you are weighing (\"PLA\", \"6061 aluminum\", \"stainless\") — free-form; a family ask like \"stainless\" returns the whole family"
            },
            "process": {
              "type": "string",
              "description": "A UFP process to scope to (\"fdm_print\", \"resin_print\", \"cnc\", \"sheetmetal\", \"laser_cut\") — lists the materials that process makes"
            },
            "question": {
              "type": "string",
              "description": "The user's raw question — mined for intent (stronger/tougher, heat/hot, outdoor/UV) so the right ladder is surfaced"
            }
          },
          "additionalProperties": false,
          "$schema": "http://json-schema.org/draft-07/schema#"
        },
        "output_schema": {},
        "unit_kind": "mcp_tool",
        "effect": "read",
        "open_world": false,
        "idempotency": "unknown",
        "confirmation": "explicit policy",
        "evidence_ids": [
          "protocol-tools"
        ],
        "runtime_auth": {},
        "pricing": {},
        "metadata": {}
      },
      {
        "name": "get_network_capabilities",
        "title_en": "Network capabilities",
        "title_zh": "网络能力",
        "description_en": "The LIVE catalog of what the fabrication network can do right now.",
        "description_zh": "制造网络当前可做什么的实时目录。",
        "input_schema": {
          "type": "object",
          "properties": {
            "process": {
              "type": "string",
              "description": "Advisory scope (\"sheetmetal\") — v1 returns the whole catalog either way; filter what you relay"
            }
          },
          "additionalProperties": false,
          "$schema": "http://json-schema.org/draft-07/schema#"
        },
        "output_schema": {},
        "unit_kind": "mcp_tool",
        "effect": "read",
        "open_world": false,
        "idempotency": "unknown",
        "confirmation": "explicit policy",
        "evidence_ids": [
          "protocol-tools"
        ],
        "runtime_auth": {},
        "pricing": {},
        "metadata": {}
      },
      {
        "name": "get_order_status",
        "title_en": "Get order status",
        "title_zh": "获取订单状态",
        "description_en": "Check status, ETA and tracking for a UFP order.",
        "description_zh": "检查 UFP 订单的状态、预计时间和物流跟踪。",
        "input_schema": {
          "type": "object",
          "properties": {
            "order_id": {
              "type": "string"
            }
          },
          "required": [
            "order_id"
          ],
          "additionalProperties": false,
          "$schema": "http://json-schema.org/draft-07/schema#"
        },
        "output_schema": {},
        "unit_kind": "mcp_tool",
        "effect": "read",
        "open_world": false,
        "idempotency": "unknown",
        "confirmation": "explicit policy",
        "evidence_ids": [
          "protocol-tools"
        ],
        "runtime_auth": {},
        "pricing": {},
        "metadata": {}
      },
      {
        "name": "leave_review",
        "title_en": "Leave vendor review",
        "title_zh": "留下供应商评价",
        "description_en": "Record the user's verified-purchase review of how a UFP order turned out.",
        "description_zh": "记录用户对 UFP 订单结果的已验证购买评价。",
        "input_schema": {
          "type": "object",
          "properties": {
            "order_id": {
              "type": "string",
              "description": "The UFP order being reviewed (ord_…) — see list_orders"
            },
            "stars": {
              "type": "integer",
              "minimum": 1,
              "maximum": 5,
              "description": "Overall rating the user confirmed, 1-5"
            },
            "comment": {
              "type": "string",
              "maxLength": 2000,
              "description": "Short factual summary of the user's feedback, in their spirit — optional"
            },
            "facets": {
              "type": "object",
              "properties": {
                "quality": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 5,
                  "description": "Build/print/cut quality"
                },
                "timeliness": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 5,
                  "description": "Delivery speed vs the quoted ETA"
                },
                "accuracy": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 5,
                  "description": "How well the item matched the ordered spec/design"
                }
              },
              "additionalProperties": false,
              "description": "Score only the facets the user actually spoke to"
            },
            "claims": {
              "type": "object",
              "properties": {
                "received_material": {
                  "type": "string",
                  "maxLength": 80,
                  "description": "Material the user says actually ARRIVED, when they complain it differs from the order (\"they sent aluminum\")"
                },
                "received_quantity": {
                  "type": "integer",
                  "exclusiveMinimum": 0,
                  "description": "Count the user says actually arrived, when it differs from the order"
                },
                "delivery_claim": {
                  "type": "string",
                  "enum": [
                    "not_delivered",
                    "late",
                    "on_time"
                  ],
                  "description": "The user's delivery claim (\"never showed up\" -> not_delivered)"
                }
              },
              "additionalProperties": false,
              "description": "CHECKABLE claims from the user's feedback — the network stamps each against its own records (the ordered spec, polled tracking + delivery events) and attaches evidence chips to the review. Only pass what the user actually asserted."
            }
          },
          "required": [
            "order_id",
            "stars"
          ],
          "additionalProperties": false,
          "$schema": "http://json-schema.org/draft-07/schema#"
        },
        "output_schema": {},
        "unit_kind": "mcp_tool",
        "effect": "unknown",
        "open_world": false,
        "idempotency": "unknown",
        "confirmation": "explicit policy",
        "evidence_ids": [
          "protocol-tools"
        ],
        "runtime_auth": {},
        "pricing": {},
        "metadata": {}
      },
      {
        "name": "list_orders",
        "title_en": "List recent orders",
        "title_zh": "列出最近订单",
        "description_en": "List this agent's recent UFP orders (newest first).",
        "description_zh": "列出该代理最近的 UFP 订单（最新在前）。",
        "input_schema": {
          "$schema": "http://json-schema.org/draft-07/schema#",
          "type": "object",
          "properties": {}
        },
        "output_schema": {},
        "unit_kind": "mcp_tool",
        "effect": "read",
        "open_world": false,
        "idempotency": "unknown",
        "confirmation": "explicit policy",
        "evidence_ids": [
          "protocol-tools"
        ],
        "runtime_auth": {},
        "pricing": {},
        "metadata": {}
      },
      {
        "name": "poll_quote",
        "title_en": "Poll quote (board internal)",
        "title_zh": "轮询报价（内部）",
        "description_en": "Internal: refreshes the offer board while vendors finish pricing. Not for client use.",
        "description_zh": "内部：在供应商完成定价时刷新报价板。不供客户端使用。",
        "input_schema": {
          "type": "object",
          "properties": {
            "quote_id": {
              "type": "string",
              "description": "Quote id the board is watching"
            }
          },
          "required": [
            "quote_id"
          ],
          "additionalProperties": false,
          "$schema": "http://json-schema.org/draft-07/schema#"
        },
        "output_schema": {},
        "unit_kind": "mcp_tool",
        "effect": "read",
        "open_world": false,
        "idempotency": "unknown",
        "confirmation": "explicit policy",
        "evidence_ids": [
          "protocol-tools"
        ],
        "runtime_auth": {},
        "pricing": {},
        "metadata": {}
      },
      {
        "name": "preview_quote",
        "title_en": "Preview quote routing (soft quote)",
        "title_zh": "预览报价路由（软报价）",
        "description_en": "Internal client rail: previews how many fabricators would be asked for a refined part without committing or asking vendors. No prices.",
        "description_zh": "内部客户端轨道：预览优化后的零件会询问多少制造商，而不提交或询问供应商。不包含价格。",
        "input_schema": {
          "type": "object",
          "properties": {
            "quote_id": {
              "type": "string"
            },
            "scenario": {
              "type": "string",
              "minLength": 1,
              "maxLength": 40,
              "description": "Comparison lane label. A labeled refine sits SIDE BY SIDE with the quote's other offers instead of replacing them: refines with the same label replace that scenario, different labels coexist (max 4 per quote), and a refine WITHOUT a scenario resets the baseline and supersedes every lane. \"How does X compare to Y?\" = one labeled refine per scenario (e.g. scenario \"carbon steel\" + material \"carbon steel\", then scenario \"aluminum\" + material \"aluminum\"). Keep labels short and human, like \"carbon steel\""
            },
            "material": {
              "type": [
                "string",
                "null"
              ],
              "description": "New material for this part (\"I need it in PLA\" → \"pla\"). A spec change: lanes requote with this material through warm vendor sessions; an explicit material here replaces the quote's material fan-out. Free-form — unstocked asks resolve to the closest stocked material with a substitution note. Do NOT pass material changes as requirements terms. Pass null to REMOVE a previously asked material (\"forget the aluminum ask\") — the ask comes off the record and the process-default material fan returns"
            },
            "color": {
              "type": [
                "string",
                "null"
              ],
              "description": "New color for this part (spec change — lanes requote). Pass null to REMOVE a previously asked color — back to vendor defaults"
            },
            "finish": {
              "type": [
                "string",
                "null"
              ],
              "description": "New surface finish (\"powder coat\", \"anodized\", \"bead blasted\") — a spec change: finish-capable lanes (sheet metal, CNC, metal print) requote WITH it; 3D-print lanes have no coating step, so they ignore the finish but keep the COLOR. A colored finish ask (\"black powder coat\") should set BOTH finish and color, so every lane lands on the buyer's color. Pass null to REMOVE a previously asked finish"
            },
            "thickness_in": {
              "anyOf": [
                {
                  "type": "number",
                  "exclusiveMinimum": 0,
                  "maximum": 1
                },
                {
                  "type": "null"
                }
              ],
              "description": "New sheet thickness in INCHES (\"make it in 1/8\" → 0.125) — a spec change: sheet lanes requote at the nearest stocked gauge, flagging the substitution when the match isn't close. Pass null to REMOVE a previously asked thickness — back to the material's default gauge"
            },
            "bends": {
              "anyOf": [
                {
                  "anyOf": [
                    {
                      "not": {}
                    },
                    {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 32
                          },
                          "line": {
                            "type": "object",
                            "properties": {
                              "p1": {
                                "type": "array",
                                "minItems": 3,
                                "maxItems": 3,
                                "items": [
                                  {
                                    "type": "number"
                                  },
                                  {
                                    "type": "number"
                                  },
                                  {
                                    "type": "number"
                                  }
                                ]
                              },
                              "p2": {
                                "type": "array",
                                "minItems": 3,
                                "maxItems": 3,
                                "items": [
                                  {
                                    "type": "number"
                                  },
                                  {
                                    "type": "number"
                                  },
                                  {
                                    "type": "number"
                                  }
                                ]
                              }
                            },
                            "required": [
                              "p1",
                              "p2"
                            ],
                            "additionalProperties": false
                          },
                          "angle_deg": {
                            "type": "number",
                            "exclusiveMinimum": 0,
                            "exclusiveMaximum": 180
                          },
                          "direction": {
                            "type": "string",
                            "enum": [
                              "up",
                              "down"
                            ]
                          },
                          "radius_mm": {
                            "type": "number",
                            "exclusiveMinimum": 0
                          },
                          "face_id": {
                            "type": "integer"
                          },
                          "source": {
                            "type": "string",
                            "enum": [
                              "detected",
                              "user"
                            ]
                          }
                        },
                        "required": [
                          "line",
                          "angle_deg",
                          "direction"
                        ],
                        "additionalProperties": false
                      },
                      "maxItems": 50
                    }
                  ],
                  "description": "Sheet-metal bend lines, each as TWO POINTS in the part's own mm frame (flat DXF parts use z=0: a bend from (0,12.7) to (76.2,12.7) is p1 [0,12.7,0], p2 [76.2,12.7,0]). angle_deg is the target bend angle (90 = a right-angle flange), direction \"up\"/\"down\" is the fold direction relative to the flat pattern, radius_mm the requested inside radius (omit it — the shop resolves to its tooling and reports what it used). Pass these when the user articulates WHERE the bends go; a bare \"it has 2 bends\" is bend_count, not this."
                },
                {
                  "type": "null"
                }
              ],
              "description": "New bend records for this part — a spec change: sheet lanes requote with exactly these bends (the list REPLACES the previous one, never patches it). Same shape as on get_fabrication_quote: each bend is two points in the part's own mm frame (flat DXF parts use z=0) plus angle_deg, direction up|down, and an optional requested radius_mm. Pass null to REMOVE every articulated bend"
            },
            "tapping": {
              "anyOf": [
                {
                  "anyOf": [
                    {
                      "not": {}
                    },
                    {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "hole": {
                            "type": "integer",
                            "minimum": 1
                          },
                          "thread": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 32
                          },
                          "face_id": {
                            "type": "integer"
                          },
                          "drilled_diameter_mm": {
                            "type": "number",
                            "exclusiveMinimum": 0
                          },
                          "located_at_mm": {
                            "type": "object",
                            "properties": {
                              "x": {
                                "type": "number"
                              },
                              "y": {
                                "type": "number"
                              },
                              "z": {
                                "type": "number"
                              }
                            },
                            "required": [
                              "x",
                              "y",
                              "z"
                            ],
                            "additionalProperties": false
                          },
                          "axis": {
                            "type": "array",
                            "minItems": 3,
                            "maxItems": 3,
                            "items": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "number"
                              }
                            ]
                          },
                          "depth_mm": {
                            "type": "number",
                            "exclusiveMinimum": 0
                          }
                        },
                        "required": [
                          "thread"
                        ],
                        "additionalProperties": false
                      },
                      "maxItems": 200
                    }
                  ],
                  "description": "Tapped (threaded) holes for a sheet-metal part — one record per hole the user wants threads cut into. `thread` is the callout in the user's words (\"M6\", \"M4 x 0.7\", \"1/4-20\") and is all that's required; when known, add the hole's center in the part's own mm frame (located_at_mm), its unit axis, the pre-tap drilled diameter, and depth_mm so the shop taps the right hole. Pass these when the user asks for threaded/tapped holes; vendors with a tapping service price them."
                },
                {
                  "type": "null"
                }
              ],
              "description": "New tapped-hole records for this part — a spec change: sheet lanes requote with exactly these taps (the list REPLACES the previous one, never patches it). Same shape as on get_fabrication_quote: thread callout (\"M6\", \"1/4-20\") required, hole geometry optional. Pass null to REMOVE every tap"
            },
            "inserts": {
              "anyOf": [
                {
                  "anyOf": [
                    {
                      "not": {}
                    },
                    {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "hole": {
                            "type": "integer",
                            "minimum": 1
                          },
                          "insert": {
                            "type": "string",
                            "enum": [
                              "nut",
                              "flush_nut",
                              "standoff",
                              "blind_standoff",
                              "stud"
                            ]
                          },
                          "thread": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 32
                          },
                          "face_id": {
                            "type": "integer"
                          },
                          "points": {
                            "type": "array",
                            "minItems": 3,
                            "maxItems": 3,
                            "items": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "number"
                              }
                            ]
                          },
                          "length_mm": {
                            "type": "number",
                            "exclusiveMinimum": 0
                          },
                          "drilled_diameter_mm": {
                            "type": "number",
                            "exclusiveMinimum": 0
                          },
                          "located_at_mm": {
                            "type": "object",
                            "properties": {
                              "x": {
                                "type": "number"
                              },
                              "y": {
                                "type": "number"
                              },
                              "z": {
                                "type": "number"
                              }
                            },
                            "required": [
                              "x",
                              "y",
                              "z"
                            ],
                            "additionalProperties": false
                          },
                          "axis": {
                            "type": "array",
                            "minItems": 3,
                            "maxItems": 3,
                            "items": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "number"
                              }
                            ]
                          },
                          "depth_mm": {
                            "type": "number",
                            "exclusiveMinimum": 0
                          }
                        },
                        "required": [
                          "insert",
                          "thread"
                        ],
                        "additionalProperties": false
                      },
                      "maxItems": 200
                    }
                  ],
                  "description": "PEM-style hardware inserts pressed into holes of a sheet-metal part — one record per hole. `insert` is the species (nut | flush_nut | standoff | blind_standoff | stud) and `thread` its size (\"M4\", \"1/4-20\"); both are required. When known, add length_mm (standoff/stud post length), the hole's center (located_at_mm, part's own mm frame), its axis, the drilled diameter, and `points` — the signed unit vector the insert's functional side faces (flip = negate). Pass these when the user asks for press-in nuts/standoffs/studs; vendors with a hardware service price them."
                },
                {
                  "type": "null"
                }
              ],
              "description": "New hardware-insert records for this part — a spec change: sheet lanes requote with exactly these inserts (the list REPLACES the previous one, never patches it). Same shape as on get_fabrication_quote: species (nut|flush_nut|standoff|blind_standoff|stud) and thread required, hole geometry optional. Pass null to REMOVE every insert"
            },
            "quantities": {
              "anyOf": [
                {
                  "type": "array",
                  "items": {
                    "type": "integer",
                    "exclusiveMinimum": 0
                  },
                  "maxItems": 5
                },
                {
                  "type": "null"
                }
              ],
              "description": "New quantities the user wants (spec change — lanes requote at the new quantity). Same rules as on get_fabrication_quote: pass the real ask, never inflate it. Pass null to REMOVE a previously asked quantity — the quote returns to single-part pricing"
            },
            "scale": {
              "type": "object",
              "properties": {
                "x": {
                  "type": "number",
                  "minimum": 0.01,
                  "maximum": 100
                },
                "y": {
                  "type": "number",
                  "minimum": 0.01,
                  "maximum": 100
                },
                "z": {
                  "type": "number",
                  "minimum": 0.01,
                  "maximum": 100
                }
              },
              "required": [
                "x",
                "y",
                "z"
              ],
              "additionalProperties": false,
              "description": "Rescale the DESIGN ITSELF before re-quoting: per-axis stretch factors over the file's current geometry (\"make it 2x bigger\" = {\"x\":2,\"y\":2,\"z\":2}). Mesh designs are genuinely converted — the child quote prices a rescaled file; STEP/IGES designs keep their original file with the dimensions riding as callouts (pass those too). {1,1,1} is a no-op"
            },
            "processes": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "maxItems": 8,
              "description": "Narrow this quote to specific fabrication processes (\"no, I meant in sheet metal\" → [\"sheet metal\"]). A CONSTRAINT, not a new quote: excluded lanes drop while warm vendor sessions survive, and further refines inherit the filter. Friendly terms accepted (\"sheet metal\", \"3d printing\", \"cnc\", \"laser\"); pass [\"any\"] to clear the filter and show every process again. When comparison scenarios are open and the user narrows the process, re-refine EVERY active scenario label with this same arg so all columns prune together"
            },
            "ships_from": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "maxItems": 8,
              "description": "Only vendors that ship from these countries/regions (\"only US vendors\", \"just European shops\", \"keep it domestic\") — an INCLUDE list naming where the user DOES want vendors from. A CONSTRAINT like processes: non-matching vendors drop instantly (nothing re-prices), further refines inherit the filter, and [\"any\"] clears it to show vendors everywhere again. Friendly terms accepted (\"US\", \"Europe\", \"Germany\", \"China\", \"UK\"). Vendors whose origin is unknown or whose network is worldwide (a specific origin cannot be guaranteed) are excluded, each with an honest note. For \"nothing from X\" asks, pass the regions the user does want instead"
            },
            "vendors": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "maxItems": 16,
              "description": "Only these specific vendors/makers (\"only show A3D Manufacturing\", \"just Slant 3D and Fictiv\") — an INCLUDE list of vendor names as they appear on offers. A CONSTRAINT like processes: other vendors' offers drop instantly (nothing re-prices), further refines inherit the filter, and [\"any\"] clears it to show every vendor again. Friendly names accepted (\"A3D\", \"slant 3d\"); unmatched names are reported, never an error. This is THE way to answer \"show me everything vendor X offers\" — the filtered quote lists that vendor's complete lineup"
            },
            "ship_to_zip": {
              "type": "string",
              "pattern": "^\\d{5}(-\\d{4})?$",
              "description": "Destination US ZIP code, exactly as the user stated it — use this when the user provides their ZIP after a quote priced to the assumed central-US destination (routing.ship_to); the refined prices become theirs. NEVER guess or invent a ZIP"
            },
            "deadline": {
              "type": "string",
              "description": "Latest acceptable delivery date, ISO YYYY-MM-DD"
            },
            "outdoor_rated": {
              "type": "boolean"
            },
            "submersible": {
              "type": "boolean"
            },
            "high_temp": {
              "type": "boolean"
            },
            "food_safe": {
              "type": "boolean"
            },
            "requirements": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120
              },
              "maxItems": 20,
              "description": "Verbatim context terms from the user — materials, finishes, certifications, tolerances (\"UV resistant\", \"anodized: red\", \"iso 13485\", \"tolerance: 0.1mm\"). UFP applies what it can and reports what it could not; unresolvable terms are logged for vendor sourcing. Do not interrogate the user to fill this — pass what they said."
            },
            "callouts": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "value": {
                    "type": "number"
                  },
                  "unit": {
                    "type": "string",
                    "enum": [
                      "mm",
                      "in"
                    ]
                  },
                  "tolerance_mm": {
                    "type": "number",
                    "exclusiveMinimum": 0
                  },
                  "critical": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "name",
                  "value",
                  "unit"
                ],
                "additionalProperties": false
              },
              "maxItems": 50,
              "description": "Dimensions you read off the user's drawing that matter (\"hole_diameter 6.5mm ±0.1\"). The tightest tolerance prunes vendors that cannot hold it."
            },
            "max_budget_usd": {
              "type": "number",
              "exclusiveMinimum": 0
            },
            "min_vendor_stars": {
              "type": "number",
              "minimum": 1,
              "maximum": 5,
              "description": "Only vendors whose displayed review rating is at least this many stars (1-5); vendors with no reviews yet are excluded"
            },
            "min_vendor_reviews": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "description": "Only vendors with at least this many verified-purchase reviews"
            },
            "proven_spec_orders": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "description": "Only vendors with at least N completed orders for this exact process+material — \"a vendor that prints PC reliably\""
            },
            "clear": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "deadline",
                  "budget",
                  "outdoor_rated",
                  "submersible",
                  "high_temp",
                  "food_safe",
                  "reliability",
                  "requirements",
                  "processes",
                  "ships_from",
                  "vendors"
                ]
              },
              "minItems": 1,
              "description": "REMOVE constraints entirely (\"drop the deadline\", \"forget the budget\", \"no more food-safe requirement\"): list the constraints to clear and each is removed from the quote — the one deliberate widening besides undo. Clearing a deadline or budget answers instantly from held offers (near-misses convert back); clearing an attribute/reliability/requirements demand re-prices honestly. Same effect as [\"any\"] on the three filter args, extended to every constraint"
            },
            "remove_requirements": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120
              },
              "minItems": 1,
              "maxItems": 20,
              "description": "Take back INDIVIDUAL requirements terms (\"drop the anodized ask, keep the rest\"): each listed term is removed from the quote's requirements by normalized match, the others stay. Unknown terms are ignored, never an error. Re-stating the requirements list can never drop a term (terms merge as a union) — this is the removal channel"
            },
            "undo_last_step": {
              "type": "boolean",
              "description": "GO BACK EXACTLY ONE STEP (\"undo that\", \"go back\", \"put it back how it was\"): the network restores the previous quote's stored spec and constraints EXACTLY — never reconstructed from conversation — and re-prices where needed. Send it ALONE (no other args besides quote_id); combining it with changes is rejected. The quote's steps[] names what each undo would take back — steps[0] is the newest. Undo resets the baseline like any unlabeled refine, so open comparison scenarios close. Undoing the original quote is rejected with honest wording — relay it"
            },
            "sort_by": {
              "type": "string",
              "enum": [
                "recommended",
                "price",
                "unit_price",
                "total_price",
                "arrival",
                "rating"
              ],
              "description": "\"Organize by\": re-order the quote's offer cards (\"sort by cheapest\" → \"price\"; \"soonest arrival first\" → \"arrival\"; \"best rated\" → \"rating\"; \"total_price\" = part + cheapest shipping; \"recommended\" restores the default price+speed rank). PURE PRESENTATION — answers instantly on the same quote, never re-prices or drops offers, and the ordering sticks across re-reads, streaming, and later refines until changed"
            },
            "sort_direction": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "description": "Flip a sort_by ordering: \"desc\" reverses the key's natural direction (\"most expensive first\" = sort_by \"price\" + \"desc\"). Only meaningful with sort_by"
            },
            "sort_order": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "minItems": 1,
              "maxItems": 200,
              "description": "EXPLICIT card order for asks only you can judge (\"sort the most green to the top\"): look at the offers' preview images, decide the order yourself, and pass the offer ids first-on-top. Offers you leave out (including ones that stream in later) land below the listed ones in the default rank. Pass sort_label with it"
            },
            "sort_label": {
              "type": "string",
              "minLength": 1,
              "maxLength": 60,
              "description": "Short human wording for a sort_order, displayed on the board (\"most green first\") — required with sort_order, since only you know what your order means"
            }
          },
          "required": [
            "quote_id"
          ],
          "additionalProperties": false,
          "$schema": "http://json-schema.org/draft-07/schema#"
        },
        "output_schema": {},
        "unit_kind": "mcp_tool",
        "effect": "compute",
        "open_world": false,
        "idempotency": "unknown",
        "confirmation": "explicit policy",
        "evidence_ids": [
          "protocol-tools"
        ],
        "runtime_auth": {},
        "pricing": {},
        "metadata": {}
      },
      {
        "name": "refine_quote",
        "title_en": "Refine quote",
        "title_zh": "优化报价",
        "description_en": "Narrow an existing quote with new constraints (destination ZIP, deadline, requirements, budget, vendor filters) or change its spec (material, color, quantities). Supports comparison scenarios and undo.",
        "description_zh": "通过新约束（目的地邮编、截止日期、要求、预算、供应商筛选）或更改规格（材料、颜色、数量）来优化现有报价。支持比较方案和撤销。",
        "input_schema": {
          "type": "object",
          "properties": {
            "quote_id": {
              "type": "string"
            },
            "scenario": {
              "type": "string",
              "minLength": 1,
              "maxLength": 40,
              "description": "Comparison lane label. A labeled refine sits SIDE BY SIDE with the quote's other offers instead of replacing them: refines with the same label replace that scenario, different labels coexist (max 4 per quote), and a refine WITHOUT a scenario resets the baseline and supersedes every lane. \"How does X compare to Y?\" = one labeled refine per scenario (e.g. scenario \"carbon steel\" + material \"carbon steel\", then scenario \"aluminum\" + material \"aluminum\"). Keep labels short and human, like \"carbon steel\""
            },
            "material": {
              "type": [
                "string",
                "null"
              ],
              "description": "New material for this part (\"I need it in PLA\" → \"pla\"). A spec change: lanes requote with this material through warm vendor sessions; an explicit material here replaces the quote's material fan-out. Free-form — unstocked asks resolve to the closest stocked material with a substitution note. Do NOT pass material changes as requirements terms. Pass null to REMOVE a previously asked material (\"forget the aluminum ask\") — the ask comes off the record and the process-default material fan returns"
            },
            "color": {
              "type": [
                "string",
                "null"
              ],
              "description": "New color for this part (spec change — lanes requote). Pass null to REMOVE a previously asked color — back to vendor defaults"
            },
            "finish": {
              "type": [
                "string",
                "null"
              ],
              "description": "New surface finish (\"powder coat\", \"anodized\", \"bead blasted\") — a spec change: finish-capable lanes (sheet metal, CNC, metal print) requote WITH it; 3D-print lanes have no coating step, so they ignore the finish but keep the COLOR. A colored finish ask (\"black powder coat\") should set BOTH finish and color, so every lane lands on the buyer's color. Pass null to REMOVE a previously asked finish"
            },
            "thickness_in": {
              "anyOf": [
                {
                  "type": "number",
                  "exclusiveMinimum": 0,
                  "maximum": 1
                },
                {
                  "type": "null"
                }
              ],
              "description": "New sheet thickness in INCHES (\"make it in 1/8\" → 0.125) — a spec change: sheet lanes requote at the nearest stocked gauge, flagging the substitution when the match isn't close. Pass null to REMOVE a previously asked thickness — back to the material's default gauge"
            },
            "bends": {
              "anyOf": [
                {
                  "anyOf": [
                    {
                      "not": {}
                    },
                    {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 32
                          },
                          "line": {
                            "type": "object",
                            "properties": {
                              "p1": {
                                "type": "array",
                                "minItems": 3,
                                "maxItems": 3,
                                "items": [
                                  {
                                    "type": "number"
                                  },
                                  {
                                    "type": "number"
                                  },
                                  {
                                    "type": "number"
                                  }
                                ]
                              },
                              "p2": {
                                "type": "array",
                                "minItems": 3,
                                "maxItems": 3,
                                "items": [
                                  {
                                    "type": "number"
                                  },
                                  {
                                    "type": "number"
                                  },
                                  {
                                    "type": "number"
                                  }
                                ]
                              }
                            },
                            "required": [
                              "p1",
                              "p2"
                            ],
                            "additionalProperties": false
                          },
                          "angle_deg": {
                            "type": "number",
                            "exclusiveMinimum": 0,
                            "exclusiveMaximum": 180
                          },
                          "direction": {
                            "type": "string",
                            "enum": [
                              "up",
                              "down"
                            ]
                          },
                          "radius_mm": {
                            "type": "number",
                            "exclusiveMinimum": 0
                          },
                          "face_id": {
                            "type": "integer"
                          },
                          "source": {
                            "type": "string",
                            "enum": [
                              "detected",
                              "user"
                            ]
                          }
                        },
                        "required": [
                          "line",
                          "angle_deg",
                          "direction"
                        ],
                        "additionalProperties": false
                      },
                      "maxItems": 50
                    }
                  ],
                  "description": "Sheet-metal bend lines, each as TWO POINTS in the part's own mm frame (flat DXF parts use z=0: a bend from (0,12.7) to (76.2,12.7) is p1 [0,12.7,0], p2 [76.2,12.7,0]). angle_deg is the target bend angle (90 = a right-angle flange), direction \"up\"/\"down\" is the fold direction relative to the flat pattern, radius_mm the requested inside radius (omit it — the shop resolves to its tooling and reports what it used). Pass these when the user articulates WHERE the bends go; a bare \"it has 2 bends\" is bend_count, not this."
                },
                {
                  "type": "null"
                }
              ],
              "description": "New bend records for this part — a spec change: sheet lanes requote with exactly these bends (the list REPLACES the previous one, never patches it). Same shape as on get_fabrication_quote: each bend is two points in the part's own mm frame (flat DXF parts use z=0) plus angle_deg, direction up|down, and an optional requested radius_mm. Pass null to REMOVE every articulated bend"
            },
            "tapping": {
              "anyOf": [
                {
                  "anyOf": [
                    {
                      "not": {}
                    },
                    {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "hole": {
                            "type": "integer",
                            "minimum": 1
                          },
                          "thread": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 32
                          },
                          "face_id": {
                            "type": "integer"
                          },
                          "drilled_diameter_mm": {
                            "type": "number",
                            "exclusiveMinimum": 0
                          },
                          "located_at_mm": {
                            "type": "object",
                            "properties": {
                              "x": {
                                "type": "number"
                              },
                              "y": {
                                "type": "number"
                              },
                              "z": {
                                "type": "number"
                              }
                            },
                            "required": [
                              "x",
                              "y",
                              "z"
                            ],
                            "additionalProperties": false
                          },
                          "axis": {
                            "type": "array",
                            "minItems": 3,
                            "maxItems": 3,
                            "items": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "number"
                              }
                            ]
                          },
                          "depth_mm": {
                            "type": "number",
                            "exclusiveMinimum": 0
                          }
                        },
                        "required": [
                          "thread"
                        ],
                        "additionalProperties": false
                      },
                      "maxItems": 200
                    }
                  ],
                  "description": "Tapped (threaded) holes for a sheet-metal part — one record per hole the user wants threads cut into. `thread` is the callout in the user's words (\"M6\", \"M4 x 0.7\", \"1/4-20\") and is all that's required; when known, add the hole's center in the part's own mm frame (located_at_mm), its unit axis, the pre-tap drilled diameter, and depth_mm so the shop taps the right hole. Pass these when the user asks for threaded/tapped holes; vendors with a tapping service price them."
                },
                {
                  "type": "null"
                }
              ],
              "description": "New tapped-hole records for this part — a spec change: sheet lanes requote with exactly these taps (the list REPLACES the previous one, never patches it). Same shape as on get_fabrication_quote: thread callout (\"M6\", \"1/4-20\") required, hole geometry optional. Pass null to REMOVE every tap"
            },
            "inserts": {
              "anyOf": [
                {
                  "anyOf": [
                    {
                      "not": {}
                    },
                    {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "hole": {
                            "type": "integer",
                            "minimum": 1
                          },
                          "insert": {
                            "type": "string",
                            "enum": [
                              "nut",
                              "flush_nut",
                              "standoff",
                              "blind_standoff",
                              "stud"
                            ]
                          },
                          "thread": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 32
                          },
                          "face_id": {
                            "type": "integer"
                          },
                          "points": {
                            "type": "array",
                            "minItems": 3,
                            "maxItems": 3,
                            "items": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "number"
                              }
                            ]
                          },
                          "length_mm": {
                            "type": "number",
                            "exclusiveMinimum": 0
                          },
                          "drilled_diameter_mm": {
                            "type": "number",
                            "exclusiveMinimum": 0
                          },
                          "located_at_mm": {
                            "type": "object",
                            "properties": {
                              "x": {
                                "type": "number"
                              },
                              "y": {
                                "type": "number"
                              },
                              "z": {
                                "type": "number"
                              }
                            },
                            "required": [
                              "x",
                              "y",
                              "z"
                            ],
                            "additionalProperties": false
                          },
                          "axis": {
                            "type": "array",
                            "minItems": 3,
                            "maxItems": 3,
                            "items": [
                              {
                                "type": "number"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "number"
                              }
                            ]
                          },
                          "depth_mm": {
                            "type": "number",
                            "exclusiveMinimum": 0
                          }
                        },
                        "required": [
                          "insert",
                          "thread"
                        ],
                        "additionalProperties": false
                      },
                      "maxItems": 200
                    }
                  ],
                  "description": "PEM-style hardware inserts pressed into holes of a sheet-metal part — one record per hole. `insert` is the species (nut | flush_nut | standoff | blind_standoff | stud) and `thread` its size (\"M4\", \"1/4-20\"); both are required. When known, add length_mm (standoff/stud post length), the hole's center (located_at_mm, part's own mm frame), its axis, the drilled diameter, and `points` — the signed unit vector the insert's functional side faces (flip = negate). Pass these when the user asks for press-in nuts/standoffs/studs; vendors with a hardware service price them."
                },
                {
                  "type": "null"
                }
              ],
              "description": "New hardware-insert records for this part — a spec change: sheet lanes requote with exactly these inserts (the list REPLACES the previous one, never patches it). Same shape as on get_fabrication_quote: species (nut|flush_nut|standoff|blind_standoff|stud) and thread required, hole geometry optional. Pass null to REMOVE every insert"
            },
            "quantities": {
              "anyOf": [
                {
                  "type": "array",
                  "items": {
                    "type": "integer",
                    "exclusiveMinimum": 0
                  },
                  "maxItems": 5
                },
                {
                  "type": "null"
                }
              ],
              "description": "New quantities the user wants (spec change — lanes requote at the new quantity). Same rules as on get_fabrication_quote: pass the real ask, never inflate it. Pass null to REMOVE a previously asked quantity — the quote returns to single-part pricing"
            },
            "scale": {
              "type": "object",
              "properties": {
                "x": {
                  "type": "number",
                  "minimum": 0.01,
                  "maximum": 100
                },
                "y": {
                  "type": "number",
                  "minimum": 0.01,
                  "maximum": 100
                },
                "z": {
                  "type": "number",
                  "minimum": 0.01,
                  "maximum": 100
                }
              },
              "required": [
                "x",
                "y",
                "z"
              ],
              "additionalProperties": false,
              "description": "Rescale the DESIGN ITSELF before re-quoting: per-axis stretch factors over the file's current geometry (\"make it 2x bigger\" = {\"x\":2,\"y\":2,\"z\":2}). Mesh designs are genuinely converted — the child quote prices a rescaled file; STEP/IGES designs keep their original file with the dimensions riding as callouts (pass those too). {1,1,1} is a no-op"
            },
            "processes": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "maxItems": 8,
              "description": "Narrow this quote to specific fabrication processes (\"no, I meant in sheet metal\" → [\"sheet metal\"]). A CONSTRAINT, not a new quote: excluded lanes drop while warm vendor sessions survive, and further refines inherit the filter. Friendly terms accepted (\"sheet metal\", \"3d printing\", \"cnc\", \"laser\"); pass [\"any\"] to clear the filter and show every process again. When comparison scenarios are open and the user narrows the process, re-refine EVERY active scenario label with this same arg so all columns prune together"
            },
            "ships_from": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "maxItems": 8,
              "description": "Only vendors that ship from these countries/regions (\"only US vendors\", \"just European shops\", \"keep it domestic\") — an INCLUDE list naming where the user DOES want vendors from. A CONSTRAINT like processes: non-matching vendors drop instantly (nothing re-prices), further refines inherit the filter, and [\"any\"] clears it to show vendors everywhere again. Friendly terms accepted (\"US\", \"Europe\", \"Germany\", \"China\", \"UK\"). Vendors whose origin is unknown or whose network is worldwide (a specific origin cannot be guaranteed) are excluded, each with an honest note. For \"nothing from X\" asks, pass the regions the user does want instead"
            },
            "vendors": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "maxItems": 16,
              "description": "Only these specific vendors/makers (\"only show A3D Manufacturing\", \"just Slant 3D and Fictiv\") — an INCLUDE list of vendor names as they appear on offers. A CONSTRAINT like processes: other vendors' offers drop instantly (nothing re-prices), further refines inherit the filter, and [\"any\"] clears it to show every vendor again. Friendly names accepted (\"A3D\", \"slant 3d\"); unmatched names are reported, never an error. This is THE way to answer \"show me everything vendor X offers\" — the filtered quote lists that vendor's complete lineup"
            },
            "ship_to_zip": {
              "type": "string",
              "pattern": "^\\d{5}(-\\d{4})?$",
              "description": "Destination US ZIP code, exactly as the user stated it — use this when the user provides their ZIP after a quote priced to the assumed central-US destination (routing.ship_to); the refined prices become theirs. NEVER guess or invent a ZIP"
            },
            "deadline": {
              "type": "string",
              "description": "Latest acceptable delivery date, ISO YYYY-MM-DD"
            },
            "outdoor_rated": {
              "type": "boolean"
            },
            "submersible": {
              "type": "boolean"
            },
            "high_temp": {
              "type": "boolean"
            },
            "food_safe": {
              "type": "boolean"
            },
            "requirements": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120
              },
              "maxItems": 20,
              "description": "Verbatim context terms from the user — materials, finishes, certifications, tolerances (\"UV resistant\", \"anodized: red\", \"iso 13485\", \"tolerance: 0.1mm\"). UFP applies what it can and reports what it could not; unresolvable terms are logged for vendor sourcing. Do not interrogate the user to fill this — pass what they said."
            },
            "callouts": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "value": {
                    "type": "number"
                  },
                  "unit": {
                    "type": "string",
                    "enum": [
                      "mm",
                      "in"
                    ]
                  },
                  "tolerance_mm": {
                    "type": "number",
                    "exclusiveMinimum": 0
                  },
                  "critical": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "name",
                  "value",
                  "unit"
                ],
                "additionalProperties": false
              },
              "maxItems": 50,
              "description": "Dimensions you read off the user's drawing that matter (\"hole_diameter 6.5mm ±0.1\"). The tightest tolerance prunes vendors that cannot hold it."
            },
            "max_budget_usd": {
              "type": "number",
              "exclusiveMinimum": 0
            },
            "min_vendor_stars": {
              "type": "number",
              "minimum": 1,
              "maximum": 5,
              "description": "Only vendors whose displayed review rating is at least this many stars (1-5); vendors with no reviews yet are excluded"
            },
            "min_vendor_reviews": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "description": "Only vendors with at least this many verified-purchase reviews"
            },
            "proven_spec_orders": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "description": "Only vendors with at least N completed orders for this exact process+material — \"a vendor that prints PC reliably\""
            },
            "clear": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "deadline",
                  "budget",
                  "outdoor_rated",
                  "submersible",
                  "high_temp",
                  "food_safe",
                  "reliability",
                  "requirements",
                  "processes",
                  "ships_from",
                  "vendors"
                ]
              },
              "minItems": 1,
              "description": "REMOVE constraints entirely (\"drop the deadline\", \"forget the budget\", \"no more food-safe requirement\"): list the constraints to clear and each is removed from the quote — the one deliberate widening besides undo. Clearing a deadline or budget answers instantly from held offers (near-misses convert back); clearing an attribute/reliability/requirements demand re-prices honestly. Same effect as [\"any\"] on the three filter args, extended to every constraint"
            },
            "remove_requirements": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120
              },
              "minItems": 1,
              "maxItems": 20,
              "description": "Take back INDIVIDUAL requirements terms (\"drop the anodized ask, keep the rest\"): each listed term is removed from the quote's requirements by normalized match, the others stay. Unknown terms are ignored, never an error. Re-stating the requirements list can never drop a term (terms merge as a union) — this is the removal channel"
            },
            "undo_last_step": {
              "type": "boolean",
              "description": "GO BACK EXACTLY ONE STEP (\"undo that\", \"go back\", \"put it back how it was\"): the network restores the previous quote's stored spec and constraints EXACTLY — never reconstructed from conversation — and re-prices where needed. Send it ALONE (no other args besides quote_id); combining it with changes is rejected. The quote's steps[] names what each undo would take back — steps[0] is the newest. Undo resets the baseline like any unlabeled refine, so open comparison scenarios close. Undoing the original quote is rejected with honest wording — relay it"
            },
            "sort_by": {
              "type": "string",
              "enum": [
                "recommended",
                "price",
                "unit_price",
                "total_price",
                "arrival",
                "rating"
              ],
              "description": "\"Organize by\": re-order the quote's offer cards (\"sort by cheapest\" → \"price\"; \"soonest arrival first\" → \"arrival\"; \"best rated\" → \"rating\"; \"total_price\" = part + cheapest shipping; \"recommended\" restores the default price+speed rank). PURE PRESENTATION — answers instantly on the same quote, never re-prices or drops offers, and the ordering sticks across re-reads, streaming, and later refines until changed"
            },
            "sort_direction": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "description": "Flip a sort_by ordering: \"desc\" reverses the key's natural direction (\"most expensive first\" = sort_by \"price\" + \"desc\"). Only meaningful with sort_by"
            },
            "sort_order": {
              "type": "array",
              "items": {
                "type": "string",
                "minLength": 1
              },
              "minItems": 1,
              "maxItems": 200,
              "description": "EXPLICIT card order for asks only you can judge (\"sort the most green to the top\"): look at the offers' preview images, decide the order yourself, and pass the offer ids first-on-top. Offers you leave out (including ones that stream in later) land below the listed ones in the default rank. Pass sort_label with it"
            },
            "sort_label": {
              "type": "string",
              "minLength": 1,
              "maxLength": 60,
              "description": "Short human wording for a sort_order, displayed on the board (\"most green first\") — required with sort_order, since only you know what your order means"
            }
          },
          "required": [
            "quote_id"
          ],
          "additionalProperties": false,
          "$schema": "http://json-schema.org/draft-07/schema#"
        },
        "output_schema": {},
        "unit_kind": "mcp_tool",
        "effect": "unknown",
        "open_world": false,
        "idempotency": "unknown",
        "confirmation": "explicit policy",
        "evidence_ids": [
          "protocol-tools"
        ],
        "runtime_auth": {},
        "pricing": {},
        "metadata": {}
      },
      {
        "name": "reply_to_maker",
        "title_en": "Reply to the maker",
        "title_zh": "回复制造商",
        "description_en": "Send the user's answer to a question the maker asked about a UFP order.",
        "description_zh": "将用户的回答发送给制造商关于 UFP 订单的问题。",
        "input_schema": {
          "type": "object",
          "properties": {
            "order_id": {
              "type": "string",
              "description": "The UFP order the maker asked about (ord_…)"
            },
            "message": {
              "type": "string",
              "minLength": 1,
              "maxLength": 4000,
              "description": "The user's answer, in their words — it is relayed to the maker"
            }
          },
          "required": [
            "order_id",
            "message"
          ],
          "additionalProperties": false,
          "$schema": "http://json-schema.org/draft-07/schema#"
        },
        "output_schema": {},
        "unit_kind": "mcp_tool",
        "effect": "external_action",
        "open_world": false,
        "idempotency": "unknown",
        "confirmation": "explicit policy",
        "evidence_ids": [
          "protocol-tools"
        ],
        "runtime_auth": {},
        "pricing": {},
        "metadata": {}
      }
    ],
    "review_profile": {
      "schema_version": "aiworkshub.resource-review/0.2",
      "method_version": "capability-evidence-v2",
      "review_state": {
        "identity": "verified",
        "source": "verified",
        "connectivity": "verified",
        "contract": "strong",
        "safe_use": "untested",
        "real_use": "unobserved"
      },
      "assessment": {
        "capability_definition": "strong",
        "contract_completeness": "strong",
        "access_friction": "low",
        "operational_transparency": "partial",
        "evidence_strength": "protocol_inspected",
        "use_readiness": "guided_use"
      },
      "profile": {
        "capabilities": [
          {
            "id": "design.quote",
            "weight": 100,
            "confidence": 90,
            "evidence_ids": [
              "source-record",
              "protocol-tools"
            ]
          },
          {
            "id": "commerce.checkout",
            "weight": 90,
            "confidence": 90,
            "evidence_ids": [
              "source-record",
              "protocol-tools"
            ]
          },
          {
            "id": "commerce.order-management",
            "weight": 80,
            "confidence": 90,
            "evidence_ids": [
              "source-record",
              "protocol-tools"
            ]
          },
          {
            "id": "agent-orchestration.refine",
            "weight": 70,
            "confidence": 90,
            "evidence_ids": [
              "source-record",
              "protocol-tools"
            ]
          },
          {
            "id": "data.retrieve",
            "weight": 60,
            "confidence": 90,
            "evidence_ids": [
              "source-record",
              "protocol-tools"
            ]
          }
        ],
        "domains": [
          {
            "id": "manufacturing",
            "weight": 100,
            "confidence": 90,
            "evidence_ids": [
              "source-record",
              "protocol-tools"
            ]
          },
          {
            "id": "ecommerce",
            "weight": 90,
            "confidence": 90,
            "evidence_ids": [
              "source-record",
              "protocol-tools"
            ]
          },
          {
            "id": "design",
            "weight": 80,
            "confidence": 90,
            "evidence_ids": [
              "source-record",
              "protocol-tools"
            ]
          }
        ],
        "workflow_roles": [
          "design",
          "transact",
          "monitor",
          "deliver",
          "instruct"
        ]
      },
      "capability_units": [
        {
          "id": "tool:get_fabrication_quote",
          "kind": "mcp_tool",
          "capability_id": "design.quote",
          "effect": "unknown",
          "open_world": false,
          "idempotency": "unknown",
          "confirmation": "explicit policy",
          "input_contract": "typed",
          "output_contract": "typed_envelope_dynamic_result",
          "accepts": [
            "design files (STL, OBJ, PLY, 3MF, AMF, STEP, IGES, DXF, images)",
            "UFP part number",
            "process, material, color, quantity, shipping constraints"
          ],
          "produces": [
            "ranked offers with price, ETA, preview image"
          ],
          "runtime_auth": {},
          "pricing": {},
          "evidence_ids": [
            "protocol-tools"
          ],
          "metadata": {}
        },
        {
          "id": "tool:refine_quote",
          "kind": "mcp_tool",
          "capability_id": "agent-orchestration.refine",
          "effect": "unknown",
          "open_world": false,
          "idempotency": "unknown",
          "confirmation": "explicit policy",
          "input_contract": "typed",
          "output_contract": "typed_envelope_dynamic_result",
          "accepts": [
            "quote_id",
            "constraints (ZIP, deadline, budget, materials, vendors, processes)",
            "spec changes (material, color, quantity, finish)"
          ],
          "produces": [
            "refined quote with updated offers"
          ],
          "runtime_auth": {},
          "pricing": {},
          "evidence_ids": [
            "protocol-tools"
          ],
          "metadata": {}
        },
        {
          "id": "tool:preview_quote",
          "kind": "mcp_tool",
          "capability_id": "agent-orchestration.refine",
          "effect": "compute",
          "open_world": false,
          "idempotency": "unknown",
          "confirmation": "explicit policy",
          "input_contract": "typed",
          "output_contract": "typed_envelope_dynamic_result",
          "accepts": [
            "quote_id",
            "same arguments as refine_quote"
          ],
          "produces": [
            "routing preview without committing"
          ],
          "runtime_auth": {},
          "pricing": {},
          "evidence_ids": [
            "protocol-tools"
          ],
          "metadata": {}
        },
        {
          "id": "tool:poll_quote",
          "kind": "mcp_tool",
          "capability_id": "agent-orchestration.refine",
          "effect": "read",
          "open_world": false,
          "idempotency": "unknown",
          "confirmation": "explicit policy",
          "input_contract": "typed",
          "output_contract": "typed_envelope_dynamic_result",
          "accepts": [
            "quote_id"
          ],
          "produces": [
            "updated quote board"
          ],
          "runtime_auth": {},
          "pricing": {},
          "evidence_ids": [
            "protocol-tools"
          ],
          "metadata": {}
        },
        {
          "id": "tool:finalize_quote",
          "kind": "mcp_tool",
          "capability_id": "agent-orchestration.refine",
          "effect": "read",
          "open_world": false,
          "idempotency": "unknown",
          "confirmation": "explicit policy",
          "input_contract": "typed",
          "output_contract": "typed_envelope_dynamic_result",
          "accepts": [
            "quote_id"
          ],
          "produces": [
            "final quote board"
          ],
          "runtime_auth": {},
          "pricing": {},
          "evidence_ids": [
            "protocol-tools"
          ],
          "metadata": {}
        },
        {
          "id": "tool:create_checkout",
          "kind": "mcp_tool",
          "capability_id": "commerce.checkout",
          "effect": "unknown",
          "open_world": false,
          "idempotency": "unknown",
          "confirmation": "explicit policy",
          "input_contract": "typed",
          "output_contract": "typed_envelope_dynamic_result",
          "accepts": [
            "offer_id",
            "shipping_option_id",
            "optional address and contact fields"
          ],
          "produces": [
            "checkout_url for hosted payment"
          ],
          "runtime_auth": {},
          "pricing": {},
          "evidence_ids": [
            "protocol-tools"
          ],
          "metadata": {}
        },
        {
          "id": "tool:get_order_status",
          "kind": "mcp_tool",
          "capability_id": "commerce.order-management",
          "effect": "read",
          "open_world": false,
          "idempotency": "unknown",
          "confirmation": "explicit policy",
          "input_contract": "typed",
          "output_contract": "typed_envelope_dynamic_result",
          "accepts": [
            "order_id"
          ],
          "produces": [
            "order status, ETA, tracking"
          ],
          "runtime_auth": {},
          "pricing": {},
          "evidence_ids": [
            "protocol-tools"
          ],
          "metadata": {}
        },
        {
          "id": "tool:list_orders",
          "kind": "mcp_tool",
          "capability_id": "commerce.order-management",
          "effect": "read",
          "open_world": false,
          "idempotency": "unknown",
          "confirmation": "explicit policy",
          "input_contract": "typed",
          "output_contract": "typed_envelope_dynamic_result",
          "accepts": [],
          "produces": [
            "list of recent orders"
          ],
          "runtime_auth": {},
          "pricing": {},
          "evidence_ids": [
            "protocol-tools"
          ],
          "metadata": {}
        },
        {
          "id": "tool:reply_to_maker",
          "kind": "mcp_tool",
          "capability_id": "commerce.order-management",
          "effect": "external_action",
          "open_world": false,
          "idempotency": "unknown",
          "confirmation": "explicit policy",
          "input_contract": "typed",
          "output_contract": "typed_envelope_dynamic_result",
          "accepts": [
            "order_id",
            "message"
          ],
          "produces": [
            "confirmation of relay"
          ],
          "runtime_auth": {},
          "pricing": {},
          "evidence_ids": [
            "protocol-tools"
          ],
          "metadata": {}
        },
        {
          "id": "tool:leave_review",
          "kind": "mcp_tool",
          "capability_id": "commerce.order-management",
          "effect": "unknown",
          "open_world": false,
          "idempotency": "unknown",
          "confirmation": "explicit policy",
          "input_contract": "typed",
          "output_contract": "typed_envelope_dynamic_result",
          "accepts": [
            "order_id",
            "stars",
            "optional comment, facets, claims"
          ],
          "produces": [
            "review submission confirmation"
          ],
          "runtime_auth": {},
          "pricing": {},
          "evidence_ids": [
            "protocol-tools"
          ],
          "metadata": {}
        },
        {
          "id": "tool:get_material_guide",
          "kind": "mcp_tool",
          "capability_id": "data.retrieve",
          "effect": "read",
          "open_world": false,
          "idempotency": "unknown",
          "confirmation": "explicit policy",
          "input_contract": "typed",
          "output_contract": "typed_envelope_dynamic_result",
          "accepts": [
            "material",
            "process",
            "question"
          ],
          "produces": [
            "material facts and comparisons"
          ],
          "runtime_auth": {},
          "pricing": {},
          "evidence_ids": [
            "protocol-tools"
          ],
          "metadata": {}
        },
        {
          "id": "tool:get_network_capabilities",
          "kind": "mcp_tool",
          "capability_id": "data.retrieve",
          "effect": "read",
          "open_world": false,
          "idempotency": "unknown",
          "confirmation": "explicit policy",
          "input_contract": "typed",
          "output_contract": "typed_envelope_dynamic_result",
          "accepts": [
            "process"
          ],
          "produces": [
            "live network capabilities catalog"
          ],
          "runtime_auth": {},
          "pricing": {},
          "evidence_ids": [
            "protocol-tools"
          ],
          "metadata": {}
        }
      ],
      "access": {
        "distribution_license": {},
        "runtime_auth": {},
        "runtime_pricing": {},
        "dependencies": []
      },
      "operational_flags": [],
      "trust": {
        "signal": "none",
        "evidence_ids": [],
        "reason": "No suspicious or malicious evidence found."
      },
      "fit": {
        "good_for": [
          "Getting instant quotes for 3D printing, CNC, sheet metal, and decals from multiple vendors",
          "Comparing fabrication options across materials, processes, and shipping constraints",
          "Placing orders and tracking them through a unified interface",
          "Providing material guidance for design decisions"
        ],
        "not_for": [
          "Designing or generating 3D models (only quoting existing designs)",
          "Handling non-US shipping destinations (only US ZIP codes supported)",
          "Complex multi-part assemblies with mixed processes (not explicitly supported)"
        ]
      },
      "evidence": [
        {
          "id": "source-record",
          "type": "registry_record",
          "source": "https://registry.modelcontextprotocol.io/v0.1/servers/ai.agenticfabricationnetwork%2Fufp/versions/0.1.1",
          "observation": "MCP source record for Agentic Fabrication Network (AFN); version 0.1.1.",
          "observed_at": null,
          "payload": {}
        },
        {
          "id": "protocol-tools",
          "type": "protocol_observation",
          "source": "https://agenticfabricationnetwork.ai/mcp#tools/list",
          "observation": "12 tools were returned by MCP discovery; 12 were retained for review.",
          "observed_at": "2026-09-03T06:07:19.850Z",
          "payload": {}
        }
      ],
      "unknowns": [
        "Authentication mechanism (type unknown)",
        "Pricing model (unknown)",
        "Exact output schema for tools (not provided)",
        "Runtime behavior under load or failure conditions",
        "Whether the server supports OAuth or other auth flows"
      ],
      "id": "REV_0FADFE35025F",
      "resource_id": "RES_828ADF804FBA",
      "evaluator_type": "platform_ai",
      "provider": "deepseek",
      "model": "deepseek-v4-flash",
      "review_scope": "protocol-inspected-mcp",
      "created_at": "2026-09-03T06:31:04.718Z"
    }
  }
}