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
190 lines
5.1 KiB
Markdown
190 lines
5.1 KiB
Markdown
# 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 |
|