odh-mcp-server
A FastMCP server that exposes hospitality data — accommodations, events, and gastronomy — through a unified MCP interface, supporting multiple worlds for real or fictional data.
README
odh-mcp-server
A FastMCP server that exposes hospitality data — accommodations, events, and gastronomy — through a unified MCP interface. Part of the GaiaWM ecosystem, it is open source, self-hostable, and designed to work both locally (stdio) and remotely (SSE / streamable-http).
The server maintains a "current world" in session context. A set_world tool switches the active world. All other tools query the current world transparently. The same find_accommodations call returns real hotel data from South Tyrol or fictional inn listings from a Spelljammer asteroid city.
Quickstart
# Install with uv (recommended)
pip install uv
# Run locally via stdio (Claude Desktop, etc.)
uvx odh-mcp-server --stdio
# Or clone and run directly
git clone https://github.com/openfantasymap/odh-mcp-server
cd odh-mcp-server
uv run server.py --stdio
Available worlds
| World ID | Name | Data source | Notes |
|---|---|---|---|
earth-313 |
South Tyrol | Open Data Hub (opendatahub.com) |
Real hotels, events, restaurants. WGS84 coordinates. |
bral |
The Rock of Bral | JSON fixtures | Spelljammer city-asteroid. Mock data for demo/roleplay. |
Tools
| Tool | Description |
|---|---|
set_world |
Switch the active world. Returns world description on success. |
describe_world |
Describe the current world and how to query it. |
find_accommodations |
Search for hotels / inns with optional geo, feature, and date filters. |
find_events |
Search for events with optional geo, date, and topic filters. |
find_gastronomy |
Search for restaurants and food places with geo and cuisine filters. |
Example session
# 1. Start in South Tyrol
set_world("earth-313")
→ World set to: South Tyrol (earth-313)
Real hospitality data from the Open Data Hub...
# 2. Find hotels near Bolzano with a pool
find_accommodations(near="Bolzano centro", features=["pool"], max_results=3)
→ Found 2 accommodations in South Tyrol (earth-313), near Bolzano centro...
# 3. Switch to the Rock of Bral
set_world("bral")
→ World set to: The Rock of Bral
A city-asteroid drifting through Wildspace...
# 4. Find an inn near the Great Market
find_accommodations(near="great market", radius_m=800)
→ Found 1 inn in the Rock of Bral, near great market...
1. The Raised Cup [inn] (budget) — A lively taproom in the lower city...
Claude Desktop config
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"odh-world": {
"command": "uv",
"args": ["run", "/path/to/odh-mcp-server/server.py", "--stdio"]
}
}
}
Or, once published to PyPI:
{
"mcpServers": {
"odh-world": {
"command": "uvx",
"args": ["odh-mcp-server", "--stdio"]
}
}
}
Session context notes
The server uses contextvars.ContextVar to track the current world per session.
- SSE / streamable-http transport: each client connection gets its own context — multiple users can be in different worlds simultaneously.
- stdio transport: single process, single context — fine for local single-user use (Claude Desktop, CLI).
Adding a new world
- Create
worlds/myworld.pyand implement theWorldAdapterabstract base class:
from worlds.base import WorldAdapter, Accommodation, Event, GastronomyPlace, WorldInfo
class MyWorldAdapter(WorldAdapter):
async def find_accommodations(self, ...) -> list[Accommodation]: ...
async def find_events(self, ...) -> list[Event]: ...
async def find_gastronomy(self, ...) -> list[GastronomyPlace]: ...
async def describe(self) -> WorldInfo: ...
- Register it in
worlds/__init__.py:
from .myworld import MyWorldAdapter
WORLD_REGISTRY = {
"earth-313": Earth313Adapter(),
"bral": BralAdapter(),
"myworld": MyWorldAdapter(), # add this line
}
- That's it. All tools will automatically support your new world once it's in the registry.
Configuration
Copy .env.example to .env and adjust as needed:
DEFAULT_WORLD=earth-313
ODH_BASE_URL=https://tourism.api.opendatahub.com/v1
ODH_TIMEOUT=10
NOMINATIM_URL=https://nominatim.openstreetmap.org
NOMINATIM_USER_AGENT=odh-mcp-server/0.1 (opensource hospitality MCP)
License
MIT
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.