nia-mcp-server 1.0.14__tar.gz → 1.0.16__tar.gz

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.

Files changed (22) hide show
  1. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/PKG-INFO +1 -1
  2. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/pyproject.toml +1 -1
  3. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/src/nia_mcp_server/__init__.py +1 -1
  4. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/src/nia_mcp_server/api_client.py +43 -7
  5. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/src/nia_mcp_server/assets/rules/nia_rules.md +43 -4
  6. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/src/nia_mcp_server/server.py +42 -3
  7. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/.gitignore +0 -0
  8. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/ARCHITECTURE.md +0 -0
  9. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/LICENSE +0 -0
  10. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/README.md +0 -0
  11. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/nia_analytics.log +0 -0
  12. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/nia_mcp_server.log +0 -0
  13. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/src/nia_mcp_server/__main__.py +0 -0
  14. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/src/nia_mcp_server/assets/rules/claude_rules.md +0 -0
  15. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/src/nia_mcp_server/assets/rules/cursor_rules.md +0 -0
  16. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/src/nia_mcp_server/assets/rules/vscode_rules.md +0 -0
  17. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/src/nia_mcp_server/assets/rules/windsurf_rules.md +0 -0
  18. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/src/nia_mcp_server/cli.py +0 -0
  19. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/src/nia_mcp_server/profiles.py +0 -0
  20. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/src/nia_mcp_server/project_init.py +0 -0
  21. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/src/nia_mcp_server/rule_transformer.py +0 -0
  22. {nia_mcp_server-1.0.14 → nia_mcp_server-1.0.16}/src/nia_mcp_server/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nia-mcp-server
3
- Version: 1.0.14
3
+ Version: 1.0.16
4
4
  Summary: Nia Knowledge Agent
5
5
  Project-URL: Homepage, https://trynia.ai
6
6
  Project-URL: Documentation, https://docs.trynia.ai
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "nia-mcp-server"
7
- version = "1.0.14"
7
+ version = "1.0.16"
8
8
  description = "Nia Knowledge Agent"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -2,4 +2,4 @@
2
2
  NIA MCP Server - Proxy server for NIA Knowledge Agent
