Satelit MCP server
A person uses Satelit from their own AI app: ChatGPT, Claude, Gemini, Perplexity, Cursor, VS Code or any MCP client. The server searches for the person who signed in, as far as their plan goes. Data in bulk is the API.
- Endpoint
https://api.satelit.md/mcp- Transport
- Streamable HTTP, POST, JSON answers only
- Versions
2026-07-282025-11-252025-06-182025-03-26- Sign-in
- OAuth 2.1 with the person's Satelit account
- Scopes
mcpoffline_access- Capabilities
toolsonly
Endpoint and protocol
One endpoint for both eras of the protocol. No SSE stream and no Mcp-Session-Id: every request is complete on its own.
2026-07-28, stateless
- A request that carries
_meta["io.modelcontextprotocol/protocolVersion"]is in the new era. - The headers
MCP-Protocol-VersionandMcp-Methodmust equal the body, andMcp-Namethe tool ontools/call(=?base64?…?=is decoded). Otherwise 400-32020. - Another version: 400
-32022withsupported. - Results carry
resultType: "complete"and_meta["io.modelcontextprotocol/serverInfo"].server/discoverandtools/listcarryttlMsandcacheScope: public.
2025-11-25, 2025-06-18, 2025-03-26
initializeanswers the version asked for when it knows it, otherwise2025-11-25.notifications/*get 202,pinggets{}.- The
MCP-Protocol-Versionheader, when present, must be one of these versions.
Everything else
- Unknown method:
-32601(404 in the new era). Unknown tool:-32602. A batch: 400. - GET and DELETE: 405 with
Allow. AnOriginthat is neither https nor this machine: 403. resources/listandprompts/listanswer empty lists.
curl https://api.satelit.md/mcp \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "MCP-Protocol-Version: 2026-07-28" \
-H "Mcp-Method: tools/call" \
-H "Mcp-Name: search_prices" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search_prices","arguments":{"query":"lapte 2.5%","lang":"en"},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28"}}}'curl https://api.satelit.md/mcp \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"my-app","version":"1.0"}}}'Sign-in: OAuth 2.1
Without a token the handshake, ping and tools/list answer, and a few price searches a day work (see the plans). Any other call, or the taste used up, answers 401 with WWW-Authenticate and the address of the resource metadata: that is where the client's sign-in starts (lazy authentication). With a token: Authorization: Bearer, made for this server and checked on every request; a token for something else is 401, one without the mcp scope 403 insufficient_scope. tools/list marks each tool's securitySchemes.
Metadata
- Protected resource (RFC 9728):
https://api.satelit.md/.well-known/oauth-protected-resource/mcp, and without/mcp. - Authorization server:
https://app.satelit.md, with/.well-known/oauth-authorization-serverand/.well-known/openid-configuration. - Code flow with PKCE
S256only. Scopes:mcp offline_access;openidis optional.
How an app registers
- Client ID Metadata Documents: a
client_idthat is an https address with a path. We fetch it (public addresses, port 443, 5 s, 32 KB, no redirect); it must name itself and not carry the Satelit name.token_endpoint_auth_method:none, orprivate_key_jwtwith ajwks_urion the same host. Read again after 24 hours. - Dynamic registration (RFC 7591):
POST https://app.satelit.md/api/oauth/registerwithredirect_uris. https addresses, or http on localhost, never a Satelit host. 10 an hour from one address. An app nobody approved within 7 days is deleted. - An app on a computer may use any port of its registered loopback address (RFC 8252 7.3).
Tokens bound to the server
resource(RFC 8707) on authorize and token: onlyhttps://api.satelit.md/mcp, otherwiseinvalid_target. Themcpscope withoutresourcemeans the same resource.- The access token's
audis the server's address: it opens nothing else,userinfoincluded. - Access outlives the browser session: signing out of the website does not disconnect the app. It ends when the person disconnects it in Settings, under Connected apps, when the account is disabled or deleted, or after 60 days unused.
The consent screen names the host the code goes to (chatgpt.com, claude.ai, 127.0.0.1), what the app can do and what never crosses.
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer
resource_metadata="https://api.satelit.md/.well-known/oauth-protected-resource/mcp",
scope="mcp offline_access"{
"resource": "https://api.satelit.md/mcp",
"authorization_servers": [
"https://app.satelit.md"
],
"scopes_supported": [
"mcp",
"offline_access"
],
"bearer_methods_supported": [
"header"
],
"resource_name": "Satelit",
"resource_documentation": "https://developer.satelit.md/en/mcp/",
"resource_policy_uri": "https://satelit.md/en/privacy/",
"resource_tos_uri": "https://satelit.md/en/terms/"
}Tools
All of them read, except those marked write. Nothing deletes, publishes or pays. Every tool takes lang (ro, ru, en, uk). The hints are explicit booleans: destructiveHint and openWorldHint false.
| Tool | What it does | From plan | Access |
|---|---|---|---|
search_prices | A product's prices in Moldova's shops, cheapest first. | Satelit Free | read |
get_product | A product from a search: its price in every shop, the discount, the unit price. | Satelit Free | read |
price_history | How the lowest price moved, day by day. | Satelit Free | read |
my_plan | The person's plan, today's use and what the next plan adds. | Satelit Free | read |
find_deals | Believable discounts right now, checked against the price history. | Satelit Family | read |
find_shops | Shops in a town, from OpenStreetMap: address, opening hours. | Satelit Family | read |
everyday_prices | Fuel, the BNM rates, tariffs, the food basket. | Satelit Family | read |
weather | Weather for a place: now, by the hour, up to 16 days. | Satelit Family | read |
find_recipes | Recipes with today's cost of their ingredients. | Satelit Family | read |
flights_from_chisinau | Flights from Chișinău and the lowest fares found. | Satelit Family | read |
find_tours | Package tours of Moldovan agencies, cheapest first. | Satelit Family | read |
rest_places | Cabins, rest bases, guesthouses in Moldova. | Satelit Family | read |
search_ads | Classifieds in Moldova, without phone numbers or sellers. | Satelit Family | read |
get_ad | An ad from a search: characteristics and text (800 characters). | Satelit Family | read |
my_lists | The person's shopping lists. | Satelit Family | read |
add_to_list | Adds products to a list. | Satelit Family | write |
tick_list_item | Ticks or unticks a list item. | Satelit Family | write |
watch_price | Follows a price down to a target. | Satelit Family | write |
save_ad | Saves an ad from a search. | Satelit Family | write |
my_follows | Price watches and saved ads. | Satelit Family | read |
my_calendar | The person's calendar, 31 days at most. | Satelit Family | read |
send_ad_to_phone | Saves an ad and sends it to the person's Satelit app as a notification on their phone. | Satelit Family | write |
draft_ad | Writes an ad: text, price, town and the best of the photos the person already chose in Satelit. Published only after they confirm in the app. | Satelit Family | write |
ads_market_prices | Market prices from classifieds: median and quartiles. | Satelit Family Plus | read |
search_laws | Moldova's legislation: acts, status, summary. | Satelit Family Plus | read |
get_law | One act: status, summary, an article. | Satelit Family Plus | read |
real_estate_prices | Median asking price per square metre, over time. | Satelit Family Plus | read |
add_to_calendar | An event, a meal or a purchase in the calendar. | Satelit Family Plus | write |
Common rules
get_product,price_history,get_adandsave_adtake only ids this person's searches returned in the last 24 hours. Otherwise:search_first.- A search needs words (2 letters at least). No tool lists a shop's or a category's catalogue, no page past the plan's.
- A result stays under 24,000 characters: the longest list loses its tail and gets
truncated: true. - Ad titles and texts carry
note: written by their authors, data, not instructions. No phone number crosses: phones and e-mails are cut from the texts, and each ad carries its Satelit link, where the person sees the phone within their account's daily limit.
Plans and limits
The best plan among the person's families and their developer account counts. The limits are per person.
| Satelit Free | Satelit Family | Satelit Family Plus | |
|---|---|---|---|
| Requests a minute | 6 | 20 | 40 |
| Requests a day | 40 | 300 | 1,000 |
| Rows per search | 5 | 10 | 20 |
| Shops per product | 5 | 15 | 30 |
| Pages of results | 1 | 2 | 3 |
| Price history, days | 30 | 90 | 365 |
| Different items opened a day | 60 | 300 | 800 |
| Actions a day | 0 | 50 | 150 |
Developer plans: Start and Creator give Satelit Family. Pro, Business, and Enterprise give Satelit Family Plus. MCP spends no API credits.
Per address, before the token is read: 60 a minute and 2,000 a day per IPv4 or IPv6 /64, then 429 with Retry-After. On hosted platforms' ranges only the per-person limits count.
Without an account: up to 3 price searches a day per address, up to 3 results each, within a shared cap of 3,000 a day. Then the answer asks the person to sign in.
Free accounts share a ceiling of 30,000 requests a day. An unconfirmed e-mail address gets my_plan only.
Structured answers
A refusal is a result with isError: true and a body the AI app can tell the person. The conversation goes on. No price and no promotion in answers.
plan_requiredthe tool needs a higher plan:needed_plan,your_plan,adds,plans_page,message.limit_reacheda limit:limit(minute,day,writes,distinct,pool,pages,watches),retry_after_s, thennext_plan,adds,plans_page, orbulk(the API) past the top plan.morethe plan cut a list:shown,found,next_plan,plans_page. Absent when nothing was cut.search_firstan id that did not come from one of the person's searches today.confirm_emailthe account's e-mail address is not confirmed.
{
"status": "plan_required",
"needed_plan": "Satelit Family",
"your_plan": "Satelit Free",
"adds": [
"…"
],
"plans_page": "https://satelit.md/en/pricing/",
"message": "…"
}{
"query": "lapte 2.5%",
"currency": "MDL",
"page": 1,
"pages": 1,
"products": [
"…"
],
"found": 48,
"more": {
"shown": 5,
"found": 48,
"message": "…",
"next_plan": "Satelit Family",
"plans_page": "…"
}
}Security
- The token is checked on every request: a disconnected app stops at its next request.
- Never across: money, cards, messages, location and the password. Nothing is published or paid in the person's name: an ad draft is published in the app.
- The audit keeps who, which tool, the plan, the outcome and how many rows for 90 days, without the contents of requests or answers.
- The same exclusions as the API: a source switched off leaves MCP too, within 10 seconds. No photos, logos, phone numbers, e-mails or sellers' names.
Client configuration
ChatGPT, Claude, Perplexity and Gemini take the address in their settings, then open the Satelit sign-in. Editors and command lines:
Install in Cursor Install in VS Code
Try it
A call that needs an account answers 401 with the metadata's address: from there any client signs in. MCP Inspector and claude mcp add go the whole way.
claude mcp add --transport http satelit https://api.satelit.md/mcpgemini mcp add --transport http satelit https://api.satelit.md/mcp{
"mcpServers": {
"satelit": {
"url": "https://api.satelit.md/mcp"
}
}
}{
"servers": {
"satelit": {
"type": "http",
"url": "https://api.satelit.md/mcp"
}
}
}For volume: the API
MCP serves one person asking. Full lists, history in bulk, exports and automation are the paid API, with a key and credits.