quickcall-integrations 0.3.6__py3-none-any.whl → 0.3.8__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.
@@ -582,8 +582,16 @@ class GitHubClient:
582
582
  # Issue Operations
583
583
  # ========================================================================
584
584
 
585
- def _issue_to_dict(self, issue) -> Dict[str, Any]:
585
+ def _issue_to_dict(self, issue, summary: bool = False) -> Dict[str, Any]:
586
586
  """Convert PyGithub Issue to dict."""
587
+ if summary:
588
+ return {
589
+ "number": issue.number,
590
+ "title": issue.title,
591
+ "state": issue.state,
592
+ "labels": [label.name for label in issue.labels],
593
+ "html_url": issue.html_url,
594
+ }
587
595
  return {
588
596
  "number": issue.number,
589
597
  "title": issue.title,
@@ -595,6 +603,70 @@ class GitHubClient:
595
603
  "created_at": issue.created_at.isoformat(),
596
604
  }
597
605
 
606
+ def list_issues(
607
+ self,
608
+ owner: Optional[str] = None,
609
+ repo: Optional[str] = None,
610
+ state: str = "open",
611
+ labels: Optional[List[str]] = None,
612
+ assignee: Optional[str] = None,
613
+ creator: Optional[str] = None,
614
+ milestone: Optional[str] = None,
615
+ sort: str = "updated",
616
+ limit: int = 30,
617
+ ) -> List[Dict[str, Any]]:
618
+ """
619
+ List issues in a repository.
620
+
621
+ Args:
622
+ owner: Repository owner
623
+ repo: Repository name
624
+ state: Issue state: 'open', 'closed', or 'all'
625
+ labels: Filter by labels
626
+ assignee: Filter by assignee username
627
+ creator: Filter by issue creator username
628
+ milestone: Filter by milestone (number, title, or '*' for any, 'none' for no milestone)
629
+ sort: Sort by 'created', 'updated', or 'comments'
630
+ limit: Maximum issues to return
631
+
632
+ Returns:
633
+ List of issue summaries
634
+ """
635
+ gh_repo = self._get_repo(owner, repo)
636
+
637
+ kwargs = {"state": state, "sort": sort, "direction": "desc"}
638
+ if labels:
639
+ kwargs["labels"] = labels
640
+ if assignee:
641
+ kwargs["assignee"] = assignee
642
+ if creator:
643
+ kwargs["creator"] = creator
644
+ if milestone:
645
+ # Handle milestone - can be number, '*', 'none', or title
646
+ if milestone == "*" or milestone == "none":
647
+ kwargs["milestone"] = milestone
648
+ elif milestone.isdigit():
649
+ kwargs["milestone"] = gh_repo.get_milestone(int(milestone))
650
+ else:
651
+ # Search by title
652
+ for ms in gh_repo.get_milestones(state="all"):
653
+ if ms.title.lower() == milestone.lower():
654
+ kwargs["milestone"] = ms
655
+ break
656
+
657
+ issues = []
658
+ count = 0
659
+ for issue in gh_repo.get_issues(**kwargs):
660
+ # Skip pull requests (GitHub API returns PRs in issues endpoint)
661
+ if issue.pull_request is not None:
662
+ continue
663
+ issues.append(self._issue_to_dict(issue, summary=True))
664
+ count += 1
665
+ if count >= limit:
666
+ break
667
+
668
+ return issues
669
+
598
670
  def create_issue(
599
671
  self,
600
672
  title: str,
@@ -686,6 +758,232 @@ class GitHubClient:
686
758
  "issue_number": issue_number,
687
759
  }
688
760
 