3
3
  """
4
4
 
5
- __version__ = "1.0.13"
5
+ __version__ = "1.0.16"
@@ -159,15 +159,33 @@ class NIAApiClient:
159
159
  async def index_repository(self, repo_url: str, branch: str = None) -> Dict[str, Any]:
160
160
  """Index a GitHub repository."""
161
161
  try:
162
- # Parse repo URL to get owner/repo format
162
+ # Handle different input formats
163
163
  if "github.com" in repo_url:
164
- parts = repo_url.rstrip('/').split('/')
165
- owner_repo = f"{parts[-2]}/{parts[-1]}"
164
+ # Remove query parameters and fragments
165
+ clean_url = repo_url.split('?')[0].split('#')[0]
166
+
167
+ # Check if it's a folder URL (contains /tree/)
168
+ if "/tree/" in clean_url:
169
+ # Extract everything after github.com/
170
+ parts = clean_url.split('github.com/', 1)
171
+ if len(parts) > 1:
172
+ repository_path = parts[1].rstrip('/')
173
+ else:
174
+ repository_path = repo_url
175
+ else:
176
+ # Regular repo URL - extract owner/repo
177
+ parts = clean_url.rstrip('/').split('/')
178
+ if len(parts) >= 2:
179
+ repo_name = parts[-1].rstrip('.git') # Remove .git suffix
180
+ repository_path = f"{parts[-2]}/{repo_name}"
181
+ else:
182
+ repository_path = repo_url
166
183
  else:
167
- owner_repo = repo_url
184
+ # Assume it's already in the right format
185
+ repository_path = repo_url
168
186
 
169
187
  payload = {
170
- "repository": owner_repo,
188
+ "repository": repository_path,
171
189
  "branch": branch
172
190
  }
173
191
 
@@ -191,11 +209,29 @@ class NIAApiClient:
191
209
  # First, list all repositories to find the matching one
192
210
  repos = await self.list_repositories()
193
211
 
212
+ # Extract base repository path for matching
213
+ # Handle both "owner/repo" and "owner/repo/folder" formats
214
+ base_repo = owner_repo
215
+ if owner_repo.count('/') > 1:
216
+ # This might be a folder path like "owner/repo/folder"
217
+ # Extract just the owner/repo part
218
+ parts = owner_repo.split('/')
219
+ base_repo = f"{parts[0]}/{parts[1]}"
220
+
194
221
  # Look for a repository matching this owner/repo
195
222
  matching_repo = None
196
223
  for repo in repos:
197
- # Check if repository field matches
198
- if repo.get("repository") == owner_repo:
224
+ repo_path = repo.get("repository", "")
225
+ # Check exact match first
226
+ if repo_path == owner_repo:
227
+ matching_repo = repo
228
+ break
229
+ # Then check if it's the base repository
230
+ elif repo_path == base_repo:
231
+ matching_repo = repo
232
+ break
233
+ # Also check if the stored repo is a folder path that starts with our base
234
+ elif repo_path.startswith(base_repo + "/"):
199
235
  matching_repo = repo
200
236
  break
201
237
 
@@ -29,25 +29,60 @@ Note: Nia is just "Nia" - not an acronym. It's the name of the knowledge search
29
29
  - Structured output needs (tables, lists)
30
30
  - Questions with "best", "which is better", "compare"
31
31
 
32
- ### 3. Query Optimization
32
+ ### 3. Repository Identifier Formats
33
+
34
+ #### Understanding Repository Paths
35
+ When using `search_codebase`, repositories can be specified in different formats:
36
+
37
+ 1. **Full Repository Format**: `owner/repo`
38
+ - Example: `facebook/react`
39
+ - Use this when the entire repository was indexed
40
+
41
+ 2. **Folder-Specific Format**: `owner/repo/tree/branch/folder`
42
+ - Example: `PostHog/posthog/tree/master/docs`
43
+ - Use this EXACT format when a specific folder was indexed
44
+ - This format appears in `list_repositories` output - copy it exactly!
45
+
46
+ #### Important Rules:
47
+ - **Always check `list_repositories` first** to see the exact format
48
+ - **Copy the repository identifier exactly** as shown in the list
49
+ - **Don't modify folder paths** - if it shows `owner/repo/tree/branch/folder`, use that exact string
50
+ - **Don't assume** - a repository indexed as a folder won't work with just `owner/repo`
51
+
52
+ #### Examples:
53
+ ```python
54
+ # Wrong - trying to use base repo when folder was indexed
55
+ search_codebase("What is Flox?", ["PostHog/posthog"]) # ❌ Won't find folder-indexed content
56
+
57
+ # Right - using exact format from list_repositories
58
+ search_codebase("What is Flox?", ["PostHog/posthog/tree/master/docs"]) # ✅ Searches the indexed folder
59
+
60
+ # Wrong - modifying the path
61
+ search_codebase("LLM guide", ["mcp-use/mcp-use/docs"]) # ❌ Missing /tree/main/ part
62
+
63
+ # Right - exact format
64
+ search_codebase("LLM guide", ["mcp-use/mcp-use/tree/main/docs"]) # ✅ Correct format
65
+ ```
66
+
67
+ ### 4. Query Optimization
33
68
  - **Use natural language queries** - Form complete questions, not just keywords
34
69
  - **Be specific and detailed** - "How does authentication work in NextAuth.js?" not "auth nextauth"
35
70
  - **Include context** - Mention specific technologies, frameworks, or use cases
36
71
  - **Leverage repository context** - Specify repositories when searching indexed codebases
37
72
 
38
- ### 4. API Usage Best Practices
73
+ ### 5. API Usage Best Practices
39
74
  - **Handle rate limits gracefully** - Free tier has 3 indexing operations limit
40
75
  - **Cache results mentally** - Avoid redundant searches in the same conversation
41
76
  - **Batch operations** - Index multiple related repositories together
42
77
  - **Monitor status efficiently** - Check status periodically, not continuously
43
78
 
44
- ### 5. Result Interpretation
79
+ ### 6. Result Interpretation
45
80
  - **Provide actionable next steps** - Always suggest how to use the results
46
81
  - **Extract indexable content** - Identify repositories and docs from search results
47
82
  - **Format for readability** - Use markdown formatting for clear presentation
48
83
  - **Include sources** - Always show where information comes from
49
84
 
50
- ### 6. Error Handling
85
+ ### 7. Error Handling
51
86
  - **Explain API limits clearly** - Help users understand free tier limitations
52
87
  - **Suggest alternatives** - Provide workarounds when hitting limits
53
88
  - **Report issues helpfully** - Include enough context for debugging
@@ -63,8 +98,12 @@ Note: Nia is just "Nia" - not an acronym. It's the name of the knowledge search
63
98
 
64
99
  ### Pattern 2: Codebase Understanding
65
100
  1. Check if repository is already indexed with `list_repositories`
101
+ - Note the EXACT repository format shown (especially for folder paths)
102
+ - Example output: "PostHog/posthog/tree/master/docs" (not just "PostHog/posthog")
66
103
  2. If not indexed, use `index_repository` and wait for completion
67
104
  3. Use `search_codebase` with specific technical questions
105
+ - Use the EXACT repository identifier from step 1
106
+ - Don't modify or simplify folder paths
68
107
  4. Include code snippets and file references in responses
69
108
 
70
109
  ### Pattern 3: Documentation Search
@@ -83,7 +83,7 @@ async def index_repository(
83
83
  Index a GitHub repository for intelligent code search.
84
84
 
85
85
  Args:
86
- repo_url: GitHub repository URL (e.g., https://github.com/owner/repo)
86
+ repo_url: GitHub repository URL (e.g., https://github.com/owner/repo or https://github.com/owner/repo/tree/branch)
87
87
  branch: Branch to index (optional, defaults to main branch)
88
88
 
89
89
  Returns:
@@ -158,11 +158,30 @@ async def search_codebase(
158
158
 
159
159
  Args:
160
160
  query: Natural language search query. Don't just use keywords or unstrctured query, make a comprehensive question to get the best results possible.
161
- repositories: List of repositories to search (owner/repo format). If not specified, searches all indexed repos.
161
+ repositories: List of repositories to search (owner/repo or owner/repo/tree/branch if indexed differently before).
162
+ - "owner/repo" - Search entire repository (e.g., "facebook/react")
163
+ - "owner/repo/tree/branch/folder" - Search specific folder indexed separately
164
+ (e.g., "PostHog/posthog/tree/master/docs")
165
+ Use the EXACT format shown in list_repositories output for folder-indexed repos.
166
+ If not specified, searches all indexed repos.
162
167
  include_sources: Whether to include source code in results
163
168
 
164
169
  Returns:
165
170
  Search results with relevant code snippets and explanations
171
+
172
+ Examples:
173
+ # Search all indexed repositories
174
+ search_codebase("How does authentication work?")
175
+
176
+ # Search specific repository
177
+ search_codebase("How to create custom hooks?", ["facebook/react"])
178
+
179
+ # Search folder-indexed repository (use exact format from list_repositories)
180
+ search_codebase("What is Flox?", ["PostHog/posthog/tree/master/docs"])
181
+
182
+ Important:
183
+ - If you want to search a specific folder, use the EXACT repository path shown above
184
+ - Example: `search_codebase(\"query\", [\"owner/repo/tree/branch/folder\"])`
166
185
  """
