Skip to main content
Glama
nxGnosis

Travel Agent MCP Server

by nxGnosis

TravelAgentMCP šŸŒāœˆļø

A monorepo of MCP (Model Context Protocol) servers for the TVA OTA platform: flight and hotel search & booking, visa and immigration requirements & booking tracking, and user account management — built for AI travel agents.

Architecture

TravelAgentMCP/
ā”œā”€ā”€ mcps/
│   ā”œā”€ā”€ shared/            @travelagent-mcp/shared — HTTP client, config, guardrails, tool helper (not a server)
│   ā”œā”€ā”€ flight-mcp/        tva-flight-mcp   — search, pricing, seatmaps, booking lifecycle
│   ā”œā”€ā”€ hotel-mcp/         tva-hotel-mcp    — search, availability, booking lifecycle
│   ā”œā”€ā”€ visa-mcp/          tva-visa-mcp     — country requirements + booking tracking
│   ā”œā”€ā”€ immigration-mcp/   tva-immigration-mcp — service info + booking tracking
│   └── account-mcp/       tva-account-mcp  — auth, profile, promo codes, notifications
└── src/index.ts           travelagent-mcp  — gateway that mounts all five servers' tools in one process

Each mcps/* package is an independently runnable stdio MCP server with its own bin. Run the ones you need (e.g. only tva-flight-mcp + tva-hotel-mcp for a booking widget, or only tva-visa-mcp + tva-immigration-mcp for an advisory bot), or run the root gateway (travelagent-mcp) to get everything in one process — this is what the published npm package has always been, kept for backward compatibility.

One upstream API, two auth modes:

  • TVA OTA backend (TVA_BASE_URL) — flights, hotels, bookings, account, and the "client" side of visa/immigration booking tracking (updates, notifications, transactions). Most booking-management endpoints require a bearer token; guest checkout flows (book, cancel-by-UUID, verify, resend-ticket) do not.

  • Visa/Immigration content (same TVA_BASE_URL, authenticated via CONTENT_API_KEY instead of a bearer token) — country requirements, visa types, fees and FAQs, used only by GET_VISA_INFO_BY_COUNTRY / GET_IMMIGRATION_INFO_BY_COUNTRY.

Related MCP server: orizn-visa-mcp

Guardrails

  • Least privilege: only user-facing endpoints are exposed. Admin/ops endpoints (booking management, refunds, revenue stats) are deliberately not wrapped as tools — they're not appropriate for a conversational agent.

  • Explicit confirmation: every tool that moves money or is irreversible (BOOK_FLIGHT, BOOK_HOTEL, CANCEL_FLIGHT_BOOKING, CANCEL_HOTEL_BOOKING, CONFIRM_FLIGHT_PAYMENT, CONFIRM_HOTEL_PAYMENT, SELECT_FLIGHT_SEAT, CHANGE_PASSWORD, CLOSE_ACCOUNT) requires confirm: true, which the calling agent should only set after reading the specific details back to the user.

  • No secrets in the LLM's context: TVA_ACCESS_TOKEN is never a tool parameter — it's read from the process environment, injected per user session by whichever agent spawns these servers. LOGIN_USER / SOCIAL_AUTH_LOGIN return the token wrapped in a __session envelope for the spawning agent to intercept and store out-of-band; the model only ever sees a plain confirmation message. See mcps/account-mcp/src/lib/session.ts for the contract.

  • No raw offer replay: Amadeus flight offers are large opaque JSON blobs. SEARCH_FLIGHTS caches each offer server-side (SQLite, see mcps/flight-mcp/src/lib/offerCache.ts) and hands the model a short offerRef instead — the model never reconstructs offer JSON by hand, which would risk token bloat or silent price/fare corruption.

  • Redaction: passwords, tokens, OTPs and card numbers are masked before anything is logged (see mcps/shared/src/guardrails.ts).

  • Known risk — hotel payments: BOOK_HOTEL currently takes raw card details directly (the TVA hotel API has no tokenized checkout step yet). This must only be called by a client that collected card details through a secure, PCI-compliant surface — never by prompting a user to type a card number into chat. See the tool's description for details.

  • Rate limiting: each tool call is throttled per-process (defense against a runaway function-calling loop). This is not a substitute for persistent, cross-turn throttling — track abuse persistently at the session layer if you need real protection.

Setup

pnpm install
cp .env.example .env   # fill in TVA_BASE_URL and content-API keys
pnpm build              # builds mcps/shared first, then every domain server, then the gateway

Run the gateway (all tools in one process):

pnpm start

Or run a single domain server directly:

node mcps/flight-mcp/dist/index.js

Tool reference

Flight (tva-flight-mcp)

SEARCH_FLIGHTS, GET_POPULAR_FLIGHT_ROUTES, GET_FLIGHT_PRICE_ANALYSIS, GET_MOST_TRAVELED_DESTINATIONS, GET_MOST_BOOKED_DESTINATIONS, GET_BUSIEST_TRAVEL_PERIOD, GET_FLIGHT_SEATMAP_BY_OFFER, GET_FLIGHT_SEATMAP_BY_ORDER, GET_FLIGHT_FARE_UPSELL, PREDICT_FLIGHT_CHOICE, CONFIRM_FLIGHT_PRICE, BOOK_FLIGHT, LIST_MY_FLIGHT_BOOKINGS, GET_FLIGHT_BOOKING, VERIFY_FLIGHT_BOOKING, CANCEL_FLIGHT_BOOKING, GET_FLIGHT_SEAT_PRICE, SELECT_FLIGHT_SEAT, RESEND_FLIGHT_TICKET, GET_FLIGHT_TICKET_DOWNLOAD_LINK, CONFIRM_FLIGHT_PAYMENT

Hotel (tva-hotel-mcp)

SEARCH_HOTELS, SEARCH_HOTEL_CITIES, CHECK_HOTEL_AVAILABILITY, BOOK_HOTEL, LIST_MY_HOTEL_BOOKINGS, GET_HOTEL_BOOKING, CONFIRM_HOTEL_PAYMENT, CANCEL_HOTEL_BOOKING

Visa (tva-visa-mcp)

GET_VISA_INFO_BY_COUNTRY, LIST_MY_VISA_BOOKINGS, GET_VISA_BOOKING, GET_VISA_BOOKING_BY_APPLICATION_UUID, GET_VISA_UPDATES, GET_VISA_UPDATES_BY_BOOKING, GET_VISA_FOLLOWUP_QUESTIONS, ANSWER_VISA_FOLLOWUP, GET_VISA_NOTIFICATIONS, MARK_VISA_NOTIFICATION_READ, GET_VISA_TRANSACTIONS, GET_VISA_TRANSACTION_DETAIL

Immigration (tva-immigration-mcp)

GET_IMMIGRATION_INFO_BY_COUNTRY, LIST_MY_IMMIGRATION_BOOKINGS, GET_IMMIGRATION_BOOKING, GET_IMMIGRATION_UPDATES, GET_IMMIGRATION_UPDATES_BY_BOOKING, GET_IMMIGRATION_NOTIFICATIONS, MARK_IMMIGRATION_NOTIFICATION_READ, GET_IMMIGRATION_TRANSACTIONS, GET_IMMIGRATION_TRANSACTION_DETAIL

Account (tva-account-mcp)

REGISTER_USER, LOGIN_USER, SOCIAL_AUTH_LOGIN, FORGOT_PASSWORD, RESEND_OTP, VERIFY_OTP, LOGOUT_USER, GET_CURRENT_USER, GET_USER_PROFILE, EDIT_USER_PROFILE, CHANGE_PASSWORD, CHECK_DISCOUNT_PROMO, GET_USER_NOTIFICATIONS, CLOSE_ACCOUNT

Consumed by

MegaMind's NomadSage travel agent spawns these servers (via stdio, one per domain) alongside its knowledge-base search and social-mcp reply tools — see travel-agent/src/lib/tva-client.ts and travel-agent/src/lib/tva-session.ts in that repo.

Available Tools

2 tools
GET_IMMIGRATION_INFO_BY_COUNTRYC

Get immigration information for a specific country.

ParametersJSON Schema
NameRequiredDescriptionDefault
countryCodeYes

TDQS

C2.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It states 'Get' which implies a read-only operation, but does not disclose any behavioral traits such as rate limits, authentication needs, data freshness, or error handling. This is a significant gap for a tool with no annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, clear sentence with no wasted words. It is appropriately sized and front-loaded, efficiently conveying the core purpose without unnecessary elaboration.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of immigration information, lack of annotations, no output schema, and low schema coverage, the description is incomplete. It does not address what type of information is returned, potential limitations, or how it differs from the sibling tool, leaving the agent with insufficient context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 0%, and the description does not add any meaning beyond the schema. It mentions 'specific country' but does not explain the 'countryCode' parameter's format, valid values, or semantics, failing to compensate for the low schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Get' and the resource 'immigration information for a specific country', making the purpose understandable. However, it does not explicitly differentiate from its sibling tool GET_VISA_INFO_BY_COUNTRY, which likely provides overlapping or related information, so it misses the highest score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus its sibling GET_VISA_INFO_BY_COUNTRY, nor does it mention any prerequisites or alternative contexts. It lacks explicit usage instructions, leaving the agent to infer based on tool names alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

GET_VISA_INFO_BY_COUNTRYC

Get visa information for a specific country.

ParametersJSON Schema
NameRequiredDescriptionDefault
countryCodeYes
currencyCodeNo

TDQS

C2.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure but only states the basic action without details on permissions, rate limits, error handling, or response format. It doesn't add meaningful context beyond the minimal purpose, failing to compensate for the lack of structured annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, clear sentence with no wasted words, making it highly concise and front-loaded. It efficiently communicates the core purpose without unnecessary elaboration, earning full marks for brevity and structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (2 parameters, no output schema, and no annotations), the description is insufficient. It lacks details on parameter usage, behavioral traits, and output expectations, making it incomplete for effective agent operation despite the concise structure.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 0%, and the description doesn't mention any parameters or their meanings. It fails to explain what 'countryCode' and 'currencyCode' represent, their expected formats, or how they influence the output, leaving both parameters undocumented and adding no value beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with a specific verb ('Get') and resource ('visa information for a specific country'), making it immediately understandable. However, it doesn't explicitly differentiate from its sibling tool 'GET_IMMIGRATION_INFO_BY_COUNTRY', which likely covers related but distinct information, preventing a perfect score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus its sibling 'GET_IMMIGRATION_INFO_BY_COUNTRY', nor does it mention any prerequisites, alternatives, or exclusions. It only states what the tool does, leaving the agent to infer usage context without explicit direction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updates
    • First observedGET_IMMIGRATION_INFO_BY_COUNTRY
    • First observedGET_VISA_INFO_BY_COUNTRY

TDQS

C2.8/5.0

Scored across 2 tools

Disambiguation2/5

The two tools have unclear boundaries and significant overlap. 'Immigration information' and 'visa information' are closely related concepts in travel, and their descriptions do not clearly differentiate what each tool provides, leading to potential confusion for an agent trying to select the right one.

Naming Consistency5/5

The tool names follow a consistent pattern of uppercase snake_case with a clear 'GET_<domain>_BY_COUNTRY' structure. Both tools use the same verb ('GET') and format, making them predictable and easy to parse.

Tool Count2/5

With only 2 tools, the server feels thin for a 'Travel Agent' domain, which typically involves broader functionality like booking flights, hotels, or checking travel advisories. The limited scope suggests an incomplete or overly narrow implementation.

Completeness2/5

The server is severely incomplete for a travel agent purpose. It lacks core travel operations such as searching for flights, booking accommodations, checking weather, or providing general travel tips, leaving obvious gaps that will hinder agent workflows.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers