@aiwerk/mcp-bridge 2.1.1 → 2.1.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiwerk/mcp-bridge",
3
- "version": "2.1.1",
3
+ "version": "2.1.2",
4
4
  "description": "Standalone MCP server that multiplexes multiple MCP servers into one interface",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -2,9 +2,27 @@
2
2
  set -e
3
3
 
4
4
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
- MCP_BRIDGE_DIR="${HOME}/.mcp-bridge"
6
- MCP_BRIDGE_JSON="${MCP_BRIDGE_DIR}/config.json"
7
- ENV_FILE="${MCP_BRIDGE_DIR}/.env"
5
+
6
+ # Detect OpenClaw plugin or standalone mode
7
+ OPENCLAW_JSON="${HOME}/.openclaw/openclaw.json"
8
+ OPENCLAW_PLUGIN_DIR="${HOME}/.openclaw/extensions/openclaw-mcp-bridge"
9
+ if [[ -f "$OPENCLAW_JSON" ]] && python3 -c "
10
+ import json
11
+ with open('$OPENCLAW_JSON') as f:
12
+ c = json.load(f)
13
+ assert 'openclaw-mcp-bridge' in c.get('plugins',{}).get('entries',{})
14
+ " 2>/dev/null; then
15
+ CONFIG_MODE="openclaw"
16
+ MCP_BRIDGE_DIR="$OPENCLAW_PLUGIN_DIR"
17
+ MCP_BRIDGE_JSON="$OPENCLAW_JSON"
18
+ ENV_FILE="${HOME}/.openclaw/.env"
19
+ echo "[mcp-bridge] Detected OpenClaw plugin mode"
20
+ else
21
+ CONFIG_MODE="standalone"
22
+ MCP_BRIDGE_DIR="${HOME}/.mcp-bridge"
23
+ MCP_BRIDGE_JSON="${MCP_BRIDGE_DIR}/config.json"
24
+ ENV_FILE="${MCP_BRIDGE_DIR}/.env"
25
+ fi
8
26
 
9
27
  usage() {
10
28
  echo "Usage: $0 <server-name> [--dry-run] [--remove]"
@@ -160,11 +178,15 @@ if [[ "$REMOVE" == "true" ]]; then
160
178
  import json, sys
161
179
  server_name = sys.argv[1]
162
180
  config_path = sys.argv[2]
181
+ config_mode = sys.argv[3]
163
182
  with open(config_path) as f:
164
183
  cfg = json.load(f)
165
- servers = cfg.get('servers',{})
184
+ if config_mode == 'openclaw':
185
+ servers = cfg.get('plugins',{}).get('entries',{}).get('openclaw-mcp-bridge',{}).get('config',{}).get('servers',{})
186
+ else:
187
+ servers = cfg.get('servers',{})
166
188
  print('yes' if server_name in servers else 'no')
167
- " "$SERVER_NAME" "$MCP_BRIDGE_JSON" 2>/dev/null)
189
+ " "$SERVER_NAME" "$MCP_BRIDGE_JSON" "$CONFIG_MODE" 2>/dev/null)
168
190
 
169
191
  if [[ "$HAS_SERVER" != "yes" ]]; then
170
192
  echo "ℹ️ Server '$SERVER_NAME' not found in config. Nothing to remove."
@@ -181,16 +203,20 @@ print('yes' if server_name in servers else 'no')
181
203
  import json, sys
182
204
  server_name = sys.argv[1]
183
205
  config_path = sys.argv[2]
206
+ config_mode = sys.argv[3]
184
207
  with open(config_path) as f:
185
208
  cfg = json.load(f)
186
- servers = cfg.get('servers', {})
209
+ if config_mode == 'openclaw':
210
+ servers = cfg['plugins']['entries']['openclaw-mcp-bridge']['config']['servers']
211
+ else:
212
+ servers = cfg.get('servers', {})
187
213
  del servers[server_name]
188
214
  with open(config_path, 'w') as f:
189
215
  json.dump(cfg, f, indent=2)
190
216
  f.write('\n')
191
217
  print(f'✅ Removed {server_name} from config')
192
218
  print(f'ℹ️ Server recipe kept in servers/{server_name}/ (reinstall anytime)')
193
- " "$SERVER_NAME" "$MCP_BRIDGE_JSON" 2>/dev/null
219
+ " "$SERVER_NAME" "$MCP_BRIDGE_JSON" "$CONFIG_MODE" 2>/dev/null
194
220
 
195
221
  # Remove env var from .env if exists
196
222
  REMOVE_ENV_VAR=""
@@ -0,0 +1,82 @@
1
+ #!/bin/bash
2
+ # validate-recipes.sh — Verify all recipe.json URLs are reachable (no hallucinated repos!)
3
+ # Usage: ./scripts/validate-recipes.sh [--ci]
4
+ # Exit code 1 if any URL is broken.
5
+
6
+ set -uo pipefail
7
+
8
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
+ SERVERS_DIR="$SCRIPT_DIR/../servers"
10
+ CI_MODE="${1:-}"
11
+ ERRORS=0
12
+ CHECKED=0
13
+
14
+ RED='\033[0;31m'
15
+ GREEN='\033[0;32m'
16
+ NC='\033[0m'
17
+
18
+ echo "Validating recipe URLs..."
19
+ echo ""
20
+
21
+ for recipe in "$SERVERS_DIR"/*/recipe.json; do
22
+ server=$(basename "$(dirname "$recipe")")
23
+
24
+ # Extract all URLs from recipe.json
25
+ urls=$(python3 -c "
26
+ import json, sys
27
+ d = json.load(open('$recipe'))
28
+ urls = set()
29
+ if d.get('repository'): urls.add(d['repository'])
30
+ if d.get('install', {}).get('repository'): urls.add(d['install']['repository'])
31
+ if d.get('metadata', {}).get('homepage'): urls.add(d['metadata']['homepage'])
32
+ if d.get('auth', {}).get('credentialsUrl'): urls.add(d['auth']['credentialsUrl'])
33
+ for u in sorted(urls): print(u)
34
+ " 2>/dev/null)
35
+
36
+ # Cross-check git repos against install-server.sh
37
+ install_script="$SCRIPT_DIR/install-server.sh"
38
+ if [ -f "$install_script" ]; then
39
+ # Match server name in the clone context (e.g. "wise)" or "Cloning wise")
40
+ script_repo=$(grep -B1 -A0 -i "${server})" "$install_script" 2>/dev/null | grep -oP "git clone \Khttps://[^ ]+" | head -1 | sed 's/\.git$//')
41
+ recipe_repo=$(python3 -c "
42
+ import json
43
+ d = json.load(open('$recipe'))
44
+ r = d.get('install', {}).get('repository', d.get('repository', ''))
45
+ print(r.rstrip('/').removesuffix('.git'))
46
+ " 2>/dev/null)
47
+
48
+ if [ -n "$script_repo" ] && [ -n "$recipe_repo" ]; then
49
+ script_repo_clean=$(echo "$script_repo" | sed 's/\.git$//')
50
+ if [ "$recipe_repo" != "$script_repo_clean" ]; then
51
+ echo -e "${RED}❌ MISMATCH [$server]${NC}"
52
+ echo " recipe.json: $recipe_repo"
53
+ echo " install-server.sh: $script_repo_clean"
54
+ ERRORS=$((ERRORS + 1))
55
+ fi
56
+ fi
57
+ fi
58
+
59
+ # HTTP check all URLs
60
+ for url in $urls; do
61
+ CHECKED=$((CHECKED + 1))
62
+ status=$(curl -sI -o /dev/null -w "%{http_code}" --max-time 10 "$url" 2>/dev/null || echo "000")
63
+ # 401/403 are OK for credentialsUrl (login-protected pages)
64
+ if [ "$status" = "000" ] || [ "$status" -ge 404 ]; then
65
+ echo -e "${RED}❌ HTTP $status [$server] $url${NC}"
66
+ ERRORS=$((ERRORS + 1))
67
+ else
68
+ echo -e "${GREEN}✓${NC} [$server] $url"
69
+ fi
70
+ done
71
+ done
72
+
73
+ echo ""
74
+ echo "Checked $CHECKED URLs across $(ls -d "$SERVERS_DIR"/*/recipe.json 2>/dev/null | wc -l) recipes."
75
+
76
+ if [ $ERRORS -gt 0 ]; then
77
+ echo -e "${RED}$ERRORS error(s) found!${NC}"
78
+ exit 1
79
+ else
80
+ echo -e "${GREEN}All URLs valid.${NC}"
81
+ exit 0
82
+ fi
@@ -3,7 +3,7 @@
3
3
  "id": "hetzner",
