Skip to main content
Glama
mitetenov

Bedolaga MCP Server

by mitetenov

Bedolaga MCP Server

MCP サーバーは、Bedolaga Bot から Telegram ID または内部 user_id でユーザーファクトを取得します。

サーバーは read-only です。Bedolaga MCP を介して、残高の変更、サブスクリプションの作成や延長、プロモコードの適用、返金の処理、紹介資金の引き出し、その他ユーザーに代わっての操作はできません。

破壊的移行 (1.0.0)

バージョン 1.0.0 以降、ツールの公開コントラクトが変更され、古い名前は削除されました。クライアントの設定を更新してください:

旧ツール

代替

bedolaga_balance

bedolaga_user_get に置き換え

bedolaga_transactions

bedolaga_billing_get に置き換え

bedolaga_subscription

Bedolaga MCP には相当するものはありません。実際のサブスクリプションステータスと VPN パネルの状態は、このサーバーではなく、別の mcp-remnawave で確認します

また、1.0.0 では非推奨の HTTP パス /mcp が削除されました。sessionful Streamable HTTP は、mcp-remnawave と同様にルートエンドポイント / で提供されるようになりました。イメージの各公開には、:latest:{version}:{sha} の3つのタグが付与されます。

バージョン 1.0.0 は、正しい API ルート、構造化された結果、Remnawave との明確な責任境界を備えた最初のコントラクトです。

Related MCP server: Monobank MCP Server

ツール

サーバーは、MCP プロトコルを介して利用できるちょうど8つのツールを提供します。すべてのツールは readonly であり、データは変更されません。

アイデンティティのコントラクト

各ツールは、次の2つのフィールドのうちちょうど1つを受け取ります:

  • telegram_id — 整数、ユーザーの Telegram ID(正の値);

  • user_id — 整数、Bedolaga 内のユーザー内部 ID(正の値)。メール専用のキャビネットチケットに使用されます。

フィールドが1つも渡されない場合、または両方が渡された場合、ツールは invalid_input エラーを返します。アイデンティティはモデルから取得されることはありません。supportBot は常に実際の送信者を特定します。認証された Telegram update からの正の telegram_id、または email-only チケットの場合はキャビネットの内部 user_id です。

bedolaga_user_get

現在の Bedolaga ユーザーのアカウントと残高を取得します。

パラメータ:

パラメータ

必須

説明

telegram_id

int

2つのうち正確に1つ

ユーザーの Telegram ID

user_id

int

2つのうち正確に1つ

Bedolaga ユーザーの内部 ID(email-only チケット)

レスポンスの JSON フィールド(data):

フィールド

説明

found

bool

ユーザーが見つかったかどうかのフラグ

telegram_id

int | null

ユーザーの Telegram ID

display_name

string | null

安全な表示名

status

string | null

Bedolaga アカウントのステータス

balance_kopeks

int | null

残高(コペイカ)

balance_rubles

float | null

