Skip to main content
Glama
roguebot13

Stash

by roguebot13

Stash

Stash は、ファーストパーティのメール/パスワード認証、ステートレスな Auth.js セッション、Prisma/PostgreSQL による永続化、Resend によるトランザクションメール、Model Context Protocol (MCP) による認証付きブックマークツールを備えた Next.js App Router アプリケーションです。

ローカルセットアップ

  1. pnpm install で依存関係をインストールします。

  2. .env.example を .env にコピーし、すべてのプレースホルダーを置き換えます。.env をコミットしないでください。

  3. pnpm exec auth secret(または別の暗号学的に安全なジェネレーター)で AUTH_SECRET を生成します。

  4. APP_URL には信頼できる公開オリジンを設定します。通常、ローカルでは http://localhost:3000 です。本番環境では HTTPS を使用する必要があります。

  5. Resend で検証済みのドメイン上の送信者を EMAIL_FROM に設定します。

  6. MCP_AUTH_ISSUER には、信頼する OAuth 認可サーバーの正確な issuer を設定します。ローカル開発ではループバック HTTP を使用できます。本番環境の issuer は HTTPS を使用し、クエリやフラグメントを含めてはなりません。

  7. pnpm prisma migrate dev でマイグレーションを適用します。コミット済みのマイグレーションによって、認証テーブルとブックマークテーブルが作成されます。

  8. pnpm dev でアプリケーションを起動します。

サーバーは DATABASE_URL、RESEND_API_KEY、AUTH_SECRET、APP_URL、MCP_AUTH_ISSUER、EMAIL_FROM を検証し、無効な変数名を報告しますが、その値は出力しません。

Related MCP server: bookmark-mcp

認証の動作

  • /signup はクレデンシャルユーザーを作成し、ベストエフォートのウェルカムメールを送信して、ユーザーをサインインさせます。

  • /login は、7日間有効な暗号化された HTTP-only の Auth.js クッキーセッションを作成します。

  • /forgot-password は、有効なメール構文に対して常にアカウント列挙耐性のあるレスポンスを返します。

  • /reset-password は、SHA-256 でハッシュ化された60分間有効な使い捨てトークンを消費し、ユーザーのセッションバージョンをインクリメントすることで古いセッションを失効させます。

  • / は、レンダリング前に DAL を通じて現在のデータベースレコードに対して認可を行います。

lib/rate-limit.ts は、将来の共有 IP/メールレートリミッターの拡張ポイントです。データベースによる60秒のアカウント単位のクールダウンは、それ単体では完全な本番向け不正利用対策システムではありません。

ブックマーク MCP

ステートレスでモダンのみ対応の MCP エンドポイントは POST /api/mcp です。その正規の RFC 8707 リソース識別子とアクセストークンの audience は常に ${APP_URL}/api/mcp です。公開の RFC 9728 ディスカバリーは /.well-known/oauth-protected-resource/api/mcp で利用できます。Stash は認可、トークン、登録、失効、JWKS の各エンドポイントを提供しません。

このエンドポイントは正確に4つのツールを公開します:

  • add_bookmark と delete_bookmark には bookmarks:write が必要です。

  • list_bookmarks と search_bookmarks には bookmarks:read が必要です。

同一オリジンの Stash クライアントは Auth.js クッキーを使用して両方のケイパビリティを取得できます。リモートのネイティブ、デスクトップ、サーバークライアントは、すべてのリクエストでベアラーアクセストークンを送信します。ブラウザのクロスオリジン MCP 呼び出しは意図的にサポートされていません。401 チャレンジはクライアントを保護リソース文書へ導きます。403 insufficient_scope チャレンジは、制限付き OAuth ステップアップに必要な正確なスコープを特定します。

Stash は OAuth 2.1 の保護リソースにすぎません。別途運用される認可サーバーは、PKCE S256 を用いた認可コード、正確な正規 MCP URI の Resource Indicators、認可レスポンスの issuer 識別をサポートする必要があります。また、検証済みの RFC 8414 または OpenID ディスカバリーメタデータ、jwks_uri、許可された非対称アルゴリズム(RS256 または ES256)を含む access_token_signing_alg_values_supported を公開する必要があります。

アクセストークンは、保護ヘッダーに typ: at+jwt と kid を持つ短命な JWT アクセストークンでなければなりません。必須クレームは、正確な iss、正確な単一リソースの aud、sub 内のローカル Stash ユーザー ID、exp、iat、スペース区切りの scope、client_id(または azp)、整数の stash_session_version です。認可サーバーは、現在の Stash ユーザー行からそのバージョンを発行し、トークンの有効期間を60分以下に保つ必要があります。sub にメールアドレスを入れたり、Stash がトークンからユーザーをプロビジョニングすることを期待したりしてはなりません。

ローカルのリモートクライアントテストでは、ループバック認可サーバーを設定し、MCP_AUTH_ISSUER にその issuer を設定し、クライアントを事前登録して(または Client ID Metadata Document を使用して)、正確な ${APP_URL}/api/mcp リソースと最小限のブックマークスコープを要求し、結果のアクセストークンのみを Stash に送信します。リフレッシュトークンは認可サーバーにのみ送信されます。

メール開発

自動テストは Resend をモックし、その API を呼び出すことはありません。メールを送信せずにテンプレートをプレビューするには、emails/ 内のエクスポートされた React コンポーネントを、ローカルの React メールプレビューツールまたは開発専用のプライベートハーネスでレンダリングします。公開の /api/send エンドポイントを追加しないでください。エンドツーエンドのメールテストには、別の Resend テストキー/送信者と受信トレイを使用してください。本番の受信者を使用しないでください。

検証

pnpm prisma format
pnpm prisma validate
pnpm prisma generate
pnpm lint
pnpm test
pnpm build

データベース統合テストには、分離された TEST_DATABASE_URL が必要です。ブラウザテストには分離されたテスト設定が必要で、pnpm test:e2e で実行します。どちらのスイートも開発者または本番データベースに向けないでください。また、明示的な承認なしにデータベースをリセットしないでください。

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Manage Safari bookmarks through an MCP server, providing tools to list, search, add, remove, and organize bookmarks and folders.
    Apache 2.0
  • F
    license
    A
    quality
    D
    maintenance
    A bookmark management MCP server that enables saving, searching, and managing bookmarks with tags and read/unread status, providing tools, resources, and prompts for integration.
    4
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables users to search, read, and query saved bookmark content via a read-only MCP interface, with full-text and optional semantic search.
    4
    MIT