@aiwerk/mcp-bridge 1.0.0 → 1.0.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/dist/bin/mcp-bridge.d.ts +2 -0
- package/dist/bin/mcp-bridge.js +320 -0
- package/dist/src/config.d.ts +19 -0
- package/dist/src/config.js +145 -0
- package/{src/index.ts → dist/src/index.d.ts} +1 -30
- package/dist/src/index.js +21 -0
- package/dist/src/mcp-router.d.ts +65 -0
- package/dist/src/mcp-router.js +271 -0
- package/dist/src/protocol.d.ts +4 -0
- package/dist/src/protocol.js +58 -0
- package/dist/src/schema-convert.d.ts +11 -0
- package/dist/src/schema-convert.js +150 -0
- package/dist/src/standalone-server.d.ts +30 -0
- package/dist/src/standalone-server.js +312 -0
- package/dist/src/tool-naming.d.ts +3 -0
- package/dist/src/tool-naming.js +38 -0
- package/dist/src/transport-base.d.ts +76 -0
- package/dist/src/transport-base.js +163 -0
- package/dist/src/transport-sse.d.ts +16 -0
- package/dist/src/transport-sse.js +207 -0
- package/dist/src/transport-stdio.d.ts +20 -0
- package/dist/src/transport-stdio.js +281 -0
- package/dist/src/transport-streamable-http.d.ts +11 -0
- package/dist/src/transport-streamable-http.js +164 -0
- package/dist/src/types.d.ts +72 -0
- package/dist/src/types.js +4 -0
- package/dist/src/update-checker.d.ts +25 -0
- package/dist/src/update-checker.js +132 -0
- package/package.json +19 -4
- package/scripts/install-server.ps1 +25 -58
- package/scripts/install-server.sh +37 -90
- package/servers/apify/README.md +6 -6
- package/servers/github/README.md +6 -6
- package/servers/google-maps/README.md +6 -6
- package/servers/hetzner/README.md +6 -6
- package/servers/hostinger/README.md +6 -6
- package/servers/linear/README.md +6 -6
- package/servers/miro/README.md +6 -6
- package/servers/notion/README.md +6 -6
- package/servers/stripe/README.md +6 -6
- package/servers/tavily/README.md +6 -6
- package/servers/todoist/README.md +6 -6
- package/servers/wise/README.md +6 -6
- package/bin/mcp-bridge.js +0 -9
- package/bin/mcp-bridge.ts +0 -335
- package/src/config.ts +0 -168
- package/src/mcp-router.ts +0 -366
- package/src/protocol.ts +0 -69
- package/src/schema-convert.ts +0 -178
- package/src/standalone-server.ts +0 -385
- package/src/tool-naming.ts +0 -51
- package/src/transport-base.ts +0 -199
- package/src/transport-sse.ts +0 -230
- package/src/transport-stdio.ts +0 -312
- package/src/transport-streamable-http.ts +0 -188
- package/src/types.ts +0 -88
- package/src/update-checker.ts +0 -155
- package/tests/collision.test.ts +0 -60
- package/tests/env-resolve.test.ts +0 -68
- package/tests/mcp-router.test.ts +0 -301
- package/tests/schema-convert.test.ts +0 -70
- package/tests/transport-base.test.ts +0 -214
- package/tsconfig.json +0 -15
package/servers/github/README.md
CHANGED
|
@@ -10,21 +10,21 @@ Official GitHub MCP server running in Docker.
|
|
|
10
10
|
|
|
11
11
|
### Linux / macOS
|
|
12
12
|
```bash
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
# Using mcp-bridge CLI:
|
|
14
|
+
mcp-bridge install github
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
### Windows (PowerShell)
|
|
18
18
|
```powershell
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
# Using mcp-bridge CLI:
|
|
20
|
+
mcp-bridge install github
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
### Manual Setup
|
|
24
24
|
1. Get your token: https://github.com/settings/tokens
|
|
25
25
|
2. Add to .env: `GITHUB_MCP_TOKEN=your_token`
|
|
26
|
-
3. Add config to
|
|
27
|
-
4. Restart
|
|
26
|
+
3. Add config to ~/.mcp-bridge/config.json (see config.json)
|
|
27
|
+
4. Restart mcp-bridge
|
|
28
28
|
|
|
29
29
|
## What you get
|
|
30
30
|
- Repository browsing and search tools
|
|
@@ -10,21 +10,21 @@ Google Maps MCP tools for places, geocoding, and routing.
|
|
|
10
10
|
|
|
11
11
|
### Linux / macOS
|
|
12
12
|
```bash
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
# Using mcp-bridge CLI:
|
|
14
|
+
mcp-bridge install google-maps
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
### Windows (PowerShell)
|
|
18
18
|
```powershell
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
# Using mcp-bridge CLI:
|
|
20
|
+
mcp-bridge install google-maps
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
### Manual Setup
|
|
24
24
|
1. Get your token: https://console.cloud.google.com/apis/credentials
|
|
25
25
|
2. Add to .env: `GOOGLE_MAPS_API_KEY=your_token`
|
|
26
|
-
3. Add config to
|
|
27
|
-
4. Restart
|
|
26
|
+
3. Add config to ~/.mcp-bridge/config.json (see config.json)
|
|
27
|
+
4. Restart mcp-bridge
|
|
28
28
|
|
|
29
29
|
## What you get
|
|
30
30
|
- Geocoding and reverse geocoding
|
|
@@ -11,21 +11,21 @@ Hetzner Cloud MCP server built from source.
|
|
|
11
11
|
|
|
12
12
|
### Linux / macOS
|
|
13
13
|
```bash
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
# Using mcp-bridge CLI:
|
|
15
|
+
mcp-bridge install hetzner
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
### Windows (PowerShell)
|
|
19
19
|
```powershell
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
# Using mcp-bridge CLI:
|
|
21
|
+
mcp-bridge install hetzner
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
### Manual Setup
|
|
25
25
|
1. Get your token: https://console.hetzner.cloud/
|
|
26
26
|
2. Add to .env: `HETZNER_API_TOKEN=your_token`
|
|
27
|
-
3. Add config to
|
|
28
|
-
4. Restart
|
|
27
|
+
3. Add config to ~/.mcp-bridge/config.json (see config.json)
|
|
28
|
+
4. Restart mcp-bridge
|
|
29
29
|
|
|
30
30
|
## What you get
|
|
31
31
|
- Server lifecycle tools
|
|
@@ -10,21 +10,21 @@ Hostinger MCP tools for hosting operations.
|
|
|
10
10
|
|
|
11
11
|
### Linux / macOS
|
|
12
12
|
```bash
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
# Using mcp-bridge CLI:
|
|
14
|
+
mcp-bridge install hostinger
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
### Windows (PowerShell)
|
|
18
18
|
```powershell
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
# Using mcp-bridge CLI:
|
|
20
|
+
mcp-bridge install hostinger
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
### Manual Setup
|
|
24
24
|
1. Get your token: https://hpanel.hostinger.com/api
|
|
25
25
|
2. Add to .env: `HOSTINGER_API_TOKEN=your_token`
|
|
26
|
-
3. Add config to
|
|
27
|
-
4. Restart
|
|
26
|
+
3. Add config to ~/.mcp-bridge/config.json (see config.json)
|
|
27
|
+
4. Restart mcp-bridge
|
|
28
28
|
|
|
29
29
|
## What you get
|
|
30
30
|
- Hosting and site management tools
|
package/servers/linear/README.md
CHANGED
|
@@ -10,21 +10,21 @@ Linear issue and project management MCP server.
|
|
|
10
10
|
|
|
11
11
|
### Linux / macOS
|
|
12
12
|
```bash
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
# Using mcp-bridge CLI:
|
|
14
|
+
mcp-bridge install linear
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
### Windows (PowerShell)
|
|
18
18
|
```powershell
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
# Using mcp-bridge CLI:
|
|
20
|
+
mcp-bridge install linear
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
### Manual Setup
|
|
24
24
|
1. Get your token: https://linear.app/settings/api
|
|
25
25
|
2. Add to .env: `LINEAR_API_KEY=your_token`
|
|
26
|
-
3. Add config to
|
|
27
|
-
4. Restart
|
|
26
|
+
3. Add config to ~/.mcp-bridge/config.json (see config.json)
|
|
27
|
+
4. Restart mcp-bridge
|
|
28
28
|
|
|
29
29
|
## What you get
|
|
30
30
|
- Issue create/update/search tools
|
package/servers/miro/README.md
CHANGED
|
@@ -10,21 +10,21 @@ Miro board MCP tools for collaborative whiteboards.
|
|
|
10
10
|
|
|
11
11
|
### Linux / macOS
|
|
12
12
|
```bash
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
# Using mcp-bridge CLI:
|
|
14
|
+
mcp-bridge install miro
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
### Windows (PowerShell)
|
|
18
18
|
```powershell
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
# Using mcp-bridge CLI:
|
|
20
|
+
mcp-bridge install miro
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
### Manual Setup
|
|
24
24
|
1. Get your token: https://miro.com/app/settings/user-profile/apps
|
|
25
25
|
2. Add to .env: `MIRO_API_TOKEN=your_token`
|
|
26
|
-
3. Add config to
|
|
27
|
-
4. Restart
|
|
26
|
+
3. Add config to ~/.mcp-bridge/config.json (see config.json)
|
|
27
|
+
4. Restart mcp-bridge
|
|
28
28
|
|
|
29
29
|
## What you get
|
|
30
30
|
- Board content read tools
|
package/servers/notion/README.md
CHANGED
|
@@ -12,21 +12,21 @@ Official Notion integration for reading and managing your Notion workspace — p
|
|
|
12
12
|
|
|
13
13
|
### Linux / macOS
|
|
14
14
|
```bash
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
# Using mcp-bridge CLI:
|
|
16
|
+
mcp-bridge install notion
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
### Windows (PowerShell)
|
|
20
20
|
```powershell
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
# Using mcp-bridge CLI:
|
|
22
|
+
mcp-bridge install notion
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
### Manual Setup
|
|
26
26
|
1. Get your token: https://www.notion.so/my-integrations
|
|
27
27
|
2. Add to .env: `NOTION_API_KEY=ntn_xxxxx`
|
|
28
|
-
3. Add config to
|
|
29
|
-
4. Restart
|
|
28
|
+
3. Add config to ~/.mcp-bridge/config.json (see config.json)
|
|
29
|
+
4. Restart mcp-bridge
|
|
30
30
|
|
|
31
31
|
## What you get
|
|
32
32
|
- 22 tools: search, pages, databases, blocks, users, comments
|
package/servers/stripe/README.md
CHANGED
|
@@ -10,21 +10,21 @@ Stripe MCP server for billing and payments operations.
|
|
|
10
10
|
|
|
11
11
|
### Linux / macOS
|
|
12
12
|
```bash
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
# Using mcp-bridge CLI:
|
|
14
|
+
mcp-bridge install stripe
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
### Windows (PowerShell)
|
|
18
18
|
```powershell
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
# Using mcp-bridge CLI:
|
|
20
|
+
mcp-bridge install stripe
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
### Manual Setup
|
|
24
24
|
1. Get your token: https://dashboard.stripe.com/apikeys
|
|
25
25
|
2. Add to .env: `STRIPE_API_KEY=your_token`
|
|
26
|
-
3. Add config to
|
|
27
|
-
4. Restart
|
|
26
|
+
3. Add config to ~/.mcp-bridge/config.json (see config.json)
|
|
27
|
+
4. Restart mcp-bridge
|
|
28
28
|
|
|
29
29
|
## What you get
|
|
30
30
|
- Customer and subscription tools
|
package/servers/tavily/README.md
CHANGED
|
@@ -10,21 +10,21 @@ Tavily MCP search and extraction tools.
|
|
|
10
10
|
|
|
11
11
|
### Linux / macOS
|
|
12
12
|
```bash
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
# Using mcp-bridge CLI:
|
|
14
|
+
mcp-bridge install tavily
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
### Windows (PowerShell)
|
|
18
18
|
```powershell
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
# Using mcp-bridge CLI:
|
|
20
|
+
mcp-bridge install tavily
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
### Manual Setup
|
|
24
24
|
1. Get your token: https://app.tavily.com/home
|
|
25
25
|
2. Add to .env: `TAVILY_API_KEY=your_token`
|
|
26
|
-
3. Add config to
|
|
27
|
-
4. Restart
|
|
26
|
+
3. Add config to ~/.mcp-bridge/config.json (see config.json)
|
|
27
|
+
4. Restart mcp-bridge
|
|
28
28
|
|
|
29
29
|
## What you get
|
|
30
30
|
- Web search tools
|
|
@@ -10,21 +10,21 @@ Todoist MCP server for tasks, projects, and productivity workflows.
|
|
|
10
10
|
|
|
11
11
|
### Linux / macOS
|
|
12
12
|
```bash
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
# Using mcp-bridge CLI:
|
|
14
|
+
mcp-bridge install todoist
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
### Windows (PowerShell)
|
|
18
18
|
```powershell
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
# Using mcp-bridge CLI:
|
|
20
|
+
mcp-bridge install todoist
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
### Manual Setup
|
|
24
24
|
1. Get your token: https://app.todoist.com/app/settings/integrations/developer
|
|
25
25
|
2. Add to .env: `TODOIST_API_TOKEN=your_token`
|
|
26
|
-
3. Add config to
|
|
27
|
-
4. Restart
|
|
26
|
+
3. Add config to ~/.mcp-bridge/config.json (see config.json)
|
|
27
|
+
4. Restart mcp-bridge
|
|
28
28
|
|
|
29
29
|
## What you get
|
|
30
30
|
- Task and project CRUD tools
|
package/servers/wise/README.md
CHANGED
|
@@ -11,21 +11,21 @@ Wise MCP server for multi-currency account and transfer workflows.
|
|
|
11
11
|
|
|
12
12
|
### Linux / macOS
|
|
13
13
|
```bash
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
# Using mcp-bridge CLI:
|
|
15
|
+
mcp-bridge install wise
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
### Windows (PowerShell)
|
|
19
19
|
```powershell
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
# Using mcp-bridge CLI:
|
|
21
|
+
mcp-bridge install wise
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
### Manual Setup
|
|
25
25
|
1. Get your token: https://wise.com/settings/api-tokens
|
|
26
26
|
2. Add to .env: `WISE_API_TOKEN=your_token`
|
|
27
|
-
3. Add config to
|
|
28
|
-
4. Restart
|
|
27
|
+
3. Add config to ~/.mcp-bridge/config.json (see config.json)
|
|
28
|
+
4. Restart mcp-bridge
|
|
29
29
|
|
|
30
30
|
## What you get
|
|
31
31
|
- Profile and balance lookup tools
|
package/bin/mcp-bridge.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// Bootstrap: run the TypeScript entry point via tsx
|
|
4
|
-
import { register } from "node:module";
|
|
5
|
-
import { pathToFileURL } from "node:url";
|
|
6
|
-
|
|
7
|
-
register("tsx/esm", pathToFileURL("./"));
|
|
8
|
-
|
|
9
|
-
const { default: _ } = await import("./mcp-bridge.ts");
|
package/bin/mcp-bridge.ts
DELETED
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { readFileSync, existsSync } from "fs";
|
|
4
|
-
import { join, dirname, resolve } from "path";
|
|
5
|
-
import { fileURLToPath } from "url";
|
|
6
|
-
import { execSync } from "child_process";
|
|
7
|
-
import { loadConfig, initConfigDir, getConfigDir } from "../src/config.js";
|
|
8
|
-
import { StandaloneServer } from "../src/standalone-server.js";
|
|
9
|
-
import { PACKAGE_VERSION } from "../src/protocol.js";
|
|
10
|
-
import { checkForUpdate, runUpdate } from "../src/update-checker.js";
|
|
11
|
-
import type { Logger } from "../src/types.js";
|
|
12
|
-
|
|
13
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
-
const __dirname = dirname(__filename);
|
|
15
|
-
|
|
16
|
-
// -- Logger ---------------------------------------------------------------
|
|
17
|
-
|
|
18
|
-
type LogLevel = "error" | "warn" | "info" | "debug";
|
|
19
|
-
|
|
20
|
-
function createLogger(level: LogLevel): Logger {
|
|
21
|
-
const levels: Record<LogLevel, number> = { error: 0, warn: 1, info: 2, debug: 3 };
|
|
22
|
-
const threshold = levels[level];
|
|
23
|
-
const ts = () => new Date().toISOString().replace("T", " ").replace("Z", "");
|
|
24
|
-
|
|
25
|
-
return {
|
|
26
|
-
error: (...args: unknown[]) => {
|
|
27
|
-
if (threshold >= 0) process.stderr.write(`[${ts()}] [ERROR] ${args.map(String).join(" ")}\n`);
|
|
28
|
-
},
|
|
29
|
-
warn: (...args: unknown[]) => {
|
|
30
|
-
if (threshold >= 1) process.stderr.write(`[${ts()}] [WARN] ${args.map(String).join(" ")}\n`);
|
|
31
|
-
},
|
|
32
|
-
info: (...args: unknown[]) => {
|
|
33
|
-
if (threshold >= 2) process.stderr.write(`[${ts()}] [INFO] ${args.map(String).join(" ")}\n`);
|
|
34
|
-
},
|
|
35
|
-
debug: (...args: unknown[]) => {
|
|
36
|
-
if (threshold >= 3) process.stderr.write(`[${ts()}] [DEBUG] ${args.map(String).join(" ")}\n`);
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// -- Arg parsing ----------------------------------------------------------
|
|
42
|
-
|
|
43
|
-
interface CliArgs {
|
|
44
|
-
command: "serve" | "init" | "install" | "catalog" | "servers" | "search" | "update" | "version" | "help";
|
|
45
|
-
sse: boolean;
|
|
46
|
-
http: boolean;
|
|
47
|
-
port: number;
|
|
48
|
-
configPath?: string;
|
|
49
|
-
verbose: boolean;
|
|
50
|
-
debug: boolean;
|
|
51
|
-
positional: string[];
|
|
52
|
-
checkOnly: boolean;
|
|
53
|
-
offline: boolean;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function parseArgs(argv: string[]): CliArgs {
|
|
57
|
-
const args: CliArgs = {
|
|
58
|
-
command: "serve",
|
|
59
|
-
sse: false,
|
|
60
|
-
http: false,
|
|
61
|
-
port: 3000,
|
|
62
|
-
verbose: false,
|
|
63
|
-
debug: false,
|
|
64
|
-
positional: [],
|
|
65
|
-
checkOnly: false,
|
|
66
|
-
offline: false,
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
let i = 0;
|
|
70
|
-
while (i < argv.length) {
|
|
71
|
-
const arg = argv[i];
|
|
72
|
-
switch (arg) {
|
|
73
|
-
case "--sse": args.sse = true; break;
|
|
74
|
-
case "--http": args.http = true; break;
|
|
75
|
-
case "--port":
|
|
76
|
-
i++;
|
|
77
|
-
args.port = parseInt(argv[i], 10);
|
|
78
|
-
if (isNaN(args.port)) { process.stderr.write("Error: --port requires a number\n"); process.exit(1); }
|
|
79
|
-
break;
|
|
80
|
-
case "--config":
|
|
81
|
-
i++;
|
|
82
|
-
args.configPath = resolve(argv[i]);
|
|
83
|
-
break;
|
|
84
|
-
case "--verbose": args.verbose = true; break;
|
|
85
|
-
case "--debug": args.debug = true; break;
|
|
86
|
-
case "--version": args.command = "version"; break;
|
|
87
|
-
case "--help": case "-h": args.command = "help"; break;
|
|
88
|
-
case "--check": args.checkOnly = true; break;
|
|
89
|
-
case "--offline": args.offline = true; break;
|
|
90
|
-
case "init": args.command = "init"; break;
|
|
91
|
-
case "install": args.command = "install"; break;
|
|
92
|
-
case "catalog": args.command = "catalog"; break;
|
|
93
|
-
case "servers": args.command = "servers"; break;
|
|
94
|
-
case "search": args.command = "search"; break;
|
|
95
|
-
case "update": args.command = "update"; break;
|
|
96
|
-
default:
|
|
97
|
-
if (!arg.startsWith("-")) {
|
|
98
|
-
args.positional.push(arg);
|
|
99
|
-
}
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
i++;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return args;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// -- Commands -------------------------------------------------------------
|
|
109
|
-
|
|
110
|
-
function printVersion(): void {
|
|
111
|
-
process.stdout.write(`mcp-bridge ${PACKAGE_VERSION}\n`);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function printHelp(): void {
|
|
115
|
-
process.stdout.write(`
|
|
116
|
-
mcp-bridge v${PACKAGE_VERSION} — MCP server multiplexer
|
|
117
|
-
|
|
118
|
-
Usage:
|
|
119
|
-
mcp-bridge Start in stdio mode (default)
|
|
120
|
-
mcp-bridge --sse --port 3000 Start as SSE server
|
|
121
|
-
mcp-bridge --http --port 3000 Start as streamable-http server
|
|
122
|
-
mcp-bridge init Create ~/.mcp-bridge/ with config template
|
|
123
|
-
mcp-bridge install <server> Install a server from the catalog
|
|
124
|
-
mcp-bridge catalog [--offline] List available servers
|
|
125
|
-
mcp-bridge servers List configured servers
|
|
126
|
-
mcp-bridge search <query> Search catalog by keyword
|
|
127
|
-
mcp-bridge update [--check] Check for / install updates
|
|
128
|
-
|
|
129
|
-
Options:
|
|
130
|
-
--config PATH Custom config file (default: ~/.mcp-bridge/config.json)
|
|
131
|
-
--verbose Info-level logs to stderr
|
|
132
|
-
--debug Full protocol-level logs to stderr
|
|
133
|
-
--version Print version
|
|
134
|
-
--help Show this help
|
|
135
|
-
|
|
136
|
-
All logs go to stderr. Stdout is reserved for the MCP protocol (stdio mode).
|
|
137
|
-
`);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
function cmdInit(logger: Logger): void {
|
|
141
|
-
initConfigDir(logger);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function cmdCatalog(logger: Logger, offline: boolean): void {
|
|
145
|
-
const catalogPath = join(__dirname, "..", "servers", "index.json");
|
|
146
|
-
if (!existsSync(catalogPath)) {
|
|
147
|
-
logger.error("Server catalog not found");
|
|
148
|
-
process.exit(1);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const catalog = JSON.parse(readFileSync(catalogPath, "utf-8"));
|
|
152
|
-
const servers = catalog.servers || {};
|
|
153
|
-
|
|
154
|
-
process.stdout.write("\nAvailable servers:\n\n");
|
|
155
|
-
process.stdout.write(" Server Transport Description\n");
|
|
156
|
-
process.stdout.write(" " + "─".repeat(60) + "\n");
|
|
157
|
-
|
|
158
|
-
for (const [name, info] of Object.entries(servers) as [string, any][]) {
|
|
159
|
-
const padded = name.padEnd(16);
|
|
160
|
-
const transport = (info.transport || "stdio").padEnd(13);
|
|
161
|
-
process.stdout.write(` ${padded}${transport}${info.description || ""}\n`);
|
|
162
|
-
}
|
|
163
|
-
process.stdout.write("\n");
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function cmdServers(logger: Logger, configPath?: string): void {
|
|
167
|
-
try {
|
|
168
|
-
const config = loadConfig({ configPath, logger });
|
|
169
|
-
const servers = config.servers || {};
|
|
170
|
-
const entries = Object.entries(servers);
|
|
171
|
-
|
|
172
|
-
if (entries.length === 0) {
|
|
173
|
-
process.stdout.write("No servers configured.\n");
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
process.stdout.write("\nConfigured servers:\n\n");
|
|
178
|
-
process.stdout.write(" Server Transport Description\n");
|
|
179
|
-
process.stdout.write(" " + "─".repeat(60) + "\n");
|
|
180
|
-
|
|
181
|
-
for (const [name, serverConfig] of entries) {
|
|
182
|
-
const padded = name.padEnd(16);
|
|
183
|
-
const transport = serverConfig.transport.padEnd(13);
|
|
184
|
-
process.stdout.write(` ${padded}${transport}${serverConfig.description || ""}\n`);
|
|
185
|
-
}
|
|
186
|
-
process.stdout.write("\n");
|
|
187
|
-
} catch (err) {
|
|
188
|
-
logger.error(err instanceof Error ? err.message : String(err));
|
|
189
|
-
process.exit(1);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
function cmdSearch(query: string, logger: Logger): void {
|
|
194
|
-
const catalogPath = join(__dirname, "..", "servers", "index.json");
|
|
195
|
-
if (!existsSync(catalogPath)) {
|
|
196
|
-
logger.error("Server catalog not found");
|
|
197
|
-
process.exit(1);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const catalog = JSON.parse(readFileSync(catalogPath, "utf-8"));
|
|
201
|
-
const servers = catalog.servers || {};
|
|
202
|
-
const lowerQuery = query.toLowerCase();
|
|
203
|
-
|
|
204
|
-
const matches = Object.entries(servers).filter(([name, info]: [string, any]) => {
|
|
205
|
-
return name.toLowerCase().includes(lowerQuery) ||
|
|
206
|
-
(info.description || "").toLowerCase().includes(lowerQuery);
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
if (matches.length === 0) {
|
|
210
|
-
process.stdout.write(`No servers matching "${query}"\n`);
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
process.stdout.write(`\nSearch results for "${query}":\n\n`);
|
|
215
|
-
for (const [i, [name, info]] of matches.entries() as any) {
|
|
216
|
-
process.stdout.write(` ${i + 1} ${name.padEnd(16)}${(info as any).description || ""}\n`);
|
|
217
|
-
}
|
|
218
|
-
process.stdout.write("\n");
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
function cmdInstall(serverName: string, logger: Logger): void {
|
|
222
|
-
const scriptPath = join(__dirname, "..", "scripts", "install-server.sh");
|
|
223
|
-
if (!existsSync(scriptPath)) {
|
|
224
|
-
logger.error("Install script not found");
|
|
225
|
-
process.exit(1);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
try {
|
|
229
|
-
execSync(`bash "${scriptPath}" "${serverName}"`, { stdio: "inherit" });
|
|
230
|
-
} catch (err) {
|
|
231
|
-
process.exit(1);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
async function cmdUpdate(logger: Logger, checkOnly: boolean): Promise<void> {
|
|
236
|
-
if (checkOnly) {
|
|
237
|
-
const info = await checkForUpdate(logger);
|
|
238
|
-
if (info.updateAvailable) {
|
|
239
|
-
process.stdout.write(`Update available: ${info.currentVersion} → ${info.latestVersion}\n`);
|
|
240
|
-
process.stdout.write(`Run 'mcp-bridge update' to install.\n`);
|
|
241
|
-
} else {
|
|
242
|
-
process.stdout.write(`mcp-bridge ${info.currentVersion} is up to date.\n`);
|
|
243
|
-
}
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
const result = await runUpdate(logger);
|
|
248
|
-
process.stdout.write(result + "\n");
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
async function cmdServe(args: CliArgs, logger: Logger): Promise<void> {
|
|
252
|
-
let config;
|
|
253
|
-
try {
|
|
254
|
-
config = loadConfig({ configPath: args.configPath, logger });
|
|
255
|
-
} catch (err) {
|
|
256
|
-
logger.error(err instanceof Error ? err.message : String(err));
|
|
257
|
-
process.exit(1);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// HTTP modes: require auth
|
|
261
|
-
if ((args.sse || args.http) && !config.http?.auth?.token) {
|
|
262
|
-
logger.error("HTTP auth not configured. Set http.auth in config or use stdio mode.");
|
|
263
|
-
process.exit(1);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
const server = new StandaloneServer(config, logger);
|
|
267
|
-
|
|
268
|
-
// Graceful shutdown
|
|
269
|
-
const shutdown = async () => {
|
|
270
|
-
await server.shutdown();
|
|
271
|
-
process.exit(0);
|
|
272
|
-
};
|
|
273
|
-
process.on("SIGTERM", shutdown);
|
|
274
|
-
process.on("SIGINT", shutdown);
|
|
275
|
-
|
|
276
|
-
if (args.sse || args.http) {
|
|
277
|
-
// SSE/HTTP mode: not yet implemented in standalone, show message
|
|
278
|
-
logger.error("SSE and HTTP server modes are not yet implemented. Use stdio mode (default).");
|
|
279
|
-
process.exit(1);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// Default: stdio mode
|
|
283
|
-
await server.startStdio();
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// -- Main -----------------------------------------------------------------
|
|
287
|
-
|
|
288
|
-
async function main(): Promise<void> {
|
|
289
|
-
const args = parseArgs(process.argv.slice(2));
|
|
290
|
-
const logLevel: LogLevel = args.debug ? "debug" : args.verbose ? "info" : "warn";
|
|
291
|
-
const logger = createLogger(logLevel);
|
|
292
|
-
|
|
293
|
-
switch (args.command) {
|
|
294
|
-
case "version":
|
|
295
|
-
printVersion();
|
|
296
|
-
break;
|
|
297
|
-
case "help":
|
|
298
|
-
printHelp();
|
|
299
|
-
break;
|
|
300
|
-
case "init":
|
|
301
|
-
cmdInit(logger);
|
|
302
|
-
break;
|
|
303
|
-
case "catalog":
|
|
304
|
-
cmdCatalog(logger, args.offline);
|
|
305
|
-
break;
|
|
306
|
-
case "servers":
|
|
307
|
-
cmdServers(logger, args.configPath);
|
|
308
|
-
break;
|
|
309
|
-
case "search":
|
|
310
|
-
if (args.positional.length === 0) {
|
|
311
|
-
process.stderr.write("Usage: mcp-bridge search <query>\n");
|
|
312
|
-
process.exit(1);
|
|
313
|
-
}
|
|
314
|
-
cmdSearch(args.positional[0], logger);
|
|
315
|
-
break;
|
|
316
|
-
case "install":
|
|
317
|
-
if (args.positional.length === 0) {
|
|
318
|
-
process.stderr.write("Usage: mcp-bridge install <server>\n");
|
|
319
|
-
process.exit(1);
|
|
320
|
-
}
|
|
321
|
-
cmdInstall(args.positional[0], logger);
|
|
322
|
-
break;
|
|
323
|
-
case "update":
|
|
324
|
-
await cmdUpdate(logger, args.checkOnly);
|
|
325
|
-
break;
|
|
326
|
-
case "serve":
|
|
327
|
-
await cmdServe(args, logger);
|
|
328
|
-
break;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
main().catch(err => {
|
|
333
|
-
process.stderr.write(`Fatal: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
334
|
-
process.exit(1);
|
|
335
|
-
});
|