feat: implement XER MCP Server with 9 schedule query tools
Implement complete MCP server for parsing Primavera P6 XER files and exposing schedule data through MCP tools. All 4 user stories complete. Tools implemented: - load_xer: Parse XER files into SQLite database - list_activities: Query activities with pagination and filtering - get_activity: Get activity details by ID - list_relationships: Query activity dependencies - get_predecessors/get_successors: Query activity relationships - get_project_summary: Project overview with counts - list_milestones: Query milestone activities - get_critical_path: Query driving path activities Features: - Tab-delimited XER format parsing with pluggable table handlers - In-memory SQLite database for fast queries - Pagination with 100-item default limit - Multi-project file support with project selection - ISO8601 date formatting - NO_FILE_LOADED error handling for all query tools Test coverage: 81 tests (contract, integration, unit)
This commit is contained in:
17
src/xer_mcp/models/__init__.py
Normal file
17
src/xer_mcp/models/__init__.py
Normal file
@@ -0,0 +1,17 @@
|
||||
"""Data models for XER MCP Server."""
|
||||
|
||||
from xer_mcp.models.activity import Activity
|
||||
from xer_mcp.models.calendar import Calendar
|
||||
from xer_mcp.models.pagination import PaginationMetadata
|
||||
from xer_mcp.models.project import Project
|
||||
from xer_mcp.models.relationship import Relationship
|
||||
from xer_mcp.models.wbs import WBS
|
||||
|
||||
__all__ = [
|
||||
"Activity",
|
||||
"Calendar",
|
||||
"PaginationMetadata",
|
||||
"Project",
|
||||
"Relationship",
|
||||
"WBS",
|
||||
]
|
||||
23
src/xer_mcp/models/activity.py
Normal file
23
src/xer_mcp/models/activity.py
Normal file
@@ -0,0 +1,23 @@
|
||||
"""Activity data model."""
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class Activity:
|
||||
"""A unit of work in the schedule."""
|
||||
|
||||
task_id: str
|
||||
proj_id: str
|
||||
task_code: str
|
||||
task_name: str
|
||||
task_type: str
|
||||
wbs_id: str | None = None
|
||||
target_start_date: datetime | None = None
|
||||
target_end_date: datetime | None = None
|
||||
act_start_date: datetime | None = None
|
||||
act_end_date: datetime | None = None
|
||||
total_float_hr_cnt: float | None = None
|
||||
driving_path_flag: bool = False
|
||||
status_code: str | None = None
|
||||
13
src/xer_mcp/models/calendar.py
Normal file
13
src/xer_mcp/models/calendar.py
Normal file
@@ -0,0 +1,13 @@
|
||||
"""Calendar data model (internal use only)."""
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Calendar:
|
||||
"""Work schedule definition. Not exposed via MCP tools."""
|
||||
|
||||
clndr_id: str
|
||||
clndr_name: str
|
||||
day_hr_cnt: float | None = None
|
||||
week_hr_cnt: float | None = None
|
||||
13
src/xer_mcp/models/pagination.py
Normal file
13
src/xer_mcp/models/pagination.py
Normal file
@@ -0,0 +1,13 @@
|
||||
"""Pagination metadata model."""
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class PaginationMetadata:
|
||||
"""Response wrapper for paginated queries."""
|
||||
|
||||
total_count: int
|
||||
offset: int
|
||||
limit: int
|
||||
has_more: bool
|
||||
15
src/xer_mcp/models/project.py
Normal file
15
src/xer_mcp/models/project.py
Normal file
@@ -0,0 +1,15 @@
|
||||
"""Project data model."""
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
@dataclass
|
||||
class Project:
|
||||
"""Top-level container representing a P6 project."""
|
||||
|
||||
proj_id: str
|
||||
proj_short_name: str
|
||||
plan_start_date: datetime | None = None
|
||||
plan_end_date: datetime | None = None
|
||||
loaded_at: datetime | None = None
|
||||
14
src/xer_mcp/models/relationship.py
Normal file
14
src/xer_mcp/models/relationship.py
Normal file
@@ -0,0 +1,14 @@
|
||||
"""Relationship data model."""
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Relationship:
|
||||
"""A dependency link between two activities."""
|
||||
|
||||
task_pred_id: str
|
||||
task_id: str
|
||||
pred_task_id: str
|
||||
pred_type: str
|
||||
lag_hr_cnt: float = 0.0
|
||||
14
src/xer_mcp/models/wbs.py
Normal file
14
src/xer_mcp/models/wbs.py
Normal file
@@ -0,0 +1,14 @@
|
||||
"""Work Breakdown Structure (WBS) data model."""
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class WBS:
|
||||
"""Hierarchical organization of activities."""
|
||||
|
||||
wbs_id: str
|
||||
proj_id: str
|
||||
wbs_short_name: str
|
||||
parent_wbs_id: str | None = None
|
||||
wbs_name: str | None = None
|
||||
Reference in New Issue
Block a user