fenix-mcp 1.4.0__py3-none-any.whl → 1.6.0__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.
- fenix_mcp/__init__.py +1 -1
- fenix_mcp/application/tools/knowledge.py +111 -42
- fenix_mcp/domain/knowledge.py +6 -0
- fenix_mcp/infrastructure/fenix_api/client.py +6 -0
- {fenix_mcp-1.4.0.dist-info → fenix_mcp-1.6.0.dist-info}/METADATA +1 -1
- {fenix_mcp-1.4.0.dist-info → fenix_mcp-1.6.0.dist-info}/RECORD +9 -9
- {fenix_mcp-1.4.0.dist-info → fenix_mcp-1.6.0.dist-info}/WHEEL +0 -0
- {fenix_mcp-1.4.0.dist-info → fenix_mcp-1.6.0.dist-info}/entry_points.txt +0 -0
- {fenix_mcp-1.4.0.dist-info → fenix_mcp-1.6.0.dist-info}/top_level.txt +0 -0
fenix_mcp/__init__.py
CHANGED
|
@@ -39,18 +39,20 @@ class KnowledgeAction(str, Enum):
|
|
|
39
39
|
# Work items
|
|
40
40
|
WORK_CREATE = (
|
|
41
41
|
"work_create",
|
|
42
|
-
"Creates a work item with title, status and optional links.",
|
|
42
|
+
"Creates a work item with title, status and optional links. Use parent_key (e.g., DVPT-0001) to set parent.",
|
|
43
43
|
)
|
|
44
44
|
WORK_LIST = (
|
|
45
45
|
"work_list",
|
|
46
46
|
"Lists work items with status, priority and context filters.",
|
|
47
47
|
)
|
|
48
|
-
WORK_GET = (
|
|
48
|
+
WORK_GET = (
|
|
49
|
+
"work_get",
|
|
50
|
+
"Gets full details of a work item by ID or key (e.g., DVPT-0001).",
|
|
51
|
+
)
|
|
49
52
|
WORK_UPDATE = (
|
|
50
53
|
"work_update",
|
|
51
|
-
"Updates
|
|
54
|
+
"Updates allowed fields of an existing work item (title, description, priority, story_points, tags, due_date).",
|
|
52
55
|
)
|
|
53
|
-
WORK_DELETE = ("work_delete", "Permanently removes a work item.")
|
|
54
56
|
WORK_BACKLOG = ("work_backlog", "Lists backlog items for a team.")
|
|
55
57
|
WORK_SEARCH = (
|
|
56
58
|
"work_search",
|
|
@@ -60,7 +62,10 @@ class KnowledgeAction(str, Enum):
|
|
|
60
62
|
WORK_BY_BOARD = ("work_by_board", "Lists work items associated with a board.")
|
|
61
63
|
WORK_BY_SPRINT = ("work_by_sprint", "Lists work items associated with a sprint.")
|
|
62
64
|
WORK_BY_EPIC = ("work_by_epic", "Lists work items associated with an epic.")
|
|
63
|
-
WORK_CHILDREN = (
|
|
65
|
+
WORK_CHILDREN = (
|
|
66
|
+
"work_children",
|
|
67
|
+
"Lists child work items of a parent item by ID or key (e.g., DVPT-0001).",
|
|
68
|
+
)
|
|
64
69
|
WORK_STATUS_UPDATE = (
|
|
65
70
|
"work_status_update",
|
|
66
71
|
"Updates only the status of a work item.",
|
|
@@ -69,6 +74,10 @@ class KnowledgeAction(str, Enum):
|
|
|
69
74
|
"work_assign_sprint",
|
|
70
75
|
"Assigns work items to a sprint.",
|
|
71
76
|
)
|
|
77
|
+
WORK_ASSIGN_TO_ME = (
|
|
78
|
+
"work_assign_to_me",
|
|
79
|
+
"Assigns a work item to the current user.",
|
|
80
|
+
)
|
|
72
81
|
|
|
73
82
|
# Boards
|
|
74
83
|
BOARD_LIST = ("board_list", "Lists available boards with optional filters.")
|
|
@@ -203,6 +212,10 @@ class KnowledgeRequest(ToolRequest):
|
|
|
203
212
|
)
|
|
204
213
|
|
|
205
214
|
# Work item fields
|
|
215
|
+
work_key: Optional[str] = Field(
|
|
216
|
+
default=None,
|
|
217
|
+
description="Work item key (e.g., DVPT-0001). Use this instead of id for work_get and work_children.",
|
|
218
|
+
)
|
|
206
219
|
work_title: Optional[TitleStr] = Field(default=None, description="Work item title.")
|
|
207
220
|
work_description: Optional[MarkdownStr] = Field(
|
|
208
221
|
default=None, description="Work item description (Markdown)."
|
|
@@ -213,12 +226,16 @@ class KnowledgeRequest(ToolRequest):
|
|
|
213
226
|
)
|
|
214
227
|
work_status: Optional[str] = Field(
|
|
215
228
|
default=None,
|
|
216
|
-
description="Work item status (
|
|
229
|
+
description="Work item status ID (UUID of TeamStatus).",
|
|
217
230
|
)
|
|
218
231
|
work_priority: Optional[str] = Field(
|
|
219
232
|
default=None,
|
|
220
233
|
description="Work item priority (critical, high, medium, low).",
|
|
221
234
|
)
|
|
235
|
+
work_category: Optional[str] = Field(
|
|
236
|
+
default=None,
|
|
237
|
+
description="Work item category/discipline. REQUIRED for work_create. Values: backend, frontend, mobile, fullstack, devops, infra, platform, sre, database, security, data, analytics, ai_ml, qa, automation, design, research, product, project, agile, support, operations, documentation, training, architecture, planning, development.",
|
|
238
|
+
)
|
|
222
239
|
story_points: Optional[int] = Field(
|
|
223
240
|
default=None, ge=0, le=100, description="Story points (0-100)."
|
|
224
241
|
)
|
|
@@ -226,7 +243,12 @@ class KnowledgeRequest(ToolRequest):
|
|
|
226
243
|
default=None, description="Assignee ID (UUID)."
|
|
227
244
|
)
|
|
228
245
|
parent_id: Optional[UUIDStr] = Field(
|
|
229
|
-
default=None,
|
|
246
|
+
default=None,
|
|
247
|
+
description="Parent item ID (UUID). Prefer using parent_key instead.",
|
|
248
|
+
)
|
|
249
|
+
parent_key: Optional[str] = Field(
|
|
250
|
+
default=None,
|
|
251
|
+
description="Parent item key (e.g., DVPT-0001). Use this to set the parent of a work item.",
|
|
230
252
|
)
|
|
231
253
|
work_due_date: Optional[DateTimeStr] = Field(
|
|
232
254
|
default=None, description="Work item due date (ISO 8601)."
|
|
@@ -364,18 +386,29 @@ class KnowledgeTool(Tool):
|
|
|
364
386
|
if action is KnowledgeAction.WORK_CREATE:
|
|
365
387
|
if not payload.work_title:
|
|
366
388
|
return text("❌ Provide work_title to create the item.")
|
|
389
|
+
if not payload.work_category:
|
|
390
|
+
return text(
|
|
391
|
+
"❌ Provide work_category to create the item. Values: backend, frontend, mobile, fullstack, devops, infra, platform, sre, database, security, data, analytics, ai_ml, qa, automation, design, research, product, project, agile, support, operations, documentation, training, architecture, planning, development."
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
# Resolve parent_key to parent_id if provided
|
|
395
|
+
parent_id = payload.parent_id
|
|
396
|
+
if payload.parent_key and not parent_id:
|
|
397
|
+
parent_work = await self._service.work_get_by_key(payload.parent_key)
|
|
398
|
+
parent_id = parent_work.get("id")
|
|
399
|
+
|
|
367
400
|
work = await self._service.work_create(
|
|
368
401
|
{
|
|
369
402
|
"title": payload.work_title,
|
|
370
403
|
"description": payload.work_description,
|
|
371
404
|
"item_type": payload.work_type,
|
|
372
|
-
"
|
|
405
|
+
"status_id": payload.work_status,
|
|
373
406
|
"priority": payload.work_priority,
|
|
407
|
+
"work_category": payload.work_category,
|
|
374
408
|
"story_points": payload.story_points,
|
|
375
409
|
"assignee_id": payload.assignee_id,
|
|
376
410
|
"sprint_id": payload.sprint_id,
|
|
377
|
-
"
|
|
378
|
-
"parent_id": payload.parent_id,
|
|
411
|
+
"parent_id": parent_id,
|
|
379
412
|
"due_date": payload.work_due_date,
|
|
380
413
|
"tags": payload.work_tags,
|
|
381
414
|
}
|
|
@@ -390,7 +423,6 @@ class KnowledgeTool(Tool):
|
|
|
390
423
|
type=payload.work_type,
|
|
391
424
|
assignee=payload.assignee_id,
|
|
392
425
|
sprint=payload.sprint_id,
|
|
393
|
-
board=payload.board_id,
|
|
394
426
|
)
|
|
395
427
|
if not items:
|
|
396
428
|
return text("🎯 No work items found.")
|
|
@@ -398,40 +430,51 @@ class KnowledgeTool(Tool):
|
|
|
398
430
|
return text(f"🎯 **Work items ({len(items)}):**\n\n{body}")
|
|
399
431
|
|
|
400
432
|
if action is KnowledgeAction.WORK_GET:
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
433
|
+
# Support both id and work_key
|
|
434
|
+
if payload.work_key:
|
|
435
|
+
work = await self._service.work_get_by_key(payload.work_key)
|
|
436
|
+
elif payload.id:
|
|
437
|
+
work = await self._service.work_get(payload.id)
|
|
438
|
+
else:
|
|
439
|
+
return text("❌ Provide id or work_key to get the work item.")
|
|
404
440
|
return text(
|
|
405
441
|
_format_work(work, header="🎯 Work item details", show_description=True)
|
|
406
442
|
)
|
|
407
443
|
|
|
408
444
|
if action is KnowledgeAction.WORK_UPDATE:
|
|
409
|
-
|
|
410
|
-
|
|
445
|
+
# Resolve work_key to id if needed
|
|
446
|
+
work_id = payload.id
|
|
447
|
+
if payload.work_key and not work_id:
|
|
448
|
+
work_item = await self._service.work_get_by_key(payload.work_key)
|
|
449
|
+
work_id = work_item.get("id")
|
|
450
|
+
if not work_id:
|
|
451
|
+
return text("❌ Provide id or work_key to update the work item.")
|
|
452
|
+
|
|
453
|
+
# Only allow safe fields to be updated via MCP
|
|
454
|
+
# Excluded: item_type, status_id, assignee_id, sprint_id, parent_id, work_category
|
|
411
455
|
work = await self._service.work_update(
|
|
412
|
-
|
|
456
|
+
work_id,
|
|
413
457
|
{
|
|
414
458
|
"title": payload.work_title,
|
|
415
459
|
"description": payload.work_description,
|
|
416
|
-
"item_type": payload.work_type,
|
|
417
|
-
"status": payload.work_status,
|
|
418
460
|
"priority": payload.work_priority,
|
|
419
461
|
"story_points": payload.story_points,
|
|
420
|
-
"assignee_id": payload.assignee_id,
|
|
421
|
-
"sprint_id": payload.sprint_id,
|
|
422
|
-
"board_id": payload.board_id,
|
|
423
|
-
"parent_id": payload.parent_id,
|
|
424
462
|
"due_date": payload.work_due_date,
|
|
425
463
|
"tags": payload.work_tags,
|
|
426
464
|
},
|
|
427
465
|
)
|
|
428
466
|
return text(_format_work(work, header="✅ Work item updated"))
|
|
429
467
|
|
|
430
|
-
if action is KnowledgeAction.
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
468
|
+
if action is KnowledgeAction.WORK_ASSIGN_TO_ME:
|
|
469
|
+
# Resolve work_key to id if needed
|
|
470
|
+
work_id = payload.id
|
|
471
|
+
if payload.work_key and not work_id:
|
|
472
|
+
work_item = await self._service.work_get_by_key(payload.work_key)
|
|
473
|
+
work_id = work_item.get("id")
|
|
474
|
+
if not work_id:
|
|
475
|
+
return text("❌ Provide id or work_key to assign the work item.")
|
|
476
|
+
work = await self._service.work_assign_to_me(work_id)
|
|
477
|
+
return text(_format_work(work, header="✅ Work item assigned to you"))
|
|
435
478
|
|
|
436
479
|
if action is KnowledgeAction.WORK_BACKLOG:
|
|
437
480
|
items = await self._service.work_backlog()
|
|
@@ -493,22 +536,32 @@ class KnowledgeTool(Tool):
|
|
|
493
536
|
return text(f"📦 **Epic work items ({len(items)}):**\n\n{body}")
|
|
494
537
|
|
|
495
538
|
if action is KnowledgeAction.WORK_CHILDREN:
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
539
|
+
# Support both id and work_key
|
|
540
|
+
work_id = payload.id
|
|
541
|
+
if payload.work_key and not work_id:
|
|
542
|
+
work_item = await self._service.work_get_by_key(payload.work_key)
|
|
543
|
+
work_id = work_item.get("id")
|
|
544
|
+
if not work_id:
|
|
545
|
+
return text("❌ Provide id or work_key to list children.")
|
|
546
|
+
items = await self._service.work_children(work_id)
|
|
499
547
|
if not items:
|
|
500
548
|
return text("👶 No child items found.")
|
|
501
549
|
body = "\n\n".join(_format_work(item) for item in items)
|
|
502
550
|
return text(f"👶 **Child work items ({len(items)}):**\n\n{body}")
|
|
503
551
|
|
|
504
552
|
if action is KnowledgeAction.WORK_STATUS_UPDATE:
|
|
505
|
-
|
|
506
|
-
|
|
553
|
+
# Resolve work_key to id if needed
|
|
554
|
+
work_id = payload.id
|
|
555
|
+
if payload.work_key and not work_id:
|
|
556
|
+
work_item = await self._service.work_get_by_key(payload.work_key)
|
|
557
|
+
work_id = work_item.get("id")
|
|
558
|
+
if not work_id:
|
|
559
|
+
return text("❌ Provide id or work_key to update status.")
|
|
507
560
|
if not payload.work_status:
|
|
508
|
-
return text("❌ Provide work_status to update.")
|
|
561
|
+
return text("❌ Provide work_status (status_id) to update.")
|
|
509
562
|
work = await self._service.work_update_status(
|
|
510
|
-
|
|
511
|
-
{"
|
|
563
|
+
work_id,
|
|
564
|
+
{"status_id": payload.work_status},
|
|
512
565
|
)
|
|
513
566
|
return text(_format_work(work, header="✅ Status updated"))
|
|
514
567
|
|
|
@@ -1074,14 +1127,21 @@ def _format_work(
|
|
|
1074
1127
|
lines.append(header)
|
|
1075
1128
|
lines.append("")
|
|
1076
1129
|
|
|
1130
|
+
# Extract key (e.g., DVPT-0001)
|
|
1131
|
+
key = item.get("key", "")
|
|
1132
|
+
|
|
1077
1133
|
# Extract title
|
|
1078
1134
|
title = item.get("title") or item.get("name") or "Untitled"
|
|
1079
1135
|
|
|
1080
1136
|
# Extract type
|
|
1081
1137
|
item_type = item.get("item_type") or item.get("type") or "unknown"
|
|
1082
1138
|
|
|
1083
|
-
# Extract status
|
|
1084
|
-
|
|
1139
|
+
# Extract status - prefer status object with name, fallback to status_id
|
|
1140
|
+
status_obj = item.get("status")
|
|
1141
|
+
if isinstance(status_obj, dict):
|
|
1142
|
+
status = status_obj.get("name", "unknown")
|
|
1143
|
+
else:
|
|
1144
|
+
status = item.get("status_id") or status_obj or "unknown"
|
|
1085
1145
|
|
|
1086
1146
|
# Extract priority
|
|
1087
1147
|
priority = item.get("priority") or item.get("priority_level") or "undefined"
|
|
@@ -1092,15 +1152,19 @@ def _format_work(
|
|
|
1092
1152
|
# Extract assignee - check both assignee_id and assignee object
|
|
1093
1153
|
assignee = item.get("assignee_id")
|
|
1094
1154
|
if not assignee and item.get("assignee"):
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
)
|
|
1155
|
+
assignee_obj = item.get("assignee", {})
|
|
1156
|
+
assignee = assignee_obj.get("name") or assignee_obj.get("id")
|
|
1098
1157
|
if not assignee:
|
|
1099
1158
|
assignee = "N/A"
|
|
1100
1159
|
|
|
1160
|
+
# Format title line with key if available
|
|
1161
|
+
if key:
|
|
1162
|
+
lines.append(f"🎯 **[{key}] {title}**")
|
|
1163
|
+
else:
|
|
1164
|
+
lines.append(f"🎯 **{title}**")
|
|
1165
|
+
|
|
1101
1166
|
lines.extend(
|
|
1102
1167
|
[
|
|
1103
|
-
f"🎯 **{title}**",
|
|
1104
1168
|
f"ID: {item_id}",
|
|
1105
1169
|
f"Type: {item_type}",
|
|
1106
1170
|
f"Status: {status}",
|
|
@@ -1108,6 +1172,11 @@ def _format_work(
|
|
|
1108
1172
|
f"Assignee: {assignee}",
|
|
1109
1173
|
]
|
|
1110
1174
|
)
|
|
1175
|
+
|
|
1176
|
+
# Add key as separate line if present (for easy reference)
|
|
1177
|
+
if key:
|
|
1178
|
+
lines.append(f"Key: {key}")
|
|
1179
|
+
|
|
1111
1180
|
if item.get("due_date") or item.get("dueDate"):
|
|
1112
1181
|
lines.append(
|
|
1113
1182
|
f"Due date: {_format_date(item.get('due_date') or item.get('dueDate'))}"
|
fenix_mcp/domain/knowledge.py
CHANGED
|
@@ -72,6 +72,12 @@ class KnowledgeService:
|
|
|
72
72
|
async def work_get(self, work_id: str) -> Dict[str, Any]:
|
|
73
73
|
return await self._call_dict(self.api.get_work_item, work_id)
|
|
74
74
|
|
|
75
|
+
async def work_get_by_key(self, key: str) -> Dict[str, Any]:
|
|
76
|
+
return await self._call_dict(self.api.get_work_item_by_key, key)
|
|
77
|
+
|
|
78
|
+
async def work_assign_to_me(self, work_id: str) -> Dict[str, Any]:
|
|
79
|
+
return await self._call_dict(self.api.assign_work_item_to_me, work_id)
|
|
80
|
+
|
|
75
81
|
async def work_update(
|
|
76
82
|
self, work_id: str, payload: Dict[str, Any]
|
|
77
83
|
) -> Dict[str, Any]:
|
|
@@ -492,6 +492,12 @@ class FenixApiClient:
|
|
|
492
492
|
def get_work_item(self, item_id: str) -> Any:
|
|
493
493
|
return self._request("GET", f"/api/work-items/{item_id}")
|
|
494
494
|
|
|
495
|
+
def get_work_item_by_key(self, key: str) -> Any:
|
|
496
|
+
return self._request("GET", f"/api/work-items/by-key/{key}")
|
|
497
|
+
|
|
498
|
+
def assign_work_item_to_me(self, item_id: str) -> Any:
|
|
499
|
+
return self._request("POST", f"/api/work-items/{item_id}/assign-to-me")
|
|
500
|
+
|
|
495
501
|
def update_work_item(self, item_id: str, payload: Mapping[str, Any]) -> Any:
|
|
496
502
|
return self._request("PATCH", f"/api/work-items/{item_id}", json=payload)
|
|
497
503
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
fenix_mcp/__init__.py,sha256=
|
|
1
|
+
fenix_mcp/__init__.py,sha256=0hD_tbK6SIxOmfllb0TMUOmfIeKzQvRt5FZWd9Uhcgw,180
|
|
2
2
|
fenix_mcp/main.py,sha256=iJV-9btNMDJMObvcn7wBQdbLLKjkYCQ1ANGEwHGHlMU,2857
|
|
3
3
|
fenix_mcp/application/presenters.py,sha256=fGME54PdCDhTBhXO-JUB9yLdBHiE1aeXLTC2fCuxnxM,689
|
|
4
4
|
fenix_mcp/application/tool_base.py,sha256=YJk7aSVGjXEvAkXrOHOuUjCFhYni9NPKFyPKiZqkrCc,4235
|
|
@@ -7,23 +7,23 @@ fenix_mcp/application/tools/__init__.py,sha256=Gi1YvYh-KdL9HD8gLVrknHrxiKKEOhHBE
|
|
|
7
7
|
fenix_mcp/application/tools/health.py,sha256=m5DxhoRbdwl6INzd6PISxv1NAv-ljCrezsr773VB0wE,834
|
|
8
8
|
fenix_mcp/application/tools/initialize.py,sha256=YfsE3fVYiqGEwvaI_jg5-0K7pGURXxpB3WNwETmGBPc,5499
|
|
9
9
|
fenix_mcp/application/tools/intelligence.py,sha256=fXfjBwAQmZCn3Zc8BqFnQFAJkpd9JsfOPa_uXJj-bMU,15778
|
|
10
|
-
fenix_mcp/application/tools/knowledge.py,sha256=
|
|
10
|
+
fenix_mcp/application/tools/knowledge.py,sha256=mQL3PmXCQIBpSMhpxCaWmF7silj__s1pc5dMJSciXUw,54650
|
|
11
11
|
fenix_mcp/application/tools/productivity.py,sha256=wyJ7-2VqgI2cdrliBD_ejwNvQhN1DecpXSQVrCxcUpQ,11231
|
|
12
12
|
fenix_mcp/application/tools/user_config.py,sha256=O5AVg7IUKL9uIoUoBSFovBDHl9jofhKWzhFK7CnKi4s,6470
|
|
13
13
|
fenix_mcp/domain/initialization.py,sha256=AZhdSNITQ7O3clELBuqGvjJc-c8pFKc7zQz-XR2xXPc,6933
|
|
14
14
|
fenix_mcp/domain/intelligence.py,sha256=j1kkxT-pjuzLQeAGDd2H8gd3O1aeUIRgHFnMGvNwQYg,8636
|
|
15
|
-
fenix_mcp/domain/knowledge.py,sha256=
|
|
15
|
+
fenix_mcp/domain/knowledge.py,sha256=X2terO-05fMzCpDTEmdIoAAzooEqx2odF90zIOXyf6I,20726
|
|
16
16
|
fenix_mcp/domain/productivity.py,sha256=PzY664eRPuBCfZGUY_Uv1GNeyMWsw6xqC54C-nobQns,6799
|
|
17
17
|
fenix_mcp/domain/user_config.py,sha256=8rzhJCNqIArfaCoKxxQXFoemCU7qww3hq0RDanIf_2Y,2028
|
|
18
18
|
fenix_mcp/infrastructure/config.py,sha256=zhJ3hhsP-bRfICcdq8rIDh5NGDe_u7AGpcgjcc2U1nY,1908
|
|
19
19
|
fenix_mcp/infrastructure/context.py,sha256=kiDiamiPbHZpTGyZMylcQwtLhfaDXrxAkWSst_DWQNw,470
|
|
20
20
|
fenix_mcp/infrastructure/http_client.py,sha256=QLIPhGYR_cBQGsbIO4RTR6ksyvkQt-OKHQU1JhPyap8,2470
|
|
21
21
|
fenix_mcp/infrastructure/logging.py,sha256=bHrWlSi_0HshRe3--BK_5nzUszW-gh37q6jsd0ShS2Y,1371
|
|
22
|
-
fenix_mcp/infrastructure/fenix_api/client.py,sha256=
|
|
22
|
+
fenix_mcp/infrastructure/fenix_api/client.py,sha256=5ewLAdZcNO59zgCkFLke0sTLU8dalo1W0nXKATt3F4Q,28301
|
|
23
23
|
fenix_mcp/interface/mcp_server.py,sha256=5UM2NJuNbwHkmCEprIFataJ5nFZiO8efTtP_oW3_iX0,2331
|
|
24
24
|
fenix_mcp/interface/transports.py,sha256=PxdhfjH8UMl03f7nuCLc-M6tMx6-Y-btVz_mSqXKrSI,8138
|
|
25
|
-
fenix_mcp-1.
|
|
26
|
-
fenix_mcp-1.
|
|
27
|
-
fenix_mcp-1.
|
|
28
|
-
fenix_mcp-1.
|
|
29
|
-
fenix_mcp-1.
|
|
25
|
+
fenix_mcp-1.6.0.dist-info/METADATA,sha256=ZIVb_fHfqXzT-S6-vxJqVplXjwGxNTIYYpPAH4AHirE,7260
|
|
26
|
+
fenix_mcp-1.6.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
27
|
+
fenix_mcp-1.6.0.dist-info/entry_points.txt,sha256=o52x_YHBupEd-1Z1GSfUjv3gJrx5_I-EkHhCgt1WBaE,49
|
|
28
|
+
fenix_mcp-1.6.0.dist-info/top_level.txt,sha256=2G1UtKpwjaIGQyE7sRoHecxaGLeuexfjrOUjv9DDKh4,10
|
|
29
|
+
fenix_mcp-1.6.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|