@bike4mind/cli 0.2.5-feat-cli-docker-mcp-support.17095 → 0.2.5-feat-server-side-tool-execution.17096
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 +31 -81
- package/bin/b4m-mcp-proxy.mjs +79 -0
- package/dist/index.js +161 -116
- package/dist/mcp-proxy/client.d.ts +47 -0
- package/dist/mcp-proxy/client.d.ts.map +1 -0
- package/dist/mcp-proxy/client.js +124 -0
- package/dist/mcp-proxy/client.js.map +1 -0
- package/dist/mcp-proxy/index.d.ts +32 -0
- package/dist/mcp-proxy/index.d.ts.map +1 -0
- package/dist/mcp-proxy/index.js +187 -0
- package/dist/mcp-proxy/index.js.map +1 -0
- package/package.json +8 -6
package/README.md
CHANGED
|
@@ -135,52 +135,46 @@ Check your current API configuration:
|
|
|
135
135
|
/api-info
|
|
136
136
|
```
|
|
137
137
|
|
|
138
|
-
###
|
|
138
|
+
### Built-in Tools
|
|
139
|
+
|
|
140
|
+
The CLI provides access to various tools that execute server-side using B4M company API keys:
|
|
141
|
+
|
|
142
|
+
**Local Tools (always available):**
|
|
143
|
+
- ✅ `dice_roll` - Roll dice with custom notation
|
|
144
|
+
- ✅ `math_evaluate` - Evaluate mathematical expressions
|
|
145
|
+
- ✅ `current_datetime` - Get current date and time
|
|
146
|
+
- ✅ `prompt_enhancement` - Improve prompts using LLM
|
|
147
|
+
- ✅ `file_read` - Read files from local filesystem
|
|
148
|
+
- ✅ `create_file` - Create or update files
|
|
149
|
+
- ✅ `glob_files` - Find files by pattern
|
|
150
|
+
- ✅ `grep_search` - Search file contents
|
|
151
|
+
- ✅ `delete_file` - Delete files
|
|
152
|
+
|
|
153
|
+
**B4M Server Tools (require authentication):**
|
|
154
|
+
- 🌐 `weather` - Get weather information worldwide (via OpenWeather)
|
|
155
|
+
- 🔍 `serper` - Search the web using Google (via Serper API)
|
|
156
|
+
- 🔬 `deep_research` - Perform in-depth research using web search
|
|
139
157
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
```json
|
|
143
|
-
{
|
|
144
|
-
"toolApiKeys": {
|
|
145
|
-
"openweather": "your-openweather-key",
|
|
146
|
-
"serper": "your-serper-key"
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
Or use environment variables (config takes precedence):
|
|
152
|
-
|
|
153
|
-
```bash
|
|
154
|
-
export OPENWEATHER_API_KEY="your-key-here"
|
|
155
|
-
export SERPER_API_KEY="your-key-here"
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
**Available Tools:**
|
|
159
|
-
- ✅ `dice_roll` - No API key needed
|
|
160
|
-
- ✅ `math_evaluate` - No API key needed
|
|
161
|
-
- ✅ `current_datetime` - No API key needed
|
|
162
|
-
- ✅ `prompt_enhancement` - No API key needed
|
|
163
|
-
- 🔑 `weather_info` - Requires `toolApiKeys.openweather`
|
|
164
|
-
- 🔑 `web_search` - Requires `toolApiKeys.serper`
|
|
165
|
-
- 🔑 `deep_research` - Requires `toolApiKeys.serper`
|
|
166
|
-
|
|
167
|
-
**Get API Keys:**
|
|
168
|
-
- OpenWeather API: https://openweathermap.org/api
|
|
169
|
-
- Serper API: https://serper.dev/
|
|
158
|
+
**Authentication:**
|
|
159
|
+
B4M server tools execute on the backend using company-managed API keys. Simply authenticate with `/login` to access them. No personal API keys needed!
|
|
170
160
|
|
|
171
|
-
###
|
|
161
|
+
### MCP Servers
|
|
172
162
|
|
|
173
|
-
MCP (Model Context Protocol) servers provide additional tools and capabilities.
|
|
163
|
+
MCP (Model Context Protocol) servers provide additional tools and capabilities.
|
|
174
164
|
|
|
175
|
-
|
|
165
|
+
**Built-in B4M Server:**
|
|
166
|
+
The CLI includes a built-in B4M MCP server (`b4m-tools`) that provides server-side tool execution. This server is automatically configured when you authenticate with `/login`.
|
|
176
167
|
|
|
177
|
-
|
|
168
|
+
**Additional MCP Servers:**
|
|
169
|
+
You can add optional MCP servers in `~/.bike4mind/config.json`:
|
|
178
170
|
|
|
179
171
|
```json
|
|
180
172
|
{
|
|
181
173
|
"mcpServers": [
|
|
182
174
|
{
|
|
183
175
|
"name": "github",
|
|
176
|
+
"command": "node",
|
|
177
|
+
"args": ["path/to/mcp/server.js"],
|
|
184
178
|
"env": {
|
|
185
179
|
"GITHUB_ACCESS_TOKEN": "ghp_..."
|
|
186
180
|
},
|
|
@@ -190,56 +184,12 @@ For MCP servers bundled with the monorepo, you can omit `command` and `args` - t
|
|
|
190
184
|
}
|
|
191
185
|
```
|
|
192
186
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
You can run MCP servers in Docker containers for isolation and portability:
|
|
196
|
-
|
|
197
|
-
```json
|
|
198
|
-
{
|
|
199
|
-
"mcpServers": [
|
|
200
|
-
{
|
|
201
|
-
"name": "github",
|
|
202
|
-
"command": "docker",
|
|
203
|
-
"args": ["run", "-i", "--rm", "-e", "GITHUB_TOKEN", "ghcr.io/github/github-mcp-server"],
|
|
204
|
-
"env": {
|
|
205
|
-
"GITHUB_TOKEN": "ghp_..."
|
|
206
|
-
},
|
|
207
|
-
"enabled": true
|
|
208
|
-
}
|
|
209
|
-
]
|
|
210
|
-
}
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
**Docker Configuration Notes:**
|
|
214
|
-
- The `-i` flag is required for stdin communication with the MCP server
|
|
215
|
-
- Use `-e VAR_NAME` (without value) to pass environment variables from the host
|
|
216
|
-
- The `--rm` flag ensures containers are cleaned up after use
|
|
217
|
-
- Requires Docker to be installed and running
|
|
218
|
-
|
|
219
|
-
#### External MCP Servers (npx/Custom Commands)
|
|
220
|
-
|
|
221
|
-
You can also run any MCP server via npx or custom executables:
|
|
222
|
-
|
|
223
|
-
```json
|
|
224
|
-
{
|
|
225
|
-
"mcpServers": [
|
|
226
|
-
{
|
|
227
|
-
"name": "filesystem",
|
|
228
|
-
"command": "npx",
|
|
229
|
-
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"],
|
|
230
|
-
"env": {},
|
|
231
|
-
"enabled": true
|
|
232
|
-
}
|
|
233
|
-
]
|
|
234
|
-
}
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
**Available Built-in MCP Servers:**
|
|
187
|
+
**Optional MCP Servers:**
|
|
238
188
|
- 🔧 **GitHub** - Repository management, issues, PRs (requires `GITHUB_ACCESS_TOKEN`)
|
|
239
189
|
- 🔧 **LinkedIn** - Post management, analytics (requires `LINKEDIN_ACCESS_TOKEN`, `COMPANY_NAME`)
|
|
240
190
|
- 🔧 **Atlassian** - Jira/Confluence integration (requires `ATLASSIAN_ACCESS_TOKEN`, `ATLASSIAN_CLOUD_ID`, `ATLASSIAN_SITE_URL`)
|
|
241
191
|
|
|
242
|
-
**Note:**
|
|
192
|
+
**Note:** The built-in `b4m-tools` MCP server is automatically bundled with the CLI and configured on authentication. Optional MCP servers can be added as needed for additional integrations.
|
|
243
193
|
|
|
244
194
|
## Session Storage
|
|
245
195
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* B4M MCP Proxy Wrapper
|
|
4
|
+
*
|
|
5
|
+
* This wrapper script reads the CLI configuration to get the current JWT token
|
|
6
|
+
* and API URL, then launches the MCP proxy with those credentials.
|
|
7
|
+
*
|
|
8
|
+
* This allows the MCP proxy to authenticate with the B4M backend without
|
|
9
|
+
* requiring users to manually set environment variables.
|
|
10
|
+
*
|
|
11
|
+
* The wrapper reads from ~/.bike4mind/config.json to get:
|
|
12
|
+
* - auth.accessToken (JWT token)
|
|
13
|
+
* - apiConfig.customUrl (custom API URL, if set)
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { spawn } from 'child_process';
|
|
17
|
+
import { join, dirname } from 'path';
|
|
18
|
+
import { homedir } from 'os';
|
|
19
|
+
import { readFileSync } from 'fs';
|
|
20
|
+
import { fileURLToPath } from 'url';
|
|
21
|
+
|
|
22
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
|
|
24
|
+
// Read config to get current JWT token and API URL
|
|
25
|
+
const configPath = process.env.B4M_CONFIG_PATH || join(homedir(), '.bike4mind', 'config.json');
|
|
26
|
+
|
|
27
|
+
let authToken = '';
|
|
28
|
+
let apiUrl = 'https://api.bike4mind.com';
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
const configData = readFileSync(configPath, 'utf-8');
|
|
32
|
+
const config = JSON.parse(configData);
|
|
33
|
+
|
|
34
|
+
// Get JWT access token
|
|
35
|
+
authToken = config.auth?.accessToken || '';
|
|
36
|
+
|
|
37
|
+
// Get custom API URL if configured
|
|
38
|
+
apiUrl = config.apiConfig?.customUrl || apiUrl;
|
|
39
|
+
|
|
40
|
+
if (!authToken) {
|
|
41
|
+
console.warn('⚠️ Warning: No authentication token found in config');
|
|
42
|
+
console.warn(' B4M server tools will not be available.');
|
|
43
|
+
console.warn(' Run /login in the CLI to authenticate.');
|
|
44
|
+
}
|
|
45
|
+
} catch (error) {
|
|
46
|
+
// Config doesn't exist or is invalid
|
|
47
|
+
// This is OK - user might not be authenticated yet
|
|
48
|
+
if (error.code !== 'ENOENT') {
|
|
49
|
+
console.error('Warning: Could not read B4M config:', error.message);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Path to the bundled MCP proxy
|
|
54
|
+
const mcpProxyPath = join(__dirname, '../dist/mcp-proxy/index.js');
|
|
55
|
+
|
|
56
|
+
// Launch MCP proxy with dynamic environment variables
|
|
57
|
+
const child = spawn('node', [mcpProxyPath], {
|
|
58
|
+
stdio: 'inherit', // Inherit stdin/stdout/stderr for MCP protocol
|
|
59
|
+
env: {
|
|
60
|
+
...process.env,
|
|
61
|
+
B4M_AUTH_TOKEN: authToken,
|
|
62
|
+
B4M_API_URL: apiUrl,
|
|
63
|
+
B4M_TIMEOUT: process.env.B4M_TIMEOUT || '30000',
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Handle process exit
|
|
68
|
+
child.on('exit', (code) => {
|
|
69
|
+
process.exit(code || 0);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Handle signals
|
|
73
|
+
process.on('SIGINT', () => {
|
|
74
|
+
child.kill('SIGINT');
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
process.on('SIGTERM', () => {
|
|
78
|
+
child.kill('SIGTERM');
|
|
79
|
+
});
|
package/dist/index.js
CHANGED
|
@@ -1408,21 +1408,21 @@ var AuthTokensSchema = z.object({
|
|
|
1408
1408
|
var ApiConfigSchema = z.object({
|
|
1409
1409
|
customUrl: z.string().url().optional()
|
|
1410
1410
|
});
|
|
1411
|
+
var LegacyApiConfigSchema = z.object({
|
|
1412
|
+
environment: z.enum(["production", "staging", "preview", "local", "custom"]),
|
|
1413
|
+
customUrl: z.string().url().optional()
|
|
1414
|
+
});
|
|
1411
1415
|
var CliConfigSchema = z.object({
|
|
1412
1416
|
version: z.string(),
|
|
1413
1417
|
userId: z.string(),
|
|
1414
1418
|
auth: AuthTokensSchema.optional(),
|
|
1415
1419
|
defaultModel: z.string(),
|
|
1416
1420
|
apiConfig: ApiConfigSchema.optional(),
|
|
1417
|
-
toolApiKeys: z.object({
|
|
1418
|
-
openweather: z.string().optional(),
|
|
1419
|
-
serper: z.string().optional()
|
|
1420
|
-
}).optional(),
|
|
1421
1421
|
mcpServers: z.array(
|
|
1422
1422
|
z.object({
|
|
1423
1423
|
name: z.string(),
|
|
1424
|
-
command: z.string()
|
|
1425
|
-
args: z.array(z.string())
|
|
1424
|
+
command: z.string(),
|
|
1425
|
+
args: z.array(z.string()),
|
|
1426
1426
|
env: z.record(z.string()),
|
|
1427
1427
|
enabled: z.boolean()
|
|
1428
1428
|
})
|
|
@@ -1442,15 +1442,36 @@ var CliConfigSchema = z.object({
|
|
|
1442
1442
|
}),
|
|
1443
1443
|
trustedTools: z.array(z.string()).optional().default([])
|
|
1444
1444
|
});
|
|
1445
|
+
var getCliPackageRoot = () => {
|
|
1446
|
+
const currentFile = new URL(import.meta.url).pathname;
|
|
1447
|
+
const currentDir = path4.dirname(currentFile);
|
|
1448
|
+
if (currentDir.endsWith("/dist") || currentDir.includes("/dist/")) {
|
|
1449
|
+
return path4.resolve(currentDir, "..");
|
|
1450
|
+
}
|
|
1451
|
+
if (currentDir.includes("/src")) {
|
|
1452
|
+
const srcIndex = currentDir.lastIndexOf("/src");
|
|
1453
|
+
return currentDir.substring(0, srcIndex);
|
|
1454
|
+
}
|
|
1455
|
+
return process.cwd();
|
|
1456
|
+
};
|
|
1445
1457
|
var DEFAULT_CONFIG = {
|
|
1446
1458
|
version: "0.1.0",
|
|
1447
1459
|
userId: uuidv4(),
|
|
1448
1460
|
defaultModel: "claude-sonnet-4-5-20250929",
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1461
|
+
mcpServers: [
|
|
1462
|
+
// B4M server-side tools (weather, serper) via MCP proxy
|
|
1463
|
+
{
|
|
1464
|
+
name: "b4m-tools",
|
|
1465
|
+
command: "node",
|
|
1466
|
+
args: [path4.join(getCliPackageRoot(), "bin/b4m-mcp-proxy.mjs")],
|
|
1467
|
+
// Absolute path to wrapper script
|
|
1468
|
+
env: {
|
|
1469
|
+
// Token and API URL injected dynamically by wrapper script
|
|
1470
|
+
B4M_TIMEOUT: "30000"
|
|
1471
|
+
},
|
|
1472
|
+
enabled: true
|
|
1473
|
+
}
|
|
1474
|
+
],
|
|
1454
1475
|
preferences: {
|
|
1455
1476
|
maxTokens: 4096,
|
|
1456
1477
|
temperature: 0.7,
|
|
@@ -1505,11 +1526,14 @@ var ConfigStore = class {
|
|
|
1505
1526
|
const data = await fs4.readFile(this.configPath, "utf-8");
|
|
1506
1527
|
const rawConfig = JSON.parse(data);
|
|
1507
1528
|
if (rawConfig.apiConfig && "environment" in rawConfig.apiConfig) {
|
|
1508
|
-
const
|
|
1509
|
-
if (
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1529
|
+
const legacyConfigResult = LegacyApiConfigSchema.safeParse(rawConfig.apiConfig);
|
|
1530
|
+
if (legacyConfigResult.success) {
|
|
1531
|
+
const oldApiConfig = legacyConfigResult.data;
|
|
1532
|
+
if (oldApiConfig.environment === "custom" && oldApiConfig.customUrl) {
|
|
1533
|
+
rawConfig.apiConfig = { customUrl: oldApiConfig.customUrl };
|
|
1534
|
+
} else {
|
|
1535
|
+
rawConfig.apiConfig = {};
|
|
1536
|
+
}
|
|
1513
1537
|
}
|
|
1514
1538
|
}
|
|
1515
1539
|
const validated = CliConfigSchema.parse(rawConfig);
|
|
@@ -1526,10 +1550,6 @@ var ConfigStore = class {
|
|
|
1526
1550
|
...DEFAULT_CONFIG.tools,
|
|
1527
1551
|
...validated.tools
|
|
1528
1552
|
},
|
|
1529
|
-
toolApiKeys: {
|
|
1530
|
-
...DEFAULT_CONFIG.toolApiKeys,
|
|
1531
|
-
...validated.toolApiKeys || {}
|
|
1532
|
-
},
|
|
1533
1553
|
trustedTools: validated.trustedTools || []
|
|
1534
1554
|
};
|
|
1535
1555
|
return this.config;
|
|
@@ -1564,10 +1584,6 @@ var ConfigStore = class {
|
|
|
1564
1584
|
tools: {
|
|
1565
1585
|
...existingConfig.tools,
|
|
1566
1586
|
...config.tools || {}
|
|
1567
|
-
},
|
|
1568
|
-
toolApiKeys: {
|
|
1569
|
-
...existingConfig.toolApiKeys,
|
|
1570
|
-
...config.toolApiKeys || {}
|
|
1571
1587
|
}
|
|
1572
1588
|
};
|
|
1573
1589
|
}
|
|
@@ -1720,6 +1736,26 @@ var ConfigStore = class {
|
|
|
1720
1736
|
}
|
|
1721
1737
|
await this.save(config);
|
|
1722
1738
|
}
|
|
1739
|
+
/**
|
|
1740
|
+
* Ensure B4M MCP server is configured (auto-add if missing)
|
|
1741
|
+
* This provides server-side tools (weather, serper) to the CLI
|
|
1742
|
+
*/
|
|
1743
|
+
async ensureB4mMcpServer() {
|
|
1744
|
+
const config = await this.load();
|
|
1745
|
+
const hasB4mServer = config.mcpServers.some((s) => s.name === "b4m-tools");
|
|
1746
|
+
if (!hasB4mServer) {
|
|
1747
|
+
config.mcpServers.push({
|
|
1748
|
+
name: "b4m-tools",
|
|
1749
|
+
command: "node",
|
|
1750
|
+
args: [path4.join(getCliPackageRoot(), "bin/b4m-mcp-proxy.mjs")],
|
|
1751
|
+
env: {
|
|
1752
|
+
B4M_TIMEOUT: "30000"
|
|
1753
|
+
},
|
|
1754
|
+
enabled: true
|
|
1755
|
+
});
|
|
1756
|
+
await this.save(config);
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1723
1759
|
};
|
|
1724
1760
|
|
|
1725
1761
|
// src/storage/CommandHistoryStore.ts
|
|
@@ -4281,8 +4317,8 @@ async function processAndStoreImages(images, context) {
|
|
|
4281
4317
|
const buffer = await downloadImage(image);
|
|
4282
4318
|
const fileType = await fileTypeFromBuffer2(buffer);
|
|
4283
4319
|
const filename = `${uuidv45()}.${fileType?.ext}`;
|
|
4284
|
-
const
|
|
4285
|
-
return
|
|
4320
|
+
const path14 = await context.imageGenerateStorage.upload(buffer, filename, {});
|
|
4321
|
+
return path14;
|
|
4286
4322
|
}));
|
|
4287
4323
|
}
|
|
4288
4324
|
async function updateQuestAndReturnMarkdown(storedImageUrls, context) {
|
|
@@ -5466,8 +5502,8 @@ async function processAndStoreImage(imageUrl, context) {
|
|
|
5466
5502
|
const buffer = await downloadImage2(imageUrl);
|
|
5467
5503
|
const fileType = await fileTypeFromBuffer3(buffer);
|
|
5468
5504
|
const filename = `${uuidv46()}.${fileType?.ext}`;
|
|
5469
|
-
const
|
|
5470
|
-
return
|
|
5505
|
+
const path14 = await context.imageGenerateStorage.upload(buffer, filename, {});
|
|
5506
|
+
return path14;
|
|
5471
5507
|
}
|
|
5472
5508
|
async function updateQuestAndReturnMarkdown2(storedImagePath, context) {
|
|
5473
5509
|
await context.onFinish?.("edit_image", storedImagePath);
|
|
@@ -8186,21 +8222,21 @@ var NoOpStorage = class extends BaseStorage {
|
|
|
8186
8222
|
async upload(input, destination, options) {
|
|
8187
8223
|
return `/tmp/${destination}`;
|
|
8188
8224
|
}
|
|
8189
|
-
async download(
|
|
8225
|
+
async download(path14) {
|
|
8190
8226
|
throw new Error("Download not supported in CLI");
|
|
8191
8227
|
}
|
|
8192
|
-
async delete(
|
|
8228
|
+
async delete(path14) {
|
|
8193
8229
|
}
|
|
8194
|
-
async getSignedUrl(
|
|
8195
|
-
return `/tmp/${
|
|
8230
|
+
async getSignedUrl(path14) {
|
|
8231
|
+
return `/tmp/${path14}`;
|
|
8196
8232
|
}
|
|
8197
|
-
getPublicUrl(
|
|
8198
|
-
return `/tmp/${
|
|
8233
|
+
getPublicUrl(path14) {
|
|
8234
|
+
return `/tmp/${path14}`;
|
|
8199
8235
|
}
|
|
8200
|
-
async getPreview(
|
|
8201
|
-
return `/tmp/${
|
|
8236
|
+
async getPreview(path14) {
|
|
8237
|
+
return `/tmp/${path14}`;
|
|
8202
8238
|
}
|
|
8203
|
-
async getMetadata(
|
|
8239
|
+
async getMetadata(path14) {
|
|
8204
8240
|
return { size: 0, contentType: "application/octet-stream" };
|
|
8205
8241
|
}
|
|
8206
8242
|
};
|
|
@@ -8272,7 +8308,7 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
|
|
|
8272
8308
|
}
|
|
8273
8309
|
};
|
|
8274
8310
|
}
|
|
8275
|
-
function generateCliTools(userId, llm, model, permissionManager, showPermissionPrompt, agentContext
|
|
8311
|
+
function generateCliTools(userId, llm, model, permissionManager, showPermissionPrompt, agentContext) {
|
|
8276
8312
|
const logger2 = new CliLogger();
|
|
8277
8313
|
const storage = new NoOpStorage();
|
|
8278
8314
|
const user = {
|
|
@@ -8287,50 +8323,27 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
|
|
|
8287
8323
|
};
|
|
8288
8324
|
const onFinish = async (toolName, data) => {
|
|
8289
8325
|
};
|
|
8290
|
-
const mockAdminSettings = {
|
|
8291
|
-
findBySettingName: async (settingName) => {
|
|
8292
|
-
if (settingName === "OpenWeatherKey") {
|
|
8293
|
-
const key = toolApiKeys?.openweather || process.env.OPENWEATHER_API_KEY;
|
|
8294
|
-
if (key) {
|
|
8295
|
-
return { settingValue: key };
|
|
8296
|
-
}
|
|
8297
|
-
}
|
|
8298
|
-
if (settingName === "SerperKey") {
|
|
8299
|
-
const key = toolApiKeys?.serper || process.env.SERPER_API_KEY;
|
|
8300
|
-
if (key) {
|
|
8301
|
-
return { settingValue: key };
|
|
8302
|
-
}
|
|
8303
|
-
}
|
|
8304
|
-
return null;
|
|
8305
|
-
}
|
|
8306
|
-
};
|
|
8307
8326
|
const dbAdapters = {
|
|
8308
8327
|
db: {
|
|
8309
8328
|
apiKeys: null,
|
|
8310
|
-
adminSettings:
|
|
8329
|
+
adminSettings: null
|
|
8311
8330
|
}
|
|
8312
8331
|
};
|
|
8313
|
-
const hasSerperKey = !!(toolApiKeys?.serper || process.env.SERPER_API_KEY);
|
|
8314
|
-
const hasOpenWeatherKey = !!(toolApiKeys?.openweather || process.env.OPENWEATHER_API_KEY);
|
|
8315
8332
|
const toolConfig = {
|
|
8316
|
-
//
|
|
8333
|
+
// Local-only tools (no external API keys needed)
|
|
8317
8334
|
dice_roll: {},
|
|
8318
8335
|
math_evaluate: {},
|
|
8319
8336
|
current_datetime: {},
|
|
8320
8337
|
prompt_enhancement: {},
|
|
8321
|
-
// File operation tools (CLI-specific)
|
|
8338
|
+
// File operation tools (CLI-specific, local execution)
|
|
8322
8339
|
file_read: {},
|
|
8323
8340
|
create_file: {},
|
|
8324
8341
|
glob_files: {},
|
|
8325
8342
|
grep_search: {},
|
|
8326
|
-
delete_file: {}
|
|
8327
|
-
//
|
|
8328
|
-
|
|
8329
|
-
//
|
|
8330
|
-
...hasOpenWeatherKey && { weather_info: {} },
|
|
8331
|
-
// Requires OPENWEATHER_API_KEY
|
|
8332
|
-
...hasSerperKey && { deep_research: {} }
|
|
8333
|
-
// Requires SERPER_API_KEY
|
|
8343
|
+
delete_file: {}
|
|
8344
|
+
// REMOVED: weather_info, web_search, deep_research
|
|
8345
|
+
// These are now provided by B4M MCP server (b4m-tools)
|
|
8346
|
+
// They execute server-side using B4M company API keys
|
|
8334
8347
|
// Disable web-only tools
|
|
8335
8348
|
// blog_publish: undefined,
|
|
8336
8349
|
// blog_edit: undefined,
|
|
@@ -8790,16 +8803,14 @@ var MCPClient = class {
|
|
|
8790
8803
|
mcp;
|
|
8791
8804
|
transport = null;
|
|
8792
8805
|
envVariables;
|
|
8793
|
-
|
|
8794
|
-
customArgs;
|
|
8806
|
+
customScriptPath;
|
|
8795
8807
|
tools = [];
|
|
8796
8808
|
serverName;
|
|
8797
|
-
constructor({ envVariables, name, selectedRepositories,
|
|
8809
|
+
constructor({ envVariables, name, selectedRepositories, customScriptPath }) {
|
|
8798
8810
|
this.mcp = new Client2({ name: "mcp-client-cli", version: "1.0.0" });
|
|
8799
8811
|
this.envVariables = [...envVariables];
|
|
8800
8812
|
this.serverName = name;
|
|
8801
|
-
this.
|
|
8802
|
-
this.customArgs = args;
|
|
8813
|
+
this.customScriptPath = customScriptPath;
|
|
8803
8814
|
if (name === "github" && selectedRepositories) {
|
|
8804
8815
|
const reposJson = JSON.stringify(selectedRepositories);
|
|
8805
8816
|
this.envVariables.push({
|
|
@@ -8810,16 +8821,12 @@ var MCPClient = class {
|
|
|
8810
8821
|
}
|
|
8811
8822
|
async connectToServer() {
|
|
8812
8823
|
try {
|
|
8813
|
-
|
|
8814
|
-
|
|
8815
|
-
|
|
8816
|
-
|
|
8817
|
-
|
|
8818
|
-
|
|
8819
|
-
if (this.customCommand && this.customCommand.trim() !== "") {
|
|
8820
|
-
command = this.customCommand;
|
|
8821
|
-
args = this.customArgs ?? [];
|
|
8822
|
-
console.log(`[MCP] Using external command for ${this.serverName}: ${command} ${args.join(" ")}`);
|
|
8824
|
+
let serverScriptPath;
|
|
8825
|
+
if (this.customScriptPath) {
|
|
8826
|
+
if (!existsSync6(this.customScriptPath)) {
|
|
8827
|
+
throw new Error(`Custom MCP server script not found at: ${this.customScriptPath}`);
|
|
8828
|
+
}
|
|
8829
|
+
serverScriptPath = this.customScriptPath;
|
|
8823
8830
|
} else {
|
|
8824
8831
|
const root = process.env.INIT_CWD || process.cwd();
|
|
8825
8832
|
const candidatePaths = [
|
|
@@ -8835,23 +8842,25 @@ var MCPClient = class {
|
|
|
8835
8842
|
path12.join(root, `/b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
8836
8843
|
path12.join(root, "core", "mcp", "servers", this.serverName, "dist", "index.js")
|
|
8837
8844
|
];
|
|
8838
|
-
const
|
|
8839
|
-
if (!
|
|
8845
|
+
const foundPath = candidatePaths.find((p) => existsSync6(p));
|
|
8846
|
+
if (!foundPath) {
|
|
8840
8847
|
const getDirectories = (source) => readdirSync3(source, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
8841
8848
|
console.error(`[MCP] Server script not found. Tried paths:`, candidatePaths);
|
|
8842
8849
|
console.error(`[MCP] Available directories in ${root}:`, getDirectories(root));
|
|
8843
8850
|
throw new Error(`MCP Server script path not found for ${this.serverName}. Root: ${root}, Available dirs: ${getDirectories(root).join(", ")}`);
|
|
8844
8851
|
}
|
|
8845
|
-
|
|
8846
|
-
args = [serverScriptPath];
|
|
8847
|
-
console.log(`[MCP] Using server: ${this.serverName} at ${serverScriptPath}`);
|
|
8852
|
+
serverScriptPath = foundPath;
|
|
8848
8853
|
}
|
|
8854
|
+
console.log(`[MCP] Using server: ${this.serverName} at ${serverScriptPath}`);
|
|
8849
8855
|
this.transport = new StdioClientTransport({
|
|
8850
|
-
command,
|
|
8851
|
-
args,
|
|
8856
|
+
command: process.execPath,
|
|
8857
|
+
args: [serverScriptPath],
|
|
8852
8858
|
env: {
|
|
8853
|
-
...
|
|
8854
|
-
...
|
|
8859
|
+
...process.env,
|
|
8860
|
+
...this.envVariables.reduce((acc, env) => ({
|
|
8861
|
+
...acc,
|
|
8862
|
+
[env.key]: env.value
|
|
8863
|
+
}), {})
|
|
8855
8864
|
}
|
|
8856
8865
|
});
|
|
8857
8866
|
this.transport.onerror = (error) => {
|
|
@@ -8922,6 +8931,20 @@ var MCPClient = class {
|
|
|
8922
8931
|
};
|
|
8923
8932
|
|
|
8924
8933
|
// src/utils/mcpAdapter.ts
|
|
8934
|
+
import path13 from "path";
|
|
8935
|
+
import { fileURLToPath } from "url";
|
|
8936
|
+
var getCliPackageRoot2 = () => {
|
|
8937
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
8938
|
+
const currentDir = path13.dirname(currentFile);
|
|
8939
|
+
if (currentDir.includes("/dist")) {
|
|
8940
|
+
return path13.resolve(currentDir, "..");
|
|
8941
|
+
}
|
|
8942
|
+
if (currentDir.includes("/src")) {
|
|
8943
|
+
const srcIndex = currentDir.lastIndexOf("/src");
|
|
8944
|
+
return currentDir.substring(0, srcIndex);
|
|
8945
|
+
}
|
|
8946
|
+
return process.cwd();
|
|
8947
|
+
};
|
|
8925
8948
|
var McpManager = class {
|
|
8926
8949
|
constructor(config) {
|
|
8927
8950
|
this.servers = /* @__PURE__ */ new Map();
|
|
@@ -8957,11 +8980,16 @@ var McpManager = class {
|
|
|
8957
8980
|
key,
|
|
8958
8981
|
value
|
|
8959
8982
|
}));
|
|
8983
|
+
let scriptPath = serverConfig.args?.[0];
|
|
8984
|
+
if (scriptPath && !path13.isAbsolute(scriptPath)) {
|
|
8985
|
+
scriptPath = path13.join(getCliPackageRoot2(), scriptPath);
|
|
8986
|
+
logger.debug(`Resolved MCP script path: ${scriptPath}`);
|
|
8987
|
+
}
|
|
8960
8988
|
const client = new MCPClient({
|
|
8961
8989
|
envVariables,
|
|
8962
8990
|
name: serverConfig.name,
|
|
8963
|
-
|
|
8964
|
-
|
|
8991
|
+
// Pass custom script path for bundled servers like b4m-tools
|
|
8992
|
+
customScriptPath: scriptPath
|
|
8965
8993
|
});
|
|
8966
8994
|
await client.connectToServer();
|
|
8967
8995
|
const mcpData = {
|
|
@@ -9419,7 +9447,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
|
|
|
9419
9447
|
// package.json
|
|
9420
9448
|
var package_default = {
|
|
9421
9449
|
name: "@bike4mind/cli",
|
|
9422
|
-
version: "0.2.5-feat-
|
|
9450
|
+
version: "0.2.5-feat-server-side-tool-execution.17096+d6b936a82",
|
|
9423
9451
|
type: "module",
|
|
9424
9452
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
9425
9453
|
license: "UNLICENSED",
|
|
@@ -9452,6 +9480,7 @@ var package_default = {
|
|
|
9452
9480
|
scripts: {
|
|
9453
9481
|
dev: "tsx src/index.tsx",
|
|
9454
9482
|
build: "tsup",
|
|
9483
|
+
postbuild: "node scripts/bundle-mcp-proxy.mjs",
|
|
9455
9484
|
typecheck: "tsc --noEmit",
|
|
9456
9485
|
test: "vitest run",
|
|
9457
9486
|
"test:watch": "vitest",
|
|
@@ -9521,10 +9550,11 @@ var package_default = {
|
|
|
9521
9550
|
},
|
|
9522
9551
|
devDependencies: {
|
|
9523
9552
|
"@bike4mind/agents": "0.1.0",
|
|
9524
|
-
"@bike4mind/common": "2.37.1-feat-
|
|
9525
|
-
"@bike4mind/mcp": "1.19.6-feat-
|
|
9526
|
-
"@bike4mind/
|
|
9527
|
-
"@bike4mind/
|
|
9553
|
+
"@bike4mind/common": "2.37.1-feat-server-side-tool-execution.17096+d6b936a82",
|
|
9554
|
+
"@bike4mind/mcp": "1.19.6-feat-server-side-tool-execution.17096+d6b936a82",
|
|
9555
|
+
"@bike4mind/mcp-server-b4m-proxy": "1.0.1-feat-server-side-tool-execution.17096+d6b936a82",
|
|
9556
|
+
"@bike4mind/services": "2.32.2-feat-server-side-tool-execution.17096+d6b936a82",
|
|
9557
|
+
"@bike4mind/utils": "2.1.1-feat-server-side-tool-execution.17096+d6b936a82",
|
|
9528
9558
|
"@types/diff": "^5.0.9",
|
|
9529
9559
|
"@types/jsonwebtoken": "^9.0.4",
|
|
9530
9560
|
"@types/node": "^22.9.0",
|
|
@@ -9536,7 +9566,7 @@ var package_default = {
|
|
|
9536
9566
|
typescript: "^5.9.3",
|
|
9537
9567
|
vitest: "^3.2.4"
|
|
9538
9568
|
},
|
|
9539
|
-
gitHead: "
|
|
9569
|
+
gitHead: "d6b936a82aed081ee4ef534a0e5260bc9fbe5714"
|
|
9540
9570
|
};
|
|
9541
9571
|
|
|
9542
9572
|
// src/config/constants.ts
|
|
@@ -9643,6 +9673,7 @@ function CliApp() {
|
|
|
9643
9673
|
isAuthenticated = true;
|
|
9644
9674
|
const daysUntilExpiry = Math.floor((expiresAt.getTime() - Date.now()) / (1e3 * 60 * 60 * 24));
|
|
9645
9675
|
console.log(`\u2705 Authenticated (expires in ${daysUntilExpiry} day${daysUntilExpiry !== 1 ? "s" : ""})`);
|
|
9676
|
+
await state.configStore.ensureB4mMcpServer();
|
|
9646
9677
|
}
|
|
9647
9678
|
}
|
|
9648
9679
|
if (!isAuthenticated) {
|
|
@@ -9740,10 +9771,6 @@ function CliApp() {
|
|
|
9740
9771
|
setPermissionPrompt(prompt);
|
|
9741
9772
|
});
|
|
9742
9773
|
};
|
|
9743
|
-
console.log("\u{1F511} Tool API Keys:", {
|
|
9744
|
-
openweather: config.toolApiKeys?.openweather ? "\u2713 configured" : "\u2717 missing",
|
|
9745
|
-
serper: config.toolApiKeys?.serper ? "\u2713 configured" : "\u2717 missing"
|
|
9746
|
-
});
|
|
9747
9774
|
const agentContext = {
|
|
9748
9775
|
currentAgent: null,
|
|
9749
9776
|
observationQueue: []
|
|
@@ -9754,18 +9781,35 @@ function CliApp() {
|
|
|
9754
9781
|
modelInfo.id,
|
|
9755
9782
|
permissionManager,
|
|
9756
9783
|
promptFn,
|
|
9757
|
-
agentContext
|
|
9758
|
-
config.toolApiKeys
|
|
9784
|
+
agentContext
|
|
9759
9785
|
);
|
|
9760
|
-
console.log(`\u{1F6E0}\uFE0F Loaded ${b4mTools.length}
|
|
9761
|
-
|
|
9762
|
-
|
|
9763
|
-
|
|
9764
|
-
|
|
9765
|
-
|
|
9766
|
-
|
|
9767
|
-
|
|
9768
|
-
|
|
9786
|
+
console.log(`\u{1F6E0}\uFE0F Loaded ${b4mTools.length} local tool(s)`);
|
|
9787
|
+
let mcpManager = null;
|
|
9788
|
+
let mcpTools = [];
|
|
9789
|
+
try {
|
|
9790
|
+
mcpManager = new McpManager(config);
|
|
9791
|
+
await mcpManager.initialize();
|
|
9792
|
+
mcpTools = mcpManager.getTools();
|
|
9793
|
+
if (mcpTools.length > 0) {
|
|
9794
|
+
const toolCounts = mcpManager.getToolCount();
|
|
9795
|
+
toolCounts.forEach(({ serverName, count }) => {
|
|
9796
|
+
console.log(` \u{1F4E1} ${serverName}: ${count} tool(s)`);
|
|
9797
|
+
});
|
|
9798
|
+
}
|
|
9799
|
+
const hasB4mServer = mcpManager.getServerNames().includes("b4m-tools");
|
|
9800
|
+
if (hasB4mServer) {
|
|
9801
|
+
console.log("\u{1F310} B4M server tools available (weather, web search)");
|
|
9802
|
+
} else if (!authTokens) {
|
|
9803
|
+
console.log("\u2139\uFE0F Weather and search tools require authentication");
|
|
9804
|
+
console.log(" Run /login to enable B4M server tools");
|
|
9805
|
+
}
|
|
9806
|
+
} catch (error) {
|
|
9807
|
+
console.log("\u26A0\uFE0F MCP server initialization failed - continuing with local tools only");
|
|
9808
|
+
if (error instanceof Error) {
|
|
9809
|
+
console.log(` Error: ${error.message}`);
|
|
9810
|
+
}
|
|
9811
|
+
mcpManager = null;
|
|
9812
|
+
mcpTools = [];
|
|
9769
9813
|
}
|
|
9770
9814
|
const allTools = [...b4mTools, ...mcpTools];
|
|
9771
9815
|
console.log(`\u2705 Total: ${allTools.length} tool(s) available`);
|
|
@@ -10229,9 +10273,10 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
10229
10273
|
{
|
|
10230
10274
|
apiUrl: loginApiUrl,
|
|
10231
10275
|
configStore: state.configStore,
|
|
10232
|
-
onSuccess: () => {
|
|
10276
|
+
onSuccess: async () => {
|
|
10233
10277
|
setState((prev) => ({ ...prev, showLoginFlow: false }));
|
|
10234
10278
|
console.log("\n\u2705 Login successful! Initializing CLI...\n");
|
|
10279
|
+
await state.configStore.ensureB4mMcpServer();
|
|
10235
10280
|
init().catch((err) => {
|
|
10236
10281
|
console.error("\n\u274C Initialization failed:", err.message, "\n");
|
|
10237
10282
|
exit();
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for communicating with B4M backend API
|
|
3
|
+
* Handles authentication, request/response formatting, and error handling
|
|
4
|
+
*/
|
|
5
|
+
export interface ToolExecuteRequest {
|
|
6
|
+
tool: string;
|
|
7
|
+
params: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
export interface ToolExecuteResponse {
|
|
10
|
+
success: boolean;
|
|
11
|
+
data?: unknown;
|
|
12
|
+
error?: {
|
|
13
|
+
code: string;
|
|
14
|
+
message: string;
|
|
15
|
+
details?: Record<string, unknown>;
|
|
16
|
+
};
|
|
17
|
+
metadata?: {
|
|
18
|
+
executionTime: number;
|
|
19
|
+
tool: string;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export interface ClientConfig {
|
|
23
|
+
/** Base URL for B4M API (e.g., https://api.bike4mind.com or http://localhost:3000) */
|
|
24
|
+
apiUrl: string;
|
|
25
|
+
/** JWT authentication token */
|
|
26
|
+
authToken: string;
|
|
27
|
+
/** Request timeout in milliseconds */
|
|
28
|
+
timeout?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Client for executing tools via B4M backend API
|
|
32
|
+
*/
|
|
33
|
+
export declare class B4MApiClient {
|
|
34
|
+
private readonly apiUrl;
|
|
35
|
+
private readonly authToken;
|
|
36
|
+
private readonly timeout;
|
|
37
|
+
constructor(config: ClientConfig);
|
|
38
|
+
/**
|
|
39
|
+
* Execute a tool via the backend API
|
|
40
|
+
*/
|
|
41
|
+
executeTool(tool: string, params: Record<string, unknown>): Promise<ToolExecuteResponse>;
|
|
42
|
+
/**
|
|
43
|
+
* Test connection to backend API
|
|
44
|
+
*/
|
|
45
|
+
testConnection(): Promise<boolean>;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACnC,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,aAAa,EAAE,MAAM,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,sFAAsF;IACtF,MAAM,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,MAAM,EAAE,YAAY;IAMhC;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAgG9F;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;CAezC"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for communicating with B4M backend API
|
|
3
|
+
* Handles authentication, request/response formatting, and error handling
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Client for executing tools via B4M backend API
|
|
7
|
+
*/
|
|
8
|
+
export class B4MApiClient {
|
|
9
|
+
apiUrl;
|
|
10
|
+
authToken;
|
|
11
|
+
timeout;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.apiUrl = config.apiUrl.replace(/\/$/, ''); // Remove trailing slash
|
|
14
|
+
this.authToken = config.authToken;
|
|
15
|
+
this.timeout = config.timeout || 30000; // 30s default
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Execute a tool via the backend API
|
|
19
|
+
*/
|
|
20
|
+
async executeTool(tool, params) {
|
|
21
|
+
const url = `${this.apiUrl}/api/tools/execute`;
|
|
22
|
+
const requestBody = {
|
|
23
|
+
tool,
|
|
24
|
+
params,
|
|
25
|
+
};
|
|
26
|
+
try {
|
|
27
|
+
// Create abort controller for timeout
|
|
28
|
+
const controller = new AbortController();
|
|
29
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
30
|
+
const response = await fetch(url, {
|
|
31
|
+
method: 'POST',
|
|
32
|
+
headers: {
|
|
33
|
+
'Content-Type': 'application/json',
|
|
34
|
+
Authorization: `Bearer ${this.authToken}`,
|
|
35
|
+
'User-Agent': 'B4M-MCP-Proxy/1.0',
|
|
36
|
+
},
|
|
37
|
+
body: JSON.stringify(requestBody),
|
|
38
|
+
signal: controller.signal,
|
|
39
|
+
});
|
|
40
|
+
clearTimeout(timeoutId);
|
|
41
|
+
// Parse response
|
|
42
|
+
const data = (await response.json());
|
|
43
|
+
// Check for HTTP errors
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
// Handle authentication errors with helpful message
|
|
46
|
+
if (response.status === 401) {
|
|
47
|
+
return {
|
|
48
|
+
success: false,
|
|
49
|
+
error: {
|
|
50
|
+
code: 'AUTHENTICATION_REQUIRED',
|
|
51
|
+
message: 'Authentication required. Please run /login in the CLI to authenticate with your B4M account.',
|
|
52
|
+
details: data.error?.details,
|
|
53
|
+
},
|
|
54
|
+
metadata: data.metadata,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
success: false,
|
|
59
|
+
error: {
|
|
60
|
+
code: data.error?.code || 'HTTP_ERROR',
|
|
61
|
+
message: data.error?.message || `HTTP ${response.status}: ${response.statusText}`,
|
|
62
|
+
details: data.error?.details,
|
|
63
|
+
},
|
|
64
|
+
metadata: data.metadata,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return data;
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
// Handle timeout
|
|
71
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
72
|
+
return {
|
|
73
|
+
success: false,
|
|
74
|
+
error: {
|
|
75
|
+
code: 'TIMEOUT',
|
|
76
|
+
message: `Request timeout after ${this.timeout}ms`,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
// Handle network errors
|
|
81
|
+
if (error instanceof TypeError) {
|
|
82
|
+
return {
|
|
83
|
+
success: false,
|
|
84
|
+
error: {
|
|
85
|
+
code: 'NETWORK_ERROR',
|
|
86
|
+
message: 'Failed to connect to B4M API',
|
|
87
|
+
details: {
|
|
88
|
+
error: error.message,
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
// Unknown error
|
|
94
|
+
return {
|
|
95
|
+
success: false,
|
|
96
|
+
error: {
|
|
97
|
+
code: 'UNKNOWN_ERROR',
|
|
98
|
+
message: error instanceof Error ? error.message : 'An unknown error occurred',
|
|
99
|
+
details: {
|
|
100
|
+
error: String(error),
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Test connection to backend API
|
|
108
|
+
*/
|
|
109
|
+
async testConnection() {
|
|
110
|
+
try {
|
|
111
|
+
const controller = new AbortController();
|
|
112
|
+
const timeoutId = setTimeout(() => controller.abort(), 5000);
|
|
113
|
+
const response = await fetch(`${this.apiUrl}/api/health`, {
|
|
114
|
+
signal: controller.signal,
|
|
115
|
+
});
|
|
116
|
+
clearTimeout(timeoutId);
|
|
117
|
+
return response.ok;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* B4M MCP Proxy Server
|
|
4
|
+
*
|
|
5
|
+
* This MCP server acts as a proxy between Claude CLI and B4M backend API.
|
|
6
|
+
* It executes tools server-side using B4M company API keys, ensuring
|
|
7
|
+
* keys are never exposed to clients.
|
|
8
|
+
*
|
|
9
|
+
* Environment Variables:
|
|
10
|
+
* - B4M_API_URL: Base URL for B4M API (default: https://api.bike4mind.com)
|
|
11
|
+
* - B4M_AUTH_TOKEN: JWT authentication token (required)
|
|
12
|
+
* - B4M_TIMEOUT: Request timeout in milliseconds (default: 30000)
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* node dist/index.js
|
|
16
|
+
*
|
|
17
|
+
* MCP Configuration (claude_desktop_config.json):
|
|
18
|
+
* {
|
|
19
|
+
* "mcpServers": {
|
|
20
|
+
* "b4m-tools": {
|
|
21
|
+
* "command": "node",
|
|
22
|
+
* "args": ["/path/to/mcp-server-b4m-proxy/dist/index.js"],
|
|
23
|
+
* "env": {
|
|
24
|
+
* "B4M_API_URL": "https://api.bike4mind.com",
|
|
25
|
+
* "B4M_AUTH_TOKEN": "your-jwt-token"
|
|
26
|
+
* }
|
|
27
|
+
* }
|
|
28
|
+
* }
|
|
29
|
+
* }
|
|
30
|
+
*/
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* B4M MCP Proxy Server
|
|
4
|
+
*
|
|
5
|
+
* This MCP server acts as a proxy between Claude CLI and B4M backend API.
|
|
6
|
+
* It executes tools server-side using B4M company API keys, ensuring
|
|
7
|
+
* keys are never exposed to clients.
|
|
8
|
+
*
|
|
9
|
+
* Environment Variables:
|
|
10
|
+
* - B4M_API_URL: Base URL for B4M API (default: https://api.bike4mind.com)
|
|
11
|
+
* - B4M_AUTH_TOKEN: JWT authentication token (required)
|
|
12
|
+
* - B4M_TIMEOUT: Request timeout in milliseconds (default: 30000)
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* node dist/index.js
|
|
16
|
+
*
|
|
17
|
+
* MCP Configuration (claude_desktop_config.json):
|
|
18
|
+
* {
|
|
19
|
+
* "mcpServers": {
|
|
20
|
+
* "b4m-tools": {
|
|
21
|
+
* "command": "node",
|
|
22
|
+
* "args": ["/path/to/mcp-server-b4m-proxy/dist/index.js"],
|
|
23
|
+
* "env": {
|
|
24
|
+
* "B4M_API_URL": "https://api.bike4mind.com",
|
|
25
|
+
* "B4M_AUTH_TOKEN": "your-jwt-token"
|
|
26
|
+
* }
|
|
27
|
+
* }
|
|
28
|
+
* }
|
|
29
|
+
* }
|
|
30
|
+
*/
|
|
31
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
32
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
33
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, McpError, ErrorCode, } from '@modelcontextprotocol/sdk/types.js';
|
|
34
|
+
import { B4MApiClient } from './client.js';
|
|
35
|
+
// Configuration from environment
|
|
36
|
+
const API_URL = process.env.B4M_API_URL || 'https://api.bike4mind.com';
|
|
37
|
+
const AUTH_TOKEN = process.env.B4M_AUTH_TOKEN || '';
|
|
38
|
+
const TIMEOUT = parseInt(process.env.B4M_TIMEOUT || '30000', 10);
|
|
39
|
+
// Warn if no authentication token (but allow server to start)
|
|
40
|
+
// The wrapper script (b4m-mcp-proxy.mjs) already logs a user-friendly warning
|
|
41
|
+
if (!AUTH_TOKEN) {
|
|
42
|
+
console.error('Warning: B4M_AUTH_TOKEN not set - tools will fail until authenticated');
|
|
43
|
+
}
|
|
44
|
+
// Initialize API client
|
|
45
|
+
const client = new B4MApiClient({
|
|
46
|
+
apiUrl: API_URL,
|
|
47
|
+
authToken: AUTH_TOKEN,
|
|
48
|
+
timeout: TIMEOUT,
|
|
49
|
+
});
|
|
50
|
+
/**
|
|
51
|
+
* Tool definitions for MCP
|
|
52
|
+
* These match the tools available in the backend
|
|
53
|
+
*/
|
|
54
|
+
const TOOLS = [
|
|
55
|
+
{
|
|
56
|
+
name: 'weather',
|
|
57
|
+
description: 'Get current weather information for any location worldwide. Returns temperature, conditions, humidity, wind speed, and more.',
|
|
58
|
+
inputSchema: {
|
|
59
|
+
type: 'object',
|
|
60
|
+
properties: {
|
|
61
|
+
location: {
|
|
62
|
+
type: 'string',
|
|
63
|
+
description: 'City name, state, and/or country (e.g., "San Francisco, CA" or "London, UK")',
|
|
64
|
+
},
|
|
65
|
+
units: {
|
|
66
|
+
type: 'string',
|
|
67
|
+
enum: ['metric', 'imperial', 'standard'],
|
|
68
|
+
description: 'Temperature units (metric = Celsius, imperial = Fahrenheit, standard = Kelvin)',
|
|
69
|
+
default: 'metric',
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
required: ['location'],
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: 'serper',
|
|
77
|
+
description: 'Search the web using Google via SerpAPI. Returns organic search results with titles, links, and snippets.',
|
|
78
|
+
inputSchema: {
|
|
79
|
+
type: 'object',
|
|
80
|
+
properties: {
|
|
81
|
+
query: {
|
|
82
|
+
type: 'string',
|
|
83
|
+
description: 'Search query to execute',
|
|
84
|
+
},
|
|
85
|
+
num_results: {
|
|
86
|
+
type: 'number',
|
|
87
|
+
description: 'Number of results to return (1-10, default: 3)',
|
|
88
|
+
minimum: 1,
|
|
89
|
+
maximum: 10,
|
|
90
|
+
default: 3,
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
required: ['query'],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
/**
|
|
98
|
+
* Create and configure MCP server
|
|
99
|
+
*/
|
|
100
|
+
const server = new Server({
|
|
101
|
+
name: 'b4m-tools',
|
|
102
|
+
version: '1.0.0',
|
|
103
|
+
}, {
|
|
104
|
+
capabilities: {
|
|
105
|
+
tools: {},
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
/**
|
|
109
|
+
* Handle tool list requests
|
|
110
|
+
*/
|
|
111
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
112
|
+
return {
|
|
113
|
+
tools: TOOLS,
|
|
114
|
+
};
|
|
115
|
+
});
|
|
116
|
+
/**
|
|
117
|
+
* Handle tool execution requests
|
|
118
|
+
*/
|
|
119
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
120
|
+
const { name: toolName, arguments: toolArgs } = request.params;
|
|
121
|
+
try {
|
|
122
|
+
// Validate tool exists
|
|
123
|
+
const tool = TOOLS.find(t => t.name === toolName);
|
|
124
|
+
if (!tool) {
|
|
125
|
+
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${toolName}`);
|
|
126
|
+
}
|
|
127
|
+
// Execute tool via backend API
|
|
128
|
+
const result = await client.executeTool(toolName, toolArgs || {});
|
|
129
|
+
// Handle backend errors
|
|
130
|
+
if (!result.success) {
|
|
131
|
+
throw new McpError(ErrorCode.InternalError, result.error?.message || 'Tool execution failed', result.error?.details);
|
|
132
|
+
}
|
|
133
|
+
// Return successful result
|
|
134
|
+
return {
|
|
135
|
+
content: [
|
|
136
|
+
{
|
|
137
|
+
type: 'text',
|
|
138
|
+
text: JSON.stringify(result.data, null, 2),
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
// Re-throw McpErrors
|
|
145
|
+
if (error instanceof McpError) {
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
// Wrap other errors
|
|
149
|
+
throw new McpError(ErrorCode.InternalError, error instanceof Error ? error.message : 'Unknown error occurred', {
|
|
150
|
+
error: String(error),
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
/**
|
|
155
|
+
* Start the MCP server
|
|
156
|
+
*/
|
|
157
|
+
async function main() {
|
|
158
|
+
// Test connection to backend
|
|
159
|
+
const isConnected = await client.testConnection();
|
|
160
|
+
if (!isConnected) {
|
|
161
|
+
console.error(`Warning: Could not connect to backend API at ${API_URL}`);
|
|
162
|
+
console.error('Server will start but tool execution may fail.');
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
console.error(`Connected to B4M API at ${API_URL}`);
|
|
166
|
+
}
|
|
167
|
+
// Start stdio transport
|
|
168
|
+
const transport = new StdioServerTransport();
|
|
169
|
+
await server.connect(transport);
|
|
170
|
+
console.error('B4M MCP Proxy Server running on stdio');
|
|
171
|
+
console.error(`Available tools: ${TOOLS.map(t => t.name).join(', ')}`);
|
|
172
|
+
}
|
|
173
|
+
// Handle errors
|
|
174
|
+
process.on('uncaughtException', error => {
|
|
175
|
+
console.error('Uncaught exception:', error);
|
|
176
|
+
process.exit(1);
|
|
177
|
+
});
|
|
178
|
+
process.on('unhandledRejection', reason => {
|
|
179
|
+
console.error('Unhandled rejection:', reason);
|
|
180
|
+
process.exit(1);
|
|
181
|
+
});
|
|
182
|
+
// Start server
|
|
183
|
+
main().catch(error => {
|
|
184
|
+
console.error('Failed to start server:', error);
|
|
185
|
+
process.exit(1);
|
|
186
|
+
});
|
|
187
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bike4mind/cli",
|
|
3
|
-
"version": "0.2.5-feat-
|
|
3
|
+
"version": "0.2.5-feat-server-side-tool-execution.17096+d6b936a82",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"scripts": {
|
|
34
34
|
"dev": "tsx src/index.tsx",
|
|
35
35
|
"build": "tsup",
|
|
36
|
+
"postbuild": "node scripts/bundle-mcp-proxy.mjs",
|
|
36
37
|
"typecheck": "tsc --noEmit",
|
|
37
38
|
"test": "vitest run",
|
|
38
39
|
"test:watch": "vitest",
|
|
@@ -102,10 +103,11 @@
|
|
|
102
103
|
},
|
|
103
104
|
"devDependencies": {
|
|
104
105
|
"@bike4mind/agents": "0.1.0",
|
|
105
|
-
"@bike4mind/common": "2.37.1-feat-
|
|
106
|
-
"@bike4mind/mcp": "1.19.6-feat-
|
|
107
|
-
"@bike4mind/
|
|
108
|
-
"@bike4mind/
|
|
106
|
+
"@bike4mind/common": "2.37.1-feat-server-side-tool-execution.17096+d6b936a82",
|
|
107
|
+
"@bike4mind/mcp": "1.19.6-feat-server-side-tool-execution.17096+d6b936a82",
|
|
108
|
+
"@bike4mind/mcp-server-b4m-proxy": "1.0.1-feat-server-side-tool-execution.17096+d6b936a82",
|
|
109
|
+
"@bike4mind/services": "2.32.2-feat-server-side-tool-execution.17096+d6b936a82",
|
|
110
|
+
"@bike4mind/utils": "2.1.1-feat-server-side-tool-execution.17096+d6b936a82",
|
|
109
111
|
"@types/diff": "^5.0.9",
|
|
110
112
|
"@types/jsonwebtoken": "^9.0.4",
|
|
111
113
|
"@types/node": "^22.9.0",
|
|
@@ -117,5 +119,5 @@
|
|
|
117
119
|
"typescript": "^5.9.3",
|
|
118
120
|
"vitest": "^3.2.4"
|
|
119
121
|
},
|
|
120
|
-
"gitHead": "
|
|
122
|
+
"gitHead": "d6b936a82aed081ee4ef534a0e5260bc9fbe5714"
|
|
121
123
|
}
|