Overview
The NEMT MCP Service is a standalone, production-grade Model Context Protocol server in Go. It exposes NEMT (Non-Emergency Medical Transportation) trip booking capabilities as MCP tools, allowing AI agents to verify members, book trips, manage drivers, and track active trips through a standards-compliant interface.
What is MCP?
Section titled “What is MCP?”The Model Context Protocol is an open standard that enables AI models (Claude, GPT, custom agents) to interact with external services through a defined tool interface. The NEMT MCP Service implements the MCP spec with StreamableHTTP transport.
31 Tools
Section titled “31 Tools”The service exposes 31 tools organized into eight modules. The v2.0 audit remediation removed 3 tools whose responsibilities folded into others (get_draft_status, get_cancellation_reasons, create_standing_order), added 2 read companions (get_member_phone, get_member_addresses), introduced the INTENT contract for member contact mutations, and consolidated cancellation into a single-tool two-step pattern. Net effect: ~10-25 KB freed per booking session, parity with the source MCP server preserved, fewer round trips, and zero silent overwrites.
Verify Module (3 tools)
Section titled “Verify Module (3 tools)”- verify_member — Verify member identity, create session (response shrunk ~85-92% in v2.0; no more
recent_addresses/tokens_matched/booking_progress) - search_members — Search members by name/DOB/phone without a session (last_name → first_name → dob narrowing strategy)
- get_member_profile — Retrieve full member profile within an active session (no longer carries trip history — fetch on-demand via
get_active_trips)
Member Module (6 tools, v2.0)
Section titled “Member Module (6 tools, v2.0)”- get_member_email — List email addresses on file for the verified member
- get_member_phone — List phone numbers on file (NEW)
- get_member_addresses — List saved addresses with duplicate clustering (NEW)
- update_member_email — Add or replace a member email — INTENT-gated
- update_member_phone — Add or replace a member phone — INTENT-gated, TCPA-safe defaults
- update_member_address — Add a saved place — dedup + home-exclusivity guarded
Booking Module (4 tools)
Section titled “Booking Module (4 tools)”- set_booking_details — Set booking fields incrementally; a no-op call returns the draft status snapshot (replaces the removed
get_draft_status) - review_trip — Generate trip summary and TTS voice script for confirmation
- confirm_trip — Create the real trip OR a standing order (handles BOTH; folds in the removed
create_standing_order) - reset_booking — Clear current draft and start fresh
Address Module (3 tools)
Section titled “Address Module (3 tools)”- resolve_address — Validate + geocode (Google + HERE in parallel)
- find_place (v2.0) — Search facilities by name with Google Places Text Search + Details enrichment (top-3 results carry phone, hours, business status)
- get_location_info (v2.0) — Reverse geocode coordinates + return nearby places
Trip Module (10 tools)
Section titled “Trip Module (10 tools)”- get_member_drivers — List approved drivers for mileage reimbursement trips
- assign_driver — Assign a driver enrollment to the current booking
- get_active_trips — List active trips; per-field opt-in enrichment (
include_driver,include_vehicle,include_gps,include_eta) defaults OFF - get_trip_status (v2.0) — Detailed single-trip view with stop IDs + editable flag (uses
tripenums.StringToTripStatus) - edit_trip (v2.0) — Edit pickup/dropoff/times/notes; addresses are now geocoded before write
- activate_will_call — Activate will-call return leg for immediate pickup
- cancel_trip — Single-tool two-step: omit
reason→ list, passreason→ cancel (folds in the removedget_cancellation_reasons) - cancel_standing_order — Same single-tool two-step pattern as
cancel_trip - list_trip_providers (v2.0) — List TP candidates for a trip (10-min cache)
- assign_provider (v2.0) — Assign a TP from the cached candidate set
- get_standing_orders — List recurring trip orders for a member
Enrollment Module (2 tools, v2.0)
Section titled “Enrollment Module (2 tools, v2.0)”- enroll_driver – Enroll a driver for mileage reimbursement with age + license validation
- setup_payee – Configure direct-deposit or check payment (AES-GCM at rest, ABA mod-10 validation)
Planning Module (1 tool, v2.0)
Section titled “Planning Module (1 tool, v2.0)”- estimate_trip – All-in-one route + weather + optimal pickup time
Notification Module (1 tool, v2.0)
Section titled “Notification Module (1 tool, v2.0)”- send_confirmation – Email a trip or standing-order confirmation (HTML + PDFs)
Technology Stack
Section titled “Technology Stack”| Component | Technology |
|---|---|
| Language | Go 1.25+ |
| MCP SDK | modelcontextprotocol/go-sdk v1.4.1 |
| Database | Google Cloud Spanner (via nemt-objects) |
| Cache | Valkey (via tools/cache) |
| Geocoding | Google Maps API |
| Directions | Google Directions API |
| Places | Google Places Text Search |
| Weather | Open-Meteo |
| SendGrid v3 | |
| go-pdf/fpdf | |
| Trip Logic | nemt-trip-service, nemt-standing-order |
| Container | Distroless (gcr.io/distroless/static-debian12) |
Key Design Decisions
Section titled “Key Design Decisions”- Session-scoped drafts: Each
verify_membercall creates a fresh booking draft per session. No cross-session draft reuse. - Stateless transport:
StreamableHTTPOptions.Stateless = truemeans no in-memory session state – safe for multi-pod Cloud Run deployment. - Triple ownership validation: Every draft access checks SessionID + MemberID + OrgID.
- HIPAA audit logging: Every tool invocation is logged with tool_name, org_id, member_id, timestamp, and outcome. Write tools capture FIELD NAMES only — never values.
- PCI at rest: Enrollment account numbers and tax IDs are encrypted with AES-GCM; last-4 and a fingerprint are stored for display and idempotency.