残高(ルーブル)(常に kopeks / 100

has_made_first_topup

bool | null

過去に初回入金を行ったかどうかのフラグ

has_had_paid_subscription

bool | null

過去に有料購入があったかどうかのフラグ

referral_code

string | null

紹介コード

was_referred

bool | null

招待経由で登録したかどうか

promo_group

object | null

プロモグループ名と割引率

created_at / last_activity

string | null

作成日と最終アクティビティ日

promo_group フィールドには、nameserver_discount_percenttraffic_discount_percentdevice_discount_percent のみが含まれます。

解釈の例(合成データ): balance_kopeks: 350000balance_rubles: 3500.0 は、残高 3,500 ルーブルを意味します。has_had_paid_subscription: false は、有料購入がまだないことを意味します。

bedolaga_billing_get

1回の呼び出しで、残高、最近の金融イベント、Bedolaga の内部購入記録を表示し、入金と購入を区別します。

パラメータ:

パラメータ

必須

説明

telegram_id

int

2つのうち正確に1つ

ユーザーの Telegram ID

user_id

int

2つのうち正確に1つ

Bedolaga ユーザーの内部 ID(email-only チケット)

limit

int

なし

リスト内の操作数の上限(デフォルト 20、最大 50)

レスポンスの JSON フィールド(data):

フィールド

説明

balance_kopeks / balance_rubles

int / float | null

現在の残高

transactions

array

新しいものから古いものへの操作。最大 limit

latest_completed_deposit

object | null

最後に完了した入金のサマリー

latest_completed_subscription_purchase

object | null

最後に完了したサブスクリプション購入のサマリー

purchased_after_latest_deposit

bool | null

最後に完了した入金より後に完了した購入があるかどうか

bot_subscriptions

array

Bedolaga の内部サブスクリプション記録

meta

string

固定の説明「deposit ≠ purchase」

transactions 内の各操作:

フィールド

説明

id

number | null

トランザクションの内部 ID

category

string

正規化されたカテゴリ: deposit, subscription_purchase, gift_purchase, withdrawal, refund, failed_refund, referral_reward, poll_reward, unknown

direction

string

credit / debit / unknown

raw_type

string | null

元の安全なタイプ名

amount_kopeks / amount_rubles

int / float | null

絶対額

payment_method

string | null

支払い方法

is_completed

bool | null

操作が完了しているかどうか

description

string | null

説明

created_at / completed_at

string | null

作成時刻と完了時刻

bot_subscriptions 内の各レコードには、idbot_record_statusbot_record_effective_statusis_trialtariff_idtariff_namestart_dateend_dateautopay_enabledautopay_days_before、および固定の note が含まれます。サーバーは完全なアップストリームリスト subscriptions を優先し、id で重複レコードを削除し、単一のレガシーフィールド subscription へのフォールバックを保持します。このフィールドが bot_record_status という名前なのは意図的です。これは Bedolaga の内部レコードであり、VPN パネルのステータスではありませんbot_record_effective_status もボット側の実効ステータス(statusend_date からボットが計算したもの)であり、パネルの状態ではありません。

解釈の例(合成データ): latest_completed_deposit: {amount_kopeks: 350000}purchased_after_latest_deposit: false は、入金が残高に計上されたが、入金後の個別の購入は完了していないことを意味します。

bedolaga_referrals_get

現在のユーザーの紹介サマリーを取得します。

パラメータ:

パラメータ

必須

説明

telegram_id

int

2つのうち正確に1つ

ユーザーの Telegram ID

user_id

int

2つのうち正確に1つ

Bedolaga ユーザーの内部 ID(email-only チケット)

レスポンスの JSON フィールド(data):

フィールド

説明

referral_code

string | null

アカウント所有者の紹介コード

was_referred

bool | null

所有者が招待で来たかどうか

effective_referral_commission_percent

number | null

実効手数料

invited_count

int | null

招待合計数

active_referrals

int | null

アクティブな招待者数

total_earned_kopeks / total_earned_rubles

int / float | null

全期間の収益

month_earned_kopeks / month_earned_rubles

int / float | null

当月の収益

recent_referral_rewards

array

所有者の最近の付与

meta

string

固定の説明

返されるのはアカウント所有者のみの統計です。招待されたユーザーの Telegram ID、内部 ID、username、名前、残高、アクティビティは決して返されません。

bedolaga_subscription_get

Bot 側のサブスクリプション記録とライフサイクル日付(created_atstart_dateend_dateis_trialautopay_enabled)を取得します。

パラメータ: telegram_id または user_id(いずれか1つのみ)。

has_subscription_recordsactive_record_countsubscriptions リスト、固定の meta を返します。bot_record_status フィールドは Bot の内部記録であり、VPN パネルのステータスではありません(実際の状態は Remnawave MCP で確認します)。

bedolaga_tickets_get

自分のサポートチケットの概要(idtitlestatuspriority、作成/更新/クローズ日時)を、メッセージ本文やメディアなしで取得します。

パラメータ: telegram_id または user_id(いずれか1つのみ)、limit(デフォルト10、最大50)。

bedolaga_payment_status_get

Bot の会計システムにおける金融取引履歴と完了ステータス(completed / not_completed / unknown)を取得します。

パラメータ: telegram_id または user_id(いずれか1つのみ)、limit(デフォルト5、最大20)。

not_completed ステータスは、Bot の課金処理で取引が完了していないことを意味するだけで、支払いゲートウェイ側の障害や待機を意味するものではありません

bedolaga_promocode_check

プロモコードのグローバル定義、有効期限、アクティブ状態、ボーナス、残り利用回数を確認します。

パラメータ: code(必須)、telegram_id または user_id(いずれか1つのみ、ID 固定用)。

マスクされたコード(code_masked)、globally_valid フラグ、reason_codenot_foundinactivenot_yet_validexpired_or_exhaustedlookup_incomplete)、および user_eligibility: "unknown" を返します。

