OPlatformStudentMCP

dev-zeromoblt/OPlatformStudentMCP

3.2

If you are the rightful owner of OPlatformStudentMCP and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.

The OPlatform Student MCP Server is a Model Context Protocol server designed to interface with the Student API, leveraging Redis FT.SEARCH capabilities for advanced querying, including geo-radius queries.

Tools
2
Resources
0
Prompts
0

OPlatform Student MCP Server

MCP (Model Context Protocol) server for querying the Student API with Redis FT.SEARCH capabilities, including geo-radius queries.

Features

  • Get Student by ID: Retrieve complete student details using their unique Zrn identifier
  • Advanced Search: Redis FT.SEARCH powered queries with support for:
    • Full-text search on names and addresses
    • Tag-based filtering (status, grade, subscription, gender, campus)
    • Geo-radius queries (find students within X km/mi of a location)
    • Complex boolean queries with AND/OR operators
    • Pagination support
  • Real-Time Location Tracking: MQTT integration for live student location updates
    • Subscribe to student location topics via AWS IoT Core
    • Automatic credential refresh and connection management
    • Cached location data for instant access
    • Handles retained messages for last known locations
  • Parent Location Tools: Answer common parent questions with contextual information:
    • Where is my child? - Get current location with trip status and context
    • What time will my child be back? - Get expected return time based on trip schedule
  • Trip Search: Query trips with Redis FT.SEARCH for detailed transportation information

Architecture

┌─────────────┐      ┌──────────────────┐      ┌─────────────────┐
│   Claude    │◄────►│  Student MCP     │◄────►│  Student API    │
│   Desktop   │ stdio│  Server          │ HTTP │  (Redis Search) │
└─────────────┘      └──────────────────┘      └─────────────────┘
                            │                          │
                            │                          │ IoT Creds
                            ▼                          ▼
                     ┌─────────────┐      ┌─────────────────┐
                     │ Smithy Gen  │      │   AWS IoT Core  │
                     │ TypeScript  │      │  (MQTT Broker)  │
                     │ Models      │      └─────────────────┘
                     └─────────────┘               ▲
                                                   │ MQTT
                                                   │
                                            ┌──────┴──────┐
                                            │  Mobile App │
                                            │  (Location) │
                                            └─────────────┘

Prerequisites

  • Node.js >= 18
  • TypeScript
  • Access to Student API endpoint
  • Valid JWT authentication token

Local Development Setup

1. Build Smithy Models and Install Dependencies

The project uses Smithy-generated TypeScript models packaged as a local tarball dependency.

Option A: Use the automated build script (Recommended)

cd /Users/zeroman/workplace/nowzone/OPlatformStudentMCP
./build-with-models.sh

This script will:

  1. Build the Smithy models from OPlatformModels
  2. Pack them as a tarball
  3. Copy the tarball to src/generated/
  4. Install all dependencies (including the packaged model)
  5. Build the TypeScript project

Option B: Manual steps

cd /Users/zeroman/workplace/nowzone/OPlatformStudentMCP

# Build and package Smithy models
npm run model

# Build the project
npm run build

3. Set Environment Variables

Create a .env file or export variables:

# Required
export STUDENT_API_ENDPOINT="https://api.zeromoblt.com"
export STUDENT_API_AUTH_TOKEN="your-jwt-token-here"

# MQTT Configuration (for real-time location tracking)
export IOT_ENDPOINT="your-iot-endpoint.iot.us-east-1.amazonaws.com"
export IOT_REGION="us-east-1"

# Optional MQTT settings
export MQTT_MAX_SUBSCRIPTIONS="100"
export MQTT_CREDENTIAL_REFRESH_INTERVAL="2580000"  # 43 minutes in ms

4. Test Locally with Claude Desktop

Create or update ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "student-search": {
      "command": "node",
      "args": ["/Users/zeroman/workplace/nowzone/OPlatformStudentMCP/dist/index.js"],
      "env": {
        "STUDENT_API_ENDPOINT": "https://api.zeromoblt.com",
        "STUDENT_API_AUTH_TOKEN": "your-jwt-token-here",
        "IOT_ENDPOINT": "your-iot-endpoint.iot.us-east-1.amazonaws.com",
        "IOT_REGION": "us-east-1"
      }
    }
  }
}

