关于 brapi-mcp-server
brapi-mcp-server 将 MCP 客户端连接到 BrAPI v2 育种数据库,供植物育种研究使用。它支持注册多个服务,并提供搜索、谱系探索及表型或基因型矩阵工作流。
主要功能
- 01连接多个 BrAPI v2 服务
- 02搜索研究、种质和观测记录
- 03以图结构探索谱系
- 04构建表型和基因型矩阵
- 05使用 SQL 查询结果数据框
适用场景
- 01比较多个育种数据库中的研究
- 02追踪种质的祖先和后代
- 03整理表型或基因型矩阵
- 04使用 SQL 查询大型研究结果
MCP 相关
通过 25 个工具、6 个资源和 2 个提示词向 MCP 客户端提供 BrAPI v2.1 数据与操作,并支持使用别名连接多个服务。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://brapi.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-brapi https://brapi.caseyjhand.com/mcp{"mcpServers":{"cyanheads-brapi":{"type":"http","url":"https://brapi.caseyjhand.com/mcp"}}}在 Cursor 中打开{"servers":{"cyanheads-brapi":{"type":"http","url":"https://brapi.caseyjhand.com/mcp"}}}在 VS Code 中打开{"mcpServers":{"cyanheads-brapi":{"type":"http","url":"https://brapi.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-brapi":{"serverUrl":"https://brapi.caseyjhand.com/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
22| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| auth | any | 否 | 身份验证负载。省略时,使用此别名在服务端配置的凭据(如果未配置凭据,则不进行身份验证)。 |
| alias | string | 否 | 此连接的别名。使用不同的别名可在同一会话中注册多个 BrAPI 服务。 |
| baseUrl | string | 否 | BrAPI v2 基础 URL(绝对 URL),可包含路径前缀,例如 https://test-server.brapi.org/brapi/v2。省略时,使用此别名配置的默认值。 |
详细介绍
@cyanheads/brapi-mcp-server
通过 MCP 为多 Agent 研究提供协作式 BrAPI v2.1 工作区。可跨 Breedbase、T3、Sweetpotatobase 及任何符合 BrAPI v2 标准的服务,搜索试验、种质、基因型等数据。
公共托管服务: https://brapi.caseyjhand.com/mcp
概述
可访问任何 BrAPI(育种 API)v2 服务中的植物育种数据——包括 Cassavabase 和 Sweetpotatobase 等 Breedbase 实例、Triticeae Toolbox(T3)等,并可同时访问多个服务。搜索试验、种质、观测数据和基因型,追溯谱系并构建表型与基因型矩阵;大型结果集还可通过 SQL 查询。
工具
| 工具 | 描述 |
|---|---|
brapi_connect | 验证身份以连接到 BrAPI v2 服务,将其注册为一个别名,并返回方向信息信封 |
brapi_server_info | 返回某个别名的方向信息信封,可选择刷新功能 |
brapi_describe_filters | 列出端点的有效筛选器名称,供任何查找工具的 extraFilters 使用 |
brapi_find_studies | 按作物、试验类型、季节、地点或项目查找研究 |
brapi_get_study | 获取一项研究,并解析其项目、试验和地点,同时返回关联计数 |
brapi_find_germplasm | 按名称、同义名、种质登录号、PUI、作物或自由文本查找种质 |
brapi_get_germplasm | 获取一种种质及其属性、直接亲本和关联计数 |
brapi_walk_pedigree | 遍历祖先或后代关系,生成带循环检测功能的去重 DAG |
brapi_find_variables | 按名称、性状类别或本体术语查找观测变量,并按自由文本相关性排序 |
brapi_find_observations | 按研究、种质、变量、季节或单位提取观测记录 |
brapi_find_images | 按单位、观测、研究、本体术语或 MIME 类型查找图像元数据 |
brapi_get_image | 以图像内容块的形式内嵌获取最多 5 张图像 |
brapi_find_locations | 按国家、类型、缩写或边界框查找研究站 |
brapi_find_variants | 按变异集、参考基因组或基因组区域查找变异 |
brapi_find_genotype_calls | 通过异步搜索提取基因型调用,并受部署拉取上限限制 |
brapi_dataframe_describe | 列出数据框,或查看一个数据框的列、行数和来源信息 |
brapi_dataframe_query | 对多个数据框运行只读 SQL 查询 |
brapi_dataframe_drop | 选择启用。 按名称删除数据框 |
brapi_dataframe_export | 选择启用,仅限 stdio。 将数据框导出到磁盘,格式为 CSV、Parquet 或 JSON |
brapi_build_phenotype_matrix | 根据一项或多项研究构建种质 × 性状数据框 |
brapi_germplasm_performance | 计算一种种质在其各项研究中每个变量的汇总值(n、均值、中位数、标准差、最小值、最大值) |
brapi_export_genotype_matrix | 将变异集的调用数据透视为种质 × 变异矩阵,支持 VCF-lite 或 PLINK 文本格式 |
brapi_submit_observations | 选择启用。 分两阶段写入观测数据:preview 负责验证,apply 负责确认并写入 |
brapi_raw_get | 透传到任何精选工具未覆盖的 GET /{path} 端点 |
brapi_raw_search | 透传到任何 POST /search/{noun} 端点,并处理异步轮询 |
资源
| 资源 | 描述 |
|---|---|
brapi://server/info | 默认连接的方向信息信封 |
brapi://calls | 默认连接的原始功能配置(/serverinfo + /calls) |
brapi://study/{studyDbId} | 一项研究,并解析其项目、试验和地点 |
brapi://germplasm/{germplasmDbId} | 一种种质及其属性和亲本 |
brapi://filters/{endpoint} | 一个端点的筛选器目录 |
brapi://variable/{observationVariableDbId} | 一个观测变量(性状、尺度、方法、本体) |
每个资源都会读取 default 连接,并与某个工具对应;仅支持工具的客户端和多服务工作流应使用工具。
提示词
| 提示词 | 描述 |
|---|---|
brapi_eda_study | 针对一项研究的探索性数据分析指南,最后生成结构化报告 |
brapi_meta_analysis | 针对种质 × 性状组合的跨研究元分析指南 |
功能参考
等效的标识符筛选器也接受其 BrAPI *DbId / *DbIds 写法:例如,imageDbId 对应 imageDbIds,studyDbIds 对应 studies,observationVariableDbIds 对应 variables。数组筛选器接受单个字符串或多个 ID。每个筛选器只能使用一种写法;冲突的写法会被拒绝。
brapi_connect 工具
baseUrl和auth均为可选项:省略的值将依次从BRAPI_<ALIAS>_*环境变量、内置别名和BRAPI_DEFAULT_*中获取(参见按别名配置凭据);alias(默认为default,模式为^[a-zA-Z0-9_-]+$)可同时注册多个服务;auth.mode可以是none、bearer、api_key、sgn(Breedbase/token交换)或oauth2(客户端凭据)- 返回方向信息封装,其中包含
server身份信息、auth概要、capabilities(supported、notableGaps)、当前启用的dialect、content计数、内置服务的attribution,以及指出此服务可支持哪些入口查找工具的nextToolSuggestions - 类型化错误:
auth_session_required、auth_base_url_mismatch、alias_base_url_unset、alias_base_url_invalid、private_address_blocked、auth_token_exchange_failed、auth_no_access_token、upstream_unauthorized、upstream_forbidden、capability_discovery_unavailable(可重试);连接失败时,该别名之前的注册信息仍会保留 - 如果某个别名对应的服务有 URL(
BRAPI_DEFAULT_BASE_URL已设置时的default、内置别名或BRAPI_<ALIAS>_BASE_URL别名),则可选用此项:其他工具或资源会在首次使用时连接该服务,效果等同于不提供baseUrl或auth的brapi_connect,并且并发的首次调用会共享同一次连接。没有自身 URL 的别名仍会报错unknown_alias,即使已设置BRAPI_DEFAULT_*也不例外,因此拼写错误的别名不会转而连接默认服务。这些工具和资源会声明可能遇到的连接错误(上文的令牌、发现、身份验证拦截、alias_base_url_invalid和private_address_blocked错误),并为每种错误提供恢复提示
brapi_server_info 工具
alias为可选项;forceRefresh(默认为false)会重新获取能力配置,而不是读取缓存- 返回与
brapi_connect相同的方向信息封装
brapi_describe_filters 工具
endpoint必须是以下之一:studies、germplasm、observations、variables、images、variants、locations;unknown_endpoint会附带availableEndpoints- 每个筛选条件包含
name、type、description和example;目录遵循 v2.1 规范,但各服务可能仅支持其中一部分
brapi_find_studies 工具
- 筛选条件:
crop、trialTypes、seasons、locations、programs、trials、studyNames、active;对于忽略/studies位置筛选的 SGN 服务(CassavaBase、Breedbase、Sweetpotatobase),locations会在客户端对扫描到的研究进行筛选,totalCount表示匹配数量 - 按
programName、studyType、seasons、locationName、commonCropName统计distributions - SGN/Breedbase 研究会从
additionalInfo中补充缺失的项目 ID 和名称,同时保留原始元数据。
brapi_get_study 工具
- 必须提供
studyDbId;会内联解析program、trial和location;如果上游没有对应的研究,则返回study_not_found - 对于 SGN/Breedbase 服务,缺失的项目字段取自
additionalInfo;如果研究没有项目 ID,则可通过获取其父级试验来解析项目。 - 附带
observationCount、observationUnitCount和variableCount计数;如果服务无法将某项计数限定到该研究,则会省略该计数并发出警告,绝不会报告服务范围内的总数
brapi_find_germplasm 工具
- 筛选条件:
names、germplasmDbIds、germplasmPUIs、accessionNumbers、crops、synonyms、collections、genus、species;text会在客户端对名称、PUI、登录号、显示名称和同义词进行子字符串匹配,并舍弃不匹配的行。首次请求使用BRAPI_PAGE_SIZE,不受内联loadLimit影响;如果数据集可在一次数据框遍历中容纳(默认页面大小下为 50,000 行),就会扫描所有上游行。超过该数量时,若第一页未匹配到结果,则会在一次请求后停止,并报告实际扫描的行数;这并不能证明目录中不存在该条目,因此应配合服务端筛选条件使用。 - 按
commonCropName、genus、species、collection、countryOfOriginCode统计分布
brapi_get_germplasm 工具
- 必填
germplasmDbId;返回attributes和直接亲本;若上游不存在该种质,则返回germplasm_not_found - 附带计数:
studyCount、directParentCount、directDescendantCount
brapi_walk_pedigree 工具
- 根节点
germplasmDbIds为 1–20 个(也接受germplasmDbId);direction可设为ancestors(默认值)、descendants或both;maxDepth为 1–10(默认值为 3);遍历在达到 1,000 个节点或 10,000 条边时停止,并设置truncated both是两次遍历的并集:祖先仅通过/pedigree扩展,后代仅通过/progeny扩展,因此不会纳入某个后代的另一位亲本- 每对亲子关系对应一条边;
cycleCount统计标记为isCycle的边,即某个种质成为自身祖先的情况;共有祖先和兄弟姐妹不算循环 leafCount统计图中的终端节点,包括达到深度边界的节点;confirmedLeafCount统计相关查询成功返回无亲属关系的非根节点。frontier/frontierCount用于区分受深度限制、因安全限制跳过、查询失败和不受支持的方向;deadEndCount仍会统计查询失败的节点nodes和edges各自必须符合loadLimit,且 JSON 数组和序列化渲染行的总大小不得超过 24,000 字节。裁剪后的预览会将已发现的图保留在nodesDataframe和edgesDataframe中;若首行就超出预算,则内联行数为零。裁剪预览不会改变遍历的truncated状态- 达到安全上限的图表会标记为
truncated,且仅包含已发现的节点和边。knownOmittedRelativeCount和omittedRelativesDataframe会保留已获取但省略的亲属信息,包括germplasmDbId、expansionNodeDbId、side和ordinal;未请求的方向,其计数未知。前沿较大时还会暂存frontierDataframe - 使用
SELECT germplasmDbId, expansionNodeDbId, side FROM <table> ORDER BY ordinal LIMIT 20 OFFSET 0获取省略的 ID;根据实际显示的行数调整偏移量,然后每批最多使用 20 个根节点遍历这些 ID。若一行都无法容纳,请缩小投影字段或进行聚合;这些表不会恢复遍历 diagram: "mermaid" | "dot"会添加已发现的图(包括预览之外的行);达到安全上限时会标明覆盖范围不完整。边以父节点 → 子节点绘制,闭环边使用虚线。图表超过 50,000 个字符时,两种格式都会因警告而省略;Mermaid 图超过 500 条边时也会省略
brapi_find_variables 工具
- 筛选条件:
variables、variableNames、variablePUIs、traitClasses、ontologies、studies、methods、scales、crop。多个不同的研究会按变量 ID 合并,并在同一组共享的页面、行数和时间预算下提供studyDbIds来源信息。studyCoverage报告完整、部分、失败和未处理的研究;即使某项研究失败,其他成功研究仍可用。 text会对所有已获取的行进行排序,并将匹配项移到前面,不会舍弃其余行;ontologyCandidates列出已排序的匹配项,每项包含source(puiMatch、nameMatch、synonymMatch、traitClassMatch)- 按
ontologyDbId、traitClass、scaleName统计分布
brapi_find_observations 工具
- 筛选条件:
studies、germplasm、variables、observationUnits、observations、seasons、programs、trials、observationLevels、timestampFrom/timestampTo - 按研究范围查询 SGN/Breedbase 时,使用服务公布的
/observationunits?includeObservations=true,保留值为零的测量结果。分页依据单元总数;子级字段优先于继承的单元元数据,重复的 observation ID 只计一次。展开数据后检查观测级筛选条件;appliedFilters将上游请求与客户端筛选条件分开列出 - GET 查询若没有
studies、trials、observationUnits或observations作为锚点,会先执行单行计数探测;如果探测失败或报告的匹配项超过 5,000 条,就跳过批量拉取;warnings会说明原因 distributions统计observationVariableName、studyName、germplasmName、observationLevel、season的分布
brapi_find_images 工具
- 筛选条件:
images、observationUnits、observations、studies、imageFileNames、mimeTypes、descriptiveOntologyTerms;仅返回元数据,图像字节通过brapi_get_image获取 distributions统计mimeType、studyName、observationUnitName、descriptiveOntologyTerms的分布
brapi_get_image 工具
- 每次调用可传入 1–5 个
imageDbIds,每个图像最多 20 MB;如果服务未公布/images,则返回images_unsupported - 每张图像的
source为imagecontent,或回退至imageURL。两种来源都必须具有有效的image/*MIME 类型(会统一大小写和参数;字节响应不含类型时使用元数据)。非图像响应和获取失败会记录在各图像的errors[]中;成功获取的其他图像仍会返回 - 字节只在
content[]图像块中出现一次。images[]仅包含元数据、MIME 类型、字节大小和来源;format()会呈现元数据,不会重复输出 base64
brapi_find_locations 工具
- 筛选条件:
locations、locationNames、countryCodes(字母代码会转为大写;上游数字代码保持不变)、countryNames(英语名称会解析为 alpha-3)、locationTypes、abbreviations;除非仍保留有效的国家代码限制条件,否则无法解析的名称会导致失败。可选的bbox会在获取数据后应用;非空边界框必须包含四个按序排列的边界值(minLat、maxLat、minLon、maxLon),否则会在获取位置前失败。空边界框会被省略 distributions统计countryCode、locationType的分布;coordinateAxisOrder: "swapped"表示服务存储的坐标顺序为[lat, lon]
brapi_find_variants 工具
- 筛选条件:
variantSets、variants、references,以及由referenceName和start(包含)/end(不包含)组成的基因组区域,坐标从 0 开始 distributions统计variantType、referenceName、variantSetDbId的分布
brapi_find_genotype_calls 工具
- 至少需要提供以下一项:
variantSetDbId、variantSetDbIds、germplasmDbIds、callSetDbIds、variantDbIds(否则返回no_filters);callFormat为可选项(VCF、FLAPJACK、DARTSEQ、JSON) - 通过
brapi_raw_get({ path: "/variantsets" })列出变异集,也可传入params.studyDbId;在 Breedbase 系列服务上,变异集属于基因分型项目,而brapi_find_studies不会列出这些项目 distributions统计callSetName、variantName、variantSetDbId的分布,以及服务端的callFormatting;当当前方言将POST /search/calls标记为不可用时,返回search_endpoint_disabled- 上游拉取在达到
BRAPI_GENOTYPE_CALLS_MAX_PULL(默认值为 100,000)时停止,并设置truncated;若调用的 50 s 上游截止时间导致拉取在第一页后停止,则会保留已收集的调用结果、设置hasMore,并在warnings中说明原因;loadLimit和 24,000 字节的内联预算仅限制内联预览,并通过shown/cap报告;若预览被截断,则会将所有已收集的调用结果暂存到数据框中
brapi_dataframe_describe 工具
dataframe可选:省略则列出所有 dataframe,或指定一个名称以查看列、行数和来源信息(来源工具、baseUrl、查询、过期时间);这些信息仅由自动注册的df_*表携带- 在所有调用方共享
default租户的 HTTP 部署中,当BRAPI_SESSION_ISOLATION=true时,可在 MCP 会话内省略名称进行列表查询,并且只会显示该会话的数据框;无会话的请求或关闭隔离时的任何请求都会以list_all_disabled_on_shared_http失败
brapi_dataframe_query 工具
sql必须是单条SELECT;写入、DDL、COPY、PRAGMA、ATTACH、文件读取(包括将文件或 URL 指定为表名)、系统目录读取,以及DESCRIBE/SUMMARIZE/SHOW都会以sql_rejected失败,具体原因见data.gateReason(brapi_dataframe_describe会列出数据框的列和类型)- 数据本身导致查询失败(例如转换失败的类型转换)时,会以
sql_execution_error失败;数据框名称已不存在时,会以missing_table失败;registerAs名称已被占用时,会以register_as_clash失败 - 返回
rowCount、带类型的columns和前面的rows;结果受preview、rowLimit和BRAPI_CANVAS_MAX_ROWS限制,依次取较小值,然后每个序列化行数组和渲染后的行区段(包括转义和标记)均限制为 24,000 字节。shown是实际返回的行数;cap仍为有效的行数上限。若第一行过大,则返回零行:请使用更窄的投影或聚合 registerAs(标识符,最多 63 个字符)会将完整结果保存为新的数据框,以便后续链式使用- 使用确定性的
ORDER BY和LIMIT/OFFSET对已持久化的结果分页,并按实际返回的行数而非请求的限制值递增偏移量。若未使用registerAs,请先重新运行查询并指定该参数,再对已保存的结果分页
brapi_dataframe_drop 工具
- 必须提供
dataframe;对于未知名称,会返回dropped: false,而不会报错 - 仅当
BRAPI_CANVAS_DROP_ENABLED=true时注册
brapi_dataframe_export 工具
format为csv、parquet或json;可选的columns或sql(二者不可同时指定)以及filename(不能包含路径分隔符或..;省略时使用附带时间戳的默认名称);返回绝对path、sizeBytes和rowCount- 类型化错误:
export_dir_unset、dataframe_not_found、invalid_filename、mutually_exclusive_projection - 仅在设置了
BRAPI_EXPORT_DIR的 stdio 部署中注册
brapi_build_phenotype_matrix 工具
studies必填(≥1),variables/germplasm子集可选;shape可选wide(默认)或long;aggregate可选mean(默认)、median、first或all(始终采用长表形式);loadLimit限制每个 study 中匹配的观测数量- 根据上游总数分页获取每个 study 的观测;如果 SGN/Breedbase 声明支持,则优先使用内嵌观测单元,以保留零值;单元总数统计原始单元,而
loadLimit统计匹配的观测。其他服务器沿用/observations和回退路径。根据返回的行检查 study / variable / germplasm 子集 extraFilters会被转发,之后再根据用于构建矩阵的行进行检查,与brapi_find_observations一致:warnings会列出行所反驳的键,以及没有任何行能够反映的键- 以 dataframe 形式返回矩阵,以及
observationCount、germplasmCount、variableCount和variableLegend(将 SQL 安全的列名映射到变量名);如果某个 study 的扫描在达到总数之前停止(达到loadLimit、页数上限、遇到失败、空页或重复页,或调用期限到期),则truncated/cap会标记该 study,并在通知中列出已检查的行数 studies保留请求的 ID;coverage.studies用contributed、empty、failed、partial和unprocessed区分结果,并附上已收集的计数。两个输出面都会通过coverage.partial和truncated披露失败或不完整的拉取。某个 study 失败不会阻止其他 study 构建矩阵;仅当所有 study 均失败时,调用才会失败。如果服务器未公开任何观测路由,则返回no_observation_path
brapi_germplasm_performance 工具
germplasmDbId必填;SGN/Breedbase 使用其声明支持的、按 germplasm 范围划分的内嵌单元,并遍历其原始总数,不受 study 发现上限影响。其他服务器最多发现 200 个 study。指定studyDbIds时会跳过发现步骤,并将收集范围限制在这些 study;variables子集可选;如果上游不存在该 germplasm,则返回germplasm_not_foundperVariable行包含n、mean、median、sd(n < 2 或数值无效时省略)、min、max、studyCount、studyDbIds和seasonsstudyCount/studyDbIds仍仅统计有贡献的 study。新增的coverage用于区分有贡献、空、失败、不完整和未处理的 study;范围限定的单元扫描会报告原始单元数、页数、已知时的总数以及完成情况。单元遍历不完整时,无法确定未发现的 study 数量。重复的观测 ID 只计数一次;不同 ID 的重复测量和零值会保留。部署的观测数量上限适用于每个 study,包括 germplasm 单元遍历;页数、观测数量和期限限制都会披露,因期限跳过的 study 会收到一条计数警告
brapi_export_genotype_matrix 工具
variantSetDbId必填(否则返回no_filters;使用brapi_raw_get({ path: "/variantsets" })列出变异集),germplasmDbIds可选;format可选matrix-json、vcf-lite(增加vcf文本)或plink(增加ped/map文本),所有格式都会注册 germplasm × 变异 dataframevariantColumnLegend将 SQL 安全的列名映射回变异 ID;如果当前方言将POST /search/calls标记为不可用,则返回search_endpoint_disabled- VCF POS 和 PLINK 碱基对位置均从 1 开始:有效的零基 BrAPI
start值 0 和 500 分别导出为 1 和 501。缺失或无效的位置保留.(VCF)/0(PLINK)占位符。 maxCalls/maxColumns可以调低BRAPI_GENOTYPE_CALLS_MAX_PULL/BRAPI_GENOTYPE_MATRIX_MAX_COLUMNS,但不能调高;如果达到上限,或调用的 50 s 上游期限导致提取调用提前结束,则truncated为真,warnings会列出具体原因
brapi_submit_observations 工具
studyDbId加上 1–5,000 条observations;包含observationDbId的行通过PUT更新,不包含的行通过POST创建,不会删除任何内容mode: "preview"(默认值)会返回valid、invalid、routing计数以及perRowWarnings,不会写入数据;mode: "apply"会要求调用方确认(force: true可跳过确认),且只有在当前轮次兑现服务端对该提示词的记录时才会写入,调用方、服务、研究和行均须相同——预先提供或重放的答案会再次被询问——并返回posted、updated和studyObservationCount;失败时返回observations_unsupported、study_not_found、post_unsupported、put_unsupported和user_declined- 仅在
BRAPI_ENABLE_WRITES=true时注册;需要brapi:write:observations范围
brapi_raw_get 工具
path是相对路由,例如/samples(完整 URL 会导致cross_origin_path错误);params和loadLimit为可选项- 返回信封(
url、metadata、result);当精选工具覆盖该端点或可接收其列出的 ID 时,还会返回suggestion。列表预览(result数组或result.data)受loadLimit以及 24,000 字节限制,该限制分别适用于序列化后的每个行数组和渲染后的行区域(包括标记和转义内容);非列表结果和信封中的其他字段会保留。每个未内联显示的已获取行都会暂存,包括导致内联行数为零的超大首行 params.page/params.pageSize只会获取请求的上游页面;经裁剪的页面会被暂存,且不会继续遍历更多页面。SQL 偏移会独立于上游分页对暂存表进行分页:使用确定性的ORDER BY,按实际显示的行数推进,并在零行可显示时使用更窄的投影
brapi_raw_search 工具
noun(例如observations、calls、germplasm)以及原样提交至POST /search/{noun}的body;异步搜索会轮询至完成- 返回
kind(sync或async)、searchResultsDbId、result和suggestion;预览和暂存方式与brapi_raw_get相同,body.page/body.pageSize会将收集范围限制为请求的上游页面;当活动方言将该路由标记为失效时,返回search_endpoint_disabled
brapi://server/info 资源
default连接的方向信息信封,类型为application/json- 与不带参数调用
brapi_server_info时返回的有效载荷相同
brapi://calls 资源
default连接的功能配置:支持的服务及其 HTTP 方法和版本,以及作物- 反映上次加载时
/serverinfo+/calls返回的内容
brapi://study/{studyDbId} 资源
- 与在
default连接上调用brapi_get_study时返回的有效载荷相同 - 上游没有对应研究时返回
study_not_found
brapi://germplasm/{germplasmDbId} 资源
- 与在
default连接上调用brapi_get_germplasm时返回的有效载荷相同 - 上游没有对应种质时返回
germplasm_not_found
brapi://filters/{endpoint} 资源
- 与
brapi_describe_filters返回的有效载荷相同;端点不在目录中时返回unknown_endpoint - 列出
brapi://filters会为每个端点返回一个资源
brapi://variable/{observationVariableDbId} 资源
default连接上的/variables/{id}记录(性状、量表、方法、本体)- 上游没有对应变量时返回
variable_not_found
brapi_eda_study 提示词
- 参数:必填
studyDbId;可选alias - 返回一条用户消息:一份六步操作指南(概览、变量、覆盖情况、缺失数据、IQR 异常值、可选的谱系追溯),最后以包含推荐后续步骤的 Markdown 报告结束
brapi_meta_analysis 提示词
- 参数:必需的
germplasmDbIds(以逗号分隔)和traitName;可选的alias,用于多服务分析时每个别名运行一次 - 返回一条用户消息:包含七个步骤的操作指南(解析性状、发现研究、构建观测表、统一量表、按研究和跨研究进行汇总、可选的系谱追溯),并以一份报告收尾,报告中引用所用的每个数据框句柄或筛选映射
功能
基于 @cyanheads/mcp-ts-core 构建:支持 stdio 和 Streamable HTTP 传输、可插拔的身份验证(none / jwt / oauth)、可切换的存储(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1),以及结构化日志记录和可选的 OpenTelemetry 跟踪。
BrAPI 专属功能:
- 共享查找器契约:七种筛选查找器(studies、germplasm、variables、observations、images、locations、variants)接受
alias、loadLimit和extraFilters(键取自brapi_describe_filters),并返回results、hasMore、distributions和可选的dataframe句柄;results会在达到loadLimit或 24,000 字节时停止,以数组 JSON 或序列化转义行文本中先达到上限者为准;即使首个匹配行本身就超出预算,也会保留该行。truncated/shown/cap会报告截断情况 - Dataframe 溢出:当
results中的行数少于匹配行数时,查找器会将匹配集(继续分页获取其余结果,最多 50 页、50,000 行)暂存到 DuckDB 的df_<uuid>表中,并返回其句柄 - 方言适配器(
spec、brapi-test、breedbase、cassavabase、bms)会按连接检测,将 v2.1 复数筛选器转换为各服务器系列支持的形式,丢弃服务器忽略的筛选器,并在GET会缩小多值筛选器范围时切换为POST /search/{noun};可通过BRAPI_<ALIAS>_DIALECT固定方言 - 可通过命名别名同时连接多个服务,内置三个公共 Breedbase 服务;凭据按别名从环境变量解析,因此不会进入大模型上下文
- 支持能力感知的调用:每个连接的
/serverinfo+/calls配置会缓存,并在工具调用端点前进行检查;每个连接均设有并发上限,且会针对 429/5xx 错误进行指数退避重试
便于 Agent 使用的输出:
- 上游名称、标识符和辅助字段会以原样文本呈现。结构化值和生成的系谱图则保留原有语义
- 类型化失败:对于未注册且服务器未配置的别名,所有限定连接的工具和资源都会以
unknown_alias失败(已配置的别名会在首次使用时连接);如果服务器可能无法访问的基 URL 是私有或保留地址,则会以private_address_blocked失败,且不会缓存或注册任何内容;如果方言丢弃了筛选查找器收到的全部筛选器,则查找器会以all_filters_dropped失败,而不会扩大为不带筛选条件的查询;如果方言丢弃了所有请求研究对应的研究筛选器,brapi_build_phenotype_matrix会以dialect_all_filters_dropped失败 - ID 或筛选值为空或仅含空白字符时,会在输入架构验证阶段失败,而不会发送给上游;空白筛选值会扩大查询范围,空白 ID 会导致请求路径格式错误;空
text仍表示不应用文本筛选 - 每个查找器都会回显查询信息:
totalCount、returnedCount和appliedFilters;嵌入式 observation 查询会区分上游请求与客户端筛选条件,brapi_find_studies会单独列出客户端侧的locations。如果扫描提前停止,refinementHint会指向完整 dataframe,或建议使用更精细的筛选条件;空结果会附带notice,warnings会披露限制 - 优雅处理部分失败:
brapi_get_image会按图像返回errors[]和warnings[]行,而不是使整个批次失败 - 区分联合输出:
brapi_submit_observations会返回按mode(preview/apply)区分的结果,brapi_raw_search会报告kind,brapi_get_image会报告每张图像的source
使用数据框
当查找工具的内联 results 行数少于匹配行数时——loadLimit 或 24,000 字节的内联预算上限会先触发——响应会携带一个 dataframe 句柄:tableName、rowCount、columns、createdAt、expiresAt,以及服务器报告的 totalCount(如果有);当数据框包含的行数少于上游总数时,还会携带 truncated(若触发行数上限,还包括 maxRows);warnings 则会说明遍历停止的原因。为通过 SQL 标识符检查而重命名的列,会在 columnLegend 中映射回对应的上游键。
每个暂存数据框的响应——查找工具、因行数或字节上限而截短列表的 brapi_raw_get / brapi_raw_search、brapi_build_phenotype_matrix 和 brapi_export_genotype_matrix 返回的每个矩阵,以及因图或前沿预览被截短或省略已获取亲属而截短的 brapi_walk_pedigree——都会携带一个 notice,列出每个表、其行数和覆盖范围,并提示随后调用 brapi_dataframe_describe,然后调用 brapi_dataframe_query。在注册了 brapi_dataframe_export 的位置(设置了 BRAPI_EXPORT_DIR 的 stdio)也会提及它。对于查找工具,同一条提示还会说明 results 被哪个上限截短。
1. brapi_find_observations { studies: ["s-422"] }
→ leading rows inline + dataframe.tableName = "df_<uuid>" (when results holds fewer rows than matched)
2. brapi_dataframe_describe { dataframe: "df_<uuid>" }
→ schema + provenance (originating tool, baseUrl, query, expiry)
3. brapi_dataframe_query { sql: "SELECT germplasmName, value FROM df_<uuid> WHERE observationVariableDbId = 'V1' LIMIT 100" }
→ typed columns + bounded rows
数据框名称是能力令牌,而不是行级 ACL:同一会话或租户存储桶(参见部署形态)中持有名称的任何人都可以读取其中的行。来源记录会保留 BRAPI_DATASET_TTL_SECONDS 指定的时长(默认 24h);设置 BRAPI_CANVAS_DROP_ENABLED=true 可启用 brapi_dataframe_drop,以便显式清理。
开始使用
公共托管实例
公共实例可通过 https://brapi.caseyjhand.com/mcp 使用,无需安装。通过 Streamable HTTP 将任意 MCP 客户端指向该实例:
{
"mcpServers": {
"brapi-mcp-server": {
"type": "streamable-http",
"url": "https://brapi.caseyjhand.com/mcp"
}
}
}
自托管 / 本地
将以下内容添加到 MCP 客户端配置文件中。
{
"mcpServers": {
"brapi-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/brapi-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
或者使用 npx(无需 Bun):
{
"mcpServers": {
"brapi-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/brapi-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
或者使用 Docker:
{
"mcpServers": {
"brapi-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/brapi-mcp-server:latest"]
}
}
}
对于 Streamable HTTP,设置传输方式并启动服务:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
无需设置环境变量:内置别名(bti-cassava、bti-sweetpotato、bti-breedbase-demo)可直接连接,brapi_connect 则可在运行时接受任何其他 BrAPI v2 URL。对于需要登录的服务,请将凭据设为环境变量,避免密码、令牌和密钥进入大模型上下文(参见按别名配置凭据)。
前提条件
- Bun v1.4.0 或更高版本(或 Node.js v24+)。
@duckdb/node-api,作为常规依赖项安装,并带有适用于 macOS、Linux(glibc 和 musl)及 Windows 的 x64 和 arm64 预构建原生绑定。不支持 Cloudflare Workers。
安装
- 克隆仓库:
git clone https://github.com/cyanheads/brapi-mcp-server.git
- 进入目录:
cd brapi-mcp-server
- 安装依赖项:
bun install
- 配置环境:
cp .env.example .env
# edit .env if you need credentials or non-default settings
配置
所有变量均为可选。
| 变量 | 描述 | 默认值 |
|---|---|---|
BRAPI_DEFAULT_BASE_URL | default 别名的基础 URL(例如:https://test-server.brapi.org/brapi/v2)。 | — |
BRAPI_DEFAULT_* credentials | default 别名的一组凭据;参见各别名的凭据。 | — |
BRAPI_DEFAULT_API_KEY_HEADER | default 别名的 API 密钥标头,也是未指定标头的任何 api_key 身份验证的回退标头。 | Authorization |
BRAPI_BUILTIN_ALIASES_DISABLED | 要移除的内置别名,以逗号分隔(不区分大小写)。 | — |
BRAPI_LOAD_LIMIT | 查找工具的默认内联行数上限;24,000 字节的预算也会限制内联行数,当任一限制导致行数不足时,匹配集会溢出到 dataframe。 | 1000 |
BRAPI_PAGE_SIZE | 溢出分页遍历时上游的 pageSize。dataframe 上限为 pageSize × 50,最多 50,000 行。 | 1000 |
BRAPI_MAX_CONCURRENT_REQUESTS | 每个连接的并发上限。 | 4 |
BRAPI_RETRY_MAX_ATTEMPTS / BRAPI_RETRY_BASE_DELAY_MS | 遇到 429/5xx 和超时错误时的重试次数,以及指数退避的基础延迟。仅当调用的 50 s 上游截止时间仍允许再尝试一次时,超时请求才会重试。 | 3 / 500 |
BRAPI_REQUEST_TIMEOUT_MS | 每个请求的 HTTP 超时时间。一次工具调用发出的每个上游请求还共享从调用开始计时的 50 s 截止时间,因此服务器无响应时,调用会在 MCP 客户端默认的 60 s 请求超时之前以 Timeout 失败。 | 30000 |
BRAPI_COMPANION_TIMEOUT_MS | 非关键增强调用(外键查找、计数探测)的超时时间;这些调用也会跳过重试。 | 8000 |
BRAPI_SEARCH_POLL_TIMEOUT_MS / BRAPI_SEARCH_POLL_INTERVAL_MS | 异步 /search 轮询的预算和间隔;轮询也会在调用的 50 s 上游截止时间到达时停止。 | 60000 / 1000 |
BRAPI_DATASET_TTL_SECONDS | dataframe 来源信息的有效期(句柄的 expiresAt)。 | 86400 |
BRAPI_REFERENCE_CACHE_TTL_SECONDS | 缓存的能力配置和参考数据(计划、试验、地点、作物)的 TTL。 | 3600 |
BRAPI_ALLOW_PRIVATE_IPS | 允许 RFC 1918 / loopback 目标。仅用于开发。 | false |
BRAPI_SESSION_ISOLATION | 存在 MCP 会话时,将连接和默认画布限定在该会话范围内;false 则在整个租户范围内共享。参见部署形式。 | true |
BRAPI_ENABLE_WRITES | 功能标志。 注册 brapi_submit_observations。 | false |
BRAPI_CANVAS_DROP_ENABLED | 功能标志。 注册 brapi_dataframe_drop。 | false |
BRAPI_EXPORT_DIR | 功能标志。 brapi_dataframe_export 的输出目录;设置后会注册该工具,但仅限 stdio。 | — |
BRAPI_CANVAS_MAX_ROWS / BRAPI_CANVAS_QUERY_TIMEOUT_MS | brapi_dataframe_query 的响应行数上限和每次查询的超时时间。该上限不得超过框架的 CANVAS_DEFAULT_ROW_LIMIT(默认值为 10000);超过时启动会失败。 | 10000 / 30000 |
BRAPI_GENOTYPE_CALLS_MAX_PULL | 每次 brapi_find_genotype_calls 或 brapi_export_genotype_matrix 调用的上游调用上限。最大值为 500000。 | 100000 |
BRAPI_GENOTYPE_MATRIX_MAX_COLUMNS | 每个 brapi_export_genotype_matrix 矩阵的变异列上限。最大值为 500000。 | 10000 |
MCP_TRANSPORT_TYPE | 传输方式:stdio 或 http。 | stdio |
MCP_HTTP_PORT | HTTP 服务端口。 | 3010 |
MCP_SESSION_MODE | HTTP 会话模式。此服务要求使用 stateful(apply-mode 写入会通过会话确认,隔离也以会话为依据);如果解析为 stateless,HTTP 启动会失败。 | auto(解析为 stateful) |
MCP_AUTH_MODE | 身份验证方式:none、jwt 或 oauth。 | none |
MCP_REQUEST_STATE_KEY | 至少 32 字节的密钥,所有实例必须相同,用于密封确认轮次返回的 requestState;其他任何状态都会在处理程序运行前被拒绝。建议与 BRAPI_ENABLE_WRITES 配合使用。 | — |
MCP_LOG_LEVEL | 日志级别(debug、info、warning、error 等)。 | info |
LOG_TOOL_FAILURE_PAYLOADS | 记录每次失败工具调用的参数和结果(仅对键名进行脱敏)。 | false |
STORAGE_PROVIDER_TYPE | 存储后端:in-memory、filesystem、supabase、cloudflare-kv/r2/d1。 | in-memory |
OTEL_ENABLED | 启用 OpenTelemetry。 | false |
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT | 可选启用的 OTLP 日志导出端点;基础变量 OTEL_EXPORTER_OTLP_ENDPOINT 不会启用日志导出。 | — |
完整的可选覆盖项列表请参阅 .env.example。 |
每个别名的凭据
如果 Agent 未提供 baseUrl 和 auth,brapi_connect 会按以下顺序从环境变量中填入:
- Agent 输入,遵循下方的配对规则。
- 每个别名的环境变量:
BRAPI_<ALIAS>_*,转换为大写,并将连字符替换为下划线(my-server→BRAPI_MY_SERVER_*)。 - 内置别名:参见内置别名。
BRAPI_DEFAULT_BASE_URL,用于没有自己的 URL 或凭据的别名。
环境变量中的凭据只会发送到为其配置的服务:
- 别名的凭据会与其
BRAPI_<ALIAS>_BASE_URL配对,否则会与其已启用的内置 URL 配对。若调用方提供的baseUrl指向其他位置,则会报错auth_base_url_mismatch。没有自己的 URL 的凭据(包括因BRAPI_BUILTIN_ALIASES_DISABLED而禁用的内置别名遗留的凭据)会报错alias_base_url_unset,绝不会发送到BRAPI_DEFAULT_BASE_URL。 - 只有当解析出的 URL 是
BRAPI_DEFAULT_BASE_URL时,BRAPI_DEFAULT_*凭据才会附加。指向其他位置的别名会在没有身份验证的情况下连接,除非它有自己的凭据。如果未设置BRAPI_DEFAULT_BASE_URL,默认凭据会报错alias_base_url_unset。
URL 会在规范化主机名大小写、默认端口和末尾斜杠后进行比较。调用方提供的 auth 绝不会与环境变量中的凭据混用。
每个别名只能使用一种凭据类型,身份验证模式由已设置的字段决定。在同一别名中混用不同类型会引发 ValidationError。
| 已设置的变量 | 解析出的 mode |
|---|---|
_USERNAME + _PASSWORD | sgn(Breedbase /token 交换) |
_BEARER_TOKEN | bearer |
_API_KEY(+ 可选的 _API_KEY_HEADER) | api_key |
_OAUTH_CLIENT_ID + _OAUTH_CLIENT_SECRET(+ 可选的 _OAUTH_TOKEN_URL) | oauth2 |
| (均未设置) | none |
如果检测结果有误,BRAPI_<ALIAS>_DIALECT 可固定方言适配器(spec、brapi-test、breedbase、cassavabase、bms);设置为 auto 或留空则会自动检测。
# .env — attach write credentials to the built-in 'bti-cassava' alias
BRAPI_BTI_CASSAVA_USERNAME=alice
BRAPI_BTI_CASSAVA_PASSWORD=...
# (BASE_URL omitted — the built-in registry covers it)
# Static API key as alias 'prod'
BRAPI_PROD_BASE_URL=https://my-brapi.example.com/brapi/v2
BRAPI_PROD_API_KEY=...
BRAPI_PROD_API_KEY_HEADER=X-API-Key
随后,Agent 无需提供 baseUrl、auth,也无需在提示词中包含任何密钥,即可调用 brapi_connect({ alias: 'bti-cassava' });也可以跳过这次调用:任何使用 alias: 'bti-cassava' 的工具都会在首次使用时以相同方式连接。
内置别名
这些公开的 BrAPI v2 端点无需配置即可连接。其概览信息中包含 attribution 区块,提供许可证、引用和主页(Creative Commons Attribution)。
| 别名 | 上游 | 托管方 | 作物 | 备注 |
|---|---|---|---|---|
bti-cassava | cassavabase.org | Boyce Thompson Institute | 木薯 | NextGen Cassava |
bti-sweetpotato | sweetpotatobase.org | Boyce Thompson Institute | 甘薯 | |
bti-breedbase-demo | breedbase.org | Boyce Thompson Institute | 演示 | 仅含示例数据,用于入门和测试 |
注册表中仅包含已验证可匿名读取的服务。需要登录的服务(包括 Triticeae Toolbox(T3)的小麦、燕麦和大麦主机)需通过 BRAPI_<ALIAS>_BASE_URL 和凭据连接(参见 .env.example)。
BRAPI_<ALIAS>_BASE_URL 可覆盖内置 URL,例如通过 BRAPI_BTI_SWEETPOTATO_BASE_URL 将 bti-sweetpotato 指向预发布镜像。BRAPI_<ALIAS>_USERNAME 等变量可在内置 URL 上附加凭据;每个 Breedbase 实例都有自己的用户表,因此需要在每个实例上分别创建账号才能获得写入权限。BRAPI_BUILTIN_ALIASES_DISABLED=bti-cassava,bti-breedbase-demo 可移除相应条目。
**引用:**三个内置别名均引用 Morales 等人 2022 年发表的论文,“Breedbase: a digital ecosystem for modern plant breeding.” G3 12(7):jkac078。doi:10.1093/g3journal/jkac078。
运行服务
本地开发
-
构建并运行生产版本:
# One-time build bun run rebuild # Run the built server bun run start # transport from MCP_TRANSPORT_TYPE (stdio default) bun run start:stdio bun run start:http # Or run from source with hot reload bun --watch src/index.ts -
运行检查和测试:
bun run devcheck # Lint, format, typecheck, security, changelog sync bun run test # Vitest suite bun run lint:mcp # Validate MCP definitions
Docker
docker build -t brapi-mcp-server .
docker run --rm -p 3010:3010 brapi-mcp-server
镜像默认使用 HTTP 传输、stateful 会话模式,并将日志写入 /var/log/brapi-mcp-server。默认安装 OpenTelemetry 同级依赖;若要省略这些依赖,请使用 --build-arg OTEL_ENABLED=false 构建。
部署形态
状态范围按租户划分,默认也按 MCP 会话划分,分为两类:连接状态(已注册的别名和已交换的上游令牌)和数据框(df_<uuid> 表;同一存储区内,任何持有名称的人都可以使用)。以下三种配置决定这些存储区的范围:
| 形态 | 设置 | 隔离方式 | 适用场景 |
|---|---|---|---|
| 按会话(默认) | MCP_AUTH_MODE=none + HTTP 有状态模式 + BRAPI_SESSION_ISOLATION=true | 每个 MCP 会话都有自己的连接和画布。没有会话的请求共用一个租户级命名空间,因此 brapi_connect 会拒绝调用方提供的 auth,并返回 auth_session_required;无密钥连接和运维人员的环境凭据仍可使用。 | 无 SSO 的多用户托管 |
| 按用户凭据 | MCP_AUTH_MODE=jwt 或 oauth(+ HTTP 有状态模式) | 每位用户的 JWT tid 声明对应一个独立租户;启用隔离时,会话在该租户内进一步划分范围。 | 采用机构 SSO 的多用户托管;隔离性最强 |
| 共享工作区 | MCP_AUTH_MODE=none + BRAPI_SESSION_ISOLATION=false | 所有调用方共用一个租户的连接和画布。 | 一位研究人员使用共享的上游凭据运行多个并行 Agent |
Stdio 始终是单一会话。使用 MCP 协议修订版 2026-07-28 的客户端在任何传输方式下都不携带会话,因此除按用户凭据的形态外,这些客户端都会进入共享租户工作区;重新注册别名会更改所有这类调用方后续调用所指向的别名。
在未启用按用户身份验证的 HTTP 模式下,brapi_dataframe_describe 只有在请求拥有自己的会话范围画布时,才会在未提供名称的情况下列出数据框;brapi_dataframe_query 在所有形态下都会拒绝读取系统目录,因此,不知道某个 df_<uuid> 名称的调用方无法枚举其他调用方的表。
项目结构
| 目录 | 用途 |
|---|---|
src/index.ts | createApp() 入口点:注册工具(受各自功能标志控制)、资源和提示词,并初始化服务。 |
src/config | 服务端环境变量解析(Zod)、按别名解析凭据,以及内置别名注册表。 |
src/mcp-server/tools | 工具定义(*.tool.ts)和共享辅助函数。共 25 个工具,涵盖连接、检索、分析、写入和原始直通。 |
src/mcp-server/resources | 资源定义(*.resource.ts)。 |
src/mcp-server/prompts | 提示词定义(*.prompt.ts)。 |
src/services | BrAPI 客户端、方言适配器、筛选器目录、画布桥接、功能注册表、ISO 国家/地区解析器、本体解析器、参考数据缓存、服务端注册表。 |
tests/ | 与 src/ 结构对应的单元测试和集成测试。 |
开发指南
开发指南和架构规则请参阅 CLAUDE.md。简要说明:
- 处理程序抛出异常,框架负责捕获——工具逻辑中不要使用
try/catch - 使用
ctx.log记录日志,使用ctx.state存储租户范围的数据——不要使用console,也不要直接访问持久化存储 - 在
src/mcp-server/tools/definitions/index.ts的相应分组中添加新工具;src/index.ts会在各自的功能标志控制下组合这些分组 - 封装上游调用:校验原始数据 → 规范化 → 返回输出架构;绝不伪造缺失字段
贡献
欢迎提交问题。提交前请运行检查和测试:
bun run devcheck
bun run test
许可证
Apache-2.0 — 详情请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。