A Python-based MCP server that aligns workflows with Pazi triggers, particularly for invoice processing and tax nexus application workflows
This MCP server has fundamental structural and quality issues. The single tool 'create_workflow' has an overly broad, vague description that fails to guide LLM selection. The input schema is minimal (single string parameter with no validation, enums, or constraints). There is no documented output schema, making it impossible for agents to plan downstream operations. The tool combines multiple conceptual concerns (trigger detection, PDF parsing, tax handling, payment processing) into one operation, violating single-responsibility principle. The implementation is hardcoded business logic with no error handling, validation, or recovery guidance. No parameter constraints exist, the LLM has no guidance on valid trigger formats. The tool lacks idempotency guarantees, confirmation steps for destructive operations (Stripe charges), and permission gates. This is a proof-of-concept-level implementation, not production-grade.
Creates a workflow path based on an action trigger, with special handling for invoice-related triggers that include PDF parsing, tax nexus application, and Stripe charge triggering
No input validation or constraints on action_trigger parameter. LLM has no guidance on valid trigger formats, enums, or patterns. Free-form string invites hallucinated or invalid values.
No documented output schema. Tool returns {'workflow_path': steps} but LLMs cannot see the structure, types, or fields they should expect. Prevents planning of downstream tool calls and result extraction.
Tool description (63 chars) is vague and combines multiple concerns. It mentions 'special handling for invoice-related triggers' but does not explain WHEN to use this tool vs alternatives, WHAT triggers are valid, or what the output contains. Insufficient for LLM tool selection.
Tool performs irreversible side effects (Stripe charge triggering) with no confirmation, dry-run capability, or error recovery guidance. Violates confirmation-request and error-classification patterns. LLMs will trigger charges without safeguards.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 31 | 2026-07-28+ | v2 |
Tool combines five distinct operations: trigger detection, PDF parsing, tax calculation, charge processing, and workflow logging. Violates single-responsibility principle. Should be decomposed into separate tools (detect_trigger, parse_invoice_pdf, apply_tax_nexus, trigger_stripe_charge, log_workflow_step).
No error handling or recovery guidance. Tool returns hardcoded steps with no validation, no status codes, no error messages. If PDF parsing fails or Stripe charge is declined, agent receives no actionable error and cannot retry or correct.
No parameter description for 'action_trigger'. LLM cannot infer valid values, format expectations, or how this parameter affects behavior. Should explain: 'A trigger event name that determines workflow path (e.g., "new invoice uploaded", "payment received", "document approved"). Case-insensitive. Triggers containing "invoice" enable PDF parsing and tax handling.'
Tool name 'create_workflow' is generic and ambiguous. Does not convey what kind of workflow or what triggers it. Better names: 'align_action_trigger_to_workflow_steps', 'build_invoice_workflow_path', or 'route_trigger_to_workflow'. Current name provides no signal about invoice/Stripe handling.
No idempotency guarantee. Calling this tool twice with identical trigger may execute payment or PDF operations twice, risking duplicate charges or duplicate state. Tool must declare idempotency or implement request deduplication.
No permission gating. Tool triggers Stripe charges without validating caller permissions. Should check 'write:payments' or 'admin' scope before initiating charge. Currently any agent can spend money.
Response is a list of string steps, not structured objects. LLM cannot extract IDs, timestamps, statuses, or next-step references. Output should be: {"workflow_id": "<id>", "steps": [{"name": "<step>", "status": "<status>", "order": <int>}], "requires_confirmation": <bool>}.