Restart Claude Desktop to load the MCP server.

Quick Token Update (macOS):

Update your token quickly when it expires:

# 1. Copy JWT token from browser to clipboard
# 2. Run the update script
npm run update-token
# or: yarn update-token

# 3. Restart Claude Desktop

This automatically updates your Claude Desktop config with the token from clipboard. See for details.

Usage Examples

Get Student by ID

"Get student with ID ZST12345"

The MCP server will call:

{
  "tool": "get_student",
  "arguments": {
    "id": "ZST12345"
  }
}

Parent Location Tools

The parent location tools use real-time MQTT location tracking to provide accurate, up-to-the-second information about student whereabouts.

Where is my child?

"Where is student ZST12345?"
"What is the current location of my child ZST12345?"

Example responses with location freshness information:

  • "Your child is at home (123 Main St, Hyderabad), waiting for pickup. The school bus is scheduled to arrive at 7:30 AM."
  • "Your child is currently on the way to school (location updated 30 seconds ago). They are expected to arrive at ABC Campus at 8:15 AM."
  • "Your child is at school (ABC Campus, 456 School Rd). They are scheduled for pickup at 3:00 PM."
  • "Your child is on the way home (location updated just now). They are expected to arrive at 4:30 PM."
  • "Your child arrived at school 15 minutes ago (ABC Campus, 456 School Rd)."
  • "Your child arrived home 5 minutes ago (123 Main St, Hyderabad)."

Location Context by Trip Status:

  • SCHEDULED/ACCEPTED + ONWARD: Student is at home, waiting for pickup
  • SCHEDULED/ACCEPTED + RETURN: Student is at campus, waiting for pickup
  • STARTED + ONWARD: Real-time location via MQTT - "on the way to school"
  • STARTED + RETURN: Real-time location via MQTT - "on the way home"
  • COMPLETED + ONWARD: Student is at campus (arrived at school)
  • COMPLETED + RETURN: Student is at home (arrived home)
  • No active trip: Last known location from MQTT (if available within 6 hours)

What time will my child be back?

"What time will student ZST12345 be back home?"
"When is my child returning home today?"

Example responses:

  • "Your child is expected to return home at 4:30 PM. The return trip from ABC Campus is scheduled to depart at 3:45 PM."
  • "Your child is currently on the way home and is expected to arrive at 4:25 PM (in approximately 15 minutes)."
  • "Your child is at school, but no return trip is scheduled yet for today."
  • "Your child is not scheduled for transportation today."

Location Fallback Behavior: When MQTT is unavailable or location data cannot be retrieved, the system uses a multi-tier fallback strategy:

  1. MQTT Real-Time Location (Primary): Live GPS coordinates from mobile app
  2. Task Location Fallback (Secondary): Actual GPS coordinates from route tracking tasks
  3. Generic Message (Final): Trip schedule and address information

This ensures parents always receive the most accurate location information available, even during MQTT outages.

Search Examples

Find all active students:

"Search for all active students"

→ Query: @status:{ACTIVE}

Find students by name:

"Find students named Basavaraju"

→ Query: @name:Basavaraju

Find students in a specific grade:

"Find all students in class 10 or class 11"

→ Query: @grade:{CLASS_10|CLASS_11}

Geo-radius search:

"Find students named Kumar within 5km of Empire State Building (40.748817, -73.985428)"

→ Query: @name:Kumar with lat=40.748817, lng=-73.985428, radius=5, unit=km

Complex queries:

"Find active class 12 students at campus ZCA00123"

→ Query: @status:{ACTIVE} @grade:{CLASS_12} @campusId:{ZCA00123}

Real-Time Location Tracking

The MCP server integrates with AWS IoT Core to provide real-time student location updates via MQTT. This enables accurate, up-to-the-second location information for parent queries.

Task Location Fallback

When MQTT real-time tracking is unavailable (e.g., during service outages), the system automatically falls back to Task Location Data to provide actual GPS coordinates instead of generic messages.

How It Works:

  1. Primary Source - MQTT: System first attempts to retrieve real-time location from MQTT
  2. Fallback Source - Task API: If MQTT is unavailable, system queries the Task API for route tracking data
  3. Coordinate Extraction: Extracts GPS coordinates from task transitionInfo (origin/destination)
  4. Smart Caching: Caches task location data for 30 seconds to minimize API calls
  5. Graceful Degradation: Falls back to generic message if both MQTT and Task data unavailable