167
186
  try:
168
187
  client = await ensure_api_client()
@@ -451,6 +470,9 @@ async def list_repositories() -> List[TextContent]:
451
470
  # Format repository list
452
471
  lines = ["# Indexed Repositories\n"]
453
472
 
473
+ # Check if any repositories have folder paths (contain /tree/)
474
+ has_folder_repos = any('/tree/' in repo.get('repository', '') for repo in repositories)
475
+
454
476
  for repo in repositories:
455
477
  status_icon = "✅" if repo.get("status") == "completed" else "⏳"
456
478
 
@@ -470,6 +492,24 @@ async def list_repositories() -> List[TextContent]:
470
492
  lines.append(f"- **Indexed:** {repo['indexed_at']}")
471
493
  if repo.get("error"):
472
494
  lines.append(f"- **Error:** {repo['error']}")
495
+
496
+ # Add usage hint for completed repositories
497
+ if repo.get("status") == "completed":
498
+ lines.append(f"- **Usage:** `search_codebase(query, [\"{repo_name}\"])`")
499
+
500
+ # Add general usage instructions at the end
501
+ lines.extend([
502
+ "\n---",
503
+ "\n## Usage Tips",
504
+ "- To search all repositories: `search_codebase(\"your query\")`",
505
+ "- To search specific repository: `search_codebase(\"your query\", [\"owner/repo\"])`"
506
+ ])
507
+
508
+ if has_folder_repos:
509
+ lines.extend([
510
+ "- For folder-indexed repositories: Use the EXACT repository path shown above",
511
+ " Example: `search_codebase(\"query\", [\"owner/repo/tree/branch/folder\"])`"
512
+ ])
473
513
 
474
514
  return [TextContent(type="text", text="\n".join(lines))]
475
515
 
@@ -603,7 +643,6 @@ async def index_documentation(
603
643
  - When started indexing, prompt users to either use check_documentation_status tool or go to app.trynia.ai to check the status.
604
644
  - By default, crawls the entire domain (up to 10,000 pages)
605
645
  - Use exclude_patterns to filter out unwanted sections like blogs, changelogs, etc.
606
- - Screenshots are captured by default to provide visual context
607
646
  """
608
647
  try:
609
648
  client = await ensure_api_client()
File without changes