关于 Only Hiring
Only Hiring 是面向求职者的 Reddit 招聘帖职位看板,只收录判断为招聘的帖子,并提供结构化信息、诈骗评分和原帖链接。
主要功能
- 01汇集 Reddit 招聘版块职位
- 02展示薪酬、职位、地点与技能
- 03提供诈骗评分和警示
- 04支持筛选、搜索与排序
- 05保存已申请标记并可选登录
适用场景
- 01查找 Reddit 上的远程或合同工作
- 02按技能、地点或薪酬筛选职位
- 03查看风险提示后前往原帖申请
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://onlyhiring.hassandev.me/mcpclaude mcp add --transport http hassanaziz0012-only-hiring https://onlyhiring.hassandev.me/mcp{"mcpServers":{"hassanaziz0012-only-hiring":{"type":"http","url":"https://onlyhiring.hassandev.me/mcp"}}}在 Cursor 中打开{"servers":{"hassanaziz0012-only-hiring":{"type":"http","url":"https://onlyhiring.hassandev.me/mcp"}}}在 VS Code 中打开{"mcpServers":{"hassanaziz0012-only-hiring":{"type":"http","url":"https://onlyhiring.hassandev.me/mcp"}}}{"mcpServers":{"hassanaziz0012-only-hiring":{"serverUrl":"https://onlyhiring.hassandev.me/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
详细介绍
Only Hiring
一个汇集 Reddit 招聘子版块招聘信息的职位公告板,去除无关内容。
在 r/forhire、r/slavelabour 或 r/DesignJobs 等子版块中,约四分之三的帖子是在宣传自己的服务、讨论或发送垃圾信息。本网站只列出真正有人招聘的帖子。每个职位都包含简短摘要、结构化字段(薪酬、职位、工作模式、地点、技能)以及原始 Reddit 帖子的链接,申请请前往该帖子。
工作原理
[private pipeline (not in this repo)]
scrape new posts → grade each post with a language model → sync to Postgres
│ writes
▼
Neon Postgres, `jobs` table
▲ reads only
│
[this repo, on Vercel] Next.js reads the table server-side and renders the list
- 收集。 管道按计划读取约 19 个招聘子版块中的最新帖子。带有
[For Hire]或[Offer]标签的帖子会被跳过。 - 评估。 语言模型判断每篇帖子是否在招聘、撰写摘要、提取薪酬、技能和地点,并给出 0 到 1 的诈骗评分。
- 发布。 只有招聘帖子才会写入数据库。每篇帖子的正文仅存储开头部分(约 320 个字符);网站会显示自己的摘要,并链接到 Reddit 查看其余内容。Reddit 帖子已删除或移除的职位会从公告板上撤下。
抓取器和评估器不属于此代码库。 一个独立的私有管道会按计划收集和评估帖子,并将结果写入数据库。本仓库仅包含网站,网站始终只从数据库读取数据。
产品规则
| 规则 | 值 | 位置 |
|---|---|---|
| 超过此期限的职位会移至折叠的“较早发布”区域 | 14 天 | src/lib/site.ts |
| 诈骗评分达到或超过此值的职位默认隐藏 | 0.6 | src/lib/site.ts |
| 诈骗评分达到或超过此值的职位会显示警告 | 0.4 | src/lib/site.ts |
| 列表、计数和统计数据刷新 | 每次同步后(refresh.sh),否则每天 | src/lib/db.ts(cacheLife) |
| 职位页面刷新 | 同步添加、更改或移除该职位时;职位过期时;否则每月 | src/lib/db.ts(getJob) |
由于数据集较小,筛选、搜索和排序都在浏览器中进行。筛选条件会保存在 URL 中,因此可以分享筛选后的视图。“已申请”标记存储在访客的 localStorage 中,或存储在其账户中(如果已登录)。账户为可选项(可通过电子邮件和密码或 Google 登录,使用 better-auth);登录后,浏览器中的标记会合并到账户中。访客在未登录时标记职位或打开 Reddit 帖子,只会收到一次创建账户的提示;关闭提示后 14 天内不会再次出现。
本地运行
要求:Node 20+ 和 npm。
npm install
cp .env.example .env.local # then set WEB_DATABASE_URL (and optionally REMOVAL_EMAIL)
npm run dev
WEB_DATABASE_URL 是 Postgres 连接字符串,对应的角色只能对 jobs 表执行 SELECT。
DATABASE_URL 是另一个独立的 Postgres 数据库,用于存储账户及其已申请标记;使用 db/schema.sql 创建其中的表。BETTER_AUTH_SECRET 用于签署会话 Cookie(openssl rand -base64 32)。
GOOGLE_CLIENT_ID 和 GOOGLE_CLIENT_SECRET 是可选项,设置后会启用“使用 Google 继续”。它们来自 Google Cloud Console 中类型为“Web application”的 OAuth 客户端,并需将 https://<your domain>/api/auth/callback/google 设为授权重定向 URI(本地使用时添加 http://localhost:3000/...)。只有在构建时同时设置了这两个变量,才会显示该按钮。
REMOVAL_EMAIL 是可选配置:页脚和 About 页面中用于接收移除请求的邮箱地址。它会在构建时由服务器读取。若未设置,网站会改为链接到此仓库的问题跟踪页。
RESEND_API_KEY 是可选项:它会将每条来自页眉“反馈”对话框的消息发送到 REMOVAL_EMAIL,发件地址为 [email protected](该域名已在 Resend 验证)。消息也会存入账户数据库的 feedback 表,因此即使邮件发送失败也不会丢失(emailed 会保持为 false)。每个 IP 每小时最多可发送 5 条消息。
在 Vercel 上,为 Production 和 Preview 设置这些项目环境变量。
如果无法连接数据库,网站仍会完成构建并显示“职位列表未能加载”状态,然后每分钟重试一次。
其他脚本:npm run build、npm run start、npm run lint。
npm run dev 和 npm run build 会先运行 scripts/fetch-fonts.mjs,从 Fontshare 下载 Pilcrow Rounded 字体文件到 src/app/fonts/。该目录有意加入了 gitignore;请参阅许可证。
代码结构
src/
app/
page.tsx home: masthead + job board (server component)
jobs/[id]/page.tsx job detail, prerendered for every job
about/page.tsx how it works, scam scores, limits, removal requests
robots.ts, sitemap.ts, opengraph-image.tsx, icon.svg
components/
account/ sign-in dialog, header link, session sync
FeedbackNav.tsx header Feedback link and dialog (posts to app/api/feedback)
board/ client-side filters, search, sorting, grouping
JobItem.tsx one job in the list
JobDetail.tsx the detail view
lib/
db.ts the only database code (server-only, cached)
jobs.ts row type, defensive parsing, expiry and scam rules
labels.ts human labels for enum-like columns
format.ts pay, date and time formatting
applied.ts the "applied" store: localStorage, or the account when signed in
auth.ts better-auth config and the accounts database (server-only)
site.ts site name, thresholds, removal contact
此应用使用启用了 Cache Components 的 Next.js 16(cacheComponents: true),因此使用 "use cache" 和 cacheLife 进行缓存,而不是使用 export const revalidate。
每次同步后,流水线都会运行 refresh.sh,将同步新增、修改或移除的职位(来自流水线的 last_sync.json)发送到 /api/revalidate。只有这些职位页面会重新构建:每次重新构建都会将页面、其预取片段和图片写入 Vercel 的 ISR 缓存,而 Hobby 计划每月允许写入 200,000 次。部署时无论如何都会使用全新的缓存。如果在流水线之外(例如直接在数据库中)更改了职位,请运行 ./refresh.sh --all 重新构建所有职位页面。
设计方向
一种图案:方括号。 招聘相关的 Reddit 子版块用户会在真实职位的标题前加上 [Hiring]。方括号是网站唯一的形状,会出现在四处:
- 名称
only [hiring]。 - 页面加载时,两个大括号会给标题加上“标签”。这是页面上唯一一种无需点击就会运行的动画。
- 每个职位的发布时间会显示在左侧栏的方括号标签中,例如
[3h]。 - 选中的筛选条件会像帖子标题一样加上方括号。
颜色。 只有一组配色,每种颜色各有一种含义。薄荷绿代表我们保留的内容(页眉、选中的筛选条件、申请面板)。粉色代表我们标记的内容:诈骗警告、隐藏诈骗提示,以及提醒你在申请前检查帖子的页脚。深绿色仅用于操作。其他部分采用近白色底色和近黑色文字,通过色调而非线条或阴影区分表面。深色模式沿用相同的颜色角色,采用深绿黑配色,并遵循 prefers-color-scheme。
字体。 采用 Indian Type Foundry 的 Pilcrow Rounded,并自托管。展示文字使用粗体、紧凑的小写样式,正文使用常规字重。字体大小仅有五种:小号、正文、导读、标题和展示。
布局。 列表像菜单一样呈现:按天显示带数量的标题,职位名称靠左,薪酬在同一行右对齐,类似价格。没有卡片、边框或阴影。桌面端的筛选条件显示在固定侧栏中。手机端则从固定搜索栏打开底部面板。
动效。 动效响应访客的操作:切换开关、筛选面板和选中时出现的方括号标记。所有动效都遵循 prefers-reduced-motion。
艺术指导方向采用了 frontend-design 和 taste-skill 设计技能。新增内容必须遵循这些规则。不要添加第二种形状、第三种颜色、第二种字体或装饰性动效。
已知限制
- 已删除的帖子会保留到下一次运行数据管道。 每次运行都会重新检查过去 14 天内的职位,并移除其 Reddit 帖子已被删除或移除的职位。更早的职位不会重新检查,因此链接可能失效。
- 薪酬不会换算。 金额保留帖子的原始货币。按薪酬排序时,会按薪酬类型和货币对职位分组,而不会跨货币比较。
- 评级可能有误。 摘要、字段和诈骗评分均由语言模型生成。网站会说明这一点,并提醒访客前往 Reddit 核实帖子。
法律声明
本项目与 Reddit, Inc. 无关,也未获其认可或赞助。Reddit 是 Reddit, Inc. 的商标。我们只存储和展示每条 Reddit 帖子的开头几行;每条职位信息都链接到原始帖子。移除请求请发送至网站页脚中显示的联系方式。
许可证
代码根据 MIT License 发布。
字体 Pilcrow Rounded 不适用 MIT 许可证。它归 Indian Type Foundry 所有,并根据 ITF Free Font License 获得许可;该许可证允许在自己的网站上自托管,但不允许重新分发字体文件。因此,本仓库不包含这些文件:构建过程会从 Fontshare 获取你自己的字体副本,该副本同样受此许可证约束。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。