Python library, CLI, TUI, and MCP server for discovering Japanese restaurants on Tabelog
Project description
🍜 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 searchgurume list-cuisinesgurume tuigurume 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
# Let the CLI parse a natural-language query
gurume search --query "I want ramen in Tokyo"
# 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--query,-q--sort,-s:ranking,review-count,new-open,standard--limit,-n--output,-o:table,json,simple
Notes:
- Natural-language parsing in the CLI requires
OPENAI_API_KEY. - 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
-
tabelog_search_restaurantsSearch by area, keyword, or cuisine with structured pagination metadata.Parameters:
area: optional area, prefecture, city, or station namekeyword: optional free-text keyword for restaurant names or general matchingcuisine: optional cuisine name in Japanese for precise genre filteringsort:ranking,review-count,new-open,standardlimit: 1 to 60, default20page: 1-based page number, default1reservation_date:YYYYMMDDreservation_time:HHMMparty_size: positive integer
Returns a structured
RestaurantSearchOutputenvelope with:statusitemsreturned_countlimithas_moremetaapplied_filterswarningserror
-
tabelog_list_cuisinesReturn the supported cuisine list as structured data. -
tabelog_get_restaurant_detailsFetch a restaurant detail page and optionally collect reviews, menu items, and courses.Parameters:
restaurant_url: required Tabelog restaurant URLfetch_reviews: defaulttruefetch_menu: defaulttruefetch_courses: defaulttruemax_review_pages: minimum1, default1
-
tabelog_get_area_suggestionsReturn structured area and station suggestions from Tabelog. -
tabelog_get_keyword_suggestionsReturn structured keyword suggestions for cuisines, restaurant names, and combined terms.
📋 Recommended MCP Workflow
- Validate the area with
tabelog_get_area_suggestionswhen the user input is ambiguous. - Validate cuisines or restaurant names with
tabelog_get_keyword_suggestions. - Call
tabelog_search_restaurantswith normalized values. - Continue with
page + 1whenmeta.has_next_pageis true. - Call
tabelog_get_restaurant_detailsfor shortlisted restaurants.
⚠️ Error Model
All MCP tools return structured error data instead of relying on free-form exception text.
Current stable error codes:
invalid_parametersunsupported_cuisineupstream_unavailableinternal_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 - AI-assisted natural-language parsing with
F4 - automatic cuisine detection for direct cuisine-name input
- visible sort controls and keyboard navigation
Detailed TUI documentation lives in docs/TUI_USAGE.md.
📁 Examples
See the examples/ directory for runnable scripts:
examples/basic_search.py: simple, advanced, and async search examplesexamples/restaurant_detail.py: restaurant detail scraping examplesexamples/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.
- CLI and TUI natural-language parsing require
OPENAI_API_KEY. - 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gurume-0.0.6-py3-none-any.whl.
File metadata
- Download URL: gurume-0.0.6-py3-none-any.whl
- Upload date:
- Size: 51.5 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
19f0e0c8c74ed9137e267613d6a588f18be3ca6e78eeda0c941f6b03817c8be7
|
|
| MD5 |
8c057ff33d310de6161a8c69f992a3b5
|
|
| BLAKE2b-256 |
3011855126662aff510e2dec0cc5663fa8c7033d8aadd089d294900dc906d3ec
|