内容
# Kiki
MCP 服务器,用于**确定性的生物数据检索** — NCBI Virus (通过 gget)、NCBI 核苷酸/组装 (E-utilities)、Ensembl (直接 REST + 固定 SQL) 和 UniProt (REST API)。
代理调用 Kiki 工具来查询元数据、统计记录、检索数据集或映射标识符。每次成功的响应都使用带有确定性 `query_id`、`result` 和 `provenance` 块的 **QueryManifest** 信封。错误返回稳定的机器可读代码。
---
## 安装
```bash
git clone <你的仓库网址>
cd kiki
python3 -m venv venv
source venv/bin/activate
pip install -e ".[dev]"
kiki serve --help
```
**贡献:**参见 [CONTRIBUTING.md](CONTRIBUTING.md) 获取架构、编码规则和 PR 工作流程。
---
## 运行服务器
### HTTP(默认)
```bash
kiki serve --transport http --host 127.0.0.1 --port 8000
```
服务器网址:`http://127.0.0.1:8000/mcp`
### stdio(Cursor / Claude Desktop)
```bash
kiki serve --transport stdio
```
**Cursor(stdio):**
```json
{
"mcpServers": {
"kiki": {
"command": "/绝对路径/to/kiki/venv/bin/kiki",
"args": ["serve", "--transport", "stdio"]
}
}
}
```
**Cursor / 脚本(HTTP):**
```json
{
"mcpServers": {
"kiki": {
"url": "http://127.0.0.1:8000/mcp"
}
}
}
```
**Claude Desktop** — 与 `~/Library/Application Support/Claude/claude_desktop_config.json` 中的 stdio 配置相同。
---
## 工具参考
Kiki 在五个数据域中提供了 **20 种工具**。使用安全的查询/计数工具进行探索;仅在您打算将文件写入磁盘时使用数据集工具。
| # | 工具 | 来源 | 目的 | 是否写入文件? |
|---|------|--------|---------|---------------|
| 1 | [`get_virus_metadata`](#1-get_virus_metadata) | NCBI Virus / gget | 分页元数据搜索 + 内联预览 | 否 |
| 2 | [`count_virus_sequences`](#2-count_virus_sequences) | NCBI Virus / gget | 统计元数据记录 | 否 |
| 3 | [`retrieve_virus_dataset`](#3-retrieve_virus_dataset) | NCBI Virus / gget | 完整病毒基因组数据集(FASTA/CSV/JSONL) | **是** |
| 4 | [`get_nucleotide_sequence`](#4-get_nucleotide_sequence) | NCBI E-utilities | 单个访问编号 FASTA(GenBank/RefSeq) | 否 |
| 5 | [`get_nucleotide_metadata`](#5-get_nucleotide_metadata) | NCBI E-utilities | 核苷酸记录摘要 | 否 |
| 6 | [`get_assembly_metadata`](#6-get_assembly_metadata) | NCBI E-utilities | 基因组组装(GCF/GCA)元数据 | 否 |
| 7 | [`retrieve_nucleotide_batch`](#7-retrieve_nucleotide_batch) | NCBI E-utilities | 多访问编号 FASTA(+ 可选文件) | 可选 |
| 8 | [`submit_blast_search`](#8-submit_blast_search) | NCBI BLAST URL API | 提交 blastn/blastp 搜索 → RID | 否 |
| 9 | [`get_blast_results`](#9-get_blast_results) | NCBI BLAST URL API | 轮询一次以获取结构化命中 | 否 |
| 10 | [`get_sequence`](#10-get_sequence) | Ensembl REST | 单个基因/转录本 FASTA | 否 |
| 11 | [`retrieve_sequence_batch`](#11-retrieve_sequence_batch) | Ensembl REST | 多 ID 序列获取(+ 可选 FASTA 文件) | 可选 |
| 12 | [`search_genes`](#12-search_genes) | Ensembl SQL | 文本术语基因搜索 | 否 |
| 13 | [`get_gene_info`](#13-get_gene_info) | Ensembl REST | 基因/转录本元数据 | 否 |
| 14 | [`get_reference`](#14-get_reference) | Ensembl FTP | 参考基因组 FTP 元数据 | 否 |
| 15 | [`search_proteins`](#15-search_proteins) | UniProt REST | 分页蛋白质搜索 + 内联预览 | 否 |
| 16 | [`count_proteins`](#16-count_proteins) | UniProt REST | 统计匹配蛋白质 | 否 |
| 17 | [`get_protein`](#17-get_protein) | UniProt REST | 单个访问编号查找 | 否 |
| 18 | [`retrieve_protein_dataset`](#18-retrieve_protein_dataset) | UniProt REST | 批量 FASTA 下载 | **是** |
| 19 | [`map_protein_ids`](#19-map_protein_ids) | UniProt REST | 跨数据库 ID 映射 | 否 |
| 20 | [`get_query_history`](#20-get_query_history) | Kiki 审计日志 | 检查先前的 QueryManifest 运行 | 否 |
### 共享行为
**响应形状** — 所有工具都返回 QueryManifest:
```json
{
"tool": "get_virus_metadata",
"success": true,
"query_id": "a1b2c3d4e5f6g7h8",
"query": { "type": "accession", "value": "NC_045512.2" },
"result": { },
"provenance": { "engine": "...", "operation": "...", "filters_applied": [] },
"message": "人类可读摘要。"
}
```
**预设** — 大多数搜索/计数/数据集工具接受一个 `preset` 字符串,该字符串合并了精选的默认值。显式参数始终覆盖预设值。参见 [病毒预设](#virus-presets) 和 [UniProt 预设](#uniprot-presets)。
**数据集下载** — `retrieve_virus_dataset` 和 `retrieve_protein_dataset` 需要 `"confirm_download": true`。输出默认进入 `kiki_output/`,或设置 `outfolder` / `KIKI_OUTPUT_DIR`。
**环境变量**
| 变量 | 影响 |
|----------|--------|
| `KIKI_OUTPUT_DIR` | 覆盖默认下载目录(自动回退到 `/tmp/kiki_output` 如果不可写) |
| `KIKI_AUDIT_DIR` | 覆盖清单审计日志目录(默认:`./kiki_audit`,自动回退到 `/tmp/kiki_audit` 如果不可写) |
| `KIKI_RECORD_HISTORY` | 设置为 `false` 以禁用审计日志写入(默认:`true`) |
| `KIKI_ENSEMBL_RELEASE` | 为所有 Ensembl 工具固定 Ensembl 版本(默认 `114`) |
| `NCBI_API_KEY` | 可选 — 转发到 gget(病毒)和 NCBI BLAST URL API |
| `NCBI_BLAST_EMAIL` | 可选的 NCBI BLAST 联系邮箱(始终发送 `tool=kiki-mcp`) |
在只读托管运行时(例如 Horizon),审计日志和数据集下载会自动回退到 `/tmp/kiki_audit` 和 `/tmp/kiki_output`。工具调用永远不会因为审计日志失败而失败。
**审计和重现性** — 病毒工具响应包括丰富的 `provenance`:
- `filter_application` — 每个过滤器阶段(`ncbi_virus_api`、`deferred_local`、`local_metadata_filter`)并在 gget 在本地应用过滤器时提供人类可读的解释
- `command_summary` — gget 的 `command_summary.txt` 摘录(数据集下载)
- `audit_record` — 指向追加的本地历史文件指针
- `query_id` — 规范化参数的确定性哈希;相同的输入 → 相同的 `query_id`
使用 **`get_query_history`** 通过 `query_id` 检查先前的运行或列出按 `tool` 的最近条目。
**类型错误**
| 代码 | 含义 |
|------|---------|
| `QUERY_TOO_BROAD` | 大型分类/生物体,无收窄过滤器 |
| `CONFIRM_DOWNLOAD_REQUIRED` | 在未调用 `confirm_download=true` 的情况下调用数据集工具 |
| `INVALID_DATE_RANGE` / `INVALID_DATE_FORMAT` | 错误的日期过滤器(病毒) |
| `INVALID_SEQ_LENGTH_RANGE` | 最小长度 > 最大长度 |
| `PRESET_NOT_FOUND` | 未知的预设名称 |
| `INVALID_PARAMETER` | 缺少必填输入或无效过滤器 |
| `UPSTREAM_ERROR` | gget 或 UniProt API 失败 |
| `NOT_FOUND` | UniProt 访问编号未找到 |
---
## NCBI Virus 工具
由 [gget](https://github.com/pachterlab/gget) 支持 [NCBI Virus](https://www.ncbi.nlm.nih.gov/labs/virus/)。大型分类群(例如 SARS-CoV-2 `2697049`)需要收窄过滤器,除非查询特定访问编号。
### 1. `get_virus_metadata`
使用完整的 gget 分页查询病毒元数据。返回最多 `preview_limit` 条记录和 `total_available`。**不下载序列。**
**参数**
| 参数 | 类型 | 默认值 | 描述 |
|-----------|------|---------|-------------|
| `query` | 字符串 | — | 分类群名称/ID 或访问编号 |
| `is_accession` | 布尔值 | `false` | 将 `query` 视为访问编号 |
| `preset` | 字符串 | — | 命名预设(见下文) |
| `preview_limit` | 整数 | `10` | 最大内联记录数(最大 100) |
| `host` | 字符串 | — | 宿主生物体名称或 taxid |
| `geographic_location` | 字符串 | — | 例如 `Africa`、`USA` |
| `annotated` | 布尔值 | — | 仅限注释序列 |
| `complete_only` | 布尔值 | — | 仅限完整基因组 |
| `refseq_only` | 布尔值 | — | 仅限 RefSeq 记录 |
| `min_release_date` | 字符串 | — | `YYYY-MM-DD` |
**示例**
按访问编号(最安全的起点):
```json
{ "query": "NC_045512.2", "is_accession": true }
```
按分类群并过滤:
```json
{
"query": "186538",
"host": "Homo sapiens",
"complete_only": true,
"preview_limit": 5
}
```
使用预设:
```json
{ "preset": "sars_cov2_ref_genome" }
```
**结果字段:** `returned`、`total_available`、`records[]`
---
### 2. `count_virus_sequences`
使用与 `get_virus_metadata` 相同的 gget 分页路径统计元数据记录,无内联记录。支持元数据兼容的过滤器和预设。
**参数** — 与 `get_virus_metadata` 相同的过滤器(无 `preview_limit`)。
**示例**
```json
{ "preset": "sars_cov2_ref_genome" }
```
```json
{
"query": "186538",
"host": "Homo sapiens",
"complete_only": true,
"geographic_location": "Africa"
}
```
**结果字段:** `count`、`pagination_complete`
> 对于需要数据集专有过滤器(收集日期、序列长度)的计数,请使用 `retrieve_virus_dataset` 并读取 `dataset_manifest.accession_count`。
---
### 3. `retrieve_virus_dataset`
完整的 `gget.virus` 管道:元数据过滤、分页、序列下载、CSV/FASTA/JSONL 输出。**需要 `confirm_download: true`。
**参数**
| 参数 | 类型 | 默认值 | 描述 |
|-----------|------|---------|-------------|
| `query` | 字符串 | — | 分类群、taxid、访问编号、空格分隔的访问编号或访问编号列表文件路径 |
| `is_accession` | 布尔值 | `false` | 访问编号模式 |
| `preset` | 字符串 | — | 命名预设 |
| `confirm_download` | 布尔值 | `false` | **必须为 `true`** 才能运行 |
| `download_all_accessions` | 布尔值 | `false` | 跨所有病毒访问编号过滤(需要收窄过滤器) |
| `is_sars_cov2` | 布尔值 | `false` | NCBI 缓存的 SARS-CoV-2 下载 |
| `is_alphainfluenza` | 布尔值 | `false` | NCBI 缓存的甲型流感下载 |
| `outfolder` | 字符串 | — | 输出目录 |
| `host` | 字符串 | — | 宿主过滤器 |
| `geographic_location` | 字符串 | — | 位置过滤器 |
| `annotated` | 布尔值 | — | 仅限注释 |
| `complete_only` | 布尔值 | — | 完整基因组(映射到 `nuc_completeness`) |
| `refseq_only` | 布尔值 | — | 仅限 RefSeq(映射到 `source_database`) |
| `min_release_date` | 字符串 | — | `YYYY-MM-DD` |
| `max_release_date` | 字符串 | — | `YYYY-MM-DD` |
| `min_collection_date` | 字符串 | — | `YYYY-MM-DD` |
| `max_collection_date` | 字符串 | — | `YYYY-MM-DD` |
| `min_seq_length` | 整数 | — | 最小核苷酸长度 |
| `max_seq_length` | 整数 | — | 最大核苷酸长度 |
| `min_gene_count` | 整数 | — | 最小基因数 |
| `max_gene_count` | 整数 | — | 最大基因数 |
| `max_gene_count` | 整数 | — | 最大基因数 |
| `nuc_completeness` | 字符串 | — | `complete` 或 `partial` |
| `has_proteins` | 字符串\|列表 | — | 例如 `"spike"` 或 `["spike", "ORF1ab"]` |
| `proteins_complete` | 布尔值 | `false` | 所有注释蛋白质完整 |
| `lab_passaged` | 布尔值 | — | 实验室传代样本 |
| `submitter_country` | 字符串 | — | 提交者国家 |
| `min_mature_peptide_count` | 整数 | — | 最小成熟肽数 |
| `max_mature_peptide_count` | 整数 | — | 最大成熟肽数 |
| `min_protein_count` | 整数 | — | 最小蛋白质数 |
| `max_protein_count` | 整数 | — | 最大蛋白质数 |
| `max_ambiguous_chars` | 整数 | — | 最大模糊碱基(N) |
| `segment` | 字符串\|列表 | — | 例如 `"HA"` 或 `["HA", "NA"]` |
| `vaccine_strain` | 布尔值 | — | 疫苗株过滤器 |
| `source_database` | 字符串 | — | `genbank` 或 `refseq` |
| `lineage` | 字符串\|列表 | — | SARS-CoV-2 谱系 |
| `isolate` | 字符串 | — | 分离株名称 |
| `genotype` | 字符串\|列表 | — | 基因型 |
| `isolation_source` | 字符串 | — | 分离源 |
| `env_source` | 字符串\|列表 | — | 环境源 |
| `submitter_name` | 字符串 | — | 提交者名称 |
| `submitter_institution` | 字符串 | — | 提交者机构 |
| `gen_mol_type` | 字符串 | — | 基因分子类型 |
| `genbank_metadata` | 布尔值 | `false` | 获取 GenBank 元数据 CSV |
| `genbank_batch_size` | 整数 | — | GenBank 批次大小(默认 200) |
| `provirus` | 布尔值 | — | 前病毒过滤器 |
| `keep_temp` | 布尔值 | `false` | 保留中间文件 |
| `verbose` | 布尔值 | `true` | gget 进度输出 |
查看 `gget_virus_docs.md` 获取完整的 gget.virus 文档。
**示例**
埃博拉监测数据集:
```json
{
"query": "186538",
"confirm_download": true,
"host": "Homo sapiens",
"nuc_completeness": "complete",
"min_collection_date": "2014-01-01",
"geographic_location": "Africa"
}
```
SARS-CoV-2 参考基因组(缓存):
```json
{
"query": "NC_045512.2",
"is_accession": true,
"is_sars_cov2": true,
"confirm_download": true
}
```
使用预设:
```json
{ "preset": "ebola_human_complete_since_2014", "confirm_download": true }
```
**结果字段:** `returned`、`output_dir`、`files[]`、`dataset_manifest`、`failures`
> 始终检查 `result.failures` 和 `command_summary.txt` — gget 在下载批次失败时写入 `FAILED OPERATIONS - RETRY COMMANDS` 部分。
---
### 病毒预设
| 预设 | 兼容工具 | 描述 |
|--------|------------------|-------------|
| `sars_cov2_ref_genome` | 元数据、计数、数据集 | SARS-CoV-2 参考访问编号 `NC_045512.2` |
| `ebola_human_complete_africa` | 元数据、计数 | 非洲完整埃博拉人类基因组 |
| `ebola_human_complete_since_2014` | 数据集 | 2014 年以来非洲完整埃博拉人类基因组 |
| `sars_cov2_human_complete` | 数据集 | ≥29kb + GenBank 元数据的 SARS-CoV-2 完整人类基因组 |
| `influenza_a_human_complete` | 数据集 | ≤15kb + GenBank 元数据的甲型流感完整人类基因组 |
---
## NCBI 基因组 / 核苷酸工具(E-utilities)
灵感来自 [Anthropic 生物学代理博客](blog.md):代理需要一个**确定性层**,而不是手动组装 E-utilities。 这些工具包装 NCBI E-utilities 以实现**直接访问编号** — 安全启动基因组测序记录的最安全起点。
当您需要 NCBI Virus 门户过滤器(分类群、宿主、地理、收集日期)时,请使用上面的**病毒工具**。当您拥有已知访问编号或参考组装时,请在此使用**核苷酸工具**。
### 4. `get_nucleotide_sequence`
通过 `efetch` 获取一个 GenBank/RefSeq 核苷酸记录的解析 FASTA。
**示例**
```json
{ "accession": "NC_045512.2" }
```
**结果字段:** `returned`、`records[]`(`header`、`sequence`、`length`)
---
### 5. `get_nucleotide_metadata`
记录摘要(标题、长度、生物体、taxid),无需下载序列。
**示例**
```json
{ "accession": "NC_045512.2" }
```
---
### 6. `get_assembly_metadata`
GCF/GCA 访问编号的基因组组装元数据(名称、taxid、FTP 路径)。
**示例**
```json
{ "accession": "GCF_000001405.40" }
```
---
### 7. `retrieve_nucleotide_batch`
内联获取最多 50 个访问编号。传递 `confirm_download=true` 将 `sequences.fasta` 写入磁盘。
**示例**
```json
{ "accessions": ["NC_045512.2"] }
```
---
## NCBI BLAST 工具(URL API)
通过 [NCBI BLAST 通用 URL API](https://blast.ncbi.nlm.nih.gov/doc/blast-help/urlapi.html) 进行两步序列相似性搜索。代理提交搜索,等待,然后轮询结构化 JSON2 命中的结果 — 无需浏览器或手工 E-utilities 粘合。
**v1 数据库(精选允许列表):** `core_nt`、`refseq_rna`(blastn);`swissprot`、`refseq_protein`(blastp)。`nt` 和 `nr` 被排除以避免大型数据库的超时和部分结果。
**代理工作流程**
1. `submit_blast_search` → 保存 `rid`
2. 等待 `retry_after_seconds`(≥60s,根据 NCBI 政策)
3. `get_blast_results` → 如果 `status: "running"`,等待并重试
4. 当 `status: "ready"` 时,使用 `hits[]`(访问编号、e-value、身份、比对坐标)
RID 在 ~24 小时后过期。Kiki 记录每次调用的审计清单,但不保留 RID。命中列表可能会随着 NCBI 更新数据库构建而漂移。
### 8. `submit_blast_search`
**示例(blastn vs core_nt)**
```json
{
"program": "blastn",
"query": "NC_045512.2",
"database": "core_nt",
"hitlist_size": 25
}
```
**结果字段:** `rid`、`rtoe_seconds`、`retry_after_seconds`、`program`、`database`、`query_type`
---
### 9. `get_blast_results`
**示例**
```json
{ "rid": "ABCDEF12" }
```
**结果字段:** `status`(`running`\|`ready`\|`failed`)、`hits[]`、`num_hits`、`search_stats`、`retry_after_seconds`(当运行中)
---
## Ensembl 工具(固定版本)
通过 **直接 Ensembl API** — REST (`e{release}.rest.ensembl.org`)、公共 SQL 搜索和确定性 FTP URL 检索基因和参考基因组。所有工具默认为 **`KIKI_ENSEMBL_RELEASE`**(默认 `114`),因此相同输入针对该版本快照返回相同结果。
显式传递 `release` 以覆盖。
### 10. `get_sequence`
获取一个 Ensembl 基因或转录本 ID。设置 `translate=true` 获取氨基酸序列;`isoforms=true` 获取一个基因的所有转录本同工型。
**示例**
```json
{ "ensembl_id": "ENSG00000012048" }
```
翻译后的蛋白质序列:
```json
{ "ensembl_id": "ENST00000357654", "translate": true }
```
---
### 11. `retrieve_sequence_batch`
一次调用中获取多个 Ensembl ID(最大 50 个)。返回内联 FASTA 记录。传递 `confirm_download=true` 还将 `sequences.fasta` 写入磁盘。
**示例**
```json
{
"ensembl_ids": ["ENSG00000012048", "ENSG00000139618"],
"isoforms": false
}
```
---
### 12. `search_genes`
按自由文本术语搜索 Ensembl。`species` 使用 `genus_species` 格式(例如 `homo_sapiens`)。
**示例**
```json
{ "searchwords": "BRCA1", "species": "homo_sapiens", "limit": 5 }
```
多术语 OR 搜索:
```json
{ "searchwords": ["TP53", "p53"], "species": "homo_sapiens", "andor": "or" }
```
---
### 13. `get_gene_info`
来自 Ensembl REST 查找(固定版本)的单个或多个 Ensembl ID 的元数据。
**示例**
```json
{ "ensembl_id": "ENSG00000012048", "pdb": false }
```
---
### 14. `get_reference`
参考基因组注释 FTP 链接(GTF、cDNA、DNA 等)— 仅限元数据,不下载。
**示例**
```json
{ "species": "homo_sapiens", "which": "gtf" }
```
列出可用物种:
```json
{ "list_species": true }
```
---
## UniProt 工具
由 [UniProt REST API](https://rest.uniprot.org) 提供支持。所有搜索/计数/数据集工具默认设置为 **`reviewed:true`**(Swiss-Prot)。传递 `"include_unreviewed": true` 以包含 TrEMBL。大型生物体(例如人类 `9606`)需要缩小过滤器以进行数据集下载。
### 15. `search_proteins`
使用游标分页搜索 UniProtKB。返回最多 `preview_limit` 条摘要记录,以及 `total_available`。**不下载序列。**
**参数**
| 参数 | 类型 | 默认值 | 描述 |
|-----------|------|---------|-------------|
| `query` | 字符串 | — | 原始 UniProt 查询字符串 |
| `preset` | 字符串 | — | 命名预设 |
| `reviewed_only` | 布尔值 | `true` | 追加 `(reviewed:true)` |
| `include_unreviewed` | 布尔值 | `false` | 跳过已审阅过滤器 |
| `organism_id` | 字符串 | — | NCBI 分类法 ID |
| `gene` | 字符串 | — | 基因名称 |
| `protein_name` | 字符串 | — | 蛋白质名称 |
| `accession` | 字符串 | — | UniProt 登录号 |
| `length_min` | 整数 | — | 最小序列长度 |
| `length_max` | 整数 | — | 最大序列长度 |
| `preview_limit` | 整数 | `10` | 最大内联记录数(最大 100) |
结构化过滤器与 `query` 进行 AND 组合。您可以单独使用 `query`、结构化过滤器或两者结合使用。
**示例**
原始查询:
```json
{ "query": "insulin AND organism_id:9606" }
```
结构化过滤器:
```json
{ "organism_id": "9606", "gene": "INS" }
```
使用预设:
```json
{ "preset": "sars_cov2_spike", "preview_limit": 5 }
```
**结果字段:** `returned`, `total_available`, `records[]` (accession, protein_name, gene_names, organism, length, reviewed)
---
### 16. `count_proteins`
通过 `X-Total-Results` (单个 API 请求)计数 UniProtKB 条目。与 `search_proteins` 相同的过滤器。
**示例**
```json
{ "preset": "sars_cov2_spike" }
```
```json
{ "organism_id": "9606", "gene": "TP53" }
```
**结果字段:** `count`, `pagination_complete`
---
### 17. `get_protein`
通过登录号检索单个 UniProtKB 条目。不需要搜索过滤器。
**参数**
| 参数 | 类型 | 默认值 | 描述 |
|-----------|------|---------|-------------|
| `accession` | 字符串 | **必填** | UniProt 登录号(例如 `P01308`) |
| `format` | 字符串 | `json` | `json`, `fasta`, `txt`, `xml`, `gff` 或 `rdf` |
**示例**
摘要 JSON:
```json
{ "accession": "P01308" }
```
原始 FASTA:
```json
{ "accession": "P01308", "format": "fasta" }
```
**结果字段(json):** `accession`, `record`
**结果字段(其他格式):** `accession`, `format`, `content`
---
### 18. `retrieve_protein_dataset`
将所有匹配的蛋白质序列作为 FASTA 下载到磁盘。遍历每个结果页面。**需要 `confirm_download: true` 。**
**参数**
| 参数 | 类型 | 默认值 | 描述 |
|-----------|------|---------|-------------|
| `query` | 字符串 | — | 原始 UniProt 查询 |
| `preset` | 字符串 | — | 命名预设 |
| `confirm_download` | 布尔值 | `false` | **必须为 `true`** 才能运行 |
| `reviewed_only` | 布尔值 | `true` | 追加 `(reviewed:true)` |
| `include_unreviewed` | 布尔值 | `false` | 跳过已审阅过滤器 |
| `organism_id` | 字符串 | — | NCBI 分类法 ID |
| `gene` | 字符串 | — | 基因名称 |
| `protein_name` | 字符串 | — | 蛋白质名称 |
| `accession` | 字符串 | — | UniProt 登录号 |
| `length_min` | 整数 | — | 最小序列长度 |
| `length_max` | 整数 | — | 最大序列长度 |
| `outfolder` | 字符串 | — | 输出目录 |
**示例**
```json
{ "preset": "ebola_vp35", "confirm_download": true }
```
```json
{
"organism_id": "9606",
"gene": "INS",
"confirm_download": true
}
```
**结果字段:** `returned`, `expected_count`, `output_dir`, `files[]`, `fasta_path`
---
### 19. `map_protein_ids`
通过 UniProt ID 映射服务在数据库之间映射蛋白质标识符。
**参数**
| 参数 | 类型 | 默认值 | 描述 |
|-----------|------|---------|-------------|
| `ids` | 字符串列表 | **必填** | 要映射的 ID(最多 5000) |
| `from_db` | 字符串 | **必填** | 源数据库 |
| `to_db` | 字符串 | `UniProtKB` | 目标数据库 |
| `list_databases` | 布尔值 | `false` | 返回支持的字段而不是映射 |
常见的 `from_db` / `to_db` 值:`UniProtKB_AC-ID`, `Gene_Name`, `RefSeq_Protein`, `EMBL-Protein`, `UniProtKB`, `UniProtKB-Swiss-Prot`.
**示例**
登录号 → 基因名称:
```json
{
"ids": ["P01308"],
"from_db": "UniProtKB_AC-ID",
"to_db": "Gene_Name"
}
```
列出支持的数据库:
```json
{ "ids": [], "from_db": "UniProtKB_AC-ID", "list_databases": true }
```
**结果字段:** `job_id`, `mapped_count`, `mappings[]` (from/to 对),`failed[]`
---
### 20. `get_query_history`
检查存储在本地审计日志(`KIKI_AUDIT_DIR/manifest_history.jsonl`)中的先前工具运行记录。每个成功的工具调用都会记录其完整的 QueryManifest,以便代理可以验证 *如何* 生成结果。
**参数**
| 参数 | 类型 | 默认值 | 描述 |
|-----------|------|---------|-------------|
| `query_id` | 字符串 | — | 返回此确定性查询哈希的最近记录 |
| `tool` | 字符串 | — | 按工具名称过滤列表 |
| `limit` | 整数 | `20` | 列表时的最大记录数(最大 500) |
**示例**
查找先前的运行:
```json
{ "query_id": "a1b2c3d4e5f6g7h8" }
```
列出最近的病毒计数:
```json
{ "tool": "count_virus_sequences", "limit": 10 }
```
**结果字段:** `count`, `entries[]` (每个记录包含 `recorded_at`, `query_id`, `tool`, 完整的 `manifest`)
---
### UniProt 预设
| 预设 | 描述 |
|--------|-------------|
| `sars_cov2_spike` | SARS-CoV-2 刺突蛋白(已审阅) |
| `sars_cov2_nsp12` | SARS-CoV-2 nsp12(已审阅) |
| `ebola_vp35` | Ebola VP35(已审阅) |
| `influenza_a_ha` | 甲型流感病毒血凝素(已审阅) |
| `human_insulin` | 人类胰岛素(`INS`, 已审阅) |
| `human_tp53` | 人类 TP53(已审阅) |
---
## VirBench 公共子集(准确性证明)
灵感来自 [Anthropic 生物学代理博客](blog.md) 和 VirBench (Nasri 等,2026)。Kiki 附带一个 **公共查询子集**,包含地面真实计数(包括博客中的 Ebola 示例,预计 **266**)。
```bash
# 安全的烟雾基准测试(4 次查询 × 3 次运行)- 在 pytest 中运行
python -m kiki.benchmark --safe-only
# 可选:博客数据集查询(下载序列,速度慢)
KIKI_RUN_INTEGRATION_BENCHMARK=1 pytest tests/test_virbench_subset.py -m integration
```
报告:`kiki_output/virbench/*.json` 和 `*.md`。参见 [kiki/benchmark/README.md](kiki/benchmark/README.md)。
---
```bash
# 终端 1
kiki serve --transport http --port 8000
# 终端 2
python client.py # 烟雾测试:get_virus_metadata
pytest # 完整的测试套件(大多数测试不需要服务器)
```
```python
import asyncio
from fastmcp import Client
client = Client("http://127.0.0.1:8000/mcp")
async def main():
async with client:
tools = await client.list_tools()
print([t.name for t in tools])
# 所有 20 个工具:
# get_virus_metadata, count_virus_sequences, retrieve_virus_dataset,
# get_sequence, retrieve_sequence_batch, search_genes, get_gene_info, get_reference,
# search_proteins, count_proteins, get_protein,
# retrieve_protein_dataset, map_protein_ids, get_query_history
# 病毒元数据
r = await client.call_tool(
"get_virus_metadata",
{"query": "NC_045512.2", "is_accession": True},
)
print(r.data)
# UniProt 计数
r = await client.call_tool(
"count_proteins",
{"preset": "sars_cov2_spike"},
)
print(r.data)
asyncio.run(main())
```
---
## 部署到 Prefect Horizon
[Horizon](https://horizon.prefect.io) 是由 FastMCP 团队管理的 MCP 主机服务。
**入口点:** `server.py:mcp` (仓库根目录 - 不是 `kiki/server.py:mcp`)
```bash
fastmcp inspect server.py:mcp
```
1. 将仓库推送到 GitHub
2. 进入 [horizon.prefect.io](https://horizon.prefect.io) → 连接仓库
3. 设置入口点 `server.py:mcp`,部署
4. URL: `https://YOUR-SERVER-NAME.fastmcp.app/mcp`
**托管测试的安全工具:** `get_virus_metadata`, `count_virus_sequences`, `get_nucleotide_sequence`, `get_nucleotide_metadata`, `get_assembly_metadata`, `search_genes`, `get_gene_info`, `get_sequence`, `get_reference`, `search_proteins`, `count_proteins`, `get_protein`, `map_protein_ids`
**数据集工具** (`retrieve_virus_dataset`, `retrieve_protein_dataset`)写入容器文件系统 - 优先使用本地/自托管运行,除非您添加持久存储。
---
## 项目布局
```
kiki/
server.py # FastMCP 应用
cli.py # kiki serve
tools/ # MCP 工具定义(病毒 + ensembl + uniprot)
services/ # gget + UniProt REST 客户端
models/ # QueryManifest
query/ # 标准化,验证,预设
errors.py # KikiError 代码
tests/
server.py # Horizon 入口点(导入 kiki.server.mcp)
```
参见 `notebook.md` 获取路线图,`gget_virus_docs.md` 获取完整的 gget.virus 参数参考。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器