mcpField
N
NicheDB

NicheDB

远程服务
nichedb.dev搜索与检索1今天更新

关于 NicheDB

NicheDB 是用于采集和提供持续增长的公共数据集合的开放平台,适合构建可搜索信息流的用户。它通过来源适配器汇集数据,并支持网页、RSS、JSON、API、命令行和 MCP 访问。

主要功能

  1. 01公共数据来源适配器
  2. 02集合与已保存查询信息流
  3. 03网页、RSS、JSON Feed 和 API 访问
  4. 04推送、邮件和签名 Webhook 更新
  5. 05命令行与 MCP 访问
  6. 06使用 Postgres 和 Redis 自托管

适用场景

  1. 01跟踪公共注册表中的新发布内容
  2. 02从政府文件或研究数据构建信息流
  3. 03关注已保存数据查询的变化
  4. 04向应用和 Agent 提供采集的数据

MCP 相关

NicheDB 提供 MCP 工具,用于访问已采集的数据和信息流。其个人资料集合还支持通过 update_profile MCP 工具更新资料条目。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://nichedb.dev/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

安装包
npm@profullstack/nichedb0.1.0

工具

27

此工具无需参数。

详细介绍

NicheDB

源数据流入,信息流输出。 一个面向只增不减的数据库的开放平台:游戏发行、软件包注册表、政府申报,以及任何拥有大量初始数据且每日增长的公开数据。一个 Postgres、一个 Redis,每一行数据都可通过网页、RSS、JSON、API、CLI 和 MCP 访问。

首次部署位于 nichedb.dev。只要有 Postgres 和 Redis,即可运行自己的实例。

模型

项目含义
collection一个细分领域:games、packages、filings。
source一个指向单个上游数据源的适配器,按自己的频率抓取。Steam 的新发行列表。npm 变更动态。EDGAR Form D 申报。
item一个由数据源生成的数据行。标题、URL、时间(含 time_known 和 precision)、标签,以及适配器在 data 中提供的载荷。
feed对一个 collection 保存的查询。提供页面、RSS 和 JSON Feed 呈现、API 端点,以及通过推送、电子邮件或签名 Webhook 接收变更通知的关注者。

每个适配器都是 packages/adapters/src 中的一个文件。目前已在四十六个 collection 中提供一百六十一个适配器:

