Skip to main content

Minimal Azure Policy engine with file and sdk backends

Project description

MCP Travel Planner

A unified MCP (Model Context Protocol) server providing a single entry point to comprehensive travel planning services.

This project implements ONE unified MCP server that orchestrates multiple travel-related backend services (flights, hotels, weather, geocoding, events, finance). MCP clients like Claude Desktop connect to a single server interface and access all travel planning capabilities through it.

Key Features

  • Single MCP Server Entry Point: One unified server (mcp_server.py) for all travel services
  • Service Orchestration: Manages multiple backend services through one interface
  • MCP Tools: Expose travel planning capabilities via Model Context Protocol
  • Claude Desktop Integration: Ready-to-use configuration for Claude Desktop
  • Modular Backend: Each service runs independently but is coordinated by the unified server
  • Runtime Configuration: Multi-source config with env vars, .env, and YAML support

Quick Start

Ready-to-use MCP configuration examples are provided in the examples/ directory:

  • claude_desktop_config_uv_testpypi.json - Run from Test PyPI with UV (no installation)
  • claude_desktop_config_uv_pypi.json - Run from PyPI with UV (stable release)
  • claude_desktop_config_template.json - Standard Python installation

See examples/QUICK_REFERENCE.md for copy-paste configs and examples/MCP_CONFIG_README.md for complete documentation.

Configuration

The project uses a multi-source runtime configuration system with proper precedence:

  1. Environment variables (highest priority)
  2. .env file
  3. runtime_config.yaml
  4. Default values (lowest priority)

See docs/CONFIG_README.md for complete configuration documentation.

Architecture

MCP Client (Claude Desktop) 
        ↓ (stdio)
Unified MCP Server (single entry point)
        ↓ (orchestrates)
Backend Services (flight, hotel, weather, geocoder, finance, events)

Status

  • Prototype / Proof-of-Concept. Intended for local development, experimentation, and as a reference implementation for orchestration patterns.

Key Concepts

  • Modular microservice-style servers implemented as small Python scripts under py_mcp_travelplanner/.
  • Each service lives in its own folder (for example flight_server/, hotel_server/, weather_server/) with a main.py or server entrypoint.
  • A small CLI and control server are provided for orchestration and to demonstrate inter-service interactions.

Contents

  • py_mcp_travelplanner/ — main package containing CLI, control server and per-service folders.
    • flight_server/, hotel_server/, weather_server/, geocoder_server/, event_server/, finance_server/ — example service implementations.
  • requirements.txt — pinned runtime/dev dependencies used by the project.
  • tests/ — pytest-based unit tests and lifecycle tests.
  • examples/ — MCP configuration examples for Claude Desktop and other clients.

Quick Start (Local Development)

Prerequisites

  • Linux / macOS / Windows with WSL
  • Python 3.12.1 or later is recommended for development

Recommended: Create and use a virtual environment

python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip

Install dependencies

Option A — pip (quick)

pip install -r requirements.txt

Option B — poetry (if you prefer pyproject/poetry workflows)

poetry install

Running services

Each server folder contains a runnable entrypoint (usually main.py). From the repository root you can start any server directly with Python. For example:

# run the flight server
python py_mcp_travelplanner/flight_server/main.py

# run the weather server
python py_mcp_travelplanner/weather_server/main.py

# run the control server (if present)
python py_mcp_travelplanner/control_server.py

Note: Some servers may expect environment variables or API keys; check the server's README under the corresponding server folder for provider-specific setup.

Unified MCP Server — Access All Services Through One Interface

The unified MCP server (py_mcp_travelplanner/mcp_server.py) provides a single entry point to all travel planning services. Instead of running and configuring multiple separate MCP servers, you can use ONE server that automatically discovers and integrates all available subservices.

Key Benefits

  • Single Connection: MCP clients connect to one server instead of six
  • Auto-Discovery: Automatically finds and loads all available services
  • Namespaced Tools: Clear tool organization (e.g., event.search_events, flight.search_flights)
  • Service Management: Start, stop, and monitor subservices through MCP tools
  • Unified Interface: Consistent access patterns across all travel services

Running the Unified Server

# Run the unified MCP server
python -m py_mcp_travelplanner.mcp_server

# Or via CLI
py-mcp-travel unified

Available Services & Tools

The unified server integrates:

Service Tools Description
event search_events, get_event_details, list_events Event search and discovery
flight search_flights, get_flight_details, list_flights Flight search and booking
hotel search_hotels, get_hotel_details, list_hotels Hotel search and reservations
weather get_weather, get_forecast Weather forecasts
geocoder geocode, reverse_geocode Location geocoding
finance get_exchange_rates, convert_currency Currency exchange

