Skip to main content
Glama
Shivanilarokar

Trip Planner MCP Server

Trip Planner — MCP Server + LangGraph Agent

A journey-planning MCP server built with FastMCP, plus a LangGraph agent that connects to it alongside two public MCP servers. The agent manages a traveller's itinerary: journeys (trips as a whole), the city stops within a journey, and the plan items (sights, meals, activities) within each stop.

Architecture

Architecture

The user asks a question. The LangGraph agent thinks: if it needs a tool, it calls one, gets the result, and thinks again — repeating until it has enough to answer. MultiServerMCPClient connects to all three MCP servers when the agent starts and hands every discovered tool to the agent. One server is ours; two are public.

Data model, tools, resource, prompt

SQLite, three tables, one nesting level each:

Table

Holds

journeys

A trip as a whole — title, home city, dates, budget

stops

A city leg within a journey — city, country, arrival date, nights, transport mode

plan_items

A sight/meal/activity within a stop — title, category, time window, priority, status

Tools (backend/mcpserver/TripPlannerServer.py) — full CRUD plus a live weather lookup:

Tool

CRUD

create_journey

Create

add_stop

Create

add_plan_item

Create

list_stops

Read

update_plan_status

Update

delete_stop

Delete (cascades to its plan items)

get_destination_weather

Calls the free Open-Meteo API (geocoding + current weather), no key needed

Resources:

  • journeys://all — one-line summary of every journey

  • journey://{journey_id}/itinerary — templated resource, a day-by-day itinerary for one journey (each stop with its plan items underneath)

Prompt:

  • suggest_itinerary(stop_id) — a reusable template that turns a stop's saved plan items into an hour-by-hour day plan

Public servers used, and why

  • time (uvx mcp-server-time, stdio) — official reference MCP server for timezone/local-time lookups. Trivial, zero-risk, no genuine remote alternative exists for this, so stdio is the right call here.

  • tavily (Streamable HTTP, https://mcp.tavily.com/mcp) — a genuinely hosted remote MCP server (no local process at all) from Tavily, a reputable company in the LLM tooling space (the same search backend LangChain's own community tools use). It needs a free API key (tavily.com, no credit card). Picked over a plain page-fetch server because it does real-time, ranked web search (attractions, travel advisories, local facts) rather than fetching one raw page — a much stronger fit for a trip planner. Deliberately avoided pulling a server from the public MCP registries (registry.modelcontextprotocol.io, Smithery, Glama) directly — those directories are unvetted, and searching them turned up entries with suspicious names during development. Tavily is a known, reputable company with a real product, not an anonymous registry listing.

Extras beyond the core CRUD flow

  • get_destination_weather calls the free Open-Meteo API from inside a tool (geocoding + current weather, no key required).

  • backend/integrations/fastapimcp_integration.py serves REST (/health, /journeys) and MCP (/mcp) from one FastAPI ASGI app.

  • add_stop logs via ctx.info(...), visible live in the MCP Inspector's notification panel.

  • A browser console (backend/api/app.py + frontend/) — see below.

Console UI (bonus)

A small React console for driving the agent from a browser instead of the CLI: pick one of the 12 test questions (or type your own), watch each tool call and its result stream in live, tool by tool, as the agent runs.

backend/api/app.py wraps the same LangGraph agent from backend/client/langgraphagent.py in a long-lived FastAPI process. It connects to all three MCP servers once at startup, then streams each question's step-by-step trace back to the browser as newline-delimited JSON.

Three processes, three terminals:

uv run backend/mcpserver/TripPlannerServer.py     # :8000 — the MCP server
uv run python -m backend.api.app                  # :8010 — streaming console API
cd frontend && npm install && npm run dev          # :5173 — the UI

Open the printed localhost URL. The left rail shows live server/tool counts from /api/servers; the question list is the same 12-question set as DocsAndDemo/question.md.

How to run it

  1. Install dependencies (uses uv):

    uv sync
  2. Copy .env.example to .env and fill in:

    OPENAI_API_KEY=sk-...
    TAVILY_API_KEY=tvly-...      # free key at https://tavily.com
  3. Start the server (terminal 1):

    uv run backend/mcpserver/TripPlannerServer.py

    Live at http://127.0.0.1:8000/mcp (note the required /mcp suffix).

    Optional — run the combined REST+MCP app instead:

    uv run python -m backend.integrations.fastapimcp_integration
  4. Run the agent (terminal 2):

    uv run backend/client/langgraphagent.py "Add a 3-night stop in Kyoto to journey 1 and tell me the local time there"
  5. Optional — test the server directly in the MCP Inspector before running the agent:

    npx @modelcontextprotocol/inspector

    Transport: Streamable HTTP, URL: http://127.0.0.1:8000/mcp.

Requires uv (Python/uvx) and Node.js (npx, for the Inspector) installed.

Example runs

Full tool-call traces are in screenshots/demo.txt. Summary:

  1. Write-only"Create a new journey called 'Bali Getaway' from Mumbai, budget 1500, dates 2026-09-01 to 2026-09-10. Then add a 5-night stop in Bali, Indonesia to it." → Created journey #3 and stop #4 on our server.

  2. Write + public time"Add a 4-night stop in Reykjavik, Iceland to journey 3, and tell me the current local time there." → Added stop #5, and called get_current_time (both tool calls fired in parallel in one turn) → 11:03, Saturday, Atlantic/Reykjavik (UTC+0).

  3. Public tavily research"What are the top attractions to see in Reykjavik right now, and are there any current travel advisories for Iceland?" → Real-time web search returned 8 ranked attractions and 3 current government travel advisories, with live sources.

Why an MCP server instead of plain Python functions in the agent?

Putting tools in an MCP server decouples what a tool can do from which agent uses it. The same trip_planner server can be called by this LangGraph agent, tested by hand in the MCP Inspector, or plugged into a completely different agent or client later, all without touching the tool code — because the server exposes a stable, self-describing contract (schemas generated straight from function signatures and docstrings) over a standard protocol, instead of being tangled into one agent's Python process. It also means the server can run, scale, and fail independently of the agent: if the trip-planner logic needs a different host, a different language, or its own deployment schedule, that's an infrastructure change, not a rewrite. Writing the same logic as inline Python functions works fine for a single throwaway script, but it locks the tool to that one agent and gives up all of that reuse, isolation, and discoverability for no benefit.

Video walkthrough

DocsAndDemo/12.07.2026_22.51.20_REC.mp4 — demo, architecture walkthrough, MCP connection config, and live tool calls across the local and public servers.