io.github.S-CurveLabs/longpath
Official# longpath
<!-- mcp-name: io.github.S-CurveLabs/longpath -->
An MCP server that lets an assistant (Claude Code, GitHub Copilot agent mode, any MCP client) read and analyze
construction / project schedules the way a scheduler would: its own CPM engine, float, critical and driving paths, the
DCMA 14-point assessment, logic-quality checks, update-to-update comparison, baseline variance and S-curve data.
| Format | How |
|---|---|
| Primavera P6 `.xer` | native parser (multi-project files, Windows-1252 or UTF-8, optional tables) |
| MS Project XML (MSPDI) | native parser |
| MS Project `.mpp` / `.mpt` / `.mpx` | MPXJ converts to MSPDI (optional: `longpath[mpp]` + Java 11+) |
| Primavera P6 XML | MPXJ converts to XER (optional: `longpath[mpp]` + Java 11+) |
Schedule files are only ever **read**. `.xer` and MS Project XML need nothing but Python; without the optional extra
and Java, a `.mpp` fails with a message saying exactly what to install.
## Tools
| Area | Tools |
|---|---|
| Setup | `check_setup` — version, config file, whether Java + MPXJ were found |
| Overview | `schedule_summary` (start here) · `list_calendars` · `wbs_tree` · `list_resources` |
| Activities & logic | `list_activities` (WBS / code / status / type / text / float filters) · `activity_detail` · `list_relationships` |
| CPM | `run_cpm` (engine vs the float stored in the file) · `critical_path` (longest path or total float) · `driving_path` |
| Quality | `dcma_assessment` (14 points, thresholds, offenders) · `logic_check` (17 checks) |
| Change | `compare_schedules` (update vs previous update) · `baseline_variance` · `s_curve` (cost / units / activity counts) |
| Export | `export_csv` — any list above, in full, to a new `.csv` (the only write; see safety) |
Every tool takes the schedule's absolute path. Every list returns `count` plus the top `limit` rows (default 25) and
says when it truncated. Durations and float are **working days on each activity's own calendar** unless a field ends
in `_h`.
## Install
```powershell
pip install longpath # or run it without installing: uvx longpath
```
Needs Python 3.11+. That is all `.xer` and MS Project XML files need.
**MS Project `.mpp` and P6 XML (optional).** These go through [MPXJ](https://www.mpxj.org), a Java library:
1. Install the extra, which pulls in the `mpxj` package for its bundled jars: `pip install "longpath[mpp]"`
(with uvx: `uvx --from "longpath[mpp]" longpath`).
2. Install any Java 11+ runtime (JDK or JRE, e.g. [Eclipse Temurin](https://adoptium.net)). longpath looks for it in
`java_home` in `longpath.toml`, then `JAVA_HOME`, then `java` on `PATH`.
Run `check_setup` to see what was found. The MPXJ jars can also come from a folder of your own (`mpxj_classpath`).
Without Java, MS Project's *File > Save As > XML* produces a file longpath reads natively.
**Claude Code**
```bash
claude mcp add --scope user longpath -- uvx longpath
# with .mpp support:
claude mcp add --scope user longpath -e JAVA_HOME=/path/to/jdk -- uvx --from "longpath[mpp]" longpath
```
**VS Code / Copilot.** Add to the user-level `mcp.json` (*MCP: Open User Configuration*), so it works in every
window:
```json
"longpath": {
"type": "stdio",
"command": "uvx",
"args": ["--from", "longpath[mpp]", "longpath"],
"env": { "JAVA_HOME": "C:\\path\\to\\jdk-21" }
}
```
(Drop `--from longpath[mpp]` and the `env` block if you only read `.xer` / XML: `"args": ["longpath"]`.)
## Configuration (optional)
Every setting is optional. Copy [`longpath.example.toml`](https://github.com/S-CurveLabs/longpath/blob/main/longpath.example.toml)
to one of these (first match wins):
1. the file named by `LONGPATH_CONFIG`
2. `longpath.toml` in the server's working folder
3. `longpath.toml` in `LONGPATH_HOME`, default `%LOCALAPPDATA%\longpath\` on Windows, `~/.local/share/longpath/` elsewhere
| Key | Default | Meaning |
|---|---|---|
| `java_home` | `JAVA_HOME`, then `java` on PATH | Folder containing `bin/java` (Java 11+), for `.mpp` / P6 XML |
| `mpxj_classpath` | jars bundled in the `mpxj` package | Folder of MPXJ jars (or one jar) to use instead |
| `java_timeout_seconds` | `180` | Limit per MPXJ conversion |
| `max_rows` | `25` | Default top-N for list outputs |
| `allow_writes` | `false` | Let `export_csv` write files (it only previews otherwise) |
Unknown keys are rejected with the list of allowed ones. No secrets are involved and nothing is sent anywhere: the
server makes no network calls.
## Safety model
- **Read-only by design.** Every tool opens the schedule for reading only; MPXJ conversions write to a private temp
folder that is deleted afterwards. All tools except `export_csv` carry `readOnlyHint`.
- `export_csv` is the only write. It creates a **new** `.csv` file (UTF-8 with BOM for Excel) and refuses existing
files, non-`.csv` paths and relative paths. It is a dry run by default (row count, columns, first rows) and writes
only with `dry_run=false` **and** `allow_writes = true` in the config. Undo = delete the file.
## The CPM engine
P6 rules, computed from the logic in the file (not copied from its stored dates):
- FS / SS / FF / SF with positive and negative lags; lag calendar per the P6 option (predecessor, successor, 24-hour,
project default).
- Each activity on its own calendar at minute resolution: work weeks with split shifts, holidays, changed-hours days,
24-hour and 6/7-day calendars. Starts land on the first working minute (Mon 08:00), finishes at the end of the last
working interval (Fri 17:00).
- Constraints: Start/Finish On or After/Before, Start On / Finish On, Mandatory Start/Finish (breaks logic, as in P6),
As Late As Possible, P6 external early/late dates, MS Project deadlines (as finish-on-or-before), project must-finish date.
- Progress: data date floor, actual dates, in-progress remaining work under Retained Logic or Progress Override (from
the file's schedule options). Completed activities are fixed and have no float.
- Total float per the file's setting (finish, start, or smaller of the two), free float, relationship float, driving
flags, longest path, critical by the project's float threshold. Level-of-effort and WBS-summary activities are left
out of the network. Logic loops are detected and listed instead of producing garbage.
### Validation
- Known-answer tests on hand-built XERs: every relationship type, leads, lags, holidays, mixed calendars, SNET /
FNLT / Mandatory Start, must-finish, retained logic vs progress override, open ends, LOE, loops.
- MPXJ's public sample files (131 MS Project schedules), read two ways (`.mpp` → MS Project XML, and the XER MPXJ
writes): all load and every tool runs on every file. Computed total float matched the slack MS Project stored for
about 96% of activities (3,910 of 4,065 via XER; 3,880 of 4,047 via `.mpp`). Every remaining difference traced so far
is an MS Project vs P6 rule difference (see limits); the same file read both ways gives identical floats.
- 20,000 activities / 40,000 relationships (`scripts/make_big_xer.py`): open + CPM about 0.8 s, DCMA about 1 s.
- `scripts/sweep_samples.py <folder>` re-runs the stored-float comparison over any folder of schedules.
## Known limits
- **Not yet validated against a broad set of P6-calculated XERs.** The P6 rules are verified by hand-worked answers,
and the large sample sweep came from MS Project files. If `run_cpm` disagrees with the float P6 stored in your file,
an issue with the `comparison_with_file` output is very welcome.
- Resource-dependent activities use the activity calendar (resource calendars and leveling are not modelled).
- ALAP is approximated (the activity is pushed late by its free float). P6 "expected finish", suspend/resume and
multi-project scheduling across files are not modelled; relationships to other projects count as external.
- MS Project differs from P6 on slack for SS/SF-linked predecessors, summary-task logic (dropped here, with a warning),
manually scheduled tasks and resource-calendar-driven tasks, so stored MS Project slack will not always match.
- S-curves spread quantities linearly over working time (no resource curves or timephased data). MS Project "cost" is
cost at completion; its Baseline (0) is the planned curve when present.
- DCMA thresholds are the standard ones and fixed; "high duration" uses original duration; missed tasks, BEI and CPLI
need a baseline (a baseline file, MS Project Baseline 0, or P6 planned dates, labelled as such).
- Percentage lags (MS Project) are converted to hours of the predecessor's duration; elapsed lags are treated as working time.
- Password-protected `.mpp` files cannot be read.
## Layout
`src/longpath/` — `xer.py` / `mspdi.py` / `mpxj_bridge.py` → `model.py` (one normalized model) → `calendars.py`
(work-time timeline) → `cpm.py` → `checks.py` (DCMA + logic) / `compare.py` (updates, baseline) / `curves.py` (S-curve)
→ `analysis.py` (shared row shaping) → `server.py` (the tools). `tests/xerbuild.py` builds known-answer XERs.
## Development
```powershell
git clone https://github.com/S-CurveLabs/longpath; cd longpath
python -m venv .venv
.venv\Scripts\pip install -e .[mpp,dev]
.venv\Scripts\pytest
```
The tests that go through MPXJ run only when Java is found (`JAVA_HOME` or `PATH`) and skip otherwise. The fixtures in
`tests/fixtures/` are synthetic; `scripts/make_fixtures.py` rebuilds them (see `tests/fixtures/README.md`).
## License
MIT. The optional `mpxj` package is a separate LGPL library that longpath runs as a converter; it is not bundled.
TDQS
Scored across 17 tools
Each tool has a clearly distinct purpose: listing activities, relationships, resources, calendars, detailed views, CPM analysis, critical path, DCMA, logic checks, comparisons, variance, and S-curve. Even similar tools like critical_path vs driving_path are differentiated by scope (project-wide vs specific activity).
All tool names follow a consistent snake_case verb_noun pattern (list_*, run_cpm, compare_schedules, baseline_variance). Nouns like wbs_tree and s_curve are still in the same style, and there is no mixing of camelCase or inconsistent verbs.
17 tools is slightly above the ideal 3-15 range, but given the specialized domain of schedule analysis, each tool serves a distinct analytical function (DCMA, logic, comparison, variance, S-curve) and earns its place. It feels well-scoped rather than bloated.
The tool surface covers the full lifecycle of schedule analysis: reading/summarizing files, listing all resource types, detailed activity/relationship info, CPM engine, critical path, DCMA assessment, logic checks, update-to-update comparison, baseline variance, and S-curve. No obvious gaps for a read-only analysis tool.