Vitaponix — nextgen nutrients

Developers

The Vitaponix MCP server.

Connect Claude, ChatGPT, Cursor or any MCP-compatible assistant to the Vitaponix catalog and your saved subscription plans — secured with OAuth.

Endpoint

https://vitaponix.com/mcp

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.

Setup

Connect with OAuth in four steps.

  1. Step 1

    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 https://vitaponix.com/mcp. No API key is needed — authentication happens in the next step.

  2. Step 2

    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.

  3. Step 3

    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.

  4. Step 4

    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.

Client configuration

For clients that read a JSON config file, the entry looks like this:

{
  "mcpServers": {
    "vitaponix": {
      "url": "https://vitaponix.com/mcp"
    }
  }
}

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.

Tool reference

Seven tools, one catalog.

Each example below is a raw 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 tools/list.

search_products

Search the nutrient catalog by product name, ingredient or guaranteed-analysis element, and free-text keywords across descriptions, benefits, 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.

Parameters

  • queryoptional 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
  • originoptional string — only products whose ingredient origin contains this text, e.g. "seaweed", "marine", "silicon"
  • categoryoptional enum — one of "Foundation", "Bloom", "Signaling", "Structure", "Finish"
  • stageoptional string — only products whose growth stage contains this text, e.g. "veg", "late bloom", "all stages"
  • sortoptional 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)
  • regionoptional 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
  • pageoptional integer, default 1 — page number
  • pageSizeoptional integer, default 10, max 25 — results per page
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_products",
    "arguments": {
      "query": "seaweed root",
      "category": "Foundation",
      "stage": "veg",
      "sort": "price",
      "region": "EU",
      "page": 1,
      "pageSize": 5
    }
  }
}

More example queries

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

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_products",
    "arguments": {
      "query": "vitarot",
      "page": 1,
      "pageSize": 5
    }
  }
}

Filter-only browsing — no query, just an origin and growth stage

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_products",
    "arguments": {
      "origin": "marine",
      "stage": "bloom",
      "page": 1,
      "pageSize": 10
    }
  }
}

Deep paging — fetch the next slice with page + pageSize (hasMore tells you when to stop)

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_products",
    "arguments": {
      "query": "vita",
      "page": 2,
      "pageSize": 3
    }
  }
}

list_products

List the full Vitaponix nutrient catalog with category, growth stage and a short description for each product.

Parameters

None — call with an empty arguments object.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "list_products",
    "arguments": {}
  }
}

get_product

Get full details for one product by slug, including benefits, guaranteed analysis, signaling and feeding directions.

Parameters

  • slugrequired string — e.g. "vita-root". Use list_products or search_products to discover slugs
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_product",
    "arguments": {
      "slug": "vita-root"
    }
  }
}

list_subscription_plan_options

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.

Parameters

None — call with an empty arguments object.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "list_subscription_plan_options",
    "arguments": {}
  }
}

list_my_subscription_plans

List the subscription plans you saved in the nutrient calculator — schedule, products and total cost, newest first. Reads only your own plans.

Parameters

None — call with an empty arguments object.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "list_my_subscription_plans",
    "arguments": {}
  }
}

get_my_subscription_plan

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.

Parameters

  • idrequired UUID — a plan ID from list_my_subscription_plans
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_my_subscription_plan",
    "arguments": {
      "id": "3f6b2c1e-8a4d-4e2f-9c5b-7d1a0e8f6b2a"
    }
  }
}

update_my_subscription_plan

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.