集合适配器所需密钥
游戏steam、steam-news、igdb、igdb-catalog(IGDB 知道的每款游戏,按 ID 遍历,然后根据 updated_at 保持最新)、wikidata-games、steam-catalog仅 IGDB(Twitch 客户端)
软件包npm、pypi、crates、go-modules、huggingface、github-releases(运行时和框架,以及 NIST 自有软件,在 usnistgov 下以 github-releases-nist 收录)不需要(GitHub 令牌可选)
申报文件edgar、federal-register不需要
法律courtlistener(Atom 订阅源中的最新意见:所有法院,以及各法院自己的订阅源轮流更新,或指定一个法院)、courtlistener-oral-arguments(播客,包含 MP3)、courtlistener-api(案卷、法官和财务披露,在免费版每天 125 次请求的限额内,每次运行请求一次)、courtlistener-catalog(所有法院、附带教育背景和党派信息的法官、注明所披露内容的披露记录、口头辩论、附有报告员引证标签的意见集群,以及 FJC 数据库,均来自季度批量转储;案卷可选择加入)仅 API 来源需要 COURTLISTENER_TOKEN;订阅源和转储无需密钥且属于公有领域
音乐musicbrainz、musicbrainz-catalog、discogs-catalog不需要
图书openlibrary、gutenberg-catalog、librivox-catalog、openlibrary-catalog不需要
桌游scryfall-sets、scryfall-cards不需要
太空launch-library不需要
棋类lichess-broadcasts不需要
警报usgs-earthquakes、gdacs不需要
天气nws-alerts、nhc-cyclones、swpc-space-weather、eonet-events不需要
服务中断statuspage(任何 Statuspage 主机)不需要
扩展firefox-addons、vscode-extensions不需要
健康openfda-recalls、clinical-trials不需要
研究arxiv、crossref、openalex(按主题或搜索结果从最新条目开始;openalex-algorithms 已预先填充)、nist-datasets(data.nist.gov 上的所有数据集,按最近修订时间排列)、nist-csrc-drafts(开放征求意见的 NIST 安全草案,关闭后在原位置标记)不需要
汽车fueleconomy-catalog、nhtsa-recalls、nhtsa-complaints、nhtsa-safety-ratings不需要
市场iso-mic-exchanges、alpaca-corporate-actions、alpaca-news、alpaca-assets、equity-history、nasdaq-halts、ecb-fx-rates、sec-fundamentalsAlpaca(APCA_API_KEY_ID、APCA_API_SECRET_KEY、APCA_FEED,值为 iex 或 sip);SEC 要求在 user agent 中提供 CONTACT_EMAIL
加密货币coingecko-assets、crypto-pairs无需密钥(COINGECKO_API_KEY 可选;从数据中心访问 Binance.US 需提供 CRYPTO_PROXY_URL)
犯罪socrata-crime、uk-police-crime、fbi-crime-estimates、police-updates(39 个加州警察部门的订阅源;来源覆盖范围)仅 FBI 需要密钥(免费的 api.data.gov 密钥)
公共资金usaspending-awards、ocds-tenders、ted-notices不需要
住房uk-land-registry、freddie-mac-rates、building-permits、ruuster(Agent 保存的搜索)不需要
工作bls-series、eurostat、warn-layoffs、agenticjobs不需要
人口worldbank-population(所有国家,World Bank WDI,CC BY 4.0)、census-acs(ACS 5 年汇总文件中的所有美国州、城市和 ZIP 代码,公有领域)、geonames-cities(其他地区人口超过 15,000 的城市及其区域,CC BY 4.0);在 /population 浏览树状目录,或访问 /api/v1/population/{key}不需要
活动musicbrainz-events(来自 MusicBrainz JSON 转储的约 126,000 场音乐会、音乐节和演出:按角色列出演出者、附坐标的场地、日期和当地开始时间、演出曲目单、售票和 setlist.fm 链接;CC0)、wikidata-festivals(Wikidata 上的所有音乐节,含网站、地点、流派和其 MusicBrainz 系列;CC0)。不含票价:Ticketmaster 和 SeatGeek 的条款禁止存储其数据,而 StubHub 和 Vivid Seats 仅提供联盟营销计划不需要
电台radiobrowser(来自 radio-browser.info 的约 67,000 个网络电台,其中 60,000 个正在播放:流媒体和主页、国家、语言、流派、编解码器和比特率、上次流媒体检查时间、投票数和过去一天的收听量,以及已知情况下的坐标;可免费使用,每日抓取)不需要
AI 事件rogue-ai-incidents、rogue-ai-research、aiid-reports不需要
新闻newsfeed(新闻编辑部订阅源,以及 NIST 的 28 个主题、事件和博客订阅源,以 nist-news 收录)、gdelt、rssamplifier、brisk、news-channels不需要
域名ntld-totals、ntld-tlds、ntld-launches、ntld-changes不需要
播客podcasts、p0dcasters、podcastindex-catalog不需要
航空faa-nas-status、aviation-hazards、aviation-metar、ntsb-accidents、adsb-flights不需要(NTSB 需要 mdbtools + unzip,已包含在 Dockerfile 中)
水资源nwps-river-gauges、coops-water-levels、drought-monitor、ndbc-buoys、nws-surf-zone不需要
消费者金融cfpb-complaints、fdic-institutions、fdic-structure-changes不需要
优惠信息slickdeals、dealnews、dealcatcher、bensbargains、reddit-deals不需要
体育espn-catalogue、espn-schedule、espn-live、espn-plays、livetennis、sportsdb-tv、sportsdb-leagues、sportsdb-teams、sportsdb-live、sportsdb-scheduleLive Tennis;TheSportsDB(SPORTSDB_API_KEY:使用共享密钥 3 时,每个列表只会返回一行,且完全没有实时订阅源;使用订阅者密钥时,会遍历列表来获取目录,并启用 sportsdb-live 和 sportsdb-schedule);ESPN 无需密钥(云端出站访问需提供 SPORTS_PROXY_URL)
影视tmdb-releases、tvmaze-schedule、tvmaze-catalog(TVmaze 知道的所有节目,CC BY-SA,遍历一次后根据 /updates/shows 保持最新)、anilist-airing、imdb-ratings、wikidata-films、kitsu-anime、thetvdb-catalog(TheTVDB 上的所有剧集,需要 THETVDB_API_KEY,必须提供归属链接)仅 TMDB
频道iptv-org-channels不需要
SaaSsaasrow、opensaas(首先使用 nichedb.dev;任何提供 /.well-known/opensaas.json 的服务)不需要
市场平台d0rz、bl0ggers不需要
AI 媒体aiornot不需要
论坛tsbb不需要
优惠券c0upons(仅收录 c0upons.com 自行收录的内容:提交的代码及其 r/couponcodes 列表;不会回读从 deals 复制的行)不需要
DHTbittorrented-dht(排除成人内容)bittorrented.com 的 Supabase URL 和可发布密钥(BITTORRENTED_SUPABASE_URL、BITTORRENTED_SUPABASE_KEY);未提供时暂停
托管服务findhost、buyvps、vultr-plans、linode-types、scaleway-instances、ovh-vps、storefront(WHMCS、Blesta 和 WooCommerce 订单表单)、lowendbox、openserver;hetzner-plans、digitalocean-sizes、upcloud-plans前八项不需要(FindHost 数据采用 CC BY 4.0:请注明 FindHost,findhost.app;JavaScript 专用商店可选提供 OBSCURA_MCP_URL);Hetzner(HETZNER_API_TOKEN)、DigitalOcean(DIGITALOCEAN_TOKEN)和 UpCloud(UPCLOUD_USERNAME、UPCLOUD_PASSWORD)各自都需要只读凭据,未提供时保持暂停
威胁openthreat(首先使用 ThreatCrush;任何提供 /.well-known/openthreat.json 的报告方)、nvd(所有 CVE,每 15 分钟按 lastModified 获取;“本产品使用 NVD API,但未获得 NVD 的认可或认证”)、surbl(将 SURBL 列表作为目录,并在 multi.surbl.org 查询你指定的域名;按照 SURBL 的使用政策,可免费进行 DNS 查询;完整列表仅以订阅源形式出售)不需要(NVD_API_KEY 可选,可将速率提高到十倍)
个人资料openprofiles(首先收录 p0dcasters 和 OutreachGraph 列表;任何列出其提供的 OpenProfile.md 文件的应用)、sportarr-persons(Sportarr 的 11.1 万个名字,仅保留 Wikidata 标记为具有某项运动的真人及其社交账号)、sportsdb-players、installmap-yc-people(运行 MCP 服务的 YC 公司,以包含其账号的组织形式收录,并列出其创始人)不需要
The way out(OpenSaaS)

