AI agents often need structured, current information from websites that were designed for human browsing. Indian Railway PNR status is a practical example: passengers may encounter different railway information pages, regional portals, mobile layouts, and intermittent responses. A WebMCP can expose a controlled, machine-readable interface that helps agents discover the right page, submit a PNR query, normalize results, and explain uncertainty.
The goal is not to build an unrestricted scraper. A reliable implementation should respect Indian Railways and third-party website terms, robots directives, rate limits, authentication boundaries, and passenger privacy. The safest design uses officially permitted data sources wherever available, keeps PNRs out of logs, and returns only the minimum information required by the user.
What Is a WebMCP for AI Agents?
A WebMCP is a web-facing Model Context Protocol integration that exposes tools, resources, or prompts to an AI agent in a predictable format. The agent does not need to understand every HTML layout. Instead, it invokes a typed operation such as get_pnr_status, and the WebMCP service handles source selection, request validation, extraction, normalization, and error reporting.
For a railway PNR use case, the interface might accept:
- A 10-digit PNR supplied by the user.
- An optional preferred source or language.
- A freshness requirement, such as “current status only.”
- A consent or purpose flag if your product requires one.
It should return structured fields including train number, train name when available, boarding and destination stations, journey date, booking status, current status, charting information, last-updated time, source attribution, and a confidence or verification state.
MCP is an interface standard, not a permission to bypass anti-bot controls or access restricted data. Your WebMCP must operate only against sources you are authorized to use.
Define the PNR Data Contract First
Before writing a browser adapter, create a canonical schema. This prevents each railway page from leaking its own labels and formatting into the agent experience.
A practical TypeScript model is:
export type PnrStatus = {
pnr: string; // redact before persistence or logging
source: {
id: string;
url: string;
retrievedAt: string;
};
journey?: {
trainNumber?: string;
trainName?: string;
from?: Station;
to?: Station;
journeyDate?: string; // ISO-8601 date
boardingPoint?: Station;
};
passengers: PassengerStatus[];
chart?: {
prepared?: boolean;
text?: string;
};
overallStatus?: string;
verification: {
state: "verified" | "partial" | "failed";
warnings: string[];
};
};
type Station = {
code?: string;
name?: string;
};
type PassengerStatus = {
serial?: number;
bookingStatus?: string;
currentStatus?: string;
coach?: string;
berth?: string;
};Keep raw HTML out of the normal agent response. If debugging is necessary, store an encrypted, short-lived artifact behind access control and never include full pages in model context. Mark every field as optional because pages may omit chart status, coach data, or station codes.
Use ISO-8601 dates internally, while preserving the source’s displayed date in a separate diagnostic field if needed. Indian railway pages may use date formats such as DD-MM-YYYY; convert them only after validating the day, month, and year.
Architecture for Multiple Indian Railway Pages
A maintainable WebMCP normally has six layers:
1. MCP server — publishes tools and validates input and output.
2. Orchestrator — selects an authorized source and applies retry policy.
3. Source adapters — one adapter per permitted page or API.
4. Extraction engine — parses structured data, DOM fields, or rendered content.
5. Normalizer and validator — converts variants into the canonical schema.
6. Observability and privacy layer — records health metrics without exposing PNRs.
Do not put source-specific selectors directly in the MCP tool handler. An adapter interface keeps the system testable:
interface PnrSourceAdapter {
id: string;
supports(input: PnrQuery): boolean;
fetch(input: PnrQuery, signal: AbortSignal): Promise<SourceResult>;
normalize(result: SourceResult): PnrStatus;
}The orchestrator can try a primary source, then a separately authorized fallback. A fallback should not silently combine contradictory records. Return the source used and clearly label disagreements.
Build a Strict WebMCP Tool
Use a schema library such as Zod or JSON Schema to reject malformed input before any outbound request. A PNR should be exactly 10 numeric digits unless the authorized source documents another format.
const PnrQuery = z.object({
pnr: z.string().regex(/^\d{10}$/, "PNR must contain 10 digits"),
source: z.string().optional(),
locale: z.enum(["en", "hi"]).default("en")
});Expose a narrow tool description. For example:
{
"name": "get_indian_railway_pnr_status",
"description": "Retrieve current PNR status from an authorized railway information source.",
"inputSchema": {
"type": "object",
"required": ["pnr"],
"properties": {
"pnr": { "type": "string", "pattern": "^[0-9]{10}$" },
"source": { "type": "string" },
"locale": { "enum": ["en", "hi"] }
}
}
}The tool response should be compact and explicit about uncertainty:
{
"verification": {
"state": "verified",
"warnings": []
},
"overallStatus": "Confirmed/RAC",
"passengers": [
{
"serial": 1,
"bookingStatus": "WL 12",
"currentStatus": "RAC 45"
}
],
"source": {
"id": "authorized-source-1",
"retrievedAt": "2026-09-03T10:15:00Z"
}
}Never instruct an agent to infer confirmation from a missing value. Unknown, unavailable, and failed extraction are different states.
Extract Data Reliably from Different Page Layouts
If a permitted source offers JSON, XML, or a documented API, prefer it over browser automation. Structured data is more stable, faster, and easier to validate. If only a human-facing page is available and its use is permitted, create a dedicated adapter with the following extraction order:
1. Documented API or embedded JSON.
2. Semantic HTML fields, labels, tables, and data-* attributes.
3. JSON-LD only when its meaning matches the visible result.
4. Rendered DOM extraction as a last resort.
Avoid relying only on CSS classes such as .status-box, because redesigns frequently change class names. Anchor extraction to labels, table headers, accessible names, and stable form semantics. Capture the source URL and retrieval timestamp for every successful result.
For browser-based adapters, use a short timeout, a bounded number of retries, and a per-domain concurrency limit. Do not attempt to defeat CAPTCHA, fingerprinting, login controls, or rate limits. If a page requires an interactive challenge, return verification.state = "failed" and direct the user to the authorized official channel.
Normalization Rules for Indian Railway Statuses
Status strings may include abbreviations, spacing differences, coach and berth details, or multiple passenger rows. Preserve the original status while adding normalized categories.
A useful mapping layer can classify values into categories such as:
confirmedracwaitlistedcancellednot_availableunknown
Do not collapse detailed values. For example, WL 12, RAC 45, and CNF S4 32 carry different operational meaning. Store the raw display value and parse coach or berth only when the pattern is unambiguous.
When an input includes multiple passengers, maintain passenger serial numbers and never reorder rows unless the source explicitly does so. If current and booking status are both present, preserve both. A ticket can move from waitlisted to RAC or confirmed, and the agent should not present only one field as if it were historical truth.
Source Selection and Fallbacks
Multiple pages do not necessarily provide independent confirmation. They may mirror the same upstream railway data, cache results, or update at different times. Treat source diversity as a reliability problem, not merely a scraping problem.
Implement source selection using:
- Authorized-domain allowlists.
- Source health and recent success rate.
- Response freshness.
- Language or regional requirements.
- Explicit user preference when supported.
- Cost and latency budgets.
If two sources disagree, return both timestamps and state that the result requires verification. Never choose the “more favorable” status. A response such as “Sources differ; check the official railway channel before travel” is safer than false certainty.
Privacy and Security for PNR Queries
A PNR is sensitive travel information. It can expose journey dates, stations, passenger status, and potentially personal details. Apply data minimization from the first request.
Recommended controls include:
- Do not log raw PNRs; use a keyed hash or last-two-digit redaction for correlation.
- Disable request-body logging at API gateways and application middleware.
- Encrypt data in transit and at rest.
- Avoid persistent storage unless it is necessary and consented to.
- Apply short TTLs to caches, and consider not caching at all.
- Remove PNRs from prompts, traces, analytics events, and error messages.
- Enforce authentication and per-user rate limits for public deployments.
- Return only fields required by the requesting product.
- Define deletion and incident-response procedures.
For Indian users, review the Digital Personal Data Protection Act, 2023 and applicable contractual obligations. If your service processes data outside India, document transfer, vendor, retention, and access-control decisions. Obtain legal advice for a production service handling passenger information at scale.
Reliability, Validation, and Error Handling
A WebMCP should distinguish transport, source, parsing, and business errors:
INVALID_PNR: input failed validation.SOURCE_UNAVAILABLE: timeout, DNS, or upstream failure.ACCESS_NOT_PERMITTED: source policy or authorization prevents retrieval.CHALLENGE_REQUIRED: CAPTCHA or human verification encountered.PARSE_FAILED: page returned but the expected schema was not found.CONFLICTING_RESULTS: authorized sources disagree.NO_RESULT: valid request but no usable status returned.
Use a circuit breaker for repeatedly failing sources. Set deadlines rather than allowing an agent request to hang. Validate invariants such as a 10-digit PNR, valid ISO dates, passenger serial ordering, and status values that do not contain suspicious markup.
Test with recorded, sanitized fixtures representing confirmed, RAC, waitlisted, cancelled, chart-prepared, multilingual, empty, and redesigned pages. Add contract tests for every adapter. Run canary checks against authorized test endpoints where available, but do not create unnecessary production traffic.
Useful metrics include success rate by source, p95 latency, parse-failure rate, freshness age, fallback frequency, and disagreement rate. Exclude PNRs and personally identifying data from metric labels.
Agent Instructions and UX
Agents need guidance on when to call the tool and how to communicate results. Include instructions such as:
- Ask for a PNR only when the user wants a status lookup.
- Never guess a PNR from context.
- Explain that status can change before chart preparation or departure.
- State the retrieval time and source.
- Preserve booking status versus current status.
- Mention warnings and conflicts prominently.
- Never claim a ticket is confirmed when the verification state is partial or failed.
- Avoid repeating the complete PNR in the final response.
For Hindi and other Indian-language experiences, localize labels while keeping the canonical machine fields stable. Dates, station names, and status abbreviations should remain unambiguous. Provide a link or direction to the authorized official railway service when the WebMCP cannot verify a result.
Deployment Checklist
Before exposing the WebMCP to agents, verify:
- Every source is authorized and documented.
- The tool schema rejects invalid PNRs.
- No raw PNR appears in logs, traces, analytics, or exception messages.
- Requests have timeouts, rate limits, and concurrency caps.
- Adapters use stable semantic extraction rather than fragile selectors alone.
- Results include source, timestamp, verification state, and warnings.
- Conflicting or partial results are not silently normalized as confirmed.
- CAPTCHA and access-control barriers are respected.
- Cache retention and deletion policies are tested.
- Monitoring alerts on source changes and parse failures.
- Security review covers SSRF, outbound-domain allowlisting, injection, and secret management.
- Human-readable fallbacks are available for users.
SSRF protection is especially important if an agent can influence a source URL. Do not accept arbitrary URLs from the model. Resolve a source identifier against a server-side allowlist, block private IP ranges, and restrict redirects to approved domains.
Common Mistakes to Avoid
The most common failure is treating WebMCP as a generic web-scraping wrapper. That approach exposes unstable HTML, leaks private values into model context, and fails when a page changes. Other mistakes include using unofficial aggregators without permission, scraping around CAPTCHA, caching PNRs indefinitely, omitting retrieval timestamps, and returning a single status when passenger rows differ.
Another mistake is over-automating interpretation. A model can explain RAC or WL, but the extraction layer should provide the exact source text and normalized category. Keep deterministic facts in code and reserve language-model reasoning for presentation and user questions.
FAQ: WebMCP for Indian Railway PNR Status
Can an AI agent check any PNR through WebMCP?
Only if your application has a permitted, technically accessible source and follows its terms, privacy requirements, and rate limits. A WebMCP does not bypass authentication, CAPTCHA, or access restrictions.
Should I scrape several PNR pages at the same time?
Usually not by default. Use an authorized primary source, apply bounded fallbacks, and avoid duplicate traffic. Parallel requests are appropriate only when policy, capacity, and user value justify them.
What if two pages show different statuses?
Return the source timestamps and mark the response as conflicting or partial. Tell the user to verify through the official railway channel before making travel decisions.
Is it safe to store PNR results?
Minimize storage. If persistence is necessary, encrypt it, apply a short retention period, restrict access, and ensure raw PNRs are excluded from logs and analytics.
Which technology stack works well?
A TypeScript MCP server with Zod validation, Playwright only where authorized, adapter-specific tests, structured logging with redaction, and a Redis-like short-lived cache can work well. A documented API remains preferable to browser automation.
Apply for AI Grants India
Building a privacy-first WebMCP or another high-impact AI product for Indian users? Apply to AI Grants India to explore support, visibility, and opportunities for your startup.