761
+ def get_issue(
762
+ self,
763
+ issue_number: int,
764
+ owner: Optional[str] = None,
765
+ repo: Optional[str] = None,
766
+ include_sub_issues: bool = True,
767
+ ) -> Dict[str, Any]:
768
+ """
769
+ Get detailed information about a GitHub issue.
770
+
771
+ Args:
772
+ issue_number: Issue number
773
+ owner: Repository owner
774
+ repo: Repository name
775
+ include_sub_issues: Whether to fetch sub-issues list
776
+
777
+ Returns:
778
+ Issue details including sub-issues if requested
779
+ """
780
+ gh_repo = self._get_repo(owner, repo)
781
+ issue = gh_repo.get_issue(issue_number)
782
+
783
+ result = {
784
+ "number": issue.number,
785
+ "id": issue.id, # Internal ID needed for sub-issues API
786
+ "title": issue.title,
787
+ "body": issue.body,
788
+ "state": issue.state,
789
+ "html_url": issue.html_url,
790
+ "labels": [label.name for label in issue.labels],
791
+ "assignees": [a.login for a in issue.assignees],
792
+ "created_at": issue.created_at.isoformat(),
793
+ "updated_at": issue.updated_at.isoformat() if issue.updated_at else None,
794
+ "closed_at": issue.closed_at.isoformat() if issue.closed_at else None,
795
+ "comments_count": issue.comments,
796
+ "author": issue.user.login if issue.user else "unknown",
797
+ }
798
+
799
+ # Fetch sub-issues if requested
800
+ if include_sub_issues:
801
+ owner = owner or self.default_owner
802
+ repo_name = repo or self.default_repo
803
+ sub_issues = self.list_sub_issues(issue_number, owner=owner, repo=repo_name)
804
+ result["sub_issues"] = sub_issues
805
+ result["sub_issues_count"] = len(sub_issues)
806
+
807
+ return result
808
+
809
+ # ========================================================================
810
+ # Sub-Issue Operations (GitHub's native sub-issues feature)
811
+ # ========================================================================
812
+
813
+ def list_sub_issues(
814
+ self,
815
+ parent_issue_number: int,
816
+ owner: Optional[str] = None,
817
+ repo: Optional[str] = None,
818
+ ) -> List[Dict[str, Any]]:
819
+ """
820
+ List sub-issues of a parent issue.
821
+
822
+ Args:
823
+ parent_issue_number: Parent issue number
824
+ owner: Repository owner
825
+ repo: Repository name
826
+
827
+ Returns:
828
+ List of sub-issue summaries
829
+ """
830
+ owner = owner or self.default_owner
831
+ repo = repo or self.default_repo
832
+
833
+ if not owner or not repo:
834
+ raise ValueError("Repository owner and name must be specified")
835
+
836
+ try:
837
+ with httpx.Client() as client:
838
+ response = client.get(
839
+ f"https://api.github.com/repos/{owner}/{repo}/issues/{parent_issue_number}/sub_issues",
840
+ headers={
841
+ "Authorization": f"Bearer {self.token}",
842
+ "Accept": "application/vnd.github+json",
843
+ "X-GitHub-Api-Version": "2022-11-28",
844
+ },
845
+ timeout=30.0,
846
+ )
847
+ response.raise_for_status()
848
+ data = response.json()
849
+
850
+ return [
851
+ {
852
+ "number": item["number"],
853
+ "id": item["id"],
854
+ "title": item["title"],
855
+ "state": item["state"],
856
+ "html_url": item["html_url"],
857
+ }
858
+ for item in data
859
+ ]
860
+ except httpx.HTTPStatusError as e:
861
+ if e.response.status_code == 404:
862
+ # No sub-issues or feature not enabled
863
+ return []
864
+ logger.error(f"Failed to list sub-issues: HTTP {e.response.status_code}")
865
+ raise GithubException(e.response.status_code, e.response.json())
866
+ except Exception as e:
867
+ logger.error(f"Failed to list sub-issues: {e}")
868
+ return []
869
+
870
+ def add_sub_issue(
871
+ self,
872
+ parent_issue_number: int,
873
+ child_issue_number: int,
874
+ owner: Optional[str] = None,
875
+ repo: Optional[str] = None,
876
+ ) -> Dict[str, Any]:
877
+ """
878
+ Add an existing issue as a sub-issue to a parent.
879
+
880
+ Args:
881
+ parent_issue_number: Parent issue number
882
+ child_issue_number: Child issue number to add as sub-issue
883
+ owner: Repository owner
884
+ repo: Repository name
885
+
886
+ Returns:
887
+ Result with parent and child info
888
+ """
889
+ owner = owner or self.default_owner
890
+ repo = repo or self.default_repo
891
+
892
+ if not owner or not repo:
893
+ raise ValueError("Repository owner and name must be specified")
894
+
895
+ # First, get the child issue's internal ID (required by API)
896
+ gh_repo = self._get_repo(owner, repo)
897
+ child_issue = gh_repo.get_issue(child_issue_number)
898
+ child_id = child_issue.id
899
+
900
+ try:
901
+ with httpx.Client() as client:
902
+ response = client.post(
903
+ f"https://api.github.com/repos/{owner}/{repo}/issues/{parent_issue_number}/sub_issues",
904
+ headers={
905
+ "Authorization": f"Bearer {self.token}",
906
+ "Accept": "application/vnd.github+json",
907
+ "X-GitHub-Api-Version": "2022-11-28",
908
+ },
909
+ json={"sub_issue_id": child_id},
910
+ timeout=30.0,
911
+ )
912
+ response.raise_for_status()
913
+
914
+ return {
915
+ "success": True,
916
+ "parent_issue": parent_issue_number,
917
+ "child_issue": child_issue_number,
918
+ "child_id": child_id,
919
+ }
920
+ except httpx.HTTPStatusError as e:
921
+ logger.error(f"Failed to add sub-issue: HTTP {e.response.status_code}")
922
+ error_data = e.response.json() if e.response.content else {}
923
+ raise GithubException(
924
+ e.response.status_code,
925
+ error_data,
926
+ message=f"Failed to add #{child_issue_number} as sub-issue of #{parent_issue_number}",
927
+ )
928
+
929
+ def remove_sub_issue(
930
+ self,
931
+ parent_issue_number: int,
932
+ child_issue_number: int,
933
+ owner: Optional[str] = None,
934
+ repo: Optional[str] = None,
935
+ ) -> Dict[str, Any]:
936
+ """
937
+ Remove a sub-issue from a parent.
938
+
939
+ Args:
940
+ parent_issue_number: Parent issue number
941
+ child_issue_number: Child issue number to remove
942
+ owner: Repository owner
943
+ repo: Repository name
944
+
945
+ Returns:
946
+ Result with parent and child info
947
+ """
948
+ owner = owner or self.default_owner
949
+ repo = repo or self.default_repo
950
+
951
+ if not owner or not repo:
952
+ raise ValueError("Repository owner and name must be specified")
953
+
954
+ # Get the child issue's internal ID
955
+ gh_repo = self._get_repo(owner, repo)
956
+ child_issue = gh_repo.get_issue(child_issue_number)
957
+ child_id = child_issue.id
958
+
959
+ try:
960
+ with httpx.Client() as client:
961
+ response = client.delete(
962
+ f"https://api.github.com/repos/{owner}/{repo}/issues/{parent_issue_number}/sub_issues/{child_id}",
963
+ headers={
964
+ "Authorization": f"Bearer {self.token}",
965
+ "Accept": "application/vnd.github+json",
966
+ "X-GitHub-Api-Version": "2022-11-28",
967
+ },
968
+ timeout=30.0,
969
+ )
970
+ response.raise_for_status()
971
+
972
+ return {
973
+ "success": True,
974
+ "parent_issue": parent_issue_number,
975
+ "child_issue": child_issue_number,
976
+ "removed": True,
977
+ }
978
+ except httpx.HTTPStatusError as e:
979
+ logger.error(f"Failed to remove sub-issue: HTTP {e.response.status_code}")
980
+ error_data = e.response.json() if e.response.content else {}
981
+ raise GithubException(
982
+ e.response.status_code,
983
+ error_data,
984
+ message=f"Failed to remove #{child_issue_number} from #{parent_issue_number}",
985
+ )
986
+
689
987
  # ========================================================================
