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.

Files changed (66) hide show
  1. mcp_eregistrations_bpa/__init__.py +121 -0
  2. mcp_eregistrations_bpa/__main__.py +6 -0
  3. mcp_eregistrations_bpa/arazzo/__init__.py +21 -0
  4. mcp_eregistrations_bpa/arazzo/expression.py +379 -0
  5. mcp_eregistrations_bpa/audit/__init__.py +56 -0
  6. mcp_eregistrations_bpa/audit/context.py +66 -0
  7. mcp_eregistrations_bpa/audit/logger.py +236 -0
  8. mcp_eregistrations_bpa/audit/models.py +131 -0
  9. mcp_eregistrations_bpa/auth/__init__.py +64 -0
  10. mcp_eregistrations_bpa/auth/callback.py +391 -0
  11. mcp_eregistrations_bpa/auth/cas.py +409 -0
  12. mcp_eregistrations_bpa/auth/oidc.py +252 -0
  13. mcp_eregistrations_bpa/auth/permissions.py +162 -0
  14. mcp_eregistrations_bpa/auth/token_manager.py +348 -0
  15. mcp_eregistrations_bpa/bpa_client/__init__.py +84 -0
  16. mcp_eregistrations_bpa/bpa_client/client.py +740 -0
  17. mcp_eregistrations_bpa/bpa_client/endpoints.py +193 -0
  18. mcp_eregistrations_bpa/bpa_client/errors.py +276 -0
  19. mcp_eregistrations_bpa/bpa_client/models.py +203 -0
  20. mcp_eregistrations_bpa/config.py +349 -0
  21. mcp_eregistrations_bpa/db/__init__.py +21 -0
  22. mcp_eregistrations_bpa/db/connection.py +64 -0
  23. mcp_eregistrations_bpa/db/migrations.py +168 -0
  24. mcp_eregistrations_bpa/exceptions.py +39 -0
  25. mcp_eregistrations_bpa/py.typed +0 -0
  26. mcp_eregistrations_bpa/rollback/__init__.py +19 -0
  27. mcp_eregistrations_bpa/rollback/manager.py +616 -0
  28. mcp_eregistrations_bpa/server.py +152 -0
  29. mcp_eregistrations_bpa/tools/__init__.py +372 -0
  30. mcp_eregistrations_bpa/tools/actions.py +155 -0
  31. mcp_eregistrations_bpa/tools/analysis.py +352 -0
  32. mcp_eregistrations_bpa/tools/audit.py +399 -0
  33. mcp_eregistrations_bpa/tools/behaviours.py +1042 -0
  34. mcp_eregistrations_bpa/tools/bots.py +627 -0
  35. mcp_eregistrations_bpa/tools/classifications.py +575 -0
  36. mcp_eregistrations_bpa/tools/costs.py +765 -0
  37. mcp_eregistrations_bpa/tools/debug_strategies.py +351 -0
  38. mcp_eregistrations_bpa/tools/debugger.py +1230 -0
  39. mcp_eregistrations_bpa/tools/determinants.py +2235 -0
  40. mcp_eregistrations_bpa/tools/document_requirements.py +670 -0
  41. mcp_eregistrations_bpa/tools/export.py +899 -0
  42. mcp_eregistrations_bpa/tools/fields.py +162 -0
  43. mcp_eregistrations_bpa/tools/form_errors.py +36 -0
  44. mcp_eregistrations_bpa/tools/formio_helpers.py +971 -0
  45. mcp_eregistrations_bpa/tools/forms.py +1269 -0
  46. mcp_eregistrations_bpa/tools/jsonlogic_builder.py +466 -0
  47. mcp_eregistrations_bpa/tools/large_response.py +163 -0
  48. mcp_eregistrations_bpa/tools/messages.py +523 -0
  49. mcp_eregistrations_bpa/tools/notifications.py +241 -0
  50. mcp_eregistrations_bpa/tools/registration_institutions.py +680 -0
  51. mcp_eregistrations_bpa/tools/registrations.py +897 -0
  52. mcp_eregistrations_bpa/tools/role_status.py +447 -0
  53. mcp_eregistrations_bpa/tools/role_units.py +400 -0
  54. mcp_eregistrations_bpa/tools/roles.py +1236 -0
  55. mcp_eregistrations_bpa/tools/rollback.py +335 -0
  56. mcp_eregistrations_bpa/tools/services.py +674 -0
  57. mcp_eregistrations_bpa/tools/workflows.py +2487 -0
  58. mcp_eregistrations_bpa/tools/yaml_transformer.py +991 -0
  59. mcp_eregistrations_bpa/workflows/__init__.py +28 -0
  60. mcp_eregistrations_bpa/workflows/loader.py +440 -0
  61. mcp_eregistrations_bpa/workflows/models.py +336 -0
  62. mcp_eregistrations_bpa-0.8.5.dist-info/METADATA +965 -0
  63. mcp_eregistrations_bpa-0.8.5.dist-info/RECORD +66 -0
  64. mcp_eregistrations_bpa-0.8.5.dist-info/WHEEL +4 -0
  65. mcp_eregistrations_bpa-0.8.5.dist-info/entry_points.txt +2 -0
  66. mcp_eregistrations_bpa-0.8.5.dist-info/licenses/LICENSE +86 -0
