Skip to main content
Glama
LingerDavid

enterprise-scout-mcp

by LingerDavid
README.md
# enterprise-scout-mcp

[![test](https://github.com/LingerDavid/enterprise-scout-mcp/actions/workflows/test.yml/badge.svg)](https://github.com/LingerDavid/enterprise-scout-mcp/actions/workflows/test.yml)

企业工商/穿透情报 **MCP 服务**。Python 编排层(人设、风控路由、行为配额)+ 多通道采集,输出到 [EnterpriseLake](../EnterpriseLake) `G:/enterprise_lake/`。

与 `enterprise-mcp-server`(Handaas 单源 API)互补:工商主路径只走 ENScan_GO;Handaas 为可选付费补源。

## MCP 工具

| 工具 | 说明 |
|------|------|
| `enterprise_collect` | 按关键词采集(平台 / 深度 / fields / persona);股权请用 `aiqicha`,勿默认天眼查 |
| `enterprise_search` | 轻量搜索(depth=0) |
| `enterprise_collect_batch` | 批量采集(支持 checkpoint) |
| `enterprise_equity_tree` | 从湖边表本地 BFS 组穿透树(只读) |
| `enterprise_equity_expand` | 按需用 **aiqicha** 迭代补采缺失法人邻居(拒绝 tyc) |
| `scout_sessions` | 查看统一 cookie 注册表(GSXT / 爱企查 / ENScan) |
| `sync_enscan_cookies` | 把本地 cookie 写入 ENScan config |
| `scout_drain_retry` | 重跑 `raw/retry_queue`(成功则归档) |
| `scout_doctor` | 检查 ENScan / Handaas / 人设(可 probe sidecar) |
| `scout_sidecars` | 探活 ENScan / proxy_pool |
| `scout_import_neo4j` | warehouse parquet → Neo4j(默认 dry_run) |

## 快速启动

```powershell
cd E:\Project\enterprise-scout-mcp
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e ".[dev,warehouse]"
# 浏览器回退(可选): pip install -e ".[browser]"

copy config.example.yaml config.yaml
enterprise-scout-mcp                    # stdio(Cursor / Hermes 默认)
enterprise-scout-mcp streamable-http  # HTTP :8000
```

## Cursor / Hermes 配置

**stdio(推荐本地):**

```json
{
  "mcpServers": {
    "enterprise-scout-mcp": {
      "command": "enterprise-scout-mcp",
      "args": [],
      "cwd": "E:/Project/enterprise-scout-mcp"
    }
  }
}
```

**streamable-http:**

```json
{
  "mcpServers": {
    "enterprise-scout-mcp": {
      "type": "streamableHttp",
      "url": "http://127.0.0.1:8000/mcp"
    }
  }
}
```

## 开发 CLI

编排层调试(非 MCP 面):

```powershell
escout doctor
escout personas
escout collect 小米 -p aiqicha
escout collect-batch --file keywords.txt -p aiqicha --checkpoint .state/batch.json
escout import-neo4j --dry-run    # 统计 warehouse 行数
escout import-neo4j              # 写入 Neo4j(需 pip install -e ".[graph]")
escout sessions list                              # 统一查看 cookie 路径与就绪状态
escout sessions import gsxt --from-file cookies.json
escout sessions import aiqicha --from-file ./secrets/aiqicha_cookies.txt
escout sessions cdp-hint                            # GSXT 瑞数:真实 Chrome CDP 接管步骤
escout sessions warmup gsxt                       # nodriver 刷新 cookie(需 .[browser])
escout sync-cookies --from-file ./secrets/aiqicha_cookies.txt   # 兼容别名 → sessions import aiqicha
escout register-hermes          # 写入 ~/.hermes/config.yaml
escout doctor --probe           # 含 ENScan / proxy_pool 探活 + sessions
escout smoke-sidecars           # 仅 sidecar 探活(CI/脚本用)
escout smoke-collect 小米       # 实机采集冒烟(需 ENScan 运行)
escout sync-gsxt-session --from-file cookies.json   # 兼容别名 → sessions import gsxt
escout sync-gsxt-session --warmup                   # 兼容别名 → sessions warmup gsxt
escout collect 苏州挚途 --dims registry --prefer-tier l1 -p gsxt
escout smoke-registry-l1 苏州挚途                  # L1 registry 穿通验收
escout drain-retry --dry-run    # 列出 retry_queue 待重跑任务
escout drain-retry --limit 20   # 重跑 captcha 队列(成功 → .archive)
escout corpus init              # 创建语料目录 + 示例 JSONL
escout corpus status            # L3 / judicial 语料目录状态
```

语料格式见 [docs/corpus-schema.md](docs/corpus-schema.md)。

**采集策略(三级源):** 默认 `ensan_only` — 爱企查 / 天眼查等走 ENScan L2。L1 官方工商默认 **`integrations.gsxt.search_mode: browser`**:在**真实浏览器页面环境**内调用搜索 API(绕过瑞数 CT/瑞数对 httpx 的拦截),**不要**对 412/405 盲目重试或换 IP。

| 模式 | 配置 | 说明 |
|------|------|------|
| **CDP 接管(推荐)** | `browser_cdp_port: 9222` | 真实 Chrome → Playwright `connect_over_cdp` → **Method A**:DOM 触发站点 XHR(拦截响应)/ `pajax`·`$.ajax` / 页面内 fetch |
| nodriver 自建 | `browser_cdp_port: 0` | 持久 profile + 有头浏览器;NWAF 仍可能拦截自动化指纹 |
| httpx API | `search_mode: api` | 仅 JSL 可过;瑞数 Environment Checking 会 412 — **勿对 521/412 换 IP 硬刚** |

```powershell
pip install -e ".[browser]"
escout sessions cdp-hint                    # 打印 Chrome 启动命令与步骤
# 1) 按 hint 启动 Chrome,打开 gsxt.gov.cn 并完成验证
# 2) config.yaml: browser_cdp_port: 9222
escout sessions import gsxt --from-file .state/gsxt_browser_export.json
escout smoke-registry-l1 苏州挚途
```

VPN/Clash:`proxy_url: http://127.0.0.1:7897` 或 `$env:HTTPS_PROXY=...`(改善连通性,**不能**单独绕过瑞数环境检测)。`routing.l1_fallback_to_l2: true` 时 L1 仍失败则降级 ENScan(`degraded=true`)。

默认 `fields`:`enterprise_info,partner,holds,invest,branch`(写入实体 + 股权边)。可用 `-f` / MCP `fields` 覆盖。可选加 `supplier`(供给边 `relation=supply`)。

**股权穿透(本地树,非天眼查计费):**

```powershell
escout collect 示例公司 -p aiqicha
escout equity-tree 示例公司 --depth 2
escout equity-expand 示例公司 --depth 2 --min-ratio 20   # 强制 aqc;勿并行
```

树读 `warehouse/edges/equity/part.parquet` 做 BFS;expand 只补从未作为 `query_keyword` 采集过的**法人**邻居(跳过自然人与分支)。边写入按 `(src,dst,relation)` 去重。

`state_persist: true` 时,日配额与路由成功率写入 `state_dir`(默认 `./.state/`)。`collect-batch --checkpoint` 断点续跑:仅 `ok`/`partial` 记为 done,`error`/`captcha`/`blocked` 下次会重试。

`neo4j.enabled` + `neo4j.auto_import: true` 时,单采 / 批采结束 / drain 成功后会自动 merge warehouse → Neo4j(需 `pip install -e ".[graph]"`)。

## Warehouse 输出

`output.parquet_enabled: true` 时写入 EnterpriseLake:

| 路径 | 内容 |
|------|------|
| `warehouse/entities/part.parquet` | 企业实体行 |
| `warehouse/edges/equity/part.parquet` | 股权/投资/分支边(partner/holds/invest/branch) |
| `raw/` / `raw/retry_queue/` | partial / captcha 分级 JSON |

列定义见 [docs/warehouse-schema.md](docs/warehouse-schema.md)(与 EnterpriseLake layout 对齐)。

## 架构

```
MCP (enterprise-scout-mcp)
  └─ CollectorScheduler
       ├─ PersonaEngine         ← 人设 UA / locale / tz / OS
       ├─ RiskAwareRouter       ← ensan_only default for aiqicha/tyc
       ├─ TierAwareRouter       ← L1 GSXT / L2 ENScan (--prefer-tier)
       ├─ BehaviorOrchestrator  ← 配额 / 冷却 / 延迟
       ├─ EnvironmentValidator  ← UA/TLS/locale/语言/geo/时区/OS
       ├─ disguise egress       ← curl_cffi [transport] · Camoufox [camoufox]
       ├─ CaptchaHandler        ← rotate_ip | CapSolver API | OpenCV 滑块 [captcha]
       ├─ GsxtOfficialChannel   ← L1 registry (CDP / nodriver)
       ├─ EnsanGoChannel        ← L2 ENScan :31000
       └─ HandaasChannel        ← optional paid API
```

**维度路由**(`--dims` / MCP `dims`):`registry`(L1 GSXT / L2 ENScan)、`equity`(股东/投资/分支 → ENScan)、`digital`/`ip`(备案/小程序等 → ENScan)、`credit`(Handaas 凭证可用时走付费 API)/`judicial`(本地 corpus 或 stub)/`prefer-tier l3`(`corpus/l3` JSON/JSONL)、`prefer-tier l3`(academic stub)。多维度一次采集会自动合并 payload。

模块落地状态见 `escout doctor` → `architecture` / `tiers`。

**Neo4j:**

```powershell
escout doctor              # warehouse.counts + neo4j.connectivity(enabled 时)
escout import-neo4j --dry-run
escout import-neo4j        # Company / HOLDS / Supplement / Conflict
```

**Phase 3 — Fine UI**(参考 `E:/Project/fine-2.7.2/README_images`:设置 + 爱企查 + 多 Tab):

```powershell
# 首次(或 venv 损坏时)
.\setup-venv.ps1 -Ui

# 推荐:不依赖 PATH 里的 escout
.\serve-ui.ps1             # 自动 build ui/dist + API :8790
.\serve-ui-dev.ps1         # API :8790 + Vite :5179 热更新

# 或手动
.\.venv\Scripts\escout serve
cd ui && npm run dev       # :5179,/api 代理到 8790
```

页面:**设置**(warehouse / Neo4j / 通道)、**爱企查**(查询 + 股东/投资/分支 Tab)、**状态**(verify checklist)。

**验收:**

```powershell
escout verify --summary
pytest -q
```

可选依赖:

```powershell
pip install -e ".[transport]"   # curl_cffi TLS 伪装
pip install -e ".[camoufox]"    # Camoufox 浏览器出口
pip install -e ".[captcha]"     # OpenCV 滑块定位
```

## Sidecar

```powershell
docker compose up -d proxy_pool
# ENScan: cd ..\ENScan_GO && .\enscan.exe -api
```

## 测试

```powershell
pytest -q
```

CI: GitHub Actions workflow `.github/workflows/test.yml` runs the same suite on push/PR.

TDQS

C2.8/5.0

Scored across 10 tools

Disambiguation3/5

enterprise_collect, enterprise_collect_batch, and enterprise_search overlap significantly — search is explicitly described as 'collect with depth=0', so an agent may struggle to pick the right entry point. scout_doctor and scout_sidecars also both probe sidecar availability with unclear boundaries, while the sync_* tools are distinct.

Naming Consistency3/5

Two inconsistent prefixes (enterprise_* vs scout_*) are mixed with two verb styles: action-oriented names (enterprise_collect, sync_gsxt_session) coexist with noun-style names (scout_sessions, scout_doctor, scout_sidecars). Still readable, but no single predictable pattern.

Tool Count4/5

Ten tools is a reasonable, well-scoped set for an enterprise collection pipeline covering collection, sessions, diagnostics, and export. Slightly heavy given that collect/search/batch and doctor/sidecars duplicate intent.

Completeness4/5

The surface covers collection, batch, search, session management, diagnostics, Neo4j import, and retry/drain, forming a coherent pipeline. Minor gaps exist around inspecting or deleting already-collected warehouse data and no explicit export/reporting operation.

Maintenance

ActivityMaintained
ResponsivenessNo issues