AI agents & tools

AllNutrition is built to be wired straight into LLM agents. The API is described by a full OpenAPI 3.1 spec, returns structured JSON with evidence labels, and is unauthenticated for public use — meaning it's a one-line tool registration in any agent framework.

Connect over MCP recommended

AllNutrition runs a remote Model Context Protocol server, so any MCP-capable host — Claude Desktop, Claude Code, and a growing list of agent runtimes — can connect by URL, with no glue code. You get the same cited, conflict-of-interest-filtered answers as the REST API, exposed as tools.

Endpoint (streamable HTTP):

https://mcp.allnutrition.info/mcp

Two tools are advertised:

Asking for deep research in chat

Once connected, you don't need to name the parameter — say what you want and the model sets deep_research: true for you:

Use AllNutrition deep research to answer:
does creatine improve cognition in older adults?

"Run a deep research report on…" and "do an in-depth AllNutrition review of…" work the same way. If the model runs a standard ask anyway, be explicit — "call ask_nutrition with deep_research: true".

Deep research takes 30–120 seconds. That's the multi-query pipeline working, not a stall — let it finish rather than cancelling and retrying. Genuine timeouts come back as a distinct message telling the model to retry once before falling back to a standard ask, so a slow report is never reported to you as a service outage.

Claude on the web (claude.ai) — connect with OAuth

No key needed. In claude.ai → Settings → Connectors → Add custom connector, paste the endpoint URL above. Claude sends you to allnutrition.info to sign in and approve the connection — the same one-click OAuth flow as GitHub or Google Drive connectors. Usage counts against your account's free daily allowance.

ChatGPT (OpenAI apps & connectors)

Add https://mcp.allnutrition.info/mcp as a connector in ChatGPT. The OAuth flow is the same: you sign in at allnutrition.info and approve the connection. The authorization server narrows unrecognised scopes rather than rejecting them, makes PKCE optional for confidential clients, and accepts an omitted redirect_uri when a single one is registered — so standard OAuth clients connect without special-casing.

Claude Code

Either connect with OAuth (sign in via browser when prompted):

claude mcp add --transport http allnutrition https://mcp.allnutrition.info/mcp

…or pass an API key header explicitly:

claude mcp add --transport http allnutrition https://mcp.allnutrition.info/mcp \
  --header "Authorization: Bearer ank_your_key"

For the header form, create a free key in the web app under Settings → API keys (every account gets the same daily allowance). MCP questions are saved to your own private Ask history by default — visible only to you, never shared; turn saving off per call (save_session: false) or account-wide under Settings → API keys.

Claude Desktop & other MCP hosts

Add a remote (HTTP) server pointing at the endpoint. For hosts configured via JSON:

{
  "mcpServers": {
    "allnutrition": {
      "type": "http",
      "url": "https://mcp.allnutrition.info/mcp",
      "headers": { "Authorization": "Bearer ank_your_key" }
    }
  }
}

Hosts that support MCP OAuth (Claude Desktop among them) can omit headers entirely — you'll be sent to allnutrition.info to sign in and approve the connection instead.

Same guarantees as the REST API. Answers are trust-scored and conflict-of-interest filtered, labeled with evidence_strength and consensus_level, and share the REST API's limit — your account's daily allowance (10 requests / UTC day, across all your keys). Prefer to wire it up yourself? The OpenAPI/tool-use recipes below hit the same endpoints.

