mcp-eregistrations-bpa 0.8.5__py3-none-any.whl
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.
Potentially problematic release.
This version of mcp-eregistrations-bpa might be problematic. Click here for more details.
- mcp_eregistrations_bpa/__init__.py +121 -0
- mcp_eregistrations_bpa/__main__.py +6 -0
- mcp_eregistrations_bpa/arazzo/__init__.py +21 -0
- mcp_eregistrations_bpa/arazzo/expression.py +379 -0
- mcp_eregistrations_bpa/audit/__init__.py +56 -0
- mcp_eregistrations_bpa/audit/context.py +66 -0
- mcp_eregistrations_bpa/audit/logger.py +236 -0
- mcp_eregistrations_bpa/audit/models.py +131 -0
- mcp_eregistrations_bpa/auth/__init__.py +64 -0
- mcp_eregistrations_bpa/auth/callback.py +391 -0
- mcp_eregistrations_bpa/auth/cas.py +409 -0
- mcp_eregistrations_bpa/auth/oidc.py +252 -0
- mcp_eregistrations_bpa/auth/permissions.py +162 -0
- mcp_eregistrations_bpa/auth/token_manager.py +348 -0
- mcp_eregistrations_bpa/bpa_client/__init__.py +84 -0
- mcp_eregistrations_bpa/bpa_client/client.py +740 -0
- mcp_eregistrations_bpa/bpa_client/endpoints.py +193 -0
- mcp_eregistrations_bpa/bpa_client/errors.py +276 -0
- mcp_eregistrations_bpa/bpa_client/models.py +203 -0
- mcp_eregistrations_bpa/config.py +349 -0
- mcp_eregistrations_bpa/db/__init__.py +21 -0
- mcp_eregistrations_bpa/db/connection.py +64 -0
- mcp_eregistrations_bpa/db/migrations.py +168 -0
- mcp_eregistrations_bpa/exceptions.py +39 -0
- mcp_eregistrations_bpa/py.typed +0 -0
- mcp_eregistrations_bpa/rollback/__init__.py +19 -0
- mcp_eregistrations_bpa/rollback/manager.py +616 -0
- mcp_eregistrations_bpa/server.py +152 -0
- mcp_eregistrations_bpa/tools/__init__.py +372 -0
- mcp_eregistrations_bpa/tools/actions.py +155 -0
- mcp_eregistrations_bpa/tools/analysis.py +352 -0
- mcp_eregistrations_bpa/tools/audit.py +399 -0
- mcp_eregistrations_bpa/tools/behaviours.py +1042 -0
- mcp_eregistrations_bpa/tools/bots.py +627 -0
- mcp_eregistrations_bpa/tools/classifications.py +575 -0
- mcp_eregistrations_bpa/tools/costs.py +765 -0
- mcp_eregistrations_bpa/tools/debug_strategies.py +351 -0
- mcp_eregistrations_bpa/tools/debugger.py +1230 -0
- mcp_eregistrations_bpa/tools/determinants.py +2235 -0
- mcp_eregistrations_bpa/tools/document_requirements.py +670 -0
- mcp_eregistrations_bpa/tools/export.py +899 -0
- mcp_eregistrations_bpa/tools/fields.py +162 -0
- mcp_eregistrations_bpa/tools/form_errors.py +36 -0
- mcp_eregistrations_bpa/tools/formio_helpers.py +971 -0
- mcp_eregistrations_bpa/tools/forms.py +1269 -0
- mcp_eregistrations_bpa/tools/jsonlogic_builder.py +466 -0
- mcp_eregistrations_bpa/tools/large_response.py +163 -0
- mcp_eregistrations_bpa/tools/messages.py +523 -0
- mcp_eregistrations_bpa/tools/notifications.py +241 -0
- mcp_eregistrations_bpa/tools/registration_institutions.py +680 -0
- mcp_eregistrations_bpa/tools/registrations.py +897 -0
- mcp_eregistrations_bpa/tools/role_status.py +447 -0
- mcp_eregistrations_bpa/tools/role_units.py +400 -0
- mcp_eregistrations_bpa/tools/roles.py +1236 -0
- mcp_eregistrations_bpa/tools/rollback.py +335 -0
- mcp_eregistrations_bpa/tools/services.py +674 -0
- mcp_eregistrations_bpa/tools/workflows.py +2487 -0
- mcp_eregistrations_bpa/tools/yaml_transformer.py +991 -0
- mcp_eregistrations_bpa/workflows/__init__.py +28 -0
- mcp_eregistrations_bpa/workflows/loader.py +440 -0
- mcp_eregistrations_bpa/workflows/models.py +336 -0
- mcp_eregistrations_bpa-0.8.5.dist-info/METADATA +965 -0
- mcp_eregistrations_bpa-0.8.5.dist-info/RECORD +66 -0
- mcp_eregistrations_bpa-0.8.5.dist-info/WHEEL +4 -0
- mcp_eregistrations_bpa-0.8.5.dist-info/entry_points.txt +2 -0
- mcp_eregistrations_bpa-0.8.5.dist-info/licenses/LICENSE +86 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
"""Data models for Arazzo workflow definitions.
|
|
2
|
+
|
|
3
|
+
These models represent the parsed structure of Arazzo workflow specifications,
|
|
4
|
+
optimized for MCP tool consumption and workflow execution.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass, field
|
|
10
|
+
from enum import Enum
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class InputType(Enum):
|
|
15
|
+
"""Supported input types for workflow parameters."""
|
|
16
|
+
|
|
17
|
+
STRING = "string"
|
|
18
|
+
INTEGER = "integer"
|
|
19
|
+
NUMBER = "number"
|
|
20
|
+
BOOLEAN = "boolean"
|
|
21
|
+
ARRAY = "array"
|
|
22
|
+
OBJECT = "object"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass
|
|
26
|
+
class WorkflowInput:
|
|
27
|
+
"""Definition of a workflow input parameter.
|
|
28
|
+
|
|
29
|
+
Attributes:
|
|
30
|
+
name: The input parameter name.
|
|
31
|
+
input_type: The type of the input (string, integer, boolean, etc.).
|
|
32
|
+
required: Whether this input is required.
|
|
33
|
+
description: Human-readable description of the input.
|
|
34
|
+
default: Default value if not provided.
|
|
35
|
+
enum_values: List of allowed values for enum inputs.
|
|
36
|
+
pattern: Regex pattern for string validation.
|
|
37
|
+
min_length: Minimum length for string inputs.
|
|
38
|
+
max_length: Maximum length for string inputs.
|
|
39
|
+
minimum: Minimum value for numeric inputs.
|
|
40
|
+
maximum: Maximum value for numeric inputs.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
name: str
|
|
44
|
+
input_type: InputType = InputType.STRING
|
|
45
|
+
required: bool = False
|
|
46
|
+
description: str = ""
|
|
47
|
+
default: Any = None
|
|
48
|
+
enum_values: list[str] | None = None
|
|
49
|
+
pattern: str | None = None
|
|
50
|
+
min_length: int | None = None
|
|
51
|
+
max_length: int | None = None
|
|
52
|
+
minimum: float | None = None
|
|
53
|
+
maximum: float | None = None
|
|
54
|
+
|
|
55
|
+
def to_dict(self) -> dict[str, Any]:
|
|
56
|
+
"""Convert to dictionary for API response."""
|
|
57
|
+
result: dict[str, Any] = {
|
|
58
|
+
"name": self.name,
|
|
59
|
+
"type": self.input_type.value,
|
|
60
|
+
"required": self.required,
|
|
61
|
+
}
|
|
62
|
+
if self.description:
|
|
63
|
+
result["description"] = self.description
|
|
64
|
+
if self.default is not None:
|
|
65
|
+
result["default"] = self.default
|
|
66
|
+
if self.enum_values:
|
|
67
|
+
result["enum"] = self.enum_values
|
|
68
|
+
if self.pattern:
|
|
69
|
+
result["pattern"] = self.pattern
|
|
70
|
+
if self.min_length is not None:
|
|
71
|
+
result["minLength"] = self.min_length
|
|
72
|
+
if self.max_length is not None:
|
|
73
|
+
result["maxLength"] = self.max_length
|
|
74
|
+
if self.minimum is not None:
|
|
75
|
+
result["minimum"] = self.minimum
|
|
76
|
+
if self.maximum is not None:
|
|
77
|
+
result["maximum"] = self.maximum
|
|
78
|
+
return result
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@dataclass
|
|
82
|
+
class WorkflowStep:
|
|
83
|
+
"""Definition of a single step in a workflow.
|
|
84
|
+
|
|
85
|
+
Attributes:
|
|
86
|
+
step_id: Unique identifier for this step within the workflow.
|
|
87
|
+
description: Human-readable description of what this step does.
|
|
88
|
+
operation_id: The BPA API operation ID (optional).
|
|
89
|
+
mcp_tool: The MCP tool to invoke for this step (derived from operationId).
|
|
90
|
+
request_body: The request body template with input references.
|
|
91
|
+
parameters: Path/query parameters for the API call.
|
|
92
|
+
success_criteria: Conditions for step success.
|
|
93
|
+
on_success: Actions to take on success (goto next step, end).
|
|
94
|
+
on_failure: Actions to take on failure.
|
|
95
|
+
outputs: Output mappings from response to step outputs.
|
|
96
|
+
condition: Optional condition for conditional step execution.
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
step_id: str
|
|
100
|
+
description: str = ""
|
|
101
|
+
operation_id: str | None = None
|
|
102
|
+
mcp_tool: str | None = None
|
|
103
|
+
request_body: dict[str, Any] = field(default_factory=dict)
|
|
104
|
+
parameters: list[dict[str, Any]] = field(default_factory=list)
|
|
105
|
+
success_criteria: list[dict[str, Any]] = field(default_factory=list)
|
|
106
|
+
on_success: list[dict[str, Any]] = field(default_factory=list)
|
|
107
|
+
on_failure: list[dict[str, Any]] = field(default_factory=list)
|
|
108
|
+
outputs: dict[str, str] = field(default_factory=dict)
|
|
109
|
+
condition: str | None = None
|
|
110
|
+
|
|
111
|
+
def to_dict(self) -> dict[str, Any]:
|
|
112
|
+
"""Convert to dictionary for API response."""
|
|
113
|
+
result: dict[str, Any] = {
|
|
114
|
+
"step_id": self.step_id,
|
|
115
|
+
"description": self.description,
|
|
116
|
+
}
|
|
117
|
+
if self.mcp_tool:
|
|
118
|
+
result["tool"] = self.mcp_tool
|
|
119
|
+
if self.outputs:
|
|
120
|
+
result["outputs"] = list(self.outputs.keys())
|
|
121
|
+
if self.condition:
|
|
122
|
+
result["condition"] = self.condition
|
|
123
|
+
return result
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@dataclass
|
|
127
|
+
class WorkflowDefinition:
|
|
128
|
+
"""Complete definition of an Arazzo workflow.
|
|
129
|
+
|
|
130
|
+
Attributes:
|
|
131
|
+
workflow_id: Unique identifier for the workflow.
|
|
132
|
+
summary: Short summary of what the workflow does.
|
|
133
|
+
description: Detailed description with usage examples.
|
|
134
|
+
category: Category for grouping related workflows.
|
|
135
|
+
inputs: List of input parameter definitions.
|
|
136
|
+
steps: List of workflow steps to execute.
|
|
137
|
+
outputs: Output mappings from step outputs to workflow outputs.
|
|
138
|
+
failure_actions: Actions to take on workflow failure.
|
|
139
|
+
source_file: Path to the source Arazzo file.
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
workflow_id: str
|
|
143
|
+
summary: str = ""
|
|
144
|
+
description: str = ""
|
|
145
|
+
category: str = "general"
|
|
146
|
+
inputs: list[WorkflowInput] = field(default_factory=list)
|
|
147
|
+
steps: list[WorkflowStep] = field(default_factory=list)
|
|
148
|
+
outputs: dict[str, str] = field(default_factory=dict)
|
|
149
|
+
failure_actions: list[dict[str, Any]] = field(default_factory=list)
|
|
150
|
+
source_file: str = ""
|
|
151
|
+
|
|
152
|
+
@property
|
|
153
|
+
def required_inputs(self) -> list[str]:
|
|
154
|
+
"""Get list of required input names."""
|
|
155
|
+
return [inp.name for inp in self.inputs if inp.required]
|
|
156
|
+
|
|
157
|
+
@property
|
|
158
|
+
def optional_inputs(self) -> list[str]:
|
|
159
|
+
"""Get list of optional input names."""
|
|
160
|
+
return [inp.name for inp in self.inputs if not inp.required]
|
|
161
|
+
|
|
162
|
+
def get_input(self, name: str) -> WorkflowInput | None:
|
|
163
|
+
"""Get input definition by name."""
|
|
164
|
+
for inp in self.inputs:
|
|
165
|
+
if inp.name == name:
|
|
166
|
+
return inp
|
|
167
|
+
return None
|
|
168
|
+
|
|
169
|
+
def to_catalog_entry(self) -> dict[str, Any]:
|
|
170
|
+
"""Convert to catalog entry format (summary view)."""
|
|
171
|
+
return {
|
|
172
|
+
"id": self.workflow_id,
|
|
173
|
+
"summary": self.summary,
|
|
174
|
+
"category": self.category,
|
|
175
|
+
"required_inputs": self.required_inputs,
|
|
176
|
+
"optional_inputs": self.optional_inputs,
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
def to_detail_dict(self) -> dict[str, Any]:
|
|
180
|
+
"""Convert to detailed format for workflow_describe."""
|
|
181
|
+
return {
|
|
182
|
+
"id": self.workflow_id,
|
|
183
|
+
"summary": self.summary,
|
|
184
|
+
"description": self.description,
|
|
185
|
+
"category": self.category,
|
|
186
|
+
"inputs": {inp.name: inp.to_dict() for inp in self.inputs},
|
|
187
|
+
"steps": [step.to_dict() for step in self.steps],
|
|
188
|
+
"outputs": list(self.outputs.keys()),
|
|
189
|
+
"source_file": self.source_file,
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
# Mapping from Arazzo operationId to MCP tool names
|
|
194
|
+
OPERATION_TO_TOOL_MAP: dict[str, str] = {
|
|
195
|
+
# Service operations
|
|
196
|
+
"createService": "service_create",
|
|
197
|
+
"updateService": "service_update",
|
|
198
|
+
"getService": "service_get",
|
|
199
|
+
"listServices": "service_list",
|
|
200
|
+
# Registration operations
|
|
201
|
+
"createRegistration": "registration_create",
|
|
202
|
+
"updateRegistration": "registration_update",
|
|
203
|
+
"getRegistration": "registration_get",
|
|
204
|
+
"listRegistrations": "registration_list",
|
|
205
|
+
# Role operations
|
|
206
|
+
"createRole": "role_create",
|
|
207
|
+
"updateRole": "role_update",
|
|
208
|
+
"deleteRole": "role_delete",
|
|
209
|
+
"getRole": "role_get",
|
|
210
|
+
"listRoles": "role_list",
|
|
211
|
+
# Bot operations
|
|
212
|
+
"createBot": "bot_create",
|
|
213
|
+
"updateBot": "bot_update",
|
|
214
|
+
"getBot": "bot_get",
|
|
215
|
+
"listBots": "bot_list",
|
|
216
|
+
# Determinant operations
|
|
217
|
+
"createTextDeterminant": "textdeterminant_create",
|
|
218
|
+
"updateTextDeterminant": "textdeterminant_update",
|
|
219
|
+
"createSelectDeterminant": "selectdeterminant_create",
|
|
220
|
+
"createNumericDeterminant": "numericdeterminant_create",
|
|
221
|
+
"createBooleanDeterminant": "booleandeterminant_create",
|
|
222
|
+
"createDateDeterminant": "datedeterminant_create",
|
|
223
|
+
"createClassificationDeterminant": "classificationdeterminant_create",
|
|
224
|
+
"createGridDeterminant": "griddeterminant_create",
|
|
225
|
+
"createRadioDeterminant": "selectdeterminant_create",
|
|
226
|
+
"getDeterminant": "determinant_get",
|
|
227
|
+
"listDeterminants": "determinant_list",
|
|
228
|
+
"deleteDeterminant": "determinant_delete",
|
|
229
|
+
# Document requirement operations
|
|
230
|
+
"createDocumentRequirement": "documentrequirement_create",
|
|
231
|
+
"updateDocumentRequirement": "documentrequirement_update",
|
|
232
|
+
"deleteDocumentRequirement": "documentrequirement_delete",
|
|
233
|
+
"listDocumentRequirements": "documentrequirement_list",
|
|
234
|
+
# Cost operations
|
|
235
|
+
"createFixedCost": "cost_create_fixed",
|
|
236
|
+
"createFormulaCost": "cost_create_formula",
|
|
237
|
+
"updateCost": "cost_update",
|
|
238
|
+
"deleteCost": "cost_delete",
|
|
239
|
+
# Field operations
|
|
240
|
+
"getField": "field_get",
|
|
241
|
+
"listFields": "field_list",
|
|
242
|
+
# Service-registration link operations
|
|
243
|
+
"linkServiceRegistration": "serviceregistration_link",
|
|
244
|
+
# Registration institution operations
|
|
245
|
+
"assignRegistrationInstitution": "registrationinstitution_create",
|
|
246
|
+
"listRegistrationInstitutions": "registrationinstitution_list",
|
|
247
|
+
"getRegistrationInstitution": "registrationinstitution_get",
|
|
248
|
+
"deleteRegistrationInstitution": "registrationinstitution_delete",
|
|
249
|
+
# Service lifecycle operations
|
|
250
|
+
"publishService": "service_publish",
|
|
251
|
+
"activateService": "service_activate",
|
|
252
|
+
# Delete operations
|
|
253
|
+
"deleteRegistration": "registration_delete",
|
|
254
|
+
"deleteBot": "bot_delete",
|
|
255
|
+
# Classification operations
|
|
256
|
+
"listClassifications": "classification_list",
|
|
257
|
+
"getClassification": "classification_get",
|
|
258
|
+
"createClassification": "classification_create",
|
|
259
|
+
"updateClassification": "classification_update",
|
|
260
|
+
"exportCatalogToCsv": "classification_export_csv",
|
|
261
|
+
# Notification operations
|
|
262
|
+
"listNotifications": "notification_list",
|
|
263
|
+
"createNotification": "notification_create",
|
|
264
|
+
# Role status operations
|
|
265
|
+
"getRoleStatus": "rolestatus_get",
|
|
266
|
+
"createUserDefinedRoleStatus": "rolestatus_create",
|
|
267
|
+
"updateUserDefinedRoleStatus": "rolestatus_update",
|
|
268
|
+
"deleteRoleStatus": "rolestatus_delete",
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def derive_category(workflow_id: str, summary: str, description: str) -> str:
|
|
273
|
+
"""Derive workflow category from its ID and content.
|
|
274
|
+
|
|
275
|
+
Args:
|
|
276
|
+
workflow_id: The workflow ID.
|
|
277
|
+
summary: The workflow summary.
|
|
278
|
+
description: The workflow description.
|
|
279
|
+
|
|
280
|
+
Returns:
|
|
281
|
+
A category string for grouping.
|
|
282
|
+
"""
|
|
283
|
+
workflow_lower = workflow_id.lower()
|
|
284
|
+
combined = f"{summary} {description}".lower()
|
|
285
|
+
|
|
286
|
+
# Service creation (Story 10-6: catch createCompleteService, createMinimalService)
|
|
287
|
+
if (
|
|
288
|
+
"create" in workflow_lower and "service" in workflow_lower
|
|
289
|
+
) or "create a service" in combined:
|
|
290
|
+
return "service-creation"
|
|
291
|
+
|
|
292
|
+
# Role configuration
|
|
293
|
+
if "role" in workflow_lower or "role" in combined:
|
|
294
|
+
return "roles-configuration"
|
|
295
|
+
|
|
296
|
+
# Bot configuration
|
|
297
|
+
if "bot" in workflow_lower or "automation" in combined:
|
|
298
|
+
return "automation"
|
|
299
|
+
|
|
300
|
+
# Form configuration
|
|
301
|
+
if "form" in workflow_lower or "field" in workflow_lower:
|
|
302
|
+
return "forms"
|
|
303
|
+
|
|
304
|
+
# Payment configuration
|
|
305
|
+
if "payment" in workflow_lower or "cost" in workflow_lower:
|
|
306
|
+
return "payments"
|
|
307
|
+
|
|
308
|
+
# Determinant configuration
|
|
309
|
+
if "determinant" in workflow_lower:
|
|
310
|
+
return "determinants"
|
|
311
|
+
|
|
312
|
+
# Document configuration
|
|
313
|
+
if "document" in workflow_lower:
|
|
314
|
+
return "documents"
|
|
315
|
+
|
|
316
|
+
# Notification configuration
|
|
317
|
+
if "notification" in workflow_lower:
|
|
318
|
+
return "notifications"
|
|
319
|
+
|
|
320
|
+
# Classification configuration (includes catalog operations)
|
|
321
|
+
if "classification" in workflow_lower or "catalog" in workflow_lower:
|
|
322
|
+
return "classifications"
|
|
323
|
+
|
|
324
|
+
# Institution configuration
|
|
325
|
+
if "institution" in workflow_lower:
|
|
326
|
+
return "institutions"
|
|
327
|
+
|
|
328
|
+
# Workflow configuration
|
|
329
|
+
if "workflow" in workflow_lower:
|
|
330
|
+
return "workflow"
|
|
331
|
+
|
|
332
|
+
# Publishing
|
|
333
|
+
if "publish" in workflow_lower:
|
|
334
|
+
return "publishing"
|
|
335
|
+
|
|
336
|
+
return "general"
|