quickcall-integrations 0.3.0__py3-none-any.whl → 0.3.2__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.
@@ -195,40 +195,60 @@ def create_github_tools(mcp: FastMCP) -> None:
195
195
  raise ToolError(f"Failed to list pull requests: {str(e)}")
196
196
 
197
197
  @mcp.tool(tags={"github", "prs"})
198
- def get_pr(
199
- pr_number: int = Field(..., description="Pull request number", gt=0),
200
- owner: Optional[str] = Field(
201
- default=None,
202
- description="Repository owner. Uses your GitHub username if not specified.",
203
- ),
204
- repo: Optional[str] = Field(
205
- default=None,
206
- description="Repository name. Required.",
198
+ def get_prs(
199
+ pr_refs: List[dict] = Field(
200
+ ...,
201
+ description="List of PR references. Each item should have 'owner', 'repo', and 'number' keys. "
202
+ "Example: [{'owner': 'org', 'repo': 'myrepo', 'number': 123}, ...]",
207
203
  ),
208
204
  ) -> dict:
209
205
  """
210
- Get detailed information about a specific pull request.
206
+ Get detailed information about one or more pull requests.
207
+
208
+ Works for single or multiple PRs - fetches in parallel when multiple.
209
+ Each PR ref needs owner, repo, and number.
211
210
 
212
- Includes title, description, status, files changed, and review status.
211
+ Returns full PR details including additions, deletions, and files changed.
213
212
  Requires QuickCall authentication with GitHub connected.
214
213
  """
215
214
  try:
216
215
  client = _get_client()
217
- pr = client.get_pr(pr_number, owner=owner, repo=repo)
218
216
 
219
- if not pr:
220
- raise ToolError(f"Pull request #{pr_number} not found")
217
+ # Validate input
218
+ validated_refs = []
219
+ for ref in pr_refs:
220
+ if not isinstance(ref, dict):
221
+ raise ToolError(f"Invalid PR ref (must be dict): {ref}")
222
+ if "number" not in ref:
223
+ raise ToolError(f"Missing 'number' in PR ref: {ref}")
224
+ if "owner" not in ref or "repo" not in ref:
225
+ raise ToolError(
226
+ f"Missing 'owner' or 'repo' in PR ref: {ref}. "
227
+ "Each ref must have owner, repo, and number."
228
+ )
229
+ validated_refs.append(
230
+ {
231
+ "owner": ref["owner"],
232
+ "repo": ref["repo"],
233
+ "number": int(ref["number"]),
234
+ }
235
+ )
236
+
237
+ if not validated_refs:
238
+ return {"count": 0, "prs": []}
239
+
240
+ # Fetch all PRs in parallel
241
+ prs = client.fetch_prs_parallel(validated_refs, max_workers=10)
221
242
 
222
- return {"pr": pr.model_dump()}
243
+ return {
244
+ "count": len(prs),
245
+ "requested": len(validated_refs),
246
+ "prs": prs,
247
+ }
223
248
  except ToolError:
224
249
  raise
225
- except ValueError as e:
226
- raise ToolError(
227
- f"Repository not specified: {str(e)}. "
228
- f"Please provide both owner and repo parameters."
229
- )
230
250
  except Exception as e:
231
- raise ToolError(f"Failed to get pull request #{pr_number}: {str(e)}")
251
+ raise ToolError(f"Failed to fetch PRs: {str(e)}")
232
252
 
233
253
  @mcp.tool(tags={"github", "commits"})
234
254
  def list_commits(
@@ -373,97 +393,6 @@ def create_github_tools(mcp: FastMCP) -> None:
373
393
  except Exception as e:
374
394
  raise ToolError(f"Failed to list branches: {str(e)}")
375
395
 
376
- @mcp.tool(tags={"github", "prs", "appraisal"})
377
- def search_merged_prs(
378
- author: Optional[str] = Field(
379
- default=None,
380
- description="GitHub username to filter by. Defaults to authenticated user if not specified.",
381
- ),
382
- days: int = Field(
383
- default=180,
384
- description="Number of days to look back (default: 180 for ~6 months)",
385
- ),
386
- org: Optional[str] = Field(
387
- default=None,
388
- description="GitHub org to search within. If not specified, searches all accessible repos.",
389
- ),
390
- repo: Optional[str] = Field(
391
- default=None,
392
- description="Specific repo in 'owner/repo' format (e.g., 'revolving-org/supabase'). Overrides org if specified.",
393
- ),
394
- limit: int = Field(
395
- default=100,
396
- description="Maximum PRs to return (default: 100)",
397
- ),
398
- detail_level: str = Field(
399
- default="summary",
400
- description="'summary' for minimal fields (number, title, merged_at, repo, owner, html_url, author), "
401
- "'full' adds body and labels. Use 'summary' for large result sets.",
402
- ),
403
- ) -> dict:
404
- """
405
- Search for merged pull requests by author within a time period.
406
-
407
- USE FOR APPRAISALS: This tool is ideal for gathering contribution data
408
- for performance reviews. Returns basic PR info - use get_pr for full
409
- details (additions, deletions, files) on specific PRs.
410
-
411
- Claude should analyze the returned PRs to:
412
-
413
- 1. CATEGORIZE by type (look at PR title/labels):
414
- - Features: "feat:", "add:", "implement", "new", "create"
415
- - Enhancements: "improve:", "update:", "perf:", "optimize", "enhance"
416
- - Bug fixes: "fix:", "bugfix:", "hotfix:", "resolve", "patch"
417
- - Chores: "chore:", "docs:", "test:", "ci:", "refactor:", "bump"
418
-
419
- 2. IDENTIFY top PRs worth highlighting (call get_pr for detailed metrics)
420
-
421
- 3. SUMMARIZE for appraisal with accomplishments grouped by category
422
-
423
- Use detail_level='summary' (default) to avoid context overflow with large result sets.
424
- Use get_pr(number) to get full details for specific PRs when needed.
425
-
426
- Requires QuickCall authentication with GitHub connected.
427
- """
428
- try:
429
- client = _get_client()
430
-
431
- # Calculate since_date from days
432
- from datetime import datetime, timedelta, timezone
433
-
434
- since_date = (datetime.now(timezone.utc) - timedelta(days=days)).strftime(
435
- "%Y-%m-%d"
436
- )
437
-
438
- # Use authenticated user if author not specified
439
- if not author:
440
- creds = get_credential_store().get_api_credentials()
441
- if creds and creds.github_username:
442
- author = creds.github_username
443
-
444
- prs = client.search_merged_prs(
445
- author=author,
446
- since_date=since_date,
447
- org=org,
448
- repo=repo,
449
- limit=limit,
450
- detail_level=detail_level,
451
- )
452
-
453
- return {
454
- "count": len(prs),
455
- "detail_level": detail_level,
456
- "period": f"Last {days} days",
457
- "author": author,
458
- "org": org,
459
- "repo": repo,
460
- "prs": prs,
461
- }
462
- except ToolError:
463
- raise
464
- except Exception as e:
465
- raise ToolError(f"Failed to search merged PRs: {str(e)}")
466
-
467
396
  @mcp.tool(tags={"github", "prs", "appraisal"})
468
397
  def prepare_appraisal_data(
469
398
  author: Optional[str] = Field(
@@ -486,14 +415,16 @@ def create_github_tools(mcp: FastMCP) -> None:
486
415
  """
487
416
  Prepare appraisal data by fetching ALL merged PRs with full details.
488
417
 
489
- This tool:
490
- 1. Searches for all merged PRs by the author
491
- 2. Fetches FULL details (additions, deletions, files) for each PR IN PARALLEL
492
- 3. Dumps everything to a JSON file for later queries
493
- 4. Returns the file path + list of PR titles for Claude to review
418
+ USE THIS TOOL FOR APPRAISALS AND PERFORMANCE REVIEWS!
419
+
420
+ This is the recommended tool for gathering contribution data because it:
421
+ 1. Fetches ALL merged PRs with full stats (additions, deletions) in PARALLEL
422
+ 2. Dumps everything to a local file (avoids context overflow)
423
+ 3. Returns just PR titles for you to review
424
+ 4. Then use get_appraisal_pr_details(file_path, pr_numbers) for selected PRs
494
425
 
495
- USE THIS for appraisals instead of search_merged_prs + multiple get_pr calls.
496
- After calling this, use get_appraisal_pr_details to get full info for specific PRs.
426
+ DO NOT use search_merged_prs for appraisals - it doesn't include stats
427
+ and causes context overflow with large result sets.
497
428
  """
498
429
  import json
499
430
  import tempfile
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quickcall-integrations
3
- Version: 0.3.0
3
+ Version: 0.3.2
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
@@ -11,10 +11,10 @@ mcp_server/resources/slack_resources.py,sha256=b_CPxAicwkF3PsBXIat4QoLbDUHM2g_iP
11
11
  mcp_server/tools/__init__.py,sha256=vIR2ujAaTXm2DgpTsVNz3brI4G34p-Jeg44Qe0uvWc0,405
12
12
  mcp_server/tools/auth_tools.py,sha256=kCPjPC1jrVz0XaRAwPea-ue8ybjLLTxyILplBDJ9Mv4,24477
13
13
  mcp_server/tools/git_tools.py,sha256=jyCTQR2eSzUFXMt0Y8x66758-VY8YCY14DDUJt7GY2U,13957
14
- mcp_server/tools/github_tools.py,sha256=0WUX4r9F1vd0ZUlUQvG1239zuqWCuBFrG6a48_m5XTY,25667
14
+ mcp_server/tools/github_tools.py,sha256=N4VvJu1X-1rWNTqVovYmKKmfbrJYtZ5f9kM2ftFEBVo,23002
15
15
  mcp_server/tools/slack_tools.py,sha256=-HVE_x3Z1KMeYGi1xhyppEwz5ZF-I-ZD0-Up8yBeoYE,11796
16
16
  mcp_server/tools/utility_tools.py,sha256=1WiOpJivu6Ug9OLajm77lzsmFfBPgWHs8e1hNCEX_Aw,3359
17
- quickcall_integrations-0.3.0.dist-info/METADATA,sha256=5BIm2jpjEC6uCdnERPMZ4hArn9GyZUZXda31KNERd7k,7043
18
- quickcall_integrations-0.3.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
19
- quickcall_integrations-0.3.0.dist-info/entry_points.txt,sha256=kkcunmJUzncYvQ1rOR35V2LPm2HcFTKzdI2l3n7NwiM,66
20
- quickcall_integrations-0.3.0.dist-info/RECORD,,
17
+ quickcall_integrations-0.3.2.dist-info/METADATA,sha256=_xknARbrRiIxzxz38TCAe1yW9WYPLMfl_cyzm-Nx5JA,7043
18
+ quickcall_integrations-0.3.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
19
+ quickcall_integrations-0.3.2.dist-info/entry_points.txt,sha256=kkcunmJUzncYvQ1rOR35V2LPm2HcFTKzdI2l3n7NwiM,66
20
+ quickcall_integrations-0.3.2.dist-info/RECORD,,