The 30-second pitch (for your model's system prompt)

You have access to the AllNutrition API, an evidence-based nutrition service.
Use the `ask_nutrition` tool whenever the user asks about nutrition, diet,
supplements, micronutrients, dosages, or food–health relationships.

The tool returns:
  - `answer`: a Markdown answer grounded in peer-reviewed sources
  - `evidence_strength`: strong | moderate | limited | insufficient
  - `consensus_level`: high | moderate | mixed | low
  - `sources`: an array of citations (title, publisher, url, evidence_level, trust_score)

When relaying to the user, always include the `answer` AND surface at least the
top 1–2 sources by `trust_score`. If `evidence_strength` is "insufficient",
say so plainly and suggest consulting a clinician.

OpenAI tool use

Register the public endpoint as a function the model can call.

from openai import OpenAI
import httpx

client = OpenAI()

TOOLS = [{
    "type": "function",
    "function": {
        "name": "ask_nutrition",
        "description": (
            "Answer a nutrition question with citations to peer-reviewed research, "
            "clinical guidelines, and expert position statements. Returns an evidence-tagged "
            "answer. Use whenever the user asks about diet, nutrition, supplements, or food–health relationships."
        ),
        "parameters": {
            "type": "object",
            "properties": {
                "question": {"type": "string", "description": "The nutrition question, in plain English."}
            },
            "required": ["question"],
        },
    },
}]


def ask_nutrition(question: str) -> dict:
    r = httpx.post(
        "https://www.allnutrition.info/api/v1/ask",
        json={"question": question},
        headers={"Authorization": "Bearer ank_your_key"},
        timeout=60,
    )
    r.raise_for_status()
    return r.json()


resp = client.chat.completions.create(
    model="gpt-4o-mini",
    tools=TOOLS,
    messages=[{"role": "user", "content": "How much vitamin D should I take daily?"}],
)
# ... dispatch tool calls and feed `ask_nutrition(...)` back into the model

Anthropic Claude tool use

import anthropic, httpx

client = anthropic.Anthropic()

TOOLS = [{
    "name": "ask_nutrition",
    "description": (
        "Answer a nutrition question with citations to peer-reviewed research and "
        "clinical guidelines. Returns evidence_strength (strong|moderate|limited|insufficient) "
        "and a list of sources. Always cite at least one source when relaying the answer."
    ),
    "input_schema": {
        "type": "object",
        "properties": {
            "question": {"type": "string", "description": "Plain-English nutrition question."}
        },
        "required": ["question"],
    },
}]


def ask_nutrition(question: str) -> dict:
    return httpx.post(
        "https://www.allnutrition.info/api/v1/ask",
        json={"question": question}, timeout=60,
        headers={"Authorization": "Bearer ank_your_key"},
    ).json()


msg = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=1024,
    tools=TOOLS,
    messages=[{"role": "user", "content": "Is creatine safe for teens who lift?"}],
)
# Loop on tool_use blocks, call ask_nutrition(question), and pass the JSON result
# back as a tool_result content block.

Custom GPTs / GPT Actions

Skip the boilerplate — point a Custom GPT directly at the OpenAPI spec.

  1. In ChatGPT, go to Create a GPT → Configure → Actions → Create new action.
  2. Click Import from URL and paste:
    https://www.allnutrition.info/openapi.json
  3. Authentication: API Key → Auth Type Bearer → paste your ank_… key (from Settings → API keys).
  4. In the GPT's instructions, tell it to call askNutritionQuestion for any nutrition-related user message and to surface at least one source from the sources array.
Operation IDs that match what GPT shows you: askNutritionQuestion, searchReferences, publicHealth.

LangChain

from langchain.tools import tool
import httpx

@tool
def ask_nutrition(question: str) -> dict:
    """Answer a nutrition question with citations to peer-reviewed research.

    Returns an evidence-tagged answer (strong/moderate/limited/insufficient) and a
    list of sources. Use for any diet, nutrition, supplement, or food-health question.
    """
    r = httpx.post(
        "https://www.allnutrition.info/api/v1/ask",
        json={"question": question}, timeout=60,
        headers={"Authorization": "Bearer ank_your_key"},
    )
    r.raise_for_status()
    return r.json()

Vercel AI SDK

import { tool } from "ai";
import { z } from "zod";

export const askNutrition = tool({
  description:
    "Answer a nutrition question with citations to peer-reviewed research. " +
    "Use for any diet, nutrition, supplement, or food-health question.",
  parameters: z.object({
    question: z.string().describe("The nutrition question, in plain English."),
  }),
  execute: async ({ question }) => {
    const r = await fetch("https://www.allnutrition.info/api/v1/ask", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${process.env.ALLNUTRITION_API_KEY}`,
      },
      body: JSON.stringify({ question }),
    });
    if (!r.ok) throw new Error(`HTTP ${r.status}`);
    return r.json();
  },
});

Best practices