bhoonidhi-mcp
An MCP server that lets an AI agent search,save, download, and cart satellite scenes from ISRO's Bhoonidhi Browse & Order portal(NRSC) in natural language. An agent can turn a sentence like "Sentinel-2 overShillong last January" into a real search against the live portal, see honestlywhat is available to download, save a search to reuse later, preview what adownload would fetch, and — once logged in — download open-access scenes orstage them to the cart.
It is a thin adapter over thebhoonidhi-downloaderSDK — the same client the bhd CLI uses — so no portal logic is duplicated.
Status
Search and save with no login; download and cart with one. The tools reachthe full archive of 41 satellite missions and 79 sensors, search the liveportal, and save searches to reusable slugs — all without credentials.Downloading open-access scenes and staging scenes to the Bhoonidhi cart need alogin, done out of band with bhd auth login (the server reuses that session).
Tools
| Tool | What it does | Login |
|---|---|---|
list_archive |
The vocabulary of satellites, sensors, and search tokens the portal supports, live from Bhoonidhi. | no |
resolve_location |
Turns a place name ("Loktak Lake") into a centroid and bounding box. Rejects inputs that are not place names. | no |
search_scenes |
Natural-language scene search over an area and date range. Resolves a casual satellite name to exact tokens, and reports each scene's availability (Ready / Archived / OnOrder / Priced). Stateless — nothing is saved. | no |
preview_download |
A dry run: shows what downloading the results would fetch, and what would be skipped, before anything is downloaded. | no |
save_query |
Persists a search (same arguments as search_scenes) to a reusable slug, so it can be downloaded or staged to the cart later. |
no |
list_queries |
Lists saved queries as compact summaries: slug, name, date range, satellites, area, and availability. | no |
show_query |
Returns one saved query by slug, with its scenes. | no |
remove_query |
Deletes a saved query by slug. | no |
auth_status |
Reports whether a login is configured. Never handles a password or token. | no |
download_query |
Downloads a saved query's open-access scenes in the background, to a fixed server-configured root. Returns a job_id at once. |
yes |
download_status |
One-off check of a background download by job_id: bytes downloaded, transfer rate, percent when the size is known, and per-scene detail. |
no |
download_wait |
Blocks until a download finishes (or a capped timeout), then reports — the efficient primitive a background watcher loops on. | no |
cart_add |
Stages a saved query's scenes to the cart (routes each to ready / on-order / priced). | yes |
cart_list |
Lists scenes currently staged in the cart. | yes |
cart_remove |
Removes scenes from the cart. | yes |
Availability matters: an OpenData scene is not necessarily staged fordownload. search_scenes and preview_download distinguish Ready (fetch itnow) from Archived (open data, but may need a request on the portal first),so an agent does not over-promise.
Downloads run in the background, independent of the conversation:download_query returns a job_id at once and the transfer proceeds on its own.Check progress once with download_status — it reports bytes downloaded, atransfer rate, and a percent once the size is known — or follow a job tocompletion with download_wait, which blocks until it finishes (or a cappedtimeout) so an agent can delegate a background watcher and keep the conversationfree instead of sleep-looping. A job lives only as long as the server process,so once a download proves large the status recommends running a standalone bhd query download <slug> command you own instead.
Install
The server is a Python package with a console entry point, bhoonidhi-mcp.Install it from source with uv:
git clone https://github.com/geovicco-dev/bhoonidhi-mcp
cd bhoonidhi-mcp
uv sync
This exposes the bhoonidhi-mcp command at .venv/bin/bhoonidhi-mcp. The serverspeaks stdio and is launched by an MCP client — you point the client at thatcommand.
Connecting a client
Every MCP client needs the same thing: the command to launch. Use the absolutepath to the entry point (most reliable across GUI and CLI clients):
/path/to/bhoonidhi-mcp/.venv/bin/bhoonidhi-mcp
Claude Desktop / Claude Code
claude_desktop_config.json (or claude mcp add):
{
"mcpServers": {
"bhoonidhi": {
"command": "/path/to/bhoonidhi-mcp/.venv/bin/bhoonidhi-mcp",
"args": []
}
}
}
OpenCode
~/.config/opencode/opencode.json:
{
"mcp": {
"bhoonidhi": {
"type": "local",
"command": ["/path/to/bhoonidhi-mcp/.venv/bin/bhoonidhi-mcp"],
"enabled": true
}
}
}
MCP Inspector (to try it without an agent)
npx @modelcontextprotocol/inspector /path/to/bhoonidhi-mcp/.venv/bin/bhoonidhi-mcp
Example
Ask an agent, in plain language:
"What Sentinel-2 scenes are over Shillong in January 2024, and how many can Iactually download?"
The agent calls resolve_location for Shillong, then search_scenes, andanswers from the result — for example, that all scenes are Archived (opendata, but each may need a request on the portal before it will download), ratherthan claiming they are all ready.
Prompts to try
Copy these into any connected agent to get a feel for what it can do.
Discover the archive
- "What satellites and sensors does Bhoonidhi have?"
- "Which sensors does ResourceSat-2A carry, and at what resolution?"
- "Does Bhoonidhi have any radar satellites?"
Search for scenes
- "Find Sentinel-2 scenes over Shillong in January 2024."
- "Show me Cartosat imagery within 20 km of Bengaluru in the first half of 2024."
- "Any Sentinel-1 scenes over the Sundarbans in March 2024?"
- "What Landsat-8 imagery covers Kaziranga National Park last winter?"
- "Find MODIS scenes over the Rann of Kutch in December 2023."
Check what's available to download
- "Of those Sentinel-2 scenes, how many can I actually download right now?"
- "Which of these need to be ordered or paid for?"
Preview a download
- "Preview what downloading those scenes would fetch."
Save a search to reuse
- "Save that Sentinel-2 search so I can download it later."
- "List my saved searches."
- "Show me what's in the search I saved as ."
- "Delete the saved search ."
Download and cart (need a login — see below)
- "Am I logged in to Bhoonidhi?"
- "Download the open-data scenes from my saved search ."
- "How's that download going?"
- "Download and let me know when it's done — I'll keep working."
- "Add the priced scenes from to my cart."
- "What's in my cart this week?"
Login (for downloads and cart)
Search, saved queries, and previews need no credentials. Downloading scenes andstaging them to the cart do. Log in once, out of band — the server reuses thesame session the bhd CLI writes:
bhd auth login
The MCP server never takes a username or password as a tool argument, andauth_status never returns your token. For a headless setup with no interactivelogin, you can instead set BHOONIDHI_USERNAME / BHOONIDHI_PASSWORD in theserver's environment; the server reads them only to establish a session.
Configuration
Set as environment variables (all optional):
| Variable | Default | Purpose |
|---|---|---|
BHOONIDHI_MCP_GEOCODER_USER_AGENT |
bhoonidhi-mcp/0.1 |
User-Agent sent to Nominatim (its usage policy asks for a descriptive one). |
BHOONIDHI_MCP_FUZZY_THRESHOLD |
88 |
Score (0–100) a satellite-name match must clear to be confident; below it, candidates are returned for the agent to confirm. |
BHOONIDHI_MCP_MAX_RESULTS |
50 |
Maximum scenes returned inline by search_scenes. |
BHOONIDHI_MCP_DOWNLOAD_ROOT |
~/Downloads |
Allow-listed root every download writes under, as <root>/<slug>/. The agent cannot choose an arbitrary path. |
BHOONIDHI_MCP_DOWNLOAD_PARALLEL |
4 |
Parallel download workers. |
BHOONIDHI_MCP_LARGE_DOWNLOAD_MB |
500 |
Once a download's live byte total (or known size) passes this, the status flags it large and steers the agent to hand off or run a standalone command. |
BHOONIDHI_USERNAME / BHOONIDHI_PASSWORD |
(unset) | Optional headless login. Prefer bhd auth login; fill these out of band, never commit them. |
Development
uv sync
uv run pytest # test suite
uv run ruff check . # lint
License
MIT — see LICENSE.