Skip to main content
Glama

Agentic MCP Itinerary — PoC

An MCP server that internally runs an LLM agent (Gemini Flash + LangGraph) and orchestrates multiple downstream MCP servers. The client (Claude Desktop, ChatGPT) sees a clean interface with persistent state between iterations.

Concept

Claude Desktop / ChatGPT
        │
        │  MCP (HTTP/SSE + OAuth 2.1)
        ▼
┌─────────────────────────────────────┐
│         travel-agent (este repo)    │
│  FastMCP server + LangGraph agent   │
│                                     │
│  ┌──────┐  ┌────────┐  ┌──────────┐│
│  │Vuelos│  │Hoteles │  │Actividad.││  ← MCP mocks STDIO
│  └──────┘  └────────┘  └──────────┘│
└─────────────────────────────────────┘

Why is this different? No company yet offers a "vertical agent packaged as an MCP server." This PoC demonstrates the pattern: the client only sees 4-5 clean tools, but behind them is an agent with memory, parallel fan-out, and persistent state.


Related MCP server: ts-travel-mcp-server

Stack

Component

Technology

Exposed MCP Server

FastMCP 3.1.1 (streamable-http)

Internal Agent

LangGraph (StateGraph + parallel fan-out)

LLM Model

Gemini Flash (gemini-2.0-flash)

Auth

OAuth 2.1 Authorization Code Flow + JWT HS256

Checkpointing

MemorySaver (in-memory, sufficient for PoC)

Downstream MCP

Official MCP SDK (mcp.client.stdio)

Mocks

3 FastMCP servers STDIO (flights, hotels, activities)

Deploy

Railway (RAILPACK + pyproject.toml)


Exposed Tools (Public API)

Tool

Parameters

Description

create_itinerary

requirements: str

Creates a complete draft (flights + hotel + activities in parallel)

refine_itinerary

itinerary_id: str, change_request: str

Refines an existing draft

get_itinerary

itinerary_id: str

Retrieves the current state

list_itineraries

Lists all active itineraries

confirm_itinerary

itinerary_id: str

Confirms and generates a confirmation_code


Deploy on Railway

URLs

Railway IDs

  • Project: e50da57f-ee0b-47a3-81a3-55556fe6de0d

  • Service: 09065312-ac84-4876-b9c9-dd5d6439f1d4

  • Environment: 09b3f0c9-e5ad-4f61-b351-275bbcffd5ad

Required Environment Variables

Variable

Description

GEMINI_API_KEY

Google Gemini API key

MCP_USERNAME

Username for OAuth login

MCP_PASSWORD

Password for OAuth login

MCP_JWT_SECRET

Secret to sign JWT (generated with secrets.token_urlsafe(32))

MCP_BASE_URL

Public server URL (to build redirect URIs)


Auth: OAuth 2.1 Authorization Code Flow

Full Flow

1. Claude Desktop detecta el MCP server
2. Descubre /.well-known/oauth-authorization-server
3. Redirige al usuario a /authorize
4. El servidor redirige a /oauth/authorize (form de login HTML)
5. Usuario introduce user/pass → POST /oauth/authorize
6. Servidor valida credenciales (MCP_USERNAME / MCP_PASSWORD)
7. Emite auth code → redirect a Claude Desktop
8. Claude Desktop intercambia code → JWT en /token
9. JWT usado como Bearer en todas las llamadas MCP

Implementation

  • server/auth.py: SimpleOAuthProvider (extends FastMCP's OAuthProvider)

  • JWT HS256, 1h validity

  • Auth codes: 5 min validity

  • PKCE (S256) supported

  • /health remains public without auth


Configure Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "travel-agent": {
      "type": "http",
      "url": "https://travel-agent-production-c1c4.up.railway.app/mcp"
    }
  }
}

No headers — Claude Desktop manages the OAuth flow automatically. The first time, it will open the browser for login.


Local Development

Requirements

pip install -e ".[dev]"

Start Server

PYTHONPATH=server MCP_USERNAME=alexguerra MCP_PASSWORD=tu_pass \
  MCP_JWT_SECRET=dev_secret python3 server/main.py

Smoke test

PYTHONPATH=server python3 tests/smoke_test.py

Verify syntax

PYTHONPATH=server python3 -m py_compile server/main.py server/auth.py server/agent.py

Project Structure

agentic-mcp-itinerary/
├── server/
│   ├── main.py          # FastMCP server (4 tools + OAuth + /health)
│   ├── auth.py          # SimpleOAuthProvider (OAuth 2.1 + JWT)
│   ├── agent.py         # LangGraph graph con fan-out paralelo
│   ├── state.py         # ItineraryState TypedDict + checkpointer
│   └── tools/
│       ├── flights.py   # Cliente MCP → mock vuelos
│       ├── hotels.py    # Cliente MCP → mock hoteles
│       └── activities.py # Cliente MCP → mock actividades
├── mocks/
│   ├── flights_mcp.py   # Mock server vuelos (FastMCP STDIO)
│   ├── hotels_mcp.py    # Mock server hoteles (FastMCP STDIO)
│   └── activities_mcp.py # Mock server actividades (FastMCP STDIO)
├── tests/
│   └── smoke_test.py    # Test end-to-end básico
├── docs/
│   └── OAUTH_PLAN.md    # Spec del OAuth (referencia de diseño)
├── pyproject.toml       # Deps para RAILPACK
├── railway.toml         # Builder=RAILPACK, startCommand
└── claude_desktop_config.json  # Config para Claude Desktop (sin Bearer manual)

Key Decision Log

Decision

Discarded Alternative

Reason

RAILPACK + pyproject.toml

nixpacks

nixpacks fails on pip inside immutable env

OAuth 2.1 Authorization Code

Static Bearer token

Claude Desktop manages native OAuth; more production-ready

JWT HS256 in-memory

Token DB

PoC — no persistent state between restarts

FastMCP 3.1.1 OAuthProvider

Manual auth with Starlette

FastMCP integrates the flow with the MCP transport

MemorySaver

SQLite/Redis

Sufficient for local PoC; easy to migrate to SqliteSaver

Gemini Flash

Claude Haiku

Codex had credential conflict with Anthropic


Next Steps (post-PoC)

  • [ ] Test in Claude Desktop — verify full OAuth flow

  • [ ] Real persistenceSqliteSaver or Postgres for state between restarts

  • [ ] Real downstream MCPs — replace mocks with real APIs (Amadeus, Booking, etc.)

  • [ ] Multi-user — User DB instead of env vars

  • [ ] Rate limiting — by JWT token

  • [ ] Telemetry — LangSmith or similar to trace the internal agent

F
license - not found
Not graded
quality - not tested
D
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Geo-based flight search MCP server. Find more flights between any two places on earth

  • MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.

  • Hotel booking MCP server. Search, book, and manage reservations across 250K+ properties worldwide.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AlexGHerrera/agentic-mcp-itinerary'

If you have feedback or need assistance with the MCP directory API, please join our Discord server