universal-mcp 0.1.8rc4__py3-none-any.whl → 0.1.9rc1__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.
Files changed (38) hide show
  1. universal_mcp/applications/__init__.py +7 -2
  2. universal_mcp/applications/application.py +162 -114
  3. universal_mcp/applications/cal_com_v2/README.md +175 -0
  4. universal_mcp/applications/cal_com_v2/__init__.py +0 -0
  5. universal_mcp/applications/cal_com_v2/app.py +4735 -0
  6. universal_mcp/applications/clickup/README.md +160 -0
  7. universal_mcp/applications/clickup/__init__.py +0 -0
  8. universal_mcp/applications/clickup/app.py +4359 -0
  9. universal_mcp/applications/hashnode/app.py +77 -0
  10. universal_mcp/applications/hashnode/prompt.md +21 -0
  11. universal_mcp/applications/mailchimp/README.md +306 -0
  12. universal_mcp/applications/mailchimp/__init__.py +0 -0
  13. universal_mcp/applications/mailchimp/app.py +8883 -0
  14. universal_mcp/applications/markitdown/app.py +2 -2
  15. universal_mcp/applications/perplexity/app.py +0 -1
  16. universal_mcp/applications/replicate/README.md +53 -0
  17. universal_mcp/applications/replicate/app.py +969 -0
  18. universal_mcp/applications/retell_ai/README.md +46 -0
  19. universal_mcp/applications/retell_ai/__init__.py +0 -0
  20. universal_mcp/applications/retell_ai/app.py +316 -0
  21. universal_mcp/applications/rocketlane/README.md +42 -0
  22. universal_mcp/applications/rocketlane/__init__.py +0 -0
  23. universal_mcp/applications/rocketlane/app.py +180 -0
  24. universal_mcp/applications/spotify/README.md +116 -0
  25. universal_mcp/applications/spotify/__init__.py +0 -0
  26. universal_mcp/applications/spotify/app.py +2231 -0
  27. universal_mcp/applications/supabase/README.md +112 -0
  28. universal_mcp/applications/supabase/__init__.py +0 -0
  29. universal_mcp/applications/supabase/app.py +2644 -0
  30. universal_mcp/integrations/integration.py +1 -1
  31. universal_mcp/servers/server.py +3 -3
  32. universal_mcp/stores/store.py +7 -0
  33. universal_mcp/tools/tools.py +2 -2
  34. universal_mcp/utils/docstring_parser.py +171 -104
  35. {universal_mcp-0.1.8rc4.dist-info → universal_mcp-0.1.9rc1.dist-info}/METADATA +2 -1
  36. {universal_mcp-0.1.8rc4.dist-info → universal_mcp-0.1.9rc1.dist-info}/RECORD +38 -13
  37. {universal_mcp-0.1.8rc4.dist-info → universal_mcp-0.1.9rc1.dist-info}/WHEEL +0 -0
  38. {universal_mcp-0.1.8rc4.dist-info → universal_mcp-0.1.9rc1.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,46 @@
1
+
2
+ # Retell Ai MCP Server
3
+
4
+ An MCP Server for the Retell Ai API.
5
+
6
+ ## Supported Integrations
7
+
8
+ - AgentR
9
+ - API Key (Coming Soon)
10
+ - OAuth (Coming Soon)
11
+
12
+ ## Tools
13
+
14
+ This is automatically generated from OpenAPI schema for the Retell Ai API.
15
+
16
+ ## Supported Integrations
17
+
18
+ This tool can be integrated with any service that supports HTTP requests.
19
+
20
+ ## Tool List
21
+
22
+ | Tool | Description |
23
+ |------|-------------|
24
+ | get_v2_get_call_by_call_id | Retrieve detailed information about a specific call using its call ID. |
25
+ | post_v2_create_phone_call | Initiates a phone call using a JSON payload with specified parameters. |
26
+ | post_v2_create_web_call | Creates a web call via a POST request to the v2 endpoint with specified agent ID and optional metadata or dynamic variables. |
27
+ | get_get_voice_by_voice_id | Fetches voice details based on the provided voice ID. |
28
+ | post_v2_list_calls | Sends a POST request to list call records with optional filtering, sorting, pagination, and limits. |
29
+ | post_create_phone_number | Creates a phone number with the specified area code and optional parameters. |
30
+ | get_get_phone_number_by_phone_number | Retrieves phone number details by making a GET request to the API endpoint using the provided phone number. |
31
+ | get_list_phone_numbers | Retrieves a list of phone numbers from the remote API. |
32
+ | patch_update_phone_number_by_phone_number | Updates the information of a phone number by its number, allowing optional modification of inbound and outbound agent IDs and nickname. |
33
+ | delete_delete_phone_number_by_phone_number | Deletes a phone number resource by its phone number identifier via an HTTP DELETE request. |
34
+
35
+
36
+
37
+ ## Usage
38
+
39
+ - Login to AgentR
40
+ - Follow the quickstart guide to setup MCP Server for your client
41
+ - Visit Apps Store and enable the Retell Ai app
42
+ - Restart the MCP Server
43
+
44
+ ### Local Development
45
+
46
+ - Follow the README to test with the local MCP Server
File without changes
@@ -0,0 +1,316 @@
1
+ from typing import Any
2
+
3
+ from universal_mcp.applications import APIApplication
4
+ from universal_mcp.integrations import Integration
5
+
6
+
7
+ class RetellAiApp(APIApplication):
8
+ def __init__(self, integration: Integration = None, **kwargs) -> None:
9
+ super().__init__(name='retell-ai', integration=integration, **kwargs)
10
+ self.base_url = "https://api.retellai.com"
11
+
12
+ def get_v2_get_call_by_call_id(self, call_id) -> dict[str, Any]:
13
+ """
14
+ Retrieve detailed information about a specific call using its call ID.
15
+
16
+ Args:
17
+ call_id: The unique identifier of the call to retrieve. Must not be None.
18
+
19
+ Returns:
20
+ A dictionary containing the details of the requested call as returned by the API.
21
+
22
+ Raises:
23
+ ValueError: If the 'call_id' parameter is None.
24
+ HTTPError: If the HTTP request to the API fails or returns an unsuccessful status code.
25
+
26
+ Tags:
27
+ get, call, api, important
28
+ """
29
+ if call_id is None:
30
+ raise ValueError("Missing required parameter 'call_id'")
31
+ url = f"{self.base_url}/v2/get-call/{call_id}"
32
+ query_params = {}
33
+ response = self._get(url, params=query_params)
34
+ response.raise_for_status()
35
+ return response.json()
36
+
37
+ def post_v2_create_phone_call(self, from_number, to_number, override_agent_id=None, metadata=None, retell_llm_dynamic_variables=None) -> dict[str, Any]:
38
+ """
39
+ Initiates a phone call using a JSON payload with specified parameters.
40
+
41
+ Args:
42
+ from_number: The source number for the call.
43
+ to_number: The destination number for the call.
44
+ override_agent_id: Optional ID for overriding the default agent.
45
+ metadata: Optional metadata to be included with the call request.
46
+ retell_llm_dynamic_variables: Optional dynamic variables for LLM (Large Language Model) processing.
47
+
48
+ Returns:
49
+ A dictionary containing the response data for the created phone call.
50
+
51
+ Raises:
52
+ ValueError: Raised if either 'from_number' or 'to_number' is missing.
53
+
54
+ Tags:
55
+ initiate, create-call, async_job, management, important
56
+ """
57
+ if from_number is None:
58
+ raise ValueError("Missing required parameter 'from_number'")
59
+ if to_number is None:
60
+ raise ValueError("Missing required parameter 'to_number'")
61
+ request_body = {
62
+ 'from_number': from_number,
63
+ 'to_number': to_number,
64
+ 'override_agent_id': override_agent_id,
65
+ 'metadata': metadata,
66
+ 'retell_llm_dynamic_variables': retell_llm_dynamic_variables,
67
+ }
68
+ request_body = {k: v for k, v in request_body.items() if v is not None}
69
+ url = f"{self.base_url}/v2/create-phone-call"
70
+ query_params = {}
71
+ response = self._post(url, data=request_body, params=query_params)
72
+ response.raise_for_status()
73
+ return response.json()
74
+
75
+ def post_v2_create_web_call(self, agent_id, metadata=None, retell_llm_dynamic_variables=None) -> dict[str, Any]:
76
+ """
77
+ Creates a web call via a POST request to the v2 endpoint with specified agent ID and optional metadata or dynamic variables.
78
+
79
+ Args:
80
+ agent_id: Required identifier of the agent initiating the web call.
81
+ metadata: Optional metadata to include in the web call request.
82
+ retell_llm_dynamic_variables: Optional dynamic variables for LLN model customization.
83
+
84
+ Returns:
85
+ A dictionary containing the response details from the web call creation request.
86
+
87
+ Raises:
88
+ ValueError: Raised when the required 'agent_id' parameter is missing.
89
+
90
+ Tags:
91
+ create, web-calls, api-call, important
92
+ """
93
+ if agent_id is None:
94
+ raise ValueError("Missing required parameter 'agent_id'")
95
+ request_body = {
96
+ 'agent_id': agent_id,
97
+ 'metadata': metadata,
98
+ 'retell_llm_dynamic_variables': retell_llm_dynamic_variables,
99
+ }
100
+ request_body = {k: v for k, v in request_body.items() if v is not None}
101
+ url = f"{self.base_url}/v2/create-web-call"
102
+ query_params = {}
103
+ response = self._post(url, data=request_body, params=query_params)
104
+ response.raise_for_status()
105
+ return response.json()
106
+
107
+ def get_get_voice_by_voice_id(self, voice_id) -> dict[str, Any]:
108
+ """
109
+ Fetches voice details based on the provided voice ID.
110
+
111
+ Args:
112
+ voice_id: The unique identifier of the voice to retrieve.
113
+
114
+ Returns:
115
+ A dictionary containing voice details.
116
+
117
+ Raises:
118
+ ValueError: Raised when the 'voice_id' parameter is missing or None.
119
+
120
+ Tags:
121
+ retrieve, voice, important, data-fetched
122
+ """
123
+ if voice_id is None:
124
+ raise ValueError("Missing required parameter 'voice_id'")
125
+ url = f"{self.base_url}/get-voice/{voice_id}"
126
+ query_params = {}
127
+ response = self._get(url, params=query_params)
128
+ response.raise_for_status()
129
+ return response.json()
130
+
131
+ def post_v2_list_calls(self, filter_criteria=None, sort_order=None, limit=None, pagination_key=None) -> list[Any]:
132
+ """
133
+ Sends a POST request to list call records with optional filtering, sorting, pagination, and limits.
134
+
135
+ Args:
136
+ filter_criteria: Optional dictionary specifying filter conditions for returned call records.
137
+ sort_order: Optional sorting instructions (e.g., by date or status) for the call records.
138
+ limit: Optional integer specifying the maximum number of call records to return.
139
+ pagination_key: Optional key indicating where to continue fetching records for paginated results.
140
+
141
+ Returns:
142
+ A list of call record objects returned from the API.
143
+
144
+ Raises:
145
+ HTTPError: If the HTTP request to the remote service fails or returns an error status code.
146
+
147
+ Tags:
148
+ list, calls, api, batch, management, important
149
+ """
150
+ request_body = {
151
+ 'filter_criteria': filter_criteria,
152
+ 'sort_order': sort_order,
153
+ 'limit': limit,
154
+ 'pagination_key': pagination_key,
155
+ }
156
+ request_body = {k: v for k, v in request_body.items() if v is not None}
157
+ url = f"{self.base_url}/v2/list-calls"
158
+ query_params = {}
159
+ response = self._post(url, data=request_body, params=query_params)
160
+ response.raise_for_status()
161
+ return response.json()
162
+
163
+ def post_create_phone_number(self, area_code, inbound_agent_id=None, outbound_agent_id=None, nickname=None) -> dict[str, Any]:
164
+ """
165
+ Creates a phone number with the specified area code and optional parameters.
166
+
167
+ Args:
168
+ area_code: The area code for the phone number (required).
169
+ inbound_agent_id: The ID of the agent to handle inbound calls (optional).
170
+ outbound_agent_id: The ID of the agent to handle outbound calls (optional).
171
+ nickname: A user-friendly name for the phone number (optional).
172
+
173
+ Returns:
174
+ A dictionary containing the created phone number details and any associated metadata.
175
+
176
+ Raises:
177
+ ValueError: When the required parameter 'area_code' is None or not provided.
178
+ HTTPError: When the API request fails with an error status code.
179
+
180
+ Tags:
181
+ create, phone, post, communication, important
182
+ """
183
+ if area_code is None:
184
+ raise ValueError("Missing required parameter 'area_code'")
185
+ request_body = {
186
+ 'inbound_agent_id': inbound_agent_id,
187
+ 'outbound_agent_id': outbound_agent_id,
188
+ 'area_code': area_code,
189
+ 'nickname': nickname,
190
+ }
191
+ request_body = {k: v for k, v in request_body.items() if v is not None}
192
+ url = f"{self.base_url}/create-phone-number"
193
+ query_params = {}
194
+ response = self._post(url, data=request_body, params=query_params)
195
+ response.raise_for_status()
196
+ return response.json()
197
+
198
+ def get_get_phone_number_by_phone_number(self, phone_number) -> dict[str, Any]:
199
+ """
200
+ Retrieves phone number details by making a GET request to the API endpoint using the provided phone number.
201
+
202
+ Args:
203
+ phone_number: str. The phone number to look up. Must not be None.
204
+
205
+ Returns:
206
+ dict[str, Any]: A dictionary containing the details associated with the given phone number as returned by the API.
207
+
208
+ Raises:
209
+ ValueError: If the 'phone_number' parameter is None.
210
+ requests.HTTPError: If the HTTP request fails or an error response is returned from the API.
211
+
212
+ Tags:
213
+ get, phone-number, api, lookup, important
214
+ """
215
+ if phone_number is None:
216
+ raise ValueError("Missing required parameter 'phone_number'")
217
+ url = f"{self.base_url}/get-phone-number/{phone_number}"
218
+ query_params = {}
219
+ response = self._get(url, params=query_params)
220
+ response.raise_for_status()
221
+ return response.json()
222
+
223
+ def get_list_phone_numbers(self, ) -> list[Any]:
224
+ """
225
+ Retrieves a list of phone numbers from the remote API.
226
+
227
+ Args:
228
+ None: This function takes no arguments
229
+
230
+ Returns:
231
+ A list containing the phone numbers returned by the API.
232
+
233
+ Raises:
234
+ requests.HTTPError: If the HTTP request to the API fails or returns an unsuccessful status code.
235
+
236
+ Tags:
237
+ get, list, phone-numbers, api, synchronous, important
238
+ """
239
+ url = f"{self.base_url}/list-phone-numbers"
240
+ query_params = {}
241
+ response = self._get(url, params=query_params)
242
+ response.raise_for_status()
243
+ return response.json()
244
+
245
+ def patch_update_phone_number_by_phone_number(self, phone_number, inbound_agent_id=None, outbound_agent_id=None, nickname=None) -> dict[str, Any]:
246
+ """
247
+ Updates the information of a phone number by its number, allowing optional modification of inbound and outbound agent IDs and nickname.
248
+
249
+ Args:
250
+ phone_number: str. The phone number to update. This parameter is required.
251
+ inbound_agent_id: Optional[str]. The ID of the inbound agent to associate with the phone number. If None, this field will not be updated.
252
+ outbound_agent_id: Optional[str]. The ID of the outbound agent to associate with the phone number. If None, this field will not be updated.
253
+ nickname: Optional[str]. The nickname to assign to the phone number. If None, this field will not be updated.
254
+
255
+ Returns:
256
+ dict[str, Any]: A dictionary containing the updated phone number information as returned by the API.
257
+
258
+ Raises:
259
+ ValueError: If the required parameter 'phone_number' is not provided.
260
+ requests.HTTPError: If the HTTP PATCH request fails or the response has an error status.
261
+
262
+ Tags:
263
+ update, phone-number, api, patch, management
264
+ """
265
+ if phone_number is None:
266
+ raise ValueError("Missing required parameter 'phone_number'")
267
+ request_body = {
268
+ 'inbound_agent_id': inbound_agent_id,
269
+ 'outbound_agent_id': outbound_agent_id,
270
+ 'nickname': nickname,
271
+ }
272
+ request_body = {k: v for k, v in request_body.items() if v is not None}
273
+ url = f"{self.base_url}/update-phone-number/{phone_number}"
274
+ query_params = {}
275
+ response = self._patch(url, data=request_body, params=query_params)
276
+ response.raise_for_status()
277
+ return response.json()
278
+
279
+ def delete_delete_phone_number_by_phone_number(self, phone_number) -> Any:
280
+ """
281
+ Deletes a phone number resource by its phone number identifier via an HTTP DELETE request.
282
+
283
+ Args:
284
+ phone_number: The phone number (str or compatible type) identifying the resource to be deleted.
285
+
286
+ Returns:
287
+ The server's JSON response as a Python object upon successful deletion.
288
+
289
+ Raises:
290
+ ValueError: If 'phone_number' is None.
291
+ requests.HTTPError: If the HTTP DELETE request results in an error status code.
292
+
293
+ Tags:
294
+ delete, phone-number, api, management, important
295
+ """
296
+ if phone_number is None:
297
+ raise ValueError("Missing required parameter 'phone_number'")
298
+ url = f"{self.base_url}/delete-phone-number/{phone_number}"
299
+ query_params = {}
300
+ response = self._delete(url, params=query_params)
301
+ response.raise_for_status()
302
+ return response.json()
303
+
304
+ def list_tools(self):
305
+ return [
306
+ self.get_v2_get_call_by_call_id,
307
+ self.post_v2_create_phone_call,
308
+ self.post_v2_create_web_call,
309
+ self.get_get_voice_by_voice_id,
310
+ self.post_v2_list_calls,
311
+ self.post_create_phone_number,
312
+ self.get_get_phone_number_by_phone_number,
313
+ self.get_list_phone_numbers,
314
+ self.patch_update_phone_number_by_phone_number,
315
+ self.delete_delete_phone_number_by_phone_number
316
+ ]
@@ -0,0 +1,42 @@
1
+
2
+ # Rocketlane MCP Server
3
+
4
+ An MCP Server for the Rocketlane API.
5
+
6
+ ## Supported Integrations
7
+
8
+ - AgentR
9
+ - API Key (Coming Soon)
10
+ - OAuth (Coming Soon)
11
+
12
+ ## Tools
13
+
14
+ This is automatically generated from OpenAPI schema for the Rocketlane API.
15
+
16
+ ## Supported Integrations
17
+
18
+ This tool can be integrated with any service that supports HTTP requests.
19
+
20
+ ## Tool List
21
+
22
+ | Tool | Description |
23
+ |------|-------------|
24
+ | get_subscription | Retrieves subscription details from the server. |
25
+ | get_home | Retrieves the JSON response from the '/home' endpoint of the configured API. |
26
+ | get_all_projects | Retrieves a list of all projects from the remote service. |
27
+ | get_projects_by_projectid | Retrieves project details for a given project ID from the server. |
28
+ | get_projects_by_projectid_tasks | Retrieves a list of tasks associated with a given project ID. |
29
+ | create_task | Creates a new task within the specified project, assigning optional details such as description, name, assignee, start date, and due date. |
30
+
31
+
32
+
33
+ ## Usage
34
+
35
+ - Login to AgentR
36
+ - Follow the quickstart guide to setup MCP Server for your client
37
+ - Visit Apps Store and enable the Rocketlane app
38
+ - Restart the MCP Server
39
+
40
+ ### Local Development
41
+
42
+ - Follow the README to test with the local MCP Server
File without changes
@@ -0,0 +1,180 @@
1
+ from typing import Any
2
+
3
+ from universal_mcp.applications import APIApplication
4
+ from universal_mcp.integrations import Integration
5
+
6
+
7
+ class RocketlaneApp(APIApplication):
8
+ def __init__(self, integration: Integration = None, **kwargs) -> None:
9
+ super().__init__(name='rocketlane', integration=integration, **kwargs)
10
+ subdomain= self.integration.get_credentials().get("subdomain")
11
+ self.base_url = f"https://{subdomain}.api.rocketlane.com/api/v1"
12
+
13
+ def _get_headers(self) -> dict[str, Any]:
14
+ api_key = self.integration.get_credentials().get("api_key")
15
+ return {
16
+ "api-key": f"{api_key}",
17
+ "Content-Type": "application/json",
18
+ "Accept": "application/json",
19
+ }
20
+
21
+ def get_subscription(self, ) -> Any:
22
+ """
23
+ Retrieves subscription details from the server.
24
+
25
+ Args:
26
+ None: This function does not take any parameters.
27
+
28
+ Returns:
29
+ A JSON response containing subscription details.
30
+
31
+ Raises:
32
+ requests.HTTPError: Raised if an HTTP error occurs during the request
33
+
34
+ Tags:
35
+ fetch, subscription, management, important
36
+ """
37
+ url = f"{self.base_url}/subscription"
38
+ query_params = {}
39
+ response = self._get(url, params=query_params)
40
+ response.raise_for_status()
41
+ return response.json()
42
+
43
+ def get_home(self, ) -> Any:
44
+ """
45
+ Retrieves the JSON response from the '/home' endpoint of the configured API.
46
+
47
+ Returns:
48
+ Any: Parsed JSON data returned by the '/home' endpoint.
49
+
50
+ Raises:
51
+ requests.HTTPError: If the HTTP request to the '/home' endpoint returns an unsuccessful status code.
52
+
53
+ Tags:
54
+ get, home, api, request, important
55
+ """
56
+ url = f"{self.base_url}/home"
57
+ query_params = {}
58
+ response = self._get(url, params=query_params)
59
+ response.raise_for_status()
60
+ return response.json()
61
+
62
+ def get_all_projects(self, ) -> dict[str, Any]:
63
+ """
64
+ Retrieves a list of all projects from the remote service.
65
+
66
+ Args:
67
+ None: This function takes no arguments
68
+
69
+ Returns:
70
+ A dictionary containing the JSON response data representing all available projects.
71
+
72
+ Raises:
73
+ HTTPError: If the HTTP request to retrieve the projects fails or returns an unsuccessful status code.
74
+
75
+ Tags:
76
+ list, projects, api, important
77
+ """
78
+ url = f"{self.base_url}/projects"
79
+ query_params = {}
80
+ response = self._get(url, params=query_params)
81
+ response.raise_for_status()
82
+ return response.json()
83
+
84
+ def get_projects_by_projectid(self, projectId) -> Any:
85
+ """
86
+ Retrieves project details for a given project ID from the server.
87
+
88
+ Args:
89
+ projectId: The unique identifier of the project to retrieve.
90
+
91
+ Returns:
92
+ A JSON-deserialized object containing the project's details as returned by the server.
93
+
94
+ Raises:
95
+ ValueError: Raised if 'projectId' is None.
96
+ requests.HTTPError: Raised if the HTTP request to retrieve the project fails (e.g., 4xx or 5xx response).
97
+
98
+ Tags:
99
+ get, project, fetch, management, important
100
+ """
101
+ if projectId is None:
102
+ raise ValueError("Missing required parameter 'projectId'")
103
+ url = f"{self.base_url}/projects/{projectId}"
104
+ query_params = {}
105
+ response = self._get(url, params=query_params)
106
+ response.raise_for_status()
107
+ return response.json()
108
+
109
+ def get_projects_by_projectid_tasks(self, projectId) -> Any:
110
+ """
111
+ Retrieves a list of tasks associated with a given project ID.
112
+
113
+ Args:
114
+ projectId: str. The unique identifier of the project whose tasks are to be retrieved.
115
+
116
+ Returns:
117
+ dict. A JSON object containing the list of tasks for the specified project.
118
+
119
+ Raises:
120
+ ValueError: If the projectId parameter is None.
121
+ requests.HTTPError: If the HTTP request to retrieve tasks fails (i.e., non-2xx response).
122
+
123
+ Tags:
124
+ get, list, project-tasks, management, important
125
+ """
126
+ if projectId is None:
127
+ raise ValueError("Missing required parameter 'projectId'")
128
+ url = f"{self.base_url}/projects/{projectId}/tasks"
129
+ query_params = {}
130
+ response = self._get(url, params=query_params)
131
+ response.raise_for_status()
132
+ return response.json()
133
+
134
+ def create_task(self, projectId, taskDescription=None, taskName=None, assignee=None, startDate=None, dueDate=None) -> dict[str, Any]:
135
+ """
136
+ Creates a new task within the specified project, assigning optional details such as description, name, assignee, start date, and due date.
137
+
138
+ Args:
139
+ projectId: str. The unique identifier of the project in which to create the task. Required.
140
+ taskDescription: Optional[str]. A description of the task to be created.
141
+ taskName: Optional[str]. The name of the new task.
142
+ assignee: Optional[str]. The user to whom the task is assigned.
143
+ startDate: Optional[str]. The starting date for the task, formatted as an ISO 8601 string.
144
+ dueDate: Optional[str]. The due date for task completion, formatted as an ISO 8601 string.
145
+
146
+ Returns:
147
+ dict[str, Any]: A dictionary containing the details of the created task as returned by the API.
148
+
149
+ Raises:
150
+ ValueError: If 'projectId' is not provided.
151
+ requests.HTTPError: If the API request fails and returns a non-success HTTP status code.
152
+
153
+ Tags:
154
+ create, task, management, project, api, important
155
+ """
156
+ if projectId is None:
157
+ raise ValueError("Missing required parameter 'projectId'")
158
+ request_body = {
159
+ 'taskDescription': taskDescription,
160
+ 'taskName': taskName,
161
+ 'assignee': assignee,
162
+ 'startDate': startDate,
163
+ 'dueDate': dueDate,
164
+ }
165
+ request_body = {k: v for k, v in request_body.items() if v is not None}
166
+ url = f"{self.base_url}/projects/{projectId}/tasks"
167
+ query_params = {}
168
+ response = self._post(url, data=request_body, params=query_params)
169
+ response.raise_for_status()
170
+ return response.json()
171
+
172
+ def list_tools(self):
173
+ return [
174
+ self.get_subscription,
175
+ self.get_home,
176
+ self.get_all_projects,
177
+ self.get_projects_by_projectid,
178
+ self.get_projects_by_projectid_tasks,
179
+ self.create_task
180
+ ]