1import{j as e}from"./index-BUCvl-7H.js";import{P as p,C as h}from"./page-blocks-Dsnbw40X.js";import{R as x}from"./route-jsonld-Sb2VTp7_.js";import"./product-backdrop-BD36kQZu.js";import"./page-jsonld-CA3akf3n.js";const m="https://vitaponix.com/mcp";function a({children:s}){return e.jsx("pre",{className:"mt-4 overflow-x-auto rounded-sm border border-border bg-mist p-5 font-mono text-xs leading-relaxed text-foreground",children:s})}function r({name:s,description:o,params:n,example:c,examples:i}){return e.jsxs("article",{className:"bg-background p-8",children:[e.jsx("h3",{className:"font-mono text-sm tracking-wide text-primary",children:s}),e.jsx("p",{className:"mt-3 text-sm text-muted-foreground",children:o}),e.jsxs("div",{className:"mt-5 border-t border-border pt-5",children:[e.jsx("p",{className:"eyebrow",children:"Parameters"}),n.length===0?e.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:"None â call with an empty arguments object."}):e.jsx("ul",{className:"mt-2 space-y-2",children:n.map(([l,d])=>e.jsxs("li",{className:"text-sm",children:[e.jsx("code",{className:"font-mono text-xs text-primary",children:l}),e.jsxs("span",{className:"text-muted-foreground",children:[" â ",d]})]},l))})]}),e.jsx(a,{children:c}),i&&i.length>0&&e.jsxs("div",{className:"mt-6",children:[e.jsx("p",{className:"eyebrow",children:"More example queries"}),i.map(([l,d])=>e.jsxs("div",{children:[e.jsx("p",{className:"mt-4 text-sm text-muted-foreground",children:l}),e.jsx(a,{children:d})]},l))]})]})}function t(s,o){return JSON.stringify({jsonrpc:"2.0",id:1,method:"tools/call",params:{name:s,arguments:o}},null,2)}const u=[["Add the server to your MCP client",`In Claude, ChatGPT, Cursor or any MCP-compatible client, add a new MCP server / connector with the URL ${m}. No API key is needed â authentication happens in the next step.`],["Sign in when prompted","The first time you connect, the client opens the Vitaponix OAuth flow in your browser. Sign in with the same account you use on this site."],["Approve access on the consent screen","Review what the client is asking for and choose Approve. You can revoke access at any time by disconnecting the server in your client."],["Start asking questions","Once connected, the assistant can call the tools below on your behalf â catalog tools read the public product range, and account tools read only your own saved plans."]];function w(){return e.jsxs(e.Fragment,{children:[e.jsx(x,{path:"/mcp-docs",type:"WebPage"}),e.jsx(p,{eyebrow:"Developers",title:e.jsxs(e.Fragment,{children:["The Vitaponix ",e.jsx("span",{className:"gradient-vita-text",children:"MCP server"})]}),subtitle:"Connect Claude, ChatGPT, Cursor or any MCP-compatible assistant to the Vitaponix catalog and your saved subscription plans â secured with OAuth."}),e.jsx("section",{className:"container-vp pb-16",children:e.jsxs("div",{className:"border border-border bg-background p-8",children:[e.jsx("p",{className:"eyebrow",children:"Endpoint"}),e.jsx("p",{className:"mt-3 font-mono text-lg text-foreground",children:m}),e.jsx("p",{className:"mt-3 max-w-2xl text-sm text-muted-foreground",children:"Speaks MCP over Streamable HTTP. Clients that support OAuth 2.1 with dynamic client registration (Claude, ChatGPT, Cursor) connect with zero configuration beyond the URL."})]})}),e.jsxs("section",{className:"container-vp pb-24",children:[e.jsx("p",{className:"eyebrow",children:"Setup"}),e.jsx("h2",{className:"mt-4 font-display text-4xl",children:"Connect with OAuth in four steps."}),e.jsx("ol",{className:"mt-10 grid gap-px border border-border bg-border md:grid-cols-2",children:u.map(([s,o],n)=>e.jsxs("li",{className:"bg-background p-8",children:[e.jsxs("p",{className:"font-mono text-[10px] tracking-[0.22em] uppercase text-primary",children:["Step ",n+1]}),e.jsx("h3",{className:"mt-3 font-display text-xl",children:s}),e.jsx("p",{className:"mt-3 text-sm text-muted-foreground",children:o})]},s))}),e.jsxs("div",{className:"mt-8 border border-border bg-background p-8",children:[e.jsx("p",{className:"eyebrow",children:"Client configuration"}),e.jsx("p",{className:"mt-3 text-sm text-muted-foreground",children:"For clients that read a JSON config file, the entry looks like this:"}),e.jsx(a,{children:`{ 2 "mcpServers": { 3 "vitaponix": { 4 "url": "${m}" 5 } 6 } 7}`}),e.jsx("p",{className:"mt-4 text-sm text-muted-foreground",children:"Every request is authenticated as you. Catalog tools are read-only, and account tools can only ever see the subscription plans saved under your own account."})]})]}),e.jsxs("section",{className:"container-vp pb-24",children:[e.jsx("p",{className:"eyebrow",children:"Tool reference"}),e.jsx("h2",{className:"mt-4 font-display text-4xl",children:"Seven tools, one catalog."}),e.jsxs("p",{className:"mt-4 max-w-2xl text-sm text-muted-foreground",children:["Each example below is a raw ",e.jsx("code",{className:"font-mono text-xs",children:"tools/call"})," JSON-RPC message â your MCP client sends these for you when the assistant decides a tool is needed. Discover the full machine-readable schema with"," ",e.jsx("code",{className:"font-mono text-xs",children:"tools/list"}),"."]}),e.jsxs("div",{className:"mt-10 grid gap-px border border-border bg-border",children:[e.jsx(r,{name:"search_products",description:"Search the nutrient catalog by product name, ingredient or guaranteed-analysis element, and free-text keywords across descriptions, benef
7its, category and growth stage. Optional filters narrow results by ingredient origin, product category and growth stage. Results are paginated and can be sorted by relevance, newest additions, or region-aware price. Every result explains itself: nameHighlighted and ingredientsHighlighted mark the exact substring hit or closest fuzzy-corrected portion directly inside the product name and ingredients; a matches array lists per-field context snippets with <mark> highlights; and a debug object lists each token's edit-distance budget plus any tokens that matched fuzzily, with their actual distance.",params:[["query",'optional string â e.g. "vitaroot", "seaweed", "calcium", "bloom". Typo-tolerant: minor misspellings still match and are flagged fuzzyMatch; exact hits rank higher. Omit to browse the filtered catalog'],["origin",'optional string â only products whose ingredient origin contains this text, e.g. "seaweed", "marine", "silicon"'],["category",'optional enum â one of "Foundation", "Bloom", "Signaling", "Structure", "Finish"'],["stage",'optional string â only products whose growth stage contains this text, e.g. "veg", "late bloom", "all stages"'],["sort",'optional enum â "relevance" (default, ranked by match score; AâZ when browsing), "newest" (recently added first), or "price" (lowest 1L price first in the selected pricing region)'],["region",`optional enum â "AU" (default), "EU" or "US". Pass the caller's selected region so the "price" sort uses prices from their market; ignored by other sorts`],["page","optional integer, default 1 â page number"],["pageSize","optional integer, default 10, max 25 â results per page"]],example:t("search_products",{query:"seaweed root",category:"Foundation",stage:"veg",sort:"price",region:"EU",page:1,pageSize:5}),examples:[["Typo-tolerant search â a misspelled name still finds the right product, flagged fuzzyMatch with the corrected word highlighted and a debug object showing the token's edit distance vs. its budget",t("search_products",{query:"vitarot",page:1,pageSize:5})],["Filter-only browsing â no query, just an origin and growth stage",t("search_products",{origin:"marine",stage:"bloom",page:1,pageSize:10})],["Deep paging â fetch the next slice with page + pageSize (hasMore tells you when to stop)",t("search_products",{query:"vita",page:2,pageSize:3})]]}),e.jsx(r,{name:"list_products",description:"List the full Vitaponix nutrient catalog with category, growth stage and a short description for each product.",params:[],example:t("list_products",{})}),e.jsx(r,{name:"get_product",description:"Get full details for one product by slug, including benefits, guaranteed analysis, signaling and feeding directions.",params:[["slug",'required string â e.g. "vita-root". Use list_products or search_products to discover slugs']],example:t("get_product",{slug:"vita-root"})}),e.jsx(r,{name:"list_subscription_plan_options",description:"List every configurable subscription option with its allowed values and the calculator's defaults: the two plan templates (standard vs optimized), harvest commitment range with volume-discount tiers, delivery frequency presets, payment options, seasonal break settings, pricing regions, and grower types. Call this before helping someone configure or compare subscription plans. Public â no authentication required.",params:[],example:t("list_subscription_plan_options",{})}),e.jsx(r,{name:"list_my_subscription_plans",description:"List the subscription plans you saved in the nutrient calculator â schedule, products and total cost, newest first. Reads only your own plans.",params:[],example:t("list_my_subscription_plans",{})}),e.jsx(r,{name:"get_my_subscription_plan",description:"Get the full details of one saved subscription plan: every saved setting (harvest count, veg/flower weeks, delivery frequency, payment option, seasonal break, region, grower type), the original calculator inputs, and the product breakdown with costs.",params:[["id","required UUID â a plan ID from list_my_subscription_plans"]],example:t("get_my_subscription_plan",{id:"3f6b2c1e-8a4d-4e2f-9c5b-7d1a0e8f6b2a"})}),e.jsx(r,{name:"update_my_subscription_plan",description:"Update the saved settings of one of your subscription plans and get the full updated plan back. Only the fields you pass are changed â everything else is preserved. This updates settings only: product selections and total cost are not recalculated (rebuild the plan in the nutrient calculator to reprice it). Delivery frequency is validated against the plan's grow cycle so nutrients never schedule past a harvest.",params:[["id","required UUID â a plan ID from list_my_subscription_plans"],["planName","optional string â new display name for the plan"],["harvestCommitment","optional integer 1â52 â harvests covered; 5%/10%/15% volume discounts at 3/5/10 harvests"],["frequencyWeeks","optional integer 1â52 â weeks between deliveries; must fit within the plan's veg + flower weeks"],["paymentOption",'optional enum â "upfront", "monthly", "per_delivery", or "weekly"'],["includeSeasonalBreak","optional boolean â enable or disable the off-season break"],["breakStartMonth",'optional enum â full month name, e.g. "December"'],["breakDurationMonths","optional integer 1â9 â length of the seasonal break"],["regi
7on",'optional enum â "AU", "EU", or "US" (does not reprice the saved total)'],["growerType",'optional enum â "home" or "commercial"']],example:t("update_my_subscription_plan",{id:"3f6b2c1e-8a4d-4e2f-9c5b-7d1a0e8f6b2a",harvestCommitment:10,frequencyWeeks:12,paymentOption:"monthly",includeSeasonalBreak:!0,breakStartMonth:"December",breakDurationMonths:3})})]})]}),e.jsxs("section",{className:"container-vp pb-24",children:[e.jsx("p",{className:"eyebrow",children:"Typo tolerance"}),e.jsx("h2",{className:"mt-4 font-display text-4xl",children:"Misspell it. Still find it."}),e.jsxs("p",{className:"mt-4 max-w-2xl text-sm text-muted-foreground",children:["Minor misspellings still find the right product â even in multi-term queries: misspell one word and the other terms still match, with a combined relevance score that ranks products matching every term above partial matches. Edit-distance budgets are per field, so short ingredient terms stay exact and don't produce false positives: names allow"," ",e.jsx("code",{className:"font-mono text-xs",children:"1"})," edit from 4 letters and"," ",e.jsx("code",{className:"font-mono text-xs",children:"2"})," from 8, keywords from 5/9, and ingredients from 6/10. Exact hits always rank above fuzzy ones, and closer corrections score higher. Each result carries a ",e.jsx("code",{className:"font-mono text-xs",children:"fuzzyMatch"})," flag, a"," ",e.jsx("code",{className:"font-mono text-xs",children:"relevanceScore"})," with"," ",e.jsx("code",{className:"font-mono text-xs",children:"tokenCoverage"}),", a"," ",e.jsx("code",{className:"font-mono text-xs",children:"debug"})," object, and two highlighted fields â"," ",e.jsx("code",{className:"font-mono text-xs",children:"nameHighlighted"})," and"," ",e.jsx("code",{className:"font-mono text-xs",children:"ingredientsHighlighted"})," â that mark the exact substring hit (or closest fuzzy-corrected word) directly inside the product name and ingredients so you can see which portion matched:"]}),e.jsx("div",{className:"mt-8 max-w-2xl",children:e.jsx(a,{children:`# typed "vitarot seaweed" â first result (one term misspelled, one exact) 8"name": "VitaRoot", 9"nameHighlighted": "<mark>VitaRoot</mark>", 10"ingredients": "Cold-pressed Ascophyllum nodosum seaweed extract", 11"ingredientsHighlighted": "Cold-pressed Ascophyllum nodosum <mark>seaweed</mark> extract", 12"fuzzyMatch": true, 13"relevanceScore": 4, 14"tokenCoverage": 1, 15"debug": { 16 "tokenThresholds": { 17 "vitarot": { "name": 1, "ingredient": 1, "keywords": 1 }, 18 "seaweed": { "name": 1, "ingredient": 1, "keywords": 1 } 19 }, 20 "tokenCoverage": 1, 21 "fuzzyTokens": [ 22 { "token": "vitarot", "matched": "VitaRoot", "field": "name", "distance": 1, "maxEdits": 1 } 23 ] 24}`})}),e.jsx("div",{className:"mt-8 overflow-x-auto rounded-xl border border-border",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-border bg-secondary/40",children:[e.jsx("th",{className:"px-4 py-2.5 text-left font-display text-foreground/80",children:"You typed"}),e.jsx("th",{className:"px-4 py-2.5 text-left font-display text-foreground/80",children:"Matched"}),e.jsx("th",{className:"px-4 py-2.5 text-left font-display text-foreground/80",children:"Found in"}),e.jsx("th",{className:"px-4 py-2.5 text-left font-display text-foreground/80",children:"On field"}),e.jsx("th",{className:"px-4 py-2.5 text-left font-display text-foreground/80",children:"Distance / budget"})]})}),e.jsx("tbody",{children:[["vitarot","VitaRoot","VitaRoot","product name","1 / 1"],["calcuim","calcium","VitaCal","ingredient (guaranteed analysis)","1 / 1"],["potasium","potassium","VitaBulk & VitaBud","ingredient / description","1 / 1"],["seawead","Seaweed","VitaRoot","ingredient","1 / 1"],["humic","humic","VitaRoot","ingredient â exact only, 5-letter terms get no budget","0 / 0"],["silca","Silica","VitaSilica","product name","1 / 1"]].map(([s,o,n,c,i])=>e.jsxs("tr",{className:"border-b border-border/40 last:border-0",children:[e.jsx("td",{className:"px-4 py-2.5",children:e.jsx("code",{className:"font-mono text-xs",children:s})}),e.jsx("td",{className:"px-4 py-2.5",children:e.jsx("code",{className:"font-mono text-xs text-primary",children:o})}),e.jsx("td",{className:"px-4 py-2.5 text-muted-foreground",children:n}),e.jsx("td",{className:"px-4 py-2.5 text-muted-foreground",children:c}),e.jsx("td",{className:"px-4 py-2.5",children:e.jsx("code",{className:"font-mono text-xs",children:i})})]},s))})]})}),e.jsxs("p",{className:"mt-4 max-w-2xl text-sm text-muted-foreground",children:["Budgets tighten on ingredients to keep short chemical terms precise: a 4â5 letter token like ",e.jsx("code",{className:"font-mono text-xs",children:"humic"})," must match exactly there, while a misspelled product name of the same length still corrects. The largest budget (2 edits) needs 8+ letters on names, 9+ on keywords, 10+ on ingredients. Every row above is live behavior â reproduce it with ",e.jsx("code",{className:"font-mono text-xs",children:"search_products"}),", e.g. ",e.jsx("code",{className:"font-mono text-xs",children:'{"query": "vitarot seaweed"}'}),"."]})]}),e.jsxs("section",{className:"container-vp pb-24",children:[e.jsx("p",{className:"eyebrow",children:"Paging walkthrough"}),e.jsx("h2",{className:"mt-4 font-display text-4xl",children:"Walk every page of search_products."}),e.jsxs("p",{className:"mt-4 max-w-2xl text-sm text-muted-foreground",children:["Results arrive one page at a time. Every response carries five paging fields â"," ",e.jsx("code",{className:"font-mono text-xs",children:"page"}),", ",e.jsx("code",{className:"font-mono text-xs",children:"pageSize"}),","," ",e.jsx("code",{className:"font-mono text-xs",children:"total"}),", ",e.jsx("code",{className:"font-mono text-xs",children:"totalPages"})," and"," ",e.jsx("code",{className:"font-mono text-xs",children:"hasMore"})," â so the next-page logic is a simple loop."]}),e.jsxs("ol",{className:"mt-10 grid gap-px border border-border bg-border md:grid-cols-2",children:[e.jsxs("li",{className:"bg-background p-8",children:[e.jsx("p",{className:"font-mono text-[10px] tracking-[0.22em] uppercase text-primary",children:"Step 1"}),e.jsx("h3",{className:"mt-3 font-display text-xl",children:"Ask for page 1 with a pageSize"}),e.jsxs("p",{className:"mt-3 text-sm text-muted-foreground",children:["Send the first call with ",e.jsx("code",{className:"font-mono text-xs",children:"page: 1"})," and a"," ",e.jsx("code",{className:"font-mono text-xs",children:"pageSize"})," up to 25 (default 10)."]}),e.jsx(a,{children:t("search_products",{query:"seaweed",page:1,pageSize:5})})]}),e.jsxs("li",{className:"bg-background p-8",children:[e.jsx("p",{className:"font-mono text-[10px] tracking-[0.22em] uppercase text-primary",children:"Step 2"}),e.jsx("h3",{className:"mt-3 font-display text-xl",children:"Read the paging fields"}),e.jsx("p",{className:"mt-3 text-sm text-muted-foreground",children:"The structured result tells you where you are and whether more pages exist:"}),e.jsx(a,{children:`{ 25 "page": 1, 26 "pageSize": 5, 27 "total": 12, 28 "totalPages": 3, 29 "hasMore": true, 30 "products": [ /* 5 products */ ] 31}`})]}),e.jsxs("li",{className:"bg-background p-8",children:[e.jsx("p",{className:"font-mono text-[10px] tracking-[0.22em] uppercase text-primary",children:"Step 3"}),e.jsx("h3",{className:"mt-3 font-display text-xl",children:"While hasMore is true, fetch page + 1"}),e.jsxs("p",{className:"mt-3 text-sm text-muted-foreground",children:["Keep ",e.jsx("code",{className:"font-mono text-xs",children:"query"}),", filters and"," ",e.jsx("code",{className:"font-mono text-xs",children:"sort"})," identical â only"," ",e.jsx("code",{className:"font-mono text-xs",children:"page"})," changes. Changing them mid-walk re-ranks the result set and the pages shift under you."]}),e.jsx(a,{children:t("search_products",{query:"seaweed",page:2,pageSize:5})})]}),e.jsxs("li",{className:"bg-background p-8",children:[e.jsx("p",{className:"font-mono text-[10px] tracking-[0.22em] uppercase text-primary",children:"Step 4"}),e.jsx("h3",{className:"mt-3 font-display text-xl",children:"Stop when hasMore is false"}),e.jsxs("p",{className:"mt-3 text-sm text-muted-foreground",children:["On the last page ",e.jsx("code",{className:"font-mono text-xs",children:"page === totalPages"}),". Asking beyond it is not an error â you get an empty"," ",e.jsx("code",{className:"font-mono text-xs",children:"products"})," array with"," ",e.jsx("code",{className:"font-mono text-xs",children:"hasMore: false"}),"."]}),e.jsx(a,{children:`{ 32 "page": 3, 33 "pageSize": 5, 34 "total": 12, 35 "totalPages": 3, 36 "hasMore": false, 37 "products": [ /* last 2 products */ ] 38}`})]})]})]}),e.jsx("section",{className:"container-vp pb-24",children:e.jsxs("div",{className:"border border-border bg-background p-8 md:flex md:items-center md:justify-between md:gap-8",children:[e.jsxs("div",{children:[e.jsx("p",{className:"eyebrow",children:"Postman / JSON-RPC runner"}),e.jsx("h2",{className:"mt-4 font-display text-3xl",children:"Try every tool from Postman."}),e.jsxs("p",{className:"mt-3 max-w-2xl text-sm text-muted-foreground",children:["A ready-to-import collection covering all seven tools, a session"," ",e.jsx("code",{className:"font-mono text-xs",children:"initialize"})," call and"," ",e.jsx("code",{className:"font-mono text-xs",children:"tools/list"})," â with the required"," ",e.jsx("code",{className:"font-mono text-xs",children:"Accept: application/json, text/event-stream"})," ","header preset on every request. Paste a token into the"," ",e.jsx("code",{className:"font-mono text-xs",children:"access_token"})," collection variable to call the account tools."]})]}),e.jsx("a",{href:"/vitaponix-mcp.postman_collection.json",download:!0,className:"mt-6 inline-flex shrink-0 items-center border border-primary px-6 py-3 font-mono text-xs uppercase tracking-[0.18em] text-primary transition-colors hover:bg-primary hover:text-primary-foreground md:mt-0",children:"Download collection"})]})}),e.jsx(h,{eyebrow:"No account yet?",title:"Save a plan, then ask your assistant about it.",primary:{to:"/calculator",label:"Open the Calculator"}})]})}export{w as component};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.