# Awesome Index 把网上牛逼的东西收进一个库:给人用,也给 AI 用。 精选开源软件 / 微服务 / SaaS / 网站 / 工具 / 脚本 / 插件的结构化数据库,内置 MCP 接口。 - 设计方案:[design/DESIGN.md](design/DESIGN.md)(Riso 印刷风格 + 静态原型) - 框架设计:[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)(模块划分 / 数据模型 / 端点) ## 快速开始 ### 本地开发 ```bash npm install npm run dev # http://localhost:3000(--watch 热重载) npm test # node:test,27 个用例 ``` 首次启动自动完成建表与种子数据。默认管理员 `admin`,密码取 `ADMIN_INIT_PASSWORD`(默认 `admin`)。 ### Docker 部署 ```bash docker build -t awesome-index:latest . bash start.sh # 用新镜像重启容器 ``` `start.sh` 会检查 `.env`(不存在则从 `.env.example` 复制),然后 `docker run` 启动容器。数据持久化在宿主机 `./data/awesome.duckdb`,重启不丢数据。 ## 给人的入口 | 页面 | 地址 | |---|---| | 首页(搜索 / MCP 说明 / 最近收录) | `/` | | 列表页(类型 + 嵌套标签过滤) | `/entries?q=关键字&type=工具&tags=1,2&sort=stars` | | 详情页(元数据 / 相关项目 / 评论 / 机读 JSON) | `/entries/:slug` | | 随机游览 | `/random` | | 登录 | `/login` | | 管理台 | `/admin` | 管理台分区(**点菜单每次都重新向后台取数**,不需要手动刷新浏览器): | 分区 | 说明 | |---|---| | 内容管理 | 名称搜索(标题 / slug / URL / 描述)+ 状态筛选,**每页 20 条**;pending 条目按钮为「预览」,active 为「查看」 | | 标签管理 | 无限嵌套标签树,拖拽调整层级 | | 评论管理 | 评论列表 + **联系方式**列 | | 评论人员 | 以联系方式为身份依据,可启用 / 禁用 / 改名 / 删除 | | 内容源 | 人工 / AI 接口 / 定时拉取(rss / html / eryajf-weekly) | | 账号管理 | 管理员可见 | ### 评论规则 访客评论需要提供**昵称 + 联系方式**(手机号或邮箱): - 联系方式**只存后台,前台详情页不展示**。 - **首次评论**以「昵称 + 联系方式」建档入库。 - **之后评论**必须昵称与该联系方式登记的一致,且未被管理员禁用,否则分别返回 400 / 403。 - 管理员可在「评论人员」分区按联系方式禁用某人;禁用后其评论被拒,历史评论保留。 ### 相关项目 每个条目都能关联若干「相关项目」,在详情页侧栏展示,同时进入机读 JSON 的 `related` 字段。 - 关联在管理台「编辑条目 → 相关项目」里维护。 - **关联是双向的**:A 关联 B 后,B 的详情页也会出现 A(底层只存一条记录)。 - 前台只展示已上架(`active`)的相关条目。 ## 给 AI 的入口(MCP) > **一句话:读用 MCP(免密钥),写用 REST(要 `X-Ingest-Key`)。** ### 只读部分:MCP ``` POST {BASE_URL}/mcp transport: Streamable HTTP auth: none Accept: application/json, text/event-stream # 正规客户端自动带上;curl 直连需手写 ``` **本端点不校验任何密钥**,MCP 连接里无需配置 token,它只提供读取能力。 客户端配置: ```json { "mcpServers": { "awesome-index": { "url": "{BASE_URL}/mcp" } } } ``` 一句话让 Agent 自己接入: > 请把 URL 为 `{BASE_URL}/mcp` 的 MCP 服务器添加到你的客户端配置中,名称用 awesome-index,完成后告诉我现在可以调用哪些工具。 可用工具: | tool | 参数 | 说明 | |---|---|---| | `search_entries` | `q`(必填), `limit`(1–50,默认 20) | 按关键字 / 类型 / 标签搜索。**查重先走它** | | `get_entry` | `slug`(必填,也可传标题关键字自动匹配) | 取单条完整详情与元数据 | | `random_entry` | — | 随机返回一条已上架内容,用于探索发现 | | `list_tags` | — | 列出全部标签组、嵌套结构与收录数量 | | `usage` | — | 返回完整接入说明(含写入接口与踩坑清单) | 结果格式:返回体在 `result.content[0].text` 里,是一段 **JSON 字符串,需要再解析一次**。 连接 `initialize` 后返回的 `instructions` 字段同样带有完整的接入与写入说明(AI 客户端通常会自动注入)。 ### 写入部分:AI 录入接口 MCP 只读,不能写入。要让 Agent 把新内容录进本库,请使用 HTTP 接口: ``` POST {BASE_URL}/api/ingest/entry # 等价端点:POST {BASE_URL}/api/entries Content-Type: application/json ``` 鉴权请求头(**不要**把 key 放进 URL query): | 方式 | 示例 | |---|---| | `X-Ingest-Key`(推荐) | `X-Ingest-Key: ` | | 标准 Bearer(等价) | `Authorization: Bearer ` | 请求体字段:`title`(必填) / `url`(必填,合法 URL,用于去重) / `type`(必填,枚举:微服务 / SaaS / 网站 / 工具 / 应用 / 脚本 / 插件) / `summary`(≤200) / `description_md`(≤5000,Markdown) / `license` / `stars`(整数) / `tags`(字符串数组,自动建标签) / `status`。 > `slug` 不是合法字段,传了会被静默丢弃(服务端按标题自动生成)。 ```bash curl -X POST "{BASE_URL}/api/ingest/entry" \ -H "X-Ingest-Key: " \ -H "Content-Type: application/json" \ -d '{"title":"MinerU","url":"https://github.com/opendatalab/MinerU","type":"工具","tags":["Python","OCR"]}' ``` 返回:创建成功 `201 {"ok":true,"data":{"created":true,"id":,"status":"pending"}}`;URL 已存在时 `200 {"created":false,"id":}`(自动去重);鉴权失败 `403 invalid_key`。 ### 五个必记的坑 1. **推荐 `X-Ingest-Key` 请求头**(等价 `Authorization: Bearer`);自创的 `X-API-Key`、`?key=` 一律 403。 2. **MCP 免密钥 ≠ 密钥有效**。`/mcp` 根本不查 key,别拿探测 MCP 来验证 ingest key。 3. **提交后默认 `pending`**,前台搜不到是正常的,等管理员审核转 `active`。**不要因为搜不到就重复提交。** 4. **同一 URL 重复提交返回 200 `created:false`**,这不是报错,说明已存在并被去重。 5. `slug` 不是字段,传了会被丢弃。 排错:`curl` 直连 `/mcp` 报 `406` 是缺 `Accept: application/json, text/event-stream`,正规客户端不受影响。 录入条目默认 `pending`(待审核),除非对应 AI 源开启了 direct_publish。 ## 内容源(自动化收录) 三类来源汇聚到同一条目表: | kind | 说明 | 新条目状态 | |---|---|---| | `human` | 管理台人工录入(常开) | active | | `ai` | `POST /api/ingest/entry` + `X-Ingest-Key`(或 `Authorization: Bearer`)头 | pending | | `feed` | 定时拉取外部站点(rss / html / eryajf-weekly 适配器),管理台可手动触发 | pending | 首个站点适配器:二丫讲梵学习周刊(wiki.eryajf.net)。运行记录见管理台「内容源 → 运行记录」。 ## 技术栈 Node.js 22 (ESM) · Express 5 · EJS · DuckDB (`@duckdb/node-api`) · zod · express-session · @modelcontextprotocol/sdk · node-cron · cheerio