Skip to main content
Glama

🍜 Gurume

PyPI Python License: MIT Docs

📚 Documentation: https://narumiruna.github.io/gurume/

Gurume is a Python library, CLI, TUI, and MCP server for discovering Japanese restaurants on Tabelog — Japan's largest restaurant review platform.

Search by area, cuisine, date, and party size; parse structured detail pages; and plug the same workflows directly into AI assistants via a FastMCP server.

✨ Features

  • 🍱 Tri-Source Unified Search: Concurrently query and normalize results across three industry-standard platforms: Tabelog (食べログ), Recruit Hot Pepper Gourmet (ホットペッパー グルメ), and Google Maps Platform (Places API New).

  • 🎯 Filter by Amenities: Filter for private dining rooms (個室), all-you-can-drink (飲み放題), all-you-can-eat (食べ放題), non-smoking, and parking via Hot Pepper official API.

  • 🔍 Search restaurants by area, keyword, cuisine, date, time, and party size

  • 🍣 Filter by 29 supported Japanese cuisine categories with stable Tabelog genre codes

  • 📄 Parse restaurant detail pages into structured review, menu, and course data

  • ⚡ Use synchronous and asynchronous Python APIs

  • 🖥️ Run an interactive TUI with area suggestions, keyword suggestions, and cuisine auto-detection

  • 🤖 Start an MCP server with schema-first inputs and structured outputs for AI assistant integrations

  • 🔒 Keep MCP responses typed with Pydantic models and Python APIs type-annotated

Related MCP server: FLUX Restaurants MCP Server

📦 Installation

uv add gurume

Or with pip:

pip install gurume

For local development:

uv sync --dev

🌐 HTTP Configuration

No additional HTTP setup is required for normal use. Gurume uses curl_cffi with Safari impersonation by default so its TLS fingerprint and generated browser headers remain consistent.

If Tabelog starts returning HTTP 403 for the default profile, set GURUME_IMPERSONATE before starting the CLI, TUI, MCP server, or Python process:

GURUME_IMPERSONATE=firefox gurume search --area 三重 --cuisine すき焼き

PowerShell users can set the same process environment variable before running Gurume:

$env:GURUME_IMPERSONATE = "firefox"
gurume search --area 三重 --cuisine すき焼き

The value must be an impersonation profile supported by the installed curl_cffi version. An unsupported value is rejected by curl_cffi.

🚀 Quick Start

💻 CLI

The built-in CLI currently exposes five commands:

  • gurume search

  • gurume map-search (experimental geographic yakitori search)

  • gurume list-cuisines

  • gurume tui

  • gurume mcp

Examples:

# Search by area and keyword
gurume search --area 東京 --keyword 寿司

# Search with a precise cuisine filter
gurume search --area 三重 --cuisine すき焼き

# Change sort order and output format
gurume search --area 大阪 --cuisine ラーメン --sort ranking --output json-list

# Return a structured JSON envelope for scripts and agents
gurume search --area 大阪 --cuisine ラーメン --sort ranking --output json

# List all supported cuisines
gurume list-cuisines

# Start the TUI
gurume tui

# Start the MCP server
gurume mcp

Current gurume search options:

  • --area, -a

  • --keyword, -k

  • --cuisine, -c

  • --sort, -s: ranking, review-count, new-open, standard

  • --limit, -n

  • --output, -o: table, json, json-envelope, json-list, simple

Notes:

  • For natural-language input, use the gurume-cli agent skill with an AI assistant — it decomposes free-form text into the structured flags above.

  • --output json returns a structured envelope (status, items, meta, applied_filters, warnings, error). Use --output json-list for the legacy list-only JSON shape.

  • CLI, TUI, and MCP diagnostics are in English; user-entered search terms and Tabelog restaurant data may remain in Japanese.

  • Reservation filters, detail fetching, and page selection for gurume search are available in the Python API and MCP tools, but are not currently exposed as CLI flags.

Experimental map search uses explicit geographic bounds, not a prefecture ranking:

gurume map-search --min-lat 34.36 --max-lat 35.15 \
  --min-lon 135.85 --max-lon 137.25 --cuisine 焼き鳥 --page 1 --limit 20 -o json

Only yakitori and upstream rating order are currently supported. Results can cross prefecture boundaries; raw budget fields are not interpreted as lunch/dinner prices. See Map search usage for pagination, structured outputs, and limitations.

🐍 Python Library

from gurume import SortType
from gurume import query_restaurants

restaurants = query_restaurants(
    area="銀座",
    keyword="寿司",
    party_size=2,
    sort_type=SortType.RANKING,
)

for restaurant in restaurants[:3]:
    print(restaurant.name, restaurant.rating, restaurant.url)

Advanced search with filters

from gurume import PriceRange
from gurume import RestaurantSearchRequest
from gurume import SortType