Example Output with Task Fallback:

"Your child is on the way to school (last known location: 17.418806, 78.400413, 
updated 2 minutes ago). They are expected to arrive at ABC Campus at 8:15 AM."

Configuration:

No additional configuration required. Task location fallback is automatically enabled when:

  • Student has an active trip with status STARTED
  • MQTT location data is unavailable
  • Trip has associated tasks with valid location coordinates

Benefits:

  • Transparency: Parents see actual coordinates instead of "location unavailable"
  • Reliability: System continues to provide location data during MQTT outages
  • Accuracy: Task coordinates reflect actual route tracking data
  • Performance: 30-second cache reduces API load

Location Data Sources:

SourceFreshnessAccuracyUse Case
MQTT Real-Time< 30 secondsHigh (live GPS)Normal operation
Task Location1-5 minutesMedium (route tracking)MQTT outage fallback
Generic MessageN/ALow (scheduled only)No location data available

How It Works

  1. Mobile App Publishes: The student's mobile app publishes location updates to AWS IoT MQTT topics (ZR-{studentUsername})
  2. MCP Server Subscribes: When location is requested, the server subscribes to the student's topic
  3. Instant Updates: Location updates are received in real-time and cached in memory
  4. Retained Messages: Last known location is delivered immediately upon subscription
  5. Automatic Cleanup: Subscriptions are removed when no longer needed

MQTT Configuration

Required Environment Variables
# AWS IoT Core endpoint (get from AWS IoT Console)
IOT_ENDPOINT="a3example.iot.us-east-1.amazonaws.com"

# AWS region where IoT Core is deployed
IOT_REGION="us-east-1"
Optional Configuration
# Maximum concurrent MQTT subscriptions (default: 100)
MQTT_MAX_SUBSCRIPTIONS="100"

# Credential refresh interval in milliseconds (default: 43 minutes)
MQTT_CREDENTIAL_REFRESH_INTERVAL="2580000"

Credential Management

The MQTT service automatically manages AWS IoT credentials:

  • Automatic Refresh: Credentials are refreshed every 43 minutes (17-minute buffer before 60-minute expiry)
  • Secure Storage: Temporary credentials only, stored in memory
  • Retry Logic: Failed refreshes are retried with exponential backoff (2min, 5min, 10min)
  • Connection Re-establishment: Fresh connection created when credentials are refreshed

Connection Management

The MQTT connector implements robust connection handling:

  • Auto-Reconnection: Exponential backoff (2s, 4s, 8s, 16s, 32s, 60s, 120s max)
  • Heartbeat Monitoring: 30-second keep-alive intervals
  • Connection Timeout: Progressive timeout (45s base, increases with retries)
  • Max Attempts: Up to 10 reconnection attempts before giving up

Subscription Management

Efficient subscription handling prevents resource exhaustion:

  • Dynamic Subscriptions: Subscribe only when location is requested
  • Subscription Reuse: Multiple requests for same student share one subscription
  • Delayed Unsubscription: 30-second delay to handle rapid re-subscriptions
  • Subscription Limit: Maximum 100 concurrent subscriptions

Location Data Caching

Location data is cached in memory for instant access:

  • Retained Messages: Last known location delivered immediately on subscription
  • Age Validation: Retained messages older than 6 hours are discarded
  • Live Updates: Cache updated in real-time as new locations arrive
  • Metadata Included: Timestamp, accuracy, speed, altitude, bearing, provider

Location Data Format

{
  latitude: 17.421,          // Decimal degrees
  longitude: 78.399,         // Decimal degrees
  timestamp: 1699876543210,  // Unix timestamp (ms) from mobile app
  accuracy: 10.5,            // Meters
  speed: 2.3,                // Meters per second
  altitude: 520.0,           // Meters
  bearing: 45.0,             // Degrees (0-360)
  provider: "fused",         // 'gps', 'network', 'fused'
  lastUpdated: 1699876543500,// When MCP server received this
  isRetained: false          // Whether from retained MQTT message
}

Health Monitoring

Check MQTT service health via the health endpoint:

curl http://localhost:5000/health

