Polarhub MCP Client
PolarHub MCP Client - AI Flight Booking Chatbot
Ask AI about Polarhub MCP Client
Powered by Claude Β· Grounded in docs
I know everything about Polarhub MCP Client. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
PolarHub MCP Client
English | νκ΅μ΄
"Search flights for me" β AI-powered airline booking in plain language
An AI chat client for NDC (New Distribution Capability) airline booking MCP servers. Search flights, book tickets, select seats, add services, change itineraries, and process refunds β the entire airline booking lifecycle through natural language conversation.
π Links
HaloSync halosync.kr API Documentation doc.halo-platform.net
Why This Project?
Airline booking systems are complex. NDC APIs have dozens of endpoints, airline-specific parameters, and multi-step workflows spanning booking β ticketing β modification β refund. Handling this directly requires extensive domain knowledge.
PolarHub MCP Client hides this complexity behind natural language conversation.
| Traditional Approach | This Project |
|---|---|
| Learn NDC API specs β implement request/response per endpoint | "Search flights from Seoul to Singapore on April 15" |
| Manually manage booking state machine (HELD β TICKETED β CANCELLED) | AI manages workflows automatically |
| Write airline-specific exception handling code | MCP server abstracts airline patterns |
What You Get
- Ready-to-use airline booking AI chat UI β Search/book 40+ airlines right after setup
- MCP protocol reference implementation β Working code for LLM β MCP server integration
- Multi-LLM support β Choose from OpenAI, Gemini, or Bedrock with the same interface
- Production-grade session management β State tracking for multi-step booking workflows
Key Concepts
Two concepts to understand before diving in.
NDC (New Distribution Capability)
An airline distribution standard defined by IATA. It's an XML/JSON-based API specification that enables airlines to directly offer pricing, seats, and ancillary services. PolarHub provides a unified NDC API across 40+ airlines.
MCP (Model Context Protocol)
A standard protocol proposed by Anthropic for connecting LLMs to external tools. When an LLM decides "which Tool to call," the MCP client executes that Tool on the MCP server. This project serves as the MCP client.
LLM: "I should call flight_search"
β MCP Client (this project): Request flight_search Tool execution
β MCP Server: Call PolarHub NDC API β Return results
What Is This Project?
PolarHub MCP Client is a web client application that connects to Model Context Protocol (MCP)-based airline booking servers.
This client does not work without the MCP server. All functionality is performed by calling Tools provided by the MCP server.
This README is written for external OTA developers who want to run PolarHub MCP Client or implement the same interaction contract in their own frontend/backend. It covers not only the demo UI, but also the WebSocket message format, session handoff, and credential pass-through behavior.
Features
Prime Booking (New Reservations)
| Feature | Description | MCP Tool |
|---|---|---|
| Flight Search | Search by origin/destination/date | flight_search |
| Price Confirmation | Select offer and confirm pricing | flight_price |
| Seat Selection | Choose seat from seat map | select_seat |
| Add Services | Select baggage, meals, etc. | select_service |
| Complete Booking | Enter passenger info and create PNR | flight_book |
"Seoul to Singapore, April 15, 1 adult"
β flight_search β flight_price β select_seat β flight_book
Post-Booking (Reservation Management)
| Feature | Description | MCP Tool |
|---|---|---|
| Order Retrieve | View booking details by PNR/order ID | order_retrieve |
| Seat Change | Change seat after booking | seat_availability β order_prepare β order_confirm |
| Add Services | Add ancillaries after booking | service_list β order_prepare β order_confirm |
| Itinerary Change | Change to different date/flight | order_reshop β order_prepare β order_confirm |
| Ticketing | Convert HELD to TICKETED | order_prepare β order_confirm |
| Refund | Cancel and refund booking | order_reshop β order_cancel |
| PNR Split | Separate specific passenger from multi-pax booking | order_prepare |
| Passenger Update | Modify email, phone, passport, etc. | order_prepare |
"Change seat to 12A for order ORD_12345"
β order_retrieve β seat_availability β order_prepare β (confirm) β order_confirm
How It Works
When a user sends a message, the server runs an agent loop: the LLM decides which tools to call, the MCP client executes them, and the results feed back into the same conversation until the LLM produces a final text response. A single user message can trigger a chain of tool calls (e.g. flight_search β flight_price β flight_book) without any extra round-trips to the user. Gemini and AWS Bedrock are both supported via a provider-agnostic adapter pattern (AgentLoopAdapter); OpenAI agent-loop support is a follow-up.
Step 1: Dynamic Tool Discovery
At startup the MCP client fetches the tool catalog from the MCP server and converts each tool's JSON Schema into a Gemini FunctionDeclaration. Tool names, descriptions, and parameter schemas are never hardcoded β when the server adds a tool, it's available in the next chat with no client changes.
Step 2: Agent Loop
Each user message drives the AgentLoopRunner (src/orchestrator/agentLoop.ts). The runner is provider-agnostic β it talks to an AgentLoopAdapter (src/llm/agentLoopAdapter.ts) that each LLM provider implements:
- GeminiChatStepAdapter wraps Gemini's
generateContent+ function calling, preservingthoughtSignaturefields required by thinking models. - BedrockChatStepAdapter wraps AWS Bedrock Converse API, handling
toolUse/toolResultpairing viatoolUseId.
Both share the same loop behavior:
loop (max 5 iterations):
1. call Gemini with the full conversation + tool declarations
2. if Gemini returns a functionCall:
β emit tool_call_start (WebSocket)
β execute the tool via MCP client (90s timeout by default)
β emit tool_call_end
β append the functionResponse to history, continue the loop
3. if Gemini returns plain text:
β send assistant_message, loop is done
- Cancellable β when a user sends a new message mid-loop, the previous loop is pre-empted silently.
- Tool timeouts feed back to the model β a timed-out tool becomes a
functionResponsewithisError: true, so Gemini can retry with different arguments or explain the failure. - Gemini API errors terminate the loop and surface as a WebSocket
errorevent.
MCP Client β POST /mcp
Headers: X-PolarHub-Tenant-ID, X-PolarHub-API-Secret, ...
Body: { method: "tools/call", params: { name: "flight_search", arguments: {...} } }
Step 3: Session Short-Term Memory
Each provider has its own memory implementation behind a common ProviderMemory interface:
GeminiSessionMemory(src/orchestrator/sessionMemory.ts) β boundedContent[]; pruning preservesfunctionCall/functionResponsepairs; raw candidateContentis kept verbatim to retainthoughtSignature.BedrockSessionMemory(src/orchestrator/bedrockSessionMemory.ts) β boundedConverseMessage[]; trackspendingToolUseIdto pairtoolUsewithtoolResult; pruning preserves strict user/assistant alternation and tool pairs required by Bedrock.
Shared across providers (src/orchestrator/keyFacts.ts):
- Key facts extraction β every tool result is scanned for
sessionId,orderId,transactionId,offerId,refundQuoteId, etc. These are re-injected into the LLM's system prompt on the next step so the model uses real IDs instead of hallucinating. - Agent loop preamble β a shared system-prompt preamble instructs the model to chain tools until the request is fully satisfied.
- Idle eviction β sessions inactive for 30 minutes are cleared on a 5-minute sweep.
Architecture
Core Module Roles
| Module | File | Role |
|---|---|---|
| Orchestrator | src/orchestrator/index.ts | Per-session state, idle eviction, dispatches each user message to an AgentLoopRunner |
| AgentLoopRunner | src/orchestrator/agentLoop.ts | Provider-agnostic MCP tool loop; cancellable, max-iteration guarded, per-tool timeout |
| AgentLoopAdapter | src/llm/agentLoopAdapter.ts | Contract each LLM provider implements so the loop doesn't need to know provider details |
| GeminiChatStepAdapter | src/llm/geminiAdapter.ts | Gemini implementation β Content[] history, thoughtSignature preservation |
| BedrockChatStepAdapter | src/llm/bedrockAdapter.ts | Bedrock Converse implementation β ConverseMessage[] history, toolUseId pairing |
| Session memories | src/orchestrator/sessionMemory.ts, bedrockSessionMemory.ts | Bounded per-provider history + key-facts extraction |
| MCP Client | src/mcp/client.ts | MCP server connection, tool calls (with timeout option), static header auth, reconnection |
| LLM Provider | src/llm/provider.ts | Unified interface for 3 LLM providers + dynamic prompt builder |
| WebSocket | src/server/websocket.ts | Client session management, real-time tool-event emission, metadata propagation |
Data Flow
- User β Natural language message (WebSocket)
- Orchestrator β Load / create
SessionMemory, cancel any prior loop, instantiateAgentLoopRunner - AgentLoopRunner β Call Gemini with Content[] history + tool declarations + key-facts hint
- Gemini β Either a
functionCallor a final text response - If functionCall β Execute on MCP server via Streamable HTTP β Append
functionResponsetoSessionMemoryβ loop back to step 3 - If text β Emit
assistant_message, loop ends - Frontend β Render tool progress (
tool_call_start/tool_call_end) in real time, then display final text response
Design Principles
Key design decisions that help understand the codebase.
Dynamic Tool Discovery β No Hardcoded Tool Integration
// src/orchestrator/index.ts
const tools = await this.mcpClient.getTools(); // Fetch tool list from MCP server
const prompt = buildIntentParserPrompt(tools); // Auto-generate LLM prompt from tool descriptions
Tool names, parameters, and descriptions all come from the MCP server. When new Tools are added or descriptions change, no client modifications are needed.
Two-Phase Post-Booking β Query β Preview β Execute
Booking changes always go through two phases to prevent mistakes:
Query (order_reshop) β "The change will cost an additional $50"
Preview (order_prepare) β "Proceed with this change?" [Confirm/Cancel]
Execute (order_confirm) β "Change complete!"
Agent Loop β Multi-Tool Chaining Per Message (provider-agnostic)
AgentLoopRunner is provider-neutral β it works with any AgentLoopAdapter. Currently Gemini and AWS Bedrock (Converse API) ship with adapters. OpenAI still runs the legacy processAction path and will gain an adapter in a follow-up PR.
A single user message can trigger a chain of tool calls:
"Book the cheapest Incheon β Singapore flight on 5/15 for 1 adult"
β flight_search (step 1)
β flight_price (step 2)
β passenger_form (step 3)
β flight_book (step 4)
β final text response (step 5)
Tunable via environment variables:
MCP_MAX_ITERATIONS(default5) β safety cap against runaway loops.MCP_TOOL_TIMEOUT_MS(default90000) β forwarded to the MCP SDK and enforced viaPromise.raceso our deadline and the SDK request share the same limit.
Tool errors (timeout, isError: true, unknown tool name) are returned to Gemini as functionResponse content β the model can retry with different arguments or fall back to a plain text answer. Only Gemini API errors terminate the loop and surface as a WebSocket error event.
Stateful Session β Short-Term Memory Per Connection
SessionMemory holds per-session state for the agent loop:
{
contents: Content[], // Gemini Content[] β bounded, safely pruned
keyFacts: {
mcpSessionId?, postBookingTransactionId?, postBookingOrderId?,
lastToolCalled?, lastToolKeyIds?, // offerId / responseId / refundQuoteId / ...
},
lastAccessedAt,
}
- Bounded history β default 40 entries; pruning keeps
functionCall/functionResponsepairs intact to satisfy Gemini's invariants. - Key facts auto-injected β every
functionResponseis scanned for IDs. On the next stepgetKeyFactsHint()appends them to Gemini'ssystemInstructionso the model never has to guess an ID it already saw. - Idle eviction β 30-minute TTL, swept every 5 minutes.
thoughtSignaturepreservation β rawcandidates[0].contentis stored verbatim viaappendModelContent(), required bygemini-3-flash-previewand other thinking models.- Legacy
ConversationContext(mcpSessionId,postBookingTransactionId, β¦) is still maintained for theprocessActionpath that bypasses the agent loop.
WebSocket Protocol
Real-time communication specification between frontend and backend.
Client β Server
// Natural language message
{ type: "user_message", id: "uuid", content: "Search flights", timestamp: 1234567890 }
// Recommended: action message (used by the bundled frontend)
{ type: "action", id: "uuid", action: "SelectOffer", payload: { sessionId: "sess_xxx", offerIndex: 1 }, transactionId: "client_tx_1" }
// Recommended: completed forms are also sent as action messages
{ type: "action", id: "uuid", action: "SubmitPassengers", payload: { sessionId: "sess_xxx", passengers: [...], contact: {...} }, transactionId: "client_tx_1" }
// Legacy compatibility: form_submit is still accepted by the server
{ type: "form_submit", id: "uuid", formType: "passenger", data: { passengers: [...] }, transactionId: "client_tx_1" }
Server β Client
// Connection established
{ type: "connection", status: "connected", sessionId: "sess_abc" }
// AI response (text + structured payload)
{ type: "assistant_message", id: "uuid", content: "Here are the results.", toolResult: {...}, metadata: {...} }
// Tool call start/end (for loading indicators)
{ type: "tool_call_start", id: "uuid", toolName: "flight_search" }
{ type: "tool_call_end", id: "uuid", toolName: "flight_search", success: true }
// Error
{ type: "error", id: "uuid", code: "MCP_ERROR", message: "Server connection failed" }
Integration notes:
transactionIdin the WebSocket payload is a client-side conversation correlation ID. It is separate from the MCP post-bookingtransactionId.- The bundled frontend sends most user interactions as
actionmessages. If you build your own client, this is the recommended path. assistant_message.metadatamay include follow-up identifiers such assessionId,orderId,transactionId, andrefundQuoteId, so you should persist it per conversation session.assistant_message.toolResultis the raw MCPstructuredContent, which is useful for custom UI rendering and debugging.
Quick Start
Prerequisites
- Node.js >= 18
- PolarHub MCP Server Endpoint and credentials
- LLM API Key (choose one)
- OpenAI API Key (
sk-...) - Google Gemini API Key
- Bedrock API Key (
BEDROCK_API_KEY, Bearer token auth)
- OpenAI API Key (
Installation & Run
# 1. Install dependencies
npm install
# 2. Configure environment
cp .env.example .env
Edit the .env file:
# LLM provider (choose: openai / gemini / bedrock)
LLM_PROVIDER=gemini
GEMINI_API_KEY=your-gemini-api-key-here
# MCP server endpoint
MCP_SERVER_URL=https://mcp.sandbox.halo-platform.net/mcp
# PolarHub credentials (required β request from admin)
POLARHUB_TENANT_ID=your-tenant-id
POLARHUB_API_SECRET=your-base64-secret
# 3. Build
npm run build
# 4. Run in development mode
npm run dev
Open http://localhost:3000 in your browser
Health Check
curl http://localhost:3000/health
# { "status": "ok", "mode": "development" }
Note: The
.envfile is included in.gitignoreand will not be committed. Never push your.envfile to Git.
OTA Integration Checklist
- Keep one WebSocket connection per browser/app conversation.
- Persist
assistant_message.metadataand reuse it for follow-up actions in the same conversation. - Send user interactions and completed form events as
actionmessages whenever possible. - Never place PolarHub secrets in the browser; inject them only through this server's environment variables.
Environment Variables
Required
| Variable | Description | Example |
|---|---|---|
LLM_PROVIDER | LLM provider | openai, gemini, bedrock |
MCP_SERVER_URL | MCP server endpoint | https://mcp.sandbox.halo-platform.net/mcp |
POLARHUB_TENANT_ID | Agency/Tenant ID | (request from admin) |
POLARHUB_API_SECRET | API secret (Base64) | (request from admin) |
Per LLM Provider
| Variable | Provider | Description |
|---|---|---|
OPENAI_API_KEY | OpenAI | API key (sk-...) |
OPENAI_MODEL | OpenAI | Model name (default: gpt-4-turbo-preview) |
GEMINI_API_KEY | Gemini | API key |
GEMINI_MODEL | Gemini | Model name (gemini-2.0-flash, gemini-3-flash-preview, etc.) |
BEDROCK_API_KEY | Bedrock | Bearer token for the Bedrock Converse API |
AWS_REGION | Bedrock | AWS region. Must match the inference profile's region family β e.g. apac.* profiles need an Asia Pacific region (ap-northeast-2, ap-northeast-1, ap-southeast-1, β¦); us.* profiles need a US region. Default: us-east-1. |
BEDROCK_MODEL | Bedrock | Inference profile ID (recommended) or model ID. Most newer Claude models on Bedrock require an inference profile β e.g. apac.anthropic.claude-sonnet-4-20250514-v1:0 or us.anthropic.claude-sonnet-4-5-20250929-v1:0. Using a bare model ID typically produces model identifier is invalid or on-demand throughput isn't supported. |
Note:
.env.exampleusesGEMINI_MODEL=gemini-2.0-flashas the sample value, while the runtime fallback in code isgemini-3-flash-previewif the variable is omitted entirely.
Optional
| Variable | Default | Description |
|---|---|---|
PORT | 3000 | Server port |
DEBUG_PROMPTS | false | Print LLM prompts to console |
MCP_TOOL_TIMEOUT_MS | 90000 | Per-tool-call timeout (ms). Applied to both our Promise.race guard and the MCP SDK request. Raise it for slow GDS/NDC endpoints. |
MCP_MAX_ITERATIONS | 5 | Max agent-loop iterations per user message. Guards against runaway tool chains. |
DEFAULT_LOCALE | en | Server default locale if the browser language and URL parameter are both absent. |
MCP Server Authentication
This client passes PolarHub credentials as static HTTP headers to the MCP server. The browser never needs direct access to PolarHub secrets; the Node server reads them from environment variables and forwards them server-to-server.
X-PolarHub-Tenant-ID: {tenantId}
X-PolarHub-API-Secret: {base64_secret}
Onboarding & Credentials
You need a PolarHub NDC platform account to run this client.
How to get access
Send an onboarding request to contact@halosync.kr with your company name and use case. The team will issue your Sandbox credentials.
Automated self-service onboarding is currently in progress.
Required credentials
| Required | Description | How to Get |
|---|---|---|
POLARHUB_TENANT_ID | Agency identifier | Issued after onboarding |
POLARHUB_API_SECRET | API secret (Base64) | Issued after onboarding |
The Sandbox environment is for testing only β no real flight bookings are made.
Project Structure
polarhub-mcp-client/
βββ src/ # Bridge server (Node.js + TypeScript)
β βββ index.ts # Entry point β server startup, MCP connection (5 retries)
β βββ config/ # Environment variable parsing + validation
β βββ llm/ # LLM provider abstraction
β β βββ provider.ts # Common interface + dynamic prompt builder
β β βββ openai.ts # OpenAI (Function Calling)
β β βββ gemini.ts # Google Gemini (schema sanitization included)
β β βββ bedrock.ts # AWS Bedrock (Bearer Token, direct HTTP calls)
β βββ mcp/
β β βββ client.ts # MCP client β Streamable HTTP + static header auth + reconnection + timeoutMs option
β βββ llm/
β β βββ provider.ts # LLMProvider interface + dynamic prompt builder
β β βββ agentLoopAdapter.ts # Provider-agnostic adapter contract for the agent loop
β β βββ gemini.ts # Gemini provider (schema sanitization + chatStep + adapter factory)
β β βββ geminiAdapter.ts # GeminiChatStepAdapter
β β βββ bedrock.ts # Bedrock provider (Converse API + chatStep + adapter factory)
β β βββ bedrockAdapter.ts # BedrockChatStepAdapter
β β βββ openai.ts # OpenAI (legacy single-turn only for now)
β βββ orchestrator/
β β βββ index.ts # Per-session state, idle eviction, dispatch to AgentLoopRunner
β β βββ agentLoop.ts # Provider-agnostic agent loop (cancellable, max iterations, tool timeout)
β β βββ keyFacts.ts # Shared key-facts extraction + agent-loop system preamble
β β βββ sessionMemory.ts # GeminiSessionMemory β bounded Content[] + thoughtSignature preservation
β β βββ bedrockSessionMemory.ts # BedrockSessionMemory β ConverseMessage[] + toolUseId pairing
β βββ server/
β β βββ http-server.ts # Express (static files) + Vite (HMR, dev mode)
β β βββ websocket.ts # WebSocket session management + metadata propagation
β βββ shared/
β βββ types/messages.ts # ClientβServer message type definitions
βββ packages/
β βββ frontend/ # React web app
β β βββ src/
β β βββ components/
β β β βββ chat/ # ChatContainer, ChatInput, ChatMessage
β β β βββ layout/ # Header, Sidebar, MainLayout
β β βββ store/ # Zustand state management
β β βββ chatStore.ts # WebSocket connection + message state
β β βββ conversationStore.ts # Conversation history (localStorage persistence)
βββ package.json # npm workspaces root
βββ tsconfig.json
βββ .env.example # Environment variable template (dummy values)
βββ .gitignore # Includes .env β prevents secret commits
Build Order
frontend β src/ (backend TypeScript compilation)
npm run build handles this order automatically.
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | React 18, Vite, Tailwind CSS, Zustand |
| Backend | Node.js, Express, TypeScript |
| WebSocket | ws (real-time bidirectional communication) |
| MCP Client | @modelcontextprotocol/sdk (Streamable HTTP) |
| LLM | OpenAI GPT-4 / Google Gemini / AWS Bedrock |
| Styling | Halo Design System (halo-purple, halo-green tokens) |
Scripts
| Command | Description |
|---|---|
npm run dev | Development mode (tsx watch + Vite HMR) |
npm run build | Full build (frontend β bridge) |
npm start | Production mode |
npm run clean | Clean build artifacts |
Language Support (i18n)
The client supports English and Korean. The language is auto-detected from the browser and applied to both the UI and LLM responses.
How It Works
- Browser language (
navigator.language) is detected on page load - The locale is passed to the server via WebSocket
- System prompts and LLM responses adapt to the detected language
Switching to English
Option A β Browser language: Change your browser language to English in Chrome β Settings β Languages β move English to the top.
Option B β URL parameter: Append ?locale=en to the URL:
http://localhost:3000/?locale=en
Option C β Environment variable: Set the server default in .env:
DEFAULT_LOCALE=en
The priority is: URL parameter > Browser language >
DEFAULT_LOCALEenv var.
Note: The response language is determined by the locale setting, not the input language. If you type in Korean with locale=en, the AI will still respond in English (and vice versa).
Debugging
Check LLM Prompts
To inspect system prompts sent to the LLM:
DEBUG_PROMPTS=true npm run dev
Intent Parser / Result Summarizer prompts will be printed to the console.
Verify MCP Server Connection
# MCP server health check
curl http://localhost:8000/health
# { "status": "ok", "transport": "streamable-http" }
# This client health check
curl http://localhost:3000/health
# { "status": "ok", "mode": "development" }
Common Issues
| Symptom | Cause | Solution |
|---|---|---|
MCP connection failed repeating | MCP server not running or wrong URL | Check MCP_SERVER_URL, verify MCP server status |
LLM API key missing | Environment variable not set | Set the API key matching your LLM_PROVIDER in .env |
Authentication failed | Invalid credentials | Verify POLARHUB_TENANT_ID and POLARHUB_API_SECRET |
| WebSocket disconnection | Server restart or network issue | Refresh browser (auto-reconnect attempted) |
Bedrock The provided model identifier is invalid | AWS_REGION does not match the inference profile's region family | For apac.* profiles set AWS_REGION=ap-northeast-2 (or another AP region); for us.* profiles set a US region |
Bedrock on-demand throughput isn't supported | Using a bare model ID instead of an inference profile | Switch BEDROCK_MODEL to an inference-profile ID like apac.anthropic.claude-sonnet-4-20250514-v1:0 |
Agent loop not supported for LLM provider | LLM_PROVIDER=openai with the agent loop | Use gemini or bedrock β OpenAI adapter is a follow-up |
Demo Videos
Prime Booking β Flight Search β Booking Complete (SQ)
The full flow of searching flights with natural language, selecting an offer, entering passenger details, and completing the booking.
https://github.com/user-attachments/assets/ccadbd98-76dc-4066-ab69-0810439ad164
Post-Booking β Order Retrieve β Seat Change (EK)
Retrieving an existing booking, viewing the seat map, changing the seat, and re-verifying the order.
https://github.com/user-attachments/assets/3cb47076-d57a-4ce6-808f-83781ff2bf55
Usage Examples
Flight Search + Booking
User: Search flights from Seoul to Singapore, April 15, 1 adult
β AI displays available flight options with prices and schedules
User: "Select the 2nd offer"
β AI shows fare breakdown details
User: I'd like to select a seat too
β AI presents available seats
User: "Seat 12A please"
β AI requests passenger information
User: (provides passenger details)
β AI confirms booking complete with PNR
Reservation Management
User: Retrieve order ORD_12345
β AI shows booking status, itinerary, and passenger info
User: I want to change to seat 15C
β AI checks availability β shows price difference β confirms change
User: How much would a refund be for this booking?
β AI shows refund amount details
User: Proceed with the refund
β AI processes and confirms the refund
Supported Airlines
The MCP server supports the following airlines via the Sandbox PolarHub NDC API.
Verified airlines:
| Airline | Code | Prime Booking | Post-Booking |
|---|---|---|---|
| Singapore Airlines | SQ | O | O |
| Finnair | AY | O | O |
| Air France | AF | O | O |
| KLM | KL | O | O |
| Emirates | EK | O | O |
| Lufthansa | LH | O | - |
| Turkish Airlines | TK | O | O |
| Scoot | TR | O | O |
| Hawaiian Airlines | HA | O | O |
| Qatar Airways | QR | O | - |
| British Airways | BA | O | - |
License
MIT License β See LICENSE
