Skip to main content

Python library, CLI, TUI, and MCP server for discovering Japanese restaurants on Tabelog

Project description

🍜 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

  • 🔍 Search restaurants by area, keyword, cuisine, date, time, and party size
  • 🍣 Filter by 45+ 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 AI-assisted query parsing
  • 🤖 Start an MCP server with schema-first inputs and structured outputs for AI assistant integrations
  • 🔒 Keep responses typed with Pydantic models and Python type hints

📦 Installation

uv add gurume

Or with pip:

pip install gurume

For local development:

uv sync --dev

🚀 Quick Start

💻 CLI

The built-in CLI currently exposes four commands:

  • gurume 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 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, 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.
  • Reservation filters, detail fetching, and page selection are available in the Python API and MCP tools, but are not currently exposed as CLI flags.

🐍 Python Library

Simple search

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))

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. 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
  2. tabelog_list_cuisines Return the supported cuisine list as structured data.

  3. tabelog_get_restaurant_details Fetch a restaurant detail page and optionally collect reviews, menu items, and courses.

    Parameters:

    • restaurant_url: required Tabelog restaurant URL
    • fetch_reviews: default true
    • fetch_menu: default true
    • fetch_courses: default true
    • max_review_pages: minimum 1, default 1
  4. tabelog_get_area_suggestions Return structured area and station suggestions from Tabelog.

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

📋 Recommended MCP Workflow

  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
uv run pytest -q tests/test_server.py

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

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

🌐 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/TUI_USAGE.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.

⚖️ Legal and Ethical Use

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gurume-0.0.7-py3-none-any.whl (49.6 kB view details)

Uploaded Python 3

File details

Details for the file gurume-0.0.7-py3-none-any.whl.

File metadata

  • Download URL: gurume-0.0.7-py3-none-any.whl
  • Upload date:
  • Size: 49.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.13 {"installer":{"name":"uv","version":"0.11.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for gurume-0.0.7-py3-none-any.whl
Algorithm Hash digest
SHA256 d7ece93f352303e7bc0280309668fa1740ea6e910972651fa7ce846b4bc5d5c2
MD5 df85b77b6b72dc3acfbc3f884a6fc23b
BLAKE2b-256 84d51228f28657652178b7a53aa96ba7e383dedb5cec0881c1fbe3ce40bde841

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page