管理台: - 内容管理新增名称搜索(title/slug/url/description),状态与翻页链接保留搜索词 - 菜单改为真实链接,每次点击重新向后台取数渲染分区,不再依赖手动刷新 - 内容管理每页固定 20 条 - pending 条目按钮改为「预览」,active 为「查看」 评论体系: - 评论提交新增必填联系方式(手机号/邮箱),前端不做展示 - 首次评论以「昵称+联系方式」建档,之后需匹配且未被禁用 - 后台评论管理新增联系方式列;新增评论人员管理页,可启用/禁用/改名/删除 - 评论昵称输入框不再预置 admin 相关项目: - 新增 entry_relations 双向关联,详情页侧栏展示并写入机读 JSON - 编辑页可添加/移除关联 内容源自动获取: - 修复 rss 适配器把 feed url 当成条目 url 的根本问题,支持 Atom link/href 与相对链接 - eryajf-weekly 限定正文容器取链接,修正项目说明的提取与「(opens new window)」清理 - pipeline 增加轮内去重与单条失败隔离;scheduler 对非法 cron 明确告警 MCP: - 重写 instructions 为八节说明,新增 usage 工具返回结构化接入文档 - 补全各工具的参数、用途与返回格式说明;baseUrl 取自当次请求 - 首页 MCP 区块与 README 同步补充写入示例与踩坑清单 测试: 新增 comments/relations/admin/ingest-adapters 用例,共 29 个全部通过
7.0 KiB
Awesome Index
把网上牛逼的东西收进一个库:给人用,也给 AI 用。 精选开源软件 / 微服务 / SaaS / 网站 / 工具 / 脚本 / 插件的结构化数据库,内置 MCP 接口。
- 设计方案:design/DESIGN.md(Riso 印刷风格 + 静态原型)
- 框架设计:docs/ARCHITECTURE.md(模块划分 / 数据模型 / 端点)
快速开始
本地开发
npm install
npm run dev # http://localhost:3000(--watch 热重载)
npm test # node:test,27 个用例
首次启动自动完成建表与种子数据。默认管理员 admin,密码取 ADMIN_INIT_PASSWORD(默认 admin)。
Docker 部署
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,它只提供读取能力。
客户端配置:
{
"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: <key> |
| 标准 Bearer(等价) | Authorization: Bearer <key> |
请求体字段:title(必填) / url(必填,合法 URL,用于去重) / type(必填,枚举:微服务 / SaaS / 网站 / 工具 / 应用 / 脚本 / 插件) / summary(≤200) / description_md(≤5000,Markdown) / license / stars(整数) / tags(字符串数组,自动建标签) / status。
slug不是合法字段,传了会被静默丢弃(服务端按标题自动生成)。
curl -X POST "{BASE_URL}/api/ingest/entry" \
-H "X-Ingest-Key: <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":<n>,"status":"pending"}};URL 已存在时 200 {"created":false,"id":<n>}(自动去重);鉴权失败 403 invalid_key。
五个必记的坑
- 推荐
X-Ingest-Key请求头(等价Authorization: Bearer);自创的X-API-Key、?key=一律 403。 - MCP 免密钥 ≠ 密钥有效。
/mcp根本不查 key,别拿探测 MCP 来验证 ingest key。 - 提交后默认
pending,前台搜不到是正常的,等管理员审核转active。不要因为搜不到就重复提交。 - 同一 URL 重复提交返回 200
created:false,这不是报错,说明已存在并被去重。 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