Bedolaga MCP Server
Bedolaga MCP Server
Telegram ID 또는 내부 user_id로 Bedolaga Bot에서 사용자 사실(facts)을 가져오는 MCP 서버입니다.
서버는 read-only입니다. Bedolaga MCP를 통해 잔액을 변경하거나, 구독을 생성·연장하거나, 프로모션 코드를 적용하거나, 환불을 처리하거나, 추천인 자금을 출금하거나, 사용자를 대신해 다른 작업을 수행할 수 없습니다.
Breaking migration (1.0.0)
1.0.0 버전부터 도구의 공개 계약이 변경되었으며 이전 이름은 제거되었습니다. 클라이언트 구성을 업데이트하세요:
이전 도구 | 대체 도구 |
|
|
|
|
| Bedolaga MCP에는 해당 기능이 없음. 실제 구독 상태와 VPN 패널 상태는 이 서버가 아닌 별도의 mcp-remnawave를 통해 확인함 |
또한 1.0.0에서는 더 이상 사용되지 않는 HTTP 경로 /mcp가 제거되었습니다. sessionful Streamable HTTP는 이제 mcp-remnawave와 마찬가지로 루트 endpoint /에서 제공됩니다. 각 이미지 게시물은 :latest, :{version}, :{sha} 세 가지 태그를 받습니다.
버전 1.0.0은 올바른 API routes, 구조화된 결과, 그리고 Remnawave와의 명확한 책임 경계를 갖춘 첫 번째 계약입니다.
Related MCP server: Monobank MCP Server
도구 (Tools)
서버는 MCP 프로토콜을 통해 정확히 여덟 개의 도구를 제공합니다. 모든 도구는 readonly이며 데이터를 변경하지 않습니다.
신원 계약
각 도구는 두 필드 중 정확히 하나를 받습니다:
telegram_id— 정수, 사용자의 Telegram ID(양수);user_id— 정수, Bedolaga의 내부 사용자 ID(양수), 이메일 전용(email-only) 티켓에 사용됨.
필드가 하나도 전달되지 않거나 둘 다 전달되면 도구는 invalid_input 오류를 반환합니다. 신원은 결코 모델에서 가져오지 않습니다. supportBot은 항상 실제 발신자를 고정(pin)합니다. 인증된 Telegram update의 양수 telegram_id 또는 이메일 전용 티켓의 내부 user_id입니다.
bedolaga_user_get
현재 Bedolaga 사용자의 계정과 잔액을 가져옵니다.
매개변수:
매개변수 | 타입 | 필수 | 설명 |
|
| 둘 중 정확히 하나 | 사용자의 Telegram ID |
|
| 둘 중 정확히 하나 | Bedolaga 내부 사용자 ID(이메일 전용 티켓) |
응답 JSON 필드(data):
필드 | 타입 | 설명 |
|
| 사용자가 발견되었는지 여부 |
|
| 사용자의 Telegram ID |
|
| 안전한 표시 이름 |
|
| Bedolaga 계정 상태 |
|
| 코페이카 단위 잔액 |
|
| 루블 단위 잔액(항상 |
|
| 과거 첫 충전 여부 |
|
| 과거 유료 구매 이력 여부 |
|
| 추천인 코드 |
|
| 초대를 통해 가입한 사용자인지 여부 |
|
| 프로모션 그룹 이름 및 할인율 |
|
| 생성일 및 마지막 활동일 |
promo_group 필드에는 name, server_discount_percent, traffic_discount_percent, device_discount_percent만 포함됩니다.
해석 예시(합성): balance_kopeks: 350000 및 balance_rubles: 3500.0은 3,500루블의 잔액을 의미합니다. has_had_paid_subscription: false는 아직 유료 구매가 없었음을 의미합니다.
bedolaga_billing_get
한 번의 호출로 잔액, 최근 금융 이벤트 및 Bedolaga 내부 구매 기록을 표시하여 충전과 구매를 구분합니다.
매개변수:
매개변수 | 타입 | 필수 | 설명 |
|
| 둘 중 정확히 하나 | 사용자의 Telegram ID |
|
| 둘 중 정확히 하나 | Bedolaga 내부 사용자 ID(이메일 전용 티켓) |
|
| 아니요 | 목록의 작업 수 제한(기본값 20, 최대 50) |
응답 JSON 필드(data):
필드 | 타입 | 설명 |
|
| 현재 잔액 |
|
| 최신순 작업, 최대 |
|
| 마지막으로 완료된 충전 요약 |
|
| 마지막으로 완료된 구독 구매 요약 |
|
| 마지막 완료 충전 이후 완료된 구매 여부 |
|
| Bedolaga 내부 구독 기록 |
|
| 고정 설명 "deposit ≠ purchase" |
transactions의 각 작업:
필드 | 타입 | 설명 |
|
| 내부 트랜잭션 ID |
|
| 정규화된 카테고리: |
|
|
|
|
| 원본 안전 타입 이름 |
|
| 절대 금액 |
|
| 결제 수단 |
|
| 작업 완료 여부 |
|
| 설명 |
|
| 생성 및 완료 시간 |
bot_subscriptions의 각 기록에는 id, bot_record_status, bot_record_effective_status, is_trial, tariff_id, tariff_name, start_date, end_date, autopay_enabled, autopay_days_before 및 고정 note가 포함됩니다. 서버는 전체 upstream subscriptions 목록을 우선시하고, id 기준으로 중복 기록을 제거하며, 단일 legacy 필드 subscription에 대한 fallback을 유지합니다. 필드 이름이 bot_record_status인 것은 의도적입니다. 이는 Bedolaga 내부 기록이지 VPN 패널 상태가 아닙니다. bot_record_effective_status 역시 봇 측 유효 상태(봇이 status와 end_date로 계산)이며 패널 상태가 아닙니다.
해석 예시(합성): latest_completed_deposit: {amount_kopeks: 350000} 및 purchased_after_latest_deposit: false — 돈은 잔액에 입금되었지만 충전 이후 별도의 구매는 완료되지 않았습니다.
bedolaga_referrals_get
현재 사용자의 추천인 요약을 가져옵니다.
매개변수:
매개변수 | 타입 | 필수 | 설명 |
|
| 둘 중 정확히 하나 | 사용자의 Telegram ID |
|
| 둘 중 정확히 하나 | Bedolaga 내부 사용자 ID(이메일 전용 티켓) |
응답 JSON 필드(data):
필드 | 유형 | 설명 |
|
| 계정 소유자의 추천인 코드 |
|
| 소유자가 초대를 통해 가입함 |
|
| 유효 수수료 |
|
| 총 초대 수 |
|
| 활성 초대 사용자 수 |
|
| 전체 기간 수익 |
|
| 이번 달 수익 |
|
| 소유자의 최근 적립 내역 |
|
| 고정 설명 |
계정 소유자의 통계만 반환됩니다. 초대된 사용자의 Telegram ID, 내부 ID, username, 이름, 잔액 및 활동은 절대 반환되지 않습니다.
bedolaga_subscription_get
봇 측 구독 기록과 수명 주기 날짜(created_at, start_date, end_date, is_trial, autopay_enabled)를 가져옵니다.
매개변수: telegram_id 또는 user_id (정확히 하나).
has_subscription_records, active_record_count, subscriptions 목록 및 고정 meta를 반환합니다. bot_record_status 필드는 봇의 내부 기록이며 VPN 패널 상태가 아닙니다 (실제 상태는 Remnawave MCP를 통해 확인합니다).
bedolaga_tickets_get
메시지 텍스트와 미디어 없이 자신의 지원 티켓 요약(id, title, status, priority, 생성/업데이트/종료 날짜)을 가져옵니다.
매개변수: telegram_id 또는 user_id (정확히 하나), limit (기본값 10, 최대 50).
bedolaga_payment_status_get
봇의 회계 시스템에서 금융 거래 내역과 완료 상태(completed / not_completed / unknown)를 가져옵니다.
매개변수: telegram_id 또는 user_id (정확히 하나), limit (기본값 5, 최대 20).
not_completed 상태는 봇의 빌링에서 거래가 완료되지 않았음을 의미할 뿐, 결제 게이트웨이 측의 오류나 대기를 의미하는 것이 아닙니다.
bedolaga_promocode_check
프로모코드의 전역 정의, 유효 기간, 활성 상태, 보너스 및 남은 사용 횟수를 확인합니다.
매개변수: code (필수), telegram_id 또는 user_id (정체성 고정을 위해 정확히 하나).
마스킹된 코드(code_masked), globally_valid 여부, reason_code(not_found, inactive, not_yet_valid, expired_or_exhausted, lookup_incomplete) 및 user_eligibility: "unknown"을 반환합니다.
bedolaga_gifts_get
계정 소유자의 선물 구매 내역을 가져옵니다.
매개변수: telegram_id 또는 user_id (정확히 하나), limit (기본값 20, 최대 50).
선물 구매 사실(회계)만 표시합니다. 선물 토큰, 수신자 및 활성화 상태는 공개되지 않습니다.
Decision table
LLM(supportBot)이 시나리오별로 Bedolaga 및 Remnawave 데이터를 사용하는 방법:
시나리오 | Bedolaga MCP에서 보이는 것 | LLM 조치 |
구매 없는 입금 |
| 돈이 잔액에 입금되었지만 별도의 구매가 완료되지 않았음을 설명하고, 잔액으로 구매를 완료하도록 안내합니다. 구독 오류라고 단정하지 않습니다 |
패널이 정상인 구매 | 완료된 | Remnawave MCP를 통해 패널의 실제 상태를 확인합니다 |
패널 기록 없는 구매 | 완료된 | 간략한 factual summary와 함께 확인된 불일치로 에스컬레이션합니다 |
입금 없음 |
| 결제 제공업체가 돈을 출금하지 않았다고 단정하지 않습니다(Bedolaga는 자체 회계 시스템에 입금이 없음만 확인합니다). 사용자가 실제 출금을 보고하면 에스컬레이션합니다 |
추천인 문의 |
| Bedolaga MCP로만 라우팅합니다 |
노드 / HWID 문의 | — | Remnawave MCP로만 라우팅합니다(Bedolaga는 노드 및 기기 상태를 알지 못합니다) |
결과 형식
각 도구는 단일 래퍼로 텍스트 MCP content에 JSON을 반환합니다:
성공:
ok: true,source: "bedolaga-mcp",tool,data,meta;오류:
ok: false,source,tool,error.code, 안전한error.message,error.retryable.
Bedolaga API 응답의 원본 본문과 Python 모델 예외는 반환되지 않습니다. 도구는 이메일, 구독 링크, crypto link, 키, 외부 결제 ID, receipt 식별자, Remnawave 식별자 및 추천인의 개인 데이터를 반환하지 않습니다.
Error codes
코드 | Retryable | 발생 시점 |
| 아니요 | identity 필드가 둘 다 전달되거나 하나도 전달되지 않음; 잘못된 값 |
| 아니요 | 환경 구성이 없거나 잘못됨 |
| 아니요 | 신원을 Bedolaga 사용자와 매핑할 수 없음 |
| 아니요 | 사용자를 찾을 수 없음 (upstream 404) |
| 아니요 | API 자격 증명이 잘못되었거나 없음 (upstream 401/403) |
| 예 | rate limit 도달 (upstream 429) |
| 예 | 응답 전 타임아웃 또는 네트워크 오류 |
| 예 | Upstream을 사용할 수 없음 (5xx 또는 복구 불가능한 오류) |
| 아니요 | 응답 본문이 유효하지 않은 JSON이거나 객체가 아님 |
| 아니요 | 예기치 않은 내부 오류 |
사용자 메시지는 안전한 error.message로만 구성되며 HTTP 본문이나 내부 URL을 절대 공개하지 않습니다.
전송
서버는 하나의 server factory와 하나의 도구 레지스트리에서 두 가지 전송을 지원합니다:
전송 | Launcher | 포트 | 프로토콜 |
Streamable HTTP (기본) |
| 기본 3100 |
|
Stdio |
| — | MCP stdio handshake(동일한 factory) |
/ 엔드포인트는 단 하나이지만 두 프로토콜 시대를 동시에 처리합니다. 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 |
bedolaga-mcp |
|
Python MCP SDK ( |
|
지원되는 MCP 프로토콜 |
|
supportBot |
|
mcp-remnawave |
|
도구 계약은 지정된 upstream 커밋 및 mcp-remnawave v3.2.1 기준과 대조하여 검증되었습니다.
요구 사항
Python 3.11+
Docker (선택 사항)
Web API가 있는 배포된 Bedolaga Bot
Bedolaga의 API 키(봇 관리자 패널에서 발급)
빠른 시작
1. 클론
git clone https://github.com/mitetenov/bedolaga-mcp.git
cd bedolaga-mcp2. 설정
cp .env.example .env
# Заполнить BEDOLAGA_API_URL и BEDOLAGA_API_KEY3. 실행
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 엔드포인트는 루트 /입니다.
Stdio:
BEDOLAGA_API_URL=https://your-bot.example.com \
BEDOLAGA_API_KEY=your-key \
python3 bedolaga_server.pyDocker 사용:
docker compose up -dDocker 이미지는 기본적으로 포트 3100에서 Streamable HTTP 서버를 실행합니다.
MCP 서버로 연결
Streamable HTTP
서버는 포트 3100의 HTTP로 접근할 수 있으며 엔드포인트는 루트 /(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이 사용하는 것과 동일한 협상입니다. 클라이언트가 스스로 서버가 최신인지 legacy인지 판단하며, 호출 코드가 프로토콜 시대를 미리 알 필요가 없습니다.
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이며, 세션은 두 시대 중 하나에만 적용됩니다:
Legacy initialize-handshake (
2025-11-25까지의 프로토콜):initialize후 서버는Mcp-Session-Id헤더를 반환하며, 클라이언트는 이후 모든 요청에서 이 헤더를 전달해야 합니다. 이 헤더를 사용한DELETE /는 지정된 세션만 종료합니다. 한 클라이언트는 다른 클라이언트의 세션을 종료하거나 재사용할 수 없습니다.최신 프로토콜
2026-07-28: stateless/sessionless — 서버는Mcp-Session-Id를 절대 발급하지 않으며, 이러한 클라이언트에게DELETE /는 필요하지도 않고 적용되지도 않습니다.
환경 변수
변수 | 용도 |
| Bedolaga Web API URL |
| Bedolaga API 키 (upstream에 |
| 바인드 주소 (기본값: |
| HTTP 서버 포트 (기본값: |
| upstream 타임아웃(밀리초) (기본값: 10000) |
호환성을 위해 MCP_HTTP_HOST/MCP_HTTP_PORT가 설정되지 않은 경우 legacy 변수 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
첫 버전의 제한 사항
Provider-specific 결제 시도 없음. Bedolaga는 공통 transactions 테이블에 레코드가 된 거래만 반환합니다. 레코드가 되지 않은 결제 제공자의 원시 시도는 사용할 수 없습니다.
사용자 Redis 장바구니 읽기 없음. 현재 Web API는 이를 위한 안전한 read-only 엔드포인트를 제공하지 않습니다. "충전했는데 구매가 없다"는 현재 문제는
deposit과subscription_payment의 차이로 확실하게 진단합니다(decision table 참조).Email-only 조회가 지원됩니다. Telegram ID가 없는 계정 티켓의 경우 서버는 내부
user_id(양의 정수)를 받아GET /users/{user_id}로 해석합니다. supportBot은 계정의 내부user_id(음의 synthetic conversation key의 절대값)를 고정합니다. 이러한 티켓의 경우 Bedolaga 데이터는 사용할 수 있지만, Remnawave 도구는identity_unavailable을 반환합니다. 해당 사용자에게는 Telegram 정체성과 패널에서 입증된 레코드가 없기 때문입니다.
롤백
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로 마이그레이션되기 전 마지막 릴리스, legacy 시대 Streamable HTTP만 지원)으로 롤백하는 것도 안전합니다. MCP SDK v2 기반 supportBot 클라이언트는 서버가 최신 프로토콜 2026-07-28에 응답하지 않으면 자동으로(auto-fallback) legacy initialize-handshake로 전환하므로, Bedolaga MCP 도구는 추가 설정 없이 계속 사용할 수 있습니다.
This server cannot be deployed
Maintenance
Related MCP Connectors
Non-custodial crypto payments for AI assistants: balances, payments, and create payment links.
Accept crypto payments via the TgPay Merchant API — invoices, subscriptions, webhooks.
Pay-per-use web extract, token prices, and wallet balances via x402 USDC micropayments.
Telegram bridge for your MCP-compatible agent. Bidirectional, no LLM in our stack.
Related MCP Servers
FlicenseNot gradedqualityNot gradedmaintenanceProvides user balance information by connecting to a backend service through the users_balance tool. Built with TypeScript and Express for retrieving financial data.-- AlicenseAqualityAmaintenanceEnables integration with Monobank API to check currency exchange rates, view account balances, and retrieve transaction statements through natural language queries.329 npm9MIT
- AlicenseNot gradedqualityDmaintenanceEnables interaction with Telegram Bot API for sending messages, photos, editing messages, answering callbacks, and fetching updates.MIT
- AlicenseNot gradedqualityBmaintenanceEnables sending Telegram messages, photos, and documents, and retrieving bot information through the Telegram Bot API.23 npm1MIT