mcpField
H
hrva.cc

hrva.cc

リモート
app.hrva.cc生産性01 日前に更新
リポジトリ公式サイト

hrva.cc について

hrva.cc は、リンクの安全性検査とプライバシーを重視したクリック統計を備える URL 短縮バックエンドです。MCP コネクターを通じて、AI アプリから短縮リンクの作成、一覧表示、統計確認ができます。

主な機能

  1. 01ランダムまたは任意の別名でリンク作成
  2. 02有効期限、訪問数、パスワードの設定
  3. 03フィッシングとマルウェアの検査
  4. 04日別クリック統計の確認
  5. 05QR コードとキャンペーンタグの作成

活用シーン

  1. 01キャンペーン用の短縮リンク作成
  2. 02リンクのクリック統計の確認
  3. 03報告された不審なリンクの確認

MCP 対応

https://hrva.cc/mcp を通じて、AI アプリに hrva.cc のリンク管理機能を提供します。認証には OAuth 2.1 を使用します。

設定

リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。

エンドポイントhttps://hrva.cc/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 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。

ツール

詳細

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。各キーのデフォルトの上限は 1 時間あたり 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 のように、独自のサブドメインで短縮リンクを作成できます。Settings から申請し、管理者の承認後に CNAME レコードを 1 つ追加すると、Cloudflare for SaaS を通じて証明書が発行されます。
  • 独自ドメインのエイリアスは hrva.cc のエイリアスとは別に管理されます。独自ドメインのリンクでも、同じ統計情報、制限、パスワード、有効期限を利用できます。
プロフィールページ
  • hrva.cc/@yourname にページを 1 つ作成し、短縮リンクごとにボタンを設置できます。
  • 閲覧数は日ごとに集計され、ハンドルを変更しても以前のハンドルは 30 日間保持されます。
安全性
  • 新しいリンク、すべてのクリック、夜間の再スキャンは、以下を通じてチェックされます。
    • Google Safe Browsing
    • 管理者が管理するブロックリスト(HaGeZi、OpenPhish、PhishTank、Phishing.Database、URLhaus)
    • Spamhaus DBL
    • ドメインの登録年数(RDAP)
    • リダイレクトチェーンと類似ドメインのチェック
  • 訪問者はリンクやプロフィールページを報告できます。
  • 疑わしいリンクは、無条件にブロックされるのではなく、レビューキューに送られます。
  • 新しいリンクの多くが同じ新しいドメインを指している場合、フィッシング攻撃の急増を知らせるアラートが表示されます。
プライバシーを最優先する分析
  • クリック数はリンクごとの日次集計としてのみ保存されます。集計対象は訪問者、参照元、デバイス、ブラウザー、国、および他のクリック数に対する QR コードのスキャン数です。
  • ユニーク訪問者数は、毎日変更されるキーを使った一方向ハッシュから算出され、Redis にのみ保存されます。
  • ボットは別途集計されます。
  • 公開ページ hrva.cc の統計情報 では、サイト全体の集計を確認できます。
アカウント
  • メールアドレスとパスワード、Google、パスキー、またはセキュリティキーでサインインできます。
  • すべてのサインイン方法で、認証アプリまたはパスキーとリカバリーコードを使った 2 段階認証を利用できます。
  • データをエクスポートし、アカウントを削除できます。
AI コネクター
  • Claude などの AI アプリは、OAuth 2.1 でサインインして https://hrva.cc/mcp の MCP 経由で hrva.cc を利用できます。
管理者
  • 統計情報、レビューキュー、モデレーション、ブロックリスト、ドメインルール、予約済みエイリアス、プロフィールページ、カスタムドメイン、監査ログの各ページ。
  • Discord アラート、週次概要、日次の判断内容をまとめたメール。

