Toshl MCP Server について
Toshl MCP Serverは、AIエージェントをToshl Financeのデータや操作に接続します。口座、予算、取引、支出分析に対応し、stdioまたは認証付きStreamable HTTPで動作します。
主な機能
- 01口座、カテゴリ、タグ、予算の読み取り
- 02取引の管理と分割
- 03カテゴリとタグの作成・更新
- 04カテゴリ別支出と予算実績の分析
- 05ユーザープロフィールと口座概要へのアクセス
- 06stdioまたはStreamable HTTPでの実行
活用シーン
- 01残高と口座詳細の確認
- 02予算と履歴の確認
- 03カテゴリ別の支出分析
- 04取引の作成、更新、分割
MCP 対応
Toshl FinanceのデータをMCPリソースとして公開し、金融記録の読み取り・管理や支出分析のツールを提供します。標準のstdioに加え、リモートクライアント向けのStreamable HTTPにも対応します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Toshl MCP Server
AI エージェントと Toshl Finance を連携するための MCP(Model Context Protocol)サーバーです。
概要
Toshl MCP Server は、AI エージェントと Toshl Finance API の間のブリッジを提供します。AI エージェントが Toshl の財務データにアクセスして分析し、そのデータに基づく洞察やアドバイスを提供できるようにします。
機能
-
Toshl Finance API エンドポイントへの読み取りアクセス:
- アカウント
- カテゴリ
- タグ
- 予算
- ユーザー情報
- プランニング
-
MCP リソース:
- アカウント一覧の取得
- アカウント詳細の取得
- カテゴリ一覧の取得
- カテゴリ詳細の取得
- タグ一覧の取得
- タグ詳細の取得
- タグの作成
- 予算一覧の取得
- 予算詳細の取得
- 予算履歴の取得
- ユーザープロフィールの取得
- アカウント概要の取得
- エントリー一覧の取得
-
MCP ツール:
- アカウントツール(アカウント一覧の取得、アカウント詳細の取得)
- カテゴリツール(カテゴリ一覧の取得、カテゴリ詳細の取得、カテゴリの作成、更新、削除)
- タグツール(タグ一覧の取得、タグ詳細の取得、タグの作成、更新、削除)
- 予算ツール(予算一覧の取得、予算詳細の取得、予算履歴の取得)
- ユーザーツール(プロフィール、概要、支払いタイプ、支払いの取得)
- エントリーツール(エントリー一覧の取得、エントリー詳細の取得、エントリー合計の取得、エントリータイムラインの取得、エントリーの作成、更新、削除、管理、分割、分割の取り消し)
- 分析ツール(カテゴリ別支出の分析、予算の実績分析、アカウント残高の分析)
前提条件
- Node.js(v18.x 以降)
- npm(v8.x 以降)
- Toshl Finance API トークン
API トークンの取得
- https://developer.toshl.com/apps/ にアクセスします
- 個人用トークンを新規作成します。「Description」にトークン名を、「Password」にアカウントのパスワードを入力します
インストール
- リポジトリをクローンします:
git clone https://github.com/hktari/toshl-mcp-server.git
cd toshl-mcp-server
- 依存関係をインストールします:
npm install
.env.exampleファイルを基に.envファイルを作成します:
cp .env.example .env
.envファイルを編集し、Toshl API トークンを追加します:
TOSHL_API_TOKEN=your_api_token
ビルド
プロジェクトをビルドします:
npm run build
実行
サーバーを起動します:
npm start
MCP サーバーの設定
サーバーは stdio 経由で MCP を通信します。クライアントから dist/index.js を指定し、環境変数として
TOSHL_API_TOKEN を渡してください。Claude Code、
OpenCode、Codex CLI の手順は docs/mcp-clients.md に記載されています。
汎用的な mcpServers 設定を受け付けるその他のクライアントの場合:
{
"mcpServers": {
"toshl": {
"command": "node",
"args": ["/absolute/path/to/toshl-mcp-server/dist/index.js"],
"env": {
"TOSHL_API_TOKEN": "your-token"
}
}
}
}
リモートでの使用(Streamable HTTP)
stdio がデフォルトであり、以下の設定は不要です。ローカルプロセスを起動できないクライアント(Web アプリやモバイルアプリ、別の場所で実行するサーバーなど)からサーバーに接続するには、 Streamable HTTP に切り替えます:
MCP_TRANSPORT=http MCP_AUTH_TOKEN="$(openssl rand -hex 32)" TOSHL_API_TOKEN=your-token npm start
次のエンドポイントを提供します:
| パス | メソッド | チェック項目 | 用途 |
|---|---|---|---|
/mcp | POST、GET、DELETE | Host、Origin、ベアラートークン(固定または OAuth) | MCP エンドポイント。クライアントごとに 1 つのセッション |
/healthz | GET、HEAD | Host | 稼働状態の確認。{"status":"ok"} のみを返します |
/.well-known/oauth-*、/oauth/* | OAuth によるサインインを参照 | Host | OAuth が有効な場合のみ |
| 変数 | デフォルト | 説明 |
|---|---|---|
MCP_TRANSPORT | stdio | stdio または http |
MCP_HTTP_HOST | 127.0.0.1 | バインドするインターフェース |
MCP_HTTP_PORT | 3000 | バインドするポート |
MCP_AUTH_TOKEN | 未設定 | /mcp には Authorization: Bearer <token> が必要です。32 文字以上にしてください。OAuth が有効でない場合、または MCP_ALLOW_NO_AUTH=true の場合を除き、HTTP モードでは必須です |
MCP_ALLOW_NO_AUTH | 未設定 | 正確に true を指定すると、MCP_AUTH_TOKEN なしで HTTP モードを起動できます。すべてのリクエストを認証するプロキシを使用する場合に限ります |
MCP_ALLOWED_HOSTS | 未設定 | localhost、127.0.0.1、[::1] 以外に許可する Host 名をカンマ区切りで指定します |
MCP_ALLOWED_ORIGINS | 未設定 | /mcp の Origin ヘッダーで許可するオリジン(https://host[:port])をカンマ区切りで指定します |
セキュリティ
/mcp へのリクエストを通せる人は誰でも、Toshl のデータを読み取り、変更できます。
以下の各レイヤーで、それぞれ異なる経路を遮断します。
- 認証は必須です。 HTTP モードでは、サーバーは
MCP_AUTH_TOKENまたは 組み込みの OAuth サーバー がないと起動しません。claude.ai コネクターは こちらを使ってサインインします。代わりに前段に認証プロキシを置く場合は、MCP_ALLOW_NO_AUTH=trueを設定してください。その場合、サーバーは起動するたびに エラーレベルでSECURITY WARNINGをログに記録します。認証なしで/mcpを公開しないでください。 推測されにくい URL だけで保護できると考えてはいけません。 - TLS とループバック。 デフォルトのループバックバインドを維持し、TLS 終端リバースプロキシ経由でのみ サーバーにアクセスしてください。ベアラートークンはヘッダーで送信されるため、ネットワーク上で HTTP を使うと漏えいします。
- ホストチェック(DNS リバインディング)。 各リクエストの
Hostはループバックであるか、MCP_ALLOWED_HOSTSに登録されている必要があります。これにより、アクセスしたウェブページが 自身の名前を127.0.0.1に向け、ローカルサーバーを操作することを防ぎます。通常、プロキシは 公開名をHostとして転送するため、その名前を登録してください。 - オリジンチェック。 MCP 仕様の要件に従い、
/mcpはOriginを検証します。ネイティブクライアント、 CLI、サーバー側コネクターはOriginを送信しないため、これがないリクエストは受け入れられます。nullのような不透明な値も含め、Originが指定されている場合はMCP_ALLOWED_ORIGINSに登録されている必要があります。登録されていなければ、認証の確認前に リクエストは403で拒否されます。デフォルトではリストは空なので、許可しない限りブラウザページから/mcpを呼び出すことはできません。
# Caddyfile: automatic TLS, forwards Host unchanged
example.com {
reverse_proxy 127.0.0.1:3000
}
MCP_ALLOWED_HOSTS=example.com
OAuth によるサインイン
claude.ai コネクター(ウェブ、デスクトップ、モバイル、Cowork)では、固定ヘッダーではなく OAuth でサインインします。そのために、サーバーは独自の小規模な OAuth 2.1 認可サーバーを備えています。ユーザーは 1 人だけで、クライアントを承認するには、設定したパスフレーズを入力します。Claude にカスタムコネクターとして https://<your host>/mcp を追加し、OAuth クライアントは「Use Claude's published identity」のままにしてください。
| 変数 | 意味 |
|---|---|
MCP_PUBLIC_URL | 公開オリジン。例:https://example.com。パスは含めません。MCP URL は <MCP_PUBLIC_URL>/mcp です。そのホストは自動的に MCP_ALLOWED_HOSTS に追加されます |
MCP_OAUTH_PASSPHRASE | クライアントの承認時にサインインページで入力します。20 文字以上 |
MCP_OAUTH_SIGNING_KEY | アクセストークンとサインインフォームの署名に使用します。32 文字以上(openssl rand -hex 32) |
MCP_OAUTH_SIGNING_KEY_PREVIOUS | オプション。全員をサインアウトさせずにキーをローテーションするための、引き続き検証に使う旧キー |
MCP_OAUTH_STATE_DIR | リフレッシュトークンのハッシュを保存する場所です。再起動後も保持される必要があります(イメージ内では /app/state) |
MCP_TRUST_PROXY | プロキシが X-Forwarded-For に追加するクライアントアドレスを使ってレート制限するには true にします。プロキシの背後では有効にしてください。有効にしないと、すべてのクライアントがプロキシのアドレスを共有し、1 つの IP のロックアウトによって全員がロックアウトされます。クライアントがポートに直接接続できる場合は、ヘッダーを偽装される可能性があるため、無効のままにしてください |
パスフレーズと署名キーが設定されると、OAuth が有効になります。MCP_AUTH_TOKEN と併用できるため、Claude Code やスクリプトでは引き続き静的トークンを使用できます。
動作は次のとおりです。
- クライアント。 Claude(コールバック
https://claude.ai/api/mcp/auth_callback)と Claude Code(localhostおよび127.0.0.1のループバックコールバック。ポートは任意、RFC 8252)のみ受け付けます。 どちらも公開済みのクライアント ID によって固定されています。サーバーはメタデータ ドキュメントを取得しないため、Toshl API 以外のホストには接続しません。動的なクライアント登録は提供されません。 - S256 を使った PKCE が必須です。
resourceパラメーターにはこのサーバーを指定する必要があり、トークンはこのサーバーに紐付けられます。 - アクセストークンの有効期間は 1 時間です。
MCP_OAUTH_SIGNING_KEYで署名され、どこにも保存されません。キーを変更する際に旧キーを_PREVIOUSとして保持しないと、すべてのアクセストークンが一度に無効になります。 - リフレッシュトークンは使用するたびにローテーションされ、未使用のまま 30 日が経過すると期限切れになり、最長で 180 日後に期限切れになります。
MCP_OAUTH_STATE_DIR/refresh-tokens.jsonには SHA-256 ハッシュのみが保存されます。- すでに使用済みのリフレッシュトークンは、クライアントによる 2 件の同時リフレッシュに対応するため、30 秒以内であれば 1 回だけ再試行できます。
- それ以外の再利用があった場合、そのサインインから発行されたすべてのトークンが無効になります。
- ファイルを削除すると、すべてのクライアントがサインアウトします。
- 認可コードは 1 回だけ使用できます。交換に失敗すると、そのコードは無効になります。コードが再使用された場合、最初の交換で発行されたトークンは無効になります。
- サインインページ:
- 1 つの IP(または 1 つの IPv6 /64)からパスフレーズを 5 回間違えると、そのアドレスは 15 分間ロックアウトされます
- 短時間にどこからでも 20 回間違えると、サインインは 1 時間停止します。すでに発行されたトークンは引き続き使用できますが、誰でも新たなサインインを 1 時間遅らせられることになります。
- すべての失敗に 0.5 秒の遅延が加わります
- フォームが受け付けるのは自身のオリジンからの POST のみです。スクリプトや外部アセットはなく、厳格なコンテンツセキュリティポリシーが設定されています
- ログには、サインイン、失敗、ロックアウト、トークンの再利用がクライアント ID と IP とともに記録されます。パスフレーズ、コード、トークンは記録されません。
セッション
セッションはメモリ上に保持されます。30 分間リクエストのないセッションは閉じられ、クライアントは次回の呼び出し時に新しいセッションを開始します。終了前に SIGTERM と SIGINT によってすべてのセッションが閉じられます。
Docker
Dockerfile は、非特権ユーザー node としてポート 3000 でリッスンする HTTP モードで起動するイメージをビルドします。コンテナー内では、公開ポートからアクセスできるように 0.0.0.0 にバインドします。ポートはループバックインターフェイスのみに公開し、シークレットは実行時に渡してください。イメージにはシークレットは含まれません。
docker build -t toshl-mcp-server .
docker run -d --restart unless-stopped \
-p 127.0.0.1:3000:3000 \
--env-file /path/outside/the/repo/toshl-mcp.env \
toshl-mcp-server
環境変数ファイルには TOSHL_API_TOKEN、MCP_ALLOWED_HOSTS、および MCP_AUTH_TOKEN または OAuth 設定のいずれかを記述します。いずれも設定されていない場合、MCP_ALLOW_NO_AUTH=true を指定しない限り、コンテナーは起動時に終了します。このファイルは所有者のみが読み取れるようにしてください(chmod 600)。.dockerignore により、すべての .env* ファイルがビルドコンテキストから除外されます。
OAuth を有効にする場合は、サインイン状態を再デプロイ後も維持できるように、/app/state に(uid 1000 が書き込み可能な)ボリュームをマウントします。例:-v /srv/toshl-mcp/state:/app/state。
開発
開発モードでサーバーを実行します。
npm run dev
ドキュメント
プロジェクト構成
toshl-mcp-server/
├── src/
│ ├── index.ts # Entry point
│ ├── server/ # MCP server implementation
│ │ └── server.ts # Main server class
│ ├── api/ # Toshl API client
│ │ ├── toshl-client.ts # Base API client
│ │ ├── auth.ts # Authentication module
│ │ └── endpoints/ # Endpoint-specific clients
│ │ ├── accounts.ts # Accounts API client
│ │ ├── categories.ts # Categories API client
│ │ ├── tags.ts # Tags API client
│ │ ├── budgets.ts # Budgets API client
│ │ ├── entries.ts # Entries API client
│ │ ├── me.ts # User API client
│ │ └── planning.ts # Planning API client
│ ├── resources/ # MCP resource handlers
│ │ ├── account-resources.ts # Account resources
│ │ ├── category-resources.ts# Category resources
│ │ ├── tag-resources.ts # Tag resources
│ │ ├── budget-resources.ts # Budget resources
│ │ └── user-resources.ts # User resources
│ ├── tools/ # MCP tool handlers
│ │ ├── account-tools.ts # Account tools
│ │ ├── category-tools.ts # Category tools
│ │ ├── tag-tools.ts # Tag tools
│ │ ├── budget-tools.ts # Budget tools
│ │ ├── user-tools.ts # User tools
│ │ └── analysis-tools.ts # Financial analysis tools
│ └── utils/ # Utility functions
│ ├── cache.ts # Caching utilities
│ ├── error-handler.ts # Error handling utilities
│ ├── logger.ts # Logging utilities
│ └── types.ts # TypeScript type definitions
├── dist/ # Compiled JavaScript files
├── .env # Environment variables
├── .env.example # Example environment variables
├── package.json # Project dependencies
├── tsconfig.json # TypeScript configuration
└── README.md # Project documentation
設定
サーバーは環境変数を使って設定できます。
TOSHL_API_TOKEN:Toshl API トークンTOSHL_API_BASE_URL:Toshl API のベース URL(デフォルト:https://api.toshl.com)MCP_SERVER_NAME:MCP サーバーの名前(デフォルト:toshl-mcp-server)MCP_SERVER_VERSION:MCP サーバーのバージョン(デフォルト:0.1.0)CACHE_TTL:キャッシュデータの有効期間(秒)(デフォルト:3600)CACHE_ENABLED:キャッシュを有効にするかどうか(デフォルト:true)LOG_LEVEL:ログレベル(デフォルト:info)MCP_TRANSPORT、MCP_HTTP_HOST、MCP_HTTP_PORT、MCP_AUTH_TOKEN、MCP_ALLOW_NO_AUTH、MCP_ALLOWED_HOSTS、MCP_ALLOWED_ORIGINS: リモート利用(Streamable HTTP)を参照してください
ライセンス
MIT
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。