# Herbal — canonical payload contracts

Search herbal preparations by condition/symptom from local multi-source data (EMA HMPC, Dr. Duke ethnobotany, Wikidata, WHO/NCCIH seeds) linked to WFO plant ids, plus dump/curated active constituent profiles. Query language: English MeSH headings or short HU symptom aliases for conditions; English/INN names for constituents. Not medical advice. No live external APIs.

**Service id:** `herbal`  
**Docs:** [https://mcp.glc-rag.hu/guide/herbal](https://mcp.glc-rag.hu/guide/herbal)  
**Markdown docs:** [https://mcp.glc-rag.hu/guide/herbal.md](https://mcp.glc-rag.hu/guide/herbal.md)  
**MCP resource:** `docs://herbal/payload`

POST `https://mcp.glc-rag.hu/mcp`. Values below are **type slots** from the live input schema (e.g. `<string, required>`), not example data. Fill them from the user task.

RPC result wrapper: `result.structuredContent` is the object in **Output schema**. `result.isError` mirrors `structuredContent.is_error`.

## `herbal_resolve_condition` — Resolve condition (English MeSH or short HU alias)

Resolve a short disease/symptom to MeSH candidates (hybrid FTS + vector). Query language: prefer English MeSH headings (Fatigue, Cough). Short Hungarian aliases OK (köhögés, fáradtság). Do not pass long sentences; split to a heading or short alias first.

query: English MeSH heading or a short HU alias. Not a symptom paragraph.

**Required arguments:** `query`

**Request contract**

```json
{
  "jsonrpc": "2.0",
  "id": "<integer|string>",
  "method": "tools/call",
  "params": {
    "name": "herbal_resolve_condition",
    "arguments": {
      "query": "<string, required, maxLength 200>",
      "limit": "<integer, optional, default 10, minimum 1, maximum 25>"
    }
  }
}
```

**Input schema**

```json
{
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "description": "Short condition/symptom. Best: English MeSH (Fatigue, Cough, Physical Endurance). Also: short HU alias (köhögés, fáradtság, energiahiány). Not a paragraph of symptoms.",
      "maxLength": 200
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 25,
      "default": 10
    }
  },
  "required": [
    "query"
  ],
  "additionalProperties": false
}
```

**Output schema** (`structuredContent` on success)

```json
{
  "type": "object",
  "properties": {
    "disclaimer": {
      "type": "string"
    },
    "sources": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "query": {
      "type": "string"
    },
    "count": {
      "type": "integer"
    },
    "results": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "condition_id": {
            "type": "string"
          },
          "name_en": {
            "type": "string"
          },
          "name_hu": {
            "type": [
              "string",
              "null"
            ]
          },
          "score": {
            "type": "number"
          },
          "mapped_relation_count": {
            "type": "integer"
          }
        },
        "additionalProperties": true
      }
    },
    "embedder": {
      "type": "object"
    }
  },
  "additionalProperties": true,
  "required": [
    "disclaimer",
    "sources",
    "query",
    "count",
    "results"
  ]
}
```

**Error object**

```json
{
  "type": "object",
  "required": [
    "error",
    "is_error"
  ],
  "properties": {
    "error": {
      "type": "string"
    },
    "is_error": {
      "type": "boolean",
      "const": true
    }
  },
  "additionalProperties": true
}
```

## `herbal_search_by_condition` — Search herbal uses by MeSH condition

Find herbal preparations for a MeSH condition_id (preferred) or a short free-text query. Query language same as herbal_resolve_condition: English MeSH heading or short HU alias. Long HU/EN prose often misses; call herbal_resolve_condition first and pass condition_id. Sorted by evidence_grade (A–F); monograph before ethnobotanical.

Prefer condition_id from herbal_resolve_condition. query if used: same language rules.

**Required arguments:** _(none)_

**Request contract**

```json
{
  "jsonrpc": "2.0",
  "id": "<integer|string>",
  "method": "tools/call",
  "params": {
    "name": "herbal_search_by_condition",
    "arguments": {
      "condition_id": "<string, optional>",
      "query": "<string, optional, maxLength 200>",
      "limit": "<integer, optional, default 10, minimum 1, maximum 25>",
      "include_warnings": "<boolean, optional, default True>",
      "min_evidence_grade": "<string, optional, enum A|B|C|D|E|F>",
      "sources": [
        "<string, optional, enum ema|duke|wikidata|who|nccih>"
      ]
    }
  }
}
```

**Input schema**

```json
{
  "type": "object",
  "properties": {
    "condition_id": {
      "type": "string",
      "description": "MeSH id, e.g. mesh:D003371"
    },
    "query": {
      "type": "string",
      "description": "Only if condition_id omitted. Short English MeSH or short HU alias — same rules as herbal_resolve_condition.",
      "maxLength": 200
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 25,
      "default": 10
    },
    "include_warnings": {
      "type": "boolean",
      "default": true,
      "description": "Include contraindicated / potentially_harmful rows"
    },
    "min_evidence_grade": {
      "type": "string",
      "description": "Only grades at least this strong (A best … F weakest)",
      "enum": [
        "A",
        "B",
        "C",
        "D",
        "E",
        "F"
      ]
    },
    "sources": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "ema",
          "duke",
          "wikidata",
          "who",
          "nccih"
        ]
      },
      "description": "Filter by source_system"
    }
  },
  "additionalProperties": false
}
```

**Output schema** (`structuredContent` on success)

```json
{
  "type": "object",
  "properties": {
    "disclaimer": {
      "type": "string"
    },
    "sources": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "condition_id": {
      "type": [
        "string",
        "null"
      ]
    },
    "query": {
      "type": "string"
    },
    "selection_reason": {
      "type": [
        "string",
        "null"
      ]
    },
    "mapped_relation_count": {
      "type": "integer"
    },
    "no_results_reason": {
      "type": "string"
    },
    "resolved_conditions": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "condition_id": {
            "type": "string"
          },
          "name_en": {
            "type": "string"
          },
          "name_hu": {
            "type": [
              "string",
              "null"
            ]
          },
          "score": {
            "type": "number"
          },
          "mapped_relation_count": {
            "type": "integer"
          }
        },
        "additionalProperties": true
      }
    },
    "count": {
      "type": "integer"
    },
    "results": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "preparation_id": {
            "type": "string"
          },
          "wfo_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "scientific_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "evidence_grade": {
            "type": "string"
          },
          "evidence_tier": {
            "type": "string"
          },
          "source_system": {
            "type": "string"
          },
          "relationship": {
            "type": "string"
          },
          "condition_id": {
            "type": "string"
          },
          "warnings_status": {
            "type": "string"
          }
        },
        "additionalProperties": true
      }
    },
    "warnings": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "embedder": {
      "type": "object"
    }
  },
  "additionalProperties": true,
  "required": [
    "disclaimer",
    "sources",
    "results",
    "count"
  ]
}
```

**Error object**

```json
{
  "type": "object",
  "required": [
    "error",
    "is_error"
  ],
  "properties": {
    "error": {
      "type": "string"
    },
    "is_error": {
      "type": "boolean",
      "const": true
    }
  },
  "additionalProperties": true
}
```

## `herbal_preparation_lookup`

Lookup one or more herbal preparations by preparation_id or wfo_id, including therapeutic relations, safety, and (by default) a ranked, paginated plant constituent profile.

**Required arguments:** _(none)_

**Request contract**

```json
{
  "jsonrpc": "2.0",
  "id": "<integer|string>",
  "method": "tools/call",
  "params": {
    "name": "herbal_preparation_lookup",
    "arguments": {
      "preparation_id": "<string, optional>",
      "wfo_id": "<string, optional>",
      "include_constituents": "<boolean, optional, default True>",
      "constituent_limit": "<integer, optional, default 20, minimum 1, maximum 100>",
      "constituent_offset": "<integer, optional, default 0, minimum 0>",
      "primary_only": "<boolean, optional, default False>",
      "min_confidence": "<string, optional, enum high|medium|low>",
      "include_quarantined": "<boolean, optional, default False>",
      "constituent_sources": [
        "<string, optional, enum curated|manual|lotus|cmaup|npass|duke_chem|knapsack>"
      ]
    }
  }
}
```

**Input schema**

```json
{
  "type": "object",
  "properties": {
    "preparation_id": {
      "type": "string",
      "description": "e.g. prep:liquiritiae-radix"
    },
    "wfo_id": {
      "type": "string",
      "description": "WFO taxon id from plant service"
    },
    "include_constituents": {
      "type": "boolean",
      "default": true,
      "description": "Attach plant constituent profile when available"
    },
    "constituent_limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "default": 20,
      "description": "Max compounds to return (default 20). Use herbal_constituent_lookup to page."
    },
    "constituent_offset": {
      "type": "integer",
      "minimum": 0,
      "default": 0,
      "description": "Offset into the ranked compound list"
    },
    "primary_only": {
      "type": "boolean",
      "default": false,
      "description": "Only curated/known marker compounds"
    },
    "min_confidence": {
      "type": "string",
      "enum": [
        "high",
        "medium",
        "low"
      ],
      "description": "Drop dump rows below this confidence"
    },
    "include_quarantined": {
      "type": "boolean",
      "default": false,
      "description": "Include toxic-metal / obviously bad dump rows"
    },
    "constituent_sources": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "curated",
          "manual",
          "lotus",
          "cmaup",
          "npass",
          "duke_chem",
          "knapsack"
        ]
      },
      "description": "Filter constituent sources"
    }
  },
  "additionalProperties": false
}
```

**Output schema** (`structuredContent` on success)

```json
{
  "type": "object",
  "properties": {
    "disclaimer": {
      "type": "string"
    },
    "sources": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "found": {
      "type": "boolean"
    },
    "preparations": {
      "type": "array",
      "items": {
        "type": "object"
      }
    }
  },
  "additionalProperties": true,
  "required": [
    "disclaimer",
    "found",
    "preparations"
  ]
}
```

**Error object**

```json
{
  "type": "object",
  "required": [
    "error",
    "is_error"
  ],
  "properties": {
    "error": {
      "type": "string"
    },
    "is_error": {
      "type": "boolean",
      "const": true
    }
  },
  "additionalProperties": true
}
```

## `herbal_constituent_lookup`

Lookup dump/curated active constituents for a plant by wfo_id (or preparation_id → wfo). Ranked, paginated. Not lab analysis.

**Required arguments:** _(none)_

**Request contract**

```json
{
  "jsonrpc": "2.0",
  "id": "<integer|string>",
  "method": "tools/call",
  "params": {
    "name": "herbal_constituent_lookup",
    "arguments": {
      "wfo_id": "<string, optional>",
      "preparation_id": "<string, optional>",
      "constituent_limit": "<integer, optional, default 20, minimum 1, maximum 100>",
      "constituent_offset": "<integer, optional, default 0, minimum 0>",
      "primary_only": "<boolean, optional, default False>",
      "min_confidence": "<string, optional, enum high|medium|low>",
      "include_quarantined": "<boolean, optional, default False>",
      "sources": [
        "<string, optional, enum curated|manual|lotus|cmaup|npass|duke_chem|knapsack>"
      ]
    }
  }
}
```

**Input schema**

```json
{
  "type": "object",
  "properties": {
    "wfo_id": {
      "type": "string",
      "description": "WFO taxon id"
    },
    "preparation_id": {
      "type": "string",
      "description": "Resolve wfo_id from this preparation if wfo_id omitted"
    },
    "constituent_limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "default": 20,
      "description": "Max compounds to return (default 20). Use herbal_constituent_lookup to page."
    },
    "constituent_offset": {
      "type": "integer",
      "minimum": 0,
      "default": 0,
      "description": "Offset into the ranked compound list"
    },
    "primary_only": {
      "type": "boolean",
      "default": false,
      "description": "Only curated/known marker compounds"
    },
    "min_confidence": {
      "type": "string",
      "enum": [
        "high",
        "medium",
        "low"
      ],
      "description": "Drop dump rows below this confidence"
    },
    "include_quarantined": {
      "type": "boolean",
      "default": false,
      "description": "Include toxic-metal / obviously bad dump rows"
    },
    "sources": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "curated",
          "manual",
          "lotus",
          "cmaup",
          "npass",
          "duke_chem",
          "knapsack"
        ]
      },
      "description": "Filter constituent sources"
    }
  },
  "additionalProperties": false
}
```

**Output schema** (`structuredContent` on success)

```json
{
  "type": "object",
  "properties": {
    "disclaimer": {
      "type": "string"
    },
    "sources": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "constituent_note": {
      "type": "string"
    },
    "found": {
      "type": "boolean"
    },
    "wfo_id": {
      "type": "string"
    },
    "profile": {
      "type": [
        "object",
        "null"
      ]
    }
  },
  "additionalProperties": true,
  "required": [
    "found",
    "wfo_id"
  ]
}
```

**Error object**

```json
{
  "type": "object",
  "required": [
    "error",
    "is_error"
  ],
  "properties": {
    "error": {
      "type": "string"
    },
    "is_error": {
      "type": "boolean",
      "const": true
    }
  },
  "additionalProperties": true
}
```

## `herbal_search_by_constituent` — Search plants by English/INN constituent name

Search plants by English/INN constituent name only (caffeine, citral, rosmarinic acid, salidroside). Not effect text. Not Hungarian (not szorongáscsökkentő). If count=0, retry the INN — do not retry a HU/EN effect phrase. Symptom sentences → herbal_resolve_condition, not this tool.

query: English/INN compound name only — not effect text, not Hungarian.

**Required arguments:** `query`

**Request contract**

```json
{
  "jsonrpc": "2.0",
  "id": "<integer|string>",
  "method": "tools/call",
  "params": {
    "name": "herbal_search_by_constituent",
    "arguments": {
      "query": "<string, required, maxLength 200>",
      "limit": "<integer, optional, default 10, minimum 1, maximum 25>"
    }
  }
}
```

**Input schema**

```json
{
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "description": "English compound/INN name (caffeine, citral). Not a Hungarian paragraph.",
      "maxLength": 200
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 25,
      "default": 10
    }
  },
  "required": [
    "query"
  ],
  "additionalProperties": false
}
```

**Output schema** (`structuredContent` on success)

```json
{
  "type": "object",
  "properties": {
    "disclaimer": {
      "type": "string"
    },
    "sources": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "constituent_note": {
      "type": "string"
    },
    "query": {
      "type": "string"
    },
    "count": {
      "type": "integer"
    },
    "results": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "embedder": {
      "type": "object"
    },
    "search_mode": {
      "type": "string"
    }
  },
  "additionalProperties": true,
  "required": [
    "query",
    "count",
    "results"
  ]
}
```

**Error object**

```json
{
  "type": "object",
  "required": [
    "error",
    "is_error"
  ],
  "properties": {
    "error": {
      "type": "string"
    },
    "is_error": {
      "type": "boolean",
      "const": true
    }
  },
  "additionalProperties": true
}
```

## `herbal_status`

Herbal DB health, import versions, embedding and constituent-run counts (free).

**Required arguments:** _(none)_

**Request contract**

```json
{
  "jsonrpc": "2.0",
  "id": "<integer|string>",
  "method": "tools/call",
  "params": {
    "name": "herbal_status",
    "arguments": {}
  }
}
```

**Input schema**

```json
{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
```

**Output schema** (`structuredContent` on success)

```json
{
  "type": "object",
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "preparations": {
      "type": "integer"
    },
    "error": {
      "type": "string"
    },
    "is_error": {
      "type": "boolean"
    }
  },
  "additionalProperties": true,
  "required": [
    "ok"
  ]
}
```

**Error object**

```json
{
  "type": "object",
  "required": [
    "error",
    "is_error"
  ],
  "properties": {
    "error": {
      "type": "string"
    },
    "is_error": {
      "type": "boolean",
      "const": true
    }
  },
  "additionalProperties": true
}
```