nichedb 在 /.well-known/opensaas.json 提供自己的 OpenSaaS 描述文件:其中包含结账页面实际出售的方案(预付费期限,不会自动续订),以及这里实际提供的操作。每项操作都列出用户打开的页面,以及 Agent 使用 OpenAccess bearer 调用的端点:subscribe(POST /api/v1/billing/subscribe,返回 pending 和结账页面)、cancel(POST /api/v1/billing/cancel,一键即可立即取消,不退款)、unsubscribe(一个页面:/settings,可在此关闭发送邮件的关注项)、export(POST /api/v1/account/export,一次导出一个 JSON 文档)、delete(POST /api/v1/account/delete,通过发送到账户邮箱的链接确认,立即删除,不保留任何内容)。对应的页面入口为:/account/billing、/account/export、/account/delete。opensaas 适配器会将其他服务的描述文件读入 saas 集合,每个方案占一行,并将该服务自己的 steps 和 confirm 并列展示,分别说明加入和退出的方式。

People(/c/profiles)

每人一条记录,汇总所有提供 OpenProfile.md 的应用中的信息。openprofiles 适配器会翻页读取每个应用的列表(/api/openprofiles?since=…),从列出文档的主机获取每份文档,并将身份键相同的文档(Web URL、任意 Accounts URL、Email、DID)合并为一个档案;仅姓名相同绝不会触发合并。页面地址为 /c/profiles/<slug>-<id>(按 id 解析,名称仅作展示用途,名称不匹配时会重定向 301),或者在所有者设置了 handle 后使用 /c/profiles/<handle>;旁边的 …/openprofile.md 是文件,类型为 text/markdown,允许 CORS 跨域访问,页面上带有 <link rel="openprofile">。

用户可通过 This is me 认领自己的记录(通过档案中列出的邮箱验证,或从其网站或节目链接回该页面;管理员也可以为某个邮箱认领),并可从页面、PUT /api/v1/profiles/<ref>(JSON 覆盖层或完整的 text/markdown 文件)、nichedb profile edit,或 update_profile MCP 工具进行编辑。编辑时需要会话、API 密钥,或带有 openprofile:edit 权限的 OpenAccess 令牌。所有者撰写的内容会作为覆盖层,优先于所有来源,并在每次重新读取后保留;写为 none 的章节会被移除。Broadcast 和 Guest 章节(OpenBroadcast、OpenGuest)是 podcasters 和 guests 信息流的筛选依据。

