flock-core 0.4.538__py3-none-any.whl → 0.4.540__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 flock-core might be problematic. Click here for more details.
- flock/tools/zendesk_tools.py +275 -48
- {flock_core-0.4.538.dist-info → flock_core-0.4.540.dist-info}/METADATA +1 -1
- {flock_core-0.4.538.dist-info → flock_core-0.4.540.dist-info}/RECORD +6 -6
- {flock_core-0.4.538.dist-info → flock_core-0.4.540.dist-info}/WHEEL +0 -0
- {flock_core-0.4.538.dist-info → flock_core-0.4.540.dist-info}/entry_points.txt +0 -0
- {flock_core-0.4.538.dist-info → flock_core-0.4.540.dist-info}/licenses/LICENSE +0 -0
flock/tools/zendesk_tools.py
CHANGED
|
@@ -5,17 +5,27 @@ import os
|
|
|
5
5
|
import httpx
|
|
6
6
|
from mcp.server.fastmcp import FastMCP
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
from flock.core.logging.logging import get_logger
|
|
11
9
|
|
|
10
|
+
mcp = FastMCP("ZendeskTools")
|
|
11
|
+
logger = get_logger(__name__)
|
|
12
12
|
|
|
13
13
|
def _get_headers() -> dict:
|
|
14
|
+
logger.debug("Preparing headers for Zendesk API request")
|
|
15
|
+
|
|
14
16
|
token = os.getenv("ZENDESK_BEARER_TOKEN")
|
|
15
17
|
if not token:
|
|
18
|
+
logger.error("ZENDESK_BEARER_TOKEN environment variable is not set")
|
|
16
19
|
raise ValueError(
|
|
17
20
|
"ZENDESK_BEARER_TOKEN environment variable is not set"
|
|
18
21
|
)
|
|
22
|
+
|
|
23
|
+
logger.debug("Successfully retrieved bearer token from environment")
|
|
24
|
+
# Log a masked version of the token for debugging
|
|
25
|
+
masked_token = f"{token[:10]}...{token[-4:] if len(token) > 14 else 'short'}"
|
|
26
|
+
logger.debug(f"Using bearer token: {masked_token}")
|
|
27
|
+
logger.debug("Headers prepared successfully")
|
|
28
|
+
|
|
19
29
|
return {
|
|
20
30
|
"Authorization": f"Bearer {token}",
|
|
21
31
|
"Accept": "application/json",
|
|
@@ -25,69 +35,169 @@ def _get_headers() -> dict:
|
|
|
25
35
|
@mcp.tool()
|
|
26
36
|
def zendesk_get_tickets(number_of_tickets: int = 10) -> list[dict]:
|
|
27
37
|
"""Get all tickets."""
|
|
38
|
+
logger.info(f"Starting zendesk_get_tickets with number_of_tickets: {number_of_tickets}")
|
|
39
|
+
|
|
28
40
|
ZENDESK_SUBDOMAIN = os.getenv("ZENDESK_SUBDOMAIN_TICKET")
|
|
41
|
+
logger.debug(f"Using Zendesk subdomain: {ZENDESK_SUBDOMAIN}")
|
|
42
|
+
|
|
29
43
|
BASE_URL = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com"
|
|
30
44
|
url = f"{BASE_URL}/api/v2/tickets.json"
|
|
45
|
+
logger.debug(f"Initial URL: {url}")
|
|
46
|
+
|
|
31
47
|
all_tickets = []
|
|
48
|
+
page_count = 0
|
|
49
|
+
|
|
32
50
|
with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
|
|
51
|
+
logger.debug("Created HTTP client for Zendesk API")
|
|
52
|
+
|
|
33
53
|
while url and len(all_tickets) < number_of_tickets:
|
|
34
|
-
|
|
35
|
-
|
|
54
|
+
page_count += 1
|
|
55
|
+
logger.debug(f"Fetching page {page_count} from URL: {url}")
|
|
36
56
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
57
|
+
try:
|
|
58
|
+
response = client.get(url)
|
|
59
|
+
response.raise_for_status()
|
|
60
|
+
logger.debug(f"Successfully received response with status: {response.status_code}")
|
|
40
61
|
|
|
41
|
-
|
|
62
|
+
data = response.json()
|
|
63
|
+
tickets = data.get("tickets", [])
|
|
64
|
+
logger.debug(f"Retrieved {len(tickets)} tickets from page {page_count}")
|
|
65
|
+
|
|
66
|
+
all_tickets.extend(tickets)
|
|
67
|
+
logger.debug(f"Total tickets collected so far: {len(all_tickets)}")
|
|
68
|
+
|
|
69
|
+
url = data.get("next_page")
|
|
70
|
+
if url:
|
|
71
|
+
logger.debug(f"Next page URL: {url}")
|
|
72
|
+
else:
|
|
73
|
+
logger.debug("No more pages available")
|
|
74
|
+
|
|
75
|
+
except Exception as e:
|
|
76
|
+
logger.error(f"Error fetching tickets on page {page_count}: {e}")
|
|
77
|
+
raise
|
|
78
|
+
|
|
79
|
+
logger.info(f"Successfully retrieved {len(all_tickets)} tickets across {page_count} pages")
|
|
42
80
|
return all_tickets
|
|
43
81
|
|
|
44
82
|
@mcp.tool()
|
|
45
83
|
def zendesk_get_ticket_by_id(ticket_id: str) -> dict:
|
|
46
84
|
"""Get a ticket by ID."""
|
|
85
|
+
logger.info(f"Starting zendesk_get_ticket_by_id for ticket_id: {ticket_id}")
|
|
86
|
+
|
|
47
87
|
ZENDESK_SUBDOMAIN = os.getenv("ZENDESK_SUBDOMAIN_TICKET")
|
|
88
|
+
logger.debug(f"Using Zendesk subdomain: {ZENDESK_SUBDOMAIN}")
|
|
89
|
+
|
|
48
90
|
BASE_URL = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com"
|
|
49
91
|
url = f"{BASE_URL}/api/v2/tickets/{ticket_id}"
|
|
92
|
+
logger.debug(f"Request URL: {url}")
|
|
93
|
+
|
|
50
94
|
with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
95
|
+
logger.debug("Created HTTP client for Zendesk API")
|
|
96
|
+
|
|
97
|
+
try:
|
|
98
|
+
logger.debug(f"Making GET request for ticket {ticket_id}")
|
|
99
|
+
response = client.get(url)
|
|
100
|
+
response.raise_for_status()
|
|
101
|
+
logger.debug(f"Successfully received response with status: {response.status_code}")
|
|
102
|
+
|
|
103
|
+
ticket_data = response.json()["ticket"]
|
|
104
|
+
logger.info(f"Successfully retrieved ticket {ticket_id} with subject: {ticket_data.get('subject', 'N/A')}")
|
|
105
|
+
return ticket_data
|
|
106
|
+
|
|
107
|
+
except Exception as e:
|
|
108
|
+
logger.error(f"Error fetching ticket {ticket_id}: {e}")
|
|
109
|
+
raise
|
|
54
110
|
|
|
55
111
|
@mcp.tool()
|
|
56
112
|
def zendesk_get_comments_by_ticket_id(ticket_id: str) -> list[dict]:
|
|
57
113
|
"""Get all comments for a ticket."""
|
|
114
|
+
logger.info(f"Starting zendesk_get_comments_by_ticket_id for ticket_id: {ticket_id}")
|
|
115
|
+
|
|
58
116
|
ZENDESK_SUBDOMAIN = os.getenv("ZENDESK_SUBDOMAIN_TICKET")
|
|
117
|
+
logger.debug(f"Using Zendesk subdomain: {ZENDESK_SUBDOMAIN}")
|
|
118
|
+
|
|
59
119
|
BASE_URL = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com"
|
|
60
120
|
url = f"{BASE_URL}/api/v2/tickets/{ticket_id}/comments"
|
|
121
|
+
logger.debug(f"Request URL: {url}")
|
|
122
|
+
|
|
61
123
|
with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
124
|
+
logger.debug("Created HTTP client for Zendesk API")
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
logger.debug(f"Making GET request for comments of ticket {ticket_id}")
|
|
128
|
+
response = client.get(url)
|
|
129
|
+
response.raise_for_status()
|
|
130
|
+
logger.debug(f"Successfully received response with status: {response.status_code}")
|
|
131
|
+
|
|
132
|
+
comments = response.json()["comments"]
|
|
133
|
+
logger.info(f"Successfully retrieved {len(comments)} comments for ticket {ticket_id}")
|
|
134
|
+
return comments
|
|
135
|
+
|
|
136
|
+
except Exception as e:
|
|
137
|
+
logger.error(f"Error fetching comments for ticket {ticket_id}: {e}")
|
|
138
|
+
raise
|
|
65
139
|
|
|
66
140
|
@mcp.tool()
|
|
67
141
|
def zendesk_get_article_by_id(article_id: str) -> dict:
|
|
68
142
|
"""Get an article by ID."""
|
|
143
|
+
logger.info(f"Starting zendesk_get_article_by_id for article_id: {article_id}")
|
|
144
|
+
|
|
69
145
|
ZENDESK_LOCALE = os.getenv("ZENDESK_ARTICLE_LOCALE")
|
|
70
146
|
ZENDESK_SUBDOMAIN = os.getenv("ZENDESK_SUBDOMAIN_ARTICLE")
|
|
147
|
+
logger.debug(f"Using locale: {ZENDESK_LOCALE}, subdomain: {ZENDESK_SUBDOMAIN}")
|
|
148
|
+
|
|
71
149
|
BASE_URL = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com"
|
|
72
150
|
url = (
|
|
73
151
|
f"{BASE_URL}/api/v2/help_center/{ZENDESK_LOCALE}/articles/{article_id}"
|
|
74
152
|
)
|
|
153
|
+
logger.debug(f"Request URL: {url}")
|
|
154
|
+
|
|
75
155
|
with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
156
|
+
logger.debug("Created HTTP client for Zendesk API")
|
|
157
|
+
|
|
158
|
+
try:
|
|
159
|
+
logger.debug(f"Making GET request for article {article_id}")
|
|
160
|
+
response = client.get(url)
|
|
161
|
+
response.raise_for_status()
|
|
162
|
+
logger.debug(f"Successfully received response with status: {response.status_code}")
|
|
163
|
+
|
|
164
|
+
article = response.json()["article"]
|
|
165
|
+
logger.info(f"Successfully retrieved article {article_id} with title: {article.get('title', 'N/A')}")
|
|
166
|
+
return article
|
|
167
|
+
|
|
168
|
+
except Exception as e:
|
|
169
|
+
logger.error(f"Error fetching article {article_id}: {e}")
|
|
170
|
+
raise
|
|
79
171
|
|
|
80
172
|
@mcp.tool()
|
|
81
173
|
def zendesk_get_articles() -> list[dict]:
|
|
82
174
|
"""Get all articles."""
|
|
175
|
+
logger.info("Starting zendesk_get_articles")
|
|
176
|
+
|
|
83
177
|
ZENDESK_LOCALE = os.getenv("ZENDESK_ARTICLE_LOCALE")
|
|
84
178
|
ZENDESK_SUBDOMAIN = os.getenv("ZENDESK_SUBDOMAIN_ARTICLE")
|
|
179
|
+
logger.debug(f"Using locale: {ZENDESK_LOCALE}, subdomain: {ZENDESK_SUBDOMAIN}")
|
|
180
|
+
|
|
85
181
|
BASE_URL = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com"
|
|
86
182
|
url = f"{BASE_URL}/api/v2/help_center/{ZENDESK_LOCALE}/articles.json"
|
|
183
|
+
logger.debug(f"Request URL: {url}")
|
|
184
|
+
|
|
87
185
|
with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
186
|
+
logger.debug("Created HTTP client for Zendesk API")
|
|
187
|
+
|
|
188
|
+
try:
|
|
189
|
+
logger.debug("Making GET request for articles")
|
|
190
|
+
response = client.get(url)
|
|
191
|
+
response.raise_for_status()
|
|
192
|
+
logger.debug(f"Successfully received response with status: {response.status_code}")
|
|
193
|
+
|
|
194
|
+
articles = response.json()["articles"]
|
|
195
|
+
logger.info(f"Successfully retrieved {len(articles)} articles")
|
|
196
|
+
return articles
|
|
197
|
+
|
|
198
|
+
except Exception as e:
|
|
199
|
+
logger.error(f"Error fetching articles: {e}")
|
|
200
|
+
raise
|
|
91
201
|
|
|
92
202
|
@mcp.tool()
|
|
93
203
|
def zendesk_get_articles_count() -> int:
|
|
@@ -129,10 +239,15 @@ def zendesk_get_articles_count() -> int:
|
|
|
129
239
|
@mcp.tool()
|
|
130
240
|
def zendesk_search_articles(query: str) -> list[dict]:
|
|
131
241
|
"""Search Zendesk Help Center articles using a query string."""
|
|
242
|
+
logger.info(f"Starting zendesk_search_articles with query: '{query}'")
|
|
243
|
+
|
|
132
244
|
ZENDESK_LOCALE = os.getenv("ZENDESK_ARTICLE_LOCALE") # e.g., "en-us"
|
|
133
245
|
ZENDESK_SUBDOMAIN = os.getenv("ZENDESK_SUBDOMAIN_ARTICLE")
|
|
246
|
+
logger.debug(f"Using locale: {ZENDESK_LOCALE}, subdomain: {ZENDESK_SUBDOMAIN}")
|
|
247
|
+
|
|
134
248
|
BASE_URL = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com"
|
|
135
249
|
url = f"{BASE_URL}/api/v2/help_center/articles/search.json"
|
|
250
|
+
logger.debug(f"Search URL: {url}")
|
|
136
251
|
|
|
137
252
|
params = {
|
|
138
253
|
"query": query,
|
|
@@ -140,11 +255,24 @@ def zendesk_search_articles(query: str) -> list[dict]:
|
|
|
140
255
|
"sort_by": "updated_at",
|
|
141
256
|
"sort_order": "desc",
|
|
142
257
|
}
|
|
258
|
+
logger.debug(f"Search parameters: {params}")
|
|
143
259
|
|
|
144
260
|
with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
261
|
+
logger.debug("Created HTTP client for Zendesk API")
|
|
262
|
+
|
|
263
|
+
try:
|
|
264
|
+
logger.debug(f"Making GET request to search articles with query: '{query}'")
|
|
265
|
+
response = client.get(url, params=params)
|
|
266
|
+
response.raise_for_status()
|
|
267
|
+
logger.debug(f"Successfully received response with status: {response.status_code}")
|
|
268
|
+
|
|
269
|
+
results = response.json().get("results", [])
|
|
270
|
+
logger.info(f"Search completed successfully, found {len(results)} articles matching query: '{query}'")
|
|
271
|
+
return results
|
|
272
|
+
|
|
273
|
+
except Exception as e:
|
|
274
|
+
logger.error(f"Error searching articles with query '{query}': {e}")
|
|
275
|
+
raise
|
|
148
276
|
|
|
149
277
|
@mcp.tool()
|
|
150
278
|
def zendesk_add_comment_to_ticket(ticket_id: str, comment_body: str, public: bool = False) -> dict:
|
|
@@ -153,9 +281,15 @@ def zendesk_add_comment_to_ticket(ticket_id: str, comment_body: str, public: boo
|
|
|
153
281
|
Updates the ticket with a new comment via Zendesk Ticketing API:
|
|
154
282
|
PUT /api/v2/tickets/{ticket_id}.json
|
|
155
283
|
"""
|
|
284
|
+
logger.info(f"Starting zendesk_add_comment_to_ticket for ticket_id: {ticket_id}, public: {public}")
|
|
285
|
+
logger.debug(f"Comment body length: {len(comment_body)} characters")
|
|
286
|
+
|
|
156
287
|
ZENDESK_SUBDOMAIN = os.getenv("ZENDESK_SUBDOMAIN_TICKET")
|
|
288
|
+
logger.debug(f"Using Zendesk subdomain: {ZENDESK_SUBDOMAIN}")
|
|
289
|
+
|
|
157
290
|
BASE_URL = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com"
|
|
158
291
|
url = f"{BASE_URL}/api/v2/tickets/{ticket_id}.json"
|
|
292
|
+
logger.debug(f"Request URL: {url}")
|
|
159
293
|
|
|
160
294
|
payload = {
|
|
161
295
|
"ticket": {
|
|
@@ -165,25 +299,48 @@ def zendesk_add_comment_to_ticket(ticket_id: str, comment_body: str, public: boo
|
|
|
165
299
|
}
|
|
166
300
|
}
|
|
167
301
|
}
|
|
302
|
+
logger.debug(f"Payload prepared for ticket {ticket_id}")
|
|
168
303
|
|
|
169
304
|
import httpx
|
|
170
305
|
with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
306
|
+
logger.debug("Created HTTP client for Zendesk API")
|
|
307
|
+
|
|
308
|
+
try:
|
|
309
|
+
logger.debug(f"Making PUT request to add comment to ticket {ticket_id}")
|
|
310
|
+
response = client.put(url, json=payload)
|
|
311
|
+
response.raise_for_status()
|
|
312
|
+
logger.debug(f"Successfully received response with status: {response.status_code}")
|
|
313
|
+
|
|
314
|
+
ticket_data = response.json()["ticket"]
|
|
315
|
+
logger.info(f"Successfully added comment to ticket {ticket_id}")
|
|
316
|
+
return ticket_data
|
|
317
|
+
|
|
318
|
+
except Exception as e:
|
|
319
|
+
logger.error(f"Error adding comment to ticket {ticket_id}: {e}")
|
|
320
|
+
raise
|
|
174
321
|
|
|
175
322
|
@mcp.tool()
|
|
176
323
|
def zendesk_set_ticket_custom_field(
|
|
177
|
-
ticket_id: str, custom_field_id: int, custom_field_value: str
|
|
324
|
+
ticket_id: str, custom_field_id: int, custom_field_value: str, is_multi_option: bool = False
|
|
178
325
|
) -> dict:
|
|
179
326
|
"""Set the custom field value of a Zendesk ticket.
|
|
180
327
|
|
|
181
328
|
Uses Zendesk's Update Ticket API to set a custom field value:
|
|
182
329
|
PUT /api/v2/tickets/{ticket_id}.json
|
|
183
|
-
"""
|
|
330
|
+
"""#
|
|
331
|
+
logger.info(f"Starting zendesk_set_ticket_custom_field for ticket_id: {ticket_id}, field_id: {custom_field_id}")
|
|
332
|
+
logger.debug(f"Custom field value: {custom_field_value}, is_multi_option: {is_multi_option}")
|
|
333
|
+
|
|
334
|
+
if is_multi_option:
|
|
335
|
+
custom_field_value = [custom_field_value]
|
|
336
|
+
logger.debug("Converted custom field value to list for multi-option field")
|
|
337
|
+
|
|
184
338
|
ZENDESK_SUBDOMAIN = os.getenv("ZENDESK_SUBDOMAIN_TICKET")
|
|
339
|
+
logger.debug(f"Using Zendesk subdomain: {ZENDESK_SUBDOMAIN}")
|
|
340
|
+
|
|
185
341
|
BASE_URL = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com"
|
|
186
342
|
url = f"{BASE_URL}/api/v2/tickets/{ticket_id}.json"
|
|
343
|
+
logger.debug(f"Request URL: {url}")
|
|
187
344
|
|
|
188
345
|
payload = {
|
|
189
346
|
"ticket": {
|
|
@@ -195,48 +352,99 @@ def zendesk_set_ticket_custom_field(
|
|
|
195
352
|
]
|
|
196
353
|
}
|
|
197
354
|
}
|
|
355
|
+
logger.debug(f"Payload prepared for ticket {ticket_id} with custom field {custom_field_id}")
|
|
198
356
|
|
|
199
357
|
import httpx
|
|
200
358
|
|
|
201
359
|
with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
360
|
+
logger.debug("Created HTTP client for Zendesk API")
|
|
361
|
+
|
|
362
|
+
try:
|
|
363
|
+
logger.debug(f"Making PUT request to set custom field {custom_field_id} on ticket {ticket_id}")
|
|
364
|
+
response = client.put(url, json=payload)
|
|
365
|
+
response.raise_for_status()
|
|
366
|
+
logger.debug(f"Successfully received response with status: {response.status_code}")
|
|
367
|
+
|
|
368
|
+
ticket_data = response.json()["ticket"]
|
|
369
|
+
logger.info(f"Successfully set custom field {custom_field_id} on ticket {ticket_id}")
|
|
370
|
+
return ticket_data
|
|
371
|
+
|
|
372
|
+
except Exception as e:
|
|
373
|
+
logger.error(f"Error setting custom field {custom_field_id} on ticket {ticket_id}: {e}")
|
|
374
|
+
raise
|
|
205
375
|
|
|
206
376
|
|
|
207
377
|
|
|
208
378
|
@mcp.tool()
|
|
209
379
|
def zendesk_set_ticket_tags(ticket_id: str, tags: list[str]) -> list[str]:
|
|
210
380
|
"""Set the complete tag list for a ticket (overwrites existing tags)."""
|
|
381
|
+
logger.info(f"Starting zendesk_set_ticket_tags for ticket_id: {ticket_id}")
|
|
382
|
+
logger.debug(f"Setting tags: {tags} (total: {len(tags)} tags)")
|
|
383
|
+
|
|
211
384
|
ZENDESK_SUBDOMAIN = os.getenv("ZENDESK_SUBDOMAIN_TICKET")
|
|
385
|
+
logger.debug(f"Using Zendesk subdomain: {ZENDESK_SUBDOMAIN}")
|
|
386
|
+
|
|
212
387
|
BASE_URL = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com"
|
|
213
388
|
url = f"{BASE_URL}/api/v2/tickets/{ticket_id}/tags.json"
|
|
389
|
+
logger.debug(f"Request URL: {url}")
|
|
214
390
|
|
|
215
391
|
payload = {"tags": tags}
|
|
392
|
+
logger.debug(f"Payload prepared for ticket {ticket_id}")
|
|
216
393
|
|
|
217
394
|
import httpx
|
|
218
395
|
|
|
219
396
|
with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
397
|
+
logger.debug("Created HTTP client for Zendesk API")
|
|
398
|
+
|
|
399
|
+
try:
|
|
400
|
+
logger.debug(f"Making PUT request to set tags on ticket {ticket_id}")
|
|
401
|
+
resp = client.put(url, json=payload)
|
|
402
|
+
resp.raise_for_status()
|
|
403
|
+
logger.debug(f"Successfully received response with status: {resp.status_code}")
|
|
404
|
+
|
|
405
|
+
result_tags = resp.json().get("tags", [])
|
|
406
|
+
logger.info(f"Successfully set {len(result_tags)} tags on ticket {ticket_id}")
|
|
407
|
+
return result_tags
|
|
408
|
+
|
|
409
|
+
except Exception as e:
|
|
410
|
+
logger.error(f"Error setting tags on ticket {ticket_id}: {e}")
|
|
411
|
+
raise
|
|
223
412
|
|
|
224
413
|
|
|
225
414
|
@mcp.tool()
|
|
226
415
|
def zendesk_add_ticket_tags(ticket_id: str, tags: list[str]) -> list[str]:
|
|
227
416
|
"""Add tags to a ticket (preserves existing tags)."""
|
|
417
|
+
logger.info(f"Starting zendesk_add_ticket_tags for ticket_id: {ticket_id}")
|
|
418
|
+
logger.debug(f"Adding tags: {tags} (total: {len(tags)} tags)")
|
|
419
|
+
|
|
228
420
|
ZENDESK_SUBDOMAIN = os.getenv("ZENDESK_SUBDOMAIN_TICKET")
|
|
421
|
+
logger.debug(f"Using Zendesk subdomain: {ZENDESK_SUBDOMAIN}")
|
|
422
|
+
|
|
229
423
|
BASE_URL = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com"
|
|
230
424
|
url = f"{BASE_URL}/api/v2/tickets/{ticket_id}/tags.json"
|
|
425
|
+
logger.debug(f"Request URL: {url}")
|
|
231
426
|
|
|
232
427
|
payload = {"tags": tags}
|
|
428
|
+
logger.debug(f"Payload prepared for ticket {ticket_id}")
|
|
233
429
|
|
|
234
430
|
import httpx
|
|
235
431
|
|
|
236
432
|
with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
433
|
+
logger.debug("Created HTTP client for Zendesk API")
|
|
434
|
+
|
|
435
|
+
try:
|
|
436
|
+
logger.debug(f"Making POST request to add tags to ticket {ticket_id}")
|
|
437
|
+
resp = client.post(url, json=payload)
|
|
438
|
+
resp.raise_for_status()
|
|
439
|
+
logger.debug(f"Successfully received response with status: {resp.status_code}")
|
|
440
|
+
|
|
441
|
+
result_tags = resp.json().get("tags", [])
|
|
442
|
+
logger.info(f"Successfully added tags to ticket {ticket_id}, total tags now: {len(result_tags)}")
|
|
443
|
+
return result_tags
|
|
444
|
+
|
|
445
|
+
except Exception as e:
|
|
446
|
+
logger.error(f"Error adding tags to ticket {ticket_id}: {e}")
|
|
447
|
+
raise
|
|
240
448
|
|
|
241
449
|
|
|
242
450
|
@mcp.tool()
|
|
@@ -248,23 +456,42 @@ def zendesk_get_ticket_field_type(field_id: int) -> dict:
|
|
|
248
456
|
Returns a dict containing at least:
|
|
249
457
|
{ "type": str, "custom_field_options": list }
|
|
250
458
|
"""
|
|
459
|
+
logger.info(f"Starting zendesk_get_ticket_field_type for field_id: {field_id}")
|
|
460
|
+
|
|
251
461
|
ZENDESK_SUBDOMAIN = os.getenv("ZENDESK_SUBDOMAIN_TICKET")
|
|
462
|
+
logger.debug(f"Using Zendesk subdomain: {ZENDESK_SUBDOMAIN}")
|
|
463
|
+
|
|
252
464
|
BASE_URL = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com"
|
|
253
465
|
url = f"{BASE_URL}/api/v2/ticket_fields/{field_id}.json"
|
|
466
|
+
logger.debug(f"Request URL: {url}")
|
|
254
467
|
|
|
255
468
|
import httpx
|
|
256
469
|
|
|
257
470
|
with httpx.Client(headers=_get_headers(), timeout=30.0) as client:
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
"
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
471
|
+
logger.debug("Created HTTP client for Zendesk API")
|
|
472
|
+
|
|
473
|
+
try:
|
|
474
|
+
logger.debug(f"Making GET request for ticket field {field_id}")
|
|
475
|
+
resp = client.get(url)
|
|
476
|
+
resp.raise_for_status()
|
|
477
|
+
logger.debug(f"Successfully received response with status: {resp.status_code}")
|
|
478
|
+
|
|
479
|
+
field = resp.json().get("ticket_field", {})
|
|
480
|
+
result = {
|
|
481
|
+
"id": field.get("id"),
|
|
482
|
+
"type": field.get("type"),
|
|
483
|
+
"title": field.get("title"),
|
|
484
|
+
"required": field.get("required"),
|
|
485
|
+
"custom_field_options": field.get("custom_field_options", []),
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
logger.info(f"Successfully retrieved field info for {field_id}: type={result['type']}, title='{result['title']}'")
|
|
489
|
+
logger.debug(f"Field has {len(result['custom_field_options'])} custom options")
|
|
490
|
+
return result
|
|
491
|
+
|
|
492
|
+
except Exception as e:
|
|
493
|
+
logger.error(f"Error fetching ticket field {field_id}: {e}")
|
|
494
|
+
raise
|
|
268
495
|
|
|
269
496
|
|
|
270
497
|
|
|
@@ -488,7 +488,7 @@ flock/tools/markdown_tools.py,sha256=94fjGAJ5DEutoioD0ke-YRbxF6IWJQKuPVBLkNqdBo4
|
|
|
488
488
|
flock/tools/system_tools.py,sha256=IUB8MiSxtQH5ZfTGOck3vl4TKva8m1lfU4-W5D5b-4w,202
|
|
489
489
|
flock/tools/text_tools.py,sha256=mMQ8tkyYDxIorqqzl9ccGyWYjrSynYiYFIeP9qypfdg,22491
|
|
490
490
|
flock/tools/web_tools.py,sha256=h44L5rknxGw1mVnFTYO-z0xwUr5ctOvMiJBIfeq56UE,2555
|
|
491
|
-
flock/tools/zendesk_tools.py,sha256=
|
|
491
|
+
flock/tools/zendesk_tools.py,sha256=1uNHMvfjmbxkrJoBsXS5jDaOCeEcOEDQUKoGYFODj3o,19007
|
|
492
492
|
flock/webapp/__init__.py,sha256=YtRbbyciN3Z2oMB9fdXZuvM3e49R8m2mY5qHLDoapRA,37
|
|
493
493
|
flock/webapp/run.py,sha256=btKVwIqrFg3FhLRuj2RN_fazwaFat3Ue5yiFiIg60rQ,9054
|
|
494
494
|
flock/webapp/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -563,8 +563,8 @@ flock/workflow/agent_execution_activity.py,sha256=hLqWEWsxwTgjsE9wvBejf3pN2TdIfU
|
|
|
563
563
|
flock/workflow/flock_workflow.py,sha256=iSUF_soFvWar0ffpkzE4irkDZRx0p4HnwmEBi_Ne2sY,9666
|
|
564
564
|
flock/workflow/temporal_config.py,sha256=3_8O7SDEjMsSMXsWJBfnb6XTp0TFaz39uyzSlMTSF_I,3988
|
|
565
565
|
flock/workflow/temporal_setup.py,sha256=YIHnSBntzOchHfMSh8hoLeNXrz3B1UbR14YrR6soM7A,1606
|
|
566
|
-
flock_core-0.4.
|
|
567
|
-
flock_core-0.4.
|
|
568
|
-
flock_core-0.4.
|
|
569
|
-
flock_core-0.4.
|
|
570
|
-
flock_core-0.4.
|
|
566
|
+
flock_core-0.4.540.dist-info/METADATA,sha256=iP152gm4KuyIrUHtQzSwJZXD9ZqaAnQ2mbQmLLVdnQA,22800
|
|
567
|
+
flock_core-0.4.540.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
568
|
+
flock_core-0.4.540.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
|
|
569
|
+
flock_core-0.4.540.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
|
|
570
|
+
flock_core-0.4.540.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|