meddata-mcp 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- meddata_mcp-0.1.0/.gitignore +41 -0
- meddata_mcp-0.1.0/LICENSE +21 -0
- meddata_mcp-0.1.0/PKG-INFO +123 -0
- meddata_mcp-0.1.0/README.md +102 -0
- meddata_mcp-0.1.0/meddata_mcp/__init__.py +3 -0
- meddata_mcp-0.1.0/meddata_mcp/server.py +187 -0
- meddata_mcp-0.1.0/pyproject.toml +46 -0
- meddata_mcp-0.1.0/server.json +29 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
*.egg-info/
|
|
7
|
+
*.egg
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
eggs/
|
|
11
|
+
*.whl
|
|
12
|
+
|
|
13
|
+
# Virtual environments
|
|
14
|
+
.venv/
|
|
15
|
+
venv/
|
|
16
|
+
env/
|
|
17
|
+
ENV/
|
|
18
|
+
|
|
19
|
+
# Environment variables
|
|
20
|
+
.env
|
|
21
|
+
|
|
22
|
+
# IDE
|
|
23
|
+
.vscode/
|
|
24
|
+
.idea/
|
|
25
|
+
*.swp
|
|
26
|
+
*.swo
|
|
27
|
+
*~
|
|
28
|
+
|
|
29
|
+
# OS
|
|
30
|
+
.DS_Store
|
|
31
|
+
Thumbs.db
|
|
32
|
+
|
|
33
|
+
# Testing
|
|
34
|
+
.pytest_cache/
|
|
35
|
+
.coverage
|
|
36
|
+
htmlcov/
|
|
37
|
+
.mypy_cache/
|
|
38
|
+
|
|
39
|
+
# Distribution
|
|
40
|
+
*.tar.gz
|
|
41
|
+
*.zip
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Anthesia
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: meddata-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server for the MedData API: drug and supplement lookup and interaction checks from free U.S. government health databases.
|
|
5
|
+
Project-URL: Homepage, https://meddata.anthesia.io
|
|
6
|
+
Project-URL: Documentation, https://meddata.anthesia.io/docs
|
|
7
|
+
Project-URL: Repository, https://github.com/anthesiallc/meddata-api
|
|
8
|
+
Author-email: Anthesia <support@anthesia.io>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: drug,fda,healthcare,interactions,mcp,model-context-protocol,openfda,pharmacy,rxnorm,supplement
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Requires-Dist: httpx>=0.27.0
|
|
19
|
+
Requires-Dist: mcp>=1.2.0
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# MedData MCP Server
|
|
23
|
+
|
|
24
|
+
mcp-name: io.github.anthesiallc/meddata
|
|
25
|
+
|
|
26
|
+
A [Model Context Protocol](https://modelcontextprotocol.io) server that exposes the
|
|
27
|
+
[MedData API](https://meddata.anthesia.io) as tools, so any MCP client (Claude
|
|
28
|
+
Desktop, Cursor, ChatGPT connectors, or an agent framework) can look up drug and
|
|
29
|
+
supplement data and check interactions conversationally.
|
|
30
|
+
|
|
31
|
+
It's a thin wrapper: each tool maps to one MedData REST endpoint. All the data
|
|
32
|
+
work happens in the API.
|
|
33
|
+
|
|
34
|
+
## Tools
|
|
35
|
+
|
|
36
|
+
| Tool | What it does |
|
|
37
|
+
|------|--------------|
|
|
38
|
+
| `search_drugs` | Search drugs by brand or generic name; returns RxCUI + details |
|
|
39
|
+
| `get_drug` | Full drug profile by RxCUI |
|
|
40
|
+
| `get_drug_by_ndc` | Drug profile by NDC package code |
|
|
41
|
+
| `search_supplements` | Search supplements by name; returns supplement IDs |
|
|
42
|
+
| `get_supplement` | Full supplement fact sheet by ID |
|
|
43
|
+
| `check_interactions` | Interactions across a mixed list of 2-10 drugs/supplements |
|
|
44
|
+
| `get_usage` | Current billing period usage and plan limit |
|
|
45
|
+
|
|
46
|
+
## Get an API key
|
|
47
|
+
|
|
48
|
+
Free tier is 250 calls/month, no credit card:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
curl -X POST https://meddata.anthesia.io/api/v1/signup \
|
|
52
|
+
-H 'Content-Type: application/json' \
|
|
53
|
+
-d '{"email":"you@example.com"}'
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The key comes back in the `api_key` field of the response.
|
|
57
|
+
|
|
58
|
+
## Install and run
|
|
59
|
+
|
|
60
|
+
The easiest way is with [uv](https://docs.astral.sh/uv/) (no manual venv needed):
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# stdio transport (default — for Claude Desktop, Cursor, most local clients)
|
|
64
|
+
MEDDATA_API_KEY=md_your_key uvx meddata-mcp
|
|
65
|
+
|
|
66
|
+
# streamable-HTTP transport (for remote / web clients)
|
|
67
|
+
MEDDATA_API_KEY=md_your_key uvx meddata-mcp --http
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Or install with pip into its own environment:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install meddata-mcp
|
|
74
|
+
MEDDATA_API_KEY=md_your_key meddata-mcp
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
> Note: install into a dedicated environment. The `mcp` SDK requires a newer
|
|
78
|
+
> `starlette` than the MedData API app pins, so the two will conflict if installed
|
|
79
|
+
> together.
|
|
80
|
+
|
|
81
|
+
Environment variables:
|
|
82
|
+
|
|
83
|
+
- `MEDDATA_API_KEY` (required) — your MedData API key.
|
|
84
|
+
- `MEDDATA_BASE_URL` (optional) — defaults to `https://meddata.anthesia.io`.
|
|
85
|
+
- `MEDDATA_TIMEOUT` (optional) — request timeout in seconds, default `30`.
|
|
86
|
+
|
|
87
|
+
## Client configuration
|
|
88
|
+
|
|
89
|
+
### Claude Desktop
|
|
90
|
+
|
|
91
|
+
Add to `claude_desktop_config.json` (Settings → Developer → Edit Config):
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"mcpServers": {
|
|
96
|
+
"meddata": {
|
|
97
|
+
"command": "uvx",
|
|
98
|
+
"args": ["meddata-mcp"],
|
|
99
|
+
"env": { "MEDDATA_API_KEY": "md_your_key" }
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Cursor
|
|
106
|
+
|
|
107
|
+
Add the same block to `~/.cursor/mcp.json` (or the project `.cursor/mcp.json`).
|
|
108
|
+
|
|
109
|
+
## Develop from source
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
cd mcp_server
|
|
113
|
+
python -m venv .venv
|
|
114
|
+
.venv/Scripts/python -m pip install -e . # Windows
|
|
115
|
+
# .venv/bin/pip install -e . # macOS/Linux
|
|
116
|
+
MEDDATA_API_KEY=md_your_key .venv/Scripts/python -m meddata_mcp.server
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Notes
|
|
120
|
+
|
|
121
|
+
- Data is for informational purposes only and is not medical advice.
|
|
122
|
+
- Interaction data comes from established medical databases; an empty result
|
|
123
|
+
means none were found in those sources, not that a combination is proven safe.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# MedData MCP Server
|
|
2
|
+
|
|
3
|
+
mcp-name: io.github.anthesiallc/meddata
|
|
4
|
+
|
|
5
|
+
A [Model Context Protocol](https://modelcontextprotocol.io) server that exposes the
|
|
6
|
+
[MedData API](https://meddata.anthesia.io) as tools, so any MCP client (Claude
|
|
7
|
+
Desktop, Cursor, ChatGPT connectors, or an agent framework) can look up drug and
|
|
8
|
+
supplement data and check interactions conversationally.
|
|
9
|
+
|
|
10
|
+
It's a thin wrapper: each tool maps to one MedData REST endpoint. All the data
|
|
11
|
+
work happens in the API.
|
|
12
|
+
|
|
13
|
+
## Tools
|
|
14
|
+
|
|
15
|
+
| Tool | What it does |
|
|
16
|
+
|------|--------------|
|
|
17
|
+
| `search_drugs` | Search drugs by brand or generic name; returns RxCUI + details |
|
|
18
|
+
| `get_drug` | Full drug profile by RxCUI |
|
|
19
|
+
| `get_drug_by_ndc` | Drug profile by NDC package code |
|
|
20
|
+
| `search_supplements` | Search supplements by name; returns supplement IDs |
|
|
21
|
+
| `get_supplement` | Full supplement fact sheet by ID |
|
|
22
|
+
| `check_interactions` | Interactions across a mixed list of 2-10 drugs/supplements |
|
|
23
|
+
| `get_usage` | Current billing period usage and plan limit |
|
|
24
|
+
|
|
25
|
+
## Get an API key
|
|
26
|
+
|
|
27
|
+
Free tier is 250 calls/month, no credit card:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
curl -X POST https://meddata.anthesia.io/api/v1/signup \
|
|
31
|
+
-H 'Content-Type: application/json' \
|
|
32
|
+
-d '{"email":"you@example.com"}'
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The key comes back in the `api_key` field of the response.
|
|
36
|
+
|
|
37
|
+
## Install and run
|
|
38
|
+
|
|
39
|
+
The easiest way is with [uv](https://docs.astral.sh/uv/) (no manual venv needed):
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# stdio transport (default — for Claude Desktop, Cursor, most local clients)
|
|
43
|
+
MEDDATA_API_KEY=md_your_key uvx meddata-mcp
|
|
44
|
+
|
|
45
|
+
# streamable-HTTP transport (for remote / web clients)
|
|
46
|
+
MEDDATA_API_KEY=md_your_key uvx meddata-mcp --http
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Or install with pip into its own environment:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install meddata-mcp
|
|
53
|
+
MEDDATA_API_KEY=md_your_key meddata-mcp
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
> Note: install into a dedicated environment. The `mcp` SDK requires a newer
|
|
57
|
+
> `starlette` than the MedData API app pins, so the two will conflict if installed
|
|
58
|
+
> together.
|
|
59
|
+
|
|
60
|
+
Environment variables:
|
|
61
|
+
|
|
62
|
+
- `MEDDATA_API_KEY` (required) — your MedData API key.
|
|
63
|
+
- `MEDDATA_BASE_URL` (optional) — defaults to `https://meddata.anthesia.io`.
|
|
64
|
+
- `MEDDATA_TIMEOUT` (optional) — request timeout in seconds, default `30`.
|
|
65
|
+
|
|
66
|
+
## Client configuration
|
|
67
|
+
|
|
68
|
+
### Claude Desktop
|
|
69
|
+
|
|
70
|
+
Add to `claude_desktop_config.json` (Settings → Developer → Edit Config):
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"mcpServers": {
|
|
75
|
+
"meddata": {
|
|
76
|
+
"command": "uvx",
|
|
77
|
+
"args": ["meddata-mcp"],
|
|
78
|
+
"env": { "MEDDATA_API_KEY": "md_your_key" }
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Cursor
|
|
85
|
+
|
|
86
|
+
Add the same block to `~/.cursor/mcp.json` (or the project `.cursor/mcp.json`).
|
|
87
|
+
|
|
88
|
+
## Develop from source
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
cd mcp_server
|
|
92
|
+
python -m venv .venv
|
|
93
|
+
.venv/Scripts/python -m pip install -e . # Windows
|
|
94
|
+
# .venv/bin/pip install -e . # macOS/Linux
|
|
95
|
+
MEDDATA_API_KEY=md_your_key .venv/Scripts/python -m meddata_mcp.server
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Notes
|
|
99
|
+
|
|
100
|
+
- Data is for informational purposes only and is not medical advice.
|
|
101
|
+
- Interaction data comes from established medical databases; an empty result
|
|
102
|
+
means none were found in those sources, not that a combination is proven safe.
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"""MedData MCP server.
|
|
2
|
+
|
|
3
|
+
Exposes the MedData REST API (https://meddata.anthesia.io) as Model Context
|
|
4
|
+
Protocol tools so that agents and MCP-capable clients (Claude Desktop, Cursor,
|
|
5
|
+
ChatGPT connectors, agent frameworks) can look up drug and supplement data and
|
|
6
|
+
check interactions conversationally.
|
|
7
|
+
|
|
8
|
+
This is a thin wrapper: every tool maps to one REST endpoint. The API key is
|
|
9
|
+
read from the MEDDATA_API_KEY environment variable. Get a free key (250
|
|
10
|
+
calls/month, no card) from https://meddata.anthesia.io or by POSTing your email
|
|
11
|
+
to /api/v1/signup -- the key comes back in the response.
|
|
12
|
+
|
|
13
|
+
Run it:
|
|
14
|
+
MEDDATA_API_KEY=md_... meddata-mcp # stdio (default)
|
|
15
|
+
MEDDATA_API_KEY=md_... meddata-mcp --http # streamable-http
|
|
16
|
+
MEDDATA_API_KEY=md_... python -m meddata_mcp.server # equivalent
|
|
17
|
+
|
|
18
|
+
Drug and supplement data is for informational purposes only and is not medical
|
|
19
|
+
advice. Interaction data comes from established medical databases; it is never
|
|
20
|
+
generated or inferred.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
import os
|
|
24
|
+
import sys
|
|
25
|
+
from typing import Any
|
|
26
|
+
|
|
27
|
+
import httpx
|
|
28
|
+
from mcp.server.fastmcp import FastMCP
|
|
29
|
+
|
|
30
|
+
BASE_URL = os.environ.get("MEDDATA_BASE_URL", "https://meddata.anthesia.io").rstrip("/")
|
|
31
|
+
API_KEY = os.environ.get("MEDDATA_API_KEY", "")
|
|
32
|
+
TIMEOUT = float(os.environ.get("MEDDATA_TIMEOUT", "30"))
|
|
33
|
+
|
|
34
|
+
mcp = FastMCP(
|
|
35
|
+
"meddata",
|
|
36
|
+
instructions=(
|
|
37
|
+
"Tools for looking up drug and supplement information and checking "
|
|
38
|
+
"interactions, backed by free U.S. government health databases (openFDA, "
|
|
39
|
+
"RxNorm, DailyMed, FDA Orange Book, NADAC, NIH ODS). Use search_drugs / "
|
|
40
|
+
"search_supplements to find an item, then get_drug / get_supplement for "
|
|
41
|
+
"the full profile, and check_interactions to screen a list of drugs and "
|
|
42
|
+
"supplements together. Results are informational only, not medical advice."
|
|
43
|
+
),
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
async def _get(path: str, params: dict[str, Any] | None = None) -> dict[str, Any]:
|
|
48
|
+
"""Call a MedData GET endpoint and return parsed JSON (or an error dict)."""
|
|
49
|
+
if not API_KEY:
|
|
50
|
+
return {
|
|
51
|
+
"error": "missing_api_key",
|
|
52
|
+
"detail": (
|
|
53
|
+
"Set the MEDDATA_API_KEY environment variable. Get a free key at "
|
|
54
|
+
"https://meddata.anthesia.io (no credit card)."
|
|
55
|
+
),
|
|
56
|
+
}
|
|
57
|
+
headers = {"X-API-Key": API_KEY, "Accept": "application/json"}
|
|
58
|
+
try:
|
|
59
|
+
async with httpx.AsyncClient(timeout=TIMEOUT) as client:
|
|
60
|
+
resp = await client.get(f"{BASE_URL}{path}", params=params, headers=headers)
|
|
61
|
+
except httpx.RequestError as exc:
|
|
62
|
+
return {"error": "network_error", "detail": str(exc)}
|
|
63
|
+
|
|
64
|
+
if resp.status_code >= 400:
|
|
65
|
+
# The API returns a structured ErrorResponse; pass its detail through.
|
|
66
|
+
try:
|
|
67
|
+
body = resp.json()
|
|
68
|
+
except ValueError:
|
|
69
|
+
body = {"detail": resp.text[:500]}
|
|
70
|
+
return {
|
|
71
|
+
"error": f"http_{resp.status_code}",
|
|
72
|
+
"detail": body.get("detail") or body.get("error") or "Request failed.",
|
|
73
|
+
"status_code": resp.status_code,
|
|
74
|
+
}
|
|
75
|
+
try:
|
|
76
|
+
return resp.json()
|
|
77
|
+
except ValueError:
|
|
78
|
+
return {"error": "bad_response", "detail": "API returned non-JSON content."}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _join(items: list[str]) -> str:
|
|
82
|
+
"""Join a list of names into the comma-separated form the API expects."""
|
|
83
|
+
return ",".join(i.strip() for i in items if i and i.strip())
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@mcp.tool()
|
|
87
|
+
async def search_drugs(name: str, limit: int = 10) -> dict[str, Any]:
|
|
88
|
+
"""Search for drugs by brand or generic name.
|
|
89
|
+
|
|
90
|
+
Returns matching drugs with their RxCUI (the identifier you pass to
|
|
91
|
+
get_drug), generic and brand names, and dosage form/strength when known.
|
|
92
|
+
Use this first when you have a drug name but need its details or RxCUI.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
name: Brand or generic drug name, e.g. "aspirin" or "Lipitor".
|
|
96
|
+
limit: Max results to return (1-50).
|
|
97
|
+
"""
|
|
98
|
+
return await _get("/api/v1/drugs/search", {"name": name, "limit": limit})
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@mcp.tool()
|
|
102
|
+
async def get_drug(rxcui: str) -> dict[str, Any]:
|
|
103
|
+
"""Get the full profile for a drug by its RxCUI.
|
|
104
|
+
|
|
105
|
+
Returns names, dosage forms, NDC codes, label sections, and related data.
|
|
106
|
+
Get the RxCUI from search_drugs first if you only have a name.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
rxcui: RxNorm Concept Unique Identifier, e.g. "1191" for aspirin.
|
|
110
|
+
"""
|
|
111
|
+
return await _get(f"/api/v1/drugs/{rxcui}")
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
@mcp.tool()
|
|
115
|
+
async def get_drug_by_ndc(ndc_code: str) -> dict[str, Any]:
|
|
116
|
+
"""Get a drug profile by its NDC (National Drug Code) package code.
|
|
117
|
+
|
|
118
|
+
Use when you have an NDC from a label or packaging rather than a name.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
ndc_code: NDC code, e.g. "0363-0160".
|
|
122
|
+
"""
|
|
123
|
+
return await _get(f"/api/v1/drugs/ndc/{ndc_code}")
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@mcp.tool()
|
|
127
|
+
async def search_supplements(name: str, limit: int = 10) -> dict[str, Any]:
|
|
128
|
+
"""Search for dietary supplements by name.
|
|
129
|
+
|
|
130
|
+
Returns matching supplements with their IDs (pass to get_supplement) and
|
|
131
|
+
summary info. Use first when you have a supplement name like "Vitamin D"
|
|
132
|
+
or "Fish Oil".
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
name: Supplement name, e.g. "Vitamin D" or "magnesium".
|
|
136
|
+
limit: Max results to return (1-50).
|
|
137
|
+
"""
|
|
138
|
+
return await _get("/api/v1/supplements/search", {"name": name, "limit": limit})
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
@mcp.tool()
|
|
142
|
+
async def get_supplement(supplement_id: int) -> dict[str, Any]:
|
|
143
|
+
"""Get the full fact sheet for a supplement by its ID.
|
|
144
|
+
|
|
145
|
+
Returns ingredients, recommended intake, and NIH reference data. Get the ID
|
|
146
|
+
from search_supplements first.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
supplement_id: Numeric supplement ID from search_supplements.
|
|
150
|
+
"""
|
|
151
|
+
return await _get(f"/api/v1/supplements/{supplement_id}")
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
@mcp.tool()
|
|
155
|
+
async def check_interactions(items: list[str]) -> dict[str, Any]:
|
|
156
|
+
"""Check interactions across a mixed list of drugs and supplements.
|
|
157
|
+
|
|
158
|
+
Accepts 2-10 items (drug names, supplement names, or both) and returns known
|
|
159
|
+
interactions among them. Interaction data comes from established medical
|
|
160
|
+
databases; it is never generated or inferred, so an empty result means none
|
|
161
|
+
were found in those sources, not that the combination is proven safe.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
items: 2-10 drug and/or supplement names,
|
|
165
|
+
e.g. ["warfarin", "aspirin", "Fish Oil"].
|
|
166
|
+
"""
|
|
167
|
+
if len(items) < 2:
|
|
168
|
+
return {"error": "too_few_items", "detail": "Provide at least 2 items to compare."}
|
|
169
|
+
if len(items) > 10:
|
|
170
|
+
return {"error": "too_many_items", "detail": "Provide at most 10 items."}
|
|
171
|
+
return await _get("/api/v1/interactions/check", {"items": _join(items)})
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
@mcp.tool()
|
|
175
|
+
async def get_usage() -> dict[str, Any]:
|
|
176
|
+
"""Show this API key's current billing period usage and plan limits."""
|
|
177
|
+
return await _get("/api/v1/billing/usage")
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def main() -> None:
|
|
181
|
+
"""Run the MCP server. Use --http for streamable-HTTP, otherwise stdio."""
|
|
182
|
+
transport = "streamable-http" if "--http" in sys.argv else "stdio"
|
|
183
|
+
mcp.run(transport=transport)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
if __name__ == "__main__":
|
|
187
|
+
main()
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "meddata-mcp"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "MCP server for the MedData API: drug and supplement lookup and interaction checks from free U.S. government health databases."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Anthesia", email = "support@anthesia.io" }]
|
|
13
|
+
keywords = [
|
|
14
|
+
"mcp",
|
|
15
|
+
"model-context-protocol",
|
|
16
|
+
"drug",
|
|
17
|
+
"supplement",
|
|
18
|
+
"interactions",
|
|
19
|
+
"fda",
|
|
20
|
+
"openfda",
|
|
21
|
+
"rxnorm",
|
|
22
|
+
"healthcare",
|
|
23
|
+
"pharmacy",
|
|
24
|
+
]
|
|
25
|
+
classifiers = [
|
|
26
|
+
"Programming Language :: Python :: 3",
|
|
27
|
+
"License :: OSI Approved :: MIT License",
|
|
28
|
+
"Operating System :: OS Independent",
|
|
29
|
+
"Intended Audience :: Developers",
|
|
30
|
+
"Topic :: Scientific/Engineering :: Medical Science Apps.",
|
|
31
|
+
]
|
|
32
|
+
dependencies = [
|
|
33
|
+
"mcp>=1.2.0",
|
|
34
|
+
"httpx>=0.27.0",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[project.urls]
|
|
38
|
+
Homepage = "https://meddata.anthesia.io"
|
|
39
|
+
Documentation = "https://meddata.anthesia.io/docs"
|
|
40
|
+
Repository = "https://github.com/anthesiallc/meddata-api"
|
|
41
|
+
|
|
42
|
+
[project.scripts]
|
|
43
|
+
meddata-mcp = "meddata_mcp.server:main"
|
|
44
|
+
|
|
45
|
+
[tool.hatch.build.targets.wheel]
|
|
46
|
+
packages = ["meddata_mcp"]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.json",
|
|
3
|
+
"name": "io.github.anthesiallc/meddata",
|
|
4
|
+
"description": "Look up U.S. drug and supplement data and check interactions, from free government health databases (openFDA, RxNorm, NIH ODS).",
|
|
5
|
+
"status": "active",
|
|
6
|
+
"version": "0.1.0",
|
|
7
|
+
"repository": {
|
|
8
|
+
"url": "https://github.com/anthesiallc/meddata-api",
|
|
9
|
+
"source": "github"
|
|
10
|
+
},
|
|
11
|
+
"packages": [
|
|
12
|
+
{
|
|
13
|
+
"registryType": "pypi",
|
|
14
|
+
"identifier": "meddata-mcp",
|
|
15
|
+
"version": "0.1.0",
|
|
16
|
+
"transport": {
|
|
17
|
+
"type": "stdio"
|
|
18
|
+
},
|
|
19
|
+
"environmentVariables": [
|
|
20
|
+
{
|
|
21
|
+
"name": "MEDDATA_API_KEY",
|
|
22
|
+
"description": "MedData API key. Get a free one (250 calls/month, no card) at https://meddata.anthesia.io",
|
|
23
|
+
"isRequired": true,
|
|
24
|
+
"isSecret": true
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|