使用技術

  • バックエンド: Java 25、Spring Boot 4.1、Spring Security、Spring Authorization Server、Spring AI(MCP)
  • データベース: Liquibase マイグレーションを使用する PostgreSQL、および 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 を使った 2 段階構成で、非 root ユーザー app(uid 10001)として実行し、ポート 8080 で待ち受けます。30 秒ごとに /actuator/health/liveness を確認する HEALTHCHECK を設定します(起動期間は 120 秒とし、初回起動時や Liquibase の実行中に異常と判定されないようにします)。チェックではプライマリホスト(HEALTHCHECK_HOST、設定されていない場合は APP_DOMAINS_PRIMARY_HOSTS の最初のエントリー、それもなければ hrva.cc)を指定します。ほかのホストはすべて 404 を返すためです。CI は :latest と不変の :<commit sha> をプッシュします。Java が PID 1 なので、docker stop は SIGTERM でアプリを正常に終了し、30 秒の stop_grace_period 内に収まります。
    • コミットで固定(任意): Portainer スタックで image: ghcr.io/hrvalabs/url-shortener:latest を image: ghcr.io/hrvalabs/url-shortener:<full commit sha> に変更し、スタックを更新します。Webhook は同じ sha を再デプロイするため、スタックの変更が反映されるのは編集したときだけです。以前の sha に戻すだけでロールバックできます。プッシュのたびにデプロイする場合は :latest のままにします。
    • ポート: Nginx Proxy Manager は Docker ネットワーク上の url-shortener-backend:8080 に接続するため、アプリでポートを公開する必要はありません。Portainer スタックではポートを公開していないため、Cloudflare を迂回してオリジンにアクセスすることはできません。その状態を維持してください(ホストのポートが必要になった場合は 127.0.0.1 にバインドします)。
  • Actuator: HTTP 経由で health を公開し、liveness と readiness の各プローブも公開します。また(v2.30)、APP_METRICS_TOKEN が設定されている場合に限り 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 時間)が経過すると終了します。Web アプリは使用中に更新しますが、サインインから APP_JWT_SESSION_MAX_SECONDS(デフォルトは 2592000、30 日)が経過すると、それ以上は有効になりません。「ログイン状態を保持する」の有効期間は従来どおり 30 日です。
  • Daily Browser Run の利用上限(v2.30):APP_INSPECTION_BROWSER_SECONDS_DAILY_LIMIT(デフォルトは 600。Cloudflare の無料枠)は、管理者の Health ページで本日のスクリーンショットの秒数と比較される値です。
  • Redis がダウンした場合: レート制限はリクエストを通しますが、Redis が復旧するまで拒否する操作が 3 つあります。アカウントなしでのリンク作成、リンクパスワードによるロック解除、パスワードでのサインインです(いずれも Retry-After: 60 を付けて 503 を返します)。サインイン済みのユーザー、API キー、MCP による作成は続行できます。
  • 管理者アカウントでは 2 段階サインインが必要です(v2.23):デプロイ前、またはデプロイ直後に、すべての管理者アカウントで有効にしてください。有効にするまでは、管理者ページと MCP のモデレーションツールは「管理者ページを利用するには、2 段階サインインを有効にしてください。」と応答します。
  • アウトバウンド通信(v2.23):アプリが行うすべてのフェッチは検証済みのパブリックアドレスに固定されますが、ホスト側でもコンテナーから 169.254.169.254 およびスタックの Docker ネットワーク以外のプライベート範囲へのアウトバウンド通信をブロックしてください(DOCKER-USER iptables ルール)。
  • コードスキャン(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 ゾーンの ID であり、トークンには hrva.cc ゾーンだけで 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 ゾーンの Cloudflare ルールを通過します。必要なキャッシュ、設定、リダイレクト、WAF スキップの各ルールが、http.host eq "hrva.cc" のみに一致するようになっていないことを確認してください。また、リダイレクトがキャッシュされないようにしてください。
  • Cloudflare のみからアクセスできるオリジン。 ネットワークごとのレート制限は CF-Connecting-IP を信頼し、国別カウントは CF-IPCountry を信頼します。そのため、オリジンへのトラフィックは Cloudflare Tunnel 経由、またはCloudflare の IP 範囲に限定したファイアウォール経由で、Cloudflare からのみ受け付ける必要があります。そうしないと、誰でもこれらのヘッダーを偽装できます。
  • MCP のパスとワンクリック配信停止に対する Cloudflare ルール。 MCP クライアントはブラウザーではなく、メールプロバイダーも同様です。メールプロバイダーはメールの List-Unsubscribe ヘッダーを使って、ワンクリック配信停止(RFC 8058)の POST リクエストを送信します。チャレンジを設定すると、どちらも機能しなくなります。
    • /mcp、/oauth2/*、/.well-known/*、/api/v1/notifications/unsubscribe を WAF のマネージドチャレンジと Super Bot Fight Mode の対象外にしてください。Free プランで Bot Fight Mode がこれらにチャレンジを課す場合は、無効にしてください。
    • エッジで GET /oauth2/authorize や /.well-known/* をキャッシュしないでください。
  • デプロイ後のスモークテスト。 発行者は https://hrva.cc、リソースは 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 をご利用いただき、またはこのページをご覧いただき、ありがとうございます!

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。