Real-time railway PNR tracking is a practical use case for tool-enabled AI agents: a passenger asks, “What is the latest status of my PNR?” and the agent retrieves, validates, explains, and refreshes the result without forcing the user through a complex website. WebMCP can provide the browser-facing tool layer that makes this workflow discoverable and controllable, while a backend service handles authentication, API access, caching, rate limits, and sensitive data protection.
This guide explains how to integrate WebMCP with AI agents for real-time railway PNR status tracking, including architecture, tool design, polling logic, security, error handling, and an implementation blueprint suitable for an India-focused travel or railway application.
What WebMCP Adds to an AI Agent
WebMCP can be treated as a structured interface between a web application and an AI agent. Instead of asking an agent to infer how to navigate a page, the application exposes explicit capabilities such as:
- Validate a 10-digit PNR number
- Fetch the current PNR status
- Retrieve train, boarding, destination, and passenger status details
- Refresh a previously queried PNR
- Explain abbreviations such as CNF, RAC, WL, GNWL, and RLWL
- Notify a user when a status changes
The exact WebMCP API and browser support may vary as the ecosystem evolves, so production systems should isolate WebMCP adapters from core business logic. The agent should call stable, typed tools; the backend should decide how data is obtained.
A useful design principle is: WebMCP exposes intent, not infrastructure. The AI agent should request get_pnr_status, while the server decides whether to use an authorized railway data provider, a cached response, or a refresh operation.
Reference Architecture for PNR Tracking
A production-grade integration normally contains five layers:
1. User interface – Chat, voice, or web form where the passenger provides a PNR.
2. AI agent – Interprets the request, selects a tool, asks for missing information, and explains results.
3. WebMCP tool layer – Publishes typed, permission-aware tools to the agent.
4. PNR service backend – Validates input, calls an approved data source, normalizes responses, and applies rate limits.
5. Railway data provider – An authorized API or licensed integration that returns current PNR information.
A typical request flow is:
Passenger → AI agent → WebMCP tool → PNR backend → authorized provider
↓
Passenger ← natural-language response ← normalized statusDo not make the browser call an unofficial endpoint directly. PNR data can include passenger-related details, and exposing provider credentials in JavaScript creates a serious security and abuse risk. Put provider calls behind a server-side service with logging, quotas, and secret management.
Define the PNR Tool Contract First
Before connecting WebMCP, define a strict tool schema. A good contract reduces hallucinations and prevents the agent from passing malformed identifiers to the backend.
Example conceptual schema:
{
"name": "get_pnr_status",
"description": "Retrieve the latest available railway PNR status for a valid 10-digit PNR.",
"inputSchema": {
"type": "object",
"properties": {
"pnr": {
"type": "string",
"pattern": "^[0-9]{10}$",
"description": "A 10-digit Indian railway PNR number"
},
"forceRefresh": {
"type": "boolean",
"default": false
}
},
"required": ["pnr"]
}
}The response should also be structured rather than returned as a block of scraped text:
{
"pnr": "1234567890",
"retrievedAt": "2026-09-03T10:15:00Z",
"source": "authorized-provider",
"train": {
"number": "12301",
"name": "Example Express",
"journeyDate": "2026-10-12"
},
"route": {
"boarding": "NDLS",
"destination": "HWH"
},
"overallStatus": "RAC",
"passengers": [
{
"serial": 1,
"bookingStatus": "WL 12",
"currentStatus": "RAC 45"
}
],
"refreshRecommendedAfterSeconds": 300
}Keep internal provider fields out of the public response. Return only the minimum data needed for the user’s request, and redact unnecessary personal information.
Register the WebMCP Tool in the Web Application
The integration pattern depends on the WebMCP implementation available in your target browsers and agent runtime. Conceptually, the website registers a tool with a name, description, input schema, and handler. The handler sends a request to your backend rather than querying railway systems from the client.
Illustrative browser-side pseudocode:
const pnrTool = {
name: "get_pnr_status",
description: "Get the latest available status for a 10-digit railway PNR.",
inputSchema: {
type: "object",
properties: {
pnr: { type: "string", pattern: "^[0-9]{10}$" },
forceRefresh: { type: "boolean" }
},
required: ["pnr"]
},
async execute({ pnr, forceRefresh = false }) {
const response = await fetch("/api/pnr/status", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": getCsrfToken()
},
credentials: "include",
body: JSON.stringify({ pnr, forceRefresh })
});
if (!response.ok) {
throw new Error("PNR status service is temporarily unavailable");
}
return response.json();
}
};
registerWebMCPTool(pnrTool);Treat registerWebMCPTool as an adapter placeholder until your chosen WebMCP SDK specifies the exact registration method. Keep the tool definition versioned so schema changes do not silently break agent behavior.
Build the Backend PNR Service
The backend should perform validation again even if the WebMCP schema validates the input. Client-side validation is for usability; server-side validation is for security and correctness.
Core backend responsibilities include:
- Confirming the PNR contains exactly 10 digits
- Rejecting unexpected fields and oversized request bodies
- Authenticating the user or applying anonymous quotas
- Checking cache freshness
- Calling an authorized railway data source
- Normalizing provider-specific status codes
- Recording retrieval timestamps
- Returning actionable errors without leaking credentials or provider internals
Illustrative server-side pseudocode:
app.post("/api/pnr/status", requireAuthOrQuota, async (req, res) => {
const { pnr, forceRefresh = false } = req.body;
if (!/^\d{10}$/.test(pnr)) {
return res.status(400).json({
code: "INVALID_PNR",
message: "Enter a valid 10-digit PNR number."
});
}
const cached = await cache.get(`pnr:${pnr}`);
const cacheAge = cached ? Date.now() - cached.retrievedAt : Infinity;
if (cached && !forceRefresh && cacheAge < 300000) {
return res.json({ ...cached, cached: true });
}
try {
const providerResult = await railwayProvider.getPnrStatus(pnr);
const normalized = normalizePnr(providerResult);
await cache.set(`pnr:${pnr}`, normalized, 300);
return res.json({ ...normalized, cached: false });
} catch (error) {
logger.error({ requestId: req.id, error: error.message }, "PNR lookup failed");
return res.status(503).json({
code: "PNR_UNAVAILABLE",
message: "The latest PNR status could not be retrieved. Please try again shortly."
});
}
});Never log complete PNR queries alongside identifiable user data unless there is a documented operational need and an appropriate retention policy.
Normalize Indian Railway Status Codes
Different providers may return inconsistent labels. Your normalization layer should map them into stable categories while preserving the original value for audit or advanced users.
Useful categories include:
- CNF – Confirmed
- RAC – Reservation Against Cancellation
- WL – Waitlisted
- CAN – Cancelled
- REGRET – No more booking permitted or availability not offered
- NOSB – No seat or berth information, depending on provider context
- REL – Released or related provider-specific state
Waitlist types can matter to users. Examples include GNWL, RLWL, PQWL, RLGN, and TQWL. Do not promise confirmation based only on historical patterns. The agent should state the current returned status and clearly label any prediction as uncertain—or avoid prediction entirely.
A response should distinguish:
- Booking status at the time of reservation
- Current status after charting or updates
- Coach and berth, if assigned
- Chart preparation information, if supplied by the provider
- The timestamp and source of the lookup
Add Real-Time Refresh Without Overloading APIs
“Real-time” in PNR tracking usually means the freshest available provider response, not a permanent streaming connection. Railway status changes are event-driven and provider availability may be limited, so use controlled polling.
Recommended approach:
- Return cached data when it is only a few minutes old.
- Offer a
forceRefreshaction with stricter quotas. - Poll more frequently near the journey date only when justified.
- Stop polling after a terminal state such as confirmed, cancelled, or journey completion.
- Use exponential backoff after timeouts or rate-limit responses.
- Include
retrievedAtin every result.
Example refresh policy:
First request: provider lookup
0–5 minutes: serve cache unless user explicitly refreshes
After 5 minutes: permit a fresh lookup subject to quota
Repeated failures: 30s, 60s, 120s backoff
Terminal journey state: stop automatic pollingFor notifications, store a hash of the normalized status and notify only when the hash changes. Require user consent, provide unsubscribe controls, and avoid sending sensitive PNR information in notification previews.
Agent Instructions and Conversation Design
The AI agent needs explicit behavioral rules. Without them, it may invent status meanings, claim that a lookup is live when it used cached data, or ask for unnecessary personal details.
Recommended system instructions include:
- Ask for the PNR when it is missing.
- Validate that it has 10 digits before calling the tool.
- Call
get_pnr_statusrather than browsing arbitrary pages. - Report the retrieval time and whether the result was cached.
- Never invent train details, coach numbers, berth numbers, or confirmation probabilities.
- Explain railway abbreviations in plain language.
- If the provider is unavailable, say so and suggest retrying later.
- Do not request passwords, OTPs, card details, or unrelated identity data.
A strong response might be:
> Your PNR was last checked at 10:15 AM IST. Passenger 1 is currently RAC 45, previously WL 12. The train is scheduled from NDLS to HWH on 12 October. This is the latest available provider response; status can change before chart preparation.
This format is concise, transparent, and useful without overstating certainty.
Security and Privacy Requirements
PNR tracking touches travel data and should be designed as a privacy-sensitive feature. Apply the following controls:
- Use HTTPS for every client-server request.
- Keep provider API keys in a server-side secret manager.
- Apply per-IP, per-user, and per-PNR rate limits.
- Use CSRF protection for cookie-authenticated browser sessions.
- Validate WebMCP tool origin and permissions where supported.
- Restrict CORS to trusted application origins.
- Encrypt stored subscriptions and notification targets.
- Set short retention periods for lookup logs.
- Redact PNRs in application logs, for example
12******90. - Avoid exposing passenger names or personal fields unless essential.
- Provide deletion and notification opt-out controls.
For Indian deployments, document data handling, vendor contracts, access controls, and breach procedures in line with applicable privacy obligations, including the Digital Personal Data Protection framework and contractual requirements from data providers.
Testing the Integration
Test the complete tool chain, not only the happy path. Your test plan should cover:
- Valid 10-digit PNR
- Nine-digit, eleven-digit, alphabetic, and whitespace-heavy input
- Empty or missing tool arguments
- Provider timeout and HTTP 5xx errors
- Provider rate limiting
- Malformed provider JSON
- Unknown status codes
- Cached versus forced refresh responses
- Multiple passengers with mixed statuses
- Cancellation and terminal states
- Unauthorized WebMCP tool invocation
- Prompt injection attempts in page content or tool results
Use contract tests to ensure the WebMCP schema, backend request, normalized response, and agent rendering remain compatible. Also test with real network latency and mobile devices common in India; a PNR assistant that works only on a fast desktop connection is not production-ready.
Common Integration Mistakes
Calling unofficial railway endpoints from the browser
This exposes credentials, increases scraping risk, and makes availability unpredictable. Use an authorized provider through your backend.
Treating cached results as live
Always show retrievedAt and a freshness indicator. “Real-time” should never mean “possibly stale without disclosure.”
Letting the model interpret raw provider text
Normalize status values in code first. The model should explain structured data, not guess what an unfamiliar code means.
Polling too aggressively
A five-second loop for every open chat can trigger quotas and degrade service. Use cache windows, backoff, and user-triggered refresh.
Returning sensitive fields by default
Minimize the response. Ask for consent before adding subscriptions or notifications, and do not expose personal details unnecessarily.
Recommended Production Checklist
Before launch, confirm that you have:
- A documented WebMCP tool schema and versioning policy
- A server-side, authorized railway data integration
- Input validation at both client and server layers
- Status normalization with unknown-code handling
- Cache, refresh, timeout, and backoff policies
- Rate limiting and abuse monitoring
- Privacy-safe logging and retention controls
- Clear cached/live timestamps in the UI
- Agent instructions that prohibit fabrication
- Tests for provider failures and prompt injection
- Consent-based notifications with unsubscribe support
- Observability for latency, error rates, cache hits, and provider quotas
FAQ: WebMCP and Railway PNR Tracking
Can WebMCP fetch Indian railway PNR data by itself?
No. WebMCP is an interface for exposing web capabilities to an agent. You still need a reliable, authorized backend data source and a secure server-side integration.
How often should a PNR be refreshed?
A five-minute cache window is a reasonable starting point, but the correct interval depends on provider limits, journey timing, and user expectations. Always offer an explicit refresh option with throttling.
Should an AI agent predict whether a waitlisted ticket will confirm?
It should not present a prediction as fact. Unless your product has a separately validated forecasting model, report the current booking and current status with the retrieval timestamp.
Is a PNR number personal data?
It can be sensitive travel-related information, especially when combined with passenger or itinerary details. Minimize collection, protect access, and define retention and deletion policies.
What should happen when the railway provider is unavailable?
Return a clear temporary-unavailability message, preserve the last known result only if it is visibly labelled with its timestamp, and provide a safe retry path.
Apply for AI Grants India
Building an AI-native railway, travel, or public-service product in India? Apply to AI Grants India for support, visibility, and opportunities to develop responsible, high-impact AI solutions.