Skip to main content
Glama
carnation77

先机 NPA Vanguard

by carnation77
README.md
# 先机 NPA Vanguard

> **为 AI Agent 服务的不良资产数据层 MCP Server。**
> MCP(Model Context Protocol,模型上下文协议——让 AI agent 以统一方式调用外部工具的开放协议)。
> 不为人服务,为 agent 服务——把「不良资产(NPA/NPL)公告与挂牌标的」的初筛查询,封装成 agent 可一次性调用成功的 3 个工具。

[![version](https://img.shields.io/badge/version-0.1.0-blue.svg)](pyproject.toml)
[![license](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
[![python](https://img.shields.io/badge/python-%3E%3D3.10-yellow.svg)](https://www.python.org/)

---

## 这是什么

**先机 NPA Vanguard**(包名 `npa-vanguard`)是一个开源的 **MCP Server**,站在 AI agent 与公开不良资产公告之间,做一层**只读数据层**。

它不做投研、不下单、不发函。它只做一件事:**agent 问一句,它给一条带出处、字段齐全、绝不编造的答案。**

| 对比 | 给人用的数据终端 | 先机 NPA Vanguard |
|---|---|---|
| 服务对象 | 人看屏幕、人工翻页 | **agent 程序化调用** |
| 输出形态 | 报表、图表、PDF | 结构化 JSON(工具返回值) |
| 出错方式 | 人自己判断 | 中文友好兜底,不崩溃 |
| 出处要求 | 可溯源即可 | **每条回答强制带 `source + ann_id + 链接 + 抓取时间`** |

---

## 🧭 三要素原则(贯穿全项目)

| 要素 | 问题 | 本项目怎么做 |
|---|---|---|
| **看到** | agent 怎么发现我们 | 工具描述清晰、参数自解释;发布到 GitHub(规范 topics);登记到 MCP Registry / Smithery 等可被 agent 检索的目录 |
| **信任** | agent 怎么信任我们 | 每条回答强制带**出处四件套**:`source` + `ann_id` + `original_url` + `crawl_time`;某源没链接就如实标 `NA`,**绝不编造 URL**;缺数据即 NA,不脑补 |
| **爱用** | agent 怎么一次用成功 | 首次调用成功率目标 100%;银行简称自动扩展("建行"→"中国建设银行");空结果给中文提示而非报错;参数有合理默认值与 limit 上限 |

---

## 📊 数据底座

| 数据源 | 行数 | 覆盖 | 原文链接 | 抓取时间 | 更新时间(截至发布) |
|---|---:|---|---|---|---|
| 银登中心(不良贷款转让公告) | 5,954 | 公告标题 / 借款人 / 地区 / 本金 / 五级分类 | NA(未收录) | NA(未记录) | 公告日期最新 2026-10-10 |
| 公拍网(司法拍卖) | 13,874 | 评估价 / 成交价 / 围观报名出价 | NA(未收录) | NA(未记录) | 竞价结束最新 2026-10-11 |
| 北京产权交易所(司法拍卖栏目) | 1,668 | 起拍 / 评估 / 成交价 + **原文链接 + 抓取时间** | ✅ 完整 | ✅ 完整 | 抓取最新 2026-10-11 22:21 |
| **合计** | **21,496** | **55 个统一字段** | — | — | 每日增量采集 |

> 仓库仅附 30 行脱敏样例(`data/samples/`,三源各 10),全量 sqlite 不随仓库发布(见合规声明)。

---

## 🔧 三个工具

### 1. `search_listings` — 搜公告 / 标的

按关键词、地区、来源、状态检索挂牌记录,返回结构化摘要列表。

**参数**

| 参数 | 类型 | 说明 |
|---|---|---|
| `keyword` | string | 关键词;**银行简称自动扩展**("建行"→"中国建设银行","工行"→"中国工商银行"…);可匹配标题 / 借款人 / 法院 |
| `region` | string | 地区,如 `上海` / `广东` / `湖南省` |
| `source` | string | 过滤来源:`银登` / `公拍网` / `北交所`;缺省=全部 |
| `status` | string | 过滤状态:`挂牌转让公告` / `成交` / `竞价中` / `流拍` / `悔拍` / `已结束` / `未开始` |
| `limit` | int | 返回条数上限,默认 20,上限 100 |

**返回示例(节选,真实输出:`search_listings(keyword="建设银行", limit=2)`)**

```json
{
  "查询条件": { "keyword": "建设银行", "region": "", "source": "", "status": "" },
  "命中条数": 2,
  "说明": "价格 NA 表示该源未披露该字段(银登为债权转让公告,无起拍/评估/成交价)。",
  "结果": [
    {
      "title": "中国建设银行股份有限公司湖南省分行关于2026年第7期个人不良贷款(信用卡透支)转让项目转让公告",
      "source": "银登",
      "publish_date": "2026-10-09",
      "status": "挂牌转让公告",
      "起拍价": "NA",
      "评估价": "NA",
      "成交价": "NA",
      "debtor_region": "NA",
      "debtor_name": "NA",
      "出处": {
        "source": "银登",
        "ann_id": "855442445",
        "original_url": "NA(该源未收录原文链接)",
        "crawl_time": "NA(该源未记录抓取时间)"
      }
    },
    {
      "title": "中国建设银行股份有限公司河北省分行关于2026年第4期个人不良贷款(信用卡透支)转让项目转让公告",
      "source": "银登",
      "publish_date": "2026-09-30",
      "status": "挂牌转让公告",
      "起拍价": "NA",
      "评估价": "NA",
      "成交价": "NA",
      "debtor_region": "NA",
      "debtor_name": "NA",
      "出处": {
        "source": "银登",
        "ann_id": "855437495",
        "original_url": "NA(该源未收录原文链接)",
        "crawl_time": "NA(该源未记录抓取时间)"
      }
    }
  ]
}
```

> 列表项固定 9 个业务字段 + `出处`(四件套:`source` / `ann_id` / `original_url` / `crawl_time`,缺则如实标 `NA`)。北交所记录的 `original_url` / `crawl_time` 为真实链接与抓取时间,见下节详情示例。

### 2. `get_listing_detail` — 查单条完整字段

按 `ann_id`(配合 `source`)或 `original_url` 取回该条记录的全部 55 个字段。

**参数**

| 参数 | 类型 | 说明 |
|---|---|---|
| `ann_id` | string | 该源公告/标的 ID;与 `url` 二选一 |
| `source` | string | 当用 `ann_id` 时建议指定,避免跨源 ID 撞号 |
| `url` | string | 原文链接(北交所记录可用);与 `ann_id` 二选一 |

**返回示例(节选,真实输出:`get_listing_detail(ann_id="1BDAEBF4DEED00976F4F7330821C1A78")`,北交所记录)**

```json
{
  "source": "北交所",
  "ann_id": "1BDAEBF4DEED00976F4F7330821C1A78",
  "title": "天津市和平区贵阳路吉利花园3-1-2010号房屋",
  "status": "成交",
  "starting_price": "NA",
  "appraisal_value": 3960000.0,
  "deal_price": 3602000.0,
  "raw_appraisal_value": "396.00万",
  "raw_deal_price": "360.20万",
  "signup_count": 9.0,
  "starting_price_fmt": "NA",
  "appraisal_value_fmt": "3,960,000元",
  "deal_price_fmt": "3,602,000元",
  "出处": {
    "source": "北交所",
    "ann_id": "1BDAEBF4DEED00976F4F7330821C1A78",
    "original_url": "https://otc.cbex.com/sfpm/detail/1BDAEBF4DEED00976F4F7330821C1A78.html",
    "crawl_time": "2026-10-11 22:21:32"
  }
}
```

> 全字段共 55 列(此处节选);空值一律如实标 `"NA"`;金额列另附 `*_fmt` 千分位友好格式;末尾 `出处` 为四件套。

### 3. `get_latest_listings` — 最近 N 天新挂牌

按挂牌日期倒序,拉取最近 `days` 天内新出现的公告/标的,用于 agent 盯盘。

**参数**

| 参数 | 类型 | 说明 |
|---|---|---|
| `days` | int | 最近 N 天,默认 7 |
| `source` | string | 过滤来源,缺省=全部 |
| `limit` | int | 返回条数上限,默认 20,上限 200 |

---

## 🚀 快速开始

依赖:Python 3.10+。

```bash
# 1. 用自带样例 build 一个可跑的本地库(30 行脱敏数据)
git clone https://github.com/carnation77/npa-vanguard.git
cd npa-vanguard
python3 examples/build_sample_db.py
# -> 生成 data/npa_listings.sqlite(gitignore 已排除,不会进版本库)

# 2. 启动(二选一)
#    (a) stdio —— 本地 Claude Desktop / Claude Code / Cursor
TRANSPORT=stdio npa-vanguard
#    (b) HTTP / Streamable —— 对外暴露给远程生态
API_KEY=your-secret-key PORT=8765 npa-vanguard
#    -> endpoint: http://127.0.0.1:8765/mcp
#    -> health:   http://127.0.0.1:8765/health
```

> 注:GitHub 用户名已由发布人提供(`carnation77`),README、`pyproject.toml` 的 `[project.urls]`、`server.json` 三处均已全局替换完成,可直接 clone / 发布。
> 直接 `uvx npa-vanguard` 亦可跑 stdio。默认读取 `data/npa_listings.sqlite`,可用环境变量 `NPA_DB=/任意路径/xxx.sqlite` 覆盖。

---

## 🔌 各生态一键接入

> 对外暴露时用 **HTTP 模式**,把 `<your-endpoint>` 换成你的公网地址(形如 `http://your-host:8765/mcp`),`<your-api-key>` 换成你自己的 `API_KEY`。

### Claude Desktop(stdio)

编辑 `claude_desktop_config.json`(见 [`examples/claude_desktop_config.json`](examples/claude_desktop_config.json)):

```json
{
  "mcpServers": {
    "npa-vanguard": {
      "command": "uvx",
      "args": ["npa-vanguard"],
      "env": { "TRANSPORT": "stdio" }
    }
  }
}
```

### Claude Code

```bash
# stdio
claude mcp add npa-vanguard -- uvx npa-vanguard

# 或 HTTP 远程
claude mcp add --transport http npa-vanguard <your-endpoint> \
  --header "Authorization: Bearer <your-api-key>"
```

### Cursor

项目级 `.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "npa-vanguard": {
      "url": "<your-endpoint>",
      "headers": { "Authorization": "Bearer <your-api-key>" }
    }
  }
}
```

### Dify(v1.6.0+)

Dify Cloud / 自托管版均在 **Integrations → Tools → MCP → Add MCP Server** 中添加:

| 字段 | 值 |
|---|---|
| Server URL | `<your-endpoint>`(即 `http://host:8765/mcp`,**不是 `/sse`**) |
| Display name | `先机NPA不良资产库` |
| Server identifier | `npa-vanguard` |
| Custom Header | `Authorization` = `Bearer <your-api-key>` |

> 详细图文步骤、自托管 Docker 网络坑、FAQ 见 **[DIFY_INTEGRATION.md](DIFY_INTEGRATION.md)**。

### OpenAI Agents SDK

```python
from agents import Agent, Runner
from agents.mcp import MCPServerStreamableHttp

mcp = MCPServerStreamableHttp(
    name="npa-vanguard",
    url="<your-endpoint>",
    headers={"Authorization": "Bearer <your-api-key>"},
)
async with mcp:
    agent = Agent(name="npa", tools=[], mcp_servers=[mcp])
    # await Runner.run(agent, "建行最近在银登挂了什么转让公告")
```

### 扣子 Coze

扣子编程 → 创建插件 → 选择「基于已有 MCP 服务」→ 填入 `<your-endpoint>` 与 Bearer 鉴权头。

### 阿里百炼

百炼控制台 → 自定义 MCP 服务 → 部署方式选 `http` → 填入 `<your-endpoint>` 与 Bearer 鉴权。

---

## 🛑 人工确认节点声明

本版本为**纯只读查询**:只有搜公告、查详情、看新挂牌 3 个工具,**不含任何写动作**。

后续版本若接入真实动作(发函 / 出价 / 下单 / 对外发布),**必须内建人工确认节点**——每次动作前弹窗并等待用户显式确认,**绝不静默执行**。当前版本不提供任何此类动作。

---

## ⚖️ 数据来源与合规声明

- 数据来自**公开渠道**:银登中心不良贷款转让公告、公拍网司法拍卖、北京产权交易所司法拍卖栏目,均为公开挂牌/披露信息。
- 本项目仅做**公开信息聚合与初筛参考**,**不构成任何投资建议**;价格与成交信息以原始公告及法院/交易所正式公告为准。
- **全量数据不随仓库发布**:仓库仅附 `data/samples/` 脱敏样例(30 行,三源各 10,联系字段已剔除)。
- 使用方须遵守数据源平台及监管关于公告信息使用的相关规定。

---

## 🗂 项目结构

```
npa-vanguard/
├── pyproject.toml            # PyPI 打包配置(entry: npa-vanguard = npa_vanguard.server:main)
├── README.md                 # 本文件
├── LICENSE                   # MIT
├── .gitignore                # 排除 *.sqlite / __pycache__ / .env 等
├── src/
│   └── npa_vanguard/        # MCP Server 包(3 工具,stdio / HTTP 双模式)
│       ├── __init__.py
│       └── server.py
├── examples/
│   ├── mcp.json              # 通用 MCP 客户端配置模板
│   ├── claude_desktop_config.json
│   └── build_sample_db.py   # sample CSV -> 本地 sqlite 构建脚本
└── data/
    ├── samples/
    │   ├── sample_listings.csv   # 30 行脱敏样例(三源各 10,52 列)
    │   └── README.md             # 字段口径与 build 方法
    └── npa_listings.sqlite       # 本地库(gitignore,由 build_sample_db.py 生成)
```

---

## ⚠️ 已知数据缺口(如实写)

| 数据源 | 有什么 | 缺什么(如实,不掩饰) |
|---|---|---|
| 银登(5,954 行) | 公告标题 / 借款人 / 地区 / 本金 / 五级分类 / 担保 / 诉讼 | **无起拍价、无评估价、无成交价**(挂牌转让,从无落槌价);`original_url` = NA;`crawl_time` = NA |
| 公拍网(13,874 行) | 评估价 / 成交价(~95% 覆盖)、围观报名出价 | **无起拍价**;`original_url` = NA;`crawl_time` = NA |
| 北交所(1,668 行) | `original_url` + `crawl_time` 完整,起拍/评估/成交价 | 起拍价仅 ~3.7% 覆盖,成交价约 ~48% 覆盖 |

另:`execution_court` 等结构化地区字段稀疏,跨源地区对齐仍在迭代;所有结果**仅供初筛参考**。

---

## License

[MIT](LICENSE) © 2026 npa-vanguard contributors