@theone1345/smartrelay 0.2.0
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.
- package/README.md +446 -0
- package/config/runners/agents.yaml +47 -0
- package/config/runners/anthropic.yaml +23 -0
- package/config/runners/nvidia.yaml +53 -0
- package/config/runners/ollama.yaml +33 -0
- package/config/runners/openai.yaml +23 -0
- package/config/runners/openrouter.yaml +83 -0
- package/config.yaml +16 -0
- package/dist/benchmark/engine.d.ts +49 -0
- package/dist/benchmark/engine.js +147 -0
- package/dist/benchmark/engine.js.map +1 -0
- package/dist/benchmark/scorers.d.ts +59 -0
- package/dist/benchmark/scorers.js +241 -0
- package/dist/benchmark/scorers.js.map +1 -0
- package/dist/http-api.d.ts +23 -0
- package/dist/http-api.js +329 -0
- package/dist/http-api.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +22 -0
- package/dist/logger.js +34 -0
- package/dist/logger.js.map +1 -0
- package/dist/router.d.ts +33 -0
- package/dist/router.js +298 -0
- package/dist/router.js.map +1 -0
- package/dist/runners/anthropic.d.ts +15 -0
- package/dist/runners/anthropic.js +116 -0
- package/dist/runners/anthropic.js.map +1 -0
- package/dist/runners/base.d.ts +90 -0
- package/dist/runners/base.js +61 -0
- package/dist/runners/base.js.map +1 -0
- package/dist/runners/nvidia.d.ts +14 -0
- package/dist/runners/nvidia.js +23 -0
- package/dist/runners/nvidia.js.map +1 -0
- package/dist/runners/ollama.d.ts +8 -0
- package/dist/runners/ollama.js +107 -0
- package/dist/runners/ollama.js.map +1 -0
- package/dist/runners/openai.d.ts +28 -0
- package/dist/runners/openai.js +131 -0
- package/dist/runners/openai.js.map +1 -0
- package/dist/runners/openrouter.d.ts +11 -0
- package/dist/runners/openrouter.js +19 -0
- package/dist/runners/openrouter.js.map +1 -0
- package/dist/runners/registry.d.ts +53 -0
- package/dist/runners/registry.js +273 -0
- package/dist/runners/registry.js.map +1 -0
- package/dist/server.d.ts +16 -0
- package/dist/server.js +305 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/handlers.d.ts +49 -0
- package/dist/tools/handlers.js +331 -0
- package/dist/tools/handlers.js.map +1 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/util.d.ts +47 -0
- package/dist/util.js +140 -0
- package/dist/util.js.map +1 -0
- package/package.json +70 -0
- package/prompts/code_review.md +99 -0
- package/prompts/explain_code.md +79 -0
- package/prompts/planner.md +23 -0
- package/prompts/test_generator.md +2 -0
package/README.md
ADDED
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
# ⚡ SmartRelay
|
|
2
|
+
|
|
3
|
+
> **The intelligent delegation layer & zero-token task server for AI agents.**
|
|
4
|
+
|
|
5
|
+
[](https://modelcontextprotocol.io)
|
|
6
|
+
[](https://www.typescriptlang.org)
|
|
7
|
+
[](#-testing--verification)
|
|
8
|
+
[](#-supported-backends--models)
|
|
9
|
+
|
|
10
|
+
**SmartRelay** is a high-performance [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server built with TypeScript. It transforms **Claude Code**, **Cursor**, **Windsurf**, and other MCP-compatible AI editors into a **Master Orchestrator** — delegating heavy tasks (code reviews, test generation, explanations, architecture planning) to specialized sub-agents (NVIDIA NIM, Claude Sonnet, GPT-4o, local Ollama) with **zero context-window bloat** and concurrent multi-model benchmarking.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 📋 Prerequisites
|
|
15
|
+
|
|
16
|
+
Before installing, ensure you have:
|
|
17
|
+
- **Node.js**: `v20.11.0` or higher (`node -v`)
|
|
18
|
+
- **Git**
|
|
19
|
+
- *(Optional)* **[Ollama](https://ollama.ai)**: If using local offline models (`ollama serve && ollama pull qwen2.5-coder`)
|
|
20
|
+
- API keys for at least one provider (Anthropic, OpenAI, OpenRouter, or NVIDIA NIM)
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 🚀 Quick Install
|
|
25
|
+
|
|
26
|
+
### Option A — `npx` *(Easiest — zero install, runs everywhere)*
|
|
27
|
+
|
|
28
|
+
Add directly to your Claude Desktop / Cursor / Windsurf configuration:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"mcpServers": {
|
|
33
|
+
"smartrelay": {
|
|
34
|
+
"command": "npx",
|
|
35
|
+
"args": ["-y", "@theone1345/smartrelay"],
|
|
36
|
+
"env": {
|
|
37
|
+
"OPENROUTER_API_KEY": "sk-or-v1-...",
|
|
38
|
+
"NVIDIA_API_KEY": "nvapi-..."
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Or in **Claude Code CLI** (one single command from anywhere):
|
|
46
|
+
```bash
|
|
47
|
+
claude mcp add -s user smartrelay -- npx -y @theone1345/smartrelay
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
### Option B — Clone & Link (`npm link`) *(For developers customizing code)*
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
git clone https://github.com/DhavanBhalodiya/smart-relay.git
|
|
56
|
+
cd smart-relay
|
|
57
|
+
npm install
|
|
58
|
+
npm run build
|
|
59
|
+
npm link
|
|
60
|
+
cp .env.example .env # fill in your API keys
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Now connect it via the global `smartrelay` command:
|
|
64
|
+
```bash
|
|
65
|
+
claude mcp add -s user smartrelay -- smartrelay
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
### Option C — Direct Path Execution
|
|
71
|
+
|
|
72
|
+
If you prefer not linking globally, simply point your AI client to the compiled `dist/server.js`:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
git clone https://github.com/DhavanBhalodiya/smart-relay.git
|
|
76
|
+
cd smart-relay
|
|
77
|
+
npm install
|
|
78
|
+
npm run build
|
|
79
|
+
cp .env.example .env # fill in your API keys
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Then point your editor to `node /ABSOLUTE/PATH/TO/smart-relay/dist/server.js` — see [Connect to Your AI Client](#4-connect-to-your-ai-client) below.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
### Method 3 — Browser Test Drive (MCP Inspector)
|
|
87
|
+
|
|
88
|
+
Test all 13 tools interactively in your browser with zero editor configuration:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
cd smart-relay
|
|
92
|
+
npm run build
|
|
93
|
+
npx -y @modelcontextprotocol/inspector node dist/server.js
|
|
94
|
+
```
|
|
95
|
+
Opens an interactive UI at **http://localhost:6274** where you can execute and inspect tools live.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## ⚡ Natural Language Model Switching
|
|
100
|
+
|
|
101
|
+
Switch models on the fly during your session — just type plain English:
|
|
102
|
+
|
|
103
|
+
| What to say | Target Model & Provider | Purpose |
|
|
104
|
+
| :--- | :--- | :--- |
|
|
105
|
+
| **`Switch to openrouter`** | **Claude 3.7 Sonnet** via OpenRouter | Flagship cloud reasoning & architecture |
|
|
106
|
+
| **`Switch to deepseek`** / **`Switch to r1`** | **DeepSeek-R1 671B** via OpenRouter / NIM | Deep reasoning with chain-of-thought (CoT) |
|
|
107
|
+
| **`Switch to v3`** | **DeepSeek-V3 671B** via OpenRouter | High-speed code generation ($0.14/M) |
|
|
108
|
+
| **`Switch to qwen`** | **Qwen 2.5 Coder 32B** | Specialized code intelligence |
|
|
109
|
+
| **`Switch to llama`** | **Llama 3.3 70B** | Meta flagship for planning & system design |
|
|
110
|
+
| **`Switch to gemini`** | **Gemini 2.0 Flash** via OpenRouter | Ultra-fast with 1M token context window |
|
|
111
|
+
| **`Switch to nvidia`** | **NVIDIA NIM** (Nemotron 3 Super 120B) | Heavyweight cloud code & test agent |
|
|
112
|
+
| **`Switch to claude`** | **Claude Sonnet 4.5 / 3.7** | Elite code reviews & refactoring |
|
|
113
|
+
| **`Switch to ollama`** / **`Switch to local`** | Local **Qwen 2.5 Coder** | $0.00 completely free & offline |
|
|
114
|
+
| **`Switch to auto`** | Smart intent routing (default) | Automatically picks the best agent for the task |
|
|
115
|
+
| **`Switch to direct`** | Claude Code native intelligence | Answers directly without sub-agents |
|
|
116
|
+
| **`What model is active?`** | Calls `get_active_model` | Shows current runner and routing mode |
|
|
117
|
+
| **`What models can I switch to?`** | Calls `switch_model(model='list')` | Displays full interactive model fleet menu |
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## 🛠️ 13 MCP Tools
|
|
122
|
+
|
|
123
|
+
| Tool | What It Does |
|
|
124
|
+
| :--- | :--- |
|
|
125
|
+
| **`review_file`** ⭐ | Zero-token: server reads the file itself → returns 🛡️ Code Review Report |
|
|
126
|
+
| **`test_file`** ⭐ | Zero-token: server reads the file itself → generates production-ready tests |
|
|
127
|
+
| **`explain_file`** ⭐ | Zero-token: server reads the file itself → returns 📖 plain-English explanation |
|
|
128
|
+
| **`review_code`** | Code review on code passed directly in the prompt |
|
|
129
|
+
| **`generate_tests`** | Unit & integration tests for code passed directly |
|
|
130
|
+
| **`explain_code`** | Plain-English explanation for any code snippet (any language, any audience) |
|
|
131
|
+
| **`create_plan`** | Generates a phased architectural implementation plan |
|
|
132
|
+
| **`ask_subagent`** | Offloads any question or coding task to a specific sub-agent model |
|
|
133
|
+
| **`delegate_task`** | Delegates to a specific runner or uses auto-routing |
|
|
134
|
+
| **`benchmark_run`** | Runs a task across multiple models concurrently and compares results |
|
|
135
|
+
| **`switch_model`** | Programmatically switch the active runner |
|
|
136
|
+
| **`get_active_model`** | Returns the currently active runner info |
|
|
137
|
+
| **`list_runners`** | Lists all registered runners and their metadata |
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## 📋 Copy-Paste Prompts for Claude Code
|
|
142
|
+
|
|
143
|
+
### ⭐ Zero-Token File Operations
|
|
144
|
+
```text
|
|
145
|
+
Call tool review_file with file_path='lib/screens/login_screen.dart'
|
|
146
|
+
```
|
|
147
|
+
```text
|
|
148
|
+
Call tool test_file with file_path='lib/services/auth_service.dart'
|
|
149
|
+
```
|
|
150
|
+
```text
|
|
151
|
+
Call tool explain_file with file_path='lib/blocs/cart_bloc.dart' and audience='junior'
|
|
152
|
+
```
|
|
153
|
+
```text
|
|
154
|
+
Call tool explain_file with file_path='lib/blocs/cart_bloc.dart' and audience='senior'
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
> **Audiences**: `junior` | `mid-level` (default) | `senior` | `non-technical`
|
|
158
|
+
|
|
159
|
+
### 💡 Code Snippet Explanation
|
|
160
|
+
```text
|
|
161
|
+
Call tool explain_code with code='Future<void> sync() async { ... }' and audience='mid-level'
|
|
162
|
+
```
|
|
163
|
+
```text
|
|
164
|
+
Call tool explain_code with code='type UserState = { status: "idle" | "loading" };' and language='typescript' and audience='junior'
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 📐 Architecture Planning
|
|
168
|
+
```text
|
|
169
|
+
Call tool create_plan for 'Offline SQLite caching in Flutter'
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### 🤖 Ask a Specific Model
|
|
173
|
+
```text
|
|
174
|
+
Call tool ask_subagent with prompt='Write a Flutter Riverpod StateNotifier for cart' and model='nvidia'
|
|
175
|
+
```
|
|
176
|
+
```text
|
|
177
|
+
Call tool ask_subagent with prompt='Explain Dart Streams' and model='ollama'
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### 📊 Multi-Model Benchmark
|
|
181
|
+
```text
|
|
182
|
+
Call tool benchmark_run with task='Write an LRU Cache in Dart' and runner_ids=['nvidia-llama-3.3-70b', 'openrouter-claude-sonnet-4.5']
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## 🌐 Supported Backends & Models
|
|
188
|
+
|
|
189
|
+
| Provider | Models | Env Variable |
|
|
190
|
+
| :--- | :--- | :--- |
|
|
191
|
+
| **OpenRouter** | Claude 3.7 Sonnet, DeepSeek-R1 (671B), DeepSeek-V3, Qwen 2.5 Coder, Llama 3.3 70B, Gemini 2.0 Flash | `OPENROUTER_API_KEY` |
|
|
192
|
+
| **NVIDIA NIM** | Nemotron 3 Super 120B, Llama 3.3 70B, Qwen Coder, DeepSeek R1 | `NVIDIA_API_KEY` |
|
|
193
|
+
| **Local Ollama** | Qwen 2.5 Coder, Llama 3.2, DeepSeek-R1 | *(none — free & offline)* |
|
|
194
|
+
| **Anthropic Direct** | Claude 3.7 Sonnet, Claude 3.5 Haiku | `ANTHROPIC_API_KEY` |
|
|
195
|
+
| **OpenAI Direct** | GPT-4o, GPT-4o-mini | `OPENAI_API_KEY` |
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## 📁 Project Structure
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
SmartRelay/
|
|
203
|
+
├── src/
|
|
204
|
+
│ ├── server.ts ← MCP stdio server (13 tools registered)
|
|
205
|
+
│ ├── http-api.ts ← Fastify HTTP API (for MCPHub plugin)
|
|
206
|
+
│ ├── router.ts ← TaskRouter with intent classification
|
|
207
|
+
│ ├── tools/
|
|
208
|
+
│ │ └── handlers.ts ← All tool implementations
|
|
209
|
+
│ ├── runners/ ← Anthropic, OpenAI, NVIDIA, Ollama, OpenRouter
|
|
210
|
+
│ ├── benchmark/ ← BenchmarkEngine + scorers
|
|
211
|
+
│ ├── logger.ts
|
|
212
|
+
│ └── util.ts
|
|
213
|
+
├── plugin-smartrelay/ ← MCPHub plugin (standalone, uploadable)
|
|
214
|
+
│ └── src/index.ts ← SmartRelayPlugin class
|
|
215
|
+
├── config/
|
|
216
|
+
│ └── runners/
|
|
217
|
+
│ ├── agents.yaml ← Specialized agents (planner, reviewer, etc.)
|
|
218
|
+
│ ├── nvidia.yaml
|
|
219
|
+
│ ├── openrouter.yaml
|
|
220
|
+
│ ├── ollama.yaml
|
|
221
|
+
│ ├── anthropic.yaml
|
|
222
|
+
│ └── openai.yaml
|
|
223
|
+
├── config.yaml ← Main config (includes all runner files)
|
|
224
|
+
├── prompts/ ← System prompts for each agent role
|
|
225
|
+
│ ├── code_review.md
|
|
226
|
+
│ ├── explain_code.md
|
|
227
|
+
│ ├── planner.md
|
|
228
|
+
│ └── test_generator.md
|
|
229
|
+
└── tests/ ← 39 Vitest tests
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## 🚀 Quick Setup Guide (Development / Self-hosted)
|
|
235
|
+
|
|
236
|
+
### 1. Clone & Install
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
git clone https://github.com/DhavanBhalodiya/smart-relay
|
|
240
|
+
cd smart-relay
|
|
241
|
+
npm install
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### 2. Configure Environment Variables
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
cp .env.example .env
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Edit `.env` and add your API keys:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
ANTHROPIC_API_KEY=sk-ant-api03-...
|
|
254
|
+
OPENAI_API_KEY=sk-proj-...
|
|
255
|
+
OPENROUTER_API_KEY=sk-or-v1-...
|
|
256
|
+
NVIDIA_API_KEY=nvapi-...
|
|
257
|
+
|
|
258
|
+
# For HTTP API / MCPHub plugin
|
|
259
|
+
SMARTRELAY_HTTP_API_KEY=your-secure-bearer-token-here
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
> You only need keys for the providers you want to use. Ollama works with no key (free, local).
|
|
263
|
+
|
|
264
|
+
### 3. Build
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
npm run build
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### 4. Connect to Your AI Client
|
|
271
|
+
|
|
272
|
+
> 💡 **Tip — Finding your absolute path**:
|
|
273
|
+
> Run `pwd` (macOS/Linux) or `echo %cd%` (Windows) in your `smart-relay` folder to find your `/ABSOLUTE/PATH/TO/smart-relay`.
|
|
274
|
+
>
|
|
275
|
+
> ⚠️ **Important (GUI Apps & Node PATH)**:
|
|
276
|
+
> GUI applications (Claude Desktop, Cursor) on macOS and Linux often do not inherit shell environment variables like `PATH`. If you get `spawn node ENOENT` or `Connection failed`:
|
|
277
|
+
> - Run `which node` in your terminal (e.g. `/opt/homebrew/bin/node` or `/usr/local/bin/node`).
|
|
278
|
+
> - Use that exact full path instead of `"command": "node"`.
|
|
279
|
+
|
|
280
|
+
#### 🟣 Claude Code (CLI)
|
|
281
|
+
|
|
282
|
+
To make SmartRelay available across **all your projects** (e.g. Flutter apps in `Documents`):
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
claude mcp add -s user smartrelay -- node /ABSOLUTE/PATH/TO/smart-relay/dist/server.js
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
> **Note**: The `-s user` flag installs it globally for your user account so it works inside any folder or project. Omit `-s user` only if you want it scoped to the current directory only.
|
|
289
|
+
|
|
290
|
+
Verify anywhere: `claude mcp list` | Remove: `claude mcp remove -s user smartrelay`
|
|
291
|
+
|
|
292
|
+
#### 🟠 Claude Desktop
|
|
293
|
+
|
|
294
|
+
Config file locations:
|
|
295
|
+
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
296
|
+
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
297
|
+
- **Linux**: `~/.config/Claude/claude_desktop_config.json`
|
|
298
|
+
|
|
299
|
+
```json
|
|
300
|
+
{
|
|
301
|
+
"mcpServers": {
|
|
302
|
+
"smartrelay": {
|
|
303
|
+
"command": "node",
|
|
304
|
+
"args": ["/ABSOLUTE/PATH/TO/smart-relay/dist/server.js"],
|
|
305
|
+
"env": {
|
|
306
|
+
"OPENAI_API_KEY": "sk-proj-...",
|
|
307
|
+
"ANTHROPIC_API_KEY": "sk-ant-...",
|
|
308
|
+
"NVIDIA_API_KEY": "nvapi-...",
|
|
309
|
+
"OPENROUTER_API_KEY": "sk-or-v1-..."
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
*(Note: If you already configured `.env` inside the `smart-relay` repository, the `"env"` block above is optional — SmartRelay auto-detects it!)*
|
|
316
|
+
|
|
317
|
+
#### 🔵 Cursor IDE
|
|
318
|
+
|
|
319
|
+
Go to **Settings → Features → MCP → + Add New MCP Server**:
|
|
320
|
+
- **Name**: `smartrelay`
|
|
321
|
+
- **Type**: `command`
|
|
322
|
+
- **Command**: `node /ABSOLUTE/PATH/TO/smart-relay/dist/server.js`
|
|
323
|
+
|
|
324
|
+
#### 🌊 Windsurf / Codeium
|
|
325
|
+
|
|
326
|
+
Edit `~/.codeium/windsurf/mcp_config.json`:
|
|
327
|
+
```json
|
|
328
|
+
{
|
|
329
|
+
"mcpServers": {
|
|
330
|
+
"smartrelay": {
|
|
331
|
+
"command": "node",
|
|
332
|
+
"args": ["/ABSOLUTE/PATH/TO/smart-relay/dist/server.js"]
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
#### 🟢 VS Code (Cline / Roo Code)
|
|
339
|
+
|
|
340
|
+
Edit your Cline MCP settings (`cline_mcp_settings.json`):
|
|
341
|
+
```json
|
|
342
|
+
{
|
|
343
|
+
"mcpServers": {
|
|
344
|
+
"smartrelay": {
|
|
345
|
+
"command": "node",
|
|
346
|
+
"args": ["/ABSOLUTE/PATH/TO/smart-relay/dist/server.js"]
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## 🧪 Testing & Verification
|
|
355
|
+
|
|
356
|
+
### Run all 39 automated tests
|
|
357
|
+
```bash
|
|
358
|
+
npm test
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### TypeScript type check
|
|
362
|
+
```bash
|
|
363
|
+
npm run typecheck
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Plugin conformance test (MCPHub)
|
|
367
|
+
```bash
|
|
368
|
+
npm run test:plugin
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Quick manual CLI test
|
|
372
|
+
```bash
|
|
373
|
+
# List all registered runners
|
|
374
|
+
npm run quick-test -- --list
|
|
375
|
+
|
|
376
|
+
# Test a specific runner
|
|
377
|
+
npm run quick-test -- "Say hello" --runner nvidia-llama-3.3-70b
|
|
378
|
+
|
|
379
|
+
# Test local Ollama (free)
|
|
380
|
+
npm run quick-test -- "Explain Dart Streams" --runner ollama-llama3.2
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### Start HTTP API server (for MCPHub plugin)
|
|
384
|
+
```bash
|
|
385
|
+
export SMARTRELAY_HTTP_API_KEY=my-secret-token
|
|
386
|
+
npm run start:http
|
|
387
|
+
# → http://127.0.0.1:8000
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Test HTTP endpoints:
|
|
391
|
+
```bash
|
|
392
|
+
curl -H "Authorization: Bearer my-secret-token" http://127.0.0.1:8000/v1/health
|
|
393
|
+
curl -H "Authorization: Bearer my-secret-token" http://127.0.0.1:8000/v1/runners
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
## 🌐 MCP Inspector — Visual Browser UI
|
|
399
|
+
|
|
400
|
+
Browse and run all 13 tools interactively in your browser:
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
npm run build
|
|
404
|
+
npx -y @modelcontextprotocol/inspector node dist/server.js
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
Opens at **http://localhost:6274**
|
|
408
|
+
|
|
409
|
+
| Tab | What's inside |
|
|
410
|
+
| :--- | :--- |
|
|
411
|
+
| **Tools** | All 13 tools with interactive forms — fill in params and run live |
|
|
412
|
+
| **Resources** | Resources exposed by the server |
|
|
413
|
+
| **Prompts** | Prompt templates |
|
|
414
|
+
|
|
415
|
+
> Fastest way to verify everything works without needing Claude Code or any AI client.
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## 🔧 npm Scripts Reference
|
|
420
|
+
|
|
421
|
+
| Script | Command | What it does |
|
|
422
|
+
| :--- | :--- | :--- |
|
|
423
|
+
| `npm run build` | `tsc` | Compile TypeScript → `dist/` |
|
|
424
|
+
| `npm run dev` | `tsx src/server.ts` | Run MCP server (dev mode, no build needed) |
|
|
425
|
+
| `npm run dev:http` | `tsx src/http-api.ts` | Run HTTP API server (dev mode) |
|
|
426
|
+
| `npm start` | `node dist/server.js` | Run compiled MCP server |
|
|
427
|
+
| `npm run start:http` | `node dist/http-api.js` | Run compiled HTTP API |
|
|
428
|
+
| `npm test` | `vitest run` | Run 39 automated tests |
|
|
429
|
+
| `npm run typecheck` | `tsc --noEmit` | TypeScript type check only |
|
|
430
|
+
| `npm run test:plugin` | `tsx scripts/test-plugin.ts` | MCPHub plugin conformance test |
|
|
431
|
+
| `npm run quick-test` | `tsx scripts/quick-test.ts` | Manual CLI runner test |
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
## 🔒 Security Notes
|
|
436
|
+
|
|
437
|
+
- API keys are read from environment variables only — never hardcoded
|
|
438
|
+
- The HTTP API requires a Bearer token (`SMARTRELAY_HTTP_API_KEY`)
|
|
439
|
+
- The MCP stdio server is local-only (no network exposure)
|
|
440
|
+
- No `process.exit()` calls — uses `process.exitCode` for safe shutdown
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## 📄 License
|
|
445
|
+
|
|
446
|
+
MIT — See [LICENSE](./LICENSE)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
runners:
|
|
2
|
+
# ==========================================
|
|
3
|
+
# Specialized Role-Based Agents
|
|
4
|
+
# ==========================================
|
|
5
|
+
planner-agent:
|
|
6
|
+
type: "openrouter"
|
|
7
|
+
model: "openai/gpt-5.6-luna"
|
|
8
|
+
api_key_env: "OPENROUTER_API_KEY"
|
|
9
|
+
cost_per_million_input_tokens: 3.00
|
|
10
|
+
cost_per_million_output_tokens: 15.00
|
|
11
|
+
default_params:
|
|
12
|
+
max_tokens: 4096
|
|
13
|
+
temperature: 0.2
|
|
14
|
+
system_prompt_file: "prompts/planner.md"
|
|
15
|
+
|
|
16
|
+
code-review-agent:
|
|
17
|
+
type: "nvidia"
|
|
18
|
+
model: "nvidia/nemotron-3-super-120b-a12b"
|
|
19
|
+
api_key_env: "NVIDIA_API_KEY"
|
|
20
|
+
cost_per_million_input_tokens: 0.70
|
|
21
|
+
cost_per_million_output_tokens: 0.90
|
|
22
|
+
default_params:
|
|
23
|
+
max_tokens: 4096
|
|
24
|
+
temperature: 0.1
|
|
25
|
+
system_prompt_file: "prompts/code_review.md"
|
|
26
|
+
|
|
27
|
+
test-generator-agent:
|
|
28
|
+
type: "nvidia"
|
|
29
|
+
model: "nvidia/nemotron-3-super-120b-a12b"
|
|
30
|
+
api_key_env: "NVIDIA_API_KEY"
|
|
31
|
+
cost_per_million_input_tokens: 0.70
|
|
32
|
+
cost_per_million_output_tokens: 0.90
|
|
33
|
+
default_params:
|
|
34
|
+
max_tokens: 4096
|
|
35
|
+
temperature: 0.2
|
|
36
|
+
system_prompt_file: "prompts/test_generator.md"
|
|
37
|
+
|
|
38
|
+
explain-agent:
|
|
39
|
+
type: "openrouter"
|
|
40
|
+
model: "deepseek/deepseek-v4-flash-0731"
|
|
41
|
+
api_key_env: "OPENROUTER_API_KEY"
|
|
42
|
+
cost_per_million_input_tokens: 0.70
|
|
43
|
+
cost_per_million_output_tokens: 0.90
|
|
44
|
+
default_params:
|
|
45
|
+
max_tokens: 4096
|
|
46
|
+
temperature: 0.3
|
|
47
|
+
system_prompt_file: "prompts/explain_code.md"
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
runners:
|
|
2
|
+
# ==========================================
|
|
3
|
+
# Anthropic Direct API
|
|
4
|
+
# ==========================================
|
|
5
|
+
claude-3-7-sonnet:
|
|
6
|
+
type: "anthropic"
|
|
7
|
+
model: "claude-3-7-sonnet-20250219"
|
|
8
|
+
api_key_env: "ANTHROPIC_API_KEY"
|
|
9
|
+
cost_per_million_input_tokens: 3.00
|
|
10
|
+
cost_per_million_output_tokens: 15.00
|
|
11
|
+
default_params:
|
|
12
|
+
max_tokens: 2048
|
|
13
|
+
temperature: 0.7
|
|
14
|
+
|
|
15
|
+
claude-3-5-haiku:
|
|
16
|
+
type: "anthropic"
|
|
17
|
+
model: "claude-3-5-haiku-20241022"
|
|
18
|
+
api_key_env: "ANTHROPIC_API_KEY"
|
|
19
|
+
cost_per_million_input_tokens: 0.80
|
|
20
|
+
cost_per_million_output_tokens: 4.00
|
|
21
|
+
default_params:
|
|
22
|
+
max_tokens: 2048
|
|
23
|
+
temperature: 0.7
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
runners:
|
|
2
|
+
# ==========================================
|
|
3
|
+
# NVIDIA NIM / API Catalog (build.nvidia.com)
|
|
4
|
+
# ==========================================
|
|
5
|
+
nemotron-3-super-120b-a12b:
|
|
6
|
+
type: "nvidia"
|
|
7
|
+
model: "nvidia/nemotron-3-super-120b-a12b"
|
|
8
|
+
api_key_env: "NVIDIA_API_KEY"
|
|
9
|
+
cost_per_million_input_tokens: 0.70
|
|
10
|
+
cost_per_million_output_tokens: 0.90
|
|
11
|
+
default_params:
|
|
12
|
+
max_tokens: 16384
|
|
13
|
+
temperature: 1
|
|
14
|
+
|
|
15
|
+
nvidia-llama-3.3-70b:
|
|
16
|
+
type: "nvidia"
|
|
17
|
+
model: "meta/llama-3.3-70b-instruct"
|
|
18
|
+
api_key_env: "NVIDIA_API_KEY"
|
|
19
|
+
cost_per_million_input_tokens: 0.70
|
|
20
|
+
cost_per_million_output_tokens: 0.90
|
|
21
|
+
default_params:
|
|
22
|
+
max_tokens: 4096
|
|
23
|
+
temperature: 0.1
|
|
24
|
+
|
|
25
|
+
nvidia-qwen-coder:
|
|
26
|
+
type: "nvidia"
|
|
27
|
+
model: "qwen/qwen2.5-coder-32b-instruct"
|
|
28
|
+
api_key_env: "NVIDIA_API_KEY"
|
|
29
|
+
cost_per_million_input_tokens: 0.50
|
|
30
|
+
cost_per_million_output_tokens: 0.70
|
|
31
|
+
default_params:
|
|
32
|
+
max_tokens: 2048
|
|
33
|
+
temperature: 0.2
|
|
34
|
+
|
|
35
|
+
nvidia-deepseek-r1:
|
|
36
|
+
type: "nvidia"
|
|
37
|
+
model: "deepseek-ai/deepseek-r1"
|
|
38
|
+
api_key_env: "NVIDIA_API_KEY"
|
|
39
|
+
cost_per_million_input_tokens: 0.55
|
|
40
|
+
cost_per_million_output_tokens: 2.19
|
|
41
|
+
default_params:
|
|
42
|
+
max_tokens: 2048
|
|
43
|
+
temperature: 0.6
|
|
44
|
+
|
|
45
|
+
nvidia-nemotron:
|
|
46
|
+
type: "nvidia"
|
|
47
|
+
model: "nvidia/llama-3.1-nemotron-70b-instruct"
|
|
48
|
+
api_key_env: "NVIDIA_API_KEY"
|
|
49
|
+
cost_per_million_input_tokens: 0.70
|
|
50
|
+
cost_per_million_output_tokens: 0.90
|
|
51
|
+
default_params:
|
|
52
|
+
max_tokens: 2048
|
|
53
|
+
temperature: 0.6
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
runners:
|
|
2
|
+
# ==========================================
|
|
3
|
+
# Local Ollama Models (100% Free & Offline)
|
|
4
|
+
# ==========================================
|
|
5
|
+
ollama-llama3.2:
|
|
6
|
+
type: "ollama"
|
|
7
|
+
model: "llama3.2"
|
|
8
|
+
base_url: "http://localhost:11434"
|
|
9
|
+
cost_per_million_input_tokens: 0.00
|
|
10
|
+
cost_per_million_output_tokens: 0.00
|
|
11
|
+
default_params:
|
|
12
|
+
max_tokens: 2048
|
|
13
|
+
temperature: 0.7
|
|
14
|
+
|
|
15
|
+
ollama-qwen-coder:
|
|
16
|
+
type: "ollama"
|
|
17
|
+
model: "qwen2.5-coder:7b"
|
|
18
|
+
base_url: "http://localhost:11434"
|
|
19
|
+
cost_per_million_input_tokens: 0.00
|
|
20
|
+
cost_per_million_output_tokens: 0.00
|
|
21
|
+
default_params:
|
|
22
|
+
max_tokens: 2048
|
|
23
|
+
temperature: 0.2
|
|
24
|
+
|
|
25
|
+
ollama-deepseek-r1:
|
|
26
|
+
type: "ollama"
|
|
27
|
+
model: "deepseek-r1:8b"
|
|
28
|
+
base_url: "http://localhost:11434"
|
|
29
|
+
cost_per_million_input_tokens: 0.00
|
|
30
|
+
cost_per_million_output_tokens: 0.00
|
|
31
|
+
default_params:
|
|
32
|
+
max_tokens: 2048
|
|
33
|
+
temperature: 0.6
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
runners:
|
|
2
|
+
# ==========================================
|
|
3
|
+
# OpenAI Direct API
|
|
4
|
+
# ==========================================
|
|
5
|
+
gpt-4o:
|
|
6
|
+
type: "openai"
|
|
7
|
+
model: "gpt-4o"
|
|
8
|
+
api_key_env: "OPENAI_API_KEY"
|
|
9
|
+
cost_per_million_input_tokens: 2.50
|
|
10
|
+
cost_per_million_output_tokens: 10.00
|
|
11
|
+
default_params:
|
|
12
|
+
max_tokens: 2048
|
|
13
|
+
temperature: 0.7
|
|
14
|
+
|
|
15
|
+
gpt-4o-mini:
|
|
16
|
+
type: "openai"
|
|
17
|
+
model: "gpt-4o-mini"
|
|
18
|
+
api_key_env: "OPENAI_API_KEY"
|
|
19
|
+
cost_per_million_input_tokens: 0.15
|
|
20
|
+
cost_per_million_output_tokens: 0.60
|
|
21
|
+
default_params:
|
|
22
|
+
max_tokens: 2048
|
|
23
|
+
temperature: 0.7
|