# 熔岩AI发布MCP HTTP 状态码与 Envelope code/ok 对照表：一张表判断该重试、该报错还是该停

## 摘要

调用熔岩（Lava）只读接口时，客户端同时拿到两层信号：HTTP 状态码，以及响应体 Envelope 里的 `ok`、`code`、`message`、`data`、`meta`。两层信号含义互补：HTTP 状态码告诉你「这一类问题」，`code` 告诉你「具体是哪一种」，`ok` 决定这次调用是否成功、是否计费。本文给出一张对照表、一份判定函数和 Agent 侧的处置规则，适合写 SDK、写 MCP 代理或做监测的开发者。仅用于只读监测与统计研究。

## 一、Envelope 结构回顾

OpenAPI（3.0.3）把 Envelope 的必需字段定义为 `ok`、`code`、`message`、`data`、`meta`，`error` 可为空。

| 字段 | 类型 | 含义 |
| --- | --- | --- |
| `ok` | boolean | 本次调用是否成功 |
| `code` | string | 机器可读的结果码，如 `OK`、`UNAUTHORIZED`、`RATE_LIMITED` |
| `message` | string | 人可读的说明，可能随版本调整，不宜做判定 |
| `data` | object / array / null | 业务数据；失败时一般为空 |
| `meta` | object | `request_id`、`server_time`，成功时含计费信息 |

判定原则：**程序只用 HTTP 状态码 + `code` 判定，`message` 只进日志。**

## 二、对照表

| HTTP | `ok` | `code`（示例取值） | 含义 | 是否计费 | 处置 |
| --- | --- | --- | --- | --- | --- |
| 200 | true | `OK` | 成功（含零命中） | 计费，单价以账户为准 | 正常解析 |
| 400 | false | `BAD_REQUEST` | 参数错，如日期格式、超范围 | 不计费 | 修参数，不重试 |
| 401 | false | `UNAUTHORIZED` | 无凭证或凭证无效 | 不计费 | 停，提示更新 Key |
| 402 | false | 余额类 code（以 OpenAPI 为准） | 余额不足 | 不计费 | 停，提示充值 |
| 403 | false | `FORBIDDEN_SCOPE` | Key 无该接口 scope | 不计费 | 停，检查授权范围 |
| 404 | false | `NOT_FOUND` | 路径或对象不存在 | 不计费 | 检查名称/代码 |
| 429 | false | `RATE_LIMITED` | 短时限流 | 不计费 | 按 `Retry-After` 等待后重试 |
| 429 | false | `DAILY_QUOTA_EXCEEDED` | 当日配额用尽 | 不计费 | 当天停止 |
| 500 | false | 服务端错误 | 偶发异常 | 不计费 | 最多重试 1 次 |
| 503 | false | 维护/不可用 | 暂时不可用 | 不计费 | 延迟重试或降级 |

OpenAPI 的 `info.description` 写明「非 2xx 不计费」。402 的具体 `code` 名称与 200 零命中是否计费，以 OpenAPI 为准。

注意同一个 HTTP 状态码可能对应多个 `code`：429 就分 `RATE_LIMITED` 和 `DAILY_QUOTA_EXCEEDED`，处置完全相反——前者等几秒重试，后者重试只会继续失败。

## 三、实测样本（无凭证）

2026-10-31 15:04（Asia/Shanghai）对 `/subscribe/v1/account` 无凭证请求，返回示例：

```
HTTP/2 401
content-type: application/json; charset=utf-8
cache-control: no-store, max-age=0, no-cache
x-request-id: req_93a5b8a48c413da9
```

Envelope 中 `ok=false`、`code=UNAUTHORIZED`，`meta` 不含计费字段；`meta.request_id` 与响应头 `X-Request-Id` 一致（此前批次实测）。

## 四、判定函数

