首页 / 开发者文档 / GraphQL

GraphQL 操作文档

用一条查询按需取字段,适合后端服务、数据脚本与 BI 直接调用。与 MCP 工具共用同一套 Token 和数据口径。

端点 POST /graphql 鉴权 Bearer Token 查询字段 13 个 只读 不支持写入

1. 这是什么

GraphQL 是同一个数据底座上的第二种取数方式。你写一段查询,声明要哪些字段、传什么参数,服务端按需返回,不需要为每个接口记不同的 URL 和参数格式。

用 MCP,当……

调用方是大模型客户端(WorkBuddy、Claude、Cursor 等),希望模型自己挑工具、自己组合,不需要你写代码。

用 GraphQL,当……

调用方是你自己的后端、脚本或 BI,字段固定、需要稳定契约,想一次拿到结果、自己控制解析和落库。

两者的关系:底层是同一批上游接口、同一套计费和权限,只是入口不同。已经接入 MCP 的账号无需额外开通,同一个 Token 直接可用。

2. 端点与鉴权

项目值
端点https://mcp.yushanshuju.com/graphql
方法POST
Content-Typeapplication/json
鉴权头Authorization: Bearer <TOKEN>
Token 来源在 控制台 → Token 管理 中创建,与 MCP 通用

3. 快速开始

curl

终端执行
curl -s https://mcp.yushanshuju.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $YUSHAN_TOKEN" \
  -d '{"query":"{ queryCompanyBasicInfo(entname: \"深圳市腾讯计算机系统有限公司\") }"}'

Python

graphql_demo.py
import json, os, httpx

TOKEN = os.environ["YUSHAN_TOKEN"]
URL = "https://mcp.yushanshuju.com/graphql"

QUERY = """
query Basic($name: String!) {
  queryCompanyBasicInfo(entname: $name)
}
"""

with httpx.Client(timeout=30) as c:
    r = c.post(
        URL,
        headers={"Authorization": f"Bearer {TOKEN}"},
        json={"query": QUERY, "variables": {"name": "深圳市腾讯计算机系统有限公司"}},
    )
    r.raise_for_status()
    payload = r.json()

raw = payload["data"]["queryCompanyBasicInfo"]
inner = json.loads(raw)                       # 返回的是 JSON 字符串,再解析一次
basic = inner["retdata"]["BASIC"]
print(basic["ENTNAME"], basic["FRNAME"])      # 内层字段名是全大写

JavaScript

