Files
xer-mcp/specs/001-schedule-tools/quickstart.md
Bill Ballou a7b6b76db8 feat: add milestone_type field to distinguish start/finish milestones
Add milestone_type field to milestone queries that indicates whether
a milestone is a start milestone ('start') or finish milestone ('finish').

Changes:
- Add milestone_type column to activities table schema
- Parse milestone_type from XER TASK table (MS_Start/MS_Finish)
- Include milestone_type in list_milestones response
- Update contract tests for milestone_type field
- Update specs, contracts, and documentation

The milestone_type is determined by:
1. Explicit milestone_type field in XER (MS_Start -> 'start', MS_Finish -> 'finish')
2. Derived from task_type (TT_Mile -> 'start', TT_FinMile -> 'finish')
2026-01-08 12:18:34 -05:00

303 lines
6.5 KiB
Markdown

# Quickstart: XER MCP Server
This guide shows how to set up and use the XER MCP Server for querying Primavera P6 schedule data.
## Prerequisites
- Python 3.14+
- uv package manager
- An XER file exported from Primavera P6
## Installation
```bash
# Clone the repository
git clone <repo-url>
cd xer-mcp
# Install dependencies with uv
uv sync
# Verify installation
uv run python -m xer_mcp --help
```
## Configuration
Add the server to your MCP client configuration (e.g., Claude Desktop):
```json
{
"mcpServers": {
"xer-mcp": {
"command": "uv",
"args": ["run", "python", "-m", "xer_mcp"],
"cwd": "/path/to/xer-mcp"
}
}
}
```
## Basic Usage
### 1. Load an XER File
```
Use the load_xer tool with file_path="/path/to/schedule.xer"
```
**Response** (single project):
```json
{
"success": true,
"project": {
"proj_id": "P001",
"proj_short_name": "Construction Phase 1",
"plan_start_date": "2026-01-15T00:00:00",
"plan_end_date": "2026-06-30T00:00:00"
},
"activity_count": 450,
"relationship_count": 520
}
```
**Response** (multi-project, no selection):
```json
{
"success": false,
"available_projects": [
{"proj_id": "P001", "proj_short_name": "Phase 1"},
{"proj_id": "P002", "proj_short_name": "Phase 2"}
],
"message": "Multiple projects found. Please specify project_id."
}
```
### 2. List Activities
```
Use the list_activities tool
```
**Response**:
```json
{
"activities": [
{
"task_id": "A1000",
"task_code": "A1000",
"task_name": "Site Preparation",
"task_type": "TT_Task",
"target_start_date": "2026-01-15T08:00:00",
"target_end_date": "2026-01-22T17:00:00",
"status_code": "TK_NotStart",
"driving_path_flag": true
}
],
"pagination": {
"total_count": 450,
"offset": 0,
"limit": 100,
"has_more": true
}
}
```
### 3. Filter Activities by Date Range
```
Use the list_activities tool with start_date="2026-02-01" and end_date="2026-02-28"
```
### 4. Get Activity Details
```
Use the get_activity tool with activity_id="A1000"
```
**Response**:
```json
{
"task_id": "A1000",
"task_code": "A1000",
"task_name": "Site Preparation",
"task_type": "TT_Task",
"wbs_id": "WBS001",
"wbs_name": "Pre-Construction",
"target_start_date": "2026-01-15T08:00:00",
"target_end_date": "2026-01-22T17:00:00",
"act_start_date": null,
"act_end_date": null,
"total_float_hr_cnt": 0,
"status_code": "TK_NotStart",
"driving_path_flag": true,
"predecessor_count": 0,
"successor_count": 5
}
```
### 5. Query Predecessors/Successors
```
Use the get_predecessors tool with activity_id="A1050"
```
**Response**:
```json
{
"activity_id": "A1050",
"predecessors": [
{
"task_id": "A1000",
"task_code": "A1000",
"task_name": "Site Preparation",
"relationship_type": "FS",
"lag_hr_cnt": 0,
"driving": true
},
{
"task_id": "A1010",
"task_code": "A1010",
"task_name": "Permits Approved",
"relationship_type": "FS",
"lag_hr_cnt": 8,
"driving": false
}
]
}
```
The `driving` flag indicates which predecessor relationship constrains the successor's early start date. A driving relationship is one where the predecessor's completion (plus lag) determines when the successor can begin.
### 6. Get Project Summary
```
Use the get_project_summary tool
```
**Response**:
```json
{
"project": {
"proj_id": "P001",
"proj_short_name": "Construction Phase 1",
"plan_start_date": "2026-01-15T00:00:00",
"plan_end_date": "2026-06-30T00:00:00"
},
"activity_count": 450,
"milestone_count": 25,
"relationship_count": 520,
"wbs_element_count": 30,
"critical_activity_count": 85
}
```
### 7. Get Critical Path
```
Use the get_critical_path tool
```
**Response**:
```json
{
"critical_activities": [
{
"task_id": "A1000",
"task_code": "A1000",
"task_name": "Site Preparation",
"task_type": "TT_Task",
"target_start_date": "2026-01-15T08:00:00",
"target_end_date": "2026-01-22T17:00:00"
}
],
"pagination": {
"total_count": 85,
"offset": 0,
"limit": 100,
"has_more": false
}
}
```
### 8. List Milestones
```
Use the list_milestones tool
```
**Response**:
```json
{
"milestones": [
{
"task_id": "M001",
"task_code": "MS-START",
"task_name": "Project Start",
"target_start_date": "2026-01-15T08:00:00",
"target_end_date": "2026-01-15T08:00:00",
"status_code": "TK_Complete",
"milestone_type": "start"
},
{
"task_id": "M025",
"task_code": "MS-END",
"task_name": "Project Complete",
"target_start_date": "2026-06-30T17:00:00",
"target_end_date": "2026-06-30T17:00:00",
"status_code": "TK_NotStart",
"milestone_type": "finish"
}
]
}
```
The `milestone_type` field indicates whether the milestone is a Start Milestone (`"start"`) or a Finish Milestone (`"finish"`).
## Pagination
All list operations support pagination:
```
Use the list_activities tool with limit=50 and offset=100
```
This returns activities 101-150 (0-indexed).
## Error Handling
| Error | Meaning | Solution |
|-------|---------|----------|
| FILE_NOT_FOUND | XER file path doesn't exist | Check file path |
| PARSE_ERROR | XER file is malformed | Verify file is valid P6 export |
| NO_FILE_LOADED | Query before load_xer | Call load_xer first |
| PROJECT_SELECTION_REQUIRED | Multi-project file | Specify project_id in load_xer |
| ACTIVITY_NOT_FOUND | Invalid activity_id | Check activity exists |
## Relationship Types
| Code | Name | Meaning |
|------|------|---------|
| FS | Finish-to-Start | B starts after A finishes |
| SS | Start-to-Start | B starts after A starts |
| FF | Finish-to-Finish | B finishes after A finishes |
| SF | Start-to-Finish | B finishes after A starts |
## Activity Types
| Code | Name | Description |
|------|------|-------------|
| TT_Task | Task | Normal work activity with duration |
| TT_Mile | Milestone | Zero-duration marker |
| TT_LOE | Level of Effort | Duration spans linked activities |
| TT_WBS | WBS Summary | Summary of child activities |
| TT_Rsrc | Resource Dependent | Duration from resource assignment |
## Tips for AI Assistants
1. **Start with summary**: Call `get_project_summary` first to understand scope
2. **Use pagination**: Large schedules may have thousands of activities
3. **Filter early**: Use date ranges and WBS filters to reduce results
4. **Check critical path**: `get_critical_path` identifies schedule-driving work
5. **Follow relationships**: Use `get_predecessors`/`get_successors` to trace dependencies