prt-mcp
MCP server exposing Pittsburgh Regional Transit (PRT) TrueTime operations as typed tools for agent clients.
What this implements
- MCP
toolsfor core TrueTime queries: prt_get_routesprt_get_directionsprt_get_stopsprt_get_vehiclesprt_get_predictionsprt_get_patternsprt_get_service_bulletins- MCP
resources: prt://capabilities(discoverability for clients)- MCP
prompts: transit-arrival-workflow
Source references used for design
- MCP protocol/spec and server guidance:
- modelcontextprotocol.io docs + specification (JSON-RPC, capabilities, safety)
- MCP reference implementations:
modelcontextprotocol/servers(everything,fetch,filesystem)- MCP SDK patterns:
modelcontextprotocol/typescript-sdk- PRT data/API entry points:
- PRT Developer Resources
- TrueTime account/API key workflow
- TrueTime v3 endpoint behavior from public community codebases:
juctaposed/bustimePGHaidan2312/prt-api
Prerequisites
- Node 20+ (Node 22 recommended)
- A PRT TrueTime API key
Configuration
Copy env template:
cp .env.example .env
Set:
PRT_TRUETIME_API_KEY(required)- Optional tuning:
PRT_TRUETIME_BASE_URLPRT_REQUEST_TIMEOUT_MSPRT_MAX_RETRIESPRT_USER_AGENT- Optional HTTP mode security:
HOST(default:127.0.0.1)PORT(default:3000)MCP_ALLOWED_HOSTS(comma-separatedHostallowlist)MCP_ALLOWED_ORIGINS(comma-separated browserOriginallowlist)MCP_AUTH_TOKEN(Bearer token expected on/mcp)MCP_RATE_LIMIT_WINDOW_MSMCP_RATE_LIMIT_MAX
Run
npm install
npm run build
npm start
For local development:
npm run dev
For hosted HTTP mode (remote MCP endpoint):
npm run build
PORT=3000 HOST=0.0.0.0 MCP_AUTH_TOKEN=change-me npm run start:http
Health check:
curl http://localhost:3000/healthz
MCP endpoint:
POST /mcpGET /mcp(SSE stream)DELETE /mcp(close session if stateful)- Include
Authorization: Bearer <MCP_AUTH_TOKEN>if auth is enabled.
Alternate SSE endpoint for clients that expect /sse:
POST /sseGET /sse(SSE stream)DELETE /sse(close session if stateful)
Example MCP client config (stdio)
{
"mcpServers": {
"prt": {
"command": "node",
"args": ["/ABSOLUTE/PATH/prt-mcp/dist/index.js"],
"env": {
"PRT_TRUETIME_API_KEY": "YOUR_KEY"
}
}
}
}
Hosting options
You now have two transport modes:
- Local stdio (
npm start)
Best for Claude Desktop / local agent tools.
- Remote Streamable HTTP (
npm run start:http)
Best for hosting on Render/Railway/Fly.io/a VM.
Minimal production checklist:
- Set
PRT_TRUETIME_API_KEYin host environment variables. - Use Node 20+ runtime.
- Expose the
PORTyour host provides. - Keep at least one health check path (
/healthz). - Set
MCP_AUTH_TOKEN. - Set
MCP_ALLOWED_HOSTSandMCP_ALLOWED_ORIGINSfor your deployment. - Restrict inbound access (IP allowlist, auth gateway, or private network).
Example Render/Railway start command:
npm run build && npm run start:http
Docker
Build image:
docker build -t prt-mcp:latest .
Run container:
docker run --rm -p 3000:3000 -e PRT_TRUETIME_API_KEY=YOUR_KEY prt-mcp:latest
Implementation best practices applied
- Input validation with
zodon every tool schema - Fail-fast config checks (missing key)
- Retry + timeout behavior to handle unstable upstream API responses
- Uniform structured + text output for deterministic agent parsing
- Tool execution failures returned as MCP
isErrorresults - Tool annotations (
readOnlyHint,idempotentHint,openWorldHint) for client safety hints - HTTP hardening: auth token, origin checks, host allowlist support, and rate limiting
- Strict TypeScript + minimal surface area
- No secrets in source; env-only configuration
Notes
- TrueTime key acquisition is account-gated by PRT.
- API responses can differ by data feed (
Port Authority Bus,Light Rail). - Some endpoints require additional filters (
rt,stpid,pid).












