Skip to main content
Glama
bluesky050

tianyan-mcp-server

by bluesky050
README.md
# Tianyan MCP Server

> Server 公开八个 Tool,其中四个查询 Tool 只读。实验提交与期望值测量提交会创建远程任务,
> 受安全开关与 Host 确认约束;期望值提交默认仅预览。
<p align="center">
  <img src="docs/assets/tianyan-mcp-banner.svg" alt="Tianyan MCP Server 项目横幅">
</p>

只读查询并受控提交实验的 Streamable HTTP MCP Server。

当前 MVP 提供八个 Tool:

- `list_available_quantum_backends`:查询当前运行中的量子计算机和量子仿真机;
- `get_quantum_backend`:按 `id` 或 `code` 精确查询资源详情;
- `get_quantum_experiment_result`:按已有实验查询状态和结果,只读;
- `submit_quantum_experiment`:在受控条件下提交一条 QCIS 实验线路;
- `submit_quantum_experiment_batch`:在受控条件下批量提交 2–20 条 QCIS 实验线路;
- `estimate_quantum_expectation`:预览或提交单条制备线路的观测量测量任务;
- `batch_estimate_quantum_expectation`:多条制备线路使用同一个观测量,按输入顺序估计;
- `get_quantum_expectation_result`:凭完整任务清单查询期望值,只读。

## 前置条件

- Python 3.11 或更高版本;
- uv;
- 天衍云列表接口的网络访问能力;
- 实验结果查询和实验提交都还需要天衍云 SDK API 的网络访问能力,以及当前身份模式可用的 Tianyan SDK 凭证。

## 安装

```powershell
uv sync
```

依赖只安装到项目 `.venv`,无需全局安装 Python 包。

cqlib 固定为 GitHub 提交 `1d0a2c49ac32712d995f46147dfc5e3c4f4ac8e6` 的
`crates/binding-python`(包版本 `1.4.0b1`),由 `uv.lock` 锁定;不是旧版 PyPI cqlib。
从源码安装需要 Git、Rust 1.89 或更高版本和本机 C/C++ 构建工具。
Docker 构建阶段使用固定 Rust 1.93 镜像,最终运行镜像不包含 Rust 工具链。
不需要在 Windows 全局安装 Python 包。当前原生扩展验证环境为 Linux x86_64 / Python 3.11;
Windows 原生构建与现有部署文档使用的 ARM64 目标尚未验证;不能把本次 x86_64 构建等同于服务器部署验证。

## 期望值估计

计算路径:QCIS 制备线路 → 云端测量概率 → cqlib `Hamiltonian.expectation_probs()`。
不使用理想态向量代替设备测量,不更换原有 SDK 凭证和身份隔离逻辑。

单条 Tool `estimate_quantum_expectation` 的预览输入(MCP Tool 输入,不是 shell 命令):

```json
{
  "computer_code": "tianyan_sw",
  "circuit": "H Q1",
  "observable": [{"pauli": "X1", "coefficient": 1.0}],
  "name": "expectation-demo",
  "shots": 100,
  "dry_run": true
}
```

批量入口 `batch_estimate_quantum_expectation` 将 `circuit` 替换为
`"circuits": ["H Q1", "X Q1"]`,其余字段相同。所有线路使用同一个 `observable`。

- `X1`、`Y1`、`Z1` 对应物理 Q1;如 `"Z1 Z9"` 表示两个物理比特的乘积,恒等项写 `"I"`。
- 系数为有限实数,绝对值不超过 1000000;合并后的系数也受此上限约束。重复项合并,零项删除。
- 最多 8 条输入线路、16 个输入 Pauli 项、32 个观测量比特、16 个展开测量任务。
- 每个不同的非恒等项生成一条测量线路;不跨项分组。恒等项不提交任务。
- `shots` 为**每条实际测量线路**的采样次数(1..1000)。返回的 `total_shots` 是完整计划的采样次数,
  不是实际扣费或成功提交数量;部分提交以 `manifest.jobs` 中的状态为准。
