Static source inference · medium confidence · evidence: Streamable HTTP
Current-spec patterns detected
Summary
PyP6Xer MCP demonstrates solid tool organization with 18 well-named, verb-prefixed tools covering a coherent domain (Primavera P6 XER schedule analysis). All tools have descriptions (100-200 chars, well-balanced). Input schemas are present and properly typed for all tools. However, output schemas are not explicitly documented in the source code, only inferred from descriptions. Error handling is minimal (no recovery guidance, no actionable error messages visible). Tool names follow verb_noun convention consistently (load_file, list_projects, get_activity, search_activities, etc.), which aids LLM comprehension. Parameters are well-described with types and constraints (e.g., date formats YYYY-MM-DD, enums for status/type/relationship_type). Cache-key pattern is a domain-specific design choice that works but is less intuitive than built-in session management. The server does not include permission gates or audit logging despite having destructive operations (delete_activity, delete_relationship). Composition is clean, each tool does one job; however, there is no evidence of multi-step confirmation or dry-run patterns for irreversible operations.
Tools (18)
pyp6xer_add_relationshipwrite50/100
Add a dependency relationship between two activities.
pyp6xer_compare_schedulesread only50/100
Compare two loaded XER schedules and identify differences.
pyp6xer_create_activitywrite50/100
Create a new activity in the schedule.
pyp6xer_delete_activitydestructive50/100
Delete an activity from the schedule.
pyp6xer_delete_relationshipwrite50/100
Delete a dependency relationship between two activities.
Output schemas not documented in source code. While tool descriptions imply structure (e.g., 'List all activities' suggests an array of activity objects), the actual return types, field names, pagination behavior, and nested structures are not explicitly defined in the provided code. LLMs cannot reliably plan downstream operations without documented schemas.
No error recovery guidance in tool descriptions. Tools do not document what errors can occur, how to classify them (retryable vs. fatal), or what corrective action the LLM should take. For example, pyp6xer_delete_activity offers no guidance on 'file not found', 'activity not found', or permission-related failures.
Document output schemas for all tools. For each tool, explicitly declare the response structure: field names, types (string, number, boolean, array, object), nested structure, and pagination (if applicable). Use this format in the tool description or a separate schema block: 'Returns: {activity: {task_id: string, name: string, status: 'Not Started'|'In Progress'|'Completed', ...}, count: number}'.
Add error handling guidance to tool descriptions for write and destructive operations. Example: 'Error handling: Returns 404 if project or activity not found (user-fixable, verify project ID via pyp6xer_list_projects); 409 if activity has dependencies (suggest removing relationships first); 500 on file I/O errors (retryable). Always check error message for recovery steps.'
Implement a dry-run or confirmation mechanism for pyp6xer_delete_activity and pyp6xer_delete_relationship. Add an optional 'confirm' parameter (default false) or a separate 'preview_deletion' endpoint that shows what would be deleted without executing. Example: 'Set confirm=true only after reviewing the deletion preview. Deletions are irreversible.'
Add permission gating and audit logging. Before executing write or destructive operations, check that the calling context (derived from MCP handshake metadata or a passed authorization token) has the required scope (e.g., 'write:schedule', 'admin:schedule'). Log all modifications to stderr or a metrics endpoint with user, timestamp, operation, and result for compliance.
Simplify cache management. Consider storing the most recently loaded file in a default context so simple queries do not require cache_key. Document the cache-key pattern explicitly: 'Multiple files can be loaded simultaneously. Each file gets a unique cache_key. If omitted, the tool uses cache_key='default'. Cache is per-session and cleared when the server restarts.'
Score history
Overall score trend
First recorded score · v2 rubric
63/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-23
C
63
2026-07-28+
v2
read only50/100
Filter activities by various criteria (status, type, critical path, date range).
Destructive operations lack confirmation/dry-run pattern. pyp6xer_delete_activity and pyp6xer_delete_relationship provide no dry-run or confirmation step. Agents can accidentally delete schedule data without a safety mechanism.
No permission gating or audit logging. The server does not verify user/agent authorization before executing destructive operations (delete_activity, delete_relationship). No audit trail is visible for compliance or incident response. This is a critical security gap.
Cache-key pattern is non-standard. Most MCP servers use session management or request-level context. Requiring LLMs to track cache_key strings across calls is unintuitive and error-prone. Descriptions for cache_key mention 'default' but don't explain the implications of cache-key conflicts or cache eviction.
Brief descriptions for discovery and output tools. Tools like pyp6xer_list_projects ('List all projects in a loaded XER file'), pyp6xer_get_critical_path ('Get the critical path activities from the schedule'), and pyp6xer_metrics ('Get schedule metrics and statistics') are under 100 characters. While not critically short, they lack context hints like 'Call this first to discover available projects' or 'Returns project IDs needed for other queries.'
Enhance descriptions for discovery tools. Add phrases like 'Start here to enumerate available projects before filtering' (list_projects) and 'Call this after loading a file to understand schedule structure' (metrics). This guides LLMs toward optimal call sequencing.
Add pagination parameters (limit, offset) to list_activities, search_activities, and filter_activities if results can exceed 50 items. Document: 'Returns up to 50 activities; use offset to fetch additional batches. Includes total count for pagination.'
Validate and normalize date inputs. For parameters like start_after and start_before, explicitly accept ISO 8601 dates (YYYY-MM-DD) and return actionable errors: 'Invalid start_after: got "2024/1/15", use YYYY-MM-DD format, e.g., "2024-01-15".'
Include relationship/chaining IDs in all responses. If an LLM retrieves an activity and later needs to fetch its successors, the activity response must include task_id, proj_id, and cache_key so the next call is one-shot.
Document parameter interdependencies. For filter_activities, clarify: 'All filter parameters are optional (OR logic). If both start_after and start_before are provided, only activities in that date range are returned. If neither is set, all activities are included regardless of dates.'