bedolaga_gifts_get

アカウント所有者のギフト購入履歴を取得します。

パラメータ: telegram_id または user_id(いずれか1つのみ)、limit(デフォルト20、最大50)。

ギフトの購入事実(会計)のみを表示します。ギフトトークン、受取人、アクティベーションステータスは開示されません。

判定テーブル

LLM(supportBot)がシナリオに応じて Bedolaga と Remnawave のデータをどう使うか:

シナリオ

Bedolaga MCP で見えるもの

LLM のアクション

入金(購入なし)

deposit あり、purchased_after_latest_deposit: false

お金は残高に入金されているが、個別の購入は完了していないことを説明し、残高から購入を完了するよう案内する。サブスクリプションの故障とは断言しない

購入(パネル稼働中)

完了した subscription_payment あり

Remnawave MCP でパネルの実際の状態を確認する

購入(パネル記録なし)

完了した subscription_payment あり

確認された不整合として、簡潔な事実に基づく要約付きでエスカレーションする

入金なし

deposit なし

支払いプロバイダーが引き落としていないとは断言しない(Bedolaga は自社の会計システムに入金がないことのみを確認する)。ユーザーが実際の引き落としを報告した場合はエスカレーションする

紹介に関する質問

bedolaga_referrals_get

Bedolaga MCP のみにルーティングする

ノード / HWID に関する質問

Remnawave MCP のみにルーティングする(ノードとデバイスの状態は Bedolaga は知らない)

結果の形式

各ツールは、共通ラッパー付きのテキスト MCP content 内の JSON を返します:

  • 成功: ok: truesource: "bedolaga-mcp"tooldatameta;

  • エラー: ok: falsesourcetoolerror.code、安全な error.messageerror.retryable

Bedolaga API の生のレスポンスボディや Python モデルの例外は返されません。ツールは email、サブスクリプションリンク、crypto link、キー、外部決済 ID、receipt 識別子、Remnawave 識別子、紹介者の個人データを返しません。

エラーコード

コード

Retryable

発生条件

invalid_input

いいえ

identity フィールドが両方または両方ともなしで渡された。不正な値

not_configured

いいえ

環境設定が欠落/不正

identity_unavailable

いいえ

アイデンティティを Bedolaga ユーザーにマッピングできない

user_not_found

いいえ

ユーザーが見つからない(upstream 404)

unauthorized

いいえ

API クレデンシャルが不正/欠落(upstream 401/403)

rate_limited

はい

rate limit に達した(upstream 429)

upstream_timeout

はい

応答までのタイムアウトまたはネットワーク障害

upstream_unavailable

はい

upstream が利用不可(5xx または回復不能なエラー)

invalid_upstream_response

いいえ

レスポンスボディが不正な JSON またはオブジェクトではない

internal_error

いいえ

予期しない内部エラー

ユーザー向けメッセージは安全な error.message のみから構築され、HTTP ボディや内部 URL を決して開示しません。

トランスポート

サーバーは、単一の server factory と単一のツールレジストリ上で2つのトランスポートをサポートします:

