nia-mcp-server 1.0.25__py3-none-any.whl → 1.0.42__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.
- nia_mcp_server/__init__.py +1 -1
- nia_mcp_server/api_client.py +503 -99
- nia_mcp_server/cli.py +31 -4
- nia_mcp_server/profiles.py +20 -4
- nia_mcp_server/project_init.py +1 -1
- nia_mcp_server/rule_transformer.py +2 -2
- nia_mcp_server/server.py +2577 -2167
- nia_mcp_server/setup.py +593 -79
- {nia_mcp_server-1.0.25.dist-info → nia_mcp_server-1.0.42.dist-info}/METADATA +7 -4
- nia_mcp_server-1.0.42.dist-info/RECORD +19 -0
- {nia_mcp_server-1.0.25.dist-info → nia_mcp_server-1.0.42.dist-info}/WHEEL +1 -1
- nia_mcp_server-1.0.25.dist-info/RECORD +0 -19
- {nia_mcp_server-1.0.25.dist-info → nia_mcp_server-1.0.42.dist-info}/entry_points.txt +0 -0
- {nia_mcp_server-1.0.25.dist-info → nia_mcp_server-1.0.42.dist-info}/licenses/LICENSE +0 -0
nia_mcp_server/setup.py
CHANGED
|
@@ -5,49 +5,210 @@ import os
|
|
|
5
5
|
import json
|
|
6
6
|
import platform
|
|
7
7
|
import shutil
|
|
8
|
+
import subprocess
|
|
8
9
|
from pathlib import Path
|
|
9
|
-
from typing import Dict, Optional, Any
|
|
10
|
+
from typing import Dict, Optional, Any, List
|
|
10
11
|
|
|
12
|
+
# Remote MCP endpoint
|
|
13
|
+
REMOTE_MCP_URL = "https://apigcp.trynia.ai/mcp"
|
|
14
|
+
NIA_API_URL = "https://apigcp.trynia.ai/"
|
|
11
15
|
|
|
12
|
-
|
|
16
|
+
# All supported IDEs
|
|
17
|
+
SUPPORTED_IDES = [
|
|
18
|
+
"cursor", "claude-code", "claude-desktop", "vscode", "windsurf", "continue",
|
|
19
|
+
"cline", "codex", "antigravity", "trae", "amp", "zed", "augment", "roo-code",
|
|
20
|
+
"kilo-code", "gemini-cli", "opencode", "jetbrains", "kiro", "lm-studio",
|
|
21
|
+
"visual-studio", "crush", "bolt-ai", "rovo-dev", "zencoder", "qodo-gen",
|
|
22
|
+
"qwen-coder", "perplexity", "warp", "copilot-agent", "copilot-cli",
|
|
23
|
+
"amazon-q", "factory"
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
# IDEs that support remote mode
|
|
27
|
+
REMOTE_SUPPORTED_IDES = [
|
|
28
|
+
"cursor", "vscode", "windsurf", "cline", "antigravity", "trae", "continue",
|
|
29
|
+
"roo-code", "kilo-code", "gemini-cli", "opencode", "qodo-gen", "qwen-coder",
|
|
30
|
+
"visual-studio", "crush", "copilot-agent", "copilot-cli", "factory",
|
|
31
|
+
"rovo-dev", "claude-code", "amp"
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
# IDEs that require CLI-based setup
|
|
35
|
+
CLI_BASED_IDES = ["claude-code", "codex", "amp", "factory"]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def find_mcp_config_path(ide: str = "cursor") -> Optional[Path]:
|
|
13
39
|
"""
|
|
14
40
|
Find the MCP configuration file path based on OS and IDE.
|
|
15
|
-
|
|
41
|
+
|
|
16
42
|
Args:
|
|
17
|
-
ide: IDE to configure
|
|
18
|
-
|
|
43
|
+
ide: IDE to configure
|
|
44
|
+
|
|
19
45
|
Returns:
|
|
20
|
-
Path to the MCP configuration file
|
|
46
|
+
Path to the MCP configuration file, or None for CLI-based IDEs
|
|
21
47
|
"""
|
|
22
48
|
system = platform.system()
|
|
23
49
|
home = Path.home()
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
|
|
51
|
+
# CLI-based IDEs don't have a config file path
|
|
52
|
+
if ide in CLI_BASED_IDES:
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
config_paths = {
|
|
56
|
+
# Standard MCP config IDEs
|
|
57
|
+
"cursor": {
|
|
58
|
+
"Darwin": home / ".cursor" / "mcp.json",
|
|
59
|
+
"Windows": Path(os.environ.get("APPDATA", home / "AppData" / "Roaming")) / "Cursor" / "mcp.json",
|
|
60
|
+
"Linux": home / ".config" / "cursor" / "mcp.json",
|
|
61
|
+
},
|
|
62
|
+
"vscode": {
|
|
63
|
+
"Darwin": home / ".vscode" / "mcp.json",
|
|
64
|
+
"Windows": Path(os.environ.get("APPDATA", home / "AppData" / "Roaming")) / "Code" / "User" / "mcp.json",
|
|
65
|
+
"Linux": home / ".config" / "Code" / "User" / "mcp.json",
|
|
66
|
+
},
|
|
67
|
+
"windsurf": {
|
|
68
|
+
"Darwin": home / ".codeium" / "windsurf" / "mcp_config.json",
|
|
69
|
+
"Windows": Path(os.environ.get("APPDATA", home / "AppData" / "Roaming")) / "Windsurf" / "mcp_config.json",
|
|
70
|
+
"Linux": home / ".codeium" / "windsurf" / "mcp_config.json",
|
|
71
|
+
},
|
|
72
|
+
"continue": {
|
|
73
|
+
"Darwin": home / ".continue" / "config.json",
|
|
74
|
+
"Windows": home / ".continue" / "config.json",
|
|
75
|
+
"Linux": home / ".continue" / "config.json",
|
|
76
|
+
},
|
|
77
|
+
"cline": {
|
|
78
|
+
"Darwin": home / "Library" / "Application Support" / "Code" / "User" / "globalStorage" / "saoudrizwan.claude-dev" / "settings" / "cline_mcp_settings.json",
|
|
79
|
+
"Windows": Path(os.environ.get("APPDATA", home / "AppData" / "Roaming")) / "Code" / "User" / "globalStorage" / "saoudrizwan.claude-dev" / "settings" / "cline_mcp_settings.json",
|
|
80
|
+
"Linux": home / ".config" / "Code" / "User" / "globalStorage" / "saoudrizwan.claude-dev" / "settings" / "cline_mcp_settings.json",
|
|
81
|
+
},
|
|
82
|
+
"antigravity": {
|
|
83
|
+
"Darwin": home / ".gemini" / "antigravity" / "mcp_config.json",
|
|
84
|
+
"Windows": Path(os.environ.get("APPDATA", home / "AppData" / "Roaming")) / "Gemini" / "Antigravity" / "mcp_config.json",
|
|
85
|
+
"Linux": home / ".config" / "gemini" / "antigravity" / "mcp_config.json",
|
|
86
|
+
},
|
|
87
|
+
"trae": {
|
|
88
|
+
"Darwin": home / "Library" / "Application Support" / "Trae" / "User" / "mcp.json",
|
|
89
|
+
"Windows": Path(os.environ.get("APPDATA", home / "AppData" / "Roaming")) / "Trae" / "User" / "mcp.json",
|
|
90
|
+
"Linux": home / ".config" / "trae" / "mcp.json",
|
|
91
|
+
},
|
|
92
|
+
"gemini-cli": {
|
|
93
|
+
"Darwin": home / ".gemini" / "settings.json",
|
|
94
|
+
"Windows": home / ".gemini" / "settings.json",
|
|
95
|
+
"Linux": home / ".gemini" / "settings.json",
|
|
96
|
+
},
|
|
97
|
+
"qwen-coder": {
|
|
98
|
+
"Darwin": home / ".qwen" / "settings.json",
|
|
99
|
+
"Windows": home / ".qwen" / "settings.json",
|
|
100
|
+
"Linux": home / ".qwen" / "settings.json",
|
|
101
|
+
},
|
|
102
|
+
"claude-desktop": {
|
|
103
|
+
"Darwin": home / "Library" / "Application Support" / "Claude" / "claude_desktop_config.json",
|
|
104
|
+
"Windows": Path(os.environ.get("APPDATA", home / "AppData" / "Roaming")) / "Claude" / "claude_desktop_config.json",
|
|
105
|
+
"Linux": home / ".config" / "claude" / "claude_desktop_config.json",
|
|
106
|
+
},
|
|
107
|
+
"zed": {
|
|
108
|
+
"Darwin": home / ".config" / "zed" / "settings.json",
|
|
109
|
+
"Windows": home / ".config" / "zed" / "settings.json",
|
|
110
|
+
"Linux": home / ".config" / "zed" / "settings.json",
|
|
111
|
+
},
|
|
112
|
+
"roo-code": {
|
|
113
|
+
"Darwin": home / ".roo-code" / "mcp.json",
|
|
114
|
+
"Windows": home / ".roo-code" / "mcp.json",
|
|
115
|
+
"Linux": home / ".roo-code" / "mcp.json",
|
|
116
|
+
},
|
|
117
|
+
"kilo-code": {
|
|
118
|
+
"Darwin": home / ".kilocode" / "mcp.json",
|
|
119
|
+
"Windows": home / ".kilocode" / "mcp.json",
|
|
120
|
+
"Linux": home / ".kilocode" / "mcp.json",
|
|
121
|
+
},
|
|
122
|
+
"opencode": {
|
|
123
|
+
"Darwin": home / ".opencode" / "config.json",
|
|
124
|
+
"Windows": home / ".opencode" / "config.json",
|
|
125
|
+
"Linux": home / ".opencode" / "config.json",
|
|
126
|
+
},
|
|
127
|
+
"jetbrains": {
|
|
128
|
+
"Darwin": home / ".jetbrains" / "mcp.json",
|
|
129
|
+
"Windows": home / ".jetbrains" / "mcp.json",
|
|
130
|
+
"Linux": home / ".jetbrains" / "mcp.json",
|
|
131
|
+
},
|
|
132
|
+
"kiro": {
|
|
133
|
+
"Darwin": home / ".kiro" / "mcp.json",
|
|
134
|
+
"Windows": home / ".kiro" / "mcp.json",
|
|
135
|
+
"Linux": home / ".kiro" / "mcp.json",
|
|
136
|
+
},
|
|
137
|
+
"lm-studio": {
|
|
138
|
+
"Darwin": home / ".lmstudio" / "mcp.json",
|
|
139
|
+
"Windows": home / ".lmstudio" / "mcp.json",
|
|
140
|
+
"Linux": home / ".lmstudio" / "mcp.json",
|
|
141
|
+
},
|
|
142
|
+
"visual-studio": {
|
|
143
|
+
"Darwin": home / ".vs" / "mcp.json",
|
|
144
|
+
"Windows": home / ".vs" / "mcp.json",
|
|
145
|
+
"Linux": home / ".vs" / "mcp.json",
|
|
146
|
+
},
|
|
147
|
+
"crush": {
|
|
148
|
+
"Darwin": home / ".crush" / "config.json",
|
|
149
|
+
"Windows": home / ".crush" / "config.json",
|
|
150
|
+
"Linux": home / ".crush" / "config.json",
|
|
151
|
+
},
|
|
152
|
+
"bolt-ai": {
|
|
153
|
+
"Darwin": home / "Library" / "Application Support" / "BoltAI" / "mcp.json",
|
|
154
|
+
"Windows": Path(os.environ.get("APPDATA", home / "AppData" / "Roaming")) / "BoltAI" / "mcp.json",
|
|
155
|
+
"Linux": home / ".config" / "bolt-ai" / "mcp.json",
|
|
156
|
+
},
|
|
157
|
+
"augment": {
|
|
158
|
+
"Darwin": home / ".augment" / "settings.json",
|
|
159
|
+
"Windows": home / ".augment" / "settings.json",
|
|
160
|
+
"Linux": home / ".augment" / "settings.json",
|
|
161
|
+
},
|
|
162
|
+
"qodo-gen": {
|
|
163
|
+
"Darwin": home / ".qodo" / "mcp.json",
|
|
164
|
+
"Windows": home / ".qodo" / "mcp.json",
|
|
165
|
+
"Linux": home / ".qodo" / "mcp.json",
|
|
166
|
+
},
|
|
167
|
+
"perplexity": {
|
|
168
|
+
"Darwin": home / "Library" / "Application Support" / "Perplexity" / "mcp.json",
|
|
169
|
+
"Windows": Path(os.environ.get("APPDATA", home / "AppData" / "Roaming")) / "Perplexity" / "mcp.json",
|
|
170
|
+
"Linux": home / ".config" / "perplexity" / "mcp.json",
|
|
171
|
+
},
|
|
172
|
+
"warp": {
|
|
173
|
+
"Darwin": home / ".warp" / "mcp.json",
|
|
174
|
+
"Windows": home / ".warp" / "mcp.json",
|
|
175
|
+
"Linux": home / ".warp" / "mcp.json",
|
|
176
|
+
},
|
|
177
|
+
"copilot-cli": {
|
|
178
|
+
"Darwin": home / ".copilot" / "mcp-config.json",
|
|
179
|
+
"Windows": home / ".copilot" / "mcp-config.json",
|
|
180
|
+
"Linux": home / ".copilot" / "mcp-config.json",
|
|
181
|
+
},
|
|
182
|
+
"copilot-agent": {
|
|
183
|
+
# This is typically in the repo, not home
|
|
184
|
+
"Darwin": Path(".github") / "copilot-mcp.json",
|
|
185
|
+
"Windows": Path(".github") / "copilot-mcp.json",
|
|
186
|
+
"Linux": Path(".github") / "copilot-mcp.json",
|
|
187
|
+
},
|
|
188
|
+
"amazon-q": {
|
|
189
|
+
"Darwin": home / ".aws" / "amazonq" / "mcp.json",
|
|
190
|
+
"Windows": home / ".aws" / "amazonq" / "mcp.json",
|
|
191
|
+
"Linux": home / ".aws" / "amazonq" / "mcp.json",
|
|
192
|
+
},
|
|
193
|
+
"rovo-dev": {
|
|
194
|
+
"Darwin": home / ".rovo" / "mcp.json",
|
|
195
|
+
"Windows": home / ".rovo" / "mcp.json",
|
|
196
|
+
"Linux": home / ".rovo" / "mcp.json",
|
|
197
|
+
},
|
|
198
|
+
"zencoder": {
|
|
199
|
+
# Zencoder uses UI-based setup
|
|
200
|
+
"Darwin": None,
|
|
201
|
+
"Windows": None,
|
|
202
|
+
"Linux": None,
|
|
203
|
+
},
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if ide not in config_paths:
|
|
49
207
|
raise ValueError(f"Unsupported IDE: {ide}")
|
|
50
208
|
|
|
209
|
+
ide_paths = config_paths[ide]
|
|
210
|
+
return ide_paths.get(system, ide_paths.get("Linux"))
|
|
211
|
+
|
|
51
212
|
|
|
52
213
|
def backup_config(config_path: Path) -> Optional[Path]:
|
|
53
214
|
"""
|
|
@@ -59,7 +220,7 @@ def backup_config(config_path: Path) -> Optional[Path]:
|
|
|
59
220
|
Returns:
|
|
60
221
|
Path to the backup file if created, None otherwise
|
|
61
222
|
"""
|
|
62
|
-
if config_path.exists():
|
|
223
|
+
if config_path and config_path.exists():
|
|
63
224
|
backup_path = config_path.with_suffix(".json.backup")
|
|
64
225
|
# If backup already exists, add timestamp
|
|
65
226
|
if backup_path.exists():
|
|
@@ -72,106 +233,459 @@ def backup_config(config_path: Path) -> Optional[Path]:
|
|
|
72
233
|
return None
|
|
73
234
|
|
|
74
235
|
|
|
75
|
-
def
|
|
236
|
+
def create_local_nia_config(api_key: str, ide: str = "cursor") -> Dict[str, Any]:
|
|
76
237
|
"""
|
|
77
|
-
Create NIA MCP server configuration.
|
|
78
|
-
|
|
238
|
+
Create local NIA MCP server configuration.
|
|
239
|
+
|
|
79
240
|
Args:
|
|
80
241
|
api_key: NIA API key
|
|
81
|
-
|
|
242
|
+
ide: IDE to configure (affects config format)
|
|
243
|
+
|
|
82
244
|
Returns:
|
|
83
|
-
Dictionary with NIA server configuration
|
|
245
|
+
Dictionary with local NIA server configuration
|
|
84
246
|
"""
|
|
85
|
-
|
|
247
|
+
base_local = {
|
|
86
248
|
"command": "pipx",
|
|
87
|
-
"args": ["run", "nia-mcp-server"],
|
|
249
|
+
"args": ["run", "--no-cache", "nia-mcp-server"],
|
|
88
250
|
"env": {
|
|
89
251
|
"NIA_API_KEY": api_key,
|
|
90
|
-
"NIA_API_URL":
|
|
252
|
+
"NIA_API_URL": NIA_API_URL
|
|
91
253
|
}
|
|
92
254
|
}
|
|
93
255
|
|
|
256
|
+
# IDE-specific variations
|
|
257
|
+
if ide == "cline":
|
|
258
|
+
return {
|
|
259
|
+
**base_local,
|
|
260
|
+
"alwaysAllow": [
|
|
261
|
+
"index", "search", "manage_resource", "regex_search",
|
|
262
|
+
"get_github_file_tree", "nia_web_search", "nia_deep_research_agent",
|
|
263
|
+
"read_source_content", "doc_tree", "doc_ls", "doc_read", "doc_grep", "context"
|
|
264
|
+
],
|
|
265
|
+
"disabled": False
|
|
266
|
+
}
|
|
267
|
+
elif ide in ["vscode", "visual-studio"]:
|
|
268
|
+
return {
|
|
269
|
+
"type": "stdio",
|
|
270
|
+
**base_local
|
|
271
|
+
}
|
|
272
|
+
elif ide == "opencode":
|
|
273
|
+
return {
|
|
274
|
+
"type": "local",
|
|
275
|
+
"command": ["pipx", "run", "--no-cache", "nia-mcp-server"],
|
|
276
|
+
"env": {
|
|
277
|
+
"NIA_API_KEY": api_key,
|
|
278
|
+
"NIA_API_URL": NIA_API_URL
|
|
279
|
+
},
|
|
280
|
+
"enabled": True
|
|
281
|
+
}
|
|
282
|
+
elif ide == "crush":
|
|
283
|
+
return {
|
|
284
|
+
"type": "stdio",
|
|
285
|
+
**base_local
|
|
286
|
+
}
|
|
287
|
+
elif ide in ["copilot-agent", "copilot-cli"]:
|
|
288
|
+
return {
|
|
289
|
+
"type": "stdio" if ide == "copilot-agent" else "local",
|
|
290
|
+
**base_local,
|
|
291
|
+
"tools": ["index", "search", "manage_resource", "nia_web_search", "nia_deep_research_agent"]
|
|
292
|
+
}
|
|
293
|
+
elif ide == "zed":
|
|
294
|
+
return {
|
|
295
|
+
"source": "custom",
|
|
296
|
+
"command": "pipx",
|
|
297
|
+
"args": ["run", "--no-cache", "nia-mcp-server"],
|
|
298
|
+
"env": {
|
|
299
|
+
"NIA_API_KEY": api_key,
|
|
300
|
+
"NIA_API_URL": NIA_API_URL
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
elif ide == "warp":
|
|
304
|
+
return {
|
|
305
|
+
**base_local,
|
|
306
|
+
"working_directory": None,
|
|
307
|
+
"start_on_launch": True
|
|
308
|
+
}
|
|
309
|
+
elif ide == "kilo-code":
|
|
310
|
+
return {
|
|
311
|
+
**base_local,
|
|
312
|
+
"alwaysAllow": [],
|
|
313
|
+
"disabled": False
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return base_local
|
|
317
|
+
|
|
94
318
|
|
|
95
|
-
def
|
|
319
|
+
def create_remote_nia_config(api_key: str, ide: str = "cursor") -> Dict[str, Any]:
|
|
96
320
|
"""
|
|
97
|
-
|
|
321
|
+
Create remote NIA MCP server configuration (HTTP transport).
|
|
322
|
+
|
|
323
|
+
Args:
|
|
324
|
+
api_key: NIA API key
|
|
325
|
+
ide: IDE to configure (affects config format)
|
|
326
|
+
|
|
327
|
+
Returns:
|
|
328
|
+
Dictionary with remote NIA server configuration
|
|
329
|
+
"""
|
|
330
|
+
base_remote = {
|
|
331
|
+
"url": REMOTE_MCP_URL,
|
|
332
|
+
"headers": {
|
|
333
|
+
"Authorization": f"Bearer {api_key}"
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
# IDE-specific variations
|
|
338
|
+
if ide == "windsurf":
|
|
339
|
+
return {
|
|
340
|
+
"serverUrl": REMOTE_MCP_URL,
|
|
341
|
+
"headers": {
|
|
342
|
+
"Authorization": f"Bearer {api_key}"
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
elif ide in ["vscode", "visual-studio"]:
|
|
346
|
+
return {
|
|
347
|
+
"type": "http",
|
|
348
|
+
"url": REMOTE_MCP_URL,
|
|
349
|
+
"headers": {
|
|
350
|
+
"Authorization": f"Bearer {api_key}"
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
elif ide == "cline":
|
|
354
|
+
return {
|
|
355
|
+
"url": REMOTE_MCP_URL,
|
|
356
|
+
"type": "streamableHttp",
|
|
357
|
+
"headers": {
|
|
358
|
+
"Authorization": f"Bearer {api_key}"
|
|
359
|
+
},
|
|
360
|
+
"alwaysAllow": [
|
|
361
|
+
"index", "search", "manage_resource", "regex_search",
|
|
362
|
+
"get_github_file_tree", "nia_web_search", "nia_deep_research_agent",
|
|
363
|
+
"read_source_content", "doc_tree", "doc_ls", "doc_read", "doc_grep", "context"
|
|
364
|
+
],
|
|
365
|
+
"disabled": False
|
|
366
|
+
}
|
|
367
|
+
elif ide == "roo-code":
|
|
368
|
+
return {
|
|
369
|
+
"type": "streamable-http",
|
|
370
|
+
"url": REMOTE_MCP_URL,
|
|
371
|
+
"headers": {
|
|
372
|
+
"Authorization": f"Bearer {api_key}"
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
elif ide == "kilo-code":
|
|
376
|
+
return {
|
|
377
|
+
"type": "streamable-http",
|
|
378
|
+
"url": REMOTE_MCP_URL,
|
|
379
|
+
"headers": {
|
|
380
|
+
"Authorization": f"Bearer {api_key}"
|
|
381
|
+
},
|
|
382
|
+
"alwaysAllow": [],
|
|
383
|
+
"disabled": False
|
|
384
|
+
}
|
|
385
|
+
elif ide in ["gemini-cli", "qwen-coder"]:
|
|
386
|
+
return {
|
|
387
|
+
"httpUrl": REMOTE_MCP_URL,
|
|
388
|
+
"headers": {
|
|
389
|
+
"Authorization": f"Bearer {api_key}",
|
|
390
|
+
"Accept": "application/json, text/event-stream"
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
elif ide == "opencode":
|
|
394
|
+
return {
|
|
395
|
+
"type": "remote",
|
|
396
|
+
"url": REMOTE_MCP_URL,
|
|
397
|
+
"headers": {
|
|
398
|
+
"Authorization": f"Bearer {api_key}"
|
|
399
|
+
},
|
|
400
|
+
"enabled": True
|
|
401
|
+
}
|
|
402
|
+
elif ide == "crush":
|
|
403
|
+
return {
|
|
404
|
+
"type": "http",
|
|
405
|
+
"url": REMOTE_MCP_URL,
|
|
406
|
+
"headers": {
|
|
407
|
+
"Authorization": f"Bearer {api_key}"
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
elif ide in ["copilot-agent", "copilot-cli"]:
|
|
411
|
+
return {
|
|
412
|
+
"type": "http",
|
|
413
|
+
"url": REMOTE_MCP_URL,
|
|
414
|
+
"headers": {
|
|
415
|
+
"Authorization": f"Bearer {api_key}"
|
|
416
|
+
},
|
|
417
|
+
"tools": ["index", "search", "manage_resource", "nia_web_search", "nia_deep_research_agent"]
|
|
418
|
+
}
|
|
98
419
|
|
|
420
|
+
# Default for cursor, antigravity, trae, qodo-gen, etc.
|
|
421
|
+
return base_remote
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
def create_nia_config(api_key: str, ide: str = "cursor", remote: bool = False) -> Dict[str, Any]:
|
|
425
|
+
"""
|
|
426
|
+
Create NIA MCP server configuration.
|
|
427
|
+
|
|
428
|
+
Args:
|
|
429
|
+
api_key: NIA API key
|
|
430
|
+
ide: IDE to configure (affects config format)
|
|
431
|
+
remote: If True, create remote HTTP config instead of local
|
|
432
|
+
|
|
433
|
+
Returns:
|
|
434
|
+
Dictionary with NIA server configuration
|
|
435
|
+
"""
|
|
436
|
+
if remote:
|
|
437
|
+
return create_remote_nia_config(api_key, ide)
|
|
438
|
+
return create_local_nia_config(api_key, ide)
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
def update_mcp_config(config_path: Path, api_key: str, ide: str = "cursor", remote: bool = False) -> bool:
|
|
442
|
+
"""
|
|
443
|
+
Update or create MCP configuration file with NIA server.
|
|
444
|
+
|
|
99
445
|
Args:
|
|
100
446
|
config_path: Path to the MCP configuration file
|
|
101
447
|
api_key: NIA API key
|
|
102
|
-
|
|
448
|
+
ide: IDE to configure
|
|
449
|
+
remote: If True, use remote HTTP config
|
|
450
|
+
|
|
103
451
|
Returns:
|
|
104
452
|
True if successful, False otherwise
|
|
105
453
|
"""
|
|
106
454
|
try:
|
|
107
455
|
# Ensure directory exists
|
|
108
456
|
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
109
|
-
|
|
457
|
+
|
|
110
458
|
# Load existing config or create new one
|
|
111
459
|
if config_path.exists():
|
|
112
|
-
|
|
113
|
-
|
|
460
|
+
try:
|
|
461
|
+
with open(config_path, 'r') as f:
|
|
462
|
+
content = f.read().strip()
|
|
463
|
+
config = json.loads(content) if content else {}
|
|
464
|
+
except (json.JSONDecodeError, ValueError):
|
|
465
|
+
config = {}
|
|
114
466
|
else:
|
|
115
467
|
config = {}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
468
|
+
|
|
469
|
+
nia_config = create_nia_config(api_key, ide, remote)
|
|
470
|
+
|
|
471
|
+
# Handle different config structures based on IDE
|
|
472
|
+
if ide == "continue":
|
|
473
|
+
if "experimental" not in config:
|
|
474
|
+
config["experimental"] = {}
|
|
475
|
+
if "modelContextProtocolServer" not in config["experimental"]:
|
|
476
|
+
config["experimental"]["modelContextProtocolServer"] = {}
|
|
477
|
+
|
|
478
|
+
if remote:
|
|
479
|
+
config["experimental"]["modelContextProtocolServer"]["transport"] = {
|
|
480
|
+
"type": "http",
|
|
481
|
+
"url": REMOTE_MCP_URL,
|
|
482
|
+
"headers": {
|
|
483
|
+
"Authorization": f"Bearer {api_key}"
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
else:
|
|
487
|
+
config["experimental"]["modelContextProtocolServer"]["transport"] = {
|
|
488
|
+
"type": "stdio",
|
|
489
|
+
"command": "pipx",
|
|
490
|
+
"args": ["run", "--no-cache", "nia-mcp-server"],
|
|
491
|
+
"env": {
|
|
492
|
+
"NIA_API_KEY": api_key,
|
|
493
|
+
"NIA_API_URL": NIA_API_URL
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
elif ide in ["vscode", "visual-studio"]:
|
|
497
|
+
if "servers" not in config:
|
|
498
|
+
config["servers"] = {}
|
|
499
|
+
config["servers"]["nia"] = nia_config
|
|
500
|
+
elif ide == "zed":
|
|
501
|
+
if "context_servers" not in config:
|
|
502
|
+
config["context_servers"] = {}
|
|
503
|
+
config["context_servers"]["Nia"] = nia_config
|
|
504
|
+
elif ide == "augment":
|
|
505
|
+
if "augment.advanced" not in config:
|
|
506
|
+
config["augment.advanced"] = {}
|
|
507
|
+
if "mcpServers" not in config["augment.advanced"]:
|
|
508
|
+
config["augment.advanced"]["mcpServers"] = []
|
|
509
|
+
# Remove existing nia config if present
|
|
510
|
+
config["augment.advanced"]["mcpServers"] = [
|
|
511
|
+
s for s in config["augment.advanced"]["mcpServers"]
|
|
512
|
+
if s.get("name") != "nia"
|
|
513
|
+
]
|
|
514
|
+
config["augment.advanced"]["mcpServers"].append({
|
|
515
|
+
"name": "nia",
|
|
516
|
+
**nia_config
|
|
517
|
+
})
|
|
518
|
+
elif ide == "opencode":
|
|
519
|
+
if "mcp" not in config:
|
|
520
|
+
config["mcp"] = {}
|
|
521
|
+
config["mcp"]["nia"] = nia_config
|
|
522
|
+
elif ide == "crush":
|
|
523
|
+
if "$schema" not in config:
|
|
524
|
+
config["$schema"] = "https://charm.land/crush.json"
|
|
525
|
+
if "mcp" not in config:
|
|
526
|
+
config["mcp"] = {}
|
|
527
|
+
config["mcp"]["nia"] = nia_config
|
|
528
|
+
else:
|
|
529
|
+
# Standard mcpServers structure for cursor, windsurf, cline, etc.
|
|
530
|
+
if "mcpServers" not in config:
|
|
531
|
+
config["mcpServers"] = {}
|
|
532
|
+
config["mcpServers"]["nia"] = nia_config
|
|
533
|
+
|
|
124
534
|
# Write updated configuration
|
|
125
535
|
with open(config_path, 'w') as f:
|
|
126
536
|
json.dump(config, f, indent=2)
|
|
127
|
-
|
|
537
|
+
|
|
128
538
|
return True
|
|
129
|
-
|
|
539
|
+
|
|
130
540
|
except Exception as e:
|
|
131
541
|
print(f"❌ Error updating configuration: {e}")
|
|
132
542
|
return False
|
|
133
543
|
|
|
134
544
|
|
|
135
|
-
def
|
|
545
|
+
def setup_command_based_ide(api_key: str, ide: str, remote: bool = False) -> bool:
|
|
546
|
+
"""
|
|
547
|
+
Setup NIA MCP Server for command-based IDEs (claude-code, codex, amp, factory).
|
|
548
|
+
|
|
549
|
+
Args:
|
|
550
|
+
api_key: NIA API key
|
|
551
|
+
ide: IDE to configure
|
|
552
|
+
remote: If True, use remote config
|
|
553
|
+
|
|
554
|
+
Returns:
|
|
555
|
+
True if successful, False otherwise
|
|
556
|
+
"""
|
|
557
|
+
if ide == "claude-code":
|
|
558
|
+
if remote:
|
|
559
|
+
cmd = [
|
|
560
|
+
"claude", "mcp", "add", "--transport", "http", "nia",
|
|
561
|
+
REMOTE_MCP_URL,
|
|
562
|
+
"--header", f"Authorization: Bearer {api_key}"
|
|
563
|
+
]
|
|
564
|
+
else:
|
|
565
|
+
cmd = [
|
|
566
|
+
"claude", "mcp", "add", "nia", "--scope", "user",
|
|
567
|
+
"-e", f"NIA_API_KEY={api_key}",
|
|
568
|
+
"-e", f"NIA_API_URL={NIA_API_URL}",
|
|
569
|
+
"--", "pipx", "run", "--no-cache", "nia-mcp-server"
|
|
570
|
+
]
|
|
571
|
+
ide_name = "Claude Code"
|
|
572
|
+
elif ide == "codex":
|
|
573
|
+
if remote:
|
|
574
|
+
print("❌ Codex does not support remote MCP. Please use local mode.")
|
|
575
|
+
return False
|
|
576
|
+
cmd = [
|
|
577
|
+
"codex", "mcp", "add", "nia",
|
|
578
|
+
"--env", f"NIA_API_KEY={api_key}",
|
|
579
|
+
"--env", f"NIA_API_URL={NIA_API_URL}",
|
|
580
|
+
"--", "pipx", "run", "--no-cache", "nia-mcp-server"
|
|
581
|
+
]
|
|
582
|
+
ide_name = "Codex"
|
|
583
|
+
elif ide == "amp":
|
|
584
|
+
if remote:
|
|
585
|
+
cmd = [
|
|
586
|
+
"amp", "mcp", "add", "nia",
|
|
587
|
+
"--header", f"Authorization=Bearer {api_key}",
|
|
588
|
+
REMOTE_MCP_URL
|
|
589
|
+
]
|
|
590
|
+
else:
|
|
591
|
+
print("❌ Amp only supports remote MCP. Please use --remote flag.")
|
|
592
|
+
return False
|
|
593
|
+
ide_name = "Amp"
|
|
594
|
+
elif ide == "factory":
|
|
595
|
+
if remote:
|
|
596
|
+
cmd = [
|
|
597
|
+
"droid", "mcp", "add", "nia",
|
|
598
|
+
REMOTE_MCP_URL,
|
|
599
|
+
"--type", "http",
|
|
600
|
+
"--header", f"Authorization: Bearer {api_key}"
|
|
601
|
+
]
|
|
602
|
+
else:
|
|
603
|
+
cmd = [
|
|
604
|
+
"droid", "mcp", "add", "nia",
|
|
605
|
+
"pipx run --no-cache nia-mcp-server",
|
|
606
|
+
"--env", f"NIA_API_KEY={api_key}",
|
|
607
|
+
"--env", f"NIA_API_URL={NIA_API_URL}"
|
|
608
|
+
]
|
|
609
|
+
ide_name = "Factory"
|
|
610
|
+
else:
|
|
611
|
+
print(f"❌ Unsupported command-based IDE: {ide}")
|
|
612
|
+
return False
|
|
613
|
+
|
|
614
|
+
try:
|
|
615
|
+
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
|
|
616
|
+
print(f"\n✅ Setup complete!")
|
|
617
|
+
return True
|
|
618
|
+
|
|
619
|
+
except subprocess.CalledProcessError as e:
|
|
620
|
+
print(f"\n❌ Setup failed with error: {e}")
|
|
621
|
+
if e.stderr:
|
|
622
|
+
print(f"Error details: {e.stderr}")
|
|
623
|
+
return False
|
|
624
|
+
except FileNotFoundError:
|
|
625
|
+
print(f"\n❌ {ide_name} CLI not found. Please ensure {ide_name} is installed and in your PATH.")
|
|
626
|
+
return False
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
def setup_mcp_config(api_key: str, ide: str = "cursor", remote: bool = False) -> bool:
|
|
136
630
|
"""
|
|
137
631
|
Main setup function to configure NIA MCP Server.
|
|
138
|
-
|
|
632
|
+
|
|
139
633
|
Args:
|
|
140
634
|
api_key: NIA API key
|
|
141
635
|
ide: IDE to configure
|
|
142
|
-
|
|
636
|
+
remote: If True, use remote HTTP config (no local installation needed)
|
|
637
|
+
|
|
143
638
|
Returns:
|
|
144
639
|
True if successful, False otherwise
|
|
145
640
|
"""
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
641
|
+
# Check remote support
|
|
642
|
+
if remote and ide not in REMOTE_SUPPORTED_IDES:
|
|
643
|
+
print(f"⚠️ {ide} does not support remote MCP mode.")
|
|
644
|
+
print(f" Falling back to local installation...")
|
|
645
|
+
remote = False
|
|
646
|
+
|
|
647
|
+
# Handle command-based IDEs differently
|
|
648
|
+
if ide in CLI_BASED_IDES:
|
|
649
|
+
return setup_command_based_ide(api_key, ide, remote)
|
|
650
|
+
|
|
651
|
+
# Handle IDEs that require manual UI setup
|
|
652
|
+
if ide == "zencoder":
|
|
653
|
+
print(f"\n📋 Zencoder requires manual setup via UI:")
|
|
654
|
+
print(" 1. Go to: Zencoder menu (…) → Agent tools → Add custom MCP")
|
|
655
|
+
print(" 2. Add this configuration:")
|
|
656
|
+
print(json.dumps({
|
|
657
|
+
"command": "pipx",
|
|
658
|
+
"args": ["run", "--no-cache", "nia-mcp-server"],
|
|
659
|
+
"env": {
|
|
660
|
+
"NIA_API_KEY": api_key,
|
|
661
|
+
"NIA_API_URL": NIA_API_URL
|
|
662
|
+
}
|
|
663
|
+
}, indent=2))
|
|
664
|
+
return True
|
|
665
|
+
|
|
666
|
+
# For file-based configuration IDEs
|
|
149
667
|
config_path = find_mcp_config_path(ide)
|
|
150
|
-
print(f"📍 Configuration path: {config_path}")
|
|
151
668
|
|
|
669
|
+
if config_path is None:
|
|
670
|
+
print(f"❌ Could not determine config path for {ide}")
|
|
671
|
+
return False
|
|
672
|
+
|
|
152
673
|
# Backup existing config
|
|
153
674
|
backup_path = backup_config(config_path)
|
|
154
675
|
if backup_path:
|
|
155
676
|
print(f"📦 Backed up existing config to: {backup_path}")
|
|
156
|
-
|
|
677
|
+
|
|
157
678
|
# Update configuration
|
|
158
|
-
if update_mcp_config(config_path, api_key):
|
|
159
|
-
|
|
160
|
-
print(f"\n
|
|
161
|
-
print(f"
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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
|
-
|
|
679
|
+
if update_mcp_config(config_path, api_key, ide, remote):
|
|
680
|
+
mode_str = "Remote MCP" if remote else "Local MCP"
|
|
681
|
+
print(f"\n✅ {mode_str} setup complete!")
|
|
682
|
+
print(f"📝 Configuration written to: {config_path}")
|
|
683
|
+
if remote:
|
|
684
|
+
print(f"🌐 Connected to: {REMOTE_MCP_URL}")
|
|
685
|
+
print(f"\n💡 No local installation required - your IDE connects directly to NIA's servers.")
|
|
172
686
|
return True
|
|
173
687
|
else:
|
|
174
688
|
print(f"\n❌ Setup failed. Please check the error messages above.")
|
|
175
689
|
if backup_path:
|
|
176
690
|
print(f" Your original config is safe at: {backup_path}")
|
|
177
|
-
return False
|
|
691
|
+
return False
|