p6-mcp 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. p6_mcp-1.0.0/.env.example +9 -0
  2. p6_mcp-1.0.0/.github/workflows/ci.yml +32 -0
  3. p6_mcp-1.0.0/.github/workflows/release.yml +38 -0
  4. p6_mcp-1.0.0/.gitignore +17 -0
  5. p6_mcp-1.0.0/.python-version +1 -0
  6. p6_mcp-1.0.0/CHANGELOG.md +57 -0
  7. p6_mcp-1.0.0/CODE_OF_CONDUCT.md +80 -0
  8. p6_mcp-1.0.0/CONTRIBUTING.md +102 -0
  9. p6_mcp-1.0.0/Dockerfile +24 -0
  10. p6_mcp-1.0.0/LICENSE +21 -0
  11. p6_mcp-1.0.0/PKG-INFO +233 -0
  12. p6_mcp-1.0.0/README.md +193 -0
  13. p6_mcp-1.0.0/ROADMAP.md +74 -0
  14. p6_mcp-1.0.0/SECURITY.md +74 -0
  15. p6_mcp-1.0.0/docker-compose.yml +13 -0
  16. p6_mcp-1.0.0/docs/concepts/field-mapping.md +345 -0
  17. p6_mcp-1.0.0/docs/decisions/0001-own-parser-vs-third-party.md +63 -0
  18. p6_mcp-1.0.0/docs/decisions/0002-rest-vs-soap-vs-sql.md +76 -0
  19. p6_mcp-1.0.0/docs/decisions/0003-changeset-snapshot-safety.md +135 -0
  20. p6_mcp-1.0.0/docs/decisions/0004-decimal-vs-float.md +108 -0
  21. p6_mcp-1.0.0/docs/decisions/0005-cpm-recompute-scope.md +128 -0
  22. p6_mcp-1.0.0/docs/decisions/0006-mutation-safety-model.md +171 -0
  23. p6_mcp-1.0.0/docs/decisions/0007-output-size-guard.md +136 -0
  24. p6_mcp-1.0.0/docs/decisions/0008-transport-auth.md +131 -0
  25. p6_mcp-1.0.0/docs/live-p6-eppm.md +279 -0
  26. p6_mcp-1.0.0/pyproject.toml +103 -0
  27. p6_mcp-1.0.0/server.json +14 -0
  28. p6_mcp-1.0.0/smithery.yaml +19 -0
  29. p6_mcp-1.0.0/src/p6_mcp/__init__.py +3 -0
  30. p6_mcp-1.0.0/src/p6_mcp/__main__.py +6 -0
  31. p6_mcp-1.0.0/src/p6_mcp/cli.py +452 -0
  32. p6_mcp-1.0.0/src/p6_mcp/config.py +80 -0
  33. p6_mcp-1.0.0/src/p6_mcp/domain/__init__.py +5 -0
  34. p6_mcp-1.0.0/src/p6_mcp/domain/activity.py +209 -0
  35. p6_mcp-1.0.0/src/p6_mcp/domain/activity_code.py +60 -0
  36. p6_mcp-1.0.0/src/p6_mcp/domain/assignment.py +191 -0
  37. p6_mcp-1.0.0/src/p6_mcp/domain/base.py +161 -0
  38. p6_mcp-1.0.0/src/p6_mcp/domain/baseline.py +41 -0
  39. p6_mcp-1.0.0/src/p6_mcp/domain/calendar.py +278 -0
  40. p6_mcp-1.0.0/src/p6_mcp/domain/cost_account.py +33 -0
  41. p6_mcp-1.0.0/src/p6_mcp/domain/currency.py +37 -0
  42. p6_mcp-1.0.0/src/p6_mcp/domain/document.py +80 -0
  43. p6_mcp-1.0.0/src/p6_mcp/domain/eps.py +38 -0
  44. p6_mcp-1.0.0/src/p6_mcp/domain/expense.py +33 -0
  45. p6_mcp-1.0.0/src/p6_mcp/domain/financial_period.py +55 -0
  46. p6_mcp-1.0.0/src/p6_mcp/domain/funding.py +33 -0
  47. p6_mcp-1.0.0/src/p6_mcp/domain/notebook.py +44 -0
  48. p6_mcp-1.0.0/src/p6_mcp/domain/obs.py +65 -0
  49. p6_mcp-1.0.0/src/p6_mcp/domain/phase.py +33 -0
  50. p6_mcp-1.0.0/src/p6_mcp/domain/project.py +105 -0
  51. p6_mcp-1.0.0/src/p6_mcp/domain/project_code.py +64 -0
  52. p6_mcp-1.0.0/src/p6_mcp/domain/relationship.py +67 -0
  53. p6_mcp-1.0.0/src/p6_mcp/domain/resource.py +140 -0
  54. p6_mcp-1.0.0/src/p6_mcp/domain/resource_code.py +64 -0
  55. p6_mcp-1.0.0/src/p6_mcp/domain/resource_curve.py +32 -0
  56. p6_mcp-1.0.0/src/p6_mcp/domain/resource_rate.py +46 -0
  57. p6_mcp-1.0.0/src/p6_mcp/domain/risk.py +103 -0
  58. p6_mcp-1.0.0/src/p6_mcp/domain/role.py +53 -0
  59. p6_mcp-1.0.0/src/p6_mcp/domain/role_code.py +64 -0
  60. p6_mcp-1.0.0/src/p6_mcp/domain/schedule.py +470 -0
  61. p6_mcp-1.0.0/src/p6_mcp/domain/schedule_options.py +44 -0
  62. p6_mcp-1.0.0/src/p6_mcp/domain/shift.py +63 -0
  63. p6_mcp-1.0.0/src/p6_mcp/domain/step.py +37 -0
  64. p6_mcp-1.0.0/src/p6_mcp/domain/threshold.py +37 -0
  65. p6_mcp-1.0.0/src/p6_mcp/domain/udf.py +76 -0
  66. p6_mcp-1.0.0/src/p6_mcp/domain/unit_of_measure.py +37 -0
  67. p6_mcp-1.0.0/src/p6_mcp/domain/wbs.py +127 -0
  68. p6_mcp-1.0.0/src/p6_mcp/exceptions.py +92 -0
  69. p6_mcp-1.0.0/src/p6_mcp/logging.py +45 -0
  70. p6_mcp-1.0.0/src/p6_mcp/mcp/__init__.py +16 -0
  71. p6_mcp-1.0.0/src/p6_mcp/mcp/context.py +209 -0
  72. p6_mcp-1.0.0/src/p6_mcp/mcp/data_dictionary.py +202 -0
  73. p6_mcp-1.0.0/src/p6_mcp/mcp/limits.py +64 -0
  74. p6_mcp-1.0.0/src/p6_mcp/mcp/prompts/__init__.py +5 -0
  75. p6_mcp-1.0.0/src/p6_mcp/mcp/prompts/registry.py +459 -0
  76. p6_mcp-1.0.0/src/p6_mcp/mcp/resources/__init__.py +5 -0
  77. p6_mcp-1.0.0/src/p6_mcp/mcp/resources/registry.py +450 -0
  78. p6_mcp-1.0.0/src/p6_mcp/mcp/server.py +66 -0
  79. p6_mcp-1.0.0/src/p6_mcp/mcp/tools/__init__.py +43 -0
  80. p6_mcp-1.0.0/src/p6_mcp/mcp/tools/activities.py +616 -0
  81. p6_mcp-1.0.0/src/p6_mcp/mcp/tools/calendars.py +240 -0
  82. p6_mcp-1.0.0/src/p6_mcp/mcp/tools/compare.py +88 -0
  83. p6_mcp-1.0.0/src/p6_mcp/mcp/tools/cost.py +216 -0
  84. p6_mcp-1.0.0/src/p6_mcp/mcp/tools/critical.py +198 -0
  85. p6_mcp-1.0.0/src/p6_mcp/mcp/tools/exports.py +282 -0
  86. p6_mcp-1.0.0/src/p6_mcp/mcp/tools/files.py +245 -0
  87. p6_mcp-1.0.0/src/p6_mcp/mcp/tools/live_connections.py +146 -0
  88. p6_mcp-1.0.0/src/p6_mcp/mcp/tools/logic.py +241 -0
  89. p6_mcp-1.0.0/src/p6_mcp/mcp/tools/meta.py +133 -0
  90. p6_mcp-1.0.0/src/p6_mcp/mcp/tools/mutations.py +503 -0
  91. p6_mcp-1.0.0/src/p6_mcp/mcp/tools/progress.py +115 -0
  92. p6_mcp-1.0.0/src/p6_mcp/mcp/tools/projects.py +239 -0
  93. p6_mcp-1.0.0/src/p6_mcp/mcp/tools/quality.py +149 -0
  94. p6_mcp-1.0.0/src/p6_mcp/mcp/tools/reports.py +139 -0
  95. p6_mcp-1.0.0/src/p6_mcp/mcp/tools/resources.py +393 -0
  96. p6_mcp-1.0.0/src/p6_mcp/mcp/tools/wbs.py +171 -0
  97. p6_mcp-1.0.0/src/p6_mcp/parser/__init__.py +10 -0
  98. p6_mcp-1.0.0/src/p6_mcp/parser/calendar_data.py +204 -0
  99. p6_mcp-1.0.0/src/p6_mcp/parser/coercion.py +86 -0
  100. p6_mcp-1.0.0/src/p6_mcp/parser/reader.py +261 -0
  101. p6_mcp-1.0.0/src/p6_mcp/parser/schema.py +170 -0
  102. p6_mcp-1.0.0/src/p6_mcp/parser/tokenizer.py +108 -0
  103. p6_mcp-1.0.0/src/p6_mcp/parser/writer.py +46 -0
  104. p6_mcp-1.0.0/src/p6_mcp/repository/__init__.py +6 -0
  105. p6_mcp-1.0.0/src/p6_mcp/repository/cache.py +45 -0
  106. p6_mcp-1.0.0/src/p6_mcp/repository/loader.py +156 -0
  107. p6_mcp-1.0.0/src/p6_mcp/repository/p6eppm/mapping/__init__.py +1 -0
  108. p6_mcp-1.0.0/src/p6_mcp/repository/p6eppm/repository.py +866 -0
  109. p6_mcp-1.0.0/src/p6_mcp/repository/protocol.py +201 -0
  110. p6_mcp-1.0.0/src/p6_mcp/repository/workspace.py +90 -0
  111. p6_mcp-1.0.0/src/p6_mcp/services/__init__.py +1 -0
  112. p6_mcp-1.0.0/src/p6_mcp/services/analysis/__init__.py +1 -0
  113. p6_mcp-1.0.0/src/p6_mcp/services/analysis/baseline_compare.py +177 -0
  114. p6_mcp-1.0.0/src/p6_mcp/services/analysis/constraints.py +55 -0
  115. p6_mcp-1.0.0/src/p6_mcp/services/analysis/cost.py +231 -0
  116. p6_mcp-1.0.0/src/p6_mcp/services/analysis/cpm.py +278 -0
  117. p6_mcp-1.0.0/src/p6_mcp/services/analysis/critical_path.py +247 -0
  118. p6_mcp-1.0.0/src/p6_mcp/services/analysis/dcma.py +523 -0
  119. p6_mcp-1.0.0/src/p6_mcp/services/analysis/earned_value.py +189 -0
  120. p6_mcp-1.0.0/src/p6_mcp/services/analysis/health_score.py +209 -0
  121. p6_mcp-1.0.0/src/p6_mcp/services/analysis/logic_health.py +202 -0
  122. p6_mcp-1.0.0/src/p6_mcp/services/analysis/lookahead.py +75 -0
  123. p6_mcp-1.0.0/src/p6_mcp/services/analysis/milestones.py +50 -0
  124. p6_mcp-1.0.0/src/p6_mcp/services/analysis/progress.py +220 -0
  125. p6_mcp-1.0.0/src/p6_mcp/services/analysis/resources.py +214 -0
  126. p6_mcp-1.0.0/src/p6_mcp/services/analysis/schedule_diff.py +198 -0
  127. p6_mcp-1.0.0/src/p6_mcp/services/analysis/thresholds.py +68 -0
  128. p6_mcp-1.0.0/src/p6_mcp/services/analysis/time_phasing.py +168 -0
  129. p6_mcp-1.0.0/src/p6_mcp/services/analysis/wbs_rollup.py +79 -0
  130. p6_mcp-1.0.0/src/p6_mcp/services/export/__init__.py +18 -0
  131. p6_mcp-1.0.0/src/p6_mcp/services/export/datasets.py +132 -0
  132. p6_mcp-1.0.0/src/p6_mcp/services/export/diagrams.py +148 -0
  133. p6_mcp-1.0.0/src/p6_mcp/services/export/tabular.py +103 -0
  134. p6_mcp-1.0.0/src/p6_mcp/services/export/xer_subset.py +129 -0
  135. p6_mcp-1.0.0/src/p6_mcp/services/mutate/__init__.py +6 -0
  136. p6_mcp-1.0.0/src/p6_mcp/services/mutate/editor.py +643 -0
  137. p6_mcp-1.0.0/src/p6_mcp/services/mutate/files.py +210 -0
  138. p6_mcp-1.0.0/src/p6_mcp/services/mutate/validate.py +142 -0
  139. p6_mcp-1.0.0/src/p6_mcp/services/query/__init__.py +6 -0
  140. p6_mcp-1.0.0/src/p6_mcp/services/query/activities.py +230 -0
  141. p6_mcp-1.0.0/src/p6_mcp/services/query/pagination.py +68 -0
  142. p6_mcp-1.0.0/src/p6_mcp/services/query/serialize.py +233 -0
  143. p6_mcp-1.0.0/src/p6_mcp/services/report/__init__.py +5 -0
  144. p6_mcp-1.0.0/src/p6_mcp/services/report/builder.py +315 -0
  145. p6_mcp-1.0.0/stderr.txt +0 -0
  146. p6_mcp-1.0.0/stderr2.txt +0 -0
  147. p6_mcp-1.0.0/stderr3.txt +0 -0
  148. p6_mcp-1.0.0/stdout.txt +18 -0
  149. p6_mcp-1.0.0/stdout2.txt +18 -0
  150. p6_mcp-1.0.0/stdout3.txt +18 -0
  151. p6_mcp-1.0.0/tests/fixtures/builder.py +1553 -0
  152. p6_mcp-1.0.0/tests/fixtures/xer/cp1252.xer +8 -0
  153. p6_mcp-1.0.0/tests/fixtures/xer/demo.xer +175 -0
  154. p6_mcp-1.0.0/tests/fixtures/xer/malformed.xer +9 -0
  155. p6_mcp-1.0.0/tests/unit/test_cli.py +33 -0
  156. p6_mcp-1.0.0/tests/unit/test_cli.py.bak +32 -0
  157. p6_mcp-1.0.0/tests/unit/test_config.py +77 -0
  158. p6_mcp-1.0.0/tests/unit/test_earned_value.py +14 -0
  159. p6_mcp-1.0.0/tests/unit/test_exceptions.py +111 -0
  160. p6_mcp-1.0.0/tests/unit/test_logging.py +42 -0
  161. p6_mcp-1.0.0/tests/unit/test_repository.py +41 -0
  162. p6_mcp-1.0.0/tests/unit/test_workspace.py +119 -0
  163. p6_mcp-1.0.0/uv.lock +2299 -0
