mcpField
P
Purl

Purl

远程服务
github.com/nublson生产力32 天前更新
代码仓库

关于 Purl

Purl 是面向希望集中整理和分享有用网址的链接管理服务。它可识别网页、PDF、YouTube 视频和音频,并通过应用、REST API 与 MCP 服务提供已保存链接。

主要功能

  1. 01按内容类型识别并保存网址
  2. 02获取标题和预览元数据
  3. 03按相对日期分组链接
  4. 04在文件夹中整理链接
  5. 05跨设备同步列表变更

适用场景

  1. 01集中保存文章、PDF、视频和音频链接
  2. 02通过应用或 API 查找已保存的链接
  3. 03通过 MCP 客户端访问保存的链接

MCP 相关

Purl 提供 MCP 服务,可用于保存、列出、获取和移动链接,以及管理文件夹。MCP 访问支持 API 密钥或 OAuth 身份验证。

配置

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

服务地址https://purl.live/api/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 配置后重启。需要授权的服务会在首次连接时提示登录。

全部服务地址
Streamable HTTPhttps://purl.live/api/mcp需要授权

工具

详细介绍

Purl — 保存任何内容。留住重要的内容。为你的链接、PDF、视频和音频打造一个归属之处。

Purl

保存值得珍藏的链接。分享值得传递的链接。

在线预览: https://purl.live

Purl 是一个宁静的空间,让你保存和分享找到的链接——也是你的“珍珠”的归属之处。粘贴 URL 即可保存:网页、PDF、YouTube 视频和音频。Purl 会解析每项内容的元数据(标题、网站图标、描述、缩略图),并将所有内容集中保存,让你可以通过应用、REST API 和 MCP 服务访问。

Purl 免费使用,但有一项限制:每个账户最多可保存 1,000 个链接(src/lib/limits.ts 中的 MAX_SAVED_LINKS)。

产品目标:为你关心的链接提供一个集中存放的地方,并让值得传递的链接易于分享。

当前已实现

  • 营销网站 — 着陆页(包含实时预览的主视觉区域)、REST API 和 MCP 服务文档、隐私政策和服务条款。
  • 身份验证 — 通过 Better Auth 在着陆页使用 Google 和 GitHub 登录(设置相应环境变量后也可使用 Apple)。每个账户都会获得唯一的用户名,可在设置中编辑;你也可以在此连接或断开登录方式。头像来自 OAuth 提供方的个人资料照片。
  • 保存和整理
    • 通过 URL 添加内容,并自动检测内容类型(网页、PDF、YouTube、音频)。
    • 链接按相对时间分组(例如:今天、本周、上个月)。
    • 预览元数据(标题、描述、网站图标,以及可用时的缩略图)。
  • 强化的出站请求安全 — 服务端 safeFetch,支持可选的代理/DNS 控制(参见 AGENTS.md)。可通过 SAFE_OUTBOUND_HTTP_PROXY 配置出站代理。
  • 实时列表同步 — 使用 Supabase Realtime,让保存和更新快速同步到其他标签页/设备。
  • 链接操作 — 打开原始链接、复制 URL、编辑元数据、删除。
  • REST API 和 MCP — /api/v1(链接和文件夹)以及 MCP 服务(save_link、list_saved_items、get_link、move_link、list_folders、create_folder、update_folder、delete_folder),支持 API 密钥或 OAuth 身份验证。
  • 运维补充功能 — 可选的 Upstash API 速率限制,以及针对关键路径的 Vitest 覆盖率测试。
  • PWA(可安装应用) — Web App Manifest 以及一个 Serwist 服务工作线程(src/app/sw.ts),构建后生成 public/sw.js(运行 pnpm build 时生成,并被 git 忽略)。在平台支持的 Chrome/Edge 等浏览器中启用安装功能,并通过 Serwist 的 Next.js 默认设置实现运行时缓存,同时提供位于 /~offline 的静态离线页面。在 pnpm dev 中会禁用 Serwist,以避免开发期间出现意外的服务工作线程缓存问题——请使用 pnpm build && pnpm start(或生产环境 URL)测试安装功能和服务工作线程。

