simscout
simscout is a small local bridge to esimoa's hosted MCP
server, which catalogues travel eSIM plans: pick a
destination, say how long the trip is and how much data
you need, and the catalog answers with matching plans,
their prices in KRW, and a link to each plan's page on
esimoa.com where a purchase would happen.
The bridge keeps no catalog of its own. It serves the
upstream server's tool list locally, exactly as captured
from the live endpoint, and forwards each tool call
upstream, returning the result untouched. The whole
captured surface only reads — searching, fetching one
plan, comparing a shortlist and listing destinations —
and there is no checkout or payment tool in it.
Tools
search_esims — search the catalog for a destination.
All filters are optional: country (ISO code or name
in any language, e.g. JP or Japan), days (trip
length), data_gb / max_data_gb, unlimited,
countries (multi-country trips, up to 8), data_type
(daily or total), local_number, network
(local or roaming), multi_country, min_price_krw
/ max_price_krw, provider, hotspot, five_g,
sort (recommended, price, data, price_per_gb
or validity), limit (1-10, default 5) and lang.
Each result carries an id and a plan page url.
get_esim — the full details of one plan. Required:
id (from search_esims). Optional: lang.
compare_esims — two to five plans side by side:
price, data, validity, price per GB, coverage, network,
hotspot and local phone number, plus which plan wins
each of lowest price, most data, longest validity and
lowest price per GB. Required: ids. Optional: lang.
list_countries — every destination where plans are
sold, with the plan count and the lowest price per
country. Optional: query (name or ISO filter) and
lang.
search — free-text search in the search/fetch format
used by ChatGPT deep research, e.g. "Japan 7 days
unlimited". Required: query. Returns ids for fetch.
When you can fill filters, prefer search_esims.
fetch — one plan as a document, by an id returned
from search. Required: id. For plans found with
search_esims, use get_esim instead.
Configuration
ESIMOA_MCP_URL (optional) — override the upstream
endpoint. Defaults to https://api.esimoa.com/mcp.
(The override hook is this rebuild's own labelled
reconstruction.)
ESIMOA_API_KEY (optional) — when set, every
upstream request carries an X-API-Key: <key> header
(a partner key adds the partner's affiliate code to
buy links). When it is not set, no key header is sent
and the upstream returns plain links. No
Authorization header is ever sent. (This forwarding
is also a labelled reconstruction; the original
surface was captured keyless.)
Forwarding mechanics
On the first tool call the client opens a streamable
HTTP session with the upstream: a JSON-RPC initialize
request (protocolVersion 2025-03-26, clientInfo name
simscout), then a notifications/initialized
notification, then the tools/call request carrying
the caller's arguments unchanged. When the upstream
answers initialize with an Mcp-Session-Id header,
that value rides on every later request of the session,
which is reused for the life of the process. Replies
may arrive as plain JSON or as server-sent events;
both are read.
Successful upstream results pass through verbatim,
including any isError flag the upstream sets.
Failures — a JSON-RPC error, a non-2xx status, an
unreadable response, or a request that cannot be
completed — come back as an isError result whose
text starts with simscout error: (this rendering
is this rebuild's own labelled reconstruction).
CLI
Each tool is also a subcommand taking one JSON argument
string (omit it for tools that take none):
Exit codes: 0 on success, 1 on an isError
result, 2 on a usage error.
MCP server
MCP client config:
Docker
The container's default command is mcp, so the first
form is a stdio MCP server; any other arguments reach
the CLI normally.
Development
The test suite runs entirely against a stubbed
JSON-RPC upstream — no live network calls.
License
MIT — see LICENSE.