690
988
  # Search Operations (for Appraisals)
691
989
  # ========================================================================
@@ -570,11 +570,12 @@ def create_github_tools(mcp: FastMCP) -> None:
570
570
  def manage_issues(
571
571
  action: str = Field(
572
572
  ...,
573
- description="Action: 'create', 'update', 'close', 'reopen', or 'comment'",
573
+ description="Action: 'list', 'view', 'create', 'update', 'close', 'reopen', 'comment', "
574
+ "'add_sub_issue', 'remove_sub_issue', 'list_sub_issues'",
574
575
  ),
575
576
  issue_numbers: Optional[List[int]] = Field(
576
577
  default=None,
577
- description="Issue number(s). Required for update/close/reopen/comment. Supports bulk operations.",
578
+ description="Issue number(s). Required for view/update/close/reopen/comment/sub-issue ops.",
578
579
  ),
579
580
  title: Optional[str] = Field(
580
581
  default=None,
@@ -594,7 +595,12 @@ def create_github_tools(mcp: FastMCP) -> None:
594
595
  ),
595
596
  template: Optional[str] = Field(
596
597
  default=None,
597
- description="Template name for 'create' (e.g., 'bug', 'feature')",
598
+ description="Template name for 'create' (e.g., 'bug_report', 'feature_request')",
599
+ ),
600
+ parent_issue: Optional[int] = Field(
601
+ default=None,
602
+ description="Parent issue number. For 'create': attach new issue as sub-issue. "
603
+ "For 'add_sub_issue'/'remove_sub_issue'/'list_sub_issues': the parent issue.",
598
604
  ),
599
605
  owner: Optional[str] = Field(
600
606
  default=None,
@@ -604,20 +610,68 @@ def create_github_tools(mcp: FastMCP) -> None:
604
610
  default=None,
605
611
  description="Repository name. Required.",
606
612
  ),
613
+ state: Optional[str] = Field(
614
+ default="open",
615
+ description="Issue state filter for 'list': 'open', 'closed', or 'all' (default: 'open')",
616
+ ),
617
+ creator: Optional[str] = Field(
618
+ default=None,
619
+ description="Filter by issue creator username (for 'list')",
620
+ ),
621
+ milestone: Optional[str] = Field(
622
+ default=None,
623
+ description="Filter by milestone: number, title, '*' (any), or 'none' (for 'list')",
624
+ ),
625
+ sort: Optional[str] = Field(
626
+ default="updated",
627
+ description="Sort by: 'created', 'updated', or 'comments' (for 'list', default: 'updated')",
628
+ ),
629
+ limit: Optional[int] = Field(
630
+ default=30,
631
+ description="Maximum issues to return for 'list' action (default: 30)",
632
+ ),
607
633
  ) -> dict:
