关于 hrva.cc
hrva.cc 是带有链接安全检查和隐私导向点击统计的短链接后端。其 MCP 连接器让 AI 应用创建、列出短链接并查看统计数据。
主要功能
- 01创建随机短链接或自定义别名
- 02设置有效期、访问次数和密码
- 03检查钓鱼与恶意软件链接
- 04查看每日点击统计
- 05生成二维码和活动标签
适用场景
- 01为营销活动创建短链接
- 02查看链接的点击统计
- 03检查用户举报的可疑链接
MCP 相关
通过 https://hrva.cc/mcp 向 AI 应用开放 hrva.cc 的链接管理能力,并使用 OAuth 2.1 认证。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://hrva.cc/mcpclaude mcp add --transport http cc-hrva-url-shortener https://hrva.cc/mcp{"mcpServers":{"cc-hrva-url-shortener":{"type":"http","url":"https://hrva.cc/mcp"}}}在 Cursor 中打开{"servers":{"cc-hrva-url-shortener":{"type":"http","url":"https://hrva.cc/mcp"}}}在 VS Code 中打开{"mcpServers":{"cc-hrva-url-shortener":{"type":"http","url":"https://hrva.cc/mcp"}}}{"mcpServers":{"cc-hrva-url-shortener":{"serverUrl":"https://hrva.cc/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
详细介绍
URL-Shortener
概述
hrva.cc 是一款以隐私为先、内置链接安全检测功能的 URL 缩短服务。本仓库包含后端:一个 Spring Boot API,用于创建短链接并进行跳转、检查链接是否包含网络钓鱼或恶意软件,以及统计点击次数,同时不追踪任何人。前端位于 HrvaLabs/URL-Shortener-FE。
更新日志显示在 app.hrva.cc/changelog,并保存在 CHANGELOG.md 中。AGENTS.md 介绍了架构、命令、端点和配置。
功能
链接
- 随机短链接;登录后也可使用自定义别名。无需账号也可创建链接,但速率限制更严格。
- 到期日期、访问次数限制、密码保护和标签。
- 批量创建,以及使用 API 密钥(
X-Api-Key)的 API。默认情况下,每个密钥每小时最多可发出 600 次请求(可在站点设置中调整);每个响应都包含RateLimit-Limit、RateLimit-Remaining和RateLimit-Reset,超出限制的密钥会收到带有Retry-After的 429 响应。密钥会在你选择的天数后(1 至 3,650 天)、默认 12 个月后过期,也可设置为永不过期。密钥以 SHA-256 哈希形式存储:完整密钥只会在创建时显示一次,列表中显示其开头几个字符。 - 活动标签(UTM)生成器。
- 统计扫描次数的 QR 码。
- 可选择通过电子邮件或 Discord、Slack、Telegram、ntfy 或 webhook 接收通知:失效的目标地址、到期提醒,以及每日或每周摘要。
自定义域名
- 在自己的子域名上使用短链接,例如
go.example.com/menu。你可在设置中提交申请;管理员批准后,添加一条 CNAME 记录即可,证书将通过 Cloudflare for SaaS 签发。 - 你域名上的别名与 hrva.cc 上的别名相互独立,其链接拥有相同的统计数据、限制、密码保护和到期日期。
Bio 页面
- 在
hrva.cc/@yourname创建一个页面,为你的每个短链接添加一个按钮。 - 按天统计浏览量;更改用户名后,旧用户名会保留 30 天。
安全
- 每个新链接、每次点击以及每晚的重新扫描都会经过以下检查:
- Google Safe Browsing
- 管理员管理的屏蔽列表(HaGeZi、OpenPhish、PhishTank、Phishing.Database、URLhaus)
- Spamhaus DBL
- 域名年龄(RDAP)
- 重定向链和仿冒域名检查
- 访客可以举报链接和 Bio 页面。
- 可疑链接会进入审核队列,而不是被直接拦截。
- 当许多新链接指向同一个新域名时,会发出网络钓鱼浪潮警报。
以隐私为先的分析
- 点击数据仅按链接存储每日总数:访客、来源页、设备、浏览器、国家/地区,以及 QR 码扫描与其他点击的对比数据。
- 独立访客数据由单向哈希生成,使用的密钥每天更换,且仅保存在 Redis 中。
- 机器人单独计数。
- 公开的 hrva.cc 统计数据页面显示全站汇总数据。
账号
- 可使用电子邮件和密码、Google、通行密钥或安全密钥登录。
- 所有登录方式均支持两步验证,可使用验证器应用或通行密钥,并提供恢复代码。
- 你可以导出数据并删除账号。
AI 连接器
- Claude 等 AI 应用通过 MCP 在
https://hrva.cc/mcp上使用 hrva.cc,并通过 OAuth 2.1 登录。
管理员
- 提供统计数据、审核队列、内容审核、屏蔽列表、域名规则、保留别名、Bio 页面、自定义域名和审计日志等页面。
- 提供 Discord 警报、每周摘要和每日决策邮件。
使用的技术
- 后端: Java 25、Spring Boot 4.1、Spring Security 和 Spring Authorization Server、Spring AI(MCP)
- 数据库: PostgreSQL(使用 Liquibase 迁移)和 Redis
- 前端: Cloudflare Workers 上的 Next.js 16(独立仓库)
- 部署: GitHub Actions 构建 Docker 镜像并触发 Portainer 堆栈 webhook。站点运行在 Cloudflare 后方。
运行
构建、测试和运行命令、本地开发用户以及端到端检查(scripts/mcp-e2e.sh)详见 AGENTS.md。简要来说:运行 docker compose -f docker/docker-compose.yml up -d 启动 Postgres 和 Redis,然后运行 mvn spring-boot:run -Dspring-boot.run.profiles=local。运行测试时,执行 mvn -B test。
生产环境要求
- **Docker 镜像:**基于
eclipse-temurin:25-jre分两个阶段构建,由非 root 用户app(uid 10001)运行,监听 8080,并配置HEALTHCHECK每隔 30 s 请求一次/actuator/health/liveness(启动等待时间为 120 s,因此首次启动及其 Liquibase 运行不会导致容器被标记为不健康)。检查会使用一个主机名(HEALTHCHECK_HOST,否则使用APP_DOMAINS_PRIMARY_HOSTS中的第一项,再否则使用hrva.cc),因为其他主机名都会返回 404。CI 会推送:latest和不可变标签:<commit sha>。Java 是 PID 1,因此docker stop会发送 SIGTERM,让应用正常结束,且会远早于 30 s 的stop_grace_period。- **按提交固定版本(可选):**在 Portainer stack 中,将
image: ghcr.io/hrvalabs/url-shortener:latest改为image: ghcr.io/hrvalabs/url-shortener:<full commit sha>,然后更新 stack。此后 webhook 会重新部署相同的 sha,因此只有在编辑 stack 时才会更改版本;回滚只需编辑一次,改回之前的 sha。如果希望每次推送都触发部署,请保留:latest。 - **端口:**应用无需发布端口,因为 Nginx Proxy Manager 会通过 Docker 网络访问
url-shortener-backend:8080。Portainer stack 不发布任何端口,因此没有人能绕过 Cloudflare 直接访问源站;请保持如此(如果确实需要主机端口,则绑定到127.0.0.1)。
- **按提交固定版本(可选):**在 Portainer stack 中,将
- **Actuator:**通过 HTTP 暴露
health,以及其liveness和readiness探针;只有在设置了APP_METRICS_TOKEN时才会暴露(v2.30)prometheus:请求需携带Authorization: Bearer <APP_METRICS_TOKEN>,令牌错误或缺失时返回 401,未设置该变量时返回 404。env、beans、metrics、caches和info不会通过 Web 暴露。https://hrva.cc/actuator/health会检查数据库和 Redis(任一不可用时返回 503)、磁盘空间、ping 和 SSL,但不会检查邮件服务器(management.health.mail.enabled: false):该检查每次调用都会打开 SMTP 连接;在本地运行中,每个服务有 30 ms 网络延迟时,连接耗时约为 185 ms 总耗时中的 110 ms。容器检查使用 liveness。 - 登录会话持续时间(v2.31):登录会在 Web 应用上次续期
app.jwt-token-validity-seconds(10 小时)后结束;应用会在你使用时续期,而且会话最晚不会超过登录后APP_JWT_SESSION_MAX_SECONDS(默认 2592000,即 30 天)。记住我功能仍保持 30 天。 - 每日 Browser Run 配额(v2.30):管理员 Health 页面会将今天的截图秒数与
APP_INSPECTION_BROWSER_SECONDS_DAILY_LIMIT(默认 600,即 Cloudflare 的免费配额)进行比较。 - **Redis 不可用:**限流功能会放行请求,但有三种请求会拒绝处理,直到 Redis 恢复:未登录用户创建链接、解锁链接密码,以及密码登录(每种情况均返回 503 和
Retry-After: 60)。已登录用户、API 密钥和 MCP 创建操作不受影响。 - 管理员账户需要两步登录(v2.23):在部署前或部署后立即为每个管理员账户启用此功能。在启用之前,管理页面和 MCP 管理工具都会返回“Turn on two-step sign-in to use admin pages.”
- 出站流量(v2.23):应用发出的每个请求都会固定到经过检查的公共地址,但还应在主机上阻止容器访问
169.254.169.254及 stack Docker 网络以外的私有地址范围(DOCKER-USERiptables 规则)。 - 代码扫描(v2.23):
codeql.yml需要在仓库中启用代码扫描;dependencies.yml的 PR 审查需要依赖项关系图。对于私有仓库,两者都需要 GitHub Advanced Security。 - 不活跃账户在连续 5 年未使用后,将于停用前 30 天收到邮件通知(登录、使用 API 密钥或连接 MCP 应用均算作使用)。无需设置;部署后首次运行时,会警告所有已超过期限的账户,并在 30 天后停用这些账户。
- PostgreSQL 15 或更高版本(分析计数器使用
MERGE),以及 Redis 6.2 或更高版本(GETDEL、SMISMEMBER)。 - **环境变量:**完整列表见 AGENTS.md(CI / Deploy,以及 MCP connector → Configuration)。必须设置
APP_MCP_SIGNING_KEY,否则应用无法启动。生成一个私有 RSA JWK,并确保不将其提交到 git 或写入日志:node -e "const {generateKeyPairSync, randomUUID} = require('node:crypto'); const {privateKey} = generateKeyPairSync('rsa', {modulusLength: 2048}); console.log(JSON.stringify({...privateKey.export({format: 'jwk'}), kid: randomUUID(), use: 'sig', alg: 'RS256'}))" APP_NOTIFICATIONS_KEY也是必需的,否则应用无法启动。它用于加密通知渠道的 URL 和令牌,并为取消订阅链接签名,因此请将其与 MCP 签名密钥一起保管:丢失此密钥意味着所有人都必须重新添加自己的渠道。生成 32 个随机字节:openssl rand -base64 32- 未登录用户创建链接时的人机验证需要
APP_TURNSTILE_SITE_KEY和APP_TURNSTILE_SECRET_KEY(Turnstile 小组件的密钥);未设置时,应用仍会启动,但不会进行验证。请勿将密钥提交到 git 或写入日志。 - 自定义域名需要
CLOUDFLARE_API_TOKEN和CLOUDFLARE_ZONE_ID;未设置时,应用仍会启动,但会拒绝审批。其他变量(APP_DOMAINS_ENABLED、APP_DOMAINS_MAX_ACTIVE、APP_DOMAINS_FREE_ALLOWANCE、APP_DOMAINS_PER_USER、APP_DOMAINS_RESERVED、APP_DOMAINS_PRIMARY_HOSTS、APP_DOMAINS_IGNORED_HOSTNAMES、APP_DOMAINS_CNAME_TARGET、APP_CLOUDFLARE_API_BASE)都有可用的默认值,见 AGENTS.md(Config Profiles)。首次部署自定义域名前:- O1:
CLOUDFLARE_ZONE_ID是 hrva.cc zone 的 id,且令牌仅在 hrva.cc zone 上拥有 Zone、SSL and Certificates、Edit 权限。请勿在其他地方使用该令牌。 - **O2:**反向代理的兜底
default_server会拒绝来自非 Cloudflare 地址的请求(返回 444),与代理主机一样。自定义主机名会通过该代理访问源站。 - **O3:**所有必须继续访问后端的主机名都要列在
APP_DOMAINS_PRIMARY_HOSTS中(默认值为hrva.cc,domains.hrva.cc;app.server-url的主机名始终计入)。部署后,其他所有Host都会返回 404,包括通过 IP 或localhost访问容器的请求,因此健康检查应通过https://hrva.cc/actuator/health进行。 - O4:
APP_DOMAINS_IGNORED_HOSTNAMES列出不属于自定义域名的 Cloudflare 主机名(默认值为test.karlo.cc),这样夜间对账就不会将它们标记出来。这些主机名会返回 404。 - **O5:**管理员 System 选项卡会显示 PostgreSQL 15 或更高版本;否则迁移 032 会阻止应用启动。
- **O6:**自定义主机名会经过 hrva.cc zone 的 Cloudflare 规则。请确认它们所需的缓存、配置、重定向或 WAF 跳过规则,不会仅匹配
http.host eq "hrva.cc",并确保绝不缓存重定向。
- O1:
- **仅允许通过 Cloudflare 访问源站。**每个网络的限流规则会信任
CF-Connecting-IP,国家/地区计数会信任CF-IPCountry。因此,源站必须只接受来自 Cloudflare 的流量,可以通过 Cloudflare Tunnel 实现,也可以在防火墙中限制为 Cloudflare 的 IP 范围。否则,任何人都可以伪造这些请求头。 - **MCP 路径和一键取消订阅的 Cloudflare 规则。**MCP 客户端不是浏览器;从邮件的
List-Unsubscribe标头发起一键取消订阅 POST 请求(RFC 8058)的邮件服务提供商也不是浏览器。质询会导致这两种请求失败:- 将
/mcp、/oauth2/*、/.well-known/*和/api/v1/notifications/unsubscribe从 WAF 托管质询和 Super Bot Fight Mode 中排除。如果 Free 计划上的 Bot Fight Mode 会对它们发起质询,请将其关闭。 - 不要在边缘缓存
GET /oauth2/authorize或/.well-known/*。
- 将
- **部署后进行冒烟测试。**预期 issuer 为
https://hrva.cc,resource 为https://hrva.cc/mcp,而不带令牌访问/mcp时返回 401:curl -s https://hrva.cc/actuator/health curl -s https://hrva.cc/.well-known/oauth-authorization-server | jq '{issuer, registration_endpoint}' curl -s https://hrva.cc/.well-known/oauth-protected-resource/mcp | jq '{resource, authorization_servers}' curl -s -o /dev/null -w '%{http_code}\n' -X POST https://hrva.cc/mcp
贡献
我们欢迎社区贡献!
许可证
本项目采用 GNU General Public License v3.0 许可。详情请参阅 LICENSE 文件。
联系方式
如有疑问、问题或功能请求,请在 GitHub 上提交 issue,或通过 电子邮件直接联系我。
感谢使用 URL-Shortener,或仅仅是浏览此页面!
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。