Response includes:

  • Connection status (connected/disconnected)
  • Credentials validity (time remaining)
  • Active subscription count
  • Last heartbeat timestamp

Troubleshooting MQTT

See the Troubleshooting section below for common MQTT issues and solutions.

Redis Search Query Syntax

TEXT Fields (full-text search)

  • @name:Basavaraju - Contains "Basavaraju"
  • @givenName:Raj* - Starts with "Raj"
  • @familyName:"Kumar Singh" - Exact phrase

TAG Fields (exact match)

  • @status:{ACTIVE} - Single value
  • @status:{ACTIVE|PENDING_DUES} - OR condition
  • @grade:{CLASS_11|CLASS_12} - Multiple values

Available Fields

TEXT: name, givenName, familyName, middleName, geoAddress

TAG: status, grade, subscription, gender, campusId, primaryParentId, secondaryParentId

GEO: location (use with longitude, latitude, radius parameters)

NUMERIC: birthdate, startDate, updatedAt

Operators

  • * - Wildcard
  • | - OR (within tags)
  • - - NOT
  • () - Grouping

See src/schemas/redis-schema.txt for complete reference.

Docker Build

Important: Before building the Docker image, you must build and pack the Smithy models:

cd /Users/zeroman/workplace/nowzone/OPlatformStudentMCP

# Build and pack models
npm run model

# Build Docker image
docker build -t student-mcp:latest .

The Dockerfile expects src/generated/smithy-o-platform-client.tgz to exist before the build.

Kubernetes Deployment

Prerequisites

  1. Configure Pulumi secrets:
cd /Users/zeroman/workplace/nowzone/now-zeromoblt
pulumi config set studentApiEndpoint https://api.zeromoblt.com
pulumi config set --secret studentApiAuthToken "your-jwt-token"
  1. Import deployment in index.ts:
import "./deployments/student-mcp";
  1. Deploy:
pulumi up

View Logs

kubectl logs -n student-mcp-dev -l app=student-mcp-server -f

Project Structure

OPlatformStudentMCP/
├── src/
│   ├── index.ts                    # MCP server entry point
│   ├── stdio-server.ts             # Claude Desktop/Kiro integration
│   ├── http-server.ts              # HTTP server mode
│   ├── client/
│   │   └── apiClient.ts            # Student API HTTP client
│   ├── services/
│   │   ├── mqttService.ts          # MQTT service singleton
│   │   └── iotConnector.ts         # AWS IoT SDK wrapper
│   ├── tools/
│   │   ├── getStudent.ts           # Get student by ID tool
│   │   ├── searchStudents.ts       # Search students tool
│   │   ├── getTrip.ts              # Get trip by ID tool
│   │   ├── searchTrips.ts          # Search trips tool
│   │   ├── getStudentLocation.ts   # Get student location tool
│   │   └── getStudentReturnTime.ts # Get student return time tool
│   ├── utils/
│   │   └── locationContextBuilder.ts # Location context utilities
│   └── schemas/
│       └── redis-schema.txt        # Redis search documentation
├── package.json
├── tsconfig.json
├── Dockerfile
└── README.md

Environment Variables

VariableRequiredDescription
STUDENT_API_ENDPOINTYesStudent API base URL
STUDENT_API_AUTH_TOKENNoDefault JWT authentication token (can be overridden per-request)
IOT_ENDPOINTYes*AWS IoT Core endpoint URL (required for real-time location tracking)
IOT_REGIONYes*AWS region for IoT Core (default: us-east-1)
MQTT_MAX_SUBSCRIPTIONSNoMaximum concurrent MQTT subscriptions (default: 100)
MQTT_CREDENTIAL_REFRESH_INTERVALNoCredential refresh interval in milliseconds (default: 2580000 = 43 minutes)

* Required only if using real-time location tracking features

Authentication

The server supports two authentication modes:

  1. Per-Request Token (Recommended): Pass authToken parameter with each tool call

    • Allows dynamic token refresh
    • More secure (token not hardcoded)
    • Example: { "id": "ZST123", "authToken": "eyJ..." }
  2. Default Environment Token: Set STUDENT_API_AUTH_TOKEN environment variable

    • Used when no token provided in request
    • Simpler for single-user scenarios

See for detailed authentication guide.

API Reference

Tools

