nia-mcp-server 1.0.11__tar.gz → 1.0.13__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.
- nia_mcp_server-1.0.13/PKG-INFO +39 -0
- nia_mcp_server-1.0.13/README.md +13 -0
- {nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/pyproject.toml +1 -1
- {nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/src/nia_mcp_server/__init__.py +1 -1
- nia_mcp_server-1.0.13/src/nia_mcp_server/__main__.py +21 -0
- {nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/src/nia_mcp_server/api_client.py +29 -3
- nia_mcp_server-1.0.13/src/nia_mcp_server/cli.py +69 -0
- {nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/src/nia_mcp_server/server.py +225 -30
- nia_mcp_server-1.0.13/src/nia_mcp_server/setup.py +177 -0
- nia_mcp_server-1.0.11/PKG-INFO +0 -246
- nia_mcp_server-1.0.11/README.md +0 -220
- nia_mcp_server-1.0.11/src/nia_mcp_server/__main__.py +0 -11
- {nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/.gitignore +0 -0
- {nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/ARCHITECTURE.md +0 -0
- {nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/LICENSE +0 -0
- {nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/nia_analytics.log +0 -0
- {nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/nia_mcp_server.log +0 -0
- {nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/src/nia_mcp_server/assets/rules/claude_rules.md +0 -0
- {nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/src/nia_mcp_server/assets/rules/cursor_rules.md +0 -0
- {nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/src/nia_mcp_server/assets/rules/nia_rules.md +0 -0
- {nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/src/nia_mcp_server/assets/rules/vscode_rules.md +0 -0
- {nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/src/nia_mcp_server/assets/rules/windsurf_rules.md +0 -0
- {nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/src/nia_mcp_server/profiles.py +0 -0
- {nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/src/nia_mcp_server/project_init.py +0 -0
- {nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/src/nia_mcp_server/rule_transformer.py +0 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nia-mcp-server
|
|
3
|
+
Version: 1.0.13
|
|
4
|
+
Summary: Nia Knowledge Agent
|
|
5
|
+
Project-URL: Homepage, https://trynia.ai
|
|
6
|
+
Project-URL: Documentation, https://docs.trynia.ai
|
|
7
|
+
Author-email: Nia Team <founders@nozomio.com>
|
|
8
|
+
License-Expression: AGPL-3.0
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: ai,codebase,mcp,nia,search
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: GNU Affero General Public License v3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Requires-Python: >=3.8
|
|
21
|
+
Requires-Dist: httpx>=0.24.0
|
|
22
|
+
Requires-Dist: mcp>=0.1.0
|
|
23
|
+
Requires-Dist: pydantic>=2.0.0
|
|
24
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# NIA MCP Server
|
|
28
|
+
|
|
29
|
+
The NIA MCP Server enables AI assistants like Claude to search and understand your indexed codebases through the Model Context Protocol (MCP).
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
### Automatic Setup (Recommended) ✨
|
|
34
|
+
|
|
35
|
+
Get your API key from [https://trynia.ai/api-keys](https://trynia.ai/api-keys) and run:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pipx run nia-mcp-server setup YOUR_API_KEY
|
|
39
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# NIA MCP Server
|
|
2
|
+
|
|
3
|
+
The NIA MCP Server enables AI assistants like Claude to search and understand your indexed codebases through the Model Context Protocol (MCP).
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### Automatic Setup (Recommended) ✨
|
|
8
|
+
|
|
9
|
+
Get your API key from [https://trynia.ai/api-keys](https://trynia.ai/api-keys) and run:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pipx run nia-mcp-server setup YOUR_API_KEY
|
|
13
|
+
```
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Entry point for NIA MCP Server
|
|
3
|
+
"""
|
|
4
|
+
import sys
|
|
5
|
+
from .server import run
|
|
6
|
+
from .cli import main as cli_main
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def main():
|
|
10
|
+
"""Main entry point."""
|
|
11
|
+
# Check if running as CLI command
|
|
12
|
+
if len(sys.argv) > 1 and sys.argv[1] in ["setup", "--help", "-h"]:
|
|
13
|
+
# Run CLI interface
|
|
14
|
+
cli_main()
|
|
15
|
+
else:
|
|
16
|
+
# Run MCP server
|
|
17
|
+
run()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
if __name__ == "__main__":
|
|
21
|
+
main()
|
|
@@ -75,7 +75,7 @@ class NIAApiClient:
|
|
|
75
75
|
"lifetime limit",
|
|
76
76
|
"no chat credits",
|
|
77
77
|
"free api requests",
|
|
78
|
-
"
|
|
78
|
+
"5 free",
|
|
79
79
|
"usage limit",
|
|
80
80
|
]
|
|
81
81
|
):
|
|
@@ -99,7 +99,7 @@ class NIAApiClient:
|
|
|
99
99
|
for phrase in [
|
|
100
100
|
"lifetime limit",
|
|
101
101
|
"free api requests",
|
|
102
|
-
"
|
|
102
|
+
"5 free",
|
|
103
103
|
"usage limit",
|
|
104
104
|
]
|
|
105
105
|
):
|
|
@@ -623,4 +623,30 @@ class NIAApiClient:
|
|
|
623
623
|
except httpx.HTTPStatusError as e:
|
|
624
624
|
raise self._handle_api_error(e)
|
|
625
625
|
except Exception as e:
|
|
626
|
-
raise APIError(f"Deep research failed: {str(e)}")
|
|
626
|
+
raise APIError(f"Deep research failed: {str(e)}")
|
|
627
|
+
|
|
628
|
+
async def get_source_content(
|
|
629
|
+
self,
|
|
630
|
+
source_type: str,
|
|
631
|
+
source_identifier: str,
|
|
632
|
+
metadata: Dict[str, Any] = None
|
|
633
|
+
) -> Dict[str, Any]:
|
|
634
|
+
"""Get full content of a specific source file or document."""
|
|
635
|
+
try:
|
|
636
|
+
payload = {
|
|
637
|
+
"source_type": source_type,
|
|
638
|
+
"source_identifier": source_identifier,
|
|
639
|
+
"metadata": metadata or {}
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
response = await self.client.post(
|
|
643
|
+
f"{self.base_url}/v2/sources/content",
|
|
644
|
+
json=payload
|
|
645
|
+
)
|
|
646
|
+
response.raise_for_status()
|
|
647
|
+
return response.json()
|
|
648
|
+
|
|
649
|
+
except httpx.HTTPStatusError as e:
|
|
650
|
+
raise self._handle_api_error(e)
|
|
651
|
+
except Exception as e:
|
|
652
|
+
raise APIError(f"Failed to get source content: {str(e)}")
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CLI interface for NIA MCP Server
|
|
3
|
+
"""
|
|
4
|
+
import sys
|
|
5
|
+
import argparse
|
|
6
|
+
from typing import Optional
|
|
7
|
+
from .setup import setup_mcp_config
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def validate_api_key(api_key: str) -> bool:
|
|
11
|
+
"""Validate API key format."""
|
|
12
|
+
if not api_key:
|
|
13
|
+
return False
|
|
14
|
+
# Check if it starts with the expected prefix
|
|
15
|
+
if not api_key.startswith("nk_"):
|
|
16
|
+
return False
|
|
17
|
+
# Check minimum length (prefix + reasonable key length)
|
|
18
|
+
if len(api_key) < 10:
|
|
19
|
+
return False
|
|
20
|
+
return True
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def main():
|
|
24
|
+
"""Main CLI entry point."""
|
|
25
|
+
parser = argparse.ArgumentParser(
|
|
26
|
+
description="NIA MCP Server - AI-powered code search",
|
|
27
|
+
prog="nia-mcp-server"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
subparsers = parser.add_subparsers(dest="command", help="Available commands")
|
|
31
|
+
|
|
32
|
+
# Setup command
|
|
33
|
+
setup_parser = subparsers.add_parser(
|
|
34
|
+
"setup",
|
|
35
|
+
help="Set up NIA MCP Server for your IDE"
|
|
36
|
+
)
|
|
37
|
+
setup_parser.add_argument(
|
|
38
|
+
"api_key",
|
|
39
|
+
help="Your NIA API key (get it from https://app.trynia.ai/api-keys)"
|
|
40
|
+
)
|
|
41
|
+
setup_parser.add_argument(
|
|
42
|
+
"--ide",
|
|
43
|
+
choices=["cursor", "vscode", "continue"],
|
|
44
|
+
default="cursor",
|
|
45
|
+
help="IDE to configure (default: cursor)"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
# Parse arguments
|
|
49
|
+
args = parser.parse_args()
|
|
50
|
+
|
|
51
|
+
# Handle commands
|
|
52
|
+
if args.command == "setup":
|
|
53
|
+
# Validate API key
|
|
54
|
+
if not validate_api_key(args.api_key):
|
|
55
|
+
print("❌ Invalid API key format. API key should start with 'nk_'")
|
|
56
|
+
print(" Get your API key from: https://app.trynia.ai/api-keys")
|
|
57
|
+
sys.exit(1)
|
|
58
|
+
|
|
59
|
+
# Run setup
|
|
60
|
+
success = setup_mcp_config(args.api_key, args.ide)
|
|
61
|
+
sys.exit(0 if success else 1)
|
|
62
|
+
|
|
63
|
+
# If no command specified, show help
|
|
64
|
+
parser.print_help()
|
|
65
|
+
sys.exit(1)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
if __name__ == "__main__":
|
|
69
|
+
main()
|
|
@@ -25,7 +25,7 @@ load_dotenv(env_path)
|
|
|
25
25
|
|
|
26
26
|
# Configure logging
|
|
27
27
|
logging.basicConfig(
|
|
28
|
-
level=logging.INFO,
|
|
28
|
+
level=logging.INFO, # Changed from INFO to DEBUG for troubleshooting
|
|
29
29
|
format='%(asctime)s [%(levelname)s] %(name)s: %(message)s',
|
|
30
30
|
)
|
|
31
31
|
logger = logging.getLogger(__name__)
|
|
@@ -122,7 +122,7 @@ async def index_repository(
|
|
|
122
122
|
except APIError as e:
|
|
123
123
|
logger.error(f"API Error indexing repository: {e} (status_code={e.status_code}, detail={e.detail})")
|
|
124
124
|
if e.status_code == 403 or "free tier limit" in str(e).lower() or "free api requests" in str(e).lower():
|
|
125
|
-
if e.detail and "
|
|
125
|
+
if e.detail and "5 free API requests" in e.detail:
|
|
126
126
|
return [TextContent(
|
|
127
127
|
type="text",
|
|
128
128
|
text=f"❌ {e.detail}\n\n💡 Tip: Upgrade to Pro at https://trynia.ai/billing for unlimited API access."
|
|
@@ -222,9 +222,11 @@ async def search_codebase(
|
|
|
222
222
|
response_parts.append(data["content"])
|
|
223
223
|
|
|
224
224
|
if "sources" in data and data["sources"]:
|
|
225
|
+
logger.debug(f"Received sources data: {type(data['sources'])}, count: {len(data['sources'])}")
|
|
225
226
|
sources_parts.extend(data["sources"])
|
|
226
227
|
|
|
227
|
-
except json.JSONDecodeError:
|
|
228
|
+
except json.JSONDecodeError as e:
|
|
229
|
+
logger.warning(f"Failed to parse JSON chunk: {chunk}, error: {e}")
|
|
228
230
|
continue
|
|
229
231
|
|
|
230
232
|
# Format the response
|
|
@@ -232,21 +234,53 @@ async def search_codebase(
|
|
|
232
234
|
|
|
233
235
|
if sources_parts and include_sources:
|
|
234
236
|
response_text += "\n\n## Sources\n\n"
|
|
235
|
-
for i, source in enumerate(sources_parts[:
|
|
237
|
+
for i, source in enumerate(sources_parts[:10], 1): # Limit to 10 sources (matches backend)
|
|
236
238
|
response_text += f"### Source {i}\n"
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
239
|
+
|
|
240
|
+
# Handle both string sources (file paths) and dictionary sources
|
|
241
|
+
if isinstance(source, str):
|
|
242
|
+
# Source is just a file path string
|
|
243
|
+
response_text += f"**File:** `{source}`\n\n"
|
|
244
|
+
continue
|
|
245
|
+
elif not isinstance(source, dict):
|
|
246
|
+
logger.warning(f"Expected source to be dict or str, got {type(source)}: {source}")
|
|
247
|
+
response_text += f"**Source:** {str(source)}\n\n"
|
|
248
|
+
continue
|
|
249
|
+
|
|
250
|
+
# Handle dictionary sources with metadata
|
|
251
|
+
metadata = source.get("metadata", {})
|
|
252
|
+
|
|
253
|
+
# Repository name
|
|
254
|
+
repository = source.get("repository") or metadata.get("source_name") or metadata.get("repository")
|
|
255
|
+
if repository:
|
|
256
|
+
response_text += f"**Repository:** {repository}\n"
|
|
257
|
+
|
|
258
|
+
# File path
|
|
259
|
+
file_path = source.get("file") or source.get("file_path") or metadata.get("file_path")
|
|
260
|
+
if file_path:
|
|
261
|
+
response_text += f"**File:** `{file_path}`\n"
|
|
262
|
+
|
|
263
|
+
# Content/preview
|
|
264
|
+
content = source.get("preview") or source.get("content")
|
|
265
|
+
if content:
|
|
266
|
+
# Truncate very long content
|
|
267
|
+
if len(content) > 500:
|
|
268
|
+
content = content[:500] + "..."
|
|
269
|
+
response_text += f"```\n{content}\n```\n\n"
|
|
270
|
+
else:
|
|
271
|
+
# If no content, at least show that this is a valid source
|
|
272
|
+
response_text += f"*Referenced source*\n\n"
|
|
273
|
+
|
|
274
|
+
# Add helpful text about read_source_content tool
|
|
275
|
+
response_text += "\n💡 **Need more details from a source?**\n\n"
|
|
276
|
+
response_text += "If you need more information from the source links provided above, use the `read_source_content` tool from the available tools provided by Nia to get full context about that particular source.\n"
|
|
243
277
|
|
|
244
278
|
return [TextContent(type="text", text=response_text)]
|
|
245
279
|
|
|
246
280
|
except APIError as e:
|
|
247
281
|
logger.error(f"API Error searching codebase: {e} (status_code={e.status_code}, detail={e.detail})")
|
|
248
282
|
if e.status_code == 403 or "free tier limit" in str(e).lower() or "free api requests" in str(e).lower():
|
|
249
|
-
if e.detail and "
|
|
283
|
+
if e.detail and "5 free API requests" in e.detail:
|
|
250
284
|
return [TextContent(
|
|
251
285
|
type="text",
|
|
252
286
|
text=f"❌ {e.detail}\n\n💡 Tip: Upgrade to Pro at https://trynia.ai/billing for unlimited API access."
|
|
@@ -287,6 +321,9 @@ async def search_documentation(
|
|
|
287
321
|
|
|
288
322
|
Returns:
|
|
289
323
|
Search results with relevant documentation excerpts
|
|
324
|
+
|
|
325
|
+
Important:
|
|
326
|
+
- Always use Source ID. If you don't have it, use `list_documentation` tool to get it.
|
|
290
327
|
"""
|
|
291
328
|
try:
|
|
292
329
|
client = await ensure_api_client()
|
|
@@ -316,7 +353,7 @@ async def search_documentation(
|
|
|
316
353
|
messages=messages,
|
|
317
354
|
repositories=[], # No repositories
|
|
318
355
|
data_sources=sources,
|
|
319
|
-
search_mode="unified", # Use unified for
|
|
356
|
+
search_mode="unified", # Use unified mode for intelligent LLM processing
|
|
320
357
|
stream=True,
|
|
321
358
|
include_sources=include_sources
|
|
322
359
|
):
|
|
@@ -327,9 +364,11 @@ async def search_documentation(
|
|
|
327
364
|
response_parts.append(data["content"])
|
|
328
365
|
|
|
329
366
|
if "sources" in data and data["sources"]:
|
|
367
|
+
logger.debug(f"Received doc sources data: {type(data['sources'])}, count: {len(data['sources'])}")
|
|
330
368
|
sources_parts.extend(data["sources"])
|
|
331
369
|
|
|
332
|
-
except json.JSONDecodeError:
|
|
370
|
+
except json.JSONDecodeError as e:
|
|
371
|
+
logger.warning(f"Failed to parse JSON chunk in documentation search: {chunk}, error: {e}")
|
|
333
372
|
continue
|
|
334
373
|
|
|
335
374
|
# Format the response
|
|
@@ -337,14 +376,42 @@ async def search_documentation(
|
|
|
337
376
|
|
|
338
377
|
if sources_parts and include_sources:
|
|
339
378
|
response_text += "\n\n## Sources\n\n"
|
|
340
|
-
for i, source in enumerate(sources_parts[:
|
|
379
|
+
for i, source in enumerate(sources_parts[:10], 1): # Limit to 10 sources (matches backend)
|
|
341
380
|
response_text += f"### Source {i}\n"
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
381
|
+
|
|
382
|
+
# Handle both string sources and dictionary sources
|
|
383
|
+
if isinstance(source, str):
|
|
384
|
+
# Source is just a URL or file path string
|
|
385
|
+
response_text += f"**Document:** {source}\n\n"
|
|
386
|
+
continue
|
|
387
|
+
elif not isinstance(source, dict):
|
|
388
|
+
logger.warning(f"Expected source to be dict or str, got {type(source)}: {source}")
|
|
389
|
+
response_text += f"**Source:** {str(source)}\n\n"
|
|
390
|
+
continue
|
|
391
|
+
|
|
392
|
+
# Handle dictionary sources with metadata
|
|
393
|
+
metadata = source.get("metadata", {})
|
|
394
|
+
|
|
395
|
+
# URL or file
|
|
396
|
+
url = source.get("url") or metadata.get("url") or metadata.get("source") or metadata.get("sourceURL")
|
|
397
|
+
file_path = source.get("file") or source.get("file_path") or metadata.get("file_path") or metadata.get("document_name")
|
|
398
|
+
|
|
399
|
+
if url:
|
|
400
|
+
response_text += f"**URL:** {url}\n"
|
|
401
|
+
elif file_path:
|
|
402
|
+
response_text += f"**Document:** {file_path}\n"
|
|
403
|
+
|
|
404
|
+
# Title if available
|
|
405
|
+
title = source.get("title") or metadata.get("title")
|
|
406
|
+
if title:
|
|
407
|
+
response_text += f"**Title:** {title}\n"
|
|
408
|
+
|
|
409
|
+
# Add spacing after each source
|
|
410
|
+
response_text += "\n"
|
|
411
|
+
|
|
412
|
+
# Add helpful text about read_source_content tool
|
|
413
|
+
response_text += "\n💡 **Need more details from a source?**\n\n"
|
|
414
|
+
response_text += "If you need more information from the source links provided above, use the `read_source_content` tool from the available tools provided by Nia to get full context about that particular source.\n"
|
|
348
415
|
|
|
349
416
|
return [TextContent(type="text", text=response_text)]
|
|
350
417
|
|
|
@@ -352,7 +419,7 @@ async def search_documentation(
|
|
|
352
419
|
logger.error(f"API Error searching documentation: {e}")
|
|
353
420
|
error_msg = f"❌ {str(e)}"
|
|
354
421
|
if e.status_code == 403 and "lifetime limit" in str(e).lower():
|
|
355
|
-
error_msg += "\n\n💡 Tip: You've reached the free tier limit of
|
|
422
|
+
error_msg += "\n\n💡 Tip: You've reached the free tier limit of 5 API requests. Upgrade to Pro for unlimited access."
|
|
356
423
|
return [TextContent(type="text", text=error_msg)]
|
|
357
424
|
except Exception as e:
|
|
358
425
|
logger.error(f"Error searching documentation: {e}")
|
|
@@ -411,7 +478,7 @@ async def list_repositories() -> List[TextContent]:
|
|
|
411
478
|
# Check for free tier limit errors
|
|
412
479
|
if e.status_code == 403 or "free tier limit" in str(e).lower() or "free api requests" in str(e).lower():
|
|
413
480
|
# Extract the specific limit message
|
|
414
|
-
if e.detail and "
|
|
481
|
+
if e.detail and "5 free API requests" in e.detail:
|
|
415
482
|
return [TextContent(
|
|
416
483
|
type="text",
|
|
417
484
|
text=f"❌ {e.detail}\n\n💡 Tip: Upgrade to Pro at https://trynia.ai/billing for unlimited API access."
|
|
@@ -491,7 +558,7 @@ async def check_repository_status(repository: str) -> List[TextContent]:
|
|
|
491
558
|
logger.error(f"API Error checking repository status: {e}")
|
|
492
559
|
error_msg = f"❌ {str(e)}"
|
|
493
560
|
if e.status_code == 403 and "lifetime limit" in str(e).lower():
|
|
494
|
-
error_msg += "\n\n💡 Tip: You've reached the free tier limit of
|
|
561
|
+
error_msg += "\n\n💡 Tip: You've reached the free tier limit of 5 API requests. Upgrade to Pro for unlimited access."
|
|
495
562
|
return [TextContent(type="text", text=error_msg)]
|
|
496
563
|
except Exception as e:
|
|
497
564
|
logger.error(f"Error checking repository status: {e}")
|
|
@@ -578,7 +645,7 @@ async def index_documentation(
|
|
|
578
645
|
logger.error(f"API Error indexing documentation: {e}")
|
|
579
646
|
error_msg = f"❌ {str(e)}"
|
|
580
647
|
if e.status_code == 403 and "lifetime limit" in str(e).lower():
|
|
581
|
-
error_msg += "\n\n💡 Tip: You've reached the free tier limit of
|
|
648
|
+
error_msg += "\n\n💡 Tip: You've reached the free tier limit of 5 API requests. Upgrade to Pro for unlimited access."
|
|
582
649
|
return [TextContent(type="text", text=error_msg)]
|
|
583
650
|
except Exception as e:
|
|
584
651
|
logger.error(f"Error indexing documentation: {e}")
|
|
@@ -637,7 +704,7 @@ async def list_documentation() -> List[TextContent]:
|
|
|
637
704
|
logger.error(f"API Error listing documentation: {e}")
|
|
638
705
|
error_msg = f"❌ {str(e)}"
|
|
639
706
|
if e.status_code == 403 and "lifetime limit" in str(e).lower():
|
|
640
|
-
error_msg += "\n\n💡 Tip: You've reached the free tier limit of
|
|
707
|
+
error_msg += "\n\n💡 Tip: You've reached the free tier limit of 5 API requests. Upgrade to Pro for unlimited access."
|
|
641
708
|
return [TextContent(type="text", text=error_msg)]
|
|
642
709
|
except Exception as e:
|
|
643
710
|
logger.error(f"Error listing documentation: {e}")
|
|
@@ -703,7 +770,7 @@ async def check_documentation_status(source_id: str) -> List[TextContent]:
|
|
|
703
770
|
logger.error(f"API Error checking documentation status: {e}")
|
|
704
771
|
error_msg = f"❌ {str(e)}"
|
|
705
772
|
if e.status_code == 403 and "lifetime limit" in str(e).lower():
|
|
706
|
-
error_msg += "\n\n💡 Tip: You've reached the free tier limit of
|
|
773
|
+
error_msg += "\n\n💡 Tip: You've reached the free tier limit of 5 API requests. Upgrade to Pro for unlimited access."
|
|
707
774
|
return [TextContent(type="text", text=error_msg)]
|
|
708
775
|
except Exception as e:
|
|
709
776
|
logger.error(f"Error checking documentation status: {e}")
|
|
@@ -742,7 +809,7 @@ async def delete_documentation(source_id: str) -> List[TextContent]:
|
|
|
742
809
|
logger.error(f"API Error deleting documentation: {e}")
|
|
743
810
|
error_msg = f"❌ {str(e)}"
|
|
744
811
|
if e.status_code == 403 and "lifetime limit" in str(e).lower():
|
|
745
|
-
error_msg += "\n\n💡 Tip: You've reached the free tier limit of
|
|
812
|
+
error_msg += "\n\n💡 Tip: You've reached the free tier limit of 5 API requests. Upgrade to Pro for unlimited access."
|
|
746
813
|
return [TextContent(type="text", text=error_msg)]
|
|
747
814
|
except Exception as e:
|
|
748
815
|
logger.error(f"Error deleting documentation: {e}")
|
|
@@ -781,7 +848,7 @@ async def delete_repository(repository: str) -> List[TextContent]:
|
|
|
781
848
|
logger.error(f"API Error deleting repository: {e}")
|
|
782
849
|
error_msg = f"❌ {str(e)}"
|
|
783
850
|
if e.status_code == 403 and "lifetime limit" in str(e).lower():
|
|
784
|
-
error_msg += "\n\n💡 Tip: You've reached the free tier limit of
|
|
851
|
+
error_msg += "\n\n💡 Tip: You've reached the free tier limit of 5 API requests. Upgrade to Pro for unlimited access."
|
|
785
852
|
return [TextContent(type="text", text=error_msg)]
|
|
786
853
|
except Exception as e:
|
|
787
854
|
logger.error(f"Error deleting repository: {e}")
|
|
@@ -1033,7 +1100,7 @@ async def nia_web_search(
|
|
|
1033
1100
|
except APIError as e:
|
|
1034
1101
|
logger.error(f"API Error in web search: {e}")
|
|
1035
1102
|
if e.status_code == 403 or "free tier limit" in str(e).lower() or "free api requests" in str(e).lower():
|
|
1036
|
-
if e.detail and "
|
|
1103
|
+
if e.detail and "5 free API requests" in e.detail:
|
|
1037
1104
|
return [TextContent(
|
|
1038
1105
|
type="text",
|
|
1039
1106
|
text=f"❌ {e.detail}\n\n💡 Tip: Upgrade to Pro at https://trynia.ai/billing for unlimited API access."
|
|
@@ -1212,7 +1279,7 @@ async def nia_deep_research_agent(
|
|
|
1212
1279
|
except APIError as e:
|
|
1213
1280
|
logger.error(f"API Error in deep research: {e}")
|
|
1214
1281
|
if e.status_code == 403 or "free tier limit" in str(e).lower() or "free api requests" in str(e).lower():
|
|
1215
|
-
if e.detail and "
|
|
1282
|
+
if e.detail and "5 free API requests" in e.detail:
|
|
1216
1283
|
return [TextContent(
|
|
1217
1284
|
type="text",
|
|
1218
1285
|
text=f"❌ {e.detail}\n\n💡 Tip: Upgrade to Pro at https://trynia.ai/billing for unlimited API access."
|
|
@@ -1388,6 +1455,134 @@ async def initialize_project(
|
|
|
1388
1455
|
"- The NIA MCP server is properly installed"
|
|
1389
1456
|
)]
|
|
1390
1457
|
|
|
1458
|
+
@mcp.tool()
|
|
1459
|
+
async def read_source_content(
|
|
1460
|
+
source_type: str,
|
|
1461
|
+
source_identifier: str,
|
|
1462
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
1463
|
+
) -> List[TextContent]:
|
|
1464
|
+
"""
|
|
1465
|
+
Read the full content of a specific source file or document.
|
|
1466
|
+
|
|
1467
|
+
This tool allows AI to fetch complete content from sources identified during search,
|
|
1468
|
+
enabling deeper analysis when the truncated search results are insufficient.
|
|
1469
|
+
|
|
1470
|
+
Args:
|
|
1471
|
+
source_type: Type of source - "repository" or "documentation"
|
|
1472
|
+
source_identifier:
|
|
1473
|
+
- For repository: "owner/repo:path/to/file.py" (e.g., "facebook/react:src/React.js")
|
|
1474
|
+
- For documentation: The source URL or document ID
|
|
1475
|
+
metadata: Optional metadata from search results to help locate the source
|
|
1476
|
+
|
|
1477
|
+
Returns:
|
|
1478
|
+
Full content of the requested source with metadata
|
|
1479
|
+
|
|
1480
|
+
Examples:
|
|
1481
|
+
- read_source_content("repository", "langchain-ai/langchain:libs/core/langchain_core/runnables/base.py")
|
|
1482
|
+
- read_source_content("documentation", "https://docs.python.org/3/library/asyncio.html")
|
|
1483
|
+
"""
|
|
1484
|
+
try:
|
|
1485
|
+
client = await ensure_api_client()
|
|
1486
|
+
|
|
1487
|
+
logger.info(f"Reading source content - type: {source_type}, identifier: {source_identifier}")
|
|
1488
|
+
|
|
1489
|
+
# Call the API to get source content
|
|
1490
|
+
result = await client.get_source_content(
|
|
1491
|
+
source_type=source_type,
|
|
1492
|
+
source_identifier=source_identifier,
|
|
1493
|
+
metadata=metadata or {}
|
|
1494
|
+
)
|
|
1495
|
+
|
|
1496
|
+
if not result or not result.get("success"):
|
|
1497
|
+
error_msg = result.get("error", "Unknown error") if result else "Failed to fetch source content"
|
|
1498
|
+
return [TextContent(
|
|
1499
|
+
type="text",
|
|
1500
|
+
text=f"❌ Error reading source: {error_msg}"
|
|
1501
|
+
)]
|
|
1502
|
+
|
|
1503
|
+
# Format the response
|
|
1504
|
+
content = result.get("content", "")
|
|
1505
|
+
source_metadata = result.get("metadata", {})
|
|
1506
|
+
|
|
1507
|
+
# Build response with metadata header
|
|
1508
|
+
response_lines = []
|
|
1509
|
+
|
|
1510
|
+
if source_type == "repository":
|
|
1511
|
+
repo_name = source_metadata.get("repository", "Unknown")
|
|
1512
|
+
file_path = source_metadata.get("file_path", source_identifier.split(":", 1)[-1] if ":" in source_identifier else "Unknown")
|
|
1513
|
+
branch = source_metadata.get("branch", "main")
|
|
1514
|
+
|
|
1515
|
+
response_lines.extend([
|
|
1516
|
+
f"# Source: {repo_name}",
|
|
1517
|
+
f"**File:** `{file_path}`",
|
|
1518
|
+
f"**Branch:** {branch}",
|
|
1519
|
+
""
|
|
1520
|
+
])
|
|
1521
|
+
|
|
1522
|
+
if source_metadata.get("url"):
|
|
1523
|
+
response_lines.append(f"**GitHub URL:** {source_metadata['url']}")
|
|
1524
|
+
response_lines.append("")
|
|
1525
|
+
|
|
1526
|
+
# Add file info if available
|
|
1527
|
+
if source_metadata.get("size"):
|
|
1528
|
+
response_lines.append(f"**Size:** {source_metadata['size']} bytes")
|
|
1529
|
+
if source_metadata.get("language"):
|
|
1530
|
+
response_lines.append(f"**Language:** {source_metadata['language']}")
|
|
1531
|
+
|
|
1532
|
+
response_lines.extend(["", "## Content", ""])
|
|
1533
|
+
|
|
1534
|
+
# Add code block with language hint
|
|
1535
|
+
language = source_metadata.get("language", "").lower() or "text"
|
|
1536
|
+
response_lines.append(f"```{language}")
|
|
1537
|
+
response_lines.append(content)
|
|
1538
|
+
response_lines.append("```")
|
|
1539
|
+
|
|
1540
|
+
elif source_type == "documentation":
|
|
1541
|
+
url = source_metadata.get("url", source_identifier)
|
|
1542
|
+
title = source_metadata.get("title", "Documentation")
|
|
1543
|
+
|
|
1544
|
+
response_lines.extend([
|
|
1545
|
+
f"# Documentation: {title}",
|
|
1546
|
+
f"**URL:** {url}",
|
|
1547
|
+
""
|
|
1548
|
+
])
|
|
1549
|
+
|
|
1550
|
+
if source_metadata.get("last_updated"):
|
|
1551
|
+
response_lines.append(f"**Last Updated:** {source_metadata['last_updated']}")
|
|
1552
|
+
response_lines.append("")
|
|
1553
|
+
|
|
1554
|
+
response_lines.extend(["## Content", "", content])
|
|
1555
|
+
|
|
1556
|
+
else:
|
|
1557
|
+
# Generic format for unknown source types
|
|
1558
|
+
response_lines.extend([
|
|
1559
|
+
f"# Source Content",
|
|
1560
|
+
f"**Type:** {source_type}",
|
|
1561
|
+
f"**Identifier:** {source_identifier}",
|
|
1562
|
+
"",
|
|
1563
|
+
"## Content",
|
|
1564
|
+
"",
|
|
1565
|
+
content
|
|
1566
|
+
])
|
|
1567
|
+
|
|
1568
|
+
return [TextContent(type="text", text="\n".join(response_lines))]
|
|
1569
|
+
|
|
1570
|
+
except APIError as e:
|
|
1571
|
+
logger.error(f"API Error reading source content: {e}")
|
|
1572
|
+
if e.status_code == 403 or "free tier limit" in str(e).lower():
|
|
1573
|
+
return [TextContent(
|
|
1574
|
+
type="text",
|
|
1575
|
+
text=f"❌ {str(e)}\n\n💡 Tip: Upgrade to Pro at https://trynia.ai/billing for unlimited access."
|
|
1576
|
+
)]
|
|
1577
|
+
else:
|
|
1578
|
+
return [TextContent(type="text", text=f"❌ {str(e)}")]
|
|
1579
|
+
except Exception as e:
|
|
1580
|
+
logger.error(f"Error reading source content: {e}")
|
|
1581
|
+
return [TextContent(
|
|
1582
|
+
type="text",
|
|
1583
|
+
text=f"❌ Error reading source content: {str(e)}"
|
|
1584
|
+
)]
|
|
1585
|
+
|
|
1391
1586
|
@mcp.tool()
|
|
1392
1587
|
async def visualize_codebase(
|
|
1393
1588
|
repository: str
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Setup utilities for NIA MCP Server configuration
|
|
3
|
+
"""
|
|
4
|
+
import os
|
|
5
|
+
import json
|
|
6
|
+
import platform
|
|
7
|
+
import shutil
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Dict, Optional, Any
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def find_mcp_config_path(ide: str = "cursor") -> Path:
|
|
13
|
+
"""
|
|
14
|
+
Find the MCP configuration file path based on OS and IDE.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
ide: IDE to configure (cursor, vscode, continue)
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
Path to the MCP configuration file
|
|
21
|
+
"""
|
|
22
|
+
system = platform.system()
|
|
23
|
+
home = Path.home()
|
|
24
|
+
|
|
25
|
+
if ide == "cursor":
|
|
26
|
+
if system == "Darwin": # macOS
|
|
27
|
+
return home / ".cursor" / "mcp.json"
|
|
28
|
+
elif system == "Windows":
|
|
29
|
+
appdata = os.environ.get("APPDATA", home / "AppData" / "Roaming")
|
|
30
|
+
return Path(appdata) / "Cursor" / "mcp.json"
|
|
31
|
+
else: # Linux and others
|
|
32
|
+
return home / ".config" / "cursor" / "mcp.json"
|
|
33
|
+
|
|
34
|
+
elif ide == "vscode":
|
|
35
|
+
# VS Code uses different config locations
|
|
36
|
+
if system == "Darwin":
|
|
37
|
+
return home / "Library" / "Application Support" / "Code" / "User" / "mcp.json"
|
|
38
|
+
elif system == "Windows":
|
|
39
|
+
appdata = os.environ.get("APPDATA", home / "AppData" / "Roaming")
|
|
40
|
+
return Path(appdata) / "Code" / "User" / "mcp.json"
|
|
41
|
+
else:
|
|
42
|
+
return home / ".config" / "Code" / "User" / "mcp.json"
|
|
43
|
+
|
|
44
|
+
elif ide == "continue":
|
|
45
|
+
# Continue.dev uses .continue directory
|
|
46
|
+
return home / ".continue" / "config.json"
|
|
47
|
+
|
|
48
|
+
else:
|
|
49
|
+
raise ValueError(f"Unsupported IDE: {ide}")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def backup_config(config_path: Path) -> Optional[Path]:
|
|
53
|
+
"""
|
|
54
|
+
Create a backup of existing configuration file.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
config_path: Path to the configuration file
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
Path to the backup file if created, None otherwise
|
|
61
|
+
"""
|
|
62
|
+
if config_path.exists():
|
|
63
|
+
backup_path = config_path.with_suffix(".json.backup")
|
|
64
|
+
# If backup already exists, add timestamp
|
|
65
|
+
if backup_path.exists():
|
|
66
|
+
import time
|
|
67
|
+
timestamp = int(time.time())
|
|
68
|
+
backup_path = config_path.with_suffix(f".json.backup.{timestamp}")
|
|
69
|
+
|
|
70
|
+
shutil.copy2(config_path, backup_path)
|
|
71
|
+
return backup_path
|
|
72
|
+
return None
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def create_nia_config(api_key: str) -> Dict[str, Any]:
|
|
76
|
+
"""
|
|
77
|
+
Create NIA MCP server configuration.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
api_key: NIA API key
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
Dictionary with NIA server configuration
|
|
84
|
+
"""
|
|
85
|
+
return {
|
|
86
|
+
"command": "pipx",
|
|
87
|
+
"args": ["run", "nia-mcp-server"],
|
|
88
|
+
"env": {
|
|
89
|
+
"NIA_API_KEY": api_key,
|
|
90
|
+
"NIA_API_URL": "https://apigcp.trynia.ai/"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def update_mcp_config(config_path: Path, api_key: str) -> bool:
|
|
96
|
+
"""
|
|
97
|
+
Update or create MCP configuration file with NIA server.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
config_path: Path to the MCP configuration file
|
|
101
|
+
api_key: NIA API key
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
True if successful, False otherwise
|
|
105
|
+
"""
|
|
106
|
+
try:
|
|
107
|
+
# Ensure directory exists
|
|
108
|
+
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
109
|
+
|
|
110
|
+
# Load existing config or create new one
|
|
111
|
+
if config_path.exists():
|
|
112
|
+
with open(config_path, 'r') as f:
|
|
113
|
+
config = json.load(f)
|
|
114
|
+
else:
|
|
115
|
+
config = {}
|
|
116
|
+
|
|
117
|
+
# Ensure mcpServers section exists
|
|
118
|
+
if "mcpServers" not in config:
|
|
119
|
+
config["mcpServers"] = {}
|
|
120
|
+
|
|
121
|
+
# Add or update NIA server configuration
|
|
122
|
+
config["mcpServers"]["nia"] = create_nia_config(api_key)
|
|
123
|
+
|
|
124
|
+
# Write updated configuration
|
|
125
|
+
with open(config_path, 'w') as f:
|
|
126
|
+
json.dump(config, f, indent=2)
|
|
127
|
+
|
|
128
|
+
return True
|
|
129
|
+
|
|
130
|
+
except Exception as e:
|
|
131
|
+
print(f"❌ Error updating configuration: {e}")
|
|
132
|
+
return False
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def setup_mcp_config(api_key: str, ide: str = "cursor") -> bool:
|
|
136
|
+
"""
|
|
137
|
+
Main setup function to configure NIA MCP Server.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
api_key: NIA API key
|
|
141
|
+
ide: IDE to configure
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
True if successful, False otherwise
|
|
145
|
+
"""
|
|
146
|
+
print(f"\n🚀 Setting up NIA MCP Server for {ide.title()}...\n")
|
|
147
|
+
|
|
148
|
+
# Find config path
|
|
149
|
+
config_path = find_mcp_config_path(ide)
|
|
150
|
+
print(f"📍 Configuration path: {config_path}")
|
|
151
|
+
|
|
152
|
+
# Backup existing config
|
|
153
|
+
backup_path = backup_config(config_path)
|
|
154
|
+
if backup_path:
|
|
155
|
+
print(f"📦 Backed up existing config to: {backup_path}")
|
|
156
|
+
|
|
157
|
+
# Update configuration
|
|
158
|
+
if update_mcp_config(config_path, api_key):
|
|
159
|
+
print(f"\n✅ NIA MCP Server setup complete!")
|
|
160
|
+
print(f"\n📝 Configuration written to: {config_path}")
|
|
161
|
+
print(f"🔑 API Key: {api_key[:10]}...")
|
|
162
|
+
|
|
163
|
+
print("\n📌 Next steps:")
|
|
164
|
+
print(f" 1. Restart {ide.title()} to load the NIA MCP server")
|
|
165
|
+
print(f" 2. Test with: \"Claude, list my repositories\"")
|
|
166
|
+
print(f" 3. Get started: \"Claude, index https://github.com/owner/repo\"")
|
|
167
|
+
|
|
168
|
+
print("\n💡 Learn more:")
|
|
169
|
+
print(" - Documentation: https://docs.trynia.ai")
|
|
170
|
+
print(" - Get help: https://discord.gg/BBSwUMrrfn")
|
|
171
|
+
|
|
172
|
+
return True
|
|
173
|
+
else:
|
|
174
|
+
print(f"\n❌ Setup failed. Please check the error messages above.")
|
|
175
|
+
if backup_path:
|
|
176
|
+
print(f" Your original config is safe at: {backup_path}")
|
|
177
|
+
return False
|
nia_mcp_server-1.0.11/PKG-INFO
DELETED
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: nia-mcp-server
|
|
3
|
-
Version: 1.0.11
|
|
4
|
-
Summary: Nia Knowledge Agent
|
|
5
|
-
Project-URL: Homepage, https://trynia.ai
|
|
6
|
-
Project-URL: Documentation, https://docs.trynia.ai
|
|
7
|
-
Author-email: Nia Team <founders@nozomio.com>
|
|
8
|
-
License-Expression: AGPL-3.0
|
|
9
|
-
License-File: LICENSE
|
|
10
|
-
Keywords: ai,codebase,mcp,nia,search
|
|
11
|
-
Classifier: Development Status :: 4 - Beta
|
|
12
|
-
Classifier: Intended Audience :: Developers
|
|
13
|
-
Classifier: License :: OSI Approved :: GNU Affero General Public License v3
|
|
14
|
-
Classifier: Programming Language :: Python :: 3
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
-
Requires-Python: >=3.8
|
|
21
|
-
Requires-Dist: httpx>=0.24.0
|
|
22
|
-
Requires-Dist: mcp>=0.1.0
|
|
23
|
-
Requires-Dist: pydantic>=2.0.0
|
|
24
|
-
Requires-Dist: python-dotenv>=1.0.0
|
|
25
|
-
Description-Content-Type: text/markdown
|
|
26
|
-
|
|
27
|
-
# NIA MCP Server
|
|
28
|
-
|
|
29
|
-
The NIA MCP Server enables AI assistants like Claude to search and understand your indexed codebases through the Model Context Protocol (MCP).
|
|
30
|
-
|
|
31
|
-
## Quick Start
|
|
32
|
-
|
|
33
|
-
### 1. Get your NIA API Key
|
|
34
|
-
|
|
35
|
-
Sign up and get your API key at [https://trynia.ai/api-keys](https://trynia.ai/api-keys)
|
|
36
|
-
|
|
37
|
-
### 2. Install via pip
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
pip install nia-mcp-server
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### 3. Configure with Claude Desktop
|
|
44
|
-
|
|
45
|
-
Add to your Claude Desktop configuration (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
|
|
46
|
-
|
|
47
|
-
```json
|
|
48
|
-
{
|
|
49
|
-
"mcpServers": {
|
|
50
|
-
"nia": {
|
|
51
|
-
"command": "nia-mcp-server",
|
|
52
|
-
"env": {
|
|
53
|
-
"NIA_API_KEY": "your-api-key-here"
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### 4. Restart Claude Desktop
|
|
61
|
-
|
|
62
|
-
That's it! You can now ask Claude to index and search codebases.
|
|
63
|
-
|
|
64
|
-
## Usage Examples
|
|
65
|
-
|
|
66
|
-
### Index a repository
|
|
67
|
-
```
|
|
68
|
-
Claude, please index https://github.com/facebook/react
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### Index documentation
|
|
72
|
-
```
|
|
73
|
-
Index the documentation at https://docs.python.org
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### Search across everything
|
|
77
|
-
```
|
|
78
|
-
How does async/await work? Search both my code and documentation.
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### Search only repositories
|
|
82
|
-
```
|
|
83
|
-
Find the authentication logic in my repositories
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
### Search only documentation
|
|
87
|
-
```
|
|
88
|
-
What are the best practices for error handling according to the docs?
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### Search and index new content
|
|
92
|
-
```
|
|
93
|
-
Find the best RAG implementations out there
|
|
94
|
-
```
|
|
95
|
-
Claude will:
|
|
96
|
-
1. Use the `nia_web_search` tool to find trending RAG repos
|
|
97
|
-
2. Show you the results with summaries
|
|
98
|
-
3. Prompt you to index the ones you want
|
|
99
|
-
4. You say "Index the first two" and it indexes them!
|
|
100
|
-
|
|
101
|
-
```
|
|
102
|
-
What are the hottest new Rust web frameworks this week?
|
|
103
|
-
```
|
|
104
|
-
Claude searches trending repos and guides you through indexing them.
|
|
105
|
-
|
|
106
|
-
Advanced search examples:
|
|
107
|
-
```
|
|
108
|
-
Find GitHub repos similar to langchain/langchain
|
|
109
|
-
|
|
110
|
-
Search for AI papers published in the last 30 days
|
|
111
|
-
|
|
112
|
-
What are the trending machine learning frameworks this month?
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
### Deep research questions
|
|
116
|
-
```
|
|
117
|
-
Compare the top 3 vector databases for RAG applications
|
|
118
|
-
|
|
119
|
-
What are the pros and cons of different LLM orchestration frameworks?
|
|
120
|
-
|
|
121
|
-
Research the latest developments in AI agent architectures
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### List your resources
|
|
125
|
-
```
|
|
126
|
-
Show me all my indexed repositories and documentation
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
## Available Tools
|
|
130
|
-
|
|
131
|
-
### Search & Research
|
|
132
|
-
- **`nia_web_search`** - AI-powered search of repositories, documentation, and content
|
|
133
|
-
- Finds trending GitHub repos, relevant documentation, and more
|
|
134
|
-
- Returns structured results that guide you to index the best content
|
|
135
|
-
- Advanced options:
|
|
136
|
-
- `category`: Filter by type (github, company, research paper, news, etc.)
|
|
137
|
-
- `days_back`: Find content from the last N days (great for trending)
|
|
138
|
-
- `find_similar_to`: Search for content similar to a given URL
|
|
139
|
-
- Built into NIA's advanced search capabilities
|
|
140
|
-
|
|
141
|
-
- **`nia_deep_research_agent`** - Multi-step AI research for complex questions
|
|
142
|
-
- Best for comparative analysis, comprehensive overviews
|
|
143
|
-
- Returns structured data with citations
|
|
144
|
-
- Examples: "Compare top RAG frameworks", "Analyze trends in AI safety"
|
|
145
|
-
|
|
146
|
-
### Repository Management
|
|
147
|
-
- **`index_repository`** - Index a GitHub repository
|
|
148
|
-
- **`list_repositories`** - List all indexed repositories
|
|
149
|
-
- **`check_repository_status`** - Check repository indexing progress
|
|
150
|
-
- **`delete_repository`** - Remove an indexed repository
|
|
151
|
-
|
|
152
|
-
### Documentation Management
|
|
153
|
-
- **`index_documentation`** - Index documentation or any website
|
|
154
|
-
- **`list_documentation`** - List all indexed documentation sources
|
|
155
|
-
- **`check_documentation_status`** - Check documentation indexing progress
|
|
156
|
-
- **`delete_documentation`** - Remove indexed documentation
|
|
157
|
-
|
|
158
|
-
### Unified Search
|
|
159
|
-
- **`search_codebase`** - Search across repositories and/or documentation
|
|
160
|
-
- `search_mode`: "repositories", "sources", or "unified" (default)
|
|
161
|
-
- Automatically searches all indexed content if not specified
|
|
162
|
-
|
|
163
|
-
## Other MCP Clients
|
|
164
|
-
|
|
165
|
-
### Continue.dev
|
|
166
|
-
|
|
167
|
-
Add to your `~/.continue/config.json`:
|
|
168
|
-
|
|
169
|
-
```json
|
|
170
|
-
{
|
|
171
|
-
"models": [...],
|
|
172
|
-
"mcpServers": [
|
|
173
|
-
{
|
|
174
|
-
"name": "nia",
|
|
175
|
-
"command": "nia-mcp-server",
|
|
176
|
-
"env": {
|
|
177
|
-
"NIA_API_KEY": "your-api-key-here"
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
]
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### VS Code Cline
|
|
185
|
-
|
|
186
|
-
Add to your Cline settings:
|
|
187
|
-
|
|
188
|
-
```json
|
|
189
|
-
{
|
|
190
|
-
"mcpServers": {
|
|
191
|
-
"nia": {
|
|
192
|
-
"command": "nia-mcp-server",
|
|
193
|
-
"env": {
|
|
194
|
-
"NIA_API_KEY": "your-api-key-here"
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
## Environment Variables
|
|
202
|
-
|
|
203
|
-
- `NIA_API_KEY` (required) - Your NIA API key
|
|
204
|
-
- `NIA_API_URL` (optional) - API endpoint (defaults to https://apigcp.trynia.ai)
|
|
205
|
-
|
|
206
|
-
## Pricing
|
|
207
|
-
|
|
208
|
-
NIA offers simple, transparent pricing:
|
|
209
|
-
|
|
210
|
-
- **Free Tier**: Limited usage, public repos only
|
|
211
|
-
- **Pro**: Unlimited API calls, private repos, advanced features
|
|
212
|
-
|
|
213
|
-
See [https://trynia.ai/pricing](https://trynia.ai/pricing) for details.
|
|
214
|
-
|
|
215
|
-
## Features
|
|
216
|
-
|
|
217
|
-
- 🔍 **Unified Search** - Search across code AND documentation seamlessly
|
|
218
|
-
- 📚 **Documentation Indexing** - Index any website or documentation
|
|
219
|
-
- 🚀 **Fast Indexing** - Index repositories and websites quickly
|
|
220
|
-
- 🔒 **Private Repos** - Support for private repositories (Pro)
|
|
221
|
-
- 📊 **Smart Understanding** - AI-powered code and content comprehension
|
|
222
|
-
- 🌐 **Works Everywhere** - Any MCP-compatible client
|
|
223
|
-
|
|
224
|
-
## Troubleshooting
|
|
225
|
-
|
|
226
|
-
### "No API key provided"
|
|
227
|
-
Make sure `NIA_API_KEY` is set in your MCP client configuration.
|
|
228
|
-
|
|
229
|
-
### "Invalid API key"
|
|
230
|
-
Check your API key at [https://trynia.ai/api-keys](https://trynia.ai/api-keys)
|
|
231
|
-
|
|
232
|
-
### "Rate limit exceeded"
|
|
233
|
-
You've hit your monthly limit. Upgrade at [https://trynia.ai/billing](https://trynia.ai/billing)
|
|
234
|
-
|
|
235
|
-
### Repository not indexing
|
|
236
|
-
Large repositories can take a few minutes. Use `check_repository_status` to monitor progress.
|
|
237
|
-
|
|
238
|
-
## Support
|
|
239
|
-
|
|
240
|
-
- Documentation: [https://docs.trynia.ai](https://docs.trynia.ai)
|
|
241
|
-
- Discord: [https://discord.gg/BBSwUMrrfn](https://discord.gg/BBSwUMrrfn)
|
|
242
|
-
- Email: support@trynia.ai
|
|
243
|
-
|
|
244
|
-
## License
|
|
245
|
-
|
|
246
|
-
MIT License - see LICENSE file for details.
|
nia_mcp_server-1.0.11/README.md
DELETED
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
# NIA MCP Server
|
|
2
|
-
|
|
3
|
-
The NIA MCP Server enables AI assistants like Claude to search and understand your indexed codebases through the Model Context Protocol (MCP).
|
|
4
|
-
|
|
5
|
-
## Quick Start
|
|
6
|
-
|
|
7
|
-
### 1. Get your NIA API Key
|
|
8
|
-
|
|
9
|
-
Sign up and get your API key at [https://trynia.ai/api-keys](https://trynia.ai/api-keys)
|
|
10
|
-
|
|
11
|
-
### 2. Install via pip
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
pip install nia-mcp-server
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
### 3. Configure with Claude Desktop
|
|
18
|
-
|
|
19
|
-
Add to your Claude Desktop configuration (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
|
|
20
|
-
|
|
21
|
-
```json
|
|
22
|
-
{
|
|
23
|
-
"mcpServers": {
|
|
24
|
-
"nia": {
|
|
25
|
-
"command": "nia-mcp-server",
|
|
26
|
-
"env": {
|
|
27
|
-
"NIA_API_KEY": "your-api-key-here"
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### 4. Restart Claude Desktop
|
|
35
|
-
|
|
36
|
-
That's it! You can now ask Claude to index and search codebases.
|
|
37
|
-
|
|
38
|
-
## Usage Examples
|
|
39
|
-
|
|
40
|
-
### Index a repository
|
|
41
|
-
```
|
|
42
|
-
Claude, please index https://github.com/facebook/react
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
### Index documentation
|
|
46
|
-
```
|
|
47
|
-
Index the documentation at https://docs.python.org
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### Search across everything
|
|
51
|
-
```
|
|
52
|
-
How does async/await work? Search both my code and documentation.
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### Search only repositories
|
|
56
|
-
```
|
|
57
|
-
Find the authentication logic in my repositories
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### Search only documentation
|
|
61
|
-
```
|
|
62
|
-
What are the best practices for error handling according to the docs?
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### Search and index new content
|
|
66
|
-
```
|
|
67
|
-
Find the best RAG implementations out there
|
|
68
|
-
```
|
|
69
|
-
Claude will:
|
|
70
|
-
1. Use the `nia_web_search` tool to find trending RAG repos
|
|
71
|
-
2. Show you the results with summaries
|
|
72
|
-
3. Prompt you to index the ones you want
|
|
73
|
-
4. You say "Index the first two" and it indexes them!
|
|
74
|
-
|
|
75
|
-
```
|
|
76
|
-
What are the hottest new Rust web frameworks this week?
|
|
77
|
-
```
|
|
78
|
-
Claude searches trending repos and guides you through indexing them.
|
|
79
|
-
|
|
80
|
-
Advanced search examples:
|
|
81
|
-
```
|
|
82
|
-
Find GitHub repos similar to langchain/langchain
|
|
83
|
-
|
|
84
|
-
Search for AI papers published in the last 30 days
|
|
85
|
-
|
|
86
|
-
What are the trending machine learning frameworks this month?
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### Deep research questions
|
|
90
|
-
```
|
|
91
|
-
Compare the top 3 vector databases for RAG applications
|
|
92
|
-
|
|
93
|
-
What are the pros and cons of different LLM orchestration frameworks?
|
|
94
|
-
|
|
95
|
-
Research the latest developments in AI agent architectures
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### List your resources
|
|
99
|
-
```
|
|
100
|
-
Show me all my indexed repositories and documentation
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
## Available Tools
|
|
104
|
-
|
|
105
|
-
### Search & Research
|
|
106
|
-
- **`nia_web_search`** - AI-powered search of repositories, documentation, and content
|
|
107
|
-
- Finds trending GitHub repos, relevant documentation, and more
|
|
108
|
-
- Returns structured results that guide you to index the best content
|
|
109
|
-
- Advanced options:
|
|
110
|
-
- `category`: Filter by type (github, company, research paper, news, etc.)
|
|
111
|
-
- `days_back`: Find content from the last N days (great for trending)
|
|
112
|
-
- `find_similar_to`: Search for content similar to a given URL
|
|
113
|
-
- Built into NIA's advanced search capabilities
|
|
114
|
-
|
|
115
|
-
- **`nia_deep_research_agent`** - Multi-step AI research for complex questions
|
|
116
|
-
- Best for comparative analysis, comprehensive overviews
|
|
117
|
-
- Returns structured data with citations
|
|
118
|
-
- Examples: "Compare top RAG frameworks", "Analyze trends in AI safety"
|
|
119
|
-
|
|
120
|
-
### Repository Management
|
|
121
|
-
- **`index_repository`** - Index a GitHub repository
|
|
122
|
-
- **`list_repositories`** - List all indexed repositories
|
|
123
|
-
- **`check_repository_status`** - Check repository indexing progress
|
|
124
|
-
- **`delete_repository`** - Remove an indexed repository
|
|
125
|
-
|
|
126
|
-
### Documentation Management
|
|
127
|
-
- **`index_documentation`** - Index documentation or any website
|
|
128
|
-
- **`list_documentation`** - List all indexed documentation sources
|
|
129
|
-
- **`check_documentation_status`** - Check documentation indexing progress
|
|
130
|
-
- **`delete_documentation`** - Remove indexed documentation
|
|
131
|
-
|
|
132
|
-
### Unified Search
|
|
133
|
-
- **`search_codebase`** - Search across repositories and/or documentation
|
|
134
|
-
- `search_mode`: "repositories", "sources", or "unified" (default)
|
|
135
|
-
- Automatically searches all indexed content if not specified
|
|
136
|
-
|
|
137
|
-
## Other MCP Clients
|
|
138
|
-
|
|
139
|
-
### Continue.dev
|
|
140
|
-
|
|
141
|
-
Add to your `~/.continue/config.json`:
|
|
142
|
-
|
|
143
|
-
```json
|
|
144
|
-
{
|
|
145
|
-
"models": [...],
|
|
146
|
-
"mcpServers": [
|
|
147
|
-
{
|
|
148
|
-
"name": "nia",
|
|
149
|
-
"command": "nia-mcp-server",
|
|
150
|
-
"env": {
|
|
151
|
-
"NIA_API_KEY": "your-api-key-here"
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
]
|
|
155
|
-
}
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### VS Code Cline
|
|
159
|
-
|
|
160
|
-
Add to your Cline settings:
|
|
161
|
-
|
|
162
|
-
```json
|
|
163
|
-
{
|
|
164
|
-
"mcpServers": {
|
|
165
|
-
"nia": {
|
|
166
|
-
"command": "nia-mcp-server",
|
|
167
|
-
"env": {
|
|
168
|
-
"NIA_API_KEY": "your-api-key-here"
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
## Environment Variables
|
|
176
|
-
|
|
177
|
-
- `NIA_API_KEY` (required) - Your NIA API key
|
|
178
|
-
- `NIA_API_URL` (optional) - API endpoint (defaults to https://apigcp.trynia.ai)
|
|
179
|
-
|
|
180
|
-
## Pricing
|
|
181
|
-
|
|
182
|
-
NIA offers simple, transparent pricing:
|
|
183
|
-
|
|
184
|
-
- **Free Tier**: Limited usage, public repos only
|
|
185
|
-
- **Pro**: Unlimited API calls, private repos, advanced features
|
|
186
|
-
|
|
187
|
-
See [https://trynia.ai/pricing](https://trynia.ai/pricing) for details.
|
|
188
|
-
|
|
189
|
-
## Features
|
|
190
|
-
|
|
191
|
-
- 🔍 **Unified Search** - Search across code AND documentation seamlessly
|
|
192
|
-
- 📚 **Documentation Indexing** - Index any website or documentation
|
|
193
|
-
- 🚀 **Fast Indexing** - Index repositories and websites quickly
|
|
194
|
-
- 🔒 **Private Repos** - Support for private repositories (Pro)
|
|
195
|
-
- 📊 **Smart Understanding** - AI-powered code and content comprehension
|
|
196
|
-
- 🌐 **Works Everywhere** - Any MCP-compatible client
|
|
197
|
-
|
|
198
|
-
## Troubleshooting
|
|
199
|
-
|
|
200
|
-
### "No API key provided"
|
|
201
|
-
Make sure `NIA_API_KEY` is set in your MCP client configuration.
|
|
202
|
-
|
|
203
|
-
### "Invalid API key"
|
|
204
|
-
Check your API key at [https://trynia.ai/api-keys](https://trynia.ai/api-keys)
|
|
205
|
-
|
|
206
|
-
### "Rate limit exceeded"
|
|
207
|
-
You've hit your monthly limit. Upgrade at [https://trynia.ai/billing](https://trynia.ai/billing)
|
|
208
|
-
|
|
209
|
-
### Repository not indexing
|
|
210
|
-
Large repositories can take a few minutes. Use `check_repository_status` to monitor progress.
|
|
211
|
-
|
|
212
|
-
## Support
|
|
213
|
-
|
|
214
|
-
- Documentation: [https://docs.trynia.ai](https://docs.trynia.ai)
|
|
215
|
-
- Discord: [https://discord.gg/BBSwUMrrfn](https://discord.gg/BBSwUMrrfn)
|
|
216
|
-
- Email: support@trynia.ai
|
|
217
|
-
|
|
218
|
-
## License
|
|
219
|
-
|
|
220
|
-
MIT License - see LICENSE file for details.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/src/nia_mcp_server/assets/rules/claude_rules.md
RENAMED
|
File without changes
|
{nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/src/nia_mcp_server/assets/rules/cursor_rules.md
RENAMED
|
File without changes
|
{nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/src/nia_mcp_server/assets/rules/nia_rules.md
RENAMED
|
File without changes
|
{nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/src/nia_mcp_server/assets/rules/vscode_rules.md
RENAMED
|
File without changes
|
{nia_mcp_server-1.0.11 → nia_mcp_server-1.0.13}/src/nia_mcp_server/assets/rules/windsurf_rules.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|