robokassa-mcp
Comprehensive Python client and Model Context Protocol server for Robokassa — the Russian payment gateway.
Covers the full API surface: checkout, XML status interfaces, refunds, holding (pre-auth), recurring subscriptions, 54-ФЗ fiscal receipts, Partner API, and auxiliary endpoints.
Install (once published)
# As an MCP server for Claude Desktop / Claude Code / Cursor / Windsurf
uvx robokassa-mcp
# As a Python library
pip install robokassa-mcpUse as a Python library
import asyncio
from decimal import Decimal
from robokassa import create_invoice, RobokassaClient
# Build a signed checkout URL (no HTTP — just URL construction).
invoice = create_invoice(
merchant_login="my-shop",
out_sum=Decimal("599.00"),
inv_id=12345,
password1="...",
description="Premium subscription",
email="user@example.com",
)
print(invoice.url) # https://auth.robokassa.ru/Merchant/Index.aspx?...
# Check the state of a payment (hits the OpStateExt XML endpoint).
async def check() -> None:
async with RobokassaClient("my-shop", password2="...") as client:
state = await client.check_payment(inv_id=12345)
print(state.is_paid, state.info.op_key)
asyncio.run(check())Full refund flow
from robokassa import RobokassaClient
async def refund_flow(inv_id: int) -> None:
async with RobokassaClient("my-shop", password2="p2", password3="p3") as client:
# 1. Fetch the payment state to get its OpKey.
state = await client.check_payment(inv_id)
assert state.info.op_key, "payment not complete yet"
# 2. Initiate a refund.
created = await client.refund_create(state.info.op_key)
print("refund requestId:", created.request_id)
# 3. Poll status until finished / canceled.
while True:
status = await client.refund_status(created.request_id)
if status.is_terminal:
print("final:", status.state)
breakWebhook signature verification (FastAPI example)
from fastapi import FastAPI, Request, HTTPException, PlainTextResponse
from robokassa import verify_result_signature, build_ok_response
app = FastAPI()
@app.post("/robokassa/result")
async def result_url(req: Request) -> PlainTextResponse:
form = dict(await req.form())
if not verify_result_signature(form, password2="..."):
raise HTTPException(status_code=403, detail="Bad signature")
# ... persist the notification, mark invoice paid ...
return PlainTextResponse(build_ok_response(form["InvId"]))Use as an MCP server
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"robokassa": {
"command": "uvx",
"args": ["robokassa-mcp"],
"env": {
"ROBOKASSA_LOGIN": "your-shop-login",
"ROBOKASSA_PASSWORD1": "password1",
"ROBOKASSA_PASSWORD2": "password2",
"ROBOKASSA_PASSWORD3": "password3"
}
}
}
}Claude Code
claude mcp add robokassa \
-e ROBOKASSA_LOGIN=my-shop \
-e ROBOKASSA_PASSWORD1=... \
-e ROBOKASSA_PASSWORD2=... \
-e ROBOKASSA_PASSWORD3=... \
-- uvx robokassa-mcpCursor
Edit ~/.cursor/mcp.json:
{
"mcpServers": {
"robokassa": {
"command": "uvx",
"args": ["robokassa-mcp"],
"env": {
"ROBOKASSA_LOGIN": "your-shop-login",
"ROBOKASSA_PASSWORD1": "password1",
"ROBOKASSA_PASSWORD2": "password2",
"ROBOKASSA_PASSWORD3": "password3"
}
}
}
}VS Code (GitHub Copilot)
In user or workspace settings.json:
{
"github.copilot.chat.mcp.servers": {
"robokassa": {
"command": "uvx",
"args": ["robokassa-mcp"],
"env": {
"ROBOKASSA_LOGIN": "your-shop-login",
"ROBOKASSA_PASSWORD1": "password1",
"ROBOKASSA_PASSWORD2": "password2",
"ROBOKASSA_PASSWORD3": "password3"
}
}
}
}Windsurf
Edit ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"robokassa": {
"command": "uvx",
"args": ["robokassa-mcp"],
"env": {
"ROBOKASSA_LOGIN": "your-shop-login",
"ROBOKASSA_PASSWORD1": "password1",
"ROBOKASSA_PASSWORD2": "password2",
"ROBOKASSA_PASSWORD3": "password3"
}
}
}
}HTTP transport (MCP Inspector, remote clients)
uvx robokassa-mcp --transport http --port 8000Flags: --transport {stdio,http,streamable-http,sse}, --host, --port.
MCP tools exposed to agents
All 18 tools are wrapped as @mcp.tool() and available to any MCP-capable agent (Claude Desktop, Claude Code, Cursor, Windsurf, etc.).
Tool | Purpose | Auth |
| Build a signed checkout URL (optional 54-ФЗ receipt). | Password#1 |
| Get current state of a payment by InvId (via OpStateExt). | Password#2 |
| List payment methods available to the shop. | — |
| Compute amount credited to shop for a given payment. | Password#1 |
| Initiate a refund (requires Refund API access). | Password#3 JWT |
| Poll refund progress by requestId. | — |
| Validate a ResultURL webhook. | Password#2 |
| Validate a SuccessURL redirect. | Password#1 |
| Two-step card pre-authorization. | Password#1 |
| Subscription auto-charges. | Password#1 |
| Marketplace multi-recipient checkout. | — |
| Paid SMS service. | Password#1 |
| 54-ФЗ final receipt after advance. | Password#1 |
| Alternative refund path for partner integrators. | Partner JWT |
Low-level signature helpers are available from Python only: compute_signature, op_state_signature, build_checkout_signature, build_refund_jwt, build_sms_signature, compute_result_signature, compute_success_signature, encode_fiscal_body.
API coverage
Mapped against the 8 public Robokassa API groups:
Group | Coverage | Module |
Merchant Checkout | ✅ |
|
XML Interfaces | ✅ |
|
Refund API | ✅ |
|
Holding / Pre-auth | ✅ init / confirm / cancel |
|
Recurring | ✅ parent + child |
|
Fiscal 54-ФЗ | ✅ second receipt create / status |
|
Partner API | 🟡 |
|
Auxiliary | ✅ |
|
Environment variables
Most high-level entry points fall back to these env vars when credentials aren't passed explicitly:
Variable | Required for |
| All operations |
| Checkout, webhook SuccessURL verification, CalcOutSumm, fiscal, SMS |
|
|
|
|
Signature algorithms
All signature-producing helpers accept algorithm= with "md5" / "sha256" / "sha384" / "sha512" — match whatever is configured in your Robokassa cabinet.
Development
git clone https://github.com/artgas1/robokassa-mcp.git
cd robokassa-mcp
uv sync --all-extras --dev
uv run pytest # 107+ unit tests
uv run ruff check .
uv run pyrightLicense
MIT — see LICENSE. Drop-and-forget maintenance; PRs welcome but not guaranteed to be reviewed promptly.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/artgas1/robokassa-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server