Install
openclaw skills install esimagentFind eSIM plans for travel. Searches plans by country, filters by data and duration, ranks by value, checks device compatibility, and surfaces deals. Connects via remote HTTP MCP endpoint — no install needed.
openclaw skills install esimagentHelp users find the best eSIM data plan for their trip. Search plans by country, filter by duration and data needs, check device compatibility, and surface active deals.
esim-agent MCP tools (names like search_esim_plans, list_providers, get_deals). If present → use them.https://esimagent.vdigital.app/api/* — a public, unauthenticated API. No credentials, no user data sent beyond the query parameters you pass.buyUrl (short click-tracked redirect on https://esimagent.vdigital.app/r/...) and an affiliateUrl (the raw partner URL with referral code). The buyUrl is a stable short link that resolves server-side to the same partner destination as affiliateUrl. Use buyUrl by default — it's what funds the service and keeps responses readable. Disclose affiliateUrl on request if the user asks for the direct partner link or wants to avoid the redirect.buyUrl record the provider, plan, and country but not user identity; the redirect then forwards the user to the partner.MCP servers are configured in the user's AI client BEFORE a session starts. You cannot install an MCP server during an active conversation and have it appear in your toolset. If esim-agent tools aren't in your current session, they won't appear later in this conversation — use the HTTP API immediately.
This is universal across every MCP server (Stripe, GitHub, Slack, etc.), not specific to eSIM Agent.
Available tools when the esim-agent MCP server is connected:
{country, minDays?, maxDays?, minGb?, maxGb?} — Returns plans already ranked and deal-fused. Pass bands to get opinionated matches; omit them for the full catalog.{} — All providers with ratings and features{} — Active promo codes and discounts{device} — eSIM support + installation steps{search?} — Country list (use to resolve ambiguous names)The server computes
matchScore,isExactDurationMatch,isExactDataMatch, andvalueScore. Trust these over your own scoring. Plans are already sorted by relevance when filters are passed.
Data filters (
minGb,maxGb) exclude unlimited plans. To find unlimited plans, omit data filters and look forcapacityMB === -1.
Base URL: https://esimagent.vdigital.app/api
Returns Plan[] — plans for a country. Optional query params let the server filter and rank for you. You do NOT need to re-sort or re-score.
Supported query params:
country (required) — ISO 3166-1 alpha-2 codeminDays, maxDays — integer days, 1..365 (plans outside the range are dropped)minGb, maxGb — GB, 0..1000 (plans outside the range are dropped; unlimited plans are excluded when either is set)Validation errors return HTTP 400 with a Zod issues array.
Response shape:
{
"id": "yesim-es-10240-10",
"providerId": "yesim",
"providerName": "Yesim",
"providerLogo": "/logos/yesim.jpg",
"country": "Spain",
"countryCode": "ES",
"capacityMB": 10240,
"capacityLabel": "10 GB",
"periodDays": 10,
"priceUSD": 14.99,
"priceCurrency": "EUR",
"priceOriginal": 13.50,
"features": ["Instant activation", "4G/LTE"],
"buyUrl": "https://esimagent.vdigital.app/r/yesim-es-10240-10?s=api",
"affiliateUrl": "https://yesim.app/...?partner_id=3116",
"isBestValue": true,
"matchScore": 1,
"isExactDurationMatch": true,
"isExactDataMatch": true,
"valueScore": 683.12,
"activePromoCode": "SAVE10",
"discountApplied": { "type": "percentage", "value": 10 },
"finalPriceUSD": 13.49
}
buyUrl is a short click-tracked redirect on esimagent.vdigital.app/r/... that resolves to the same partner destination as affiliateUrl — i.e. the specific plan page on the partner site, not the partner home. The plan ID is encoded in the path (with ?s= marking the click source); the affiliate URL is looked up server-side from the cached plan catalog at click time. Use it as the default link. affiliateUrl is provided for transparency — surface it only when the user asks for the raw partner URL.
capacityMB: -1 means unlimited. Otherwise multiply by 1024 for GB.
matchScore ∈ [0, 1]: overall fit to the supplied filters. null when no filters are passed.isExactDurationMatch / isExactDataMatch: true when the plan sits inside the requested band. null when the corresponding filter is not passed.valueScore: always populated — higher is better. Used as the tiebreaker and the primary sort when no filters are passed.finalPriceUSD: always populated — equals priceUSD when no deal applies, otherwise the post-deal price (rounded to 2 decimals).activePromoCode / discountApplied: populated when a deal was fused in. activePromoCode may still be null even when a deal applies (some deals have no code).Returns Deal[] with promoCode, discountType (percentage|flat), discountValue, buyUrl (use this), affiliateUrl, expiresAt.
Returns Provider[] with rating, features, buyUrl (use this), affiliateUrl.
The /plans endpoint already filters, deal-fuses, and ranks for you when you pass the right query params. Your job is to translate user intent into the right bands.
| User says | Server params | Kind |
|---|---|---|
| "2 weeks", "14 days" | minDays=14&maxDays=15 | tight → fires isExactDurationMatch |
| "1 week", "7 days" | minDays=7&maxDays=8 | tight → fires isExactDurationMatch |
| "10 days" | minDays=10&maxDays=11 | tight → fires isExactDurationMatch |
| "this month" | minDays=14&maxDays=31 | range — isExactDurationMatch stays false but results are still ranked by matchScore |
| "month-long" | minDays=28&maxDays=31 | range (width 3) — exact flag will not fire, matchScore still ranks correctly |
| "5 GB" | minGb=5&maxGb=6 | tight → fires isExactDataMatch |
| "10 GB" | minGb=10&maxGb=11 | tight → fires isExactDataMatch |
| "around 10 GB" | minGb=8&maxGb=12 | range (width 4) — exact flag will not fire, matches still ranked |
| "unlimited" | Omit minGb/maxGb — data filters exclude unlimited plans. Look for capacityMB === -1 in the response. | — |
| "cheap", "budget" | No data or duration filter — trust valueScore ordering | — |
| "no limit" | Omit data filters. Unlimited will appear in the unfiltered list. | — |
Tight band rule:
isExactDurationMatchandisExactDataMatchfire only when BOTH bounds are set AND the band is narrow (duration:maxDays − minDays ≤ 2; data:maxGb − minGb ≤ 2). Single-sided bounds (minDaysalone ormaxDaysalone) NEVER count as exact. This prevents loose range queries from being falsely labelled[EXACT MATCH].
The response is pre-sorted:
matchScore descending (best fit first) when filters are present.valueScore descending (best value first) when filters are absent.isBestValue === true is set on the top plan.Look for [EXACT MATCH] signals (isExactDurationMatch === true && isExactDataMatch === true) to highlight the tightest fits.
For each plan show: provider name, data (capacityLabel), duration (periodDays), price (priceUSD), the post-deal price when different (finalPriceUSD), any active promo code (activePromoCode), and a buy link.
Always use the buyUrl field as the default buy link. It is a short click-tracked redirect on esimagent.vdigital.app/r/... that resolves to the partner URL with the correct referral parameter. The short path keeps responses clean for AI agents; click attribution is recorded server-side. Using buyUrl keeps click analytics flowing to eSIM Agent so the service can stay free; using the raw affiliateUrl still pays the referral but skips the anonymous analytics record.
If the user asks for the raw partner URL, the direct link, or a URL without the redirect, surface affiliateUrl and explain clearly: the ?partner_id=... / referral parameter in that URL is how eSIM Agent funds the comparison service. No personal data is shared via either link.
Deal information is already fused into each plan via finalPriceUSD, activePromoCode, and discountApplied. Call /deals only when the user wants the full deals list (not tied to specific plans).
The API uses ISO 3166-1 alpha-2 codes (JP, US, ES, TH). Convert country names if needed:
JP, "Spain" → ES, "Thailand" → TH, "United States" → USFor Europe, pick a major country (ES, FR, DE, IT) or call the API for several.
Direct users to https://esimagent.vdigital.app/checker for the interactive checker (covers Apple, Samsung, Google, Xiaomi, Huawei, OnePlus, OPPO, Motorola).
Quick rule: iPhone XS and newer (2018+), Samsung Galaxy S20 and newer, Pixel 3 and newer all support eSIM. Budget devices like Galaxy A-series often do NOT.
If the user asks "how do I install this for myself", the fastest path is remote HTTP — no install, no Node.js, just a URL:
{
"mcpServers": {
"esim-agent": {
"url": "https://esimagent.vdigital.app/api/mcp/mcp"
}
}
}
Nothing to install. Works with any MCP client that supports HTTP transport (Claude Desktop, Claude Code, Cursor, Windsurf, and most modern clients).
{
"mcpServers": {
"esim-agent": {
"command": "npx",
"args": ["-y", "esimagent-mcp"]
}
}
}
Requires Node.js 18+.
Auto-discovery endpoint: https://esimagent.vdigital.app/.well-known/mcp.json
If MCP tools aren't in your current session:
User: "Find me an eSIM for 10 days in Spain, around 10 GB"
You should:
GET /api/plans?country=ES&minDays=10&maxDays=11&minGb=10&maxGb=11 — tight bands on both axes so exact-match flags can fire.isExactDurationMatch AND isExactDataMatch are both true, present it as an "exact match"; otherwise present the top result as the best fit.finalPriceUSD/activePromoCode when present./deals — deal info is already fused.User: "Any cheap eSIMs for Thailand this month?"
You should:
GET /api/plans?country=TH&minDays=14&maxDays=31 — this is a range query. Exact-match flags will stay false but matchScore still ranks in-range plans first and valueScore breaks ties.valueScore handles the "cheap" intent.finalPriceUSD and any activePromoCode. Do NOT label these as [EXACT MATCH].User: "Unlimited eSIM for a week in Japan"
You should:
GET /api/plans?country=JP&minDays=7&maxDays=8 (note: NO data filters — data filters exclude unlimited; tight duration band so an exact duration match can still fire).capacityMB === -1 if you want only unlimited, or highlight the cheapest unlimited alongside the best finite match.User: "What's the cheapest eSIM for Mexico?"
You should:
GET /api/plans?country=MX (no filters).valueScore — the first one is already the best value.matchScore and valueScore are authoritativeisExactDurationMatch and isExactDataMatch fire ONLY when the filter band is tight (≤ 2 days or ≤ 2 GB) AND both bounds are set. A loose query like "this month" (minDays=14&maxDays=31) will rank correctly by matchScore but the exact-match flags will stay false — that's correct, don't slap [EXACT MATCH] on in-range plans just because they're in range.minGb/maxGb if the user wants unlimited — it will filter unlimited plans outproviderId/countryCode in user-facing output — use providerName/countryaffiliateUrl, or provider websites if the user explicitly asks for themaffiliateUrl instead of buyUrl by default — buyUrl is the tracked redirect that funds the service; affiliateUrl is for transparency when asked