4
4
  "name": "Hetzner Cloud",
5
5
  "description": "Manage Hetzner Cloud infrastructure — servers, networks, load balancers, volumes, firewalls, and more via the Hetzner Cloud API",
6
- "repository": "https://github.com/valerius21/hetzner-mcp",
6
+ "repository": "https://github.com/dkruyt/mcp-hetzner",
7
7
 
8
8
  "transports": [
9
9
  {
@@ -26,14 +26,14 @@
26
26
 
27
27
  "install": {
28
28
  "method": "git",
29
- "repository": "https://github.com/valerius21/hetzner-mcp",
29
+ "repository": "https://github.com/dkruyt/mcp-hetzner",
30
30
  "buildCommand": "npm install && npm run build",
31
31
  "version": "latest"
32
32
  },
33
33
 
34
34
  "metadata": {
35
35
  "homepage": "https://www.hetzner.com/cloud",
36
- "author": "valerius21",
36
+ "author": "dkruyt",
37
37
  "tags": ["cloud", "infrastructure", "servers", "vps", "hetzner"],
38
38
  "category": "infrastructure",
39
39
  "pricing": "byok",
@@ -3,7 +3,7 @@
3
3
  "id": "wise",
4
4
  "name": "Wise",
5
5
  "description": "International money transfers and multi-currency account management via the Wise (TransferWise) API",
6
- "repository": "https://github.com/kstam/wise-mcp",
6
+ "repository": "https://github.com/Szotasz/wise-mcp",
7
7
 
8
8
  "transports": [
9
9
  {
@@ -26,14 +26,14 @@
26
26
 
27
27
  "install": {
28
28
  "method": "git",
29
- "repository": "https://github.com/kstam/wise-mcp",
29
+ "repository": "https://github.com/Szotasz/wise-mcp",
30
30
  "buildCommand": "npm install && npm run build",
31
31
  "version": "latest"
32
32
  },
33
33
 
34
34
  "metadata": {
35
35
  "homepage": "https://wise.com/",
36
- "author": "kstam",
36
+ "author": "Szotasz",
37
37
  "tags": ["payments", "transfers", "international", "currency", "fintech"],
38
38
  "category": "finance",
39
39
  "pricing": "byok",