get_student

Retrieve a student by their unique Zrn identifier.

Input:

{
  id: string,             // Zrn format: Z[A-Z]{2}[0-9]{5,10}
  authToken?: string      // Optional: JWT token (overrides env)
}

Output: Full student object with all fields from Smithy model.

search_students

Search students using Redis FT.SEARCH syntax.

Input:

{
  query: string,          // Required: Redis FT.SEARCH query
  offset?: number,        // Pagination offset
  limit?: number,         // Results per page (max 100)
  longitude?: number,     // Geo search: center longitude
  latitude?: number,      // Geo search: center latitude
  radius?: number,        // Geo search: radius distance
  unit?: "km" | "mi",     // Geo search: distance unit
  authToken?: string      // Optional: JWT token (overrides env)
}

Output:

{
  students: StudentDetails[],
  total: number
}
get_student_location

Get the current location of a student with contextual information.

Input:

{
  studentId: string,      // Required: Student Zrn (e.g., ZST12345)
  authToken?: string      // Optional: JWT token (overrides env)
}

Output: Human-readable text describing:

  • Current location (home, school, or in transit)
  • Trip status and context
  • Pickup/arrival times
  • Trip details (driver, vehicle, route)

Example:

"Your child is at home (123 Main St, Hyderabad), waiting for pickup. 
The school bus is scheduled to arrive at 7:30 AM."
get_student_return_time

Get the expected return time for a student based on scheduled or active return trips.

Input:

{
  studentId: string,      // Required: Student Zrn (e.g., ZST12345)
  authToken?: string      // Optional: JWT token (overrides env)
}

Output: Human-readable text describing:

  • Expected arrival time at home
  • Trip status (scheduled, in progress)
  • Departure time from school
  • Trip details (driver, vehicle, route)

Example:

"Your child is expected to return home at 4:30 PM. 
The return trip from ABC Campus is scheduled to depart at 3:45 PM."
get_trip

Retrieve a trip by its unique Zrn identifier.

Input:

{
  id: string,             // Zrn format: ZTR[0-9]{5,10}
  authToken?: string      // Optional: JWT token (overrides env)
}

Output: Full trip object with stops, status, driver, vehicle, and route information.

search_trips

Search trips using Redis FT.SEARCH syntax.

Input:

{
  query: string,          // Required: Redis FT.SEARCH query
  offset?: number,        // Pagination offset
  limit?: number,         // Results per page (max 100)
  authToken?: string      // Optional: JWT token (overrides env)
}

Output:

{
  trips: TripDetails[],
  total: number
}

Testing Queries

You can ask Claude questions like:

Student Queries:

  • "How many active students are there?"
  • "Find all class 12 students at campus ZCA00123"
  • "Show me students within 10km of coordinates (17.367737, 78.563020)"
  • "List students with pending dues"
  • "Find students named Kumar in grades 11 or 12"

Parent Location Queries:

  • "Where is my child?" (if Claude has context about student ID)
  • "Where is student ZST12345?"
  • "What is the current location of student ZST12345?"
  • "What time will my child be back?"
  • "When is student ZST12345 returning home today?"
  • "Is my child at school or on the way?"

Trip Queries:

  • "Show me all trips for student ZST12345 today"
  • "Find all active trips for driver ZDR007084"
  • "List completed trips on 2025-01-15"
  • "Find trips stopping at campus ZCA000053"

Troubleshooting

MCP Server Not Connecting

  1. Check Claude Desktop config path
  2. Verify environment variables are set
  3. Check logs: tail -f ~/Library/Logs/Claude/mcp*.log

Authentication Errors

  • Verify JWT token is valid and not expired
  • Check token has proper permissions for Student API

Build Errors

  • "Cannot find module '@smithy/o-platform-client'": Run npm run model to build and pack the Smithy models
  • Missing tarball in Docker build: Run npm run model before docker build
  • OPlatformModels build fails: Ensure Smithy models compile: cd ../OPlatformModels && ./gradlew clean build

MQTT Connection Issues Affecting Location Tools

When MQTT connection issues occur, the parent location tools (get_student_location and get_student_return_time) may experience degraded functionality. Here's how to diagnose and resolve issues:

Impact on Location Tools