页面会显示 OpenProfile 0.4 设为默认项的三个身份字段,内容从 Markdown 读取:Emoji(一个字素,或 OpenEmoji :shortcode:)显示在姓名旁边;Pronouns 按原样显示在 handle 旁边(未提供即表示未说明,绝不推断);Web(Website、Homepage 和 Site 也都视为同一个键)。API 和 MCP 的返回结果会将它们分别标记为 emoji、pronouns 和 web;所有者可在编辑器中设置,也可在 PUT 或 update_profile 中设置 emoji/pronouns/web,或者运行 nichedb profile edit <ref> --emoji … --pronouns … --web … 设置。 职业相关维度仅来自本人(或适配器已读取的公开页面)发布的信息:身份行 Title:(或 Job Title:、Role:、Position:)以及 Company:(或 Employer:)行,且不区分大小写;Company: Acme (https://acme.com)、[Acme](https://acme.com)、acme.com 和单独的名称都能识别,Title: CEO at Acme 则会同时识别两者。职级(c-suite、vp、director、manager、senior、entry 或无)根据职位名称中的关键词推导。API 和 MCP 的回答包含 title、company({name, domain})、seniority 和 facets;集合条目会标记为 title:<slug>、company:<domain>(没有域名时使用名称的 slug)和 seniority:<level>,因此 ?tags= 会像筛选其他维度一样筛选这些条目;GET /api/v1/profiles(以及 search_profiles、nichedb profiles)接受 title、company、seniority 和 tags。GET /api/v1/profiles?linkedin=<url>(find_profile_by_linkedin、nichedb profiles --linkedin)会返回 LinkedIn 页面所属的公开档案。按电子邮件查询是刻意不提供的:这样做会让任何持有某个地址的人都能得知其所有者是否被收录。 | 目录 | outreachgraph | 否 | | 网站 | opensite | 否 | | 算法 | nist-dads(NIST 的《算法与数据结构词典》,包含每个条目的定义和关系;公有领域)、wikidata-algorithms(Wikidata 上的所有算法和数据结构,包含设计者、设计时间和复杂度;CC0)、pwc-archive(存档于 Hugging Face 的 Papers With Code 方法和数据集目录,已剔除呼叫中心垃圾内容;CC BY-SA 4.0)、rosetta-code(所有编程任务及解决这些任务所用的语言;GFDL)、thealgorithms(The Algorithms 各仓库 DIRECTORY.md 中按语言列出的实现;MIT)。docs/algorithms.md | 否 | | 模型 | modelsdev(models.dev 上的所有 AI 模型及其费用;MIT)。每个供应商提供项占一行,而非每个模型占一行,因为同一个模型可由 223 家供应商提供,价格也各不相同:每百万输入、输出和缓存 token 的价格、上下文和输出限制、模态及能力标记,共 8,179 项。此外还有实验室目录,其中每个模型各占一项,按照制造商发布的内容记录,并链接到其专属页面;以及供应商本身。openmodel(供应商位于 /.well-known/openmodel.json 的自有文件;只有在文件由其所描述的源站提供时才予以采信;使用与旁边 models.dev 条目相同的词汇,因此一个信息源即可同时涵盖两者)。docs/models.md | 无需密钥(GITHUB_TOKEN 可提高搜索和信息补充的速率限制);但 glama-mcp 需要 GLAMA_API_KEY,未配置时会保持暂停 | | mcp | mcp-registry(官方注册表:每个服务一行,采用其最新版本,包含软件包、远程服务和状态)、docker-mcp(Docker 的目录:拉取次数、类别、许可证及各服务公开的工具)、smithery(每个服务通过 Smithery 代理实际被调用的频率)、awesome-mcp(punkpeye、wong2 和 appcypher 列表,以及协议仓库中的参考服务)、aitmpl-mcps(现成配置)、github-mcp-topics(标记为 MCP 的仓库,按最近推送时间排序)、installmap-yc-mcp(通过 Installmap 的 CC BY 爬取结果收录的运行服务的 Y Combinator 公司,记录为 OpenMCP,并探测其端点,同时包含各公司的账号和创始人;公司和创始人也会通过 installmap-yc-people 作为 OpenProfiles 收录到 profiles 中)、glama-mcp(最后处理 Glama 目录,因此只会补充其他来源都未收录的服务;且仅收录 Glama 质量评分不低于 3.5、仓库属于列表维护者的服务,从而排除克隆垃圾内容)。数据已获授权,因此每条 Glama 记录都会显示“来自 Glama 的 MCP 数据”以及指向其 Glama 条目的链接)。按 URL 去重:最先收录某服务的来源会保留该服务。docs/mcp-and-workflows.md | 无需密钥(GITHUB_TOKEN 可提高搜索和信息补充的速率限制),但 glama-mcp 需要 GLAMA_API_KEY,未配置时会保持暂停 | | 工作流 | reddit-workflows(r/ClaudeWorkflows 库,每个工作流一篇帖子,并从帖子中解析其评分、新旧程度、级别和类别)、awesome-claude-code(读取生成该列表所依据的 CSV,因此会跳过维护者已标记为失效的条目)、aitmpl-components(设置包、Agent 循环和行为修改项)、github-agent-topics(标记为 Claude Code、技能和子 Agent 的仓库)。可通过 /workflows 和 /c/workflows 访问。docs/mcp-and-workflows.md | 无需密钥(GITHUB_TOKEN 可选,同上) | | 技能 | aitmpl-skills(890 项技能,包含安装次数和各自的安装命令)、awesome-claude-code-skills(精选技能)。/skills | 否 | | Agent | aitmpl-agents(按类别划分的 420 个子 Agent)、awesome-agents(注明每个子 Agent 名称而非其所属软件包名称的社区列表;由 VoltAgent 提供初始数据)。/agents | 否 | | 命令 | aitmpl-commands(290 个斜杠命令,包含安装次数)。/commands | 否 | | 插件 | plugin-marketplaces(你指定的仓库中 .claude-plugin/marketplace.json 声明的所有插件,包括官方市场)。/plugins | 否 | | 钩子 | aitmpl-hooks(在工具调用、提示词或会话前后运行的内容)。/hooks | 否 |

版主

一个细分领域可以设有版主:他们会审核推荐到其集合中的内容,但不负责运营。任何已登录用户都可以在 /<niche>/moderate 申请(三个问题);申请会作为带有相应角色标记的申请记录,和其他所有申请一起列在 /admin/knowledge,并且只有管理员可以作出决定。获批的版主是细分领域成员,分享上限为零,也没有积分记录:担任版主没有收益,也不是晋级阶梯上的一级。一个细分领域可以有多位版主。版主可以查看 /admin/submissions 中按其细分领域所供给集合筛选的推荐队列,只能批准内容进入该集合,并且导航栏中会显示「队列」链接。

网站(/c/sites)

每个页面一条记录,按照 OpenSite 的说明读取:标题、简介、卡片所用图片和类型、作为键的规范地址、作者、信息流,以及原样保存的 og:、twitter: 和 JSON-LD 标签。opensite 适配器会遍历每个自有站点的首页和站点地图,每次运行抓取 100 个页面,同时遵守 robots.txt 和站点自己的 /.well-known/opensite.json。有人在 /c/sites/add 粘贴其他地址时,系统会立即读取;随后会显示所有标签,以及 X、Slack、iMessage、Discord、LinkedIn 和 WhatsApp 会如何绘制该卡片。同样的读取也可通过 POST /api/v1/sites { "url" } 执行,而 GET /api/v1/sites?url= 则返回已保存的记录,或者在记录超过一小时时重新读取页面。在同一页面粘贴或上传的整份列表(最多 10,000 个地址;也可通过 POST /api/v1/sites/bulk 传入 JSON urls 或纯文本正文)会成为提交者的一个数据源:工作进程每次运行抓取 250 个页面,间隔一分钟;/s/<slug> 会显示进度。由于列表会让部署按计划抓取,因此需要已登录的账号。页面路径为 /c/sites/<host>/<path>,包括查询字符串,因为页面的身份可能由其查询参数决定。

歌词(/lyrics)

Profullstack 自有乐队(Þrøngva、Velocity Vibe、Meine Mutter)的歌词,由 nixamp 电台服务器读取和写入:/lyrics、/lyrics/<artist>、/lyrics/<artist>/<title>,以及 GET/POST/DELETE /api/v1/lyrics。仅限我们自己的歌词(source 为 embedded、author 或 transcribed);不会从歌词网站导入任何内容。写入需要具有 lyrics 权限的密钥(scripts/lyrics-key.js)。参见 docs/lyrics.md。

顶级域名(/tlds)

IANA 根区中的所有标签每天读取一次,并生成变更日志;没有其他地方发布这份日志。每个注册商的一年期注册、续费、转移和恢复价格也会一并列出:目前包括 Porkbun、Dynadot、Cloudflare 和 OVHcloud,以及任何提供 OpenTLD 文件的注册商。可按类型、续费价格区间、注册商、文字系统、状态和注册局筛选;每一列均可排序,默认优先显示续费价格,并可单独筛选续费陷阱(第二年价格达到第一年的两倍或更高)。/tlds/check 会通过 RDAP 向各注册局查询域名是否已被注册,绝不会把 404 称为「可注册」。相同的数据也可通过 GET /api/v1/tlds(JSON 或 CSV)、MCP(search_tlds、get_tld、tld_changes、check_domain)和 CLI(nichedb tlds、nichedb check)获取。参见 docs/tlds.md。

自有聚合器

我们运营的 10 个站点中,有 10 个会发布自己的公开 feed 或 API;这里都通过它们读取数据,无需密钥,就像其他任何读取方一样。端点是于 2026-09-12 实时检查的端点(c0upons 于 2026-09-13 检查);slug 是预置的来源。

站点端点集合来源 slug类型
p0dcasters.com/opml(每个节目:feed、站点、标题)podcastsp0dcasters-showsshow
saasrow.com/api/v1/products(按偏移量分页,每页 100 条)saassaasrow-productsproduct
d0rz.com/asks/rss.xml、/offers/rss.xmlmarketplaced0rz-marketplaceask、offer
bl0ggers.com/asks/rss.xml、/offers/rss.xmlmarketplacebl0ggers-marketplaceask、offer
aiornot.vote/rss.xml、/rss/featured.xml、/rss/trending.xmlai-mediaaiornot-mediasubmission
agenticjobs.work/api/v1/jobs(按偏移量分页,每页 100 条)jobsagenticjobs-postingsjob
outreachgraph.com/api/v1/public/directory(按游标分页,每页 200 条;按域名获取公司和站点,仅获取自行发布的人员信息)directoryoutreachgraph-directorycompany、site、person
tsbb.dev/api/v1/forums,然后按论坛读取 /f/{slug}/feed.xmlforumstsbb-topicspost
c0upons.com/api/coupons(按偏移量分页,每页 200 条,包含关联的商店;跳过 source: nichedb 的行)couponsc0upons-couponscoupon
bittorrented.com通过站点自己的 Supabase 使用 PostgREST rpc/browse_dht_torrents,从游标指定的日期开始查询,每页 500 条(该站点没有提交或导出端点)dhtbittorrented-dhttorrent
c0ncerts.com暂无:/api/events 返回 501 “coming soon”,而 /api/v1/events 返回 404———

saasrow 的 /api/v1/listings 是按账户提供的,需要密钥,因此这里只读取公开的产品目录。aiornot 中同时出现在多个 feed 上的提交只存储一次,并标记上每个 feed。tsbb 的跨论坛 /api/v1/latest 不会说明某个主题属于哪个论坛,因此需要逐个论坛遍历。

Ruuster 房屋搜索

ruuster-san-jose-homes 每小时读取 Real Estate Experts / Talar Davoudi 保存的搜索,并将结果写入 /f/san-jose-homes。该搜索查找 San Jose 的房屋,状态为 Active 或 Coming Soon,卧室数不少于 2 间,浴室数不少于 1 间,面积不少于 750 平方英尺,地块面积不少于 4,500 平方英尺,且建成年份为 2000 年或之后。Ruuster 将地块面积筛选项称为 lotSizeAcresMin,但此处接受的是平方英尺;房产记录返回的是英亩,NicheDB 会保留这两种单位。搜索结果和尺寸均为上游观测值;对于冲突的 MLS 值,不会静默修正。

创建另一个 ruuster 数据源,并设置其 savedSearchUrl、pages(默认值为 20,每页十条记录)和 currency(USD 或 CAD)。系统会移除跟踪参数,并合并重复的状态筛选条件。公开详情请求会补充照片、房产信息和 MLS 归属信息。系统会按 MLS 房源编号和地址合并联合发布的副本。隐藏地址和已删除的记录会被省略。系统会遵守工作器的详情请求预算和截止时间,并为未完成的页面保留游标;已完成的遍历会在下次刷新时从第 1 页开始。

条目会保留与搜索匹配时最后观测到的状态。房产从搜索中消失并不能证明它已售出;该数据源也不会在房源离开搜索后重新检查所有历史房源。

针对已配置的数据库运行 bun run ingest ruuster-san-jose-homes;若要在不使用数据库的情况下导出,则运行 bun scripts/scrape-ruuster.js > properties.json。导出命令还接受保存的搜索 URL,以及作为位置参数提供的可选新输出文件名。Ruuster 的条款限制未经书面同意的自动访问,其 IDX 声明也限制了内容再利用;部署此适配器并不授予再分发权:https://realestateexperts.ruuster.com/terms-of-service。

MusicBrainz Web 服务请求共用一个进程级队列,请求之间至少间隔 1.1 秒。遇到 429 或 503 时,最多重试三次,退避时间分别为 5、15 和 45 秒,并遵循更长的 Retry-After 值(包括 HTTP 日期)。重试提示为 0 不会导致立即重试。此队列仅覆盖单个工作器进程;若多个进程共用一个出口 IP 部署,还需要在这些进程之间协调。

丰富

采集后,每个条目都会由适用于它的丰富器处理(packages/enrichers/src),结果保存在条目的 enrichment.<name> 下:

丰富器添加内容默认启用的集合
youtube热门视频(预告片、官方音频、网络直播);可选 Data API 密钥游戏、音乐、桌面游戏、太空、国际象棋、图书
wikipedia条目的导语和图片游戏、音乐、图书、太空、桌面游戏、托管
github-repo星标、复刻、主题、许可证、语言、最近推送时间软件包、扩展、mcp、工作流、技能、Agent、命令、插件、钩子
npm-stats上周的下载量软件包
sec-company申报方的股票代码、交易所、行业、州、网站申报文件
company-ticker托管提供商背后的上市公司:从 SEC 公司列表中获取股票代码和 CIK,并按名称匹配托管
developer官方 CLI 及其安装命令(从供应商指南读取,或按域名与 Homebrew、npm 和 Terraform 注册表匹配)、API 文档、Terraform 提供商、状态页托管
semantic-scholar摘要、引用次数、开放获取 PDF(可选密钥)研究
openlibrary-work描述和主题图书
opengraph页面自身的预览图片和描述大多数集合
tmdb-artwork对于从 IMDb 转储中导入且没有海报、背景图、剧情简介、评分和 TMDB ID 的影片,补充这些信息(TMDB_API_KEY)影视
corpusdata如果提供了 data.corpusdata.articles,则根据标题/正文/日期/实体信号匹配经过验证的 NOW 文章;否则提供查找链接新闻、研究、图书、AI 媒体、托管、软件包

Feed 的 enrichers 列表决定要显示哪些丰富器;未设置时使用集合默认值。Feed 构建器会将它们显示为复选框。条目只丰富一次,按最新优先,并在各集合间公平分配(每次处理 ENRICH_PER_RUN 个条目,每个集合最多处理 ENRICH_PER_COLLECTION 个)。丰富器找到的信息会补充缺失的图片、摘要或标签,而来源自身的文字始终优先。

运行

git clone https://github.com/profullstack/niche-db && cd niche-db
bun install
docker compose up -d db redis          # or point at your own Postgres 16+ and Redis
cp .env.example .env                    # DATABASE_URL, SITE_URL, CONTACT_EMAIL at minimum
bun run build:client
bun run dev                             # web + worker in one process on :3000

迁移会在启动时自动应用。首次启动时会为每个集合及其默认来源和 Feed 创建初始数据;对于适配器需要但部署环境不具备的凭据,对应来源会以暂停状态创建。第一个登录的账户将成为管理员。

bun run ingest [slug ...] 可在终端中运行来源,无需 Redis。bun test 会使用进程内 Postgres(PGlite)运行测试套件,因此无需服务器。

使用界面

  • Web:PWA。/sources 用于管理来源(状态、上次运行、下次运行、立即运行、暂停、编辑配置)。/feeds/new 用于创建 Feed,并提供实时预览。/settings 包含通行密钥、API 密钥和通知设置。
  • RSS / JSON Feed:/f/<slug>.rss、/f/<slug>.json。
  • API:/api/v1,文档见 /docs/api。读取无需密钥。
  • CLI:curl -fsSL https://nichedb.dev/install.sh | sh(如果已安装 bun 则使用 bun,否则使用 npm 和 Node 22+,无需 sudo),或运行 npm i -g @profullstack/nichedb → nichedb。文档见 /docs/cli。
  • MCP:/mcp(Streamable HTTP,无状态),或通过标准输入/输出运行 nichedb mcp。文档见 /docs/mcp。
  • llms.txt:/llms.txt 用一份文档介绍整个部署。

账户与资金

仅支持 Magic link 和 passkey;数据库中没有密码列。API 密钥在设置中生成,并且只显示一次。

免费页面和信息流会展示一则 CrawlProof 广告和一个跟踪器(CRAWLPROOF_AD_SLOT、CRAWLPROOF_SITE_ID)。两个付费等级都可移除这些内容,均通过 CoinPay 支付:

  • Premium — 每天 $1、每月 $30 或每年 $300(/premium)。无广告、无跟踪,可访问会员 Lounge,每月有 1,000 积分可用于打赏、专属徽章、六种主题和五种应用图标、新合集抢先体验、每小时 30,000 次 API 请求、无限信息流、自有来源,以及包含按量计费的车辆查询。/premium 提供与 Reddit Premium 的逐项对比;GET /api/v1/premium 提供相同内容的 JSON 版本。参见 docs/premium.md。
  • Pro — 每月 $120(/pro)。包含 Premium 的所有权益,另外每小时可发起 120,000 次 API 请求,并在整个订阅期内获得抓取通行证(GET /api/v1/crawl-pass),让会员自己的 Agent 可以绕过付费墙。

推荐链接可为新客户提供 20% 的折扣,并让推荐人获得首笔付款的 60%。

训练爬虫(GPTBot、ClaudeBot、CCBot、meta-externalagent…)会收到带有 x402 报价的 402 响应,并可在 /crawl 购买通行证:每天 $1 即可访问所有内容;买家在此处的累计消费越多,每天的价格越低(CRAWL_LOYALTY,默认消费满 $10 后折扣 20%、满 $50 后折扣 40%、满 $100 后折扣 60%;每笔销售都会记录在 crawl_sales 中)。通行证可通过 ?disable=ads,tracking 关闭其自身请求中的广告或跟踪。用户、搜索引擎和检索爬虫不受影响。

知识影响者

这里的每个合集也都是一个可运营的细分领域。知识影响者是了解某个行业实际运作方式,并负责监督 Agent 为该领域构建软件、数据和推广内容的人——无需编写代码。其初始分成比例为该领域收入的 20%,随着经核实的贡献不断累积,最高可升至 80%。

/opportunities 会列出正在寻找运营者的细分领域。/<niche> 是该领域的公开页面(还包含供 Agent 使用的 skill.md 和 manifest.json),/@<handle> 是运营者的个人资料,/dashboard/niches 是运营者自己的视图,/admin/knowledge 用于核实认领和贡献。

当 Agent 遇到只有亲身做过这项工作的人才能解决的问题时,就会提问:问题会显示在运营者的控制面板上,答案将成为领域知识和经评分的贡献,并通知 Chovy。回答“上下文不足”也是受认可的回答,且不会产生费用,因为对该领域而言,一个经核实的猜测不如一个公开提出的问题。参见 docs/agent-questions.md。

评分只依据经他人核实的贡献,贡献数量不会提升评分:同一类型的提交次数越多,每次获得的分数越少;任何声称涉及客户或付款的内容都需要外部依据;重复内容只计一次。评分等级定义在 contribution_tiers 中,因此部署方可以进行调整。细分领域的收入会在结算时按当时生效的分成比例分配,因此即使等级明天发生变化,也不会重新计算昨天的销售收入(docs/revenue-ledger.md)。参见 docs/knowledge-influencers.md 和 docs/revenue-share.md。

技术栈

Bun、Hono(服务端渲染 JSX)、通过 Bun 原生驱动连接的 Postgres、基于 Redis 的 BullMQ、Biome。bun apps/worker/src/enrich-cli.js [n] 可从终端运行数据丰富任务。共享的 Profullstack 模块:@profullstack/x402-gateway、@profullstack/emailer、@profullstack/coinpay、@profullstack/referrals、@profullstack/api-key-manager、@profullstack/autoblog(签名 Webhook)、@profullstack/favicon-generator。

品牌素材

brand/logo.svg 是可编辑的 SVG 源文件。运行 bun run build:brand,使用 SVGCrusher 将其压缩为 favicon.svg,然后运行已安装的 fav CLI,重新生成 apps/web/public/icons。构建还会更新 /logo.svg、/favicon.svg、成员配色方案和可遮罩应用图标。页面和应用清单优先使用 SVG;PNG 和 ICO 则作为备用格式。可在 brand/preview.html 中预览所有素材。

SVGCrusher 的首个 CLI 版本随项目打包在 vendor/ 中,因此在全新检出后、发布到 npm 之前,该命令也能正常运行。其独立源代码位于 profullstack/svgcrusher。

配置

所有配置都从环境变量读取一次,配置文件位于 packages/config/src/index.js;.env.example 列出了所有变量。生产环境密钥存放在 nichedb--prod logicsrc 保管库中:

bun run secrets:pull     # logicsrc teams pull profullstack nichedb prod --env .env
bun run secrets:push     # after adding a key locally

ROLES=web,worker 可在一个容器中运行所有服务;当单个实例不再够用时,可在第二个服务上设置 ROLES=worker,将数据导入任务拆分出去。

部署

一个 Dockerfile、一个 Railway 服务,以及 Railway 的 Postgres 和 Redis。railway.json 将健康检查路径设为 /healthz。在任何人注册通行密钥前,将 SITE_URL 设为公开来源站点地址:通行密钥的依赖方 ID 源自该地址。

添加适配器

import { defineAdapter } from '@nichedb/core/adapter';

export const example = defineAdapter({
  name: 'example',
  title: 'Example API',
  collection: 'packages',
  description: 'What it watches, in one paragraph.',
  kinds: ['thing'],
  cadenceMinutes: 30,
  configFields: [{ key: 'topic', label: 'Topic', required: true }],
  defaultSources: [{ slug: 'example-default', name: 'Example', config: { topic: 'all' } }],
  async pull({ config, cursor, http, log, budget, deadline }) {
    const page = await http.json(`https://example.com/api?topic=${config.topic}&since=${cursor.since ?? ''}`);
    return {
      items: page.results.map((r) => ({ externalId: r.id, kind: 'thing', title: r.name, url: r.url, publishedAt: r.at, tags: r.tags, data: r })),
      cursor: { since: page.next },
      note: `${page.results.length} things`,
    };
  },
});

在 packages/adapters/src/index.js 中注册。核心会规范化条目、为条目生成哈希值(这样未更改的行无需写入),分批写入,记录运行情况并重新安排任务。

流式读取数据转储

读取数 GB 文件(MusicBrainz、Discogs、Open Library、Podcast Index)的源无法返回一个数组:文件无法全部装入内存,遍历也无法在一次运行中完成。相反,pull 会分批生成数据,核心逐批处理,写入每批数据,并在读取下一批之前保存游标。pull 是一个 async * 生成器(或返回 { items: <async iterable> },效果相同),每个生成的值都是 { items, cursor },生成器的 return 值则是本次运行的 { cursor, note, nextInMinutes }。

import { dumpDir, gzipLines } from '@nichedb/core/dump';

export const example = defineAdapter({
  name: 'example-dump',
  // ...
  cadenceMinutes: 60,
  budgetMs: 60 * 60_000,
  async *pull({ cursor, http, log, deadline }) {
    const version = await http.text('https://example.com/dumps/LATEST');
    const skip = cursor.version === version ? Number(cursor.skip) || 0 : 0;
    if (cursor.version === version && cursor.done) return { cursor, note: 'unchanged' };

    const dir = await dumpDir('example');
    const file = `${dir}/${version}.ndjson.gz`;
    const dl = await http.download('https://example.com/dumps/latest.ndjson.gz', file);
    if (!dl.complete) return { cursor: { version, skip }, note: 'download in progress', nextInMinutes: 1 };

    let n = skip;
    let batch = [];
    for await (const line of gzipLines(file, { skip })) {
      n += 1;
      batch.push(toItem(JSON.parse(line)));
      if (batch.length === 500) {
        yield { items: batch, cursor: { version, skip: n } };
        batch = [];
        if (Date.now() > deadline) return { cursor: { version, skip: n }, nextInMinutes: 1 };
      }
    }
    if (batch.length) yield { items: batch, cursor: { version, skip: n } };
    return { cursor: { version, skip: n, done: true }, note: 'complete' };
  },
});

规则如下:

  • budgetMs 是本次运行的墙钟时间预算,取代此适配器的 INGEST_RUN_DEADLINE_MS(4 minutes)。回收器窗口和 BullMQ 锁会延长至声明的最大预算,因此可以安全地声明一小时的预算。核心会以 deadline 的形式传回该值;请在批次之间检查它,并在到期时返回。如果某个批次写入时已超过截止时间,核心也会结束本次运行,并在一分钟后重新调度;但适配器先行检查,才能确保运行不会超出锁的时限。
  • 每个批次的 cursor 是该批次数据之后的位置(行数、字节偏移量、最后一个 ID),以及用于标识文件的信息(转储日期、版本、LATEST 值),这样上游文件更新时就会重置遍历进度。批次写入表后会立即保存游标。至少一次投递没有问题:崩溃后重新写入的批次会针对 (source, externalId) 执行幂等 upsert,未更改的行不会产生额外开销。
  • 使用 return 返回最终的 { cursor, note, nextInMinutes }。nextInMinutes: 1 会让未完成的遍历在调度间隔之间继续推进;如果上游文件没有变化,游标中的 done: true 可让下一次运行直接结束。
  • http.download(url, path, { timeoutMs, headers, onProgress }) 会将数据流式写入磁盘,并从已有数据处通过 Range 续传(206 时追加,200 时重新开始,416 表示已完整下载)。它会返回 { path, bytes, complete };如果 complete: false,请返回,并在下次运行时再次调用。请求会发送 user agent;Podcast Index 不接受没有 user agent 的请求。Discogs 会忽略 Range 并严格限制请求频率:请做好重新下载的准备,并将请求频率控制在每小时几次。
  • dumpDir(name) 是文件存放位置:设置了 INGEST_DATA_DIR 时位于该目录下(请在此处挂载卷),否则位于操作系统临时目录中,而临时目录会在重新部署时清空。游标记录遍历进度;目录只是缓存。
  • 读取器:gzipLines(path, { skip })、xzLines(path, { member, skip })(MusicBrainz:member: 'mbdump/artist',主机上需要安装 xz)、tsvJsonLines(path, { skip })(用于 Open Library 的五列数据,每条记录都包含自己的 lineNo)、lineOffsetReader(path, { offset })(用于需要定位读取的普通文件)、untar(path, dir) 和 sqliteRows(dbPath, sql)(用于 Podcast Index),以及 bzip2CsvRows(path, { skip, escape })(用于 CourtListener 的 bzip2 CSV 表;采用纯 JS 解码器,无需 bzip2 二进制程序;记录可跨行;未加引号的空字段为 null,"" 表示空字符串;底层的 csvRecords(chunks, opts) 可读取 RFC 4180 或 COPY 的 ESCAPE '\')。每个读取器都会逐行生成内容,因此 skip + 已读取行数 就是文件位置。跳过压缩文件中的内容时,需要从头开始重新解压(gzip 每 GB 需数秒,xz 更慢,bzip2 更慢,约为 10 MB/s);普通文件的 offset 则可直接定位。截断的 bzip2 文件会在最后一条完整记录后正常结束迭代,并通过 onTruncated 报告;损坏的文件则会抛出异常。

许可证

MIT

地理筛选与扫描器上下文

在带有位置的数据集合、搜索和信息流中使用 ?lat=41.88&long=-87.62&radius=10。地理查询介绍 API、CLI/MCP 标志、带权限控制的扫描器目录、覆盖范围语义和迁移。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。