# SimAtlas — MCP Server for AI Agents SimAtlas (СимАтлас) is a Russian-language eSIM service for travelers. This document describes the Model Context Protocol (MCP) server that lets AI agents search eSIM tariffs, quote a price, and create an order that returns a payment link. The human checkout, payment, and post-payment redirect are unchanged: the returned payment URL opens the normal payment page and, after a successful payment, redirects to the order success page. The eSIM (QR code + activation instructions) is delivered by email. ## Endpoint and transport - URL: https://simatlas.ru/mcp - Transport: MCP Streamable HTTP (spec 2025-11-25), stateless. - Only request/response tool calls are used; there are no server-initiated notifications or streaming. - Tool responses use structured JSON output. ## Authentication 1. Call the `start_session` tool (no auth required). It returns a temporary opaque bearer `token` and its `expires_at`. 2. Send that token on EVERY subsequent tool call as an HTTP header: `Authorization: Bearer `. 3. The token is the equivalent of a session cookie. It expires (24h by default); call `start_session` again to obtain a new one. Treat it as a secret — do not put it in tool arguments or share it. ## Tools ### start_session (no auth) Returns: `{ token, expires_at, usage }`. Begin here. ### search_esim_offers (read-only) Search eSIM data plans. Args: `country` (ISO alpha-2, e.g. TR, DE), `query`, `package_type` (`standard` | `daypass`), `limit` (1-50, default 20), `cursor` (opaque pagination cursor), `currency` (default RUB), `lang` (`ru` | `en`). Returns: `{ offers[], count, next_cursor }`. Each offer has `offer_id`, `name`, data amount, validity, package type, final `price` (RUB, all fees included), and covered `countries`. For daypass offers `is_daypass` is true and `price` is the TOTAL for `price_basis_days` days, while `price_per_day` and `data_per_day` (allowance per day) are per-day values — do not multiply `price` again; call `get_esim_offer` for the full per-day-count price grid. ### get_esim_offer (read-only) Details for one plan. Args: `offer_id`, `currency`, `lang`. For daypass plans (`is_daypass` true) the result includes a `day_options[]` grid — one entry per allowed day count, each `{ days, price (total for that many days), price_per_day }` — plus `min_days`/`max_days`. The top-level `price` is the total for `min_days`, and `price_per_day` / `data_per_day` are per-day values. ### list_countries (read-only) Supported destination countries (ISO code + localized name). Use it to map a country name to the code accepted by `search_esim_offers`. ### create_order_quote (step 1 of ordering) Compute a binding price quote. No order is created and no payment happens yet. Args: `offer_id`, `email` (buyer email for eSIM delivery), `days` (for daypass — if omitted for a daypass offer it defaults to the offer's minimum day count), `quantity`, `promo_code` (optional), `currency` (default RUB). Returns: `{ quote_id, amount, currency, data_amount, data_unit, days, summary, requires_confirmation, expires_at }`, where `amount` is the total for the resolved `days` (matching that day count's `day_options` entry). The quote is short-lived. ### confirm_order (step 2 of ordering) Create the order from a quote and get the payment link. Args: `quote_id`, `idempotency_key` (a unique client-chosen string so retries do not create duplicate orders), `payment_method` (`card` | `sbp`). Returns: `{ order_id, payment_url, amount, currency, status }`. Open `payment_url` to pay; the price charged is recomputed server-side and is rejected if it drifted above the quoted amount (request a fresh quote in that case). ### get_order_status (read-only) Check an order you created in this session. Args: `order_id`. Returns: `{ order_id, status, amount, currency, masked_iccid, usage_url }`. Raw eSIM activation credentials are never returned here; `usage_url` is a secure link to view activation details and data usage. ## Typical flow 1. `start_session` -> save the token; send it as `Authorization: Bearer` from now on. 2. `list_countries` or `search_esim_offers` (e.g. country=TR) -> pick an `offer_id`. 3. `get_esim_offer` -> confirm details / day options. 4. `create_order_quote` with `offer_id` + buyer `email` -> get `quote_id` + price. 5. `confirm_order` with `quote_id` + a unique `idempotency_key` -> get `payment_url`. 6. Give the buyer the `payment_url`. After payment they are redirected to the success page and receive the eSIM by email. 7. `get_order_status` to check progress. ## Notes - All prices are final, in RUB, including all fees, unless another currency is requested. - Payment is by Russian bank card or SBP (Sistema Bystrykh Platezhey). - Validity of a plan starts on first connection abroad, not at purchase. - Be conservative: confirm details with the buyer before calling `confirm_order`. ## Adding SimAtlas as a custom connector (OAuth) In addition to the `start_session` bearer flow above, the `/mcp` endpoint can be added directly as a custom connector in clients that speak OAuth 2.1 (e.g. the claude.ai connector UI). When enabled, the server advertises: - Protected-resource metadata: `https://simatlas.ru/.well-known/oauth-protected-resource/mcp` - Authorization-server metadata: `https://simatlas.ru/.well-known/oauth-authorization-server` - Dynamic Client Registration (RFC 7591): `POST https://simatlas.ru/oauth/register` - Authorization Code + PKCE (S256 only): `GET https://simatlas.ru/oauth/authorize` - Token + refresh: `POST https://simatlas.ru/oauth/token` The flow is auto-consent (no login screen) and anonymous, exactly like `start_session`. Just add `https://simatlas.ru/mcp` as the connector URL; the client discovers the endpoints, registers itself, and obtains a bearer token automatically. After that, all tool calls work the same as documented above. SDK/code clients that don't do OAuth should keep using `start_session`.