トランスポート

Launcher

ポート

プロトコル

Streamable HTTP(メイン)

http_server.py

デフォルト3100

/ 上のデュアルエラ MCP(下記参照)、GET /healthDELETE /(legacy セッションのみ)

Stdio

bedolaga_server.py

MCP stdio handshake(同じ factory)

エンドポイント / は1つだけですが、2つのプロトコルエラを同時に処理します。SDK v2 は各リクエストがどのエラに属するかを MCP-Protocol-Version ヘッダーで自動判定します:

  • 最新プロトコル 2026-07-28 — stateless/sessionless。/ への各 POST は自己完結型で、サーバーは Mcp-Session-Id を発行せず、リクエスト間で状態を保持しません。公式 MCP SDK v2 クライアント(下記「公式 SDK v2 クライアント」参照)はこのモードを自動的に使用します。

  • initialize-handshake を使用する legacy クライアント2024-11-05 を含む 2025-11-25 までのプロトコル)は、initialize への応答で Mcp-Session-Id ヘッダーを受け取り、以降のすべてのリクエストでそれを渡す必要があります。このヘッダー付きの DELETE / はそのセッションのみを終了します。他のセッションや最新クライアントには影響しません。

GET /health はプロセスの liveness とサーバーバージョンを返し、設定やシークレットは開示しません。

バージョン互換性

コンポーネント

バージョン

Bedolaga Bot API (upstream)

commit 49b05d5、アプリ 4.1.0

bedolaga-mcp

1.2.0

Python MCP SDK (mcp)

2.0.0

サポートされる MCP プロトコル

2026-07-28(最新、stateless)+ 2025-11-25 までの legacy initialize-handshake

supportBot

2.0.1

mcp-remnawave

v3.2.1

ツール契約は、指定された upstream コミットおよび mcp-remnawave v3.2.1 のリファレンスに対して検証済みです。

要件

  • Python 3.11+

  • Docker(オプション)

  • Web API 付きの Bedolaga Bot がデプロイされていること

  • Bedolaga の API キー(Bot の管理パネルで発行)

クイックスタート

1. クローン

git clone https://github.com/mitetenov/bedolaga-mcp.git
cd bedolaga-mcp

2. 設定

cp .env.example .env
# Заполнить BEDOLAGA_API_URL и BEDOLAGA_API_KEY

3. 起動

Streamable HTTP(推奨):

# Установить зависимости
pip install -r requirements.txt

# Запустить HTTP-сервер
BEDOLAGA_API_URL=https://your-bot.example.com \
BEDOLAGA_API_KEY=your-key \
python3 http_server.py

サーバーは http://0.0.0.0:3100 で待ち受け、MCP endpoint はルート / です。

Stdio:

BEDOLAGA_API_URL=https://your-bot.example.com \
BEDOLAGA_API_KEY=your-key \
python3 bedolaga_server.py

Docker 経由:

docker compose up -d

Docker イメージはデフォルトでポート3100の Streamable HTTP サーバーを起動します。

MCP サーバーとしての接続

Streamable HTTP

サーバーは HTTP ポート3100で利用可能で、endpoint はルート /http://localhost:3100)です。

Hermes Agent

# ~/.hermes/config.yaml
mcp_servers:
  bedolaga:
    transport: streamable-http
    url: "http://localhost:3100"
    env:
      BEDOLAGA_API_URL: "https://your-bot.example.com"
      BEDOLAGA_API_KEY: "your-api-key"

Claude Desktop

{
  "mcpServers": {
    "bedolaga": {
      "type": "streamableHttp",
      "url": "http://localhost:3100"
    }
  }
}

Cursor / VS Code

{
  "mcpServers": {
    "bedolaga": {
      "transport": "streamable-http",
      "url": "http://localhost:3100"
    }
  }
}

curl での確認(legacy compatibility check)