Symptoms:

  • Location responses show "real-time location unavailable"
  • Location freshness information is missing
  • Only scheduled trip information is returned (no live updates)
  • Responses fall back to home/campus addresses instead of actual location

Fallback Behavior: The location tools are designed to gracefully degrade when MQTT is unavailable:

  1. STARTED trips: Falls back to "on the way to school/home" without real-time position
  2. No active trips: Falls back to home address instead of last known location
  3. Location freshness: Not included when MQTT data unavailable
  4. Core functionality: Tools continue to work using trip schedule and addresses
MQTT Service Not Initializing

Symptoms:

  • Location tools return "MQTT service not available"
  • Health check shows MQTT disconnected
  • Logs show "Failed to initialize MQTT"

Solutions:

  1. Check environment variables:

    echo $IOT_ENDPOINT
    echo $IOT_REGION
    

    Both must be set for MQTT to initialize.

  2. Verify IoT endpoint format:

    • Should be: your-endpoint.iot.us-east-1.amazonaws.com
    • Get from AWS IoT Console → Settings → Device data endpoint
  3. Check authentication:

    • Ensure STUDENT_API_AUTH_TOKEN is valid
    • IoT credentials are fetched from Student API using this token
  4. Review logs:

    # Stdio mode (Claude Desktop)
    tail -f ~/Library/Logs/Claude/mcp*.log | grep MQTT
    
    # HTTP mode
    npm run dev:http 2>&1 | grep MQTT
    
Connection Keeps Dropping

Symptoms:

  • MQTT connects then disconnects repeatedly
  • Logs show "Connection lost" or "Reconnecting..."

Solutions:

  1. Check network connectivity:

    ping your-endpoint.iot.us-east-1.amazonaws.com
    
  2. Verify credentials are refreshing:

    • Credentials expire after 60 minutes
    • Should auto-refresh every 43 minutes
    • Check logs for "Refreshing IoT credentials"
  3. Check for credential expiration:

    • If credentials expire before refresh, connection will drop
    • Verify MQTT_CREDENTIAL_REFRESH_INTERVAL is set correctly (default: 43 minutes)
  4. Review reconnection attempts:

    • Max 10 attempts with exponential backoff
    • After max attempts, manual intervention needed
    • Restart server to reset connection attempts
Subscriptions Not Working

Symptoms:

  • Location requests timeout
  • No location data received
  • Logs show "Subscription failed"

Solutions:

  1. Check subscription limit:

    • Default max: 100 concurrent subscriptions
    • Increase with MQTT_MAX_SUBSCRIPTIONS if needed
  2. Verify topic format:

    • Topics should be: ZR-{studentUsername}
    • Username is from student's preferred_username field
  3. Check IoT permissions:

    • IoT credentials must allow subscribing to ZR-* topics
    • Verify IAM policy attached to IoT credentials
  4. Test with single subscription:

    • Request location for one student
    • Check if subscription succeeds
    • If yes, issue may be subscription limit
Old Location Data

Symptoms:

  • Location data is stale (hours old)
  • Timestamp doesn't match current time

Solutions:

  1. Check if retained message:

    • Retained messages are last known location
    • May be old if student hasn't moved recently
    • Check isRetained flag in location data
  2. Verify mobile app is publishing:

    • Student's mobile app must be running
    • Location tracking must be enabled
    • Check mobile app logs
  3. Check retained message age:

    • Retained messages older than 6 hours are discarded
    • If location is older, it won't be cached
  4. Wait for live update:

    • Retained message gives last known location
    • Live update will arrive when student moves
Credential Refresh Failures

Symptoms:

  • Logs show "Failed to refresh credentials"
  • Connection drops after ~60 minutes
  • 401/403 errors from Student API

Solutions:

  1. Check JWT token validity:

    # Token should not be expired
    # Get fresh token from browser or administrator
    
  2. Verify Student API endpoint:

    curl -H "Authorization: Bearer $STUDENT_API_AUTH_TOKEN" \
         $STUDENT_API_ENDPOINT/iot/credentials
    

    Should return credentials JSON.

  3. Check retry logic:

    • Failed refreshes retry with delays: 2min, 5min, 10min
    • Check logs for retry attempts
    • If all retries fail, manual intervention needed
  4. Restart server:

    • Fresh start will re-fetch credentials
    • Ensures clean state