Parameters

  • idrequired UUID — a plan ID from list_my_subscription_plans
  • planNameoptional string — new display name for the plan
  • harvestCommitmentoptional integer 1–52 — harvests covered; 5%/10%/15% volume discounts at 3/5/10 harvests
  • frequencyWeeksoptional integer 1–52 — weeks between deliveries; must fit within the plan's veg + flower weeks
  • paymentOptionoptional enum — "upfront", "monthly", "per_delivery", or "weekly"
  • includeSeasonalBreakoptional boolean — enable or disable the off-season break
  • breakStartMonthoptional enum — full month name, e.g. "December"
  • breakDurationMonthsoptional integer 1–9 — length of the seasonal break
  • regionoptional enum — "AU", "EU", or "US" (does not reprice the saved total)
  • growerTypeoptional enum — "home" or "commercial"
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "update_my_subscription_plan",
    "arguments": {
      "id": "3f6b2c1e-8a4d-4e2f-9c5b-7d1a0e8f6b2a",
      "harvestCommitment": 10,
      "frequencyWeeks": 12,
      "paymentOption": "monthly",
      "includeSeasonalBreak": true,
      "breakStartMonth": "December",
      "breakDurationMonths": 3
    }
  }
}

Typo tolerance

Misspell it. Still find it.

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 1 edit from 4 letters and 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 fuzzyMatch flag, a relevanceScore with tokenCoverage, a debug object, and two highlighted fields — nameHighlighted and 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:

# typed "vitarot seaweed" → first result (one term misspelled, one exact)
"name": "VitaRoot",
"nameHighlighted": "<mark>VitaRoot</mark>",
"ingredients": "Cold-pressed Ascophyllum nodosum seaweed extract",
"ingredientsHighlighted": "Cold-pressed Ascophyllum nodosum <mark>seaweed</mark> extract",
"fuzzyMatch": true,
"relevanceScore": 4,
"tokenCoverage": 1,
"debug": {
  "tokenThresholds": {
    "vitarot": { "name": 1, "ingredient": 1, "keywords": 1 },
    "seaweed": { "name": 1, "ingredient": 1, "keywords": 1 }
  },
  "tokenCoverage": 1,
  "fuzzyTokens": [
    { "token": "vitarot", "matched": "VitaRoot", "field": "name", "distance": 1, "maxEdits": 1 }
  ]
}
You typedMatchedFound inOn fieldDistance / budget
vitarotVitaRootVitaRootproduct name1 / 1
calcuimcalciumVitaCalingredient (guaranteed analysis)1 / 1
potasiumpotassiumVitaBulk & VitaBudingredient / description1 / 1
seaweadSeaweedVitaRootingredient1 / 1
humichumicVitaRootingredient — exact only, 5-letter terms get no budget0 / 0
silcaSilicaVitaSilicaproduct name1 / 1

Budgets tighten on ingredients to keep short chemical terms precise: a 4–5 letter token like 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 search_products, e.g. {"query": "vitarot seaweed"}.

Paging walkthrough

Walk every page of search_products.

Results arrive one page at a time. Every response carries five paging fields — page, pageSize, total, totalPages and hasMore — so the next-page logic is a simple loop.

  1. Step 1

    Ask for page 1 with a pageSize

    Send the first call with page: 1 and a pageSize up to 25 (default 10).

    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "search_products",
        "arguments": {
          "query": "seaweed",
          "page": 1,
          "pageSize": 5
        }
      }
    }
  2. Step 2

    Read the paging fields

    The structured result tells you where you are and whether more pages exist:

    {
      "page": 1,
      "pageSize": 5,
      "total": 12,
      "totalPages": 3,
      "hasMore": true,
      "products": [ /* 5 products */ ]
    }
  3. Step 3

    While hasMore is true, fetch page + 1

    Keep query, filters and sort identical — only page changes. Changing them mid-walk re-ranks the result set and the pages shift under you.

    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "search_products",
        "arguments": {
          "query": "seaweed",
          "page": 2,
          "pageSize": 5
        }
      }
    }
  4. Step 4

    Stop when hasMore is false

    On the last page page === totalPages. Asking beyond it is not an error — you get an empty products array with hasMore: false.

    {
      "page": 3,
      "pageSize": 5,
      "total": 12,
      "totalPages": 3,
      "hasMore": false,
      "products": [ /* last 2 products */ ]
    }

Postman / JSON-RPC runner

Try every tool from Postman.

A ready-to-import collection covering all seven tools, a session initialize call and tools/list — with the required Accept: application/json, text/event-stream header preset on every request. Paste a token into the access_token collection variable to call the account tools.

Download collection

No account yet?

Save a plan, then ask your assistant about it..