608
634
  """
609
- Manage GitHub issues: create, update, close, reopen, or comment.
635
+ Manage GitHub issues: list, view, create, update, close, reopen, comment, and sub-issues.
610
636
 
611
- Supports bulk operations for close/reopen/comment via issue_numbers list.
637
+ Supports bulk operations for view/close/reopen/comment via issue_numbers list.
612
638
 
613
639
  Examples:
614
- - create: manage_issues(action="create", title="Bug", template="bug")
640
+ - list: manage_issues(action="list", state="open", milestone="v1.0")
641
+ - list by creator: manage_issues(action="list", creator="username")
642
+ - view: manage_issues(action="view", issue_numbers=[42])
643
+ - create: manage_issues(action="create", title="Bug", template="bug_report")
644
+ - create as sub-issue: manage_issues(action="create", title="Task 1", parent_issue=42)
615
645
  - close multiple: manage_issues(action="close", issue_numbers=[1, 2, 3])
616
646
  - comment: manage_issues(action="comment", issue_numbers=[42], body="Fixed!")
647
+ - add sub-issues: manage_issues(action="add_sub_issue", issue_numbers=[43,44], parent_issue=42)
648
+ - remove sub-issue: manage_issues(action="remove_sub_issue", issue_numbers=[43], parent_issue=42)
649
+ - list sub-issues: manage_issues(action="list_sub_issues", parent_issue=42)
617
650
  """
618
651
  try:
619
652
  client = _get_client()
620
653
 
654
+ # === LIST ACTION ===
655
+ if action == "list":
656
+ issues = client.list_issues(
657
+ owner=owner,
658
+ repo=repo,
659
+ state=state or "open",
660
+ labels=labels,
661
+ assignee=assignees[0] if assignees else None,
662
+ creator=creator,
663
+ milestone=milestone,
664
+ sort=sort or "updated",
665
+ limit=limit or 30,
666
+ )
667
+ return {
668
+ "action": "list",
669
+ "state": state or "open",
670
+ "count": len(issues),
671
+ "issues": issues,
672
+ }
673
+
674
+ # === CREATE ACTION ===
621
675
  if action == "create":
622
676
  if not title:
623
677
  raise ToolError("'title' is required for 'create' action")
@@ -625,24 +679,79 @@ def create_github_tools(mcp: FastMCP) -> None:
625
679
  tpl = _load_issue_template(template)
626
680
  final_body = body if body is not None else tpl.get("body", "")
627
681
  final_labels = labels if labels is not None else tpl.get("labels", [])
682
+ final_assignees = (
683
+ assignees if assignees is not None else tpl.get("assignees", [])
684
+ )
685
+
686
+ # Apply title prefix from template if present
687
+ title_prefix = tpl.get("title_prefix", "")
688
+ if title_prefix and not title.startswith(title_prefix):
689
+ title = f"{title_prefix}{title}"
628
690
 
629
691
  issue = client.create_issue(
630
692
  title=title,
631
693
  body=final_body,
632
694
  labels=final_labels,
633
- assignees=assignees,
695
+ assignees=final_assignees,
634
696
  owner=owner,
635
697
  repo=repo,
636
698
  )
637
- return {"action": "created", "issue": issue}
638
699
 
