Back to Browse

Obilet MCP Server

Developer ToolsLow Risk8.0MCP RegistryLocal
Free

Server data from the Official MCP Registry

Unofficial read-only MCP server for obilet.com bus & flight tickets: journeys, prices.

About

Unofficial read-only MCP server for obilet.com bus & flight tickets: journeys, prices.

Security Report

8.0
Low Risk8.0Low Risk

Valid MCP server (2 strong, 4 medium validity signals). 4 known CVEs in dependencies Imported from the Official MCP Registry. 1 finding(s) downgraded by scanner intelligence.

8 files analyzed · 5 issues found

Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.

Permissions Required

This plugin requests these system permissions. Most are normal for its category.

file_system

Check that this permission is expected for this type of plugin.

How to Install

Add this to your MCP configuration file:

{
  "mcpServers": {
    "io-github-mohammad-abbasi-sh-obilet-mcp": {
      "args": [
        "obilet-mcp"
      ],
      "command": "uvx"
    }
  }
}

Documentation

View on GitHub

From the project's GitHub README.

obilet-mcp 🇹🇷

mcp-name: io.github.mohammad-abbasi-sh/obilet-mcp

Unofficial read-only MCP server for obilet.com**, Türkiye's bus & flight ticket search — search bus locations, list all bus journeys for a route + date (partner, bus type, seats, departure/arrival, duration, price in TRY, partner rating, stops), read full journey details, get price statistics, and read the flight summary (flight count, min/max price, airlines) for the same city pair.

Built by Mohammad Abbasi as part of the "Turkey MCP factory" (Sepehr-style pipeline). Not affiliated with obilet.com.

For AI agents

Add to your MCP client config (stdio):

{
  "mcpServers": {
    "obilet": {
      "command": "uvx",
      "args": ["obilet-mcp"]
    }
  }
}

Or run locally: python -m obilet_mcp.server (needs mcp<2, curl-cffi).

Tools

ToolDescription
obilet_search_locationsSearch locations by name — query ("Ankara", "İstanbul"), kind ("bus" / "flight"); returns id, name, display name, city id per match (bus ids are ints, flight ids are strings like "250_0")
obilet_search_bus_journeysBus journeys for a route + date — origin_id / destination_id (bus location ids, e.g. 349 İstanbul Avrupa -> 356 Ankara), date "YYYY-MM-DD", sort ("price_asc" / "departure" / "duration"), limit 1..24; returns journey id, partner, bus type, seats, stations, departure/arrival, duration, price in TRY, partner rating (0-10), stops, plus the total count
obilet_journey_detailFull detail of one journey (journey_id): partner, bus type, seats, stations, departure/arrival, duration, internet & original price in TRY, service fee, partner rating, bus name, platform, description, every stop with its time
obilet_price_statsPrice statistics for a route + date: journey count, min / median / mean / max ticket price in TRY
obilet_flight_summaryFlight summary for a route + date: flight count, min/max price in TRY, min/max duration, first/last departure, direct-flight flag, airlines with IATA codes (individual flight listings are NOT in v1)

Example output (obilet_search_bus_journeys / İstanbul Avrupa -> Ankara, 2026-11-07):

{"origin_id": 349, "destination_id": 356, "date": "2026-11-07",
 "sort": "price_asc", "total": 421, "count": 2, "journeys": [
  {"journey_id": 1432053091, "partner": "Yükseller Aksaray Birlik",
   "bus_type": "2+1", "total_seats": 41, "available_seats": 36,
   "origin": "Esenler Otogarı", "destination": "Ankara (Aşti) Otogarı",
   "departure": "2026-11-07T07:30:00", "arrival": "2026-11-07T15:30:00",
   "duration": "08:00:00", "price_try": 539.0, "original_price_try": 700.0,
   "price_currency": "TRY", "partner_rating": 8.64, …}, …]}

Example output (obilet_flight_summary / same route & date):

{"origin_id": 349, "destination_id": 356, "date": "2026-11-07",
 "flight_count": 26, "has_direct": true, "min_price_try": 1461.99,
 "max_price_try": 7399.34, "min_duration": "01:00:00",
 "max_duration": "12:05:00", "first_departure": "00:05:00",
 "last_departure": "23:30:00",
 "airlines": [{"name": "Pegasus", "iata": "PC"}, {"name": "AJet", "iata": "VF"},
              {"name": "THY", "iata": "TK"}]}

Example output (obilet_price_stats / same route & date):

{"origin_id": 349, "destination_id": 356, "date": "2026-11-07",
 "count": 421, "min_try": 539.0, "median_try": 800.0,
 "mean_try": 852.38, "max_try": 1150.0}

How it works

obilet.com exposes a JSON API, but it is session-gated: an HTML page is fetched first (it sets cookies incl. ob_Session and __cf_bm), then POSTs carry X-Requested-With: XMLHttpRequest with that page as Referer. Locations: POST /json/duraklar (bus) or /json/ucak-duraklari (flight). Journeys: POST /json/journeys/{origin}-{destination}/{date} with {} — one response holds every journey for the route. Detail: POST /json/sefer-tam/{journeyId}. The same journeys response carries the flightSummary. Sorting is client-side (price / departure / duration). The async flights endpoint is broken on the site side (404/500), so individual flight listings are out of scope for v1. Transport uses a persistent curl-cffi chrome120 session; requests are spaced ~0.8s apart; everything is read-only, no login, no API key.

Install

uvx obilet-mcp        # run directly (needs uv)
# or
pip install obilet-mcp
obilet-mcp         # starts the MCP server on stdio

Tests

python -m venv .venv && .venv/bin/pip install -e .
.venv/bin/python -m unittest discover -s tests -v

Offline tests run on recorded fixtures (real pages fetched 2026-11-06); live tests hit obilet.com.

Roadmap

  • Individual flight listings (if the async flights endpoint is fixed)
  • Round-trip search (outbound + return in one call)
  • Seat-map / available-seat detail per journey

License

MIT — see LICENSE.

Reviews

No reviews yet

Be the first to review this server!