Management Tools

  • list_services - Show all integrated services and their tools
  • get_service_manifest - Get detailed JSON manifest of all services
  • get_status - Overall system status
  • start_server / stop_server - Manage individual subservices
  • health_check - Check service health

Claude Desktop Configuration

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "travel_planner_local": {
      "command": "python",
      "args": ["-m", "py_mcp_travelplanner.mcp_server"],
      "env": {
        "SERPAPI_KEY": "your-api-key-here"
      }
    }
  }
}

Example Usage

Once connected, use namespaced tool names:

# Search for events in New York
event.search_events({
  "query": "concerts",
  "location": "New York",
  "date_filter": "week"
})

# Search for flights
flight.search_flights({
  "departure_id": "JFK",
  "arrival_id": "LAX",
  "outbound_date": "2025-06-15"
})

# Get weather forecast
weather.get_forecast({
  "location": "New York",
  "days": 7
})

Documentation

For complete details about the unified server architecture, see docs/UNIFIED_SERVER.md.

CLI

run the weather server

python py_mcp_travelplanner/weather_server/main.py

run the control server (if present)

python py_mcp_travelplanner/control_server.py


**Note:** Some servers may expect environment variables or API keys; check the server's README under the corresponding server folder for provider-specific setup.

### CLI

A simple CLI is available under `py_mcp_travelplanner/cli.py` and `py_mcp_travelplanner/cli_handlers.py`. You can run the CLI script to access helper commands used in development:

