nia-mcp-server 1.0.26__py3-none-any.whl → 1.0.27__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 nia-mcp-server might be problematic. Click here for more details.

@@ -3,4 +3,4 @@ NIA MCP Server - Proxy server for NIA Knowledge Agent
3
3
  """
4
4
 
5
5
 
6
- __version__ = "1.0.26"
6
+ __version__ = "1.0.27"
@@ -28,7 +28,7 @@ class NIAApiClient:
28
28
  self.client = httpx.AsyncClient(
29
29
  headers={
30
30
  "Authorization": f"Bearer {api_key}",
31
- "User-Agent": "nia-mcp-server/1.0.26",
31
+ "User-Agent": "nia-mcp-server/1.0.27",
32
32
  "Content-Type": "application/json"
33
33
  },
34
34
  timeout=720.0 # 12 minute timeout for deep research operations
@@ -432,15 +432,31 @@ class NIAApiClient:
432
432
  except Exception as e:
433
433
  logger.error(f"Failed to rename repository: {e}")
434
434
  raise APIError(f"Failed to rename repository: {str(e)}")
435
-
436
- async def get_repository_hierarchy(
435
+
436
+ async def get_github_tree(
437
437
  self,
438
438
  owner_repo: str,
439
- include_classes: bool = True,
440
- include_methods: bool = False,
441
- include_tree: bool = False
439
+ branch: Optional[str] = None,
440
+ include_paths: Optional[List[str]] = None,
441
+ exclude_paths: Optional[List[str]] = None,
442
+ file_extensions: Optional[List[str]] = None,
443
+ exclude_extensions: Optional[List[str]] = None,
444
+ show_full_paths: bool = False
442
445
  ) -> Dict[str, Any]:
443
- """Get the file hierarchy for a repository."""
446
+ """Get file tree directly from GitHub API (no FalkorDB dependency).
447
+
448
+ Args:
449
+ owner_repo: Repository in owner/repo format or repository ID
450
+ branch: Optional branch name (defaults to repository's default branch)
451
+ include_paths: Only include files in these paths (e.g., ["src/", "lib/"])
452
+ exclude_paths: Exclude files in these paths (e.g., ["node_modules/", "dist/"])
453
+ file_extensions: Only include these file extensions (e.g., [".py", ".js"])
454
+ exclude_extensions: Exclude these file extensions (e.g., [".md", ".lock"])
455
+ show_full_paths: Show full file paths instead of hierarchical tree
456
+
457
+ Returns:
458
+ GitHub tree structure with files, directories, and stats
459
+ """
444
460
  try:
445
461
  # Check if this looks like owner/repo format (contains /)
446
462
  if '/' in owner_repo:
@@ -462,38 +478,46 @@ class NIAApiClient:
462
478
  if not repo_id:
463
479
  raise APIError(f"No repository ID found for {owner_repo}", 404)
464
480
 
465
- # Get hierarchy using the ID
466
- params = {
467
- "include_classes": include_classes,
468
- "include_methods": include_methods
469
- }
470
-
471
- headers = {}
472
- if include_tree:
473
- headers["X-Include-Tree"] = "true"
481
+ # Get tree using the ID
482
+ params = {}
483
+ if branch:
484
+ params["branch"] = branch
485
+ if include_paths:
486
+ params["include_paths"] = ",".join(include_paths)
487
+ if exclude_paths:
488
+ params["exclude_paths"] = ",".join(exclude_paths)
489
+ if file_extensions:
490
+ params["file_extensions"] = ",".join(file_extensions)
491
+ if exclude_extensions:
492
+ params["exclude_extensions"] = ",".join(exclude_extensions)
493
+ if show_full_paths:
494
+ params["show_full_paths"] = "true"
474
495
 
475
496
  response = await self.client.get(
476
- f"{self.base_url}/v2/repositories/{repo_id}/hierarchy",
477
- params=params,
478
- headers=headers
497
+ f"{self.base_url}/v2/repositories/{repo_id}/github-tree",
498
+ params=params
479
499
  )
480
500
  response.raise_for_status()
481
501
  return response.json()
482
502
  else:
483
503
  # Assume it's already a repository ID
484
- params = {
485
- "include_classes": include_classes,
486
- "include_methods": include_methods
487
- }
488
-
489
- headers = {}
490
- if include_tree:
491
- headers["X-Include-Tree"] = "true"
504
+ params = {}
505
+ if branch:
506
+ params["branch"] = branch
507
+ if include_paths:
508
+ params["include_paths"] = ",".join(include_paths)
509
+ if exclude_paths:
510
+ params["exclude_paths"] = ",".join(exclude_paths)
511
+ if file_extensions:
512
+ params["file_extensions"] = ",".join(file_extensions)
513
+ if exclude_extensions:
514
+ params["exclude_extensions"] = ",".join(exclude_extensions)
515
+ if show_full_paths:
516
+ params["show_full_paths"] = "true"
492
517
 
493
518
  response = await self.client.get(
494
- f"{self.base_url}/v2/repositories/{owner_repo}/hierarchy",
495
- params=params,
496
- headers=headers
519
+ f"{self.base_url}/v2/repositories/{owner_repo}/github-tree",
520
+ params=params
497
521
  )
498
522
  response.raise_for_status()
499
523
  return response.json()
@@ -503,8 +527,8 @@ class NIAApiClient:
503
527
  except APIError:
504
528
  raise
505
529
  except Exception as e:
506
- logger.error(f"Failed to get repository hierarchy: {e}")
507
- raise APIError(f"Failed to get repository hierarchy: {str(e)}")
530
+ logger.error(f"Failed to get GitHub tree: {e}")
531
+ raise APIError(f"Failed to get GitHub tree: {str(e)}")
508
532
 
509
533
  # Data Source methods
510
534
 
@@ -729,22 +753,86 @@ class NIAApiClient:
729
753
  payload = {
730
754
  "query": query,
731
755
  }
732
-
756
+
733
757
  if output_format:
734
758
  payload["output_format"] = output_format
735
-
759
+
736
760
  response = await self.client.post(
737
761
  f"{self.base_url}/v2/deep-research",
738
762
  json=payload
739
763
  )
740
764
  response.raise_for_status()
741
765
  return response.json()
742
-
766
+
743
767
  except httpx.HTTPStatusError as e:
744
768
  raise self._handle_api_error(e)
745
769
  except Exception as e:
746
770
  raise APIError(f"Deep research failed: {str(e)}")
747
-
771
+
772
+ async def regex_search(
773
+ self,
774
+ repositories: List[str],
775
+ query: str,
776
+ pattern: Optional[str] = None,
777
+ file_extensions: Optional[List[str]] = None,
778
+ languages: Optional[List[str]] = None,
779
+ max_results: int = 50,
780
+ include_context: bool = True,
781
+ context_lines: int = 3
782
+ ) -> Dict[str, Any]:
783
+ """
784
+ Perform regex pattern search over indexed repository source code.
785
+
786
+ Args:
787
+ repositories: List of repositories to search (owner/repo format)
788
+ query: Natural language query or regex pattern
789
+ pattern: Optional explicit regex pattern (overrides query extraction)
790
+ file_extensions: File extensions to filter (e.g., [".js", ".tsx"])
791
+ languages: Programming languages to filter
792
+ max_results: Maximum number of results to return
793
+ include_context: Include surrounding context lines
794
+ context_lines: Number of context lines before/after match
795
+
796
+ Returns:
797
+ Search results with matched patterns and locations
798
+ """
799
+ try:
800
+ # Build repository list
801
+ repo_list = []
802
+ for repo in repositories:
803
+ if isinstance(repo, dict):
804
+ repo_list.append(repo)
805
+ else:
806
+ repo_list.append({"repository": repo})
807
+
808
+ payload = {
809
+ "repositories": repo_list,
810
+ "query": query,
811
+ "max_results": max_results,
812
+ "include_context": include_context,
813
+ "context_lines": context_lines
814
+ }
815
+
816
+ # Add optional parameters
817
+ if pattern:
818
+ payload["pattern"] = pattern
819
+ if file_extensions:
820
+ payload["file_extensions"] = file_extensions
821
+ if languages:
822
+ payload["languages"] = languages
823
+
824
+ response = await self.client.post(
825
+ f"{self.base_url}/v2/regex-search",
826
+ json=payload
827
+ )
828
+ response.raise_for_status()
829
+ return response.json()
830
+
831
+ except httpx.HTTPStatusError as e:
832
+ raise self._handle_api_error(e)
833
+ except Exception as e:
834
+ raise APIError(f"Regex search failed: {str(e)}")
835
+
748
836
  async def get_source_content(
749
837
  self,
750
838
  source_type: str,