- 输入仅接受 `I/H/X/Y/Z/X2P/X2M/Y2P/Y2M Qn`、`CZ Qn Qm`、`RX/RY/RZ Qn <数值弧度>`。
  不支持注释、参数表达式、输入测量、重置、动态控制或其他门;未知指令直接拒绝。
  观测量可以涉及制备线路中未操作的比特;设备是否支持该比特仍由上游校验。
- Z 直接测量;X 添加 H;Y 添加 RX(+π/2);再按物理编号升序添加 M。生成线路最长 20000 字符。
- 后端沿用原白名单,额外排除单振幅仿真器 `tianyan_sa`。

`dry_run=true` 不访问云端、不提交任务,返回 `measurements`、`job_count`、`total_shots` 和清单。
预览不保证后端在线,也不代表硬件提交已获授权。Host 必须展示后端、生成线路、任务数与总 shots,
取得用户确认后才能传 `dry_run=false`。硬件提交仍需服务端开关与 `allow_hardware=true` 同时允许。
两个提交 Tool 均标记为非只读、有副作用、非幂等。

实际提交按顺序执行,首次失败即停止:`submitted` 保留 `query_id`,`rejected` 表示明确拒绝,
`unknown` 表示无法确认是否已受理,后续项为 `not_submitted`。不得自动重试未知任务或重提整批。

完整保存返回的 `manifest`,查询时调用 `get_quantum_expectation_result`,输入为
`{"manifest": <原样返回的完整清单对象>}`。清单是版本化、无凭证的显式输入,不是签名证明;
每次查询仍使用当前调用者身份访问上游,不依赖服务进程内状态。

查询每个任务一次,不轮询、不提交新任务;按原线路索引返回:

| 状态 | 含义 |
|---|---|
| `completed` | 所需测量均已完成且校验通过,`value` 为期望值 |
| `processing` | 至少一个任务仍在处理,`value=null` |
| `incomplete_submission` | 存在未成功提交的测量项,无法计算完整观测量 |
| `query_error` | 查询或内部计算出错,保留错误码,不判定为设备任务失败 |
| `invalid_result` | 测量头、概率或维度无效,不返回估计值 |

计算前检查二进制键、位宽、有限概率、[0,1] 范围及概率和(容差 1e-6),不静默归一化。
按 `resultStatus` 首行的物理比特标识重排,列 0 按最低有效位解释;缺失或冲突时拒绝计算。
此约定已通过合成数据的非对称、非连续编号测试;天衍真实设备映射仍需单独批准的最小实测。
结果不包含完整逐次测量记录,不提供未经计算的标准差、置信区间或扣费金额。

固定版本的 `Statevector.expectation(Y)` 在离线对照中发现符号差异;本功能不调用该方法。
Y 基变换以独立标准矩阵为测试对照,实际估计只调用已验证的 `expectation_probs()`。

## 启动 Streamable HTTP

HTTP 认证随 `TIANYAN_IDENTITY_MODE` 而变化,不能把三种模式的 Header 或服务端环境变量混用:

