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)
Pharma Intel MCP — Compound tools that chain ClinicalTrials.gov,
Governed data discovery, exact queries, decisions, simulations, and runtime utilities over MCP.
Link compounds to protein targets, rank bioactivity, and look up drug mechanisms and indications.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables querying openFDA drug and device data via natural language through the Pipeworx MCP gateway.385 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.33 npmMIT