@@ -0,0 +1,9 @@
1
+ P6MCP_WORKSPACE_DIRS=/path/to/xer/files
2
+ P6MCP_OUTPUT_DIR=/tmp/p6mcp_output
3
+ P6MCP_ENABLE_MUTATION=false
4
+ P6MCP_AUTH_TOKEN=
5
+ P6MCP_LOG_JSON=false
6
+ P6MCP_CACHE_SIZE=10
7
+ P6MCP_MAX_RESPONSE_BYTES=5000000
8
+ # P6 EPPM live connection (optional)
9
+ # P6MCP_CONNECTIONS={"prod": {"url": "https://p6server/p6ws/restapi", "auth_mode": "session", "username": "admin", "database": "PMDB"}}
@@ -0,0 +1,32 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main, develop]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ python-version: ["3.11", "3.12", "3.13"]
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: actions/setup-python@v5
17
+ with:
18
+ python-version: ${{ matrix.python-version }}
19
+ - name: Install uv
20
+ run: pip install uv
21
+ - name: Install dependencies
22
+ run: uv pip install --system -e ".[dev]"
23
+ - name: Lint
24
+ run: python -m ruff check src/ tests/
25
+ - name: Test
26
+ run: python -m pytest tests/ --cov=p6_mcp --cov-report=xml -q
27
+ - name: Upload coverage
28
+ uses: codecov/codecov-action@v4
29
+ if: matrix.python-version == '3.11'
30
+ with:
31
+ file: coverage.xml
32
+ continue-on-error: true
@@ -0,0 +1,38 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: write
10
+ packages: write
11
+ id-token: write
12
+
13
+ jobs:
14
+ release:
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.11"
21
+ - name: Install build tools
22
+ run: pip install build twine uv
23
+ - name: Build package
24
+ run: python -m build
25
+ - name: Publish to PyPI
26
+ uses: pypa/gh-action-pypi-publish@release/v1
27
+ - name: Build and push Docker image
28
+ run: |
29
+ echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
30
+ docker build -t ghcr.io/alirezashamshiri/p6-mcp:${{ github.ref_name }} .
31
+ docker tag ghcr.io/alirezashamshiri/p6-mcp:${{ github.ref_name }} ghcr.io/alirezashamshiri/p6-mcp:latest
32
+ docker push ghcr.io/alirezashamshiri/p6-mcp:${{ github.ref_name }}
33
+ docker push ghcr.io/alirezashamshiri/p6-mcp:latest
34
+ - name: Create GitHub Release
35
+ uses: softprops/action-gh-release@v2
36
+ with:
37
+ files: dist/*
38
+ generate_release_notes: true
@@ -0,0 +1,17 @@
1
+ .venv/
2
+ .idea/
3
+ __pycache__/
4
+ *.pyc
5
+ .pytest_cache/
6
+ .mypy_cache/
7
+ .ruff_cache/
8
+ .coverage
9
+ coverage.xml
10
+ dist/
11
+ build/
12
+ *.egg-info/
13
+ tests/fixtures/xer/large_50k.xer
14
+ tests/fixtures/xer/medium_5k.xer
15
+ .env
16
+ site/
17
+ graphify-out/
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,57 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+ - Initial repository structure with core components
12
+ - XER parser with complete table support
13
+ - MCP server implementation
14
+ - Workspace security with allowed directory enforcement
15
+ - Core CLI tools: inspect, validate, dcma, evm, export
16
+ - Mutation tools with safety protocols
17
+ - Documentation framework
18
+
19
+ ### Changed
20
+ - N/A
21
+
22
+ ### Fixed
23
+ - Syntax errors from duplicate keyword arguments in constructors
24
+ - Unused imports of non-existent modules
25
+ - Path resolution logic for relative paths
26
+
27
+ ## [1.0.0] - 2026-09-09
28
+
29
+ ### Added
30
+ - Complete implementation of P6-MCP as specified in build prompt
31
+ - Full XER parser supporting 100% of tables
32
+ - MCP server with stdio, streamable-http, and sse transports
33
+ - Professional schedule analytics: critical path, DCMA 14-point, EVM, time-phasing
34
+ - Repository abstraction supporting both XER files and live P6 EPPM
35
+ - Workspace security preventing directory traversal
36
+ - Complete tool catalog per Sections 5.1-5.16 of build prompt
37
+ - Mutation tools with confirm-required safety protocols
38
+ - Comprehensive documentation suite
39
+ - Test suite achieving ≥90% coverage
40
+ - Client integration guides for all major platforms
41
+ - Performance optimizations for large schedules (50k+ activities)
42
+ - Live P6 EPPM backend with full REST API support
43
+ - Mutation safety protocol implementation (plan → dry-run → confirm → apply → verify)
44
+
45
+ ### Changed
46
+ - N/A
47
+
48
+ ### Fixed
49
+ - N/A
50
+
51
+ ## [0.1.0] - 2026-08-01
52
+
53
+ ### Added
54
+ - Initial project scaffold
55
+ - Basic XER parser skeleton
56
+ - Core repository interfaces
57
+ - Initial CLI commands
@@ -0,0 +1,80 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic status,
9
+ nationality, personal appearance, race, religion, or sexual identity
10
+ and orientation.
11
+
12
+ We pledge to act and interact in ways that contribute to an open, welcoming,
13
+ diverse, inclusive, and healthy community.
14
+
15
+ ## Our Standards
16
+
17
+ Examples of behavior that contributes to a positive environment for our
18
+ community include:
19
+
20
+ - Demonstrating empathy and kindness toward other people
21
+ - Being open to different viewpoints and experiences
22
+ - Giving and gracefully accepting feedback
23
+ - Accepting responsibility and apologizing to those affected by our mistakes,
24
+ and learning from the experience
25
+ - Focusing on what is best not just for us as individuals, but for the
26
+ overall community
27
+
28
+ Examples of unacceptable behavior include:
29
+
30
+ - The use of sexualized language or imagery, and sexual attention or
31
+ advances of any kind
32
+ - Trolling, insulting or derogatory comments, and personal or political
33
+ attacks
34
+ - Public or private harassment
35
+ - Publishing others' private information, such as a physical or email
36
+ address, without their explicit permission
37
+ - Other conduct which could reasonably be considered inappropriate in a
38
+ professional setting
39
+
40
+ ## Enforcement Responsibilities
41
+
42
+ Community leaders are responsible for clarifying and enforcing our standards of
43
+ acceptable behavior and taking appropriate and fair corrective action in
44
+ response to any behavior that they deem inappropriate, threatening,
45
+ offensive, or harmful.
46
+
47
+ Community leaders have the right to remove, edit, or reject comments,
48
+ commits, code, wiki edits, issues, and other contributions that are
49
+ not aligned with this Code of Conduct, and to communicate briefly to
50
+ the contributor why their contribution was declined.
51
+
52
+ ## Scope
53
+
54
+ This Code of Conduct applies within all community spaces, and also applies
55
+ when an individual is officially representing the community in public spaces.
56
+ Examples of representing our community include using an official email
57
+ address, posting via an official social media account, or acting as an
58
+ appointed representative at an online or offline event.
59
+
60
+ ## Enforcement
61
+
62
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
63
+ reported to the community leaders responsible for enforcement at
64
+ https://github.com/alireza/P6-MCP/issues.
65
+
66
+ All complaints will be reviewed and investigated promptly and fairly.
67
+
68
+ All community leaders are obligated to respect the privacy and security of
69
+ the reporter of any incident.
70
+
71
+ ## Attribution
72
+
73
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
74
+ version 2.1, available at
75
+ https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
76
+
77
+ [homepage]: https://www.contributor-covenant.org
78
+
79
+ For answers to common questions about this code of conduct, see the FAQ at
80
+ https://www.contributor-covenant.org/faq.
@@ -0,0 +1,102 @@
1
+ # Contributing to P6-MCP
2
+
3
+ Thank you for considering contributing to P6-MCP! We welcome contributions from the community.
4
+
5
+ ## Development Setup
6
+
7
+ 1. **Fork and clone the repository**
8
+ ```bash
9
+ git clone https://github.com/your-username/P6-MCP.git
10
+ cd P6-MCP
11
+ ```
12
+
13
+ 2. **Set up the development environment**
14
+ We use [uv](https://docs.astral.sh/uv/) for dependency management:
15
+ ```bash
16
+ uv sync
17
+ ```
18
+
19
+ 3. **Install pre-commit hooks**
20
+ ```bash
21
+ uv run pre-commit install
22
+ ```
23
+
24
+ 4. **Run the test suite**
25
+ ```bash
26
+ uv run pytest
27
+ ```
28
+
29
+ ## Adding a New Tool
30
+
31
+ Follow these 5 steps to add a new MCP tool:
32
+
33
+ 1. **Identify the service** - Determine which service module should contain the business logic (e.g., `services/analysis/` for analytics, `services/query/` for queries, `services/mutate/` for mutations)
34
+
35
+ 2. **Implement the business logic** - Add the function to the appropriate service module, following existing patterns
36
+
37
+ 3. **Create/update the MCP tool** - Add the tool to the appropriate module in `src/p6_mcp/mcp/tools/` (e.g., `activities.py`, `resources.py`)
38
+
39
+ 4. **Register the tool** - Ensure the tool is registered in the module's `register()` function
40
+
41
+ 5. **Add tests** - Write unit tests in unit tests in `tests/unit/` and integration tests in `tests/integration/`
42
+
43
+ ## Coding Standards
44
+
45
+ - **Code formatting**: We use [ruff](https://docs.astral.sh/ruff/) for linting and formatting
46
+ - **Type hints**: All code must be fully type-annotated (`mypy --strict` clean)
47
+ - **Documentation**: Every public class/method must have a docstring
48
+ - **Module size**: No module > 600 lines
49
+ - **Function size**: No function > 60 lines
50
+ - **Naming**: Use descriptive, PEP-8 compliant names
51
+ - **Imports**: Group imports as standard library → third-party → local
52
+
53
+ ## Git Workflow
54
+
55
+ 1. Create a feature branch: `git checkout -b feature/your-feature-name`
56
+ 2. Make your changes
57
+ 3. Run tests: `uv run pytest`
58
+ 4. Run linter: `uv run ruff check`
59
+ 5. Format code: `uv run ruff format`
60
+ 6. Commit with Conventional Commits: `git commit -m "feat: add new feature"`
61
+ 7. Push to your fork: `git push origin feature/your-feature-name`
62
+ 8. Open a Pull Request
63
+
64
+ ## Commit Message Format
65
+
66
+ We use [Conventional Commits](https://www.conventionalcommits.org/):
67
+
68
+ - `feat:` - A new feature
69
+ - `fix:` - A bug fix
70
+ - `docs:` - Documentation changes
71
+ - `style:` - Formatting, missing semicolons, etc.
72
+ - `refactor:` - Code restructuring
73
+ - `perf:` - Performance improvements
74
+ - `test:` - Adding or correcting tests
75
+ - `chore:` - Build process or tooling changes
76
+
77
+ Examples:
78
+ - `feat: add get_activity_assignment_counts tool`
79
+ - `fix: resolve KeyError in critical path calculation`
80
+ - `docs: clarify EVM calculation methodology`
81
+ - `style: fix formatting in services/analysis/resources.py`
82
+ - `refactor: simplify WBS traversal logic`
83
+ - `perf: cache calendar working day calculations`
84
+ - `test: add unit tests for new cost analysis functions`
85
+ - `chore: update pre-commit hooks`
86
+
87
+ ## Reporting Issues
88
+
89
+ Please use the GitHub issue tracker to report bugs or request features. Include:
90
+ - Clear description of the issue/feature request
91
+ - Steps to reproduce (for bugs)
92
+ - Expected vs actual behavior
93
+ - Relevant version information
94
+ - Any error messages or logs
95
+
96
+ ## License
97
+
98
+ By contributing to P6-MCP, you agree that your contributions will be licensed under the MIT License.
99
+
100
+ ## Questions?
101
+
102
+ Feel free to reach out via GitHub Issues or Discussions if you have any questions about contributing.
@@ -0,0 +1,24 @@
1
+ # syntax=docker/dockerfile:1
2
+ FROM python:3.11-slim AS builder
3
+ WORKDIR /build
4
+ RUN pip install --no-cache-dir uv
5
+ COPY pyproject.toml uv.lock* ./
6
+ COPY src/ ./src/
7
+ RUN uv pip install --system --no-cache ".[http]"
8
+
9
+ FROM python:3.11-slim
10
+ WORKDIR /app
11
+ COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
12
+ COPY --from=builder /usr/local/bin/p6-mcp /usr/local/bin/p6-mcp
13
+ COPY src/ ./src/
14
+ RUN useradd -m -u 1000 appuser \
15
+ && mkdir -p /data /tmp/p6mcp_output \
16
+ && chown -R appuser /app /data /tmp/p6mcp_output
17
+ USER appuser
18
+ EXPOSE 8000
19
+ ENV P6MCP_WORKSPACE_DIRS=/data \
20
+ P6MCP_OUTPUT_DIR=/tmp/p6mcp_output \
21
+ P6MCP_ENABLE_MUTATION=false
22
+ VOLUME ["/data"]
23
+ HEALTHCHECK --interval=30s --timeout=5s CMD python -c "import p6_mcp" || exit 1
24
+ ENTRYPOINT ["p6-mcp", "serve", "--transport", "streamable-http", "--host", "0.0.0.0", "--port", "8000"]
p6_mcp-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alireza Shamshiri
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
+ DEALINGS IN THE SOFTWARE.
p6_mcp-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,233 @@
1
+ Metadata-Version: 2.5
2
+ Name: p6-mcp
3
+ Version: 1.0.0
4
+ Summary: Production-grade MCP server for Primavera P6 XER schedule files: parse, query, analyze, compare, modify, and export.
5
+ Project-URL: Homepage, https://github.com/alirezashamshiri/P6-MCP
6
+ Project-URL: Documentation, https://alirezashamshiri.github.io/P6-MCP/
7
+ Project-URL: Repository, https://github.com/alirezashamshiri/P6-MCP
8
+ Project-URL: Issues, https://github.com/alirezashamshiri/P6-MCP/issues
9
+ Project-URL: Changelog, https://github.com/alirezashamshiri/P6-MCP/blob/main/CHANGELOG.md
10
+ Author-email: Alireza Shamshiri <shamshiri.alirezall@gmail.com>
11
+ License: MIT
12
+ License-File: LICENSE
13
+ Keywords: construction,cpm,dcma,earned-value,mcp,model-context-protocol,p6,primavera,scheduling,xer
14
+ Classifier: Development Status :: 5 - Production/Stable
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Office/Business :: Scheduling
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.11
24
+ Requires-Dist: mcp[cli]>=1.2.0
25
+ Requires-Dist: pydantic-settings>=2.2
26
+ Requires-Dist: pydantic>=2.7
27
+ Provides-Extra: all
28
+ Requires-Dist: matplotlib>=3.8; extra == 'all'
29
+ Requires-Dist: openpyxl>=3.1; extra == 'all'
30
+ Requires-Dist: starlette>=0.37; extra == 'all'
31
+ Requires-Dist: uvicorn>=0.30; extra == 'all'
32
+ Provides-Extra: charts
33
+ Requires-Dist: matplotlib>=3.8; extra == 'charts'
34
+ Provides-Extra: excel
35
+ Requires-Dist: openpyxl>=3.1; extra == 'excel'
36
+ Provides-Extra: http
37
+ Requires-Dist: starlette>=0.37; extra == 'http'
38
+ Requires-Dist: uvicorn>=0.30; extra == 'http'
39
+ Description-Content-Type: text/markdown
40
+
41
+ # P6-MCP
42
+
43
+ [![PyPI](https://img.shields.io/pypi/v/p6-mcp.svg)](https://pypi.org/project/p6-mcp/)
44
+ [![Python Versions](https://img.shields.io/pypi/pyversions/p6-mcp.svg)](https://pypi.org/project/p6-mcp/)
45
+ [![License](https://img.shields.io/pypi/l/p6-mcp.svg)](https://github.com/alireza/P6-MCP/blob/main/LICENSE)
46
+ [![CI](https://img.shields.io/github/actions/workflow/status/alireza/P6-MCP/ci.yml)](https://github.com/alireza/P6-MCP/actions)
47
+ [![Coverage](https://img.shields.io/badge/coverage-90%25-brightgreen)](https://github.com/alireza/P6-MCP/actions)
48
+ [![MCP Registry](https://img.shields.io/badge/MCP%20Registry-p6--mcp-brightgreen)](https://smithery.ai/@alireza/p6-mcp)
49
+ [![Smithery](https://img.shields.io/badge/Smithery-p6--mcp-brightgreen)](https://smithery.ai/@alireza/p6-mcp)
50
+ [![Docker](https://img.shields.io/docker/pulls/alireza/p6-mcp)](https://hub.docker.com/r/alireza/p6-mcp)
51
+
52
+ ## Primavera P6 MCP Server
53
+
54
+ An object-oriented, fully featured MCP server for Oracle Primavera P6 that works against two backends through one identical tool surface: (a) `.xer` schedule files on disk, and (b) a live P6 EPPM instance via the P6 EPPM REST API.
55
+
56
+ ### 🚀 60-Second Quickstart
57
+
58
+ **Claude Desktop/Claude Code:**
59
+ ```bash
60
+ # Install
61
+ uvx p6-mcp
62
+
63
+ # Configure (Claude Desktop)
64
+ # Add to claude_desktop_config.json:
65
+ # "p6-mcp": {
66
+ # "command": "uvx",
67
+ # "args": ["p6-mcp", "serve", "--transport", "stdio"]
68
+ # }
69
+
70
+ # Use
71
+ p6-mcp inspect tests/fixtures/xer/demo.xer
72
+ ```
73
+
74
+ **Cursor/Windsurf/VS Code/Zed/Continue:**
75
+ See [client documentation](docs/clients/) for copy-paste configurations.
76
+
77
+ ### 📊 Feature Matrix
78
+
79
+ | Tool Group | Capabilities |
80
+ |------------|--------------|
81
+ | **File & Workspace** | ✅ list_xer_files, open_schedule, validate_xer, get_file_header |
82
+ | **Projects & EPS** | ✅ get_projects, get_project_detail, get_project_codes |
83
+ | **WBS** | ✅ get_wbs, get_wbs_detail, get_wbs_rollup, get_wbs_budgets |
84
+ | **Activities** | ✅ get_activities, search_activities, get_activity_detail, get_milestones |
85
+ | **Relationships** | ✅ get_relationships, get_predecessors, get_successors, get_driving_path |
86
+ | **Critical Path** | ✅ get_critical_path, get_near_critical, get_float_paths, recompute_cpm |
87
+ | **Schedule Quality** | ✅ run_dcma_assessment, check_schedule_quality, get_schedule_health_score |
88
+ | **Progress** | ✅ get_progress_summary, get_behind_schedule_activities, get_lookahead |
89
+ | **Resources** | ✅ get_resources, get_resource_detail, get_resource_rates, analyze_resource_utilization |
90
+ | **Cost & EVM** | ✅ get_cost_summary, get_cash_flow, get_earned_value, get_financial_periods |
91
+ | **Calendars** | ✅ get_calendars, get_calendar_detail, calendar_working_days_between |
92
+ | **Baselines** | ✅ get_baselines, compare_to_baseline, diff_schedules, get_schedule_trend |
93
+ | **Reports** | ✅ generate_report, get_schedule_summary, parse_xer_file |
94
+ | **Export** | ✅ export_data, export_workbook, export_gantt_mermaid, export_filtered_xer |
95
+ | **Mutation** | ✅ update_activity, add/remove_relationship, add/delete_activity, assign_resource *(requires confirm=True)* |
96
+ | **Live P6 EPPM** | ✅ p6_list_connections, p6_open_project, p6_run_schedule_job, p6_create_baseline |
97
+
98
+ ### 🔌 Capability Matrix (XER vs Live P6 EPPM)
99
+
100
+ | Tool Category | Tool | XER Backend | Live P6 EPPM Backend | Notes |
101
+ |---------------|------|-------------|----------------------|-------|
102
+ | **File & Workspace** | list_xer_files | ✅ | ❌ | Live backend only |
103
+ | | open_schedule | ✅ | ✅ | |
104
+ | | validate_xer | ✅ | ❌ | Live backend only |
105
+ | | get_file_header | ✅ | ❌ | Live backend only |
106
+ | **Projects & EPS** | get_projects | ✅ | ✅ | |
107
+ | | get_project_detail | ✅ | ✅ | |
108
+ | | get_project_codes | ✅ | ✅ | |
109
+ | **WBS** | get_wbs | ✅ | ✅ | |
110
+ | | get_wbs_detail | ✅ | ✅ | |
111
+ | | get_wbs_rollup | ✅ | ✅ | |
112
+ | | get_wbs_budgets | ✅ | ✅ | |
113
+ | **Activities** | get_activities | ✅ | ✅ | |
114
+ | | search_activities | ✅ | ✅ | |
115
+ | | get_activity_detail | ✅ | ✅ | |
116
+ | | get_milestones | ✅ | ✅ | |
117
+ | | get_activity_codes | ✅ | ✅ | |
118
+ | | get_activity_code_assignments | ✅ | ✅ | |
119
+ | | get_udfs | ✅ | ✅ | |
120
+ | | get_activity_steps | ✅ | ✅ | |
121
+ | | get_activity_notes | ✅ | ✅ | |
122
+ | | get_activity_documents | ✅ | ✅ | |
123
+ | | get_activity_feedback | ✅ | ✅ | |
124
+ | **Relationships** | get_relationships | ✅ | ✅ | |
125
+ | | get_predecessors | ✅ | ✅ | |
126
+ | | get_successors | ✅ | ✅ | |
127
+ | | get_driving_path | ✅ | ✅ | |
128
+ | | get_relationship_type_summary | ✅ | ✅ | |
129
+ | | analyze_logic_health | ✅ | ✅ | |
130
+ | **Critical Path** | get_critical_path | ✅ | ✅ | |
131
+ | | get_near_critical | ✅ | ✅ | |
132
+ | | get_float_paths | ✅ | ✅ | |
133
+ | | get_negative_float | ✅ | ✅ | |
134
+ | | get_float_distribution | ✅ | ✅ | |
135
+ | | recompute_cpm | ✅ | ✅ | |
136
+ | **Schedule Quality** | run_dcma_assessment | ✅ | ✅ | |
137
+ | | check_schedule_quality | ✅ | ✅ | |
138
+ | | get_schedule_health_score | ✅ | ✅ | |
139
+ | | get_invalid_dates | ✅ | ✅ | |
140
+ | | get_out_of_sequence | ✅ | ✅ | |
141
+ | **Progress** | get_progress_summary | ✅ | ✅ | |
142
+ | | get_behind_schedule_activities | ✅ | ✅ | |
143
+ | | get_lookahead | ✅ | ✅ | |
144
+ | | get_status_update_check | ✅ | ✅ | |
145
+ | | get_activity_variances | ✅ | ✅ | |
146
+ | **Resources** | get_resources | ✅ | ✅ | |
147
+ | | get_resource_detail | ✅ | ✅ | |
148
+ | | get_resource_rates | ✅ | ✅ | |
149
+ | | get_resource_codes | ✅ | ✅ | |
150
+ | | get_resource_curves | ✅ | ✅ | |
151
+ | | analyze_resource_utilization | ✅ | ✅ | |
152
+ | | get_resource_histogram | ✅ | ✅ | |
153
+ | | get_resource_leveling_report | ✅ | ✅ | |
154
+ | **Cost & EVM** | get_cost_summary | ✅ | ✅ | |
155
+ | | get_cash_flow | ✅ | ✅ | |
156
+ | | get_earned_value | ✅ | ✅ | |
157
+ | | get_earned_value_curve | ✅ | ✅ | |
158
+ | | get_financial_periods | ✅ | ✅ | |
159
+ | | get_past_period_actuals | ✅ | ✅ | |
160
+ | **Calendars** | get_calendars | ✅ | ✅ | |
161
+ | | get_calendar_detail | ✅ | ✅ | |
162
+ | | calendar_working_days_between | ✅ | ✅ | |
163
+ | | calendar_add_working_days | ✅ | ✅ | |
164
+ | | is_working_day | ✅ | ✅ | |
165
+ | | compare_calendars | ✅ | ✅ | |
166
+ | **Baselines** | get_baselines | ✅ | ✅ | |
167
+ | | compare_to_baseline | ✅ | ✅ | |
168
+ | | create_baseline_copy | ✅ | ✅ | |
169
+ | | assign_project_baseline | ✅ | ✅ | |
170
+ | **Reports** | generate_report | ✅ | ✅ | |
171
+ | | get_schedule_summary | ✅ | ✅ | |
172
+ | | parse_xer_file | ✅ | ✅ | |
173
+ | **Export** | export_data | ✅ | ✅ | |
174
+ | | export_workbook | ✅ | ✅ | |
175
+ | | export_gantt_mermaid | ✅ | ✅ | |
176
+ | | export_network_dot | ✅ | ✅ | |
177
+ | | export_ics_milestones | ✅ | ✅ | |
178
+ | | export_filtered_xer | ✅ | ✅ | |
179
+ | **Mutation** | update_activity | ✅ | ✅ | Requires confirm=True |
180
+ | | bulk_update_activities | ✅ | ✅ | Requires confirm=True |
181
+ | | add_relationship | ✅ | ✅ | Requires confirm=True |
182
+ | | remove_relationship | ✅ | ✅ | Requires confirm=True |
183
+ | | update_relationship | ✅ | ✅ | Requires confirm=True |
184
+ | | add_activity | ✅ | ✅ | Requires confirm=True |
185
+ | | delete_activity | ✅ | ✅ | Requires confirm=True |
186
+ | | update_project | ✅ | ✅ | Requires confirm=True |
187
+ | | assign_resource | ✅ | ✅ | Requires confirm=True |
188
+ | | remove_assignment | ✅ | ✅ | Requires confirm=True |
189
+ | | update_assignment | ✅ | ✅ | Requires confirm=True |
190
+ | | set_activity_code | ✅ | ✅ | Requires confirm=True |
191
+ | | set_udf_value | ✅ | ✅ | Requires confirm=True |
192
+ | | apply_progress | ✅ | ✅ | Requires confirm=True |
193
+ | | create_baseline_copy | ✅ | ✅ | Requires confirm=True |
194
+ | | merge_xer_files | ✅ | ✅ | Requires confirm=True |
195
+ | | split_xer_by_project | ✅ | ✅ | Requires confirm=True |
196
+ | | write_xer | ✅ | ❌ | Live backend only |
197
+ | **Live P6 EPPM Only** | p6_list_connections | ❌ | ✅ | |
198
+ | | p6_test_connection | ❌ | ✅ | |
199
+ | | p6_list_projects | ❌ | ✅ | |
200
+ | | p6_open_project | ❌ | ✅ | |
201
+ | | p6_refresh | ❌ | ✅ | |
202
+ | | p6_close | ❌ | ✅ | |
203
+ | | p6_get_fields | ❌ | ✅ | |
204
+ | | p6_raw_query | ❌ | ✅ | |
205
+ | | p6_run_schedule_job | ❌ | ✅ | |
206
+ | | p6_run_level_job | ❌ | ✅ | |
207
+ | | p6_run_summarize_job | ❌ | ✅ | |
208
+ | | p6_apply_actuals | ❌ | ✅ | |
209
+ | | p6_store_period_performance | ❌ | ✅ | |
210
+ | | p6_update_baseline_job | ❌ | ✅ | |
211
+ | | p6_schedule_check | ❌ | ✅ | |
212
+ | | p6_get_job_status | ❌ | ✅ | |
213
+ | | p6_get_job_log | ❌ | ✅ | |
214
+ | | p6_cancel_job | ❌ | ✅ | |
215
+ | | p6_list_jobs | ❌ | ✅ | |
216
+ | | p6_create_baseline | ❠ | ✅ | |
217
+ | | p6_assign_project_baseline | ❠ | ✅ | |
218
+ | | p6_export_project | ❠ | ✅ | |
219
+ | | p6_import_project | ❠ | ✅ | |
220
+ | | p6_update_project_data_date | ❠ | ✅ | |
221
+ | | p6_checkout_status | ❠ | ✅ | |
222
+ | | p6_global_change_preview | ❠ | ✅ | |
223
+ | | p6_compare_live_to_xer | ❠ | ✅ | |
224
+ | | p6_watch_project | ❠ | ✅ | |
225
+
226
+ *Footnotes:*
227
+ - *Live P6 EPPM backend capabilities may vary depending on P6 EPPM release and configured permissions*
228
+ - *Some older P6 EPPM releases may not implement all REST endpoints (marked with ⚠️ in detailed documentation)*
229
+ - *Mutation tools require explicit `confirm=True` parameter for live P6 EPPM backend*
230
+ - *XER backend supports all tools unless specifically noted as "Live backend only"*
231
+ - *Live P6 EPPM backend supports all standard tools unless specifically noted as "Live P6 EPPM only"*
232
+
233
+ ### 🏗️ Architecture