fetch
const res = await fetch("https://mcp.yushanshuju.com/graphql", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${process.env.YUSHAN_TOKEN}`,
  },
  body: JSON.stringify({
    query: `query { fuzzyQueryCompany(keyWord: "腾讯") }`,
  }),
});
const body = await res.json();
const data = JSON.parse(body.data.fuzzyQueryCompany);
console.log(data.retdata);
建议用变量传参(如上面 Python 示例的 $name),不要拼接字符串,避免企业名里的引号和特殊字符破坏查询语法。

4. 字段速查

共 13 个查询字段,全部只读,没有 Mutation。返回值均为 JSON 字符串,解析方式见下一节。

字段参数返回内容
fuzzyQueryCompanykeyWord关键词模糊搜索,拿到工商全称,是后续查询的起点
queryCompanyBasicInfoentname信用代码、法人、注册资本、成立日期、经营范围、地址
queryCompanyOverseasInvestmentsentName对外投资的目标公司、认缴金额、持股比例
queryCompanyChangeRecordsentName注册资本、法人、股东、经营范围等历次变更记录
queryCompanyCourtLitigationRelatedInfoname涉诉案件、案由、当事人角色、裁判结果
queryCompanyAbnormalBusinessOperationkeyWord经营异常名录:列入原因、决定机关、移出记录
queryCompanyTrademarkListentName商标名称、类别、注册号、法律状态
queryCompanyPatentListentName专利申请号、名称、类型、授权状态
queryCompanySoftwareCopyrightInfoentName软著登记号、软件名称、版本、登记日期
verifyCompanyNameAndPresidentoperName, entName法人两要素核验,返回 0 一致 / 1 不一致
queryCompanySeriousViolationBlacklistentname / creditcode / regno / orgcode / enttype严重违法失信名单:列入与移出日期、事由、决定机关,附企业档案。前四个至少传一个
queryCompanyGlobalInfobusinessName / businessRegistrationNumber境外与离岸主体:注册状态、管辖区、税号、成立日期、标准化登记号
parseAddressaddress地址解析:省市区、街道、道路、门牌、楼层、房间、邮编、POI

一次查询里调用多个字段

GraphQL 允许在同一个请求里并列多个字段,服务端会并行执行。这样一次 HTTP 往返就能拿到多个维度——这是它相对单个 REST 接口最实际的好处。

多个字段并列
query DueDiligence($name: String!, $key: String!) {
  queryCompanyBasicInfo(entname: $name)
  queryCompanyCourtLitigationRelatedInfo(name: $name)
  queryCompanyAbnormalBusinessOperation(keyWord: $key)
  queryCompanyPatentList(entName: $name)
}

5. 返回格式

字段的返回值是 字符串,里面装着上游原始 JSON。这是为了让不同上游接口的结构原样透出,不做二次改造。

响应示例 · queryCompanyBasicInfo
{
  "data": {
    "queryCompanyBasicInfo": "{\"retcode\":\"000000\",\"retmsg\":\"...\",\"retdata\":{
        \"BASIC\":{\"ENTNAME\":\"深圳市腾讯计算机系统有限公司\",\"FRNAME\":\"马化腾\",\"CREDITCODE\":\"91440300708461136T\"},
        \"PERSON\":[ ... ],
        \"SHAREHOLDER\":[ ... ]
    }}"
  }
}

所以解析要两步:先取 data.字段名 拿到字符串,再对它做一次 JSON 解析。注意字符串里的引号是转义的。

retdata 内部还有分组,字段名是大写

以工商基本信息为例,retdata 下面是三个节点,不是直接的字段:

节点类型内容
retdata.BASIC对象工商主体信息:ENTNAME 企业名称、FRNAME 法定代表人、CREDITCODE 信用代码、REGCAP 注册资本、ESDATE 成立日期、ENTSTATUS 经营状态、ZSOPSCOPE 经营范围、DOM 地址
retdata.PERSON数组主要人员(董事、监事、高管)列表
retdata.SHAREHOLDER数组股东及出资信息列表
内层字段名是全大写,和查询参数名不是一套写法。参数用 entname(小写),返回里是 ENTNAME(大写)。上面这个 BASIC / PERSON / SHAREHOLDER 结构是工商基本信息的实际返回;其余字段由各自上游接口定义,结构不一样,建议先用控制台跑一次看你需要的那个字段长什么样。

业务状态看 retcode,不是看 HTTP 码

retcode含义怎么处理
000000成功读 retdata
err_*上游业务错误(如查无此企业、参数不合法)按业务失败处理,不要重试
warn_*上游告警记录并按提示修正参数
企业名必须是工商全称。不确定全称就先调 fuzzyQueryCompany,拿到全称再查详情,否则多数字段会返回空结果——而空结果同样计费。

6. 控制台用法

控制台地址:https://mcp.yushanshuju.com/graphql,是一个标准 GraphiQL 界面,可以直接在浏览器里写查询、看返回,不需要装任何工具。

  1. 打开页面,地址栏不要带任何参数直接访问 https://mcp.yushanshuju.com/graphql。页面只加载界面,不会执行任何查询。
  2. 在左下角 Headers 面板填入 Token点开 Headers,把内容改成一行:
    {"Authorization": "Bearer ysk_你的TOKEN"}
    保存后这一栏会显示一个绿色小圆点。
  3. 重新拉取一次 Schema点了 Headers 之后必须点界面上的“重新加载 Schema”按钮(通常是一个刷新图标)。不点的话左侧文档树是空的,执行查询会返回 401。
  4. 写查询并执行在中间编辑区输入查询,例如 { fuzzyQueryCompany(keyWord: "腾讯") },点顶部 ▶ 按钮。右侧显示结果。
  5. 结果看起来“带反斜杠”是正常的因为返回的是字符串形式 JSON,控制台会显示成 "{\"retcode\":...}"。复制出来二次解析即可。
刷新页面后如果又变成 401,说明 Headers 没被保存,重做第 2、3 步即可。浏览器不同,GraphiQL 的存储行为略有差异。
页面白屏?控制台的前端资源从公共 CDN 加载,部分内网或网络受限环境会加载失败。此时不要依赖控制台,直接用第 3 节的 curl 或 Python 示例调用,功能完全一致。

7. 常见错误

现象原因处理
{"error":"unauthorized"}没带 Authorization 头,或 Token 写错/已停用检查 Bearer 后的完整字符串;到控制台确认 Token 状态
左侧文档树空白填 Headers 后没重新拉 Schema点刷新 Schema 按钮
Cannot query field "xxx"字段名拼错,或用了 REST 的路径名对照第 4 节表格;字段是 camelCase,首字母小写
Unknown argument "entName"参数名大小写不对,该字段要的是 entname逐字段核对,别统一套用
返回 retcode 非 000000企业名不是工商全称、或该企业无此维度数据先用 fuzzyQueryCompany 取全称
HTTP 200 但 data 为空查询语法合法但字段执行失败看 errors 数组里的 message 和 path
页面白屏CDN 资源加载失败改用 curl / SDK 调用

8. 限制说明

  • 只读。没有 Mutation,不能通过 GraphQL 创建、修改或删除任何数据。
  • GET 不能执行查询。GET 只用于返回控制台界面;执行查询必须用 POST,这是为了防止凭证出现在 URL 里被日志记录。
  • 列表类字段只返回上游第一页,条数因接口而异。专利 / 商标 / 软著 / 变更记录每页 20 条;涉诉每页 20 条(MCP 工具支持 page 翻页,上游单次最多取前 10000 条);模糊搜索固定只给前 10 条且上游不支持翻页;对外投资一次性返回全部。GraphQL 侧统一不支持 page 入参,需要翻页请改用 MCP 工具(query_company_patent_list、query_company_court_litigation_related_info 等)。请以返回体的 retdata._meta 为准:total 是真实总量、total_pages 是总页数(上游给了才有)、pagination_supported 表示该接口能否翻页、has_more 表示是否还有下一页。不要用返回条数推断总量。
  • 参数长度上限 128 字符,超长会被本地直接拒绝,不消耗上游调用。
  • 不支持嵌套查询。字段之间不能互相嵌套,一次一个企业维度。
  • 计费按字段计。一次请求里写了几个字段,就算几次调用;缓存命中的部分不计费。