# Quickstart: Direct Database Access for Scripts This guide shows how to use the XER MCP Server's persistent database feature to query schedule data directly from scripts. ## Overview The XER MCP Server can save parsed schedule data to a SQLite file, allowing your scripts to query the data directly without going through MCP tools. This is ideal for: - Large-scale data analysis - Custom reporting - Integration with other tools - Reducing LLM token usage for data-heavy operations ## Loading to a Persistent Database ### Option 1: Auto-generated Path Use an empty string for `db_path` to automatically create a database file alongside the XER file: ``` Use the load_xer tool with file_path="/path/to/schedule.xer" and db_path="" ``` **Response**: ```json { "success": true, "project": { "proj_id": "P001", "proj_short_name": "Construction Phase 1" }, "activity_count": 4440, "database": { "db_path": "/path/to/schedule.sqlite", "is_persistent": true, "source_file": "/path/to/schedule.xer", "loaded_at": "2026-01-08T14:30:00", "schema": { "version": "0.2.0", "tables": [ { "name": "activities", "columns": [ {"name": "task_id", "type": "TEXT", "nullable": false}, {"name": "task_code", "type": "TEXT", "nullable": false}, {"name": "task_name", "type": "TEXT", "nullable": false}, ... ], "row_count": 4440 }, ... ] } } } ``` ### Option 2: Specify Custom Path ``` Use the load_xer tool with file_path="/path/to/schedule.xer" and db_path="/data/my-schedule.db" ``` ### Option 3: In-Memory Only (Default) Omit `db_path` to use the original in-memory behavior: ``` Use the load_xer tool with file_path="/path/to/schedule.xer" ``` ## Querying the Database Directly Once you have the database path, use any SQLite client to query the data. ### Python Example ```python import sqlite3 # Use the db_path from load_xer response db_path = "/path/to/schedule.sqlite" conn = sqlite3.connect(db_path) conn.row_factory = sqlite3.Row # Query all milestones cursor = conn.execute(""" SELECT task_code, task_name, target_start_date, milestone_type FROM activities WHERE task_type IN ('TT_Mile', 'TT_FinMile') ORDER BY target_start_date """) for row in cursor: print(f"{row['task_code']}: {row['task_name']} ({row['milestone_type']})") conn.close() ``` ### SQL Examples **Find critical path activities:** ```sql SELECT task_code, task_name, target_start_date, target_end_date FROM activities WHERE driving_path_flag = 1 ORDER BY target_start_date; ``` **Get activity count by WBS:** ```sql SELECT w.wbs_name, COUNT(*) as activity_count FROM activities a JOIN wbs w ON a.wbs_id = w.wbs_id GROUP BY w.wbs_id ORDER BY activity_count DESC; ``` **Find activities with predecessors:** ```sql SELECT a.task_code, a.task_name, COUNT(r.pred_task_id) as predecessor_count FROM activities a LEFT JOIN relationships r ON a.task_id = r.task_id GROUP BY a.task_id HAVING predecessor_count > 0 ORDER BY predecessor_count DESC; ``` **Export milestones to CSV (using sqlite3 CLI):** ```bash sqlite3 -header -csv schedule.sqlite \ "SELECT task_code, task_name, target_start_date, milestone_type FROM activities WHERE task_type IN ('TT_Mile', 'TT_FinMile')" > milestones.csv ``` ## Getting Database Info Without Reloading If you need the database path and schema later: ``` Use the get_database_info tool ``` **Response**: ```json { "database": { "db_path": "/path/to/schedule.sqlite", "is_persistent": true, "source_file": "/path/to/schedule.xer", "loaded_at": "2026-01-08T14:30:00", "schema": { ... } } } ``` ## Database Schema Reference | Table | Description | Key Columns | |-------|-------------|-------------| | `projects` | Project metadata | proj_id, proj_short_name, plan_start_date, plan_end_date | | `activities` | Tasks and milestones | task_id, task_code, task_name, task_type, target_start_date, target_end_date | | `relationships` | Predecessor/successor links | task_pred_id, task_id, pred_task_id, pred_type, lag_hr_cnt | | `wbs` | Work breakdown structure | wbs_id, wbs_name, parent_wbs_id | | `calendars` | Calendar definitions | clndr_id, clndr_name, day_hr_cnt | ## Best Practices 1. **Use persistent database for large schedules**: Schedules with 1000+ activities benefit from direct SQL queries 2. **Close connections when done**: Always close your database connections to avoid lock issues 3. **Read-only access recommended**: The database is designed for reading; modifications may cause inconsistencies with MCP tools 4. **Re-load when XER changes**: If the source XER file is updated, reload to refresh the database 5. **Check schema version**: The schema version in the response indicates compatibility with your queries ## Error Handling | Error Code | Meaning | Solution | |------------|---------|----------| | NO_FILE_LOADED | No XER file has been loaded | Call load_xer first | | FILE_NOT_WRITABLE | Cannot write database file | Check directory permissions | | DISK_FULL | Insufficient disk space | Free up disk space | | DATABASE_ERROR | General database error | Check error message for details |