High Memory Usage

Symptoms:

  • Server memory usage increasing over time
  • Many active subscriptions

Solutions:

  1. Check subscription count:

    • Use health endpoint: curl http://localhost:5000/health
    • Look at activeSubscriptions count
  2. Verify cleanup:

    • Unused subscriptions should be removed after 30 seconds
    • Check logs for "Unsubscribed from topic"
  3. Reduce subscription limit:

    export MQTT_MAX_SUBSCRIPTIONS=50
    
  4. Monitor location cache:

    • Cache size should match active subscriptions
    • Old entries should be removed when unsubscribing
Task Location Fallback Not Working

Symptoms:

  • MQTT unavailable but still seeing "location unavailable" message
  • No coordinates displayed during MQTT outage
  • Task location not being retrieved

Solutions:

  1. Verify trip has tasks:

    # Check if trip has associated tasks
    curl -H "Authorization: Bearer $STUDENT_API_AUTH_TOKEN" \
         "$STUDENT_API_ENDPOINT/tasks?tripId=ZTR225564"
    

    Should return array of tasks with transitionInfo.

  2. Check task has location data:

    • Tasks must have transitionInfo.origin.location or transitionInfo.destination.location
    • Coordinates must be valid (lat: -90 to 90, lng: -180 to 180)
    • At least one task should have status IN_PROGRESS or recent updatedAt
  3. Verify cache is working:

    • Check logs for "Cache hit" or "Cache miss" messages
    • Cache TTL is 30 seconds
    • Multiple requests within 30s should use cached data
  4. Check API authentication:

    • Task API uses same JWT token as Student API
    • Verify token has permissions to access Task endpoints
    • Check for 403 errors in logs
  5. Review fallback logs:

    [taskLocationResolver] Fallback triggered for trip ZTR225564 (MQTT unavailable)
    [taskLocationResolver] Retrieved task location: 17.418806, 78.400413 (updated 2 minutes ago)
    [taskLocationResolver] Cache hit for trip ZTR225564 (age: 15s)
    

Common Issues:

IssueCauseSolution
No tasks foundTrip not yet started or completedNormal - fallback to generic message
Invalid coordinatesTask has malformed location dataCheck mobile app task creation logic
Cache not workingSystem time incorrectVerify server time is accurate
API timeoutTask API slow or unavailableCheck Task API health and network
Missing transitionInfoOld task format or incomplete dataUpdate task creation to include location
Debugging MQTT Issues

Enable verbose logging:

The MQTT service logs to stderr. Increase verbosity:

// In src/services/mqttService.ts
console.error('[MQTT] Debug info:', { /* details */ });

Check connection status:

# HTTP mode
curl http://localhost:5000/health | jq '.mqtt'

# Expected output:
{
  "connected": true,
  "credentialsValidFor": 2580000,
  "activeSubscriptions": 5,
  "lastHeartbeat": 1699876543210
}

Test IoT credentials manually:

# Get credentials from API
curl -H "Authorization: Bearer $STUDENT_API_AUTH_TOKEN" \
     $STUDENT_API_ENDPOINT/iot/credentials

# Should return:
{
  "accessKeyId": "ASIA...",
  "secretAccessKey": "...",
  "sessionToken": "...",
  "expiration": "2024-01-15T12:00:00Z"
}

Monitor MQTT traffic:

Use AWS IoT Console → Test → MQTT test client to monitor topics:

  • Subscribe to ZR-* to see all student location updates
  • Verify messages are being published by mobile apps

Common Error Messages:

ErrorCauseSolution
MQTT service not initializedMissing IOT_ENDPOINT or IOT_REGIONSet environment variables
Failed to fetch IoT credentialsInvalid JWT token or API errorCheck token validity
Connection timeoutNetwork issue or wrong endpointVerify endpoint and network
Subscription limit reachedToo many concurrent subscriptionsIncrease MQTT_MAX_SUBSCRIPTIONS
Invalid location payloadMalformed message from mobile appCheck mobile app logs
Credentials expiredRefresh failed or not scheduledCheck refresh timer and retry logic

Development

Watch Mode

npm run watch

Run Locally

npm run dev

License

MIT

Contributing

Generated from Smithy model at /Users/zeroman/workplace/nowzone/OPlatformModels/models/student.smithy