request = RestaurantSearchRequest(
    area="渋谷",
    keyword="焼肉",
    reservation_date="20250715",
    reservation_time="1900",
    party_size=4,
    sort_type=SortType.RANKING,
    price_range=PriceRange.DINNER_4000_5000,
    online_booking_only=True,
    has_private_room=True,
)

restaurants = request.search_sync()
print(f"Found {len(restaurants)} restaurants")

Async search with metadata

import asyncio

from gurume import SearchRequest


async def main() -> None:
    request = SearchRequest(
        area="新宿",
        keyword="居酒屋",
        max_pages=2,
        include_meta=True,
    )

    response = await request.search()
    print(response.status)
    print(response.meta.total_count if response.meta else None)

    for restaurant in response.restaurants[:5]:
        print(restaurant.name, restaurant.review_count)


asyncio.run(main())

Restaurant detail scraping

from gurume import RestaurantDetailRequest

detail = RestaurantDetailRequest(
    restaurant_url="https://tabelog.com/tokyo/A1307/A130704/13053564/",
    fetch_reviews=True,
    fetch_menu=True,
    fetch_courses=True,
    max_review_pages=2,
).fetch_sync()

print(detail.restaurant.name)
print(len(detail.reviews), len(detail.menu_items), len(detail.courses))

Set fetch_reviews=False, fetch_menu=False, and fetch_courses=False to fetch only the base restaurant page for address, station, phone, hours, closed days, and budget fields.

Cuisine helpers

from gurume import get_all_genres
from gurume import get_genre_code

print(get_genre_code("すき焼き"))
print(get_all_genres()[:5])

🤖 MCP Server

Gurume ships a FastMCP server for AI assistants and other MCP-compatible clients.

⚙️ MCP Configuration

GitHub development version:

{
  "mcpServers": {
    "gurume": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/narumiruna/gurume",
        "gurume",
        "mcp"
      ]
    }
  }
}

PyPI release:

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

Local development:

{
  "mcpServers": {
    "gurume": {
      "command": "uv",
      "args": [
        "run",
        "--directory",
        "/home/<user>/workspace/gurume",
        "gurume",
        "mcp"
      ]
    }
  }
}

🛠️ MCP Tools

  1. Unified dual-source search across both Tabelog (食べログ) and Hot Pepper (ホットペッパー グルメ). Concurrently retrieves, normalizes, and compares restaurant data.

    Parameters:

    • : required dish, cuisine, or restaurant name (e.g. '骨付きカルビ', '焼肉')

    • : optional area, prefecture, city, or station name (e.g. '大阪', '鶴橋', '新宿')

    • : optional list of sources, defaults to

    • : filter for private dining rooms (個室あり)

    • : filter for all-you-can-drink plans (飲み放題あり)

    • : filter for all-you-can-eat plans (食べ放題あり)

    • : filter for non-smoking dining (禁煙席あり)

    • : maximum results per platform (1 to 20, default )

  2. Search restaurants globally or in Japan via Google Maps Platform Places API (New). Provides worldwide location accuracy, Google user ratings, and direct Google Maps navigation links.

  3. Direct search on Recruit Hot Pepper Gourmet API with official amenities, budget ranges, and coupons.

  4. Fetch comprehensive shop details and coupon information by Hot Pepper shop ID.

  5. tabelog_search_restaurants Search by area, keyword, or cuisine with structured pagination metadata.

    Parameters:

    • area: optional area, prefecture, city, or station name

    • keyword: optional free-text keyword for restaurant names or general matching

    • cuisine: optional cuisine name in Japanese for precise genre filtering

    • sort: ranking, review-count, new-open, standard

    • limit: 1 to 60, default 20

    • page: 1-based page number, default 1

    • reservation_date: YYYYMMDD

    • reservation_time: HHMM

    • party_size: positive integer

    Returns a structured RestaurantSearchOutput envelope with:

    • status

    • items

    • returned_count

    • limit

    • has_more

    • meta

    • applied_filters

    • warnings

    • error

  6. tabelog_list_cuisines Return the supported cuisine list as structured data.

  7. tabelog_get_restaurant_details Fetch base restaurant information and optionally collect reviews, menu items, and courses.

    Parameters:

    • restaurant_url: required Tabelog restaurant URL

    • fetch_reviews: default true; set false to skip review pages

    • fetch_menu: default true; set false to skip menu pages

    • fetch_courses: default true; set false to skip course pages

    • max_review_pages: minimum 1, default 1

    All optional fetch flags may be false when only basic restaurant information is needed.

  8. tabelog_get_area_suggestions Return structured area and station suggestions from Tabelog.

  9. tabelog_get_keyword_suggestions Return structured keyword suggestions for cuisines, restaurant names, and combined terms.

  10. tabelog_search_map_restaurants Experimental yakitori search within explicit min_lat, max_lat, min_lon, and max_lon bounds. Optional cuisine (only 焼き鳥), page (1-based), and limit (1–20). Returns a separate map envelope with coordinates, raw budgets, and rectangle-scoped metadata. This is not an exact prefecture/national ranking or an automatic fallback for HTTP 403.

  1. Validate the area with tabelog_get_area_suggestions when the user input is ambiguous.

  2. Validate cuisines or restaurant names with tabelog_get_keyword_suggestions.

  3. Call tabelog_search_restaurants with normalized values.

  4. Continue with page + 1 when meta.has_next_page is true.

  5. Call tabelog_get_restaurant_details for shortlisted restaurants.

