Xpenser - oprn-source personal AI-enabled finance tracker について
xpenser は、収入と支出を記録・分析するオープンソースのセルフホスト可能な個人向けファイナンストラッカーです。複数通貨の取引、ダッシュボード、レポート、API に加え、アカウントデータと統計を扱う MCP サーバーを備えています。
主な機能
- 01収入、支出、返金、返品の記録
- 02取引のカテゴリ分けとベンダー記録
- 03既定通貨への換算
- 04ダッシュボードと期間別レポートの確認
- 05API キーと型付き Node クライアント
- 06任意の AI メールインサイト
活用シーン
- 01個人取引の記録と検索
- 02期間やカテゴリごとの支出傾向の確認
- 03外部ツールによる財務データ管理
- 04収入と支出の定期サマリーの受信
MCP 対応
ユーザー認証済みのベンダー、カテゴリ、取引、ダッシュボードのサマリー、統計を /api/mcp の Streamable HTTP エンドポイントで公開します。アクセスには公開 API と同じ API キーを使用します。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://xpenser.cleverbrush.com/external-api/mcpclaude mcp add --transport http xpenser https://xpenser.cleverbrush.com/external-api/mcp{"mcpServers":{"xpenser":{"type":"http","url":"https://xpenser.cleverbrush.com/external-api/mcp"}}}Cursor で開く{"servers":{"xpenser":{"type":"http","url":"https://xpenser.cleverbrush.com/external-api/mcp"}}}VS Code で開く{"mcpServers":{"xpenser":{"type":"http","url":"https://xpenser.cleverbrush.com/external-api/mcp"}}}{"mcpServers":{"xpenser":{"serverUrl":"https://xpenser.cleverbrush.com/external-api/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
詳細
xpenser
xpenser は、ダッシュボード、カテゴリ、ベンダー、レポート、API/MCP アクセスを使って収入と支出を記録・分析したい人向けの、オープンソースでセルフホスト可能な個人向け家計簿アプリです。