```bash
python -m py_mcp_travelplanner.cli

(If the package isn't installed as a module, run the file directly: python py_mcp_travelplanner/cli.py.)

Unified MCP Server — Single Entry Point Architecture

This project provides ONE unified MCP server that acts as a single entry point to all travel planner services. The server is located at py_mcp_travelplanner/mcp_server.py and orchestrates all backend services (flights, hotels, weather, geocoding, events, finance) through a single Model Context Protocol interface.

Architecture Overview

  • Single MCP Server: One unified server exposing all travel planning capabilities
  • Service Orchestration: The MCP server manages and coordinates multiple backend services
  • Unified Interface: MCP clients connect to one server and access all travel services through it

MCP Server Configuration

For Claude Desktop and MCP Clients

Ready-to-use configuration files are provided in the examples/ directory:

Option 1: UV with Test PyPI (recommended for testing)

{
  "mcpServers": {
    "py_mcp_travelplanner_testpypi": {
      "command": "uv",
      "args": [
        "run",
        "--index",
        "https://test.pypi.org/simple",
        "--with",
        "py_mcp_travelplanner",
        "--no-project",
        "--",
        "py_mcp_travelplanner_cli"
      ],
      "env": {
        "SERPAPI_KEY": "your_serpapi_key_here"
      }
    }
  }
}

Option 2: UV with PyPI (stable release)

{
  "mcpServers": {
    "py_mcp_travelplanner": {
      "command": "uv",
      "args": [
        "run",
        "--with",
        "py_mcp_travelplanner",
        "--no-project",
        "--",
        "py_mcp_travelplanner_cli"
      ],
      "env": {
        "SERPAPI_KEY": "your_serpapi_key_here"
      }
    }
  }
}

Option 3: Local Installation

{
  "mcpServers": {
    "py_mcp_travelplanner": {
      "command": "python",
      "args": ["-m", "py_mcp_travelplanner.mcp_server"],
      "env": {
        "SERPAPI_KEY": "your_serpapi_key_here"
      }
    }
  }
}

Configuration locations by OS:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

See examples/MCP_CONFIG_README.md for complete setup instructions.

Environment Variables

Set these in the MCP config env section or in your shell:

Required:

Optional (with defaults):

  • LOG_LEVEL - DEBUG, INFO, WARNING, ERROR (default: INFO)
  • CONTROL_SERVER_PORT - Server port (default: 8787)
  • DEBUG_MODE - Enable debug mode: true/false (default: false)
  • DRY_RUN - Test mode without side effects: true/false (default: false)

See docs/CONFIG_README.md for all configuration options.

What the unified MCP server exposes

  • Tools: list_servers, start_server, start_all_servers, stop_server, health_check, get_status, list_pids, verify_serpapi_key
  • Services: event_server, finance_server, flight_server, geocoder_server, hotel_server, weather_server
  • Each tool accepts a JSON-like arguments object and returns TextContent responses

Running the MCP Server

Method 1: With Claude Desktop (Recommended)

  1. Get a SERPAPI key from https://serpapi.com/ (free tier: 100 searches/month)

  2. Choose a configuration from examples/:

    • For testing: claude_desktop_config_uv_testpypi.json
    • For production: claude_desktop_config_uv_pypi.json
    • For local dev: claude_desktop_config_template.json
  3. Copy to Claude Desktop config location (see paths above)

  4. Edit the config and replace your_serpapi_key_here with your actual key

  5. Restart Claude Desktop

The travel planner tools will now be available in your Claude conversations!

Method 2: Direct Execution (for testing)

# Start the unified MCP server
python -m py_mcp_travelplanner.mcp_server

# Or use the CLI helper
python -m py_mcp_travelplanner.cli mcp

Available MCP Tools

When connected to the unified MCP server, you'll have access to these tools:

  • list_servers: List all available travel service backends
  • start_server: Start a specific service (event, flight, hotel, weather, etc.)
  • start_all_servers: Start all services at once
  • stop_server: Stop a running service by name or PID
  • health_check: Verify a service is healthy and ready
  • get_status: Get overall system status and running services
  • list_pids: List all running service process IDs
  • verify_serpapi_key: Test if SERPAPI_KEY is configured correctly

Tool call JSON examples (conceptual)

When calling a tool via an MCP client you will call the tool by name and pass the corresponding arguments object. The exact outer envelope depends on the MCP client library you use; below are the argument payloads for the most common operations:

  • Start a server (dry run):
{ "server": "flight_server", "dry_run": true }
  • Start a server (actual start):
{ "server": "flight_server", "dry_run": false }
  • Start all servers (dry run):
{ "dry_run": true }
  • Stop a server (by name):
{ "server": "flight_server", "timeout": 5.0 }
  • Stop a server (by PID):
{ "server": 12345, "timeout": 5.0 }
  • Health check:
{ "server": "flight_server" }
  • Get overall status (no arguments):
{}

Expected responses

The server returns an array of TextContent objects (the mcp library encodes this). When using an MCP client, you should inspect the returned text field(s). For example a get_status call may return a single element whose text contains a human-readable status summary.

HTTP Control Server (Concrete, Scriptable)

For convenience there is a small HTTP control server (py_mcp_travelplanner/control_server.py) that wraps a subset of the MCP server functionality and exposes simple HTTP endpoints. This is recommended for quick scripting and interactive use.

Start the control server (background)

python py_mcp_travelplanner/control_server.py
# or, using the CLI helper
python -m py_mcp_travelplanner.cli serve --host 127.0.0.1 --port 8787

Useful curl examples

  • Get status (discovered servers + SERPAPI presence):
curl -s http://127.0.0.1:8787/status | jq
  • Health check for a server:
curl -s "http://127.0.0.1:8787/health?server=flight_server" | jq
  • Start a single server (dry run):
curl -X POST "http://127.0.0.1:8787/start?server=flight_server&dry=true" | jq
  • Start all servers (actual start):
curl -X POST "http://127.0.0.1:8787/start_all?dry=false" | jq
  • Stop a server by name:
curl -X POST "http://127.0.0.1:8787/stop?server=flight_server" | jq
  • List registered PIDs:
curl -s http://127.0.0.1:8787/pids | jq
  • Verify SERPAPI_KEY (performs a test request using the configured key):
curl -X POST http://127.0.0.1:8787/test_key | jq

Python example

import requests

BASE = "http://127.0.0.1:8787"

# get status
print(requests.get(f"{BASE}/status").json())

# start flight server (dry-run)
print(requests.post(f"{BASE}/start?server=flight_server&dry=true").json())

# start all
print(requests.post(f"{BASE}/start_all?dry=false").json())

# verify serpapi
print(requests.post(f"{BASE}/test_key").json())

Advanced Usage: Multi-Server Orchestration & HTTP API

Running Individual Servers (stdio or HTTP)

Each backend server (weather, event, hotel, flight, finance, geocoder) can be started with either stdio (default) or HTTP transport, and exposes a manifest for tool discovery:

# Start weather server with HTTP API
python -m py_mcp_travelplanner.weather_server.main --transport http --host 127.0.0.1 --port 8791

# Start event server with stdio (default)
python -m py_mcp_travelplanner.event_server.main

# Print tool manifest/schema for debugging
python -m py_mcp_travelplanner.weather_server.main --manifest

Unified Launcher Script

You can launch all servers from a single config file (YAML or JSON) using the provided script:

python scripts/run_mcp_from_config.py --config runtime_config.yaml

Example config (runtime_config.yaml):

servers:
  weather:
    enabled: true
    transport: http
    host: 127.0.0.1
    port: 8791
  event:
    enabled: true
    transport: http
    host: 127.0.0.1
    port: 8796
  hotel:
    enabled: true
    transport: http
    host: 127.0.0.1
    port: 8795
  flight:
    enabled: true
    transport: http
    host: 127.0.0.1
    port: 8793
  finance:
    enabled: true
    transport: http
    host: 127.0.0.1
    port: 8792
  geocoder:
    enabled: true
    transport: http
    host: 127.0.0.1
    port: 8794
SERPAPI_KEY: "your_serpapi_key_here"

This will launch all enabled servers with the specified transport and ports. Press Ctrl+C to stop all servers.

Integration Testing: HTTP Endpoints & Manifest

You can test HTTP endpoints and manifest output for any server:

# Test weather server HTTP endpoint
curl http://127.0.0.1:8791/manifest

# Or print manifest to stdout
python -m py_mcp_travelplanner.weather_server.main --manifest

You can also write integration tests in pytest to verify HTTP endpoints and manifest output. See the 'tests/' folder for examples.

Tests

Run the test suite with pytest:

# Run all tests
pytest -q

# Run MCP server tests specifically
pytest tests/test_mcp_server.py -v

# Run with coverage
pytest --cov=py_mcp_travelplanner --cov-report=html

Test Coverage:

  • MCP Server Tests: 25 tests covering all 8 tools, initialization, and workflows
  • Config Tests: 28 tests covering runtime configuration system
  • Total: 58 tests passing

Development Notes (Important)

1) Consolidate pyproject files

The repository currently contains service-level metadata and possibly extra pyproject.toml files inside server folders. For a single-source-of-truth dependency management approach, consolidate those service-level pyproject.toml contents into the root pyproject.toml and remove or archive the per-server pyproject.toml files. This simplifies CI, local dependency installation, and version pinning.

2) Harmonize shared dependencies (requests example)

Several service folders may declare their own requests version. To avoid mismatched runtime behavior, pin requests at the root pyproject.toml (or requirements.txt) to a single compatible version range and update any server-specific files to rely on the root manifest.

3) Python compatibility and dependency constraints

Some dependencies in the ecosystem (for example openapi-pydantic) declare compatibility for Python versions <4.0,>=3.8. To remain compatible with such packages while still using modern Python, set the project Python requirement to a range that excludes Python 4.0. For example in pyproject.toml set:

python = ">=3.12.1,<4.0"

This avoids dependency resolution errors if someone installs or runs the project on Python 4.x while the dependencies do not declare support for it.

4) Harmonize dependency versions across the monorepo

When merging per-server manifests, ensure shared libraries (requests, aiohttp, pydantic, etc.) are pinned consistently. Run a dependency resolver (pip-tools, poetry) and test local execution after changes.

Troubleshooting

  • If a server fails to start due to missing environment variables or API keys, check the server folder README for provider-specific instructions.
  • If you hit dependency resolution errors, run pip check or poetry lock to see conflicts and adjust the root manifest accordingly.

Contributing

  • Fork the repository, create a feature branch, and open a pull request against the main branch.
  • Keep changes focused: if you're changing dependencies, update pyproject.toml/requirements.txt and add a short rationale in the PR summary.
  • Run tests locally and ensure linting passes before opening a PR.

License

See the LICENSE file in the repository root.

Acknowledgements

This repository is a learning / POC project showcasing modular service layouts, simple orchestration, and packaging considerations for small multi-service Python projects.

Contact

For questions or help, open an issue in this repository with details about your environment and the problem you're encountering.

Project details


Download files

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

Source Distribution

py_mcp_travelplanner-0.1.20.tar.gz (84.2 kB view details)

Uploaded Source

Built Distribution

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

py_mcp_travelplanner-0.1.20-py3-none-any.whl (77.2 kB view details)

Uploaded Python 3

File details

Details for the file py_mcp_travelplanner-0.1.20.tar.gz.

File metadata

  • Download URL: py_mcp_travelplanner-0.1.20.tar.gz
  • Upload date:
  • Size: 84.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for py_mcp_travelplanner-0.1.20.tar.gz
Algorithm Hash digest
SHA256 4d7039655bebb8185e0dbdb6e62471a742febdd0cdf918c1070ceeb33d13e364
MD5 3b37af3b854c0eb6586d04f02b1a34f4
BLAKE2b-256 653a8ab7538f03d50c8e057957028b47df47aa1a17780209bb94a4263d64574f

See more details on using hashes here.

File details

Details for the file py_mcp_travelplanner-0.1.20-py3-none-any.whl.

File metadata

File hashes

Hashes for py_mcp_travelplanner-0.1.20-py3-none-any.whl
Algorithm Hash digest
SHA256 8f91dd8de49eaa511a20a089ac5f557abd439213d6108187d394021d4b421086
MD5 07c91b7394a799df4cfd5593f695e90f
BLAKE2b-256 373884dbf520458ebd0b2c7ff839612a244422d27caa08e0d0d1d42caceb1967

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