⚠️ Error Model

All MCP tools return structured error data instead of relying on free-form exception text.

Current stable error codes:

  • invalid_parameters

  • unsupported_cuisine

  • upstream_unavailable

  • internal_error

When status="error", inspect error.error_code, error.retryable, and error.suggested_action first.

🧪 Testing the MCP Server

# Run the MCP test suite (mocked upstream)
uv run pytest -q tests/test_server.py

# Opt-in live stdio check of cuisines, suggestions, search, and details
uv run python scripts/check_mcp_live.py

# Start the server locally (stdio, default)
uv run gurume mcp

# Inspect tools and schemas interactively
npx @modelcontextprotocol/inspector uv run gurume mcp

The live check exits nonzero when any tool fails and reports each result as JSON. Supply a known current Tabelog restaurant URL for an independent detail check; without one, details use the first search result or are marked skipped. HTTP 403 on search or detail means Tabelog denied page access; repeated retries or different search filters will not fix it. Browser impersonation may not resolve upstream restrictions.

🌐 HTTP transport

gurume mcp can also run as an HTTP server for clients that speak streamable HTTP (or SSE):

# Streamable HTTP (recommended; endpoint at http://127.0.0.1:8000/mcp)
uv run gurume mcp --transport streamable-http

# Custom bind address, port, and path
uv run gurume mcp --transport streamable-http --host 0.0.0.0 --port 9001 --path /api/mcp

# Server-Sent Events transport
uv run gurume mcp --transport sse --port 8765 --path /events

Security note: the default bind is 127.0.0.1. Use --host 0.0.0.0 only on trusted networks; the MCP endpoint has no built-in authentication.

🖥️ TUI

Start the Textual TUI with:

uv run gurume tui

Or:

python -m gurume.tui

The TUI includes:

  • a two-column layout with search results and a detail panel

  • area suggestions with F2

  • keyword and cuisine suggestions with F3

  • automatic cuisine detection for direct cuisine-name input

  • visible sort controls and keyboard navigation

Detailed TUI documentation lives in docs/site/usage/tui.md.

🧩 Agent Skill

This repo ships an agent skill at skills/gurume-cli/ that teaches AI coding assistants (Claude Code, Codex CLI, etc.) when and how to call the gurume CLI for restaurant search on Tabelog.

Install it with skills:

npx skills add narumiruna/gurume

This pulls skills/gurume-cli/ into your local agent skills directory. After installing, your agent will reach for gurume automatically whenever you ask it to find restaurants in Japan — by area, cuisine, or a vague "where should I eat" prompt.

📁 Examples

See the examples/ directory for runnable scripts:

  • examples/basic_search.py: simple, advanced, and async search examples

  • examples/restaurant_detail.py: restaurant detail scraping examples

  • examples/cli_example.py: standalone example CLI built on the Python API

📝 Notes and Limitations

  • Gurume scrapes Tabelog pages and internal suggestion endpoints. Upstream HTML or API changes may break parsing.

  • Tabelog data is primarily Japanese. Even when user input is multilingual, normalized search values and many results are Japanese.

  • Natural-language input is no longer parsed inside the CLI/TUI. Use the gurume-cli agent skill with an AI assistant to translate free-form text into structured flags.

  • Reservation-related search results reflect Tabelog availability data and may change over time.

  • Use the library responsibly and avoid excessive request volume.

This project is intended for educational and research use.

  • Respect Tabelog terms of service and robots policies.

  • Do not send excessive or abusive traffic.

  • Add your own rate limiting and operational safeguards for production use.

📄 License

MIT License

🤝 Contributing

Contributions are welcome. Please open an issue or submit a pull request.

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    An MCP server for restaurant discovery and booking across Resy and OpenTable via natural language. It integrates Google Places data with dietary preferences, visit history, and weather awareness to provide personalized dining recommendations and group reservation management.
    23
    -
  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    An AI-native restaurant discovery service that enables searching and receiving natural language recommendations for over 2,200 restaurants across 15+ US cities. It provides tools for accessing detailed restaurant info, curated lists, and cuisine-specific searches through the Model Context Protocol.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables searching restaurants on Tabelog and retrieving details, reviews, menus, ratings, photos, and online-booking availability as MCP tools, without a browser.
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to manage restaurant reservations through typed MCP tools, including checking table availability, creating and canceling reservations, and listing the day's confirmed bookings.
    -