個人用の Telegram ボットと Google Sheets を組み合わせたワークフローから生まれました。プロジェクトはまだ初期段階にあり、進化を続けていますが、実行、調査、拡張、セルフホストができるほか、Cleverbrush Framework の実用的なリファレンスアプリとしても活用できます。現在、別の場所で支出を記録・分析している場合、xpenser がその環境の置き換えや補完に使えるか、また追加が必要な機能について、ぜひご意見をお寄せください。
xpenser は Cleverbrush Framework の実環境でのリファレンスアプリでもあり、スキーマファーストの TypeScript スタックによって、API コントラクト、バリデーション、OpenAPI、型付きクライアント、React フォーム、認証対応エンドポイント、オブザーバビリティ、Telegram ワークフロー、MCP アクセスを、ひとつのまとまったアプリケーションから実現する方法を示しています。
xpenser を選ぶ理由
- ダッシュボード、カテゴリ、ベンダー、レポート、検索可能な取引履歴を備えた構造化アプリに、日々の家計管理を移行できます。
- 収入、支出、払い戻し、返品を、カテゴリ、メモ、日付、ベンダー、通貨とともに記録できます。
- 日次、週次、月次、四半期、年次の集計を、カテゴリ別の内訳や傾向と合わせて確認できます。
- 複数の取引通貨を使用し、Frankfurter を通じてデフォルト通貨へ自動換算できます。
- 取引のスキャン画像を取り込み、ベンダーデータを充実させ、モバイルとデスクトップで使いやすいセットアップワークフローを維持できます。
- OpenAI が生成する支出と収入の分析情報を含む、週次および月次のメールサマリーを任意で受け取れます。
- API キー、型付き Node クライアント、MCP サーバー、Telegram ボットを通じて外部ツールに接続できます。
スクリーンショット
|
|
|
| ダッシュボードの月表示 | 取引履歴 | メールレポート、API キー、MCP |
Cleverbrush を使用して構築
xpenser は、調査しやすい規模を保ちつつ、本番環境を想定したフレームワークのパターンを試せるよう意図的に小さく設計されています。
packages/contractsは、Cleverbrush スキーマを使って公開コントラクトを定義します。apps/apiは、Cleverbrush サーバーハンドラー、認証メタデータ、OpenAPI、DI、ロギング、トレーシング、MCP を通じてコントラクトを公開します。packages/clientは、生成された Cleverbrush クライアントを、リトライ、タイムアウト、重複排除、バッチ処理、キャッシュタグ、OpenTelemetry の伝播機能でラップします。packages/uiは、Cleverbrush スキーマのフィールドを再利用可能な React フォームコントロールにバインドします。
アプリの背後にあるフレームワークのパターンを学ぶには、Cleverbrush リファレンスノートから始めてください。フレームワークの公式ドキュメントについては、次をご覧ください。
クイックスタート
前提条件
- Node.js 24
- npm 11
- Docker と Docker Compose v2(
docker compose)
1. 依存関係をインストールする
npm install
2. ローカル環境ファイルを作成する
cp .env.example .env
.env.example のデフォルト値はローカル開発向けに安全に設定されており、アプリは localhost:5432 の PostgreSQL に接続します。
デプロイ環境で Google Tag Manager を読み込まない場合は、DISABLE_GTM=1 を設定してください。
3. 共有ワークスペースをビルドする
アプリはビルド済みの dist 出力からローカルパッケージをインポートするため、開発サーバーを起動する前に共有パッケージを一度ビルドしてください。
npm run build -w @xpenser/contracts
npm run build -w @xpenser/client
npm run build -w @xpenser/ui
4. PostgreSQL を起動する
docker compose up -d postgres
便利な確認コマンド:
docker compose ps postgres
docker compose logs postgres
5. アプリを起動する
npm run dev
API は起動時にデータベースのマイグレーションを実行します。
ローカル URL:
- Web アプリ: http://localhost:3000
- API: http://localhost:4000
- API ヘルスチェック: http://localhost:4000/health
- OpenAPI JSON: http://localhost:4000/openapi.json
認証
メールアドレスとパスワードでのサインインは、外部の認証プロバイダーなしで利用できます。この方法で作成したアカウントは、サインインする前にメールアドレスを確認する必要があります。
ユーザーを 1 人だけにするセルフホスト環境では、アカウント認証を完全に省略できます。
XPENSER_SINGLE_USER_MODE=1
[email protected]
WEB_API_SERVICE_SECRET=replace-with-at-least-32-characters
シングルユーザーモードでは、Web アプリは認証済みのアプリを直接開き、設定されたメールアドレスを所有者として新規作成または再利用します。ログイン、登録、マーケティングページは非表示になり、Swagger/OpenAPI は引き続き利用できます。パブリック API と MCP エンドポイントには、引き続き API キーまたは OAuth が必要です。アカウントのログインフローを省略できるのは、信頼された Web サービスのみです。
Google サインインは 2 つのモードに対応しています。
- セルフホスト環境向けの直接 Google OAuth。
- ホスト型 Cleverbrush デプロイメント向けの Cleverbrush Passport。
GOOGLE_SIGN_IN_MODE でモードを選択します。
GOOGLE_SIGN_IN_MODE=auto
auto は、AUTH_GOOGLE_ID と AUTH_GOOGLE_SECRET が設定されている場合、直接 Google OAuth を使用します。これらが設定されていない場合は、すべての Passport 変数が設定されている場合に限り Passport を使用します。どちらの認証プロバイダーも設定されていない場合、Google サインインボタンは非表示になり、メールアドレスとパスワードでのサインインは引き続き利用できます。
直接 Google OAuth を必須にするには GOOGLE_SIGN_IN_MODE=direct、Passport を必須にするには GOOGLE_SIGN_IN_MODE=passport、認証情報が設定されていても Google サインインを非表示にするには GOOGLE_SIGN_IN_MODE=disabled を使用します。
直接 Google OAuth
Google Cloud Console で OAuth 2.0 クライアントを作成します。
- アプリケーションの種類:Web アプリケーション
- 承認済み JavaScript 生成元:公開されている
APP_URL - 承認済みリダイレクト URI:
${APP_URL}/authjs/callback/google
デフォルトの APP_URL を使用するローカル開発では、次のように設定します。
http://localhost:3000/authjs/callback/google
Auth.js 標準の Google 変数を使用して Web アプリを設定します。
APP_URL=https://xpenser.example.com
AUTH_URL=https://xpenser.example.com/authjs
NEXTAUTH_URL=https://xpenser.example.com/authjs
NEXTAUTH_SECRET=replace-with-at-least-32-characters
AUTH_SECRET=replace-with-the-same-value-as-NEXTAUTH_SECRET
GOOGLE_SIGN_IN_MODE=auto
AUTH_GOOGLE_ID=your-google-oauth-client-id
AUTH_GOOGLE_SECRET=your-google-oauth-client-secret
Google アカウントには、確認済みのメールアドレスが必要です。同じメールアドレスのローカルのメールアドレスとパスワードのアカウントがすでに存在する場合、アカウントを暗黙的にリンクするのではなく、Google サインインは拒否されます。
Cleverbrush Passport
Passport は、Cleverbrush 専用の認証ブローカーです。独自の互換性のある Passport サービスを運用していないセルフホスト環境では、直接 Google OAuth を使用してください。
両方のサービスを次のように設定します。
GOOGLE_SIGN_IN_MODE=passport
PASSPORT_BASE_URL=https://auth.cleverbrush.com
PASSPORT_PROJECT=xpenser
PASSPORT_ENVIRONMENT=production
PASSPORT_PUBLIC_KEY=
PASSPORT_PUBLIC_KEY は任意です。空の場合、API は <PASSPORT_BASE_URL>/.well-known/public-key を取得し、メモリにキャッシュします。設定する場合は、base64 エンコードされた PEM 公開鍵を使用してください。
Docker でのフル実行
本番環境に近いローカル実行では、Compose スタック全体をビルドして起動します。
docker compose up --build
これにより、docker-compose.yml で定義されたコンテナ化された Web アプリ、API、PostgreSQL、Swagger UI、オブザーバビリティサービスが起動します。
Docker の URL:
- Web アプリ: http://localhost:3000
- パブリック API プロキシ: http://localhost:3000/api
- アプリの Swagger UI: http://localhost:3000/api-docs/swagger
- Compose Swagger UI コンテナ: http://localhost:8090
- SigNoz: http://localhost:8080
パブリック環境にデプロイする場合は、Web アプリの前段にリバースプロキシを配置し、APP_URL に公開オリジンを設定してください。API サービスは Docker ネットワーク内でプライベートのままになり、Next アプリは /api の下で API を公開します。
より小規模なパブリック環境にデプロイする場合は、docker-compose.prod.yml を出発点として、JWT_SECRET、WEB_API_SERVICE_SECRET、TELEGRAM_BOT_SERVICE_SECRET に本番環境用のシークレットを設定してください。通常のアカウント認証を使用するデプロイメントでは、NEXTAUTH_SECRET と AUTH_SECRET も必要です。シングルユーザーデプロイメントでは、これらを空のままにできます。
オプションの連携
デフォルトの .env.example では、プロバイダーの認証情報を設定しない限り、外部連携は無効になっています。
- OpenAI のメールインサイト:
OPENAI_API_KEY、OPENAI_REPORT_MODEL、RESEND_API_KEY、EMAIL_FROM、EMAIL_REPORTS_ENABLED=1、およびEMAIL_REPORTS_SCHEDULER_ENABLED=1を設定します。 - Telegram ボットのワークフロー:
TELEGRAM_BOT_TOKEN、TELEGRAM_BOT_USERNAME、 およびTELEGRAM_BOT_SERVICE_SECRETを設定します。 - ベンダー情報の拡充:
BRANDFETCH_API_KEYまたはBRANDFETCH_CLIENT_IDを設定し、VENDOR_ENRICHMENT_ENABLED=1を有効にします。 - Google サインイン:上記の説明に従って Google OAuth を直接設定するか、 無効のままにしてメールアドレス/パスワードのアカウントを使用します。
- アプリ内フィードバック:
FEEDBACK_WEBHOOK_URLに HTTP または HTTPS の n8n Webhook を設定します。 この値が空の場合、認証済みユーザー向けのトップメニューのフォームは非表示になり、 セルフホスト可能な環境でも連携を任意のままにできます。
パブリック API
Settings -> Preferences -> API keys から API キーを作成します。API キーは、 curl または型付き Node クライアントでベアラートークンとして使用できます。
curl -X POST "$APP_URL/api/transactions" \
-H "Authorization: Bearer $XPENSER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"categoryId":1,"amount":12.34,"currency":"USD","effect":"normal","occurredAt":"2026-05-13T12:00:00.000Z"}'
import { createXpenserClient } from '@xpenser/client';
const client = createXpenserClient({
baseUrl:
process.env.XPENSER_API_BASE_URL ??
'http://localhost:3000/api',
getToken: () => process.env.XPENSER_API_KEY ?? null
});
await client.transactions.create({
body: {
categoryId: 1,
amount: 12.34,
currency: 'USD',
effect: 'normal',
occurredAt: new Date()
}
});
通常の取引では effect を省略するか、normal に設定します。経費カテゴリでの返金、
または収入カテゴリでの支払いやチャージバックには effect: 'reversal' を使用します。
入力金額は正のままで、レポートではそのカテゴリから差し引かれます。
X-API-Key: $XPENSER_API_KEY も使用できます。
MCP サーバー
xpenser は、AI エージェント向けに /api/mcp で MCP Streamable HTTP エンドポイントを公開します。
Settings -> Preferences -> API keys の同じ API キーをベアラートークンとして使用します。
MCP ツールは API キー所有者のベンダー、カテゴリ、取引を読み取り、管理できるため、
MCP へのアクセスはアカウントの全データへのアクセスとして扱ってください。
MCP クライアント専用の API キーを使用し、アクセスが不要になったら失効させてください。
{
"mcpServers": {
"xpenser": {
"type": "streamable-http",
"url": "https://xpenser.example.com/api/mcp",
"headers": {
"Authorization": "Bearer ${XPENSER_API_KEY}"
}
}
}
}
MCP サーバーは、現在のユーザー、ベンダー、カテゴリ、取引、ダッシュボードの概要、 統計情報を扱うツールを公開します。ベンダー候補の検索や情報の拡充では、 設定されたベンダー情報拡充プロバイダーが呼び出される場合があります。
開発コマンド
npm run lint
npm run typecheck
npm test
npm run test:e2e
データベース用ヘルパー:
npm run db:run -w @xpenser/api
npm run db:validate -w @xpenser/api
docker compose stop postgres
docker compose down
docker compose down -v
db:validate は読み取り専用で、稼働中のデータベーススキーマを Cleverbrush ORM エンティティと照合します。
GitHub PR 環境以外で実行する場合、e2e テストスイートには PLAYWRIGHT_BASE_URL が必要です。
型付きクエリの統合テストには、xpenser_queries という名前の専用 PostgreSQL データベースが必要です
(アプリケーションのデータベースを絶対に指定しないでください)。
docker run --name xpenser-query-tests -d -p 127.0.0.1:55437:5432 \
-e POSTGRES_DB=xpenser_queries -e POSTGRES_USER=xpenser_test \
-e POSTGRES_PASSWORD=xpenser_test postgres:16-alpine
# Wait until PostgreSQL is ready before running the suite.
docker exec xpenser-query-tests pg_isready -U xpenser_test -d xpenser_queries
QUERY_TEST_DATABASE_URL=postgres://xpenser_test:[email protected]:55437/xpenser_queries \
npm run test:queries:integration
docker stop xpenser-query-tests
このテストスイートでは、フィクスチャの型チェックを行い、ランダムなスキーマでアプリケーションのマイグレーションを実行した後、そのスキーマのみを削除します。 結合プロジェクション、集計値のデコード、認可、番号付きページング、フィルター、スキャンの概要、 先行読み込みの順序、および上限のある情報拡充クエリ数をテストします。 また、合成データを使用してクエリプランを比較します。実行時間は診断用であり、 本番環境のベンチマークではありません。同じテストスイートが PR の Lint and test チェックでも実行されます。
さらに、ワーカの復旧、再試行回数の上限、スキャン結果のアトミック性、進捗状況の認可など、 PostgreSQL を利用したレシート処理ジョブと定期レポートのスケジュールも検証します。 ライフサイクル、保持期間、配信保証、デプロイのガイダンスについては、 Background jobs を参照してください。
コントリビューション
コントリビューションを歓迎します。最初に取り組みやすい分野として、 ドキュメント、セルフホスティングガイド、フレームワークの参考資料、 UI の改善、API の例、範囲を絞った小規模なプロダクト改善などがあります。
- PR を作成する前に CONTRIBUTING.md をお読みください。
- 対応可能なバグや機能リクエストには Issue をご利用ください。
- 質問、アイデア、Cleverbrush の学習に関する議論には GitHub Discussions をご利用ください。
- API を変更する場合は、Cleverbrush のコントラクト、エンドポイントのメタデータ、 ハンドラーのツリーの整合性を保ってください。
プロジェクトの状況
xpenser はまだ初期段階にあり、実用性を重視しながら開発を続けています。現時点では、実質的なユーザーの定着には至っていません。プロダクトの適合性、README の分かりやすさ、セルフホスト、MCP のワークフローに関するフィードバックを歓迎します。個人向けの家計管理アプリとして役立つ一方で、Cleverbrush のフルスタックプロジェクトがどのように構成されているかを開発者が学べるよう、分かりやすさを保つことを目指しています。
xpenser は現在、銀行口座との同期、予算計画、純資産の追跡、ネイティブモバイルアプリ、または成熟したインポートパイプラインを提供していません。
ライセンス
xpenser は MIT License のもとで公開されています。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。