保存流程

保存链接完全采用同步方式——不会进行后台处理。

  1. 输入 — 使用 URL 调用 POST /api/links(也可使用 /api/v1/links 和 MCP 的 save_link 工具)。
  2. 分类和补充信息 — 服务端使用 detectContentType(安全防范 SSRF 的 HEAD 请求/内容嗅探)和 scrapeLinkMetadata(Open Graph HTML、PDF 的 Content-Disposition/大小、YouTube oEmbed)。再次保存已有 URL 时,会刷新其元数据并将其移至列表顶部。
  3. 持久化 — 创建包含标题、网站图标、缩略图、域名和 contentType(WEB、PDF、YOUTUBE 或 AUDIO)的 Link 行。
  4. 同步 — broadcastLinksChanged 通过 Supabase Realtime 通知其他标签页/设备。

尚未实现

由于该仓库即将公开,以下事项被明确列出:

  • 设置范围 — 设置涵盖用户名、登录方式和账户删除;更广泛的账户偏好设置(通知设置等)尚未实现。

营销内容与产品功能: 落地页文案提到了合集和每周摘要等构想。当前架构或应用中尚未实现这些功能——应将其视为路线图内容,而非已发布功能。

技术栈

  • Web: Next.js(App Router)、React、TypeScript
  • UI: Tailwind CSS、shadcn/ui
  • 身份验证: Better Auth
  • 数据库: PostgreSQL + Prisma
  • 电子邮件(开发环境中可选): 使用 Resend 发送反馈邮件
  • 实时功能: Supabase 客户端(匿名密钥 + 服务端服务角色)
  • PWA: Serwist(@serwist/next)、Web 清单 + 预缓存 / 离线回退

CI / GitHub Actions

自动化流程位于 .github/workflows/ 下。每个 PR 和手动发布都必须通过这些流水线。

PR 检查 — pr-checks.yml

在针对 develop 和 main 的 pull_request 上运行:设置与验证 → Prisma(生成客户端 + 类型修复)→ Lint 和 类型检查(并行)→ 测试 和 生产构建(并行,在 Lint 和类型检查通过后运行)。并发按 PR 隔离,因此新的推送会取消过时的运行。

pr-checks.yml 的 GitHub Actions 流程图:设置、Prisma、Lint 和类型检查、测试和构建

发布 — release.yml

在 workflow_dispatch(手动触发)时运行:将 develop 合并到 main,然后进行构建验证,确保仅在构建通过后才将版本推广到生产环境。

release.yml 的 GitHub Actions 流程图:将 develop 合并到 main,然后进行构建验证

安全