- 仅 `single_user` HTTP 模式使用 Server 端静态 MCP API Key;
- `multi_tenant`:每位用户使用自己的 MCP API Key,并通过账号路由绑定 SDK Open ID;
- `direct_sdk`:Host 发送 SDK Open ID;它不要求且拒绝 `TIANYAN_MCP_API_KEY`,Host 配置见
  [direct_sdk Host 配置](#direct_sdk-受控网络部署)。

以下启动示例仅适用于 `single_user`;只在当前 PowerShell 进程设置 API Key,不要写入代码、README
或提交到 Git:

```powershell
$env:TIANYAN_IDENTITY_MODE = 'single_user'
$env:TIANYAN_MCP_API_KEY = 'replace-with-at-least-32-characters'
uv run tianyan-mcp-http
```

默认 MCP Endpoint:

```text
http://127.0.0.1:8000/mcp
```

Client Header 也必须与身份模式匹配:

| 身份模式 | 入站 Header |
|---|---|
| `single_user` | `Authorization: Bearer <api-key>` |
| `multi_tenant` | `Authorization: Bearer <tenant-mcp-api-key>` |
| `direct_sdk` | `Authorization: Bearer <TIANYAN_SDK_OPEN_ID>` |

默认只监听 loopback。应用自身不终止 TLS,也不提供公网部署能力。

## 环境变量

| 名称 | 默认值 | 说明 |
|---|---|---|
| `TIANYAN_IDENTITY_MODE` | 无(HTTP 必填) | HTTP 身份模式;可选 `single_user`、`multi_tenant` 或 `direct_sdk`。stdio 未设置时默认 `single_user` |
| `TIANYAN_MCP_API_KEY` | 无 | 仅 `single_user` HTTP 模式必填,去除首尾空白后至少 32 字符;`direct_sdk` 拒绝此变量 |
| `TIANYAN_DIRECT_SDK_FINGERPRINT_KEY` | 无 | 仅 `direct_sdk`:Server 端至少 32 字节的指纹密钥,不能交给 Host |
| `TIANYAN_MCP_ALLOWED_ORIGINS` | 空 | 逗号分隔的精确 Origin;空值拒绝所有带 Origin 的请求 |
| `TIANYAN_MCP_ALLOWED_HOSTS` | `127.0.0.1,localhost,::1` | 逗号分隔的主机名,不包含端口 |
| `TIANYAN_HTTP_TIMEOUT_SECONDS` | `10` | 天衍云请求超时,范围 `(0, 60]` 秒 |
| `TIANYAN_MCP_HOST` | `127.0.0.1` | ASGI 监听地址 |
| `TIANYAN_MCP_PORT` | `8000` | ASGI 监听端口 |
| `TIANYAN_LIVE_TEST` | `0` | 只有值为 `1` 时才启用真实只读 Smoke Test |

`TIANYAN_MCP_ALLOWED_ORIGINS` 不支持 `*`。浏览器请求携带 `Origin` 时,必须与白名单完全匹配;非浏览器 MCP Client 未携带 `Origin` 时可继续认证。

## 健康检查

`/healthz` 不要求 Bearer API Key,且不会调用天衍云:

```powershell
Invoke-WebRequest -UseBasicParsing -Uri 'http://127.0.0.1:8000/healthz'
```

## 本地 stdio 调试

stdio 模式不要求 `TIANYAN_MCP_API_KEY`,仅用于本地进程集成:

```powershell
uv run tianyan-mcp-stdio
```

## 测试

默认测试不访问网络:

```powershell
uv run ruff format --check .
uv run ruff check .
uv run pyright
uv run pytest --cov=tianyan_mcp --cov-report=term-missing --cov-fail-under=90
```

只有在明确需要验证天衍云真实只读接口时,才在当前 PowerShell 进程显式启用:

```powershell
$env:TIANYAN_LIVE_TEST = '1'
uv run pytest tests/test_live.py -q
```

真实测试只执行列表查询和按返回资源 `id` 查询详情,不调用写接口。

## HTTPS 边界

应用只提供 HTTP。正式环境必须在 Nginx、云负载均衡或 API 网关终止 TLS,并显式配置允许的 Host 与 Origin。当前项目不负责域名、证书或公网部署。

## 能力边界

- 仅支持量子计算机和量子仿真机;
- 列表只返回 `status=0` 的运行中资源;
- 详情查询可以返回校准中或升级中的已知资源;
- 不包含 HPC、天衍-P2000、任务取消和资源修改;受控的 QCIS 实验提交是仅有的写入操作。
- 不转发 MCP 调用方的 `Authorization`、Cookie 或其他凭证到天衍云。

## 实验结果查询(只读)

`get_quantum_experiment_result` 是第三个只读 Tool,用于查询已有实验的状态和结果,不会提交、修改或重跑实验。
它有两个输入:`query_id`(已有实验的数字字符串)和 `include_result_status`(严格布尔值,默认 `false`)。下面只是
MCP Tool 输入示例,不是 shell 命令,也不会提交工作;其中的 query ID 是占位符,不能替代真实返回的 ID:

```json
{
  "query_id": "replace-with-an-existing-query-id",
  "include_result_status": false
}
```

上游状态码只接受整数 `0` 或 `1`:`status=1` 返回 `processing`,表示实验仍在处理中;`status=0` 返回
`completed`,并包含 `probability` 与 `experiment_task_id`。默认会裁剪完整的 `result_status` 测量数据;只有将
`include_result_status` 设为 `true` 时才返回它,因为完整测量结果可能很大。Tool 不轮询,也不自动重试:处理中时由
调用方稍后再次查询,单次查询只执行所需的只读请求。

该 Tool 与提交 Tool 复用当前身份模式的凭证和上游访问路径。`direct_sdk` 模式复用 MCP Host 当前请求提供的 SDK
Open ID,并由 Server 隔离对应的短期 Token;SDK Open ID 不会作为调用方凭证转发给天衍云。结果查询和实验提交均使用固定
的天衍云生产域名 `https://qc.zdxlz.com`,调用方不能控制上游 URL、Host 或请求 Header。

查询 Tool 的 MCP annotations 为 `readOnlyHint=true`、`destructiveHint=false`、`idempotentHint=true`、
`openWorldHint=true`;三个查询 Tool 都是只读;`submit_quantum_experiment` 与
`submit_quantum_experiment_batch` 都是受控写入 Tool。

## 受控实验提交

除已有的三个只读 Tool `list_available_quantum_backends`、`get_quantum_backend` 与
`get_quantum_experiment_result` 外,Server 还提供
`submit_quantum_experiment` 与 `submit_quantum_experiment_batch`。前者提交一条 QCIS 线路,后者以一次上游
请求提交 2–20 条 QCIS 线路;它们都会创建远程任务、可能消耗天衍云资源,且均不是幂等操作,调用失败后不能
把重试当作安全行为。

### Server 进程配置与认证边界(仅 `single_user`)

以下认证边界仅适用于 `single_user`。在启动 Server 的进程中设置 SDK 凭证和硬件总开关。下面的占位符不是可用密钥,禁止将真实值写入
README、代码、测试、日志或 Git:

```powershell
# 通过受控 Secret 注入 TIANYAN_SDK_OPEN_ID;不要在文档或命令历史中赋值。
$env:TIANYAN_ALLOW_HARDWARE_SUBMISSION = 'false'
```

```text
TIANYAN_MCP_API_KEY authenticates Agent -> MCP Server.
TIANYAN_SDK_OPEN_ID authenticates MCP Server -> Tianyan SDK API.
The Agent must never receive TIANYAN_SDK_OPEN_ID or the returned SDK Token.
```

`TIANYAN_ALLOW_HARDWARE_SUBMISSION` 仅接受严格的小写 `true` 或 `false`,默认 `false`。缺少 SDK 凭证不会阻止 HTTP 或 stdio Server 启动,
但调用 `get_quantum_experiment_result`、`submit_quantum_experiment` 或 `submit_quantum_experiment_batch` 时都会安全失败。SDK 登录属于 Server 内部实现,
不注册为 Agent 可调用的 Tool;也不会转发 Agent 的 `Authorization`、Cookie 或其他凭证给天衍云。
`direct_sdk` 改由 MCP Host 配置持有并逐请求传递 SDK Open ID;模型和 Tool 参数仍不会接收 SDK Open ID。

### Tool 合同

`submit_quantum_experiment` 有四个必填输入和两个可选输入:

- `computer_code`:必填;目标后端代码,只允许下方九个白名单后端及硬件别名。
- `circuit`:必填;一条 QCIS 线路,不能为空、不含 U+0000,最大 20,000 个字符。
- `name`:必填;实验名称,去除首尾空白后长度为 1–100。
- `shots`:必填;采样次数,必须为整数且 `1 <= shots <= 1000`。
- `lab_name`:可选;实验集合名称。提供时去除首尾空白后长度为 1–100;省略或传入 `null` 时,上游请求完全不发送 `lab_name` 字段。空字符串或仅包含空白不会被当作省略,而会被拒绝。
- `allow_hardware`:可选;是否显式确认真实硬件提交,默认 `false`。

`submit_quantum_experiment_batch` 使用相同的 `computer_code`、`name`、`shots`、`lab_name` 和
`allow_hardware` 合同;将单条 `circuit` 替换为必填的 `circuits` 数组。数组必须包含 2–20 条 QCIS 线路,
每条线路均遵守单条线路的字符限制。返回的 `query_ids` 与输入 `circuits` 保持相同顺序且数量完全相等。

白名单包含四个量子计算机:`tianyan176`、`tianyan176-2`、`tianyan24`、`tianyan504`;以及五个
模拟器:`tianyan_sw`、`tianyan_s`、`tianyan_tn`、`tianyan_sa`、`tianyan_swn`。硬件还可使用
`tianyan-176`、`tianyan-176-2`、`tianyan-24`、`tianyan-504` 作为提交别名。

上游请求字段被固定为 QCIS(`language=qcis`)、普通优先级(`priority=0`)和校验开启
(`is_verify=true`);调用方不能覆盖这些字段。上游 `lab_id` 固定为空字符串,其实际平台语义为
“待实测”。

模拟器提交不需要硬件开关。真实硬件提交必须同时满足:Server 的
`TIANYAN_ALLOW_HARDWARE_SUBMISSION=true`、Tool 的 `allow_hardware=true`,以及 Host 在调用前向用户展示
后端、线路名称、可选实验集合名称(如有)与 shots 并取得确认。默认配置禁止真实硬件写入。

提交 POST 不自动重试。网络超时、连接错误、5xx 或无法解析的成功响应都会报告“结果未知”:天衍云
可能已经接收了实验,应先在平台核查,不能直接重复提交。

### 测试与真实调用边界

默认测试不访问天衍云,也不会提交实验。`TIANYAN_LIVE_TEST=1` 仍然只执行只读 smoke test:仅列表查询
和按返回的资源 ID 查询详情,不调用 SDK 登录或提交接口。正常 quick-start 路径不包含任何可执行的真实
写入命令;真实写入测试需要独立开关、逐次用户批准,并不属于本项目的默认流程。

## 多租户生产部署(单主机)

共享部署必须显式设置 `TIANYAN_IDENTITY_MODE=multi_tenant`。此模式仅用于 Streamable HTTP:每位用户
使用自己的 MCP API Key,并且各自绑定的 SDK Open ID 只会在服务端加密保存。`TIANYAN_MCP_API_KEY` 和
`TIANYAN_SDK_OPEN_ID` 是单用户模式变量;它们在 `multi_tenant` 模式中不得存在。

多租户服务需要一条绝对路径的 SQLite 数据库,以及两份彼此独立的服务器密钥材料:

| 配置 | 用途 |
|---|---|
| `TIANYAN_DATABASE_PATH` | SQLite 文件的绝对路径;持久化租户、API Key 摘要、加密后的 SDK 凭据和审计记录 |
| `TIANYAN_API_KEY_PEPPER` | 仅用于验证 MCP API Key 摘要的 Pepper,不写入 SQLite |
| `TIANYAN_CREDENTIAL_ENCRYPTION_KEY_VERSION` | 当前 SDK 凭据加密密钥版本 |
| `TIANYAN_CREDENTIAL_ENCRYPTION_KEY_V<version>` | 对应版本的 Base64 编码 32 字节凭据加密密钥 |

在受控密钥管理系统中生成独立的高熵 Pepper 和 32 字节加密密钥,再由 systemd credentials、容器 Secret
或等价的进程级 Secret 注入方式交给服务。不要在终端、Shell 历史、README、工单、日志或 Git 中打印或
粘贴这些值。数据库备份不能替代这两份密钥材料的独立备份。

应用仅监听 loopback;Nginx 负责 HTTPS 终止和公网入口。部署前复制并按本机证书、域名和代理策略审查
[`docs/deployment/nginx-multi-tenant.conf.example`](docs/deployment/nginx-multi-tenant.conf.example)。公网仅
应暴露 `/mcp`、`/account/sdk-credential` 和 `/healthz`,再代理到 `127.0.0.1:8000`。
Nginx 将上游 Host 固定为 `127.0.0.1`,使其符合服务默认的 `TIANYAN_MCP_ALLOWED_HOSTS`;不要把未经验证的公网 Host 透传给应用。

### CTyunOS ARM64 内网测试部署

复用现有 `nginx-test` 容器、使用 `/mnt/sdc/MCPserver` 持久化目录的测试服务器,按
[`docs/deployment/ctyunos-arm64-test-deployment.txt`](docs/deployment/ctyunos-arm64-test-deployment.txt)
执行。该手册只适用于端口 `30002` 已限制为可信内网访问的 HTTP 测试环境,不用于正式生产开放。
正式开放前仍须增加 HTTPS,并重新审查访问控制、证书、备份和运维流程。

如果首次镜像构建失败,保留失败现场且不覆盖已有 app。新的已校验归档解压到
`/mnt/sdc/MCPserver/releases/$RELEASE_COMMIT`,只从本次完整 Git 提交 SHA 对应的隔离目录运行 Compose;
旧归档、运行时密钥、SQLite、备份和原 Nginx 配置均保持不变。

### `direct_sdk` 受控网络部署

`multi_tenant` 的管理员创建用户和用户绑定 SDK Open ID 流程仍然有效。另一条明确的
`TIANYAN_IDENTITY_MODE=direct_sdk` 路径面向受控网络测试:每个 MCP Host 调用直接在 Header
中携带自己的 SDK Open ID,Server 以该值的不可逆指纹隔离短期 SDK Token。此模式无需创建用户或绑定账号,
不写入 SQLite;它没有管理员、数据库或 account 路由可供用户操作。

Server 必须仍只监听 loopback,并由受限网络中的既有 Nginx 代理 `/mcp`、
`/account/sdk-credential` 和 `/healthz` 到 `127.0.0.1:8000`。账号路由在 `direct_sdk` 模式中
即使通过认证也返回 404;保留该 Nginx 精确路由是为了不影响已有代理配置,而不是开放账号接口。
HTTP 仅可用于受控网络测试,**不是公网生产安全基线**;不要将 loopback 约束、Nginx 或内网访问控制
误解为 TLS、证书、审计或公网隔离的替代品。

运营者仅在受保护的服务器运行时文件中配置 `TIANYAN_DIRECT_SDK_FINGERPRINT_KEY`:它是新生成的
32 字节服务端指纹密钥,绝不打印、发给 Host 或写入示例。切换时保留既有 SQLite、API Key Pepper、
凭据加密密钥和备份;详见 CTyunOS 手册中的无覆盖切换与回滚步骤。`direct_sdk` 不接受
`TIANYAN_MCP_API_KEY` 或服务端 `TIANYAN_SDK_OPEN_ID` 环境变量。

MCP Host 配置只使用受控网络的通用占位符和调用者自己的 SDK Open ID:

```json
{
  "url": "http://<restricted-network-host>:<port>/mcp",
  "headers": {
    "Authorization": "Bearer <TIANYAN_SDK_OPEN_ID>"
  }
}
```

该 Header 只用于 `direct_sdk` 的入站身份识别,Server 不会把它作为 MCP 调用方 Authorization
转发给天衍云。不得在服务端环境变量、Shell 历史、日志或文档中设置真实 SDK Open ID。

当前上游登录与实验提交地址固定为天衍云生产环境,调用者必须使用生产环境的“连接密钥/SDK Open ID”;
测试环境密钥不兼容,会被生产登录接口拒绝。更换凭据时只需更新 MCP Host 的 `Authorization` Header
并重新连接,无需修改服务器环境变量或重新部署。

回滚时,管理员将受保护运行时文件恢复为 `TIANYAN_IDENTITY_MODE=multi_tenant`,移除仅用于
direct SDK 的指纹密钥,然后只重建 MCP 容器;不要删除 SQLite、重建 Pepper 或加密密钥、清理备份,
也不要重建 Nginx 容器。

### 真实调用与受控写入测试

`TIANYAN_LIVE_TEST=1 继续只读`:它只验证列表与详情查询,不登录 SDK,也不提交实验。
`TIANYAN_LIVE_WRITE_TEST=1` 仅标识独立的受控写入测试策略,不能作为 quick-start 或自动化发布步骤。
所有真实提交测试都必须逐次由 Host 向用户展示请求并取得批准,且提交 POST 不自动重试。只有真实硬件提交
额外要求 Server 的 `TIANYAN_ALLOW_HARDWARE_SUBMISSION=true` 和 Tool 显式 `allow_hardware=true`;
模拟器提交保持 `TIANYAN_ALLOW_HARDWARE_SUBMISSION=false` 和 `allow_hardware=false`。本文不提供可执行的
真实写入或实验提交命令。提交后结果未知时先到平台核查;已存在的实验可使用只读结果查询 Tool 查看状态。

当前网络边界下,发布文件从公网开发机复制到已连接 VPN 的虚拟机,再通过网页堡垒机把归档和对应
`.sha256` 两个文件原样上传到服务器 `/mnt/sdc/MCPserver/deploy`。不能使用公网开发机直连服务器的
`scp` 作为本环境主流程;上传后必须先按手册用完整提交 SHA 检查两个普通文件的名称和最终落点。

### 管理员与用户流程

管理员只在服务器本机运行 `tianyan-mcp-admin`。使用 `create-user` 创建租户时,CLI 只显示一次新 MCP
API Key;通过受控渠道交给该用户,随后不应再记录或请求该明文。`list-users` 不显示 Key、SDK Open ID、
密文或 Token。

用户在自己的受信任客户端运行 `tianyan-mcp-client configure`,按交互提示输入 HTTPS 服务地址、自己的 MCP
API Key 和 SDK Open ID;SDK Open ID 使用隐藏输入,不会被 CLI 持久化或回显。随后将 MCP API Key 配置到
用户自己的 MCP 客户端。`tianyan-mcp-client status` 只显示是否已绑定,`remove` 只移除当前用户自己的绑定。

发生泄露、人员变更或凭据替换时,管理员在服务器本机使用 `tianyan-mcp-admin rotate-key` 或 `revoke-key`,
并确认目标租户和操作。轮换会立即废止旧 Key 并只显示一次替换 Key;撤销不会删除审计历史。禁用用户用于
临时或长期停止访问,重新启用前应完成权限核验。

### 在线备份、恢复验证与迁移

`tianyan-mcp-admin backup` 使用 SQLite 在线备份生成一致性快照,并要求管理员显式确认目标文件。备份文件
包含加密凭据但不包含用于解密的服务器密钥;将 SQLite 快照、凭据加密密钥和 API Key Pepper 以不同访问控制
和不同介质保存。

恢复前先在隔离环境中复制快照并验证 SQLite 完整性、迁移版本和抽样凭据可否用对应密钥解密;确认租户、
已撤销 Key 和审计记录都符合预期后,才安排维护窗口切换服务数据库。不要通过删除凭据、降级为明文或跳过
迁移来强行启动。升级服务版本前先完成在线备份;应用启动时只会执行版本化 SQLite 迁移,失败时应保持服务
停止并从备份与日志诊断问题。

TDQS

A4.3/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a distinct purpose: listing backends, getting a specific backend's details, and submitting an experiment. There is no overlap or ambiguity between them.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun pattern: list_available_quantum_backends, get_quantum_backend, submit_quantum_experiment. This makes the naming predictable and clear.

Tool Count4/5

With only 3 tools, the server is on the smaller end but still covers the primary actions needed for the domain. It is slightly thin but not problematically so.

Completeness2/5

The server supports listing backends, getting backend details, and submitting experiments, but there is no way to track experiment status, retrieve results, or cancel a submission. This leaves a significant gap in the experiment lifecycle.

Maintenance

ActivityActive
ResponsivenessNo issues