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

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 |