chembl-mcp-server について
chembl-mcp-serverは、創薬研究者にChEMBLの化合物、標的、生物活性、医薬品情報を提供します。化合物とタンパク質標的を結び付け、測定された活性を順位付けできるほか、ステージングした生物活性データを読み取り専用SQLで分析できます。
主な機能
- 01名称、ID、構造による化合物検索
- 02タンパク質標的と遺伝子標的の特定
- 03生物活性測定値の絞り込みと順位付け
- 04医薬品の作用機序と適応症の取得
- 05読み取り専用SQLによるステージングデータの検索
活用シーン
- 01SMILES構造から化合物を検索
- 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 を介して ChEMBL の化合物とタンパク質ターゲットを関連付け、生物活性(IC50/Ki/EC50)を順位付けし、医薬品の作用機序と適応症を検索します。STDIO または Streamable HTTP に対応しています。
公開ホストサーバー: https://chembl.caseyjhand.com/mcp
概要
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クライアントでも情報を失いません。プロンプトはありません。標準的なワークフローはエージェントが直接組み合わせる短いツールチェーンであり、サーバー間の連携手順はサーバーレベルのinstructionsとして提供されます。
機能リファレンス
chembl_search_molecules ツール
- デフォルトの
search_type=nameでは、薬剤名、別名、ChEMBL ID、InChIKeyを1回のクエリで検索します。クエリがChEMBL IDまたはInChIKeyと完全に一致する場合、あいまい検索用のテキストインデックスではなく、ChEMBLの単一レコード検索に振り分けられます(totalCount: 1)。 search_typeで構造検索を指定できます。exactは完全一致、similarityは類似性(Tanimoto ≥similarity_threshold。整数の40~100、デフォルトは70)、substructureは部分構造検索です。structureにはSMILESを指定します。max_phase_min(名前検索のみ)を使うと、最大臨床フェーズが指定値以上の化合物に絞り込めます。ChEMBLが解析できないSMILESを指定した場合、類似性検索または部分構造検索の最初のリクエストで、サービス停止ではなくinvalid_structureエラーになります。- 各行には
max_phase、MW、AlogP、Lipinskiのルール・オブ・ファイブ違反数、QEDが含まれます。Tanimotoのsimilarity割合が含まれるのはsearch_type=similarityの結果のみです。他のモードでは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(除外された行)を選択します。null_potencyとpchembl_value_minを併用するとcontradictory_potency_filterエラーになり、totalCountは両方のビューの合計です- 数値はサービス境界で
number | nullに変換されます。効力の値がない場合は0ではなくnullになります - 大きなデータセットは、ビューごとに 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秒)の範囲内で処理されます。どちらかの上限に達してビュー全体を処理できなかった場合、レスポンスにはtruncated: true、staged_row_count、truncated_by(row_capまたはtime_budget)が含まれます - インラインプレビューの上限は、スピルの状態にかかわらず常に
limit(デフォルトは25)です。limitが1,000を超える場合は1,000件まで返され、通知が表示されます - ビューがスピルされる場合に限りキャンバスが作成されるため、インラインに収まる場合はキャンバスが作成されません。返された
canvas_idを渡すと、その後のカーソルを使わない呼び出しごとに、そのビューのテーブルが呼び出し独自の行で再ステージされます。行がインラインに収まる場合や、一致する行がない場合も同様です。これにより以前の行は置き換えられますが、もう一方のビューのテーブルはそのままです。スピルによるテーブルの置き換えは、スピルが成功した場合に限られます。そのため、失敗またはキャンセルされた場合は以前の行が残ります。テナントごとのキャンバス上限に達しているときにcanvas_idなしでスピルすると、canvas_capacity_exhaustedエラーになります - 呼び出しで何もステージされない場合(キャンバスが無効、または
canvas_idなしでビューがインラインに収まる場合)、ビューはnextCursor/cursorを使って1ページずつ返されます。最後のページでは null ではなく省略されます。カーソルは、発行時と同じフィルターおよびpotency_viewを指定して使用してください。カーソルページはインラインで返され、キャンバスが有効でもステージされません
chembl_search_targets tool
accession(UniProt、例:P00533)、gene_symbol、query(フリーテキスト)のいずれかを少なくとも1つ指定し、organismとtarget_typeで絞り込みます。いずれも指定しない場合はmissing_inputエラーになります- 最も正確な入力は UniProt アクセッションです。
uniprot/proteinサーバーから連携してください。accessionとtarget_typeは大文字に変換して照合され、ChEMBL の記録形式に合わせます("p00533"はP00533として、"single protein"はSINGLE PROTEINとして扱われます)。gene_symbolとorganismは大文字と小文字を区別せずに照合されます - 各行には、ChEMBL のネストされたコンポーネント同義語からフラット化した、ターゲットタイプ、生物種、コンポーネントの UniProt アクセッションと遺伝子シンボルが含まれます
nextCursor/cursorを使ったページネーションに対応しており、limitの上限処理を含め、chembl_search_moleculesと同じ仕様ですtarget_chembl_idをchembl_get_bioactivitiesに連携してください
chembl_get_drug_info tool
molecule_chembl_id(大文字と小文字は問いません)または分子の標準 InChIKey を指定します。作用機序、分子標的、作用タイプ、初回承認年、およびそれぞれに到達した最高フェーズを含む臨床適応症を返します- 両方のリストは
parent_molecule_chembl_idで示される医薬品ファミリーを対象とします。ChEMBL では、医薬品の作用機序や承認済み適応症が塩に記録されることが多いためです。エルロチニブCHEMBL553とその塩酸塩は、同じ EGFR 作用機序を返します。この作用機序はCHEMBL1079742に記録されています。各作用機序には、記録された剤形が示されます。各適応症は MeSH/EFO の組み合わせごとに、いずれかの剤形が到達した最高フェーズで1回だけ表示され、各剤形についてはそれぞれのフェーズが記載されます(ソラフェニブの肝細胞癌は、トシル酸塩CHEMBL1200485ではフェーズ4、重水素化類縁体のドナフェニブCHEMBL4297490ではフェーズ2です) - まず分子レコードを取得し、取得に失敗すると呼び出し全体が失敗します。その後、作用機序と適応症を
Promise.allSettledで取得するため、いずれかのリストの取得に失敗しても呼び出し全体は失敗せず、部分的な結果としてその旨が明示されます - 各リストには、それぞれの
*_total_countと並んでmechanisms_status/indications_status(complete/truncated/failed)が含まれます。空の配列が確定的な結果となるのは、ステータスがcompleteの場合に限ります。取得に失敗したリストの*_failureには、時間切れ(timeout)か、ChEMBL がエラーを返したか(upstream_error)が示されます。適応症リストが切り詰められた場合はindications_rows_fetchedが返され、不足している適応症の件数の範囲がわかります。表示されたフェーズと剤形は下限値です - 作用機序の
target_chembl_idをchembl_get_bioactivitiesに連携できます
chembl_get_assay tool
chembl_get_bioactivitiesの行にあるassay_chembl_idを、大文字と小文字を問わず指定します。ChEMBL ID ではない値を指定すると、リクエストを送信する前に-32602で失敗します- 説明、アッセイタイプ(結合/機能/ADMET/毒性)、測定対象のターゲット、生物種、ChEMBL の1〜9の信頼度スコアを返します(9はタンパク質ターゲットに対する直接アッセイで、低いスコアは相同または間接的な測定を示します)
- 複数の測定値をまとめて順位付けする前に、比較可能かどうかを判断するために呼び出してください
chembl_dataframe_query tool
- テーブルをステージングした
chembl_get_bioactivities呼び出しのcanvas_idに対して、読み取り専用のSELECT文を1つ実行できます。書き込み、DDL、SELECT以外の文はフレームワークの SQL ゲートで拒否されます - ステージング済みのテーブルは、
chembl_get_bioactivitiesが返した名前で参照します。bioactivities(potency_ranked)またはbioactivities_null_potency(null_potency)を指定してください。まずchembl_dataframe_describeで列を確認してください - 独立した2つの上限があり、それぞれについて通知されます。
truncatedは Canvas エンジン独自のクエリ結果上限、rendered_rowsは文字数制限内でcontent[]の Markdown テーブルに格納される行数です。どちらか一方だけが上限に達する場合もあります。SQL のLIMIT/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時間)または絶対上限(CANVAS_ABSOLUTE_CAP_MS、デフォルトは7日)に達するとキャンバスが期限切れになり、そのキャンバス上のすべてのテーブルが解放されます。長時間のセッション中に大きなテーブルを早めに解放する場合にのみ使用してください - サーバーが
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 固有の機能:
- 双方向の生物活性ブリッジ — 1 つのツールで、化合物からターゲット、ターゲットから化合物への両方の検索に対応し、
pchembl_valueに基づいて順位付けします - 構造検索(完全一致/類似/部分構造)を、
search_type列挙型を使って 1 つの検索ツールに集約します - サービス境界で String を
number | nullに数値変換します — 効力が欠損している場合は0ではなくnullになります - 主要ツールで DataCanvas にデータをスピルします — 数万行におよぶ活性データセットを DuckDB テーブルにストリーミングし、
chembl_dataframe_describeで確認し、chembl_dataframe_queryでクエリできます - サーバーレベルの
instructionsに、サーバー間での連携方法と ChEMBL の CC BY-SA 3.0 帰属表示要件に関するガイダンスを記載しています
エージェントに適した出力:
- すべてのレスポンスに出典情報を付与 — 該当件数の合計、適用されたフィルターのエコー、スピル通知を含み、エージェントがプレビュー全体を見ているのか、キャンバステーブルの一部を見ているのかを把握できます
- 切り詰めに関する明示 — 上限のある検索では
shown/cap/totalCountを返します(合計が ChEMBL 独自の検索上限による下限値の場合はtotalCountCapped: true)。スピルされたテーブルではtruncatedとstaged_row_countとtruncated_byを返すため、ページやスライスが全件と誤認されることはありません - レイテンシの上限 — すべての呼び出しで、再試行を含む上流リクエストを 45 秒の予算内に制限するため、上流が応答しない場合、MCP クライアントの 60 秒タイムアウトより前に
upstream_timeoutとして失敗します。スピルの予算はCHEMBL_SPILL_DEADLINE_MS(既定値は 45 秒)で、期限に達すると、それまでに取得した行を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 文字列をエスケープするため、content[]を CommonMark として読む場合でも、記録されたテキストがリンク、強調、ブロックとして解釈されることはありません(アッセイの説明にある[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 上で実行されます。無効にするには、env に "CANVAS_PROVIDER_TYPE": "none" を追加してください。
前提条件
- Bun v1.4.0 以上(または 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 秒、生物活性データのスピルでは 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 を指定します(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 | /v1/traces と /v1/metrics を使用する、トレースおよびメトリクスのベース URL です。 | — |
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT | OTLP ログエクスポート用の明示的な完全エンドポイントです。オプションのログ用ピアが必要です。デフォルトの Docker ビルドには含まれています。 | — |
任意のオーバーライドの全一覧については、.env.example を参照してください。
Claude Code プラグイン、Codex プラグイン、または Claude Desktop の .mcpb バンドルとしてインストールした場合、サーバーは上記の CANVAS_PROVIDER_TYPE、CHEMBL_*、MCP_LOG_LEVEL の設定を env ブロックなしで使用します。Claude Code プラグインと .mcpb バンドルではインストールオプションとして宣言され(Claude Code では、後から /plugin configure で変更できます)、Codex は実行環境から設定を引き継ぎ、空欄のままのオプションにはデフォルト値が適用されます。.mcpb バンドルには 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 サービスと、デフォルトで DuckDB を使用する DataCanvas を初期化します。 |
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)です。5 つの ChEMBL ツールと 3 つの 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 をラップします。生データを検証し、フラットなドメイン型に正規化してから、出力スキーマを返します。不足フィールドを捏造してはいけません(欠落した数値は
0ではなくnullにします)。
コントリビューション
Issue の報告を歓迎します。提出前にチェックとテストを実行してください。
bun run devcheck
bun run test
ライセンス
Apache-2.0 — 詳細は LICENSE を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。