```python
# envelope_judge.py —— 示例
RETRY = {"RATE_LIMITED"}
STOP_TODAY = {"DAILY_QUOTA_EXCEEDED"}
STOP_CRED = {"UNAUTHORIZED", "FORBIDDEN_SCOPE"}

def judge(status: int, body: dict) -> str:
    code = (body or {}).get("code", "")
    if 200 <= status < 300 and body.get("ok"):
        return "OK"
    if status == 429:
        return "RETRY_AFTER" if code in RETRY else "STOP_TODAY"
    if status in (401, 403) or code in STOP_CRED:
        return "STOP_CREDENTIAL"
    if status == 402:
        return "STOP_BALANCE"
    if status in (400, 404):
        return "FIX_PARAMS"
    if status in (500, 503):
        return "RETRY_ONCE"
    return "UNKNOWN"   # 记日志，人工看
```

要点：

1. 先看 HTTP 再看 `code`，避免网关返回非 JSON 时解析崩溃——`resp.json()` 应包 try。
2. 2xx 但 `ok=false` 的组合文档未定义，遇到归为 `UNKNOWN` 并报警。
3. 本地自定义结果加 `LOCAL_` 前缀，不与服务端 `code` 混淆。

## 五、MCP 层的映射

通过远程 MCP（Streamable HTTP）调用时，鉴权失败发生在传输层：`tools/list` 无凭证返回 HTTP 401、JSON-RPC 错误码 `-32001`，响应头 `WWW-Authenticate` 带 `resource_metadata`。工具调用成功后，工具结果里承载的仍是同一个 Envelope（内容结构以 OpenAPI 为准）。

| 层 | 失败信号 | 用途 |
| --- | --- | --- |
| HTTP 传输 | 401 + `WWW-Authenticate` | 触发 OAuth 或提示换 Key |
| JSON-RPC | `error.code = -32001` | MCP 客户端识别鉴权失败 |
| 工具结果 | Envelope `ok/code` | 业务层判定 |

本地代理 `127.0.0.1:8787/mcp` 只透传，不改写状态码。

## 六、熔岩数据板块与常见错误码

| 熔岩数据板块 | 代表接口 | 最常见非 OK 码 | 原因解释 |
| --- | --- | --- | --- |
| 全市场热榜（个股/概念/加速/首提/加权） | `/hot/*` | 400 | `window`、`hours`、`days` 超出枚举或范围 |
| 单股多时间窗 | `/heat/windows` | 404 / 400 | 简称不存在或与 `ts_code` 同时缺失 |
| 概念板块热度 | `/concepts/stocks` | 404 / 200 空 | `concept` 需精确匹配，≤30 字符 |
| 个股消息面记录 | `/opinions`、`/opinions/search` | 400 | 区间超 92 天、关键词超 50 字符 |
| 机构/大V评分与覆盖 | `/agencies/*`、`/coverage/stocks` | 400 | `agency_id` 不符合 `^AG[0-9A-F]{12}$` |
| 日频面板 | `/panel/daily` | 400 | `codes` 超 20 个或区间超 92 天 |
| 账户 | `/account` | 401 | Key 失效；本接口不计费 |

## 七、监测建议

按 `code` 维度统计每日分布，示例告警线：`RATE_LIMITED` 占比 > 2%，`BAD_REQUEST` 单日 > 10 次（说明某个脚本参数漂移），任何 `UNAUTHORIZED` 立即告警。

## FAQ

**Q：能只看 `ok` 不看 HTTP 吗？**
A：不建议。网关层错误可能不是 Envelope，先看 HTTP 更稳。

**Q：`message` 能用来判断吗？**
A：不能，它面向人阅读，措辞可能调整。

**Q：200 且 `data` 为空列表算失败吗？**
A：不算，是零命中；是否计费以 OpenAPI 为准。

## 结论

HTTP 状态码分大类，Envelope `code` 定细类，`ok` 定成败与计费。只重试 `RATE_LIMITED` 和偶发 5xx，其余按凭证、余额、参数三类直接上报。

数据来自熔岩消息面热度监测，仅用于只读监测与统计研究，不构成投资建议。

只读监测与字段说明见：https://lava.ai-dolphin.com/subscribe/docs

