India Hotels MCP
Supplies bundled OpenStreetMap data for hotel/guest house/hostel locations, railway stations with codes, and bus stations, enabling place resolution and unpriced listings.
Provides geocoding through the public Photon instance to resolve place names or codes to coordinates, with caching.
Provides live hotel prices in INR via trivago's official MCP, merging cheapest advertiser offers per hotel across Booking.com, Agoda, MakeMyTrip, and others.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@India Hotels MCPfind hotels near New Delhi railway station for 2 adults, Dec 12-14"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
India Hotels MCP
Contributing · Disclaimer · Security · Changelog
An MCP server for finding, comparing and planning hotel stays across India around the places a trip actually revolves around: railway stations, airports, bus terminals, landmarks, localities and raw coordinates. It merges live prices from free meta-search sources, and adds road distance and drive time to arrival and departure points plus multi-stop stay planning.
It is standalone. Other servers (for example a train-timetable server) work with it through plain values
Claude passes between them: lat/lng, Indian Railways station codes, IATA airport codes and ISO-8601
datetimes.
Tools
Tool | What it does |
| Name or code → coordinates (stations, airports, bus stations, landmarks, localities); or coordinates → nearest stations, airports and bus stations |
| Hotels around a place for given dates, merged across sources, cheapest live price in INR for one room ( |
| One hotel's current prices per booking site (Booking.com, Agoda, Trip.com, MakeMyTrip, …), cheapest first, in INR, with tax status and links |
| Up to 10 hotels × up to 6 labelled places: drive or walk times, totals, ranking |
| Origin × destination matrix of road km, free-flow and traffic-adjusted minutes |
| Per-stop stay planning from arrival/departure times: dates, candidates ranked by price + transfer time, leave-by times, warnings, retiring rooms |
| IRCTC railway retiring rooms at or near a station, with booking rules and portal link |
| Status, limitations and quotas of every source; bundled dataset dates and licences |
All tools are read-only; nothing books, pays or cancels.
Related MCP server: DIDA Hotel MCP
Data sources
Need | Source | Notes |
Live prices | Free, no key. Cheapest advertiser per hotel (Booking.com, Agoda, MakeMyTrip, …) in INR | |
Live prices + availability | Free, no key, true radius search. EUR, converted to INR | |
Live prices (optional) | Needs | |
Live prices (unofficial) | Xotelo (derived from TripAdvisor meta-search) | Off by default; enabled only with |
FX | Frankfurter (ECB rates) | Daily reference rates |
Hotel locations | OpenStreetMap snapshot (bundled) | ~24k hotels/guest houses/hostels; no prices ( |
Stations, bus stations | OpenStreetMap snapshot (bundled) | ~9.2k stations with codes, ~5.3k bus stations |
Airports | OurAirports (bundled) | 151 Indian airports |
Retiring rooms | IRCTC public station list (bundled, refreshed by hand) | 356 stations; live availability needs a PNR on the IRCTC portal |
Geocoding | Public instances, cached; Nominatim limited to 1 req/s | |
Routing | FOSSGIS public instance by default, ~1 req/s, cached; self-hostable |
Third-party prices are meta-search prices: they can differ at checkout and may exclude GST
(includes_taxes: null means unknown). Every price carries its source, seller and fetched_at.
OSM routing has no traffic data, so drive times are multiplied by METRO_TRAFFIC_MULTIPLIER (default 1.5)
in the 8 largest metros and OTHER_TRAFFIC_MULTIPLIER (1.2) elsewhere; both raw and adjusted minutes are returned.
None of the free live-price sources has an SLA. Any source can be switched off with PROVIDERS_DISABLED,
and a failing source never fails a search: results come back from the others with sources_failed filled in.
Unofficial sources (currently Xotelo) run only when ENABLE_UNOFFICIAL_SOURCES=true; check the terms that apply
to you first (see DISCLAIMER.md).
Setup
Requires Node 22+.
npm install
npm run build
cp .env.example .env # set HTTP_USER_AGENT to your app name + contact (Nominatim policy)Claude Code
claude mcp add --transport stdio --env HTTP_USER_AGENT="india-hotels-mcp/0.1 (you@example.com)" india-hotels -- node /path/to/hotels-mcp/dist/src/server.jsClaude Desktop
{
"mcpServers": {
"india-hotels": {
"command": "node",
"args": ["/path/to/hotels-mcp/dist/src/server.js"],
"env": { "HTTP_USER_AGENT": "india-hotels-mcp/0.1 (you@example.com)" }
}
}
}HTTP (Docker)
docker compose up -d hotels-mcp # Streamable HTTP at http://localhost:3000/mcp, health at /healthAdd it to Claude as a custom connector with that URL (through a tunnel for claude.ai). The HTTP server has
no authentication; keep it on localhost or a private network. Outside Docker it binds 127.0.0.1 by default
(HOST); the Docker image sets HOST=0.0.0.0 and compose publishes it only on 127.0.0.1:3000. DNS-rebinding
protection rejects requests whose Host hostname is not in ALLOWED_HOSTS (default: localhost, 127.0.0.1,
[::1], any port); add your tunnel's hostname there if you use one.
Self-hosted routing (optional)
The public OSRM instance is for light use. To self-host:
scripts/osrm-setup.sh northern-zone # or "india": ~1.7 GB download, ~25 GB disk, 12+ GB Docker RAM
docker compose --profile osrm up -d
# then in .env: OSRM_URL=http://localhost:5001 OSRM_FOOT_URL=http://localhost:5002Configuration
See .env.example. Main settings: HTTP_USER_AGENT, SERPAPI_KEY (optional), ENABLE_UNOFFICIAL_SOURCES
(default false; true enables Xotelo), PROVIDERS_DISABLED, OSRM_URL, OSRM_FOOT_URL,
NOMINATIM_URL, PHOTON_URL, METRO_TRAFFIC_MULTIPLIER, OTHER_TRAFFIC_MULTIPLIER, TRAIN_BUFFER_MIN
(default 30), FLIGHT_BUFFER_MIN (default 120), PROVIDER_DEADLINE_MS (default 20000; each source's time
limit per search), CACHE_DIR.
HTTP mode only: PORT (default 3000), HOST (bind address, default 127.0.0.1; 0.0.0.0 in the Docker
image) and ALLOWED_HOSTS (comma-separated hostnames accepted in the Host header, any port; default
localhost, 127.0.0.1 and [::1]).
Searches are for one room; adults is the number of guests in that room (1–8).
Development
npm run typecheck && npm test && npm run format:check # gate before committing
npm run smoke # live acceptance checks (network, a few minutes)
npm run dev # watch mode, stdioUnit tests use synthetic fixtures only and never touch the network.
Rebuilding the bundled data
Run about once a month:
HTTP_USER_AGENT="india-hotels-mcp/0.1 (you@example.com)" npm run build:data
# add -- --with-irctc to refresh the IRCTC retiring-room list (a single manual request;
# IRCTC's terms forbid automated access, so never schedule it)
# the Xotelo location-key table is rebuilt separately with: npx tsx scripts/build-xotelo-keys.tsLimitations
Coverage of live prices is strong in metros and tourist towns and thin in small towns; use
include_unpricedto see OpenStreetMap-only listings there.Indian OTAs (MakeMyTrip, Goibibo) appear only when trivago lists them as the cheapest advertiser.
No public-transport routing; no live traffic.
IRCTC retiring-room availability and exact prices are not available without a PNR.
The SerpApi monthly quota counter is kept in memory and resets when the server restarts, and SerpApi's 50 searches/hour limit is not enforced locally.
Contributing
Bug reports, data corrections and new sources are welcome. Read CONTRIBUTING.md for the ground rules and checks, and the Code of Conduct. Report security issues privately as described in SECURITY.md.
Disclaimer
This is an independent project, not affiliated with trivago, HotelsCasa, TripAdvisor, Xotelo, Booking.com, Agoda, MakeMyTrip, IRCTC, Indian Railways, Google, SerpApi, OpenStreetMap or any other source. Prices are meta-search prices that may exclude GST; check with the seller before booking. Nothing is booked. See DISCLAIMER.md.
Licences
Code: Apache-2.0 (LICENSE). Bundled OpenStreetMap-derived data: ODbL 1.0, © OpenStreetMap contributors
(data/LICENSE, data/NOTICE). Tool responses that use OSM data carry the attribution. Other bundled and
run-time data sources are listed in NOTICE.
Available Tools
8 toolscompare_hotelsCompare hotels by travel timeARead-onlyIdempotent
Compares up to 10 hotels by travel time to a set of labelled places, such as tonight's arrival station, tomorrow's departure airport and attractions. Hotels are hotel_ids from search_hotels (which also supplies their cheapest price) or name + lat/lng. Places are lat+lng, station code, IATA code or place name. Returns, per hotel, the time and distance to every place, total minutes, the cheapest price from the search that found it (with its source, fetch time and dates) and a rank by total minutes. Does not fetch new prices; get_hotel_rates does.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | drive (car/taxi, with traffic allowance) or walk. | drive |
| hotels | Yes | Hotels to compare. | |
| places | Yes | Places to measure from each hotel; set label, e.g. 'arrive NDLS 20:10'. |
Output Schema
| Name | Required | Description |
|---|---|---|
| notes | Yes | |
| hotels | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/openWorld/non-destructive, so safety is covered; the description adds genuinely new behavior: prices are carried over from the originating search with source, fetch time and dates (staleness disclosure), and no fresh pricing call is made. It stops short of describing rate limits or failure behavior when a place name fails to resolve.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences with no filler, front-loaded with purpose before inputs, then outputs, then the pricing caveat. Slight redundancy in restating the return payload ('time and distance to every place, total minutes, ... rank by total minutes') when a full output schema already exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Inputs, output contents, price provenance and the boundary against get_hotel_rates are all covered, and return-shape detail is backed by an output schema. Nothing an agent needs in order to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real semantics beyond the schema: the either/or rule for hotels (hotel_id from search_hotels vs name + lat/lng) and the accepted place identifier forms (lat+lng, station code, IATA, place name). It does not explain the drive/walk traffic allowance beyond what the enum description already says.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Compares up to 10 hotels by travel time to a set of labelled places') and enumerates the input forms, so an agent can distinguish it from search_hotels and travel_times without opening a schema. The scope (max 10 hotels, max 6 places) is explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context for use: hotel_ids come from search_hotels, and it explicitly says 'Does not fetch new prices; get_hotel_rates does,' naming the alternative and the condition that selects it. It does not, however, contrast itself with the travel_times sibling, which could plausibly be confused for the same job.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_retiring_roomsFind IRCTC railway retiring roomsARead-onlyIdempotent
Lists Indian Railways stations that have IRCTC retiring rooms (rooms and dormitories inside the station for ticketed passengers), at a station code or within a radius of a place. Returns station code, name, operator and distance, the booking rules, indicative price ranges and the IRCTC booking portal link. Live availability and exact prices are not available here: they need a Confirmed or RAC PNR on the IRCTC portal.
| Name | Required | Description | Default |
|---|---|---|---|
| lat | No | Latitude (India). Use with lng. | |
| lng | No | Longitude (India). Use with lat. | |
| iata | No | Indian airport IATA code, e.g. DEL. | |
| place | No | Place name, e.g. 'Taj Mahal' or 'Paharganj, Delhi'; resolved to its best match. | |
| radius_km | No | Search radius when not giving a station_code. | |
| station_code | No | Indian Railways station code, e.g. NDLS. |
Output Schema
| Name | Required | Description |
|---|---|---|
| notes | Yes | |
| rules | Yes | |
| stations | Yes | |
| booking_url | Yes | |
| indicative_prices | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/openWorld/non-destructive, so the safety profile is covered. The description adds genuinely useful behavioral context beyond that: the absence of live availability, the requirement of a Confirmed or RAC PNR on the IRCTC portal for booking, and the presence of booking rules and indicative price ranges in the result.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core capability, then the return contents, then the limitation. No filler; every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given six optional parameters and an output schema, the description is largely complete and even pre-empts the availability limitation. It is slightly redundant in enumerating return fields that the output schema already defines, but nothing an agent needs to call the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds meaning beyond the schema by framing the two input modes - 'at a station code' versus 'within a radius of a place' - which helps an agent understand that station_code and the place/lat/lng/iata+radius_km path are alternative lookup strategies, not something the schema states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (lists Indian Railways stations with IRCTC retiring rooms) and clarifies the scope with a parenthetical definition of what a retiring room is. It is clearly distinguishable from sibling tools like search_hotels or get_hotel_rates, which cover commercial lodging rather than station-embedded railway accommodation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context for use (lookup by station code or by place/radius) and explicitly states a when-not: live availability and exact prices are not available here and require a Confirmed or RAC PNR on the IRCTC portal. It does not name a sibling alternative to use instead, but the exclusion is explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_data_sourcesData sources and statusARead-onlyIdempotent
Lists every data source this server uses: hotel price sources, hotel location data, geocoding, routing and bundled datasets. For each it gives whether it is enabled, whether it is official or an unofficial third-party endpoint, recent success/failure, remaining quota and known limitations. Bundled datasets include their build date and licence. Does not fetch any hotel data.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| providers | Yes | |
| snapshots | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description adds real behavioral context beyond that: quota, recent success/failure, official vs unofficial endpoints, known limitations, and licence/build date for bundled datasets, which tells the agent what it can learn about reliability before making other calls.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each doing distinct work: scope, per-source contents, and the exclusion. The scope statement is front-loaded and no sentence is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return formatting need not be explained. The description nonetheless covers the substantive return fields (enabled state, official/unofficial, quota, limitations, licences) and the key behavioral boundary, leaving nothing an agent needs to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so per the rubric the baseline is 4. Nothing in the description misrepresents the parameter surface, and no additional parameter meaning is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (lists) and resource (every data source this server uses), then enumerates the categories covered. The closing clause 'Does not fetch any hotel data' cleanly separates it from siblings like search_hotels and get_hotel_rates, so an agent can route correctly without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The negative constraint ('Does not fetch any hotel data') implicitly tells the agent this is not a data-retrieval tool but a status/diagnostic one, and the enumerated fields hint at diagnostic use. However, it never states when to call this versus the sibling tools, nor any prerequisite or sequencing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_hotel_ratesCompare a hotel's prices across sitesARead-onlyIdempotent
Fetches current prices for one hotel from every source for the given dates and lists them per booking site (e.g. Booking.com, Agoda, Trip.com, MakeMyTrip, the hotel's own site), cheapest first, in INR with the original currency, tax status, availability and links. The hotel is a hotel_id from search_hotels or plan_stays, or a name with lat/lng. Does not book.
| Name | Required | Description | Default |
|---|---|---|---|
| lat | No | Hotel latitude, when not giving hotel_id. | |
| lng | No | Hotel longitude, when not giving hotel_id. | |
| name | No | Hotel name, when not giving hotel_id. | |
| adults | No | Guests in the room; searches are for one room. | |
| check_in | Yes | Check-in date, YYYY-MM-DD (IST). | |
| hotel_id | No | hotel_id (or any of its also_ids) from search_hotels or plan_stays. | |
| check_out | Yes | Check-out date, YYYY-MM-DD. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hotel | Yes | |
| notes | Yes | |
| prices | Yes | |
| check_in | Yes | |
| check_out | Yes | |
| sources_ok | Yes | |
| cheapest_inr | Yes | |
| priciest_inr | Yes | |
| sources_failed | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description adds real behavioral context beyond that: aggregation across all booking sources, cheapest-first ordering, currency conversion to INR with original currency retained, tax status, and the explicit 'Does not book' boundary. It says nothing about rate limits, caching, or failure modes for unavailable dates/rooms.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, zero filler, with the output shape front-loaded before the input guidance and the non-booking boundary last. Every clause carries information an agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description need not explain return values, yet it still outlines them for routing purposes. Combined with full schema coverage, four annotations, and the explicit scope boundary, nothing an agent needs to invoke this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so every parameter including the hotel_id-vs-name+lat/lng alternatives is already documented in the schema. The description restates the identifier options and date scoping but adds no syntax or format detail the schema lacks, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (fetch current prices for one hotel across every source) plus the exact output ordering and fields (cheapest first, INR with original currency, tax status, availability, links). The phrase 'one hotel' and the explicit 'Does not book' cleanly separate it from sibling compare_hotels.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete input routing: use a hotel_id from search_hotels or plan_stays, or a name with lat/lng, and states the tool does not book. It stops short of explicitly contrasting with compare_hotels or plan_stays when a multi-hotel comparison is wanted, so the when-not case is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plan_staysPlan hotel stays for an itineraryARead-onlyIdempotent
Plans where to stay for each stop of a trip in India. Each stay is an arrival (place + time) and the next departure (place + time); places are lat+lng, station code, IATA code or place name, so train and flight times from any source can be passed in. For every stay it works out check-in/check-out dates (early-morning arrivals book the previous night), searches hotels near the arrival point and, if elsewhere, the departure point, and ranks them by nightly price plus drive time from arrival and to departure (valued at value_of_time_inr_per_hour). Returns candidates with leave-by times that include a check-in buffer for trains or flights, IRCTC retiring-room options for 3–48 h stays at stations, and warnings for late arrivals, early departures and same-day stays. Does not book.
| Name | Required | Description | Default |
|---|---|---|---|
| stays | Yes | One entry per stop, in trip order. | |
| adults | No | Guests in the room; searches are for one room. | |
| min_stars | No | ||
| radius_km | No | Hotel search radius around each point. | |
| candidates | No | Hotels to return per stay. | |
| max_price_inr | No | Maximum nightly price in INR. | |
| value_of_time_inr_per_hour | No | How much an hour of transfer time is worth, to trade travel time against price (0 = price only). |
Output Schema
| Name | Required | Description |
|---|---|---|
| notes | Yes | |
| stays | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, non-destructive, open-world behavior, and the description goes well beyond them: check-in/check-out derivation with early-morning arrivals booking the previous night, the ranking formula (price plus drive time weighted by value_of_time_inr_per_hour), leave-by times with a check-in buffer, IRCTC retiring-room fallback for 3-48 h station stays, and warning conditions. That is unusually rich behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and free of filler; the opening sentence answers what it does before the mechanics arrive. The middle sentence is dense with stacked clauses (ranking, buffers, retiring rooms, warnings), but that density reflects genuine tool complexity rather than padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter, nested-array tool with an output schema, the description covers everything an agent needs: input point formats, temporal edge cases, ranking behavior, fallback options and the non-booking boundary. Return values need not be explained since the output schema exists, yet the description still summarizes them helpfully.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 86%, so the baseline is 3, but the description adds real meaning: it explains that arrival/departure points accept lat+lng, station code, IATA code or place name, that early-morning arrivals shift the booked night, and that value_of_time_inr_per_hour trades transfer time against price. min_stars and max_price_inr remain unelaborated, keeping it from a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Plans where to stay for each stop of a trip in India') and frames the scope at the whole-itinerary level, which separates it from single-point siblings like search_hotels and get_hotel_rates. An agent can tell what this tool produces (ranked stay candidates per stop) without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is clear: it is the itinerary-level planner, it accepts times 'from any source', and it explicitly closes the loop with 'Does not book', so an agent knows booking is out of scope. It never names an alternative sibling (search_hotels, find_retiring_rooms, compare_hotels) or states when to prefer them, so it stops short of explicit routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resolve_placeResolve a place in IndiaARead-onlyIdempotent
Turns a name or code into coordinates, or coordinates into nearby transport points. With query: matches railway station codes and names, airport IATA codes and names, bus stations, and landmarks or localities via OpenStreetMap geocoding, returning ranked matches with kind, code and lat/lng. With lat/lng: returns the nearest railway stations (within 10 km), airports with IATA codes (within 60 km) and bus stations (within 5 km), with straight-line distances. Does not search hotels.
| Name | Required | Description | Default |
|---|---|---|---|
| lat | No | Latitude, for nearby transport points. | |
| lng | No | Longitude, for nearby transport points. | |
| kind | No | Only return this kind of place. | |
| limit | No | Maximum matches for a query. | |
| query | No | Name or code, e.g. 'Howrah', 'BLR', 'Hawa Mahal'. |
Output Schema
| Name | Required | Description |
|---|---|---|
| notes | Yes | |
| nearby | Yes | |
| matches | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, openWorld, non-destructive), so the bar is lower. The description adds genuinely useful behavior beyond that: the per-kind search radii (10/60/5 km), straight-line distance semantics, ranked matches, and returned fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences, front-loaded with the dual-mode purpose followed by detail. Nearly every clause earns its place, though the enumerated radii and field lists make it slightly heavy for a single paragraph.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values needn't be explained, yet the description still names returned fields. Combined with explicit mode scoping, radii, and exclusions, an agent has everything needed to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description goes further by explaining the mutually exclusive query-vs-coordinates modes and their distinct semantics, which is meaning beyond the per-field schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise bidirectional verb+resource: name/code to coordinates, or coordinates to nearby transport. It enumerates the exact place kinds (stations, airports, bus stations, landmarks/localities) and explicitly distinguishes itself from siblings with 'Does not search hotels.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly scopes the two operating modes ('With query' vs 'With lat/lng'), which is real when-to-use guidance. It lacks explicit routing to named alternatives beyond the negative 'Does not search hotels', so it stops short of full alternative selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_hotelsSearch hotels near a placeARead-onlyIdempotent
Finds hotels around a place in India for given dates, with live prices from several meta-search sources merged per hotel. The place is one of: lat+lng, an Indian Railways station code, an airport IATA code, or a place name. Returns each hotel's id, coordinates, straight-line distance, stars, guest rating and cheapest current price in INR (with original currency, seller and source). With max_drive_minutes, keeps only hotels within that drive time (OpenStreetMap routing with a traffic allowance) and adds drive_minutes. Results are paginated. Per-seller prices are in get_hotel_rates; times to other places are in compare_hotels. Does not book.
| Name | Required | Description | Default |
|---|---|---|---|
| lat | No | Latitude (India). Use with lng. | |
| lng | No | Longitude (India). Use with lat. | |
| iata | No | Indian airport IATA code, e.g. DEL. | |
| sort | No | Sort order; drive_time needs max_drive_minutes. | distance |
| limit | No | Hotels per page. | |
| place | No | Place name, e.g. 'Taj Mahal' or 'Paharganj, Delhi'; resolved to its best match. | |
| adults | No | Guests in the room; searches are for one room. | |
| offset | No | Number of hotels to skip, for paging. | |
| check_in | Yes | Check-in date, YYYY-MM-DD (IST). | |
| check_out | Yes | Check-out date, YYYY-MM-DD, after check_in. | |
| min_stars | No | Minimum star rating. | |
| radius_km | No | Search radius in km. | |
| station_code | No | Indian Railways station code, e.g. NDLS. | |
| max_price_inr | No | Only hotels with a known nightly price at or below this, in INR. | |
| include_unpriced | No | Also list hotels with no live price (OpenStreetMap listings), for places with thin price coverage. | |
| max_drive_minutes | No | Only hotels within this many minutes' drive of the place (traffic-adjusted). |
Output Schema
| Name | Required | Description |
|---|---|---|
| notes | Yes | |
| query | Yes | |
| total | Yes | |
| anchor | Yes | |
| hotels | Yes | |
| showing | Yes | |
| sources_ok | Yes | |
| sources_failed | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/openWorld/idempotent/non-destructive, so the safety profile is covered. The description adds real behavioral context beyond them: prices are live and merged across meta-search sources, max_drive_minutes applies OSM routing with a traffic allowance and injects drive_minutes, results are paginated, and 'Does not book.'
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded: purpose first, then accepted inputs, then result shape, then the two sibling pointers. The sentence enumerating returned fields largely restates the output schema, which is mild redundancy, but nothing else is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present the description needn't explain returns, and it still covers input forms, pagination, drive-time filtering semantics and the booking boundary. Nothing an agent needs to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description goes further by explaining that the place argument accepts lat+lng, station code, IATA code or a name, and by describing what max_drive_minutes actually does (routing plus traffic allowance, adds drive_minutes). It doesn't clarify include_unpriced or the price-cap interaction beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Finds hotels around a place in India') plus the scope (dates, live merged prices) and explicitly contrasts itself with get_hotel_rates and compare_hotels. An agent can distinguish it from every sibling without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent: per-seller prices belong to get_hotel_rates and times to other places to compare_hotels, and it enumerates the four accepted place-input forms. It stops short of stating when-not to use it (e.g. once a hotel id is known), so it is clear context without full exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
travel_timesTravel times between placesARead-onlyIdempotent
Computes road distance and travel time from each origin to each destination in India (a matrix), by car or on foot. Each place is lat+lng, a railway station code, an airport IATA code or a place name. Returns straight-line km, road km, free-flow minutes and traffic-adjusted minutes per pair, with a warning when a point is far from any road. Does not cover public transport or flights.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | drive (car/taxi, with traffic allowance) or walk. | drive |
| origins | Yes | Starting places. | |
| destinations | Yes | Destination places. |
Output Schema
| Name | Required | Description |
|---|---|---|
| legs | Yes | |
| notes | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and openWorld, so safety is covered. The description adds real operational context beyond them: the geography restriction (India only), the mode-dependent behaviour (traffic allowance for drive), and a warning when a point is far from any road. That warning behaviour is not derivable from the schema or annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core capability, then the input formats, outputs, and scope exclusions. No filler; every clause carries information an agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description need not enumerate return fields, yet it still summarises the four returned metrics and the road-proximity warning. Combined with the India-only scope and mode options, an agent has everything needed to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so each field (mode enum, lat/lng bounds, iata/station_code patterns, place resolution, per-list max items) is fully documented in the schema itself. The description restates the input formats ('lat+lng, a railway station code, an airport IATA code or a place name') but adds no syntax or constraint detail beyond what is already given. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (computes road distance and travel time) plus the scope (matrix from each origin to each destination in India) and mode (by car or on foot). An agent can immediately tell this is an origin-destination routing tool, distinct from the hotel-focused siblings and from resolve_place, which only geocodes single points.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description supplies a when-not clause ('Does not cover public transport or flights'), which usefully prevents misuse, but gives no explicit when-to-use trigger and does not name an alternative such as resolve_place for single-point geocoding. Usage is implied (trip planning / matrix comparisons) rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.1.0- First observed
compare_hotels - First observed
find_retiring_rooms - First observed
get_data_sources - First observed
get_hotel_rates - First observed
plan_stays - First observed
resolve_place - First observed
search_hotels - First observed
travel_times
TDQS
Scored across 8 tools
Descriptions are unusually explicit and cross-reference each other ('Per-seller prices are in get_hotel_rates', 'Does not fetch new prices; get_hotel_rates does'), cleanly separating search_hotels, get_hotel_rates, compare_hotels and plan_stays. There is mild conceptual overlap since search_hotels, compare_hotels and plan_stays all surface and rank hotels, and travel_times overlaps with compare_hotels' routing, but the boundaries are well spelled out.
All eight tools use consistent snake_case verb_noun (or verb_theme) form: search_hotels, get_hotel_rates, get_data_sources, resolve_place, travel_times, compare_hotels, plan_stays, find_retiring_rooms. Verb-first, lowercase, predictable throughout.
Eight tools is a well-scoped set for a hotel-search and stay-planning server, with each tool covering a distinct capability (search, rates, geocoding, routing, comparison, trip planning, retiring rooms, source metadata). No redundant or filler tools.
The surface covers the full research/planning lifecycle for Indian hotel stays: place resolution, hotel search, per-source rates, travel-time matrices, hotel comparison, multi-stop planning and retiring rooms, with a clear intentional boundary on booking. Minor gaps remain (no hotel detail/amenities lookup, no saved-trip or booking handoff), but core workflows are covered without dead ends.
Maintenance
Related MCP Connectors
Grounded, multilingual travel data + a cited travel concierge. 12+ languages, deep India coverage.
Plan intercity journeys in India by train, flight or both, with a fare for every travel class.
Hotel booking MCP server. Search, book, and manage reservations across 250K+ properties worldwide.
Search hotel prices, get best overall and best direct price in structured response. Get your developer token at https://Infoseek.ai/mcp
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables multi-modal travel planning for India, aggregating flights, trains, buses, cabs, and personal vehicles across 117 cities with multi-leg routing and weighted scoring.2 npmApache 2.0

DIDA Hotel MCPofficial
AlicenseNot gradedqualityBmaintenanceEnables AI agents to search, compare, and book hotels with real-time pricing and availability, supporting multiple location types, star ratings, and price filters.11MIT- AlicenseBqualityAmaintenanceOfficial MCP server for MAQAMI, a hotel and flight booking platform with 3M+ hotels. Search live hotel rates and flights, look up places, airports and hotel details, then prebook and book. Remote Streamable HTTP endpoint, no API key required.12898 npm1MIT

RollingGo Hotel MCPofficial
AlicenseNot gradedqualityBmaintenanceEnables AI agents to search, compare, and book hotels worldwide through natural language, with real-time pricing and availability, plus price monitoring and order management.41MIT