@@ -0,0 +1,162 @@
1
+ """MCP tools for BPA field operations.
2
+
3
+ This module provides tools for listing and retrieving BPA form fields.
4
+ Fields are accessed through service endpoints (service-centric API design).
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import Any
10
+
11
+ from mcp.server.fastmcp.exceptions import ToolError
12
+
13
+ from mcp_eregistrations_bpa.bpa_client import BPAClient
14
+ from mcp_eregistrations_bpa.bpa_client.errors import (
15
+ BPAClientError,
16
+ BPANotFoundError,
17
+ translate_error,
18
+ )
19
+ from mcp_eregistrations_bpa.tools.large_response import large_response_handler
20
+
21
+ __all__ = ["field_list", "field_get", "register_field_tools"]
22
+
23
+
24
+ @large_response_handler(
25
+ threshold_bytes=50 * 1024, # 50KB threshold for list tools
26
+ navigation={
27
+ "list_all": "jq '.fields'",
28
+ "find_by_type": "jq '.fields[] | select(.type == \"textfield\")'",
29
+ "find_by_key": "jq '.fields[] | select(.key | contains(\"search\"))'",
30
+ "required_only": "jq '.fields[] | select(.required == true)'",
31
+ },
32
+ )
33
+ async def field_list(
34
+ service_id: str | int,
35
+ limit: int = 50,
36
+ offset: int = 0,
37
+ type_filter: str | None = None,
38
+ required_only: bool = False,
39
+ ) -> dict[str, Any]:
40
+ """List fields for a service with pagination and filtering.
41
+
42
+ Large responses (>50KB) are saved to file with navigation hints.
43
+
44
+ Args:
45
+ service_id: The service ID to list fields for.
46
+ limit: Maximum number of fields to return (default: 50).
47
+ offset: Number of fields to skip (default: 0).
48
+ type_filter: Filter by field type (e.g., "select", "textfield").
49
+ required_only: Filter to only required fields (default: False).
50
+
51
+ Returns:
52
+ dict with fields, total, has_more, service_id.
53
+ """
54
+ # Normalize pagination parameters
55
+ if limit <= 0:
56
+ limit = 50
57
+ if offset < 0:
58
+ offset = 0
59
+
60
+ try:
61
+ async with BPAClient() as client:
62
+ fields_data = await client.get_list(
63
+ "/service/{service_id}/fields",
64
+ path_params={"service_id": service_id},
65
+ resource_type="field",
66
+ )
67
+ except BPAClientError as e:
68
+ raise translate_error(e, resource_type="field")
69
+
70
+ # Transform to consistent output format with snake_case keys
71
+ all_fields = []
72
+ for field in fields_data:
73
+ field_obj: dict[str, Any] = {
74
+ "key": field.get("key"),
75
+ "name": field.get("name"),
76
+ "type": field.get("type"),
77
+ "required": field.get("required", False),
78
+ "label": field.get("label"),
79
+ }
80
+ # Only include component_key if it has a value (remove null noise)
81
+ if field.get("componentKey"):
82
+ field_obj["component_key"] = field.get("componentKey")
83
+ all_fields.append(field_obj)
84
+
85
+ # Apply filters before sorting/pagination
86
+ if type_filter is not None:
87
+ all_fields = [f for f in all_fields if f.get("type") == type_filter]
88
+
89
+ if required_only:
90
+ all_fields = [f for f in all_fields if f.get("required") is True]
91
+
92
+ # Sort by key for consistent pagination ordering
93
+ all_fields.sort(key=lambda f: f.get("key") or "")
94
+
95
+ # Calculate total before pagination
96
+ total = len(all_fields)
97
+
98
+ # Apply pagination
99
+ paginated_fields = all_fields[offset : offset + limit]
100
+
101
+ # Calculate has_more
102
+ has_more = (offset + limit) < total
103
+
104
+ return {
105
+ "fields": paginated_fields,
106
+ "total": total,
107
+ "has_more": has_more,
108
+ "service_id": service_id,
109
+ }
110
+
111
+
112
+ async def field_get(service_id: str | int, field_key: str) -> dict[str, Any]:
113
+ """Get details of a BPA field by service ID and field key.
114
+
115
+ Args:
116
+ service_id: The service containing the field.
117
+ field_key: The field key/identifier within the service.
118
+
119
+ Returns:
120
+ dict with key, name, label, type, required, component_key, service_id.
121
+ """
122
+ try:
123
+ async with BPAClient() as client:
124
+ try:
125
+ field_data = await client.get(
126
+ "/service/{service_id}/fields/{field_key}",
127
+ path_params={"service_id": service_id, "field_key": field_key},
128
+ resource_type="field",
129
+ resource_id=field_key,
130
+ )
131
+ except BPANotFoundError:
132
+ raise ToolError(
133
+ f"Field '{field_key}' not found in service '{service_id}'. "
134
+ "Use 'field_list' with the service_id to see available fields."
135
+ )
136
+ except ToolError:
137
+ raise
138
+ except BPAClientError as e:
139
+ raise translate_error(e, resource_type="field", resource_id=field_key)
140
+
141
+ result = {
142
+ "key": field_data.get("key"),
143
+ "name": field_data.get("name"),
144
+ "label": field_data.get("label"),
145
+ "type": field_data.get("type"),
146
+ "required": field_data.get("required", False),
147
+ "service_id": service_id,
148
+ }
149
+ # Only include component_key if it has a value (remove null noise)
150
+ if field_data.get("componentKey"):
151
+ result["component_key"] = field_data.get("componentKey")
152
+ return result
153
+
154
+
155
+ def register_field_tools(mcp: Any) -> None:
156
+ """Register field tools with the MCP server.
157
+
158
+ Args:
159
+ mcp: The FastMCP server instance.
160
+ """
161
+ mcp.tool()(field_list)
162
+ mcp.tool()(field_get)
@@ -0,0 +1,36 @@
1
+ """Form tool error codes for programmatic handling.
2
+
3
+ This module defines error codes for Form MCP tool operations.
4
+ Error codes follow the format: FORM_XXX where XXX is a 3-digit number.
5
+
6
+ Usage in ToolError messages:
7
+ raise ToolError(f"[{FormErrorCode.DUPLICATE_KEY}] Component key already exists")
8
+
9
+ The format "[ERROR_CODE] message" allows automation tools to:
10
+ 1. Parse the error code programmatically
11
+ 2. Handle specific error types differently
12
+ 3. Provide localized error messages
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+
18
+ class FormErrorCode:
19
+ """Error codes for Form MCP tool operations.
20
+
21
+ Error codes are strings in the format FORM_XXX.
22
+ """
23
+
24
+ # Validation errors (001-010)
25
+ INVALID_FORM_TYPE = "FORM_001"
26
+ SERVICE_NOT_FOUND = "FORM_002"
27
+ COMPONENT_NOT_FOUND = "FORM_003"
28
+ DUPLICATE_KEY = "FORM_004"
29
+ INVALID_PARENT = "FORM_005"
30
+ MISSING_REQUIRED_PROPERTY = "FORM_006"
31
+ KEY_CHANGE_NOT_ALLOWED = "FORM_007"
32
+ INVALID_POSITION = "FORM_008"
33
+ CIRCULAR_REFERENCE = "FORM_009"
34
+
35
+ # Additional operation errors (010-020)
36
+ NO_UPDATES_PROVIDED = "FORM_010"