关于 chembl-mcp-server
chembl-mcp-server 为药物发现研究者提供 ChEMBL 化合物、靶点、生物活性和药物信息。它关联化合物与蛋白靶点、按测得效力排序,并支持对暂存的生物活性数据执行只读 SQL 分析。
主要功能
- 01按名称、ID 或结构搜索化合物
- 02解析蛋白质和基因靶点
- 03筛选并排序生物活性测量值
- 04查询药物机制与适应症
- 05用只读 SQL 查询暂存数据
适用场景
- 01通过 SMILES 结构查找化合物
- 02比较化合物—靶点组合的效力
- 03查看药物机制和适应症
- 04汇总暂存的生物活性数据行
MCP 相关
向 MCP 客户端提供 ChEMBL 搜索与分析工具,以及化合物和靶点资源。支持 STDIO 与 Streamable HTTP。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://chembl.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-chembl https://chembl.caseyjhand.com/mcp{"mcpServers":{"cyanheads-chembl":{"type":"http","url":"https://chembl.caseyjhand.com/mcp"}}}在 Cursor 中打开{"servers":{"cyanheads-chembl":{"type":"http","url":"https://chembl.caseyjhand.com/mcp"}}}在 VS Code 中打开{"mcpServers":{"cyanheads-chembl":{"type":"http","url":"https://chembl.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-chembl":{"serverUrl":"https://chembl.caseyjhand.com/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
7| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| limit | integer | 否 | 可返回的分子数量上限。省略时默认为服务器默认值(25)。 |
| query | string | 否 | 用于 search_type=name 的搜索文本——药物名称、ChEMBL ID 或 InChIKey,例如 "imatinib" 或 "CHEMBL25"。 |
| cursor | string | 否 | 来自先前调用的 nextCursor 的不透明续传令牌,可从该页结束处继续。首次请求时省略。重新发送生成该令牌时使用的相同查询/结构/筛选条件(仅可更改 limit;它决定本页大小);若将令牌用于不同筛选条件,将遍历不同的结果集。 |
| structure | string | 否 | 用于结构搜索的 SMILES 字符串,例如 "CC(=O)Oc1ccccc1C(=O)O"。search_type 为 exact/similarity/substructure 时必填。 |
| search_type | enum | 否 | name = 文本查找(query);exact = 精确结构匹配;similarity = Tanimoto ≥ 阈值;substructure = 包含该结构。所有结构模式都需要 `structure`。name | exact | similarity | substructure |
| max_phase_min | integer | 否 | 对于 search_type=name,仅返回最高临床阶段达到或超过此值的化合物(例如,设为 4 仅返回已上市药物)。 |
| similarity_threshold | integer | 否 | search_type=similarity 时的最低 Tanimoto 相似度百分比(40–100;ChEMBL 不接受低于 40 的值)。其他模式下忽略。 |
详细介绍
@cyanheads/chembl-mcp-server
通过 MCP 将化合物关联到蛋白质靶标、按生物活性(IC50/Ki/EC50)排序,并查询 ChEMBL 中的药物作用机制和适应症。支持 STDIO 或 Streamable HTTP。
概述
ChEMBL(EBI)的药物发现数据:汇集化合物、蛋白质靶标和实测生物活性(IC50/Ki/EC50)之间经过整理的关联信息,以及药物作用机制和适应症。可按名称、ID 或结构搜索化合物,解析靶标,并按效力对测量结果排序。
工具
| 工具 | 描述 |
|---|---|
chembl_search_molecules | 按名称 / ChEMBL ID / InChIKey 查找化合物,或根据 SMILES 执行结构搜索(精确 | 相似性 | 子结构)。 |
chembl_get_bioactivities | 核心的化合物↔靶点桥梁:获取某个分子(或其整个形式家族)、某个靶点,或两者(化合物×靶点配对)的生物活性测量值,按 pchembl_value 排序;也可通过 potency_view 获取不含该值的测量结果。大型数据集会溢出到画布。 |
chembl_search_targets | 将蛋白质 / 基因符号 / UniProt 登录号解析为 chembl_get_bioactivities 所需的 ChEMBL 靶点 ID。 |
chembl_get_drug_info | 药物药理学信息——作用机制、分子靶点、作用类型、首次获批年份和临床适应症,涵盖该药物的盐及其他替代形式。 |
chembl_get_assay | 生物活性行的测定来源信息——类型、靶点、生物体,以及 ChEMBL 的 1–9 置信度评分。 |
chembl_dataframe_query | 在画布上暂存的生物活性行上运行只读 SQL SELECT——对完整数据集进行排序、分组、去重和聚合。 |
chembl_dataframe_describe | 列出画布上暂存的表和列,便于在查询前编写正确的 SQL。 |
chembl_dataframe_drop | 从画布中删除指定的暂存表。通过 CHEMBL_DATAFRAME_DROP_ENABLED=true 启用——关闭时不会出现在 tools/list 中,因为 TTL 已会回收暂存表。 |
资源
| 资源 | 描述 |
|---|---|
chembl://molecule/{chemblId} | 按 ChEMBL ID 获取分子记录——结构与 chembl_search_molecules 行中的相同。 |
chembl://target/{chemblId} | 按 ChEMBL 靶点 ID 获取靶点记录——首选名称、类型、生物体,以及组分的 UniProt 登录号和基因符号。 |
所有资源数据也都可通过工具获取,因此仅支持工具的 MCP 客户端不会缺少任何内容。没有提示词——标准工作流是由 Agent 直接组合的简短工具链,跨服务链路指导则通过服务级 instructions 提供。
能力参考
chembl_search_molecules 工具
- 默认的
search_type=name会在一次查询中匹配药物名称、同义词、ChEMBL ID 和 InChIKey;如果查询内容恰好是 ChEMBL ID 或 InChIKey,则会转到 ChEMBL 的单条记录查询,而非模糊文本索引(totalCount: 1) - 可通过
search_type进行结构搜索:exact、similarity(Tanimoto ≥similarity_threshold,整数 40–100,默认值为 70)或substructure——将 SMILES 作为structure提供;max_phase_min(仅限名称搜索)可将结果限制为最高临床阶段达到或超过指定阶段的化合物。对于 ChEMBL 无法解析的 SMILES,相似性或子结构搜索会在首次请求时返回invalid_structure,而非服务中断 - 每一行都包含
max_phase、MW、AlogP、Lipinski 五规则违规数和 QED;只有search_type=similarity的结果包含 Tanimotosimilarity百分比——其他模式中该字段会省略,而非设为 null - 每一行还包含其所属家族的父级
parent_chembl_id:ERLOTINIB HYDROCHLORIDE(CHEMBL1079742)会指向CHEMBL553;没有记录层级关系的化合物则指向自身。盐类的排名可能高于其父级,但只占该家族测量值的一小部分 - 通过
nextCursor/cursor分页;最后一页会省略该字段(而非设为 null)——使用生成游标时相同的筛选条件来兑换游标;limit超过 100 时会按 100 返回,并附带提示 - ChEMBL 的名称搜索在匹配数达到 10,000 时停止计数和分页,子结构搜索则在达到 30,000 时停止;达到上限时,结果会返回
totalCountCapped: true,并提示至少有这么多匹配项,其余结果无法获取——缩小查询范围以低于上限 - 将
molecule_chembl_id链接到chembl_get_bioactivities或chembl_get_drug_info
chembl_get_bioactivities 工具
- 至少提供
molecule_chembl_id或target_chembl_id之一;同时提供两者时,结果会限定为该化合物–靶标对;两者都不提供会报missing_filter错误 include_alternate_forms: true会将molecule_chembl_id扩展到其所属家族,即 ChEMBL 归档在该家族下的母体、所有盐及其他替代形式(仅伊马替尼CHEMBL941就有 4,878 条测量记录,其所有形式合计 5,802 条);盐的 ID 也会指向同一家族,且每行都会保留其测量所针对的形式。计数、两个视图、游标分页和溢出读取的都是同一家族;使用游标时请重新发送此标记。未提供molecule_chembl_id时,此标记会报alternate_forms_without_molecule错误- ID 会按规范形式匹配:
"chembl941"和" CHEMBL941 "都会按CHEMBL941读取;非 ChEMBL ID 的值("imatinib")会在发出任何请求前报-32602,应改用搜索工具;对于molecule_chembl_id,如果未启用include_alternate_forms,该值会直接用于筛选 - 可按
standard_type(IC50/Ki/EC50/…)、pchembl_value_min、assay_type、organism和variant筛选;按pchembl_value排序——只有在同一standard_type内才可比较 assay_type可使用代码(B/F/A/T/P/U)或 ChEMBL 对应的名称(binding、ADMET等),且不区分大小写。standard_type必须精确匹配,包括大小写——ChEMBL 会将仅大小写不同的类型视为不同类型(Kd/KD);如果没有匹配项,提示会列出 ChEMBL 在相同筛选条件下记录的大小写变体("ic50"→IC50)variant用于区分野生型和突变型效力:"wild_type"会保留未记录变体的测量结果;其他任何值都会以不区分大小写的方式匹配完整记录的变体("T315I"、"F508del"、按 ChEMBL 顺序排列的"L858R,T790M"、"UNDEFINED MUTATION")——仅"L858R"不会匹配"L858R,T790M"- 每行包含
activity_comment(例如Not Active;未测得数值时,这通常是唯一的结果)和data_validity_comment(例如Outside typical range)、测定的assay_variant_mutation和assay_variant_accession,以及用于引用的来源document_chembl_id和document_year potency_view可选择potency_ranked(默认值,包含可推导出pchembl_value的测量结果)或null_potency(被排除的行);potency_view为null_potency时使用pchembl_value_min会报contradictory_potency_filter错误,而totalCount涵盖两个视图- 在服务边界处,数值会被转换为
number | null——缺失的效力值会显示为null,绝不会是0 - 大型结果集会按视图溢出到 DataCanvas 表格(
bioactivities/bioactivities_null_potency);默认启用画布,可通过CANVAS_PROVIDER_TYPE=none将其关闭 - 溢出时会每次提取
CHEMBL_MAX_CONCURRENT_PAGES页(默认值为 4),并受行数上限CHEMBL_MAX_SPILL_ROWS(默认值为 50,000)和时间预算CHEMBL_SPILL_DEADLINE_MS(默认值为 45 s)限制。如果任一限制导致结果视图未能全部提取,响应会报告truncated: true、staged_row_count和truncated_by(row_cap或time_budget) - 无论溢出状态如何,内联预览始终受
limit限制(默认值为 25);超过 1,000 的limit会按 1,000 处理,并附带提示 - 只有发生视图溢出时才会创建画布,因此结果可完全内联时不会有画布;传回
canvas_id后,每次后续非游标调用都会用该视图自身的行重新暂存表格——即使结果可完全内联或没有匹配项也是如此——并替换之前的行,而另一个视图的表格保持不变。只有溢出成功后才会替换表格,因此失败或取消的溢出不会影响之前的行。达到每租户画布上限时,未提供canvas_id的溢出会报canvas_capacity_exhausted - 每当一次调用没有暂存任何内容时(画布已禁用,或视图可完全内联且未提供
canvas_id),结果视图会通过nextCursor/cursor分页返回;最后一页会省略该字段(而非返回 null)。使用创建游标时相同的筛选条件和potency_view兑换游标;游标页以内联方式返回,绝不会暂存,即使画布已启用也是如此
chembl_search_targets 工具
- 至少提供
accession(UniProt,例如P00533)、gene_symbol或query(自由文本)中的一项;可用organism和target_type缩小范围——未提供任何参数会报错missing_input - UniProt 登录号是最精确的输入——可从
uniprot/protein服务串联传入。accession和target_type会按大写形式匹配,即 ChEMBL 记录的形式("p00533"会被识别为P00533,"single protein"会被识别为SINGLE PROTEIN);gene_symbol和organism则已支持不区分大小写匹配 - 每行包含靶点类型、物种,以及组分 UniProt 登录号和基因符号;这些信息由 ChEMBL 嵌套的组分同义词展开而来
- 支持通过
nextCursor/cursor分页,契约与chembl_search_molecules相同,也包含limit上限 - 将
target_chembl_id串联传入chembl_get_bioactivities
chembl_get_drug_info 工具
- 提供
molecule_chembl_id(任意大小写)或该分子的标准 InChIKey;返回作用机制、分子靶点、作用类型、首次获批年份,以及每项临床适应症达到的最高阶段 - 两个列表都涵盖药物在
parent_molecule_chembl_id下的家族成员,因为 ChEMBL 通常会将药物的作用机制和获批适应症记录在某种盐上:厄洛替尼CHEMBL553及其盐酸盐会返回相同的 EGFR 作用机制,该机制记录在CHEMBL1079742上。每项作用机制都会注明其记录形式;每项适应症按每个 MeSH/EFO 组合仅出现一次,阶段取任何形式所达到的最高阶段,并列出每种形式各自的阶段(索拉非尼的肝细胞癌在其甲苯磺酸盐CHEMBL1200485上为 4 期,在其氘代类似物多纳非尼CHEMBL4297490上为 2 期) - 首先获取分子记录;如果获取失败,整个调用也会失败。随后使用
Promise.allSettled获取作用机制和适应症,因此某个列表获取失败时会返回明确标示的部分结果,而不会导致整个调用失败 - 每个列表都附带独立的
mechanisms_status/indications_status(complete/truncated/failed)以及*_total_count——只有状态为complete时,空数组才具有权威性。失败列表中的*_failure会说明是耗尽了时间(timeout),还是 ChEMBL 返回了错误(upstream_error);被截断的适应症列表会报告indications_rows_fetched,据此可界定缺失适应症的数量;显示的阶段和形式均为下限 - 机制中的
target_chembl_id可串联传入chembl_get_bioactivities
chembl_get_assay 工具
- 提供
chembl_get_bioactivities某一行中的assay_chembl_id,大小写不限;不是 ChEMBL ID 的值会在发送任何请求之前报错-32602 - 返回描述、检测类型(结合 / 功能 / ADMET / 毒性)、检测的靶点、物种,以及 ChEMBL 的 1–9 置信度评分(9 = 直接针对蛋白靶点进行的检测;分数越低,表示同源或间接检测)
- 在将两项测量结果放在一起排序之前,可调用此工具判断它们是否具有可比性
chembl_dataframe_query 工具
- 接受针对
chembl_get_bioactivities调用暂存表格时所用canvas_id的单条只读SELECT;框架 SQL 检查会拒绝写入、DDL 和非SELECT语句 - 使用
chembl_get_bioactivities返回的名称引用每个暂存表——bioactivities(potency_ranked)或bioactivities_null_potency(null_potency);先用chembl_dataframe_describe查询列信息 - 有两个独立的限制,都会明确说明:
truncated是 Canvas 引擎自身对查询结果数量的上限;rendered_rows是content[]Markdown 表格在字符预算内能容纳的行数;任一限制都可能单独触发;使用 SQLLIMIT/OFFSET分页以获取超出限制的数据 - 无论渲染限制如何,
structuredContent.rows始终包含完整的物化结果 - 当服务以
CANVAS_PROVIDER_TYPE=none运行时,会报错canvas_disabled
chembl_dataframe_describe 工具
- 提供
chembl_get_bioactivities调用返回的canvas_id,该调用已将表暂存 - 返回每个暂存表/视图的行数、类型,以及列名和类型
- 当服务以
CANVAS_PROVIDER_TYPE=none运行时,会因canvas_disabled失败
chembl_dataframe_drop 工具
- 可选择启用——仅当
CHEMBL_DATAFRAME_DROP_ENABLED=true时注册;关闭时不会出现在tools/list中,但仍会显示在服务清单中,并附带启用提示 - 通过
canvas_id+table_name删除指定的暂存表;若表存在,则返回dropped: true;若当前画布中没有该名称的表,则返回false - 未知或已过期的
canvas_id会因canvas_not_found失败——画布过期时,其表已释放,因此没有剩余表可供删除 - 很少需要使用——暂存表会随其画布一同存在;画布会在滑动 TTL(
CANVAS_TTL_MS,默认 24 h)或绝对时限(CANVAS_ABSOLUTE_CAP_MS,默认 7 days)到期时释放其上的所有表;仅在长会话中需要提前释放大型表时使用此工具 - 当服务以
CANVAS_PROVIDER_TYPE=none运行时,会因canvas_disabled失败
chembl://molecule/{chemblId} 资源
- 分子记录,格式为
application/json——与chembl_search_molecules返回的行结构相同(ID、名称、结构、属性、最高临床阶段,以及家族parent_chembl_id) chemblId可以是任意大小写的 ChEMBL ID(chembl://molecule/chembl25会读取为CHEMBL25);其他格式会在获取前被拒绝- 工具接口已完全覆盖此功能——这是便于注入上下文的单条记录获取镜像
chembl://target/{chemblId} 资源
- 靶点记录,格式为
application/json——首选名称、类型、物种,以及组分的 UniProt 登录号和基因符号 chemblId可以是任意大小写的 ChEMBL ID(chembl://target/chembl203会读取为CHEMBL203);其他格式会在获取前被拒绝- 工具接口已完全覆盖此功能——这是便于注入上下文的单条记录获取镜像
功能
基于 @cyanheads/mcp-ts-core 构建:支持 stdio 和 Streamable HTTP 传输、可插拔身份验证(none / jwt / oauth)、可切换存储(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1),并支持结构化日志记录和可选的 OpenTelemetry 跟踪。
ChEMBL 专属功能:
- 双向生物活性桥接——一个工具同时支持化合物→靶标和靶标→化合物,并按
pchembl_value排序 - 结构搜索(精确/相似性/子结构)通过
search_type枚举整合到一个发现工具中 - 在服务边界将字符串强制转换为
number | null——缺少效力数据时会变为null,绝不会变为0 - 旗舰工具支持 DataCanvas 溢出——数万行的活性数据集会流式写入 DuckDB 表,你可以用
chembl_dataframe_describe检查,并通过chembl_dataframe_query查询 - 服务级
instructions提供跨服务链路指南以及 ChEMBL CC BY-SA 3.0 署名要求
便于 Agent 使用的输出:
- 每个响应都包含来源信息——找到的总数、已应用筛选条件的回显,以及溢出提示,让 Agent 知道预览是完整结果集,还是画布表中的一部分
- 截断信息——达到上限的搜索会报告
shown/cap/totalCount(当总数达到 ChEMBL 自身的搜索上限、因此只是一个下限时,会附带totalCountCapped: true);溢出表会报告truncated+staged_row_count+truncated_by,因此不会把某一页或某个切片误认为完整结果集 - 延迟有界——每次调用(包括重试)的上游请求总预算为 45 s,因此上游无响应时会在 MCP 客户端的 60 s 超时之前以
upstream_timeout失败;溢出的预算为CHEMBL_SPILL_DEADLINE_MS(默认 45 s),到期时会暂存已获取的行,并设置truncated_by: "time_budget" - 类型化且可恢复的错误——
missing_filter/missing_input/invalid_structure/not_a_chembl_id/alternate_forms_without_molecule/contradictory_potency_filter/canvas_disabled/canvas_capacity_exhausted会附带恢复提示,调用方无需解析说明文本即可修正调用 - 输入边界规范化——在发出任何请求之前,会将 ID、登录号、靶标类型和测定类型名称转换为符合 ChEMBL 记录的形式;每种公开的输入模式都接受服务端可映射的大小写及空格变体,因此经过 JSON-Schema 验证的客户端也可以发送这些输入
- 上游文本不产生格式效果——
format()输出的每个 ChEMBL 字符串都会经过转义,因此 CommonMark 解析器读取content[]时看到的是记录中的原文,而不是由其生成的链接、强调或块级元素(测定描述中的[125I](R)-DOI会保留为文本);SMILES 和 InChIKeys 会显示为代码跨度,structuredContent则保留 ChEMBL 写入的每个值 - 绝不伪造数据——规范化和
format()会保留null效力值/单位;缺少测量值时会显示“未报告”,绝不会显示为0
开始使用
公共托管实例
现已提供公共实例:https://chembl.caseyjhand.com/mcp——无需安装。通过 Streamable HTTP 将任意 MCP 客户端指向该实例:
{
"mcpServers": {
"chembl-mcp-server": {
"type": "streamable-http",
"url": "https://chembl.caseyjhand.com/mcp"
}
}
}
自托管/本地运行
ChEMBL 无需密钥——不需要 API 密钥或账户。
将以下内容添加到 MCP 客户端配置文件中:
{
"mcpServers": {
"chembl-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/chembl-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
也可以使用 npx(无需 Bun):
{
"mcpServers": {
"chembl-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/chembl-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
也可以使用 Docker:
{
"mcpServers": {
"chembl-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/chembl-mcp-server:latest"]
}
}
}
如需使用 Streamable HTTP,请设置传输方式并启动服务:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
分析 SQL 路径(bioactivities 溢出和 chembl_dataframe_* 工具)默认使用 DuckDB;将 "CANVAS_PROVIDER_TYPE": "none" 添加到 env 可将其关闭。
先决条件
- Bun v1.4.0](https://bun.sh/) 或更高版本(或 Node.js v24+)。
安装
- 克隆仓库:
git clone https://github.com/cyanheads/chembl-mcp-server.git
- 进入目录:
cd chembl-mcp-server
- 安装依赖项:
bun install
- 配置环境:
cp .env.example .env
# edit .env to override any defaults (all optional)
配置
CHEMBL_* 变量会在启动时由 src/config/server-config.ts 中的 Zod 模式进行验证:如果值无效,服务器会停止启动,并显示指出该变量的配置横幅。其余变量由框架验证,值无效时同样会拒绝启动。空值会回退到默认值。ChEMBL 无需密钥,因此所有变量均为可选项。
| 变量 | 描述 | 默认值 |
|---|---|---|
CANVAS_PROVIDER_TYPE | 用于生物活性数据溢出和 chembl_dataframe_* SQL 工具的 DataCanvas 提供方。设为 none 可禁用该功能:大型数据集会内联预览,但不会溢出。 | duckdb |
CHEMBL_API_BASE_URL | ChEMBL REST 数据 API 的基础 URL。可覆盖为私有镜像或固定主机。 | https://www.ebi.ac.uk/chembl/api/data |
CHEMBL_REQUEST_TIMEOUT_MS | 向上游 ChEMBL 发起请求时,每次尝试的超时时间(毫秒);该值不会超过调用剩余的时间预算(大多数调用为 45 s,生物活性数据溢出调用为 CHEMBL_SPILL_DEADLINE_MS)。 | 30000 |
CHEMBL_MAX_PAGE_SIZE | 上游 ChEMBL 每页的行数(最多 1000)。生物活性数据溢出会按此大小遍历页面;内联生物活性页面会请求其 limit,但上限为此值。 | 1000 |
CHEMBL_DEFAULT_LIMIT | 调用方未提供限制时应用的默认结果限制。 | 25 |
CHEMBL_MAX_SPILL_ROWS | chembl_get_bioactivities 分阶段写入画布表的行数上限,也就是其背后上游分页遍历的行数上限。超过上限时,响应会报告 truncated: true 和 truncated_by: "row_cap"。 | 50000 |
CHEMBL_MAX_CONCURRENT_PAGES | chembl_get_bioactivities 溢出期间同时进行的分页请求数(1–6),由服务器上的所有调用共享。 | 4 |
CHEMBL_SPILL_DEADLINE_MS | 单次 chembl_get_bioactivities 溢出的时间预算(毫秒),包括计数和分页遍历(10000–600000)。到期时,已获取的行会被分阶段写入,并设置 truncated: true 和 truncated_by: "time_budget"。 | 45000 |
CHEMBL_DATAFRAME_DROP_ENABLED | 注册可选启用的 chembl_dataframe_drop 工具(关闭时,该工具不会出现在 tools/list 中)。 | false |
MCP_TRANSPORT_TYPE | 传输方式:stdio 或 http。 | stdio |
MCP_HTTP_PORT | HTTP 服务的端口。 | 3010 |
MCP_SESSION_MODE | HTTP 会话模式;可设为 stateless、stateful 或 auto(解析为 stateful)。覆盖服务器的无状态声明。 | stateless |
MCP_AUTH_MODE | 身份验证模式:none、jwt 或 oauth。 | none |
MCP_LOG_LEVEL | 日志级别(RFC 5424)。 | debug(Docker 镜像设为 info) |
LOGS_DIR | 日志文件目录(仅限 Node.js)。 | <project-root>/logs |
LOG_TOOL_FAILURE_PAYLOADS | 记录失败调用的参数和结果,并对键名进行脱敏;自由格式值中的机密仍会显示。 | false |
LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES | 每个已记录输入/结果负载的 UTF-8 字节数上限。 | 16384 |
OTEL_ENABLED | 启用 OpenTelemetry 插桩。 | false |
OTEL_EXPORTER_OTLP_ENDPOINT | 跟踪和指标的基础 URL,使用 /v1/traces 和 /v1/metrics。 | — |
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT | OTLP 日志导出的显式完整端点。需要可选的日志对等依赖;默认 Docker 构建中已包含这些依赖。 | — |
完整的可选覆盖项列表请参阅 .env.example。
作为 Claude Code 插件、Codex 插件或 Claude Desktop .mcpb bundle 安装时,服务无需 env 块即可使用上述 CANVAS_PROVIDER_TYPE、CHEMBL_* 和 MCP_LOG_LEVEL 设置:Claude Code 插件和 .mcpb bundle 会将它们声明为安装选项(在 Claude Code 中,之后可通过 /plugin configure 修改),Codex 会转发其运行环境中的这些设置,留空的选项则保留默认值。.mcpb bundle 不附带 DuckDB 的原生绑定,因此会将 CANVAS_PROVIDER_TYPE 固定为 none,关闭 canvas,并省略仅在 canvas 开启时才有用的选项(CANVAS_PROVIDER_TYPE、CHEMBL_DATAFRAME_DROP_ENABLED、CHEMBL_MAX_SPILL_ROWS、CHEMBL_MAX_CONCURRENT_PAGES、CHEMBL_SPILL_DEADLINE_MS);如需使用 SQL 路径,请通过 npx 或 bunx 安装。
运行服务
本地开发
-
构建并运行:
# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:http -
运行检查和测试:
bun run devcheck # Lint, format, typecheck, security, changelog sync bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
docker build -t chembl-mcp-server .
docker run --rm -e MCP_TRANSPORT_TYPE=stdio chembl-mcp-server
Dockerfile 默认使用 HTTP 传输、无状态会话模式,并将日志写入 /var/log/chembl-mcp-server。默认会安装 OpenTelemetry 对等依赖;构建时添加 --build-arg OTEL_ENABLED=false 可省略它们。依赖安装和安全扫描会在构建器的原生平台上运行,Bun 的 --cpu 和 --os 会为目标 linux/amd64 或 linux/arm64 镜像选择 DuckDB 绑定。精简版运行时会使用该生产依赖树,因此默认的 DuckDB canvas 可在两种镜像架构上运行。
项目结构
| 目录 | 用途 |
|---|---|
src/index.ts | createApp() 入口点——注册工具/资源,并初始化 ChEMBL 服务和 DataCanvas;默认使用 DuckDB。 |
src/config | 使用 Zod 解析和验证服务专用环境变量。 |
src/mcp-server/input-normalization.ts | 工具和资源共用的输入边界解析——ChEMBL ID、分子引用、assay_type、大写代码以及 limit 限制。 |
src/mcp-server/markdown-text.ts | format() 中每个上游字符串都会经过的转义函数,因此 content[] 读回的内容与字段完全一致。 |
src/mcp-server/tools/definitions | 工具定义(*.tool.ts)。包含五个 ChEMBL 工具和三个 chembl_dataframe_* canvas 工具。 |
src/mcp-server/resources/definitions | 资源定义(*.resource.ts)。分子和靶点记录的镜像。 |
src/services/chembl | 唯一的 ChEMBL 上游客户端——URL 构建器、分页、数值强制转换、嵌套结构扁平化、活性数据分页流。 |
src/services/canvas-accessor.ts | 模块级容器,用于保存通过 createApp({ setup }) 接入的可选 DataCanvas。 |
tests/ | 与 src/ 结构对应的单元测试和集成测试。 |
开发指南
开发指南和架构规则请参阅 CLAUDE.md/AGENTS.md。简要说明:
- 处理器抛出异常,由框架捕获——工具逻辑中不要使用
try/catch - 使用
ctx.log记录请求范围的日志,使用ctx.state存储租户范围的数据 - 在
createApp()数组中注册新工具和资源 - 封装 ChEMBL API:验证原始数据 → 规范化为扁平领域类型 → 返回输出架构;绝不伪造缺失字段(缺失的数值应为
null,绝不能是0)
贡献
欢迎提交问题。提交前请运行检查和测试:
bun run devcheck
bun run test
许可证
Apache-2.0——详情请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。