Files
xer-mcp/specs/002-direct-db-access/quickstart.md
Bill Ballou 3e7ad39eb8 docs: add specification and implementation plan for direct database access feature
This feature (002-direct-db-access) enables scripts to query schedule data
directly via SQL after loading XER files through MCP. Key additions:

- spec.md: Feature specification with 3 user stories
- plan.md: Implementation plan with constitution check
- research.md: Technology decisions (SQLite file, WAL mode, atomic writes)
- data-model.md: DatabaseInfo, SchemaInfo, TableInfo entities
- contracts/mcp-tools.json: Extended load_xer schema, new get_database_info tool
- quickstart.md: Usage examples for direct database access
- tasks.md: 16 implementation tasks across 6 phases
2026-01-08 12:38:42 -05:00

5.1 KiB

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:

{
  "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

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:

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:

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:

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):

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:

{
  "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