curl による生の JSON-RPC は legacy initialize-handshake(プロトコル 2024-11-05)を使用します。これは手動の後方互換性チェックであり、最新クライアントの通信方法ではありません。最新の MCP SDK v2 クライアントはプロトコル 2026-07-28 を自動的にネゴシエーションし、Mcp-Session-Id を受け取りません(下記「公式 SDK v2 クライアント(最新プロトコル)」参照)。

# Liveness
curl -s http://localhost:3100/health

# Legacy initialize handshake (получить session ID; работает для протоколов вплоть до 2025-11-25)
curl -s -X POST http://localhost:3100/ \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{}},"id":1}' \
  -D - | grep -i mcp-session-id

# Список инструментов (с session ID)
curl -s -X POST http://localhost:3100/ \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: <SESSION_ID>" \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":2}'

# Вызов инструментов
# Пользователь и баланс
curl -s -X POST http://localhost:3100/ \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: <SESSION_ID>" \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"bedolaga_user_get","arguments":{"telegram_id":123456789}},"id":3}'

# Биллинг (операции и внутренние записи покупок)
curl -s -X POST http://localhost:3100/ \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: <SESSION_ID>" \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"bedolaga_billing_get","arguments":{"telegram_id":123456789,"limit":20}},"id":4}'

# Реферальная сводка
curl -s -X POST http://localhost:3100/ \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: <SESSION_ID>" \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"bedolaga_referrals_get","arguments":{"telegram_id":123456789}},"id":5}'

# Завершение legacy-сессии (для современного протокола 2026-07-28 не требуется и не применяется)
curl -s -X DELETE http://localhost:3100/ \
  -H "Mcp-Session-Id: <SESSION_ID>"

公式 SDK v2 クライアント(最新プロトコル)

Python MCP SDK v2(mcp==2.0.0)の公式クライアントは、サーバーがサポートしていれば 2026-07-28、そうでなければ legacy-handshake を、_meta やヘッダーの手動構築なしで自動的にネゴシエーションします:

import asyncio

from mcp.client.client import Client


async def main() -> None:
    async with Client("http://localhost:3100/", mode="auto") as client:
        print("negotiated protocol:", client.protocol_version)  # "2026-07-28" against this server

        tools = await client.list_tools()
        print([tool.name for tool in tools.tools])

        result = await client.call_tool(
            "bedolaga_user_get", {"telegram_id": 123456789}
        )
        print(result.content)


asyncio.run(main())

mode="auto" は supportBot が使用するのと同じネゴシエーションです。クライアント自身が、目の前のサーバーが最新版かレガシーかを判断し、呼び出し側のコードが事前にプロトコル時代を知っている必要はありません。

Stdio トランスポート

Hermes Agent

# ~/.hermes/config.yaml
mcp_servers:
  bedolaga:
    command: "python3"
    args: ["/path/to/bedolaga-mcp/bedolaga_server.py"]
    env:
      BEDOLAGA_API_URL: "https://your-bot.example.com"
      BEDOLAGA_API_KEY: "your-api-key"

Claude Desktop

{
  "mcpServers": {
    "bedolaga": {
      "command": "python3",
      "args": ["/path/to/bedolaga-mcp/bedolaga_server.py"],
      "env": {
        "BEDOLAGA_API_URL": "https://your-bot.example.com",
        "BEDOLAGA_API_KEY": "your-api-key"
      }
    }
  }
}

Cursor / VS Code

.cursor/mcp.json または settings.json に追加します:

{
  "mcpServers": {
    "bedolaga": {
      "command": "python3",
      "args": ["/path/to/bedolaga-mcp/bedolaga_server.py"],
      "env": {
        "BEDOLAGA_API_URL": "https://your-bot.example.com",
        "BEDOLAGA_API_KEY": "your-api-key"
      }
    }
  }
}

セッション管理

