@aiwerk/mcp-bridge 1.7.1 → 1.8.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.
@@ -37,9 +37,19 @@ if [[ ! -d "$SERVER_DIR" ]]; then
37
37
  fi
38
38
 
39
39
  SERVER_TITLE="$(tr '-' ' ' <<<"$SERVER_NAME" | awk '{for(i=1;i<=NF;i++){$i=toupper(substr($i,1,1))substr($i,2)};print}')"
40
- SERVER_CONFIG_FILE="$SERVER_DIR/config.json"
41
40
  ENV_VARS_FILE="$SERVER_DIR/env_vars"
42
41
 
42
+ # Prefer recipe.json (v2) over config.json (v1) when both exist
43
+ RECIPE_FILE="$SERVER_DIR/recipe.json"
44
+ SERVER_CONFIG_FILE="$SERVER_DIR/config.json"
45
+ RECIPE_FORMAT="v1"
46
+ if [[ -f "$RECIPE_FILE" ]]; then
47
+ RECIPE_FORMAT="v2"
48
+ elif [[ ! -f "$SERVER_CONFIG_FILE" ]]; then
49
+ echo "Error: No recipe.json or config.json found in $SERVER_DIR"
50
+ exit 1
51
+ fi
52
+
43
53
  require_cmd() {
44
54
  if ! command -v "$1" >/dev/null 2>&1; then
45
55
  echo "❌ Missing required command: $1"
@@ -48,6 +58,18 @@ require_cmd() {
48
58
  }
49
59
 
50
60
  get_token_url() {
61
+ # For v2 recipes, prefer credentialsUrl from auth block
62
+ if [[ "$RECIPE_FORMAT" == "v2" ]]; then
63
+ local url
64
+ url=$(python3 -c "
65
+ import json, sys
66
+ with open(sys.argv[1]) as f:
67
+ r = json.load(f)
68
+ print(r.get('auth', {}).get('credentialsUrl', ''))
69
+ " "$RECIPE_FILE" 2>/dev/null)
70
+ [[ -n "$url" ]] && echo "$url" && return
71
+ fi
72
+ # v1 fallback: hardcoded URLs
51
73
  case "$SERVER_NAME" in
52
74
  apify) echo "https://console.apify.com/settings/integrations" ;;
53
75
  github) echo "https://github.com/settings/tokens" ;;
@@ -171,11 +193,22 @@ print(f'ℹ️ Server recipe kept in servers/{server_name}/ (reinstall anytime)
171
193
  " "$SERVER_NAME" "$MCP_BRIDGE_JSON" 2>/dev/null
172
194
 
173
195
  # Remove env var from .env if exists
174
- if [[ -f "$ENV_VARS_FILE" ]] && [[ -s "$ENV_VARS_FILE" ]] && [[ -f "$ENV_FILE" ]]; then
175
- ENV_VAR_NAME="$(head -n 1 "$ENV_VARS_FILE" | tr -d '[:space:]')"
176
- if grep -q "^${ENV_VAR_NAME}=" "$ENV_FILE" 2>/dev/null; then
177
- sed -i "/^${ENV_VAR_NAME}=/d" "$ENV_FILE"
178
- echo "🔑 Removed ${ENV_VAR_NAME} from ${ENV_FILE}"
196
+ REMOVE_ENV_VAR=""
197
+ if [[ "$RECIPE_FORMAT" == "v2" ]]; then
198
+ REMOVE_ENV_VAR=$(python3 -c "
199
+ import json, sys
200
+ with open(sys.argv[1]) as f:
201
+ r = json.load(f)
202
+ env_vars = r.get('auth', {}).get('envVars', [])
203
+ print(env_vars[0] if env_vars else '')
204
+ " "$RECIPE_FILE" 2>/dev/null)
205
+ elif [[ -f "$ENV_VARS_FILE" ]] && [[ -s "$ENV_VARS_FILE" ]]; then
206
+ REMOVE_ENV_VAR="$(head -n 1 "$ENV_VARS_FILE" | tr -d '[:space:]')"
207
+ fi
208
+ if [[ -n "$REMOVE_ENV_VAR" ]] && [[ -f "$ENV_FILE" ]]; then
209
+ if grep -q "^${REMOVE_ENV_VAR}=" "$ENV_FILE" 2>/dev/null; then
210
+ sed -i "/^${REMOVE_ENV_VAR}=/d" "$ENV_FILE"
211
+ echo "🔑 Removed ${REMOVE_ENV_VAR} from ${ENV_FILE}"
179
212
  fi
180
213
  fi
181
214
 
@@ -214,8 +247,20 @@ echo "========================================"
214
247
 
215
248
  if [[ "$DRY_RUN" == "true" ]]; then
216
249
  echo "[DRY RUN] Server: $SERVER_NAME"
217
- [[ -f "$ENV_VARS_FILE" ]] && echo "[DRY RUN] Env var: $(cat "$ENV_VARS_FILE")"
218
- echo "[DRY RUN] Config:"; cat "$SERVER_CONFIG_FILE"
250
+ echo "[DRY RUN] Recipe format: $RECIPE_FORMAT"
251
+ if [[ "$RECIPE_FORMAT" == "v2" ]]; then
252
+ ENV_VAR_LIST=$(python3 -c "
253
+ import json, sys
254
+ with open(sys.argv[1]) as f:
255
+ r = json.load(f)
256
+ print(', '.join(r.get('auth', {}).get('envVars', [])))
257
+ " "$RECIPE_FILE" 2>/dev/null)
258
+ [[ -n "$ENV_VAR_LIST" ]] && echo "[DRY RUN] Env vars (from auth.envVars): $ENV_VAR_LIST"
259
+ echo "[DRY RUN] Recipe (v2):"; cat "$RECIPE_FILE"
260
+ else
261
+ [[ -f "$ENV_VARS_FILE" ]] && echo "[DRY RUN] Env var: $(cat "$ENV_VARS_FILE")"
262
+ echo "[DRY RUN] Config (v1):"; cat "$SERVER_CONFIG_FILE"
263
+ fi
219
264
  exit 0
220
265
  fi
221
266
 
@@ -226,9 +271,21 @@ check_prerequisites
226
271
  install_dependencies
227
272
 
228
273
  # 3. Get API token
229
- if [[ -f "$ENV_VARS_FILE" ]] && [[ -s "$ENV_VARS_FILE" ]]; then
274
+ # Determine env var name: v2 uses auth.envVars[], v1 uses env_vars file
275
+ ENV_VAR_NAME=""
276
+ if [[ "$RECIPE_FORMAT" == "v2" ]]; then
277
+ ENV_VAR_NAME=$(python3 -c "
278
+ import json, sys
279
+ with open(sys.argv[1]) as f:
280
+ r = json.load(f)
281
+ env_vars = r.get('auth', {}).get('envVars', [])
282
+ print(env_vars[0] if env_vars else '')
283
+ " "$RECIPE_FILE" 2>/dev/null)
284
+ elif [[ -f "$ENV_VARS_FILE" ]] && [[ -s "$ENV_VARS_FILE" ]]; then
230
285
  ENV_VAR_NAME="$(head -n 1 "$ENV_VARS_FILE" | tr -d '[:space:]')"
286
+ fi
231
287
 
288
+ if [[ -n "$ENV_VAR_NAME" ]]; then
232
289
  TOKEN_URL="$(get_token_url)"
233
290
  [[ -n "$TOKEN_URL" ]] && echo "Get your API token here: ${TOKEN_URL}"
234
291
 
@@ -268,18 +325,43 @@ cp "$MCP_BRIDGE_JSON" "$BACKUP_FILE"
268
325
  echo "Backup: ${BACKUP_FILE}"
269
326
 
270
327
  PATH_OVERRIDE="$(resolve_path_override)"
328
+ ACTIVE_RECIPE_FILE="$RECIPE_FILE"
329
+ ACTIVE_RECIPE_FORMAT="$RECIPE_FORMAT"
271
330
 
272
- python3 - "$MCP_BRIDGE_JSON" "$SERVER_CONFIG_FILE" "$SERVER_NAME" "$PATH_OVERRIDE" <<'PY'
331
+ python3 - "$MCP_BRIDGE_JSON" "$SERVER_CONFIG_FILE" "$SERVER_NAME" "$PATH_OVERRIDE" "$ACTIVE_RECIPE_FILE" "$ACTIVE_RECIPE_FORMAT" <<'PY'
273
332
  import json, sys
274
333
 
275
- config_path, server_cfg_path, server_name, path_override = sys.argv[1:5]
334
+ config_path, server_cfg_path, server_name, path_override, recipe_file, recipe_format = sys.argv[1:7]
276
335
 
277
336
  with open(config_path, "r", encoding="utf-8") as f:
278
337
  raw = f.read().strip()
279
338
  cfg = json.loads(raw) if raw else {}
280
339
 
281
- with open(server_cfg_path, "r", encoding="utf-8") as f:
282
- server_cfg = json.load(f)
340
+ if recipe_format == "v2":
341
+ # Parse v2 recipe and build v1-compatible server config for runtime
342
+ with open(recipe_file, "r", encoding="utf-8") as f:
343
+ recipe = json.load(f)
344
+ transport = recipe["transports"][0]
345
+ server_cfg = {
346
+ "schemaVersion": 1,
347
+ "name": server_name,
348
+ "transport": transport.get("type", "stdio"),
349
+ "command": transport.get("command", ""),
350
+ "args": transport.get("args", []),
351
+ "env": transport.get("env", {}),
352
+ }
353
+ # Carry over optional v1-compatible fields from recipe if present
354
+ auth = recipe.get("auth", {})
355
+ if auth.get("required"):
356
+ server_cfg["authRequired"] = True
357
+ if auth.get("credentialsUrl"):
358
+ server_cfg["credentialsUrl"] = auth["credentialsUrl"]
359
+ meta = recipe.get("metadata", {})
360
+ if meta.get("homepage"):
361
+ server_cfg["homepage"] = meta["homepage"]
362
+ else:
363
+ with open(server_cfg_path, "r", encoding="utf-8") as f:
364
+ server_cfg = json.load(f)
283
365
 
284
366
  if path_override:
285
367
  args = server_cfg.get("args")
@@ -299,7 +381,7 @@ with open(config_path, "w", encoding="utf-8") as f:
299
381
  json.dump(cfg, f, indent=2)
300
382
  f.write("\n")
301
383
 
302
- print(f"✅ Configuration merged for: {server_name}")
384
+ print(f"✅ Configuration merged for: {server_name} (recipe {recipe_format})")
303
385
  PY
304
386
 
305
387
  # 5. Gateway restart
@@ -0,0 +1,41 @@
1
+ {
2
+ "schemaVersion": 2,
3
+ "id": "apify",
4
+ "name": "Apify",
5
+ "description": "Web scraping and automation platform with 3000+ ready-made actors for data extraction, browser automation, and crawling",
6
+ "repository": "https://github.com/apify/apify-mcp-server",
7
+
8
+ "transports": [
9
+ {
10
+ "type": "streamable-http",
11
+ "url": "https://mcp.apify.com/mcp",
12
+ "headers": {
13
+ "Authorization": "Bearer ${APIFY_TOKEN}"
14
+ }
15
+ }
16
+ ],
17
+
18
+ "auth": {
19
+ "required": true,
20
+ "type": "bearer",
21
+ "envVars": ["APIFY_TOKEN"],
22
+ "credentialsUrl": "https://console.apify.com/settings/integrations",
23
+ "instructions": "Copy your API token from Apify Console > Settings > Integrations."
24
+ },
25
+
26
+ "metadata": {
27
+ "homepage": "https://apify.com/",
28
+ "author": "Apify",
29
+ "tags": ["scraping", "automation", "web", "crawling", "actors"],
30
+ "category": "automation",
31
+ "pricing": "byok",
32
+ "maturity": "stable"
33
+ },
34
+
35
+ "capabilities": {
36
+ "tools": true,
37
+ "resources": false,
38
+ "prompts": false,
39
+ "sampling": false
40
+ }
41
+ }
@@ -0,0 +1,60 @@
1
+ {
2
+ "schemaVersion": 2,
3
+ "id": "atlassian",
4
+ "name": "Atlassian (Confluence + Jira)",
5
+ "description": "Confluence wiki and Jira project management — search, create, and update pages and issues",
6
+ "repository": "https://github.com/sooperset/mcp-atlassian",
7
+
8
+ "transports": [
9
+ {
10
+ "type": "stdio",
11
+ "command": "uvx",
12
+ "args": ["mcp-atlassian"],
13
+ "env": {
14
+ "CONFLUENCE_URL": "${CONFLUENCE_URL}",
15
+ "CONFLUENCE_USERNAME": "${CONFLUENCE_USERNAME}",
16
+ "CONFLUENCE_API_TOKEN": "${CONFLUENCE_API_TOKEN}",
17
+ "JIRA_URL": "${JIRA_URL}",
18
+ "JIRA_USERNAME": "${JIRA_USERNAME}",
19
+ "JIRA_API_TOKEN": "${JIRA_API_TOKEN}"
20
+ }
21
+ }
22
+ ],
23
+
24
+ "auth": {
25
+ "required": true,
26
+ "type": "api-key",
27
+ "envVars": [
28
+ "CONFLUENCE_URL",
29
+ "CONFLUENCE_USERNAME",
30
+ "CONFLUENCE_API_TOKEN",
31
+ "JIRA_URL",
32
+ "JIRA_USERNAME",
33
+ "JIRA_API_TOKEN"
34
+ ],
35
+ "credentialsUrl": "https://id.atlassian.com/manage-profile/security/api-tokens",
36
+ "instructions": "Create an API token at Atlassian account settings. Set CONFLUENCE_URL and JIRA_URL to your instance URLs (e.g., https://yourcompany.atlassian.net/wiki and https://yourcompany.atlassian.net)."
37
+ },
38
+
39
+ "install": {
40
+ "method": "uvx",
41
+ "package": "mcp-atlassian",
42
+ "version": "latest"
43
+ },
44
+
45
+ "metadata": {
46
+ "homepage": "https://github.com/sooperset/mcp-atlassian",
47
+ "author": "sooperset",
48
+ "tags": ["wiki", "project-management", "confluence", "jira", "atlassian"],
49
+ "category": "productivity",
50
+ "pricing": "byok",
51
+ "maturity": "stable"
52
+ },
53
+
54
+ "capabilities": {
55
+ "tools": true,
56
+ "resources": false,
57
+ "prompts": false,
58
+ "sampling": false
59
+ }
60
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "schemaVersion": 2,
3
+ "id": "chrome-devtools",
4
+ "name": "Chrome DevTools",
5
+ "description": "Control and inspect a live Chrome browser for automation, debugging, and performance analysis via the Chrome DevTools Protocol",
6
+ "repository": "https://github.com/ChromeDevTools/chrome-devtools-mcp",
7
+
8
+ "transports": [
9
+ {
10
+ "type": "stdio",
11
+ "command": "npx",
12
+ "args": ["-y", "chrome-devtools-mcp@0.20.0", "--autoConnect"],
13
+ "env": {}
14
+ }
15
+ ],
16
+
17
+ "auth": {
18
+ "required": false,
19
+ "type": "none",
20
+ "envVars": [],
21
+ "instructions": "Requires Chrome >= 144 with remote debugging enabled at chrome://inspect/#remote-debugging. Chrome will show a permission dialog on each connection."
22
+ },
23
+
24
+ "install": {
25
+ "method": "npx",
26
+ "package": "chrome-devtools-mcp",
27
+ "version": "0.20.0"
28
+ },
29
+
30
+ "metadata": {
31
+ "homepage": "https://github.com/ChromeDevTools/chrome-devtools-mcp",
32
+ "author": "ChromeDevTools",
33
+ "tags": ["browser", "debugging", "automation", "devtools", "chrome"],
34
+ "category": "development",
35
+ "pricing": "free",
36
+ "maturity": "stable"
37
+ },
38
+
39
+ "capabilities": {
40
+ "tools": true,
41
+ "resources": false,
42
+ "prompts": false,
43
+ "sampling": false
44
+ }
45
+ }
@@ -0,0 +1,55 @@
1
+ {
2
+ "schemaVersion": 2,
3
+ "id": "github",
4
+ "name": "GitHub",
5
+ "description": "GitHub repository management — repos, issues, PRs, code search, and more via the official GitHub MCP server",
6
+ "repository": "https://github.com/github/github-mcp-server",
7
+
8
+ "transports": [
9
+ {
10
+ "type": "stdio",
11
+ "command": "docker",
12
+ "args": [
13
+ "run",
14
+ "-i",
15
+ "--rm",
16
+ "-e",
17
+ "GITHUB_PERSONAL_ACCESS_TOKEN",
18
+ "ghcr.io/github/github-mcp-server"
19
+ ],
20
+ "env": {
21
+ "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_MCP_TOKEN}"
22
+ }
23
+ }
24
+ ],
25
+
26
+ "auth": {
27
+ "required": true,
28
+ "type": "api-key",
29
+ "envVars": ["GITHUB_MCP_TOKEN"],
30
+ "credentialsUrl": "https://github.com/settings/tokens",
31
+ "instructions": "Create a Personal Access Token at GitHub Settings > Developer settings > Personal access tokens. Grant repo, issues, and pull_requests scopes."
32
+ },
33
+
34
+ "install": {
35
+ "method": "docker",
36
+ "image": "ghcr.io/github/github-mcp-server",
37
+ "version": "latest"
38
+ },
39
+
40
+ "metadata": {
41
+ "homepage": "https://github.com/github/github-mcp-server",
42
+ "author": "GitHub",
43
+ "tags": ["git", "repos", "issues", "pull-requests", "code-review"],
44
+ "category": "development",
45
+ "pricing": "byok",
46
+ "maturity": "stable"
47
+ },
48
+
49
+ "capabilities": {
50
+ "tools": true,
51
+ "resources": false,
52
+ "prompts": false,
53
+ "sampling": false
54
+ }
55
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "schemaVersion": 2,
3
+ "id": "google-maps",
4
+ "name": "Google Maps",
5
+ "description": "Google Maps integration for places search, geocoding, directions, and distance matrix via the official MCP server",
6
+ "repository": "https://github.com/modelcontextprotocol/servers",
7
+
8
+ "transports": [
9
+ {
10
+ "type": "stdio",
11
+ "command": "npx",
12
+ "args": ["-y", "@modelcontextprotocol/server-google-maps"],
13
+ "env": {
14
+ "GOOGLE_MAPS_API_KEY": "${GOOGLE_MAPS_API_KEY}"
15
+ }
16
+ }
17
+ ],
18
+
19
+ "auth": {
20
+ "required": true,
21
+ "type": "api-key",
22
+ "envVars": ["GOOGLE_MAPS_API_KEY"],
23
+ "credentialsUrl": "https://console.cloud.google.com/apis/credentials",
24
+ "instructions": "Create an API key in Google Cloud Console and enable the Maps JavaScript API, Places API, Geocoding API, and Directions API."
25
+ },
26
+
27
+ "install": {
28
+ "method": "npx",
29
+ "package": "@modelcontextprotocol/server-google-maps",
30
+ "version": "latest"
31
+ },
32
+
33
+ "metadata": {
34
+ "homepage": "https://developers.google.com/maps",
35
+ "author": "Anthropic / MCP Community",
36
+ "tags": ["maps", "geocoding", "places", "directions", "navigation"],
37
+ "category": "other",
38
+ "pricing": "byok",
39
+ "maturity": "stable"
40
+ },
41
+
42
+ "capabilities": {
43
+ "tools": true,
44
+ "resources": false,
45
+ "prompts": false,
46
+ "sampling": false
47
+ }
48
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "schemaVersion": 2,
3
+ "id": "hetzner",
4
+ "name": "Hetzner Cloud",
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",
7
+
8
+ "transports": [
9
+ {
10
+ "type": "stdio",
11
+ "command": "node",
12
+ "args": ["dist/index.js"],
13
+ "env": {
14
+ "HCLOUD_TOKEN": "${HETZNER_API_TOKEN}"
15
+ }
16
+ }
17
+ ],
18
+
19
+ "auth": {
20
+ "required": true,
21
+ "type": "api-key",
22
+ "envVars": ["HETZNER_API_TOKEN"],
23
+ "credentialsUrl": "https://console.hetzner.cloud/",
24
+ "instructions": "Create an API token in the Hetzner Cloud Console under your project > Security > API Tokens."
25
+ },
26
+
27
+ "install": {
28
+ "method": "git",
29
+ "repository": "https://github.com/valerius21/hetzner-mcp",
30
+ "buildCommand": "npm install && npm run build",
31
+ "version": "latest"
32
+ },
33
+
34
+ "metadata": {
35
+ "homepage": "https://www.hetzner.com/cloud",
36
+ "author": "valerius21",
37
+ "tags": ["cloud", "infrastructure", "servers", "vps", "hetzner"],
38
+ "category": "infrastructure",
39
+ "pricing": "byok",
40
+ "maturity": "stable"
41
+ },
42
+
43
+ "capabilities": {
44
+ "tools": true,
45
+ "resources": false,
46
+ "prompts": false,
47
+ "sampling": false
48
+ }
49
+ }
@@ -0,0 +1,47 @@
1
+ {
2
+ "schemaVersion": 2,
3
+ "id": "hostinger",
4
+ "name": "Hostinger",
5
+ "description": "Web hosting management via Hostinger API — manage domains, hosting plans, email accounts, and website settings",
6
+
7
+ "transports": [
8
+ {
9
+ "type": "stdio",
10
+ "command": "npx",
11
+ "args": ["-y", "@anthropic-pb/hostinger-mcp-server"],
12
+ "env": {
13
+ "HOSTINGER_API_TOKEN": "${HOSTINGER_API_TOKEN}"
14
+ }
15
+ }
16
+ ],
17
+
18
+ "auth": {
19
+ "required": true,
20
+ "type": "api-key",
21
+ "envVars": ["HOSTINGER_API_TOKEN"],
22
+ "credentialsUrl": "https://hpanel.hostinger.com/api",
23
+ "instructions": "Generate an API token in the Hostinger hPanel under API section."
24
+ },
25
+
26
+ "install": {
27
+ "method": "npx",
28
+ "package": "@anthropic-pb/hostinger-mcp-server",
29
+ "version": "latest"
30
+ },
31
+
32
+ "metadata": {
33
+ "homepage": "https://www.hostinger.com/",
34
+ "author": "Anthropic / Hostinger",
35
+ "tags": ["hosting", "domains", "web-hosting", "email", "dns"],
36
+ "category": "infrastructure",
37
+ "pricing": "byok",
38
+ "maturity": "stable"
39
+ },
40
+
41
+ "capabilities": {
42
+ "tools": true,
43
+ "resources": false,
44
+ "prompts": false,
45
+ "sampling": false
46
+ }
47
+ }