mcp-drugsea
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-drugseasearch China marketed products for aspirin"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-drugsea
MCP (Model Context Protocol) stdio server for DrugSea / Yaohai pharmaceutical databases.
The server forwards tool calls to https://db.drugsea.cn/api with personal user token auth (Authorization: Bearer ysk_…). It covers:
yaohai-* — cross-database catalog / search / detail / facets / global (
POST /g/mcp/yaohai/*; facets via GET)product-cn-* — already-marketed China products (search/detail via MCP POST; facets via GET)
reg-cn-* — CDE registration / review pipeline (search/detail via MCP POST; facets via GET)
GitHub: github.com/kinginsun/mcp-drugsea
Installation
npm install -g @kinginsun/mcp-drugseaOr run without installing (@latest makes npx re-resolve the newest published version each launch instead of pinning to its cache):
npx -y @kinginsun/mcp-drugsea@latestRelated MCP server: NanoSearchMCP
Updating
How updates reach you depends on how you installed the server.
1. npx with @latest — reload after each publish (recommended)
The MCP configs in this README use:
"args": ["-y", "@kinginsun/mcp-drugsea@latest"]@latest tells npx to resolve the newest published version when a new process starts. It does not upgrade a server that is already running, and it does not always invalidate an existing npx cache directory.
After a release: reload / reconnect the MCP connector in the client. If the client still reports the old version:
Stop the running MCP process.
Clear the npx cache (below) and launch once so npx re-fetches.
Reload the connector again.
If your config uses the bare package name ("-y", "@kinginsun/mcp-drugsea"), npx keys its cache by that exact argument and is even more likely to keep a stale tarball. Add @latest.
2. Global install — manual
npm install -g pins the version you installed; nothing updates it automatically.
npm update -g @kinginsun/mcp-drugsea
npm ls -g @kinginsun/mcp-drugsea # confirm the new version3. Stuck on an old version? Clear the npx cache
npm cache clean --force does not touch the npx cache — that is the usual reason an update appears not to take effect. npm 11+ has dedicated subcommands:
npm cache npx ls # list cached npx entries
npm cache npx rm <key> # remove the stale entry for this packagenpm 10 (still common on macOS) has no npm cache npx command. List and delete the cache directories yourself:
ls ~/.npm/_npx # each hash dir is one npx install
rm -rf ~/.npm/_npx # nuclear: next npx -y @…@latest re-fetchesOn Windows the same tree is %LOCALAPPDATA%\npm-cache\_npx.
macOS has no GNU timeout(1). To cap a warmup npx run, use
perl -e 'alarm 60; exec @ARGV' npx -y @kinginsun/mcp-drugsea@latest --help
(or gtimeout from coreutils). After a successful fetch, reload the MCP connector — the old Node process keeps serving until it is restarted.
In-server update notice
Every launch performs a non-blocking version check against the registry and, when a newer version is published, reports it on two channels:
stderr — shown in your MCP client's server log panel;
an MCP
notifications/messagelog notification (level: warning).
The notice includes the exact commands above. It never blocks startup, never writes to stdout (which carries JSON-RPC), and fails silently when the registry is unreachable — results are cached for 24h so repeated launches do not re-query.
Disable it with YAOHAI_MCP_UPDATE_CHECK=0. Behind a proxy or using an npm mirror, set YAOHAI_NPM_REGISTRY to your registry origin.
Pinning a version
Prefer stability over freshness? Pin an exact version or a range instead of @latest:
"args": ["-y", "@kinginsun/mcp-drugsea@0.4.0"]A range such as @^0.4.0 auto-updates within 0.4.x only, which avoids picking up breaking changes from a future minor release.
Configuration
YAOHAI_MCP_TOKEN (required)
Authentication uses personal user tokens only (ysk_ + 32 hex chars). The legacy shared X-Yaohai-Api-Key header is not supported.
Credential | Format | HTTP header |
Personal user token |
|
|
Obtain a token from DrugSea / Yaohai (user account settings), then:
export YAOHAI_MCP_TOKEN=ysk_your_token_hereHow to get a token from DrugSea (Yaohai)
Open https://db.drugsea.cn in a browser.
Log in with WeChat QR scan (微信扫码登录).
Enter the personal center (个人中心).
In the left sidebar, click API Token.
Click generate token (生成 Token) and copy the result — it looks like
ysk_+ 32 hex characters.
Notes:
Each account can generate up to 10 tokens.
A token inherits the same database permissions as its Yaohai account — if your account cannot see a database, the token cannot either. If a tool call returns a permission error, check your account's subscription/permissions on db.drugsea.cn, not the MCP client.
Store the token in your MCP client's
env(see below) or export it asYAOHAI_MCP_TOKEN. Never commit it to a repository.
Direct GET list routes may return encrypted payloads; this client defaults to routing product-cn-search / reg-cn-search / detail through MCP POST (YAOHAI_USE_MCP_LIST=true). Set YAOHAI_USE_MCP_LIST=0 to use GET. Prefer https://db.drugsea.cn/api over db3.drugsea.cn — the latter's gateway times out around 50s (504 HTML) on slower MCP exports.
Optional
Variable | Default | Description |
|
| API origin (no trailing slash). MCP: |
|
| Set |
|
| Force product/reg search via MCP POST instead of GET. Set |
| enabled | Set |
|
| Registry used by the version check. Point at a mirror if npmjs.org is unreachable from your network |
Cursor MCP (~/.cursor/mcp.json)
{
"mcpServers": {
"drugsea": {
"command": "npx",
"args": ["-y", "@kinginsun/mcp-drugsea@latest"],
"env": {
"YAOHAI_MCP_TOKEN": "ysk_your_token_here",
"YAOHAI_BASE_URL": "https://db.drugsea.cn/api",
"YAOHAI_USE_MCP_LIST": "true"
}
}
}
}Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"drugsea": {
"command": "npx",
"args": ["-y", "@kinginsun/mcp-drugsea@latest"],
"env": {
"YAOHAI_MCP_TOKEN": "ysk_your_token_here",
"YAOHAI_BASE_URL": "https://db.drugsea.cn/api",
"YAOHAI_USE_MCP_LIST": "true"
}
}
}
}Which tools to use
User intent | Tools |
Already listed in China (国药准字, 批准文号, 上市, 医保/集采状态) |
|
R&D / CDE (在研, 受理号, 审评, 尚未上市) |
|
Other DBs (医保 |
|
Global / 全库 hit counts |
|
Unclear which DB |
|
Therapeutic-class queries (抗癌, 心血管, …): prefer ConditionSearch ATC_code (letter, e.g. L oncology, C cardiovascular, J anti-infectives, N nervous system). Confirm values with a facets tool when unsure.
If total > 20, summarize in chat (about 5–10 sample rows) instead of pasting the full table.
Excel export (action=output): product-cn-search, reg-cn-search, and yaohai-search can export the current query as .xlsx. Search first and read total. If total is 1–999, call the same tool again with action: "output". The server counts again, generates xlsx via the list API, uploads it to OSS, and returns download_url (plus oss_url) — never a binary file. If total is 0 or ≥ 1000, narrow the query instead of exporting. Give the user the OSS link. yaohai-global-search does not support Excel.
product-cn-* and reg-cn-* list/facet/detail calls use the same routes as the website where applicable. Some deployments IP-allowlist direct GET paths. The yaohai-* tools use POST /g/mcp/yaohai/* with Bearer token auth.
Tools
Yaohai (cross-DB)
Tool | Parameters | Notes |
|
| List databases |
|
| Default limit 10, max 50; ≤ 1000 rows per query condition (offset+limit window cap). |
|
| Skip DBs with |
|
| Facets for 56 databases (44 |
|
|
|
When the target database is unclear, use yaohai-catalog (filter by category / q) to pick a dbname, then yaohai-search; or use yaohai-global-search with a term to see which databases have hits, then query those DBs.
Retrieval cap (anti-scraping, enforced client + server): one distinct query condition can return at most 1000 rows (
offset + limit ≤ 1000). A largeroffsetis rejected;limitis auto-shrunk near the edge of the window. To reach deeper slices, narrow the filters (date / province / ATC / enterprise) and query again — each new condition gets its own 1000-row window. Excel export (action=output) uses the same ceiling:totalmust be 1–999.
yaohai-facets mirrors the ConditionSearch facet filters of the website (医保 yibao, 招标 zhaobiao, 临床 ct_cn, 美国上市 product_us, …). Two modes:
Discovery (no
fields): omitdbnameto list all facet-capable databases, or passdbnameto list its facet-able fields (withfilter_type).Fetch (
dbname+fields): returns aggregation buckets (value/count) for the named terms fields, optionally narrowed byquery. Covers/indbs plus dedicated-route pages whose SPAConditionSearchPanelhas a liveGET …/{field}(zhaobiao, ct_cn, product_us, …).sales_cn/sales_globalreturn hardcoded SPA lists (countis null). Date/range/tree pickers are not faceted here.product_cn/reg_cnstill use their dedicated tools.
For the two dedicated ES routes use product-cn-facets / reg-cn-facets instead — yaohai-facets returns an actionable hint if you pass product_cn / reg_cn.
product_cn (marketed)
Tool | Parameters | Notes |
| (none) | Local field catalog |
|
| Default |
|
| Do not request all 22 dimensions. Recommended: |
|
| Encrypted id from search rows |
first_approve_date is first listing date; approve_date is latest re-registration (not first listing).
view_type: eslist (default) / list_by_drug_name / list_by_manufacture.
reg_cn (CDE review)
Tool | Parameters | Notes |
| (none) | Local field catalog |
|
| Default |
|
| Recommended: |
|
| Encrypted id from search rows |
view_type: eslist (default) / list_by_drug_name / list_by_enterprise.
query values may be string, number, or string arrays (ConditionSearch multiple). Dates: "YYYY-MM-DD to YYYY-MM-DD". Ranges: "min to max".
Quick start for AI Agents (install, configure, test)
Agents: prefer
AGENT_SETUP.md. It is the full install playbook and additionally covers installing every companion skill underskills/(drugsea,echarts,drug-project-initiation).drugseateaches correct tool routing, field keys, facets, and query gotchas across the 61 MCP-visible databases;echartscovers charts;drug-project-initiationproduces 立项调研 HTML reports. The section below installs the server only.
This section is a step-by-step playbook an AI agent (or a human) can follow to install, configure, and verify this MCP server end to end.
Prerequisites
Node.js >= 18 (
node -v)npm (
npm -v)A DrugSea / Yaohai personal token (
ysk_+ 32 hex chars) — see How to get a token from DrugSea (Yaohai)
Step 0 — Register the server with your MCP client
Add the server to your client config so it auto-starts. Example for Cursor (~/.cursor/mcp.json) — see Configuration for other clients:
{
"mcpServers": {
"drugsea": {
"command": "npx",
"args": ["-y", "@kinginsun/mcp-drugsea@latest"],
"env": {
"YAOHAI_MCP_TOKEN": "ysk_your_token_here"
}
}
}
}Then reload MCP servers in the client (Cursor: Settings → MCP → refresh). The client should list 13 tools.
Step 1 — Install (optional, for local/CLI use)
Either run via npx on demand (no install needed), or install globally / from source:
# Option A: run without installing (what the MCP configs above do)
npx -y @kinginsun/mcp-drugsea@latest
# Option B: global install
npm install -g @kinginsun/mcp-drugsea
npm ls -g @kinginsun/mcp-drugsea
# Option C: from source (when developing)
git clone https://github.com/kinginsun/mcp-drugsea.git
cd mcp-drugsea
npm install
npm run buildStep 2 — Configure the token
export YAOHAI_MCP_TOKEN=ysk_your_token_hereFor MCP client usage, put the token in the client config env instead (Step 0). Sanity-check the format:
node -e "console.log(/^ysk_[0-9a-f]{32}$/i.test(process.env.YAOHAI_MCP_TOKEN) ? 'token format OK' : 'token format BAD')"Step 3 — Smoke test over stdio (JSON-RPC)
The server speaks MCP over stdio. The recommended handshake sequence is initialize → notifications/initialized → request. Run this outside the package source directory (or use node dist/index.js inside it):
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"1.0"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
| YAOHAI_MCP_TOKEN=$YAOHAI_MCP_TOKEN npx -y @kinginsun/mcp-drugsea@latest \
| node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>{for(const l of d.split('\n')){if(!l.trim())continue;let m;try{m=JSON.parse(l)}catch{continue}if(m.id===2)console.log('tools:',m.result.tools.length)}})"Expected: tools: 13.
The filter selects the response with "id":2 rather than piping through tail -1, because the server may also emit a notifications/message (version-update notice) on stdout. Both are valid JSON-RPC, but only one is the answer you asked for.
One-liner variant without the handshake (also works with this server):
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' \
| YAOHAI_MCP_TOKEN=ysk_your_token_here npx -y @kinginsun/mcp-drugsea@latestStep 4 — Test real tool calls
# Catalog lookup (no external DB data needed)
echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"yaohai-catalog","arguments":{"q":"医保"}}}' \
| YAOHAI_MCP_TOKEN=ysk_your_token_here npx -y @kinginsun/mcp-drugsea@latest
# China marketed products search
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"product-cn-search","arguments":{"query":{"drug_name":"阿司匹林"},"limit":3}}}' \
| YAOHAI_MCP_TOKEN=ysk_your_token_here npx -y @kinginsun/mcp-drugsea@latest
# Cross-database hit counts (homepage /search)
echo '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"yaohai-global-search","arguments":{"q":"达格列净"}}}' \
| YAOHAI_MCP_TOKEN=ysk_your_token_here npx -y @kinginsun/mcp-drugsea@latestExpected: each response has "isError":false and non-empty content.
Step 5 — Full 13-tool suite (from source)
git clone https://github.com/kinginsun/mcp-drugsea.git
cd mcp-drugsea
npm install && npm run build
YAOHAI_MCP_TOKEN=ysk_your_token_here node scripts/test-all-tools.mjsExpected final line: --- Summary: 14 passed, 0 failed / 14 tool calls ---.
Step 6 — Verify inside the MCP client
After reloading MCP servers in the client, ask the agent:
"List the drugsea tools" → should see 13 tools.
"Search 阿司匹林 in product-cn" → should return rows with
total > 0."Global search: 达格列净" → should return per-database hit counts (
hits[]), not molecule rows.
Troubleshooting
Symptom | Cause / fix |
| Token env var missing/empty — set it (Step 2 / client |
| Token not |
| Token expired or revoked — regenerate at db.drugsea.cn (personal center → API Token). The backend returns that |
Permission/forbidden on a specific DB | Token inherits account permissions — check the account's subscription on db.drugsea.cn |
| You are inside the package source dir — run from another directory or use |
Empty/encrypted payload from product/reg GET | Keep default |
Search tools fail with |
|
TLS errors on some hosts | Set |
Client keeps running an old version | npx cache + a still-running MCP process. Use |
Global install never updates |
|
No update notice appears | Expected when you are already current, when the registry is unreachable (check fails silently), or when |
Manual stdio test
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' \
| YAOHAI_MCP_TOKEN=ysk_your_token_here node dist/index.jsecho '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"yaohai-catalog","arguments":{"q":"医保"}}}' \
| YAOHAI_MCP_TOKEN=ysk_your_token_here node dist/index.jsecho '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"product-cn-search","arguments":{"query":{"drug_name":"阿司匹林"},"limit":3}}}' \
| YAOHAI_MCP_TOKEN=ysk_your_token_here node dist/index.jsReleasing (maintainers)
publish.sh releases the package to npm (which is what makes npx -y @kinginsun/mcp-drugsea@latest work). It syncs src/environment.ts's PACKAGE_VERSION with package.json, builds clean, audits the tarball for leaked tokens, runs the 13-tool suite plus the facet and update-check suites, commits + tags, then publishes and pushes.
npm login # once, with rights on the @kinginsun scope
./publish.sh --dry-run # full rehearsal, no side effects
./publish.sh --minor # real release (0.2.1 → 0.3.0)
./publish.sh --help # all flags (--major, --version, --otp, --skip-tests, --note, --no-push)The suite needs a live token: publish.sh probes the API first and, on rejection, reports it as a credential problem rather than a code regression. If you rotated YAOHAI_MCP_TOKEN, run unset YAOHAI_MCP_TOKEN first so the new .env value isn't shadowed by a stale exported one.
Requirements
Node.js >= 18.0.0
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
DrugBank MCP — wraps the DrugBank Clinical API (api.drugbank.com)
ClinicalTrials MCP — wraps ClinicalTrials.gov API v2 (free, no auth)
Pharma Intel MCP — Compound tools that chain ClinicalTrials.gov,
OpenFDA MCP — wraps the openFDA API (free, no auth required)
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables querying openFDA drug and device data via natural language through the Pipeworx MCP gateway.1 npmMIT
- FlicenseNot gradedqualityDmaintenanceProvides web search, page fetching, and A-stock data access (financial reports, announcements, research reports, penalties, IR meetings) via MCP tools.-
- AlicenseAqualityCmaintenanceEnables LLM agents to query Korean drug, DUR safety rules, and health supplement databases via MCP protocol.4MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for clinical and pharmaceutical data, enabling search of ClinicalTrials.gov, PubMed, FDA, and ICH guidelines without API keys.23 npmMIT