Purl 围绕不可信输入(任意 URL)构建。生产环境中有几个重要的安全层:

  • 考虑 SSRF 的出站请求 — 用户提供的 URL 不会直接传给原始 fetch。OG/缩略图探测、PDF 获取、内容类型嗅探等路径都会通过 safeFetch:仅允许 HTTP(S),屏蔽私有、链路本地和保留地址目标,处理重定向时逐跳检查主机,并在连接前固定 DNS 解析结果(缓解针对预检查的经典 DNS 重绑定攻击);还可选用响应大小上限(例如 PDF 代理)。可选的出站代理和自定义 DNS 服务器见 AGENTS.md。
  • 身份验证与路由限制 — 使用 Better Auth 会话;Next.js proxy 会将未通过身份验证的用户重定向出私有路由。登录仅支持 OAuth(Google/GitHub,以及配置后可用的 Apple);不提供密码登录。
  • API 授权 — 敏感路由(/api/links、/api/v1/*、MCP 等)会在服务端解析会话,并将操作限制在已登录用户的范围内。
  • 速率限制 — 设置 UPSTASH_REDIS_REST_URL 和 UPSTASH_REDIS_REST_TOKEN 后,代理会对 /api/auth/*、POST /api/links 和 POST /api/feedback 实施按 IP 限制(见 proxy-rate-limit.ts)。未配置 Upstash 时,限制将停用——本地开发没有问题,但不适合生产环境。
  • 密钥与客户端暴露 — SUPABASE_SECRET_KEY(或旧版 SUPABASE_SERVICE_ROLE_KEY)等值仅供服务端使用。浏览器仅使用 Supabase anon 密钥进行实时功能;.env 会被 Git 忽略。
  • 响应大小限制 — PDF 代理流式传输设有大小上限(见 safe-outbound-fetch)。

报告漏洞: 请通过此仓库的 GitHub Security Advisories 提交报告,以便在修复前对详情保密。

设置(本地开发)

先决条件
  • **Node.js:**近期 LTS 版本
  • 包管理器:pnpm(此仓库包含 pnpm-lock.yaml)
  • **Postgres:**本地或托管实例(Supabase 是不错的选择)
1) 安装依赖
pnpm install
2) 配置环境变量

在仓库根目录创建 .env 文件。完整列表请参阅 .env.example;核心功能所需的最少配置如下:

DATABASE_URL="postgresql://USER:PASSWORD@HOST:5432/DBNAME"

# Supabase Realtime — cross-device instant link list sync (same project as Postgres)
SUPABASE_URL="https://YOUR_PROJECT.supabase.co"
SUPABASE_ANON_KEY="eyJ..."
SUPABASE_SECRET_KEY="sb_secret_..."

# Sign-in (OAuth apps with callback {BETTER_AUTH_URL}/api/auth/callback/{google,github})
GOOGLE_CLIENT_ID="..."
GOOGLE_CLIENT_SECRET="..."
GITHUB_CLIENT_ID="..."
GITHUB_CLIENT_SECRET="..."

# Optional (used to send in-app feedback emails)
RESEND_API_KEY="re_..."
RESEND_FROM="Purl <[email protected]>"

说明:

  • DATABASE_URL 是必需的(Prisma + Better Auth)。
  • 实时同步链接列表需要 Supabase 环境变量。请在 Supabase 控制台中打开 Project Settings → API。服务角色密钥必须仅用于服务器端。
  • 生产环境需要 Google/GitHub OAuth 凭据;本地环境中,缺少变量的提供方会直接隐藏。本地开发时,请使用回调 URL http://localhost:3000/api/auth/callback/{google,github}。Apple 是可选项,只有设置了全部四个 APPLE_* 变量时才会启用(请参阅 .env.example)。
  • 本地开发时 Resend 是可选的:未设置 RESEND_API_KEY 时,无法发送应用内反馈。
  • Better Auth 密钥和 URL 列于 .env.example 中——复制这些键即可完成可用的身份验证配置。
3) 运行数据库迁移
pnpm prisma migrate dev
4) 生成 Prisma 客户端(如有需要)
pnpm prisma generate
5) 启动开发服务器
pnpm dev

打开 http://localhost:3000。

可选:使用 portless 设置命名 HTTPS URL。 全局安装 portless(npm install -g portless,Node.js 24+)后,运行 portless run,而不是 pnpm dev。它会通过本地代理在 https://purl.localhost 上运行 dev 脚本。在 .env.local 中将身份验证 URL 指向该地址,否则登录时会因来源不符而被拒绝:

BETTER_AUTH_URL="https://purl.localhost"
BASE_URL="https://purl.localhost"

在 git worktree 中,portless 会为分支名称添加前缀(例如 https://my-branch.purl.localhost);请在其中将两个变量都设为该 URL。

**PWA / 安装:**使用 pnpm dev 时,服务工作线程不会启用。生产构建完成后,public/sw.js 会在本地生成;运行 pnpm start 并在 Chromium 中打开应用,即可使用 Install,或测试离线访问 /~offline。

测试

测试使用 Vitest,重点验证关键逻辑(格式化程序、链接分组、身份验证路由、API 行为、元数据抓取)。测试有意避免仅针对浅层 UI 封装的内容。

pnpm test        # run once
pnpm test:watch  # watch mode

常用命令

pnpm lint
pnpm build
pnpm start
pnpm test

更多贡献者说明(Prisma、出站代理环境变量):请参阅 AGENTS.md。

评论

支持 Markdown

第一次接触 MCP?

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

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