639
- # All other actions require issue_numbers
700
+ result = {"action": "created", "issue": issue}
701
+
702
+ # If parent_issue specified, add as sub-issue
703
+ if parent_issue:
704
+ try:
705
+ sub_result = client.add_sub_issue(
706
+ parent_issue_number=parent_issue,
707
+ child_issue_number=issue["number"],
708
+ owner=owner,
709
+ repo=repo,
710
+ )
711
+ result["sub_issue_of"] = parent_issue
712
+ result["sub_issue_linked"] = sub_result.get("success", False)
713
+ except Exception as e:
714
+ result["sub_issue_error"] = str(e)
715
+
716
+ return result
717
+
718
+ # === LIST SUB-ISSUES ACTION ===
719
+ if action == "list_sub_issues":
720
+ if not parent_issue:
721
+ raise ToolError(
722
+ "'parent_issue' is required for 'list_sub_issues' action"
723
+ )
724
+
725
+ sub_issues = client.list_sub_issues(
726
+ parent_issue_number=parent_issue,
727
+ owner=owner,
728
+ repo=repo,
729
+ )
730
+ return {
731
+ "action": "list_sub_issues",
732
+ "parent_issue": parent_issue,
733
+ "count": len(sub_issues),
734
+ "sub_issues": sub_issues,
735
+ }
736
+
737
+ # === ALL OTHER ACTIONS REQUIRE issue_numbers ===
640
738
  if not issue_numbers:
641
739
  raise ToolError(f"'issue_numbers' required for '{action}' action")
642
740
 
643
741
  results = []
644
742
  for issue_number in issue_numbers:
645
- if action == "update":
743
+ # === VIEW ACTION ===
744
+ if action == "view":
745
+ issue_data = client.get_issue(
746
+ issue_number=issue_number,
747
+ owner=owner,
748
+ repo=repo,
749
+ include_sub_issues=True,
750
+ )
751
+ results.append(issue_data)
752
+
753
+ # === UPDATE ACTION ===
754
+ elif action == "update":
646
755
  client.update_issue(
647
756
  issue_number=issue_number,
648
757
  title=title,
@@ -654,14 +763,17 @@ def create_github_tools(mcp: FastMCP) -> None:
654
763
  )
655
764
  results.append({"number": issue_number, "status": "updated"})
656
765
 
766
+ # === CLOSE ACTION ===
657
767
  elif action == "close":
658
768
  client.close_issue(issue_number, owner=owner, repo=repo)
659
769
  results.append({"number": issue_number, "status": "closed"})
660
770
 
771
+ # === REOPEN ACTION ===
661
772
  elif action == "reopen":
662
773
  client.reopen_issue(issue_number, owner=owner, repo=repo)
663
774
  results.append({"number": issue_number, "status": "reopened"})
664
775
 
776
+ # === COMMENT ACTION ===
665
777
  elif action == "comment":
666
778
  if not body:
667
779
  raise ToolError("'body' is required for 'comment' action")
@@ -676,9 +788,57 @@ def create_github_tools(mcp: FastMCP) -> None:
676
788
  }
677
789
  )
678
790
 
791
+ # === ADD SUB-ISSUE ACTION ===
792
+ elif action == "add_sub_issue":
793
+ if not parent_issue:
794
+ raise ToolError(
795
+ "'parent_issue' is required for 'add_sub_issue' action"
796
+ )
797
+ sub_result = client.add_sub_issue(
798
+ parent_issue_number=parent_issue,
799
+ child_issue_number=issue_number,
800
+ owner=owner,
801
+ repo=repo,
802
+ )
803
+ results.append(
804
+ {
805
+ "number": issue_number,
806
+ "status": "added_as_sub_issue",
807
+ "parent_issue": parent_issue,
808
+ }
809
+ )
810
+
811
+ # === REMOVE SUB-ISSUE ACTION ===
812
+ elif action == "remove_sub_issue":
813
+ if not parent_issue:
814
+ raise ToolError(
815
+ "'parent_issue' is required for 'remove_sub_issue' action"
816
+ )
817
+ client.remove_sub_issue(
818
+ parent_issue_number=parent_issue,
819
+ child_issue_number=issue_number,
820
+ owner=owner,
821
+ repo=repo,
822
+ )
823
+ results.append(
824
+ {
825
+ "number": issue_number,
826
+ "status": "removed_from_parent",
827
+ "parent_issue": parent_issue,
828
+ }
829
+ )
830
+
679
831
  else:
680
832
  raise ToolError(f"Invalid action: {action}")