Streamable HTTP トランスポートは dual-era であり、セッションは2つの時代のうちの1つにのみ適用されます:

  • レガシー initialize-handshake (2025-11-25 までのプロトコル): initialize の後、サーバーは Mcp-Session-Id ヘッダーを返し、クライアントは後続のすべてのリクエストでそれを渡す必要があります。このヘッダーを使った DELETE / は指定されたセッションのみを終了します。1つのクライアントが他のクライアントのセッションを終了したり再利用したりすることはできません。

  • 最新プロトコル 2026-07-28: stateless/sessionless — サーバーは Mcp-Session-Id を決して発行せず、そのようなクライアントに対して DELETE / は不要であり、適用されません。

環境変数

変数

用途

BEDOLAGA_API_URL

Bedolaga Web API の URL

BEDOLAGA_API_KEY

Bedolaga API キー(upstream に X-API-Key として渡されます)

MCP_HTTP_HOST

バインドするアドレス(デフォルト: 0.0.0.0

MCP_HTTP_PORT

HTTP サーバーのポート(デフォルト: 3100

BEDOLAGA_TIMEOUT_MS

upstream のタイムアウト(ミリ秒、デフォルト: 10000)

互換性のため、MCP_HTTP_HOST/MCP_HTTP_PORT が設定されていない場合は、レガシー変数 HOST/PORT が受け入れられます。

Upstream API

Bedolaga Web API: ヘッダーに X-API-Key を指定します。使用するルート:

  • GET /users/by-telegram-id/{telegram_id} — Telegram ID によるユーザー;

  • GET /users/{user_id} — 内部 ID によるユーザー(email-only チケット);

  • GET /transactions?user_id=... — フィルターとページネーション付きの取引;

  • GET /partners/referrers/{user_id} — リファーラルカード。

詳細: https://docs.bedolagam.ru

初版の制限

  • プロバイダー固有の支払い試行はありません。 Bedolaga は、共通の transactions テーブルのレコードになった操作のみを返します。レコードにならなかった支払いプロバイダーの生の試行は利用できません。

  • ユーザーの Redis カートの読み取りはありません。 現在の Web API は、このための安全な read-only エンドポイントを提供していません。「入金したのに購入がない」という現在の問題は、depositsubscription_payment の差によって確実に診断できます(decision table を参照)。

  • Email-only ルックアップはサポートされています。 Telegram ID を持たないキャビネットのチケットの場合、サーバーは内部 user_id(正の整数)を受け入れ、GET /users/{user_id} でそれを解決します。supportBot はキャビネットの内部 user_id(負の synthetic conversation key の絶対値)をピン留めします。そのようなチケットでは Bedolaga データが利用可能ですが、Remnawave ツールは identity_unavailable を返します。これは、そのようなユーザーには Telegram アイデンティティとパネル内の証明されたレコードがないためです。

ロールバック (rollback)

supportBot で BEDOLAGA_MCP_ENABLED=false を無効にすると、Remnawave-only モードに戻ります。Bedolaga MCP は接続されず、そのツールは allowlist から消え、ウェブフック/poller によるチケット処理(BEDOLAGA_ENABLED)は独立したままです。ロールバックはユーザーベースと財務データに影響しません。Bedolaga MCP は read-only であり、状態を保持しません。

bedolaga-mcp イメージをタグ 1.1.0(MCP SDK v2 への移行前の最後のリリース、レガシー時代の Streamable HTTP のみ)にロールバックすることも安全です。MCP SDK v2 上の supportBot クライアントは、サーバーが最新プロトコル 2026-07-28 に応答しない場合、自動的に(auto-fallback)レガシー initialize-handshake に移行するため、Bedolaga MCP ツールは追加設定なしで引き続き利用できます。

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    Provides user balance information by connecting to a backend service through the users_balance tool. Built with TypeScript and Express for retrieving financial data.
    -
  • A
    license
    A
    quality
    A
    maintenance
    Enables integration with Monobank API to check currency exchange rates, view account balances, and retrieve transaction statements through natural language queries.
    3
    29 npm
    9
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables interaction with Telegram Bot API for sending messages, photos, editing messages, answering callbacks, and fetching updates.
    MIT