681
833
 
834
+ # Return format depends on action
835
+ if action == "view":
836
+ return {
837
+ "action": "view",
838
+ "count": len(results),
839
+ "issues": results,
840
+ }
841
+
682
842
  return {"action": action, "count": len(results), "results": results}
683
843
 
684
844
  except ToolError:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quickcall-integrations
3
- Version: 0.3.6
3
+ Version: 0.3.8
4
4
  Summary: MCP server with developer integrations for Claude Code and Cursor
5
5
  Requires-Python: >=3.10
6
6
  Requires-Dist: fastmcp>=2.13.0
@@ -1,7 +1,7 @@
1
1
  mcp_server/__init__.py,sha256=6KGzjSPyVB6vQh150DwBjINM_CsZNDhOzwSQFWpXz0U,301
2
2
  mcp_server/server.py,sha256=kv5hh0J-M7yENUBBNI1bkq1y7MB0zn5R_-R1tib6_sk,3108
3
3
  mcp_server/api_clients/__init__.py,sha256=kOG5_sxIVpAx_tvf1nq_P0QCkqojAVidRE-wenLS-Wc,207
4
- mcp_server/api_clients/github_client.py,sha256=HBLKgwZpbbdhroladE0l4mGjmuoa8uKCTf3oEL6S_P4,29298
4
+ mcp_server/api_clients/github_client.py,sha256=Mlh6BzMhZ05NqkX9A2O80eJIQXWuW4FnnN1DBM0WKC8,40135
5
5
  mcp_server/api_clients/slack_client.py,sha256=w3rcGghttfYw8Ird2beNo2LEYLc3rCTbUKMH4X7QQuQ,16447
6
6
  mcp_server/auth/__init__.py,sha256=D-JS0Qe7FkeJjYx92u_AqPx8ZRoB3dKMowzzJXlX6cc,780
7
7
  mcp_server/auth/credentials.py,sha256=sDS0W5c16i_UGvhG8Sh1RO93FxRn-hHVAdI9hlWuhx0,20011
@@ -12,10 +12,10 @@ mcp_server/resources/slack_resources.py,sha256=b_CPxAicwkF3PsBXIat4QoLbDUHM2g_iP
12
12
  mcp_server/tools/__init__.py,sha256=vIR2ujAaTXm2DgpTsVNz3brI4G34p-Jeg44Qe0uvWc0,405
13
13
  mcp_server/tools/auth_tools.py,sha256=kCPjPC1jrVz0XaRAwPea-ue8ybjLLTxyILplBDJ9Mv4,24477
14
14
  mcp_server/tools/git_tools.py,sha256=jyCTQR2eSzUFXMt0Y8x66758-VY8YCY14DDUJt7GY2U,13957
15
- mcp_server/tools/github_tools.py,sha256=iQvVuhWwVsKSPI7Ue6Eu0gYJcMKjWBAoo4U2Is9eIUI,33241
15
+ mcp_server/tools/github_tools.py,sha256=ZBJzRhg1BSFdn9VS4qi0PYLCSGBXRfHviKzjR0LxO08,40058
16
16
  mcp_server/tools/slack_tools.py,sha256=-HVE_x3Z1KMeYGi1xhyppEwz5ZF-I-ZD0-Up8yBeoYE,11796
17
17
  mcp_server/tools/utility_tools.py,sha256=oxAXpdqtPeB5Ug5dvk54V504r-8v1AO4_px-sO6LFOw,3910
18
- quickcall_integrations-0.3.6.dist-info/METADATA,sha256=tt1WubqnaF5Yjq9mE-8HDIsDqCYXO4vaXGSw5ZKKV2Q,7070
19
- quickcall_integrations-0.3.6.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
20
- quickcall_integrations-0.3.6.dist-info/entry_points.txt,sha256=kkcunmJUzncYvQ1rOR35V2LPm2HcFTKzdI2l3n7NwiM,66
21
- quickcall_integrations-0.3.6.dist-info/RECORD,,
18
+ quickcall_integrations-0.3.8.dist-info/METADATA,sha256=d5t3CbdPI7v4PkgeoJ4x4i8KuB_RZ_GDZv2N6GhkghA,7070
19
+ quickcall_integrations-0.3.8.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
20
+ quickcall_integrations-0.3.8.dist-info/entry_points.txt,sha256=kkcunmJUzncYvQ1rOR35V2LPm2HcFTKzdI2l3n7NwiM,66
21
+ quickcall_integrations-0.3.8.dist-info/RECORD,,