@aiwerk/mcp-bridge 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +117 -0
- package/bin/mcp-bridge.js +9 -0
- package/bin/mcp-bridge.ts +335 -0
- package/package.json +42 -0
- package/scripts/install-server.ps1 +300 -0
- package/scripts/install-server.sh +357 -0
- package/servers/apify/README.md +40 -0
- package/servers/apify/config.json +13 -0
- package/servers/apify/env_vars +1 -0
- package/servers/apify/install.ps1 +3 -0
- package/servers/apify/install.sh +4 -0
- package/servers/candidates.md +13 -0
- package/servers/github/README.md +40 -0
- package/servers/github/config.json +21 -0
- package/servers/github/env_vars +1 -0
- package/servers/github/install.ps1 +3 -0
- package/servers/github/install.sh +4 -0
- package/servers/google-maps/README.md +40 -0
- package/servers/google-maps/config.json +17 -0
- package/servers/google-maps/env_vars +1 -0
- package/servers/google-maps/install.ps1 +3 -0
- package/servers/google-maps/install.sh +4 -0
- package/servers/hetzner/README.md +41 -0
- package/servers/hetzner/config.json +16 -0
- package/servers/hetzner/env_vars +1 -0
- package/servers/hetzner/install.ps1 +3 -0
- package/servers/hetzner/install.sh +4 -0
- package/servers/hostinger/README.md +40 -0
- package/servers/hostinger/config.json +17 -0
- package/servers/hostinger/env_vars +1 -0
- package/servers/hostinger/install.ps1 +3 -0
- package/servers/hostinger/install.sh +4 -0
- package/servers/index.json +125 -0
- package/servers/linear/README.md +40 -0
- package/servers/linear/config.json +16 -0
- package/servers/linear/env_vars +1 -0
- package/servers/linear/install.ps1 +3 -0
- package/servers/linear/install.sh +4 -0
- package/servers/miro/README.md +40 -0
- package/servers/miro/config.json +19 -0
- package/servers/miro/env_vars +1 -0
- package/servers/miro/install.ps1 +3 -0
- package/servers/miro/install.sh +4 -0
- package/servers/notion/README.md +42 -0
- package/servers/notion/config.json +17 -0
- package/servers/notion/env_vars +1 -0
- package/servers/notion/install.ps1 +3 -0
- package/servers/notion/install.sh +4 -0
- package/servers/stripe/README.md +40 -0
- package/servers/stripe/config.json +19 -0
- package/servers/stripe/env_vars +1 -0
- package/servers/stripe/install.ps1 +3 -0
- package/servers/stripe/install.sh +4 -0
- package/servers/tavily/README.md +40 -0
- package/servers/tavily/config.json +17 -0
- package/servers/tavily/env_vars +1 -0
- package/servers/tavily/install.ps1 +3 -0
- package/servers/tavily/install.sh +4 -0
- package/servers/todoist/README.md +40 -0
- package/servers/todoist/config.json +17 -0
- package/servers/todoist/env_vars +1 -0
- package/servers/todoist/install.ps1 +3 -0
- package/servers/todoist/install.sh +4 -0
- package/servers/wise/README.md +41 -0
- package/servers/wise/config.json +16 -0
- package/servers/wise/env_vars +1 -0
- package/servers/wise/install.ps1 +3 -0
- package/servers/wise/install.sh +4 -0
- package/src/config.ts +168 -0
- package/src/index.ts +44 -0
- package/src/mcp-router.ts +366 -0
- package/src/protocol.ts +69 -0
- package/src/schema-convert.ts +178 -0
- package/src/standalone-server.ts +385 -0
- package/src/tool-naming.ts +51 -0
- package/src/transport-base.ts +199 -0
- package/src/transport-sse.ts +230 -0
- package/src/transport-stdio.ts +312 -0
- package/src/transport-streamable-http.ts +188 -0
- package/src/types.ts +88 -0
- package/src/update-checker.ts +155 -0
- package/tests/collision.test.ts +60 -0
- package/tests/env-resolve.test.ts +68 -0
- package/tests/mcp-router.test.ts +301 -0
- package/tests/schema-convert.test.ts +70 -0
- package/tests/transport-base.test.ts +214 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Notion MCP Server
|
|
2
|
+
|
|
3
|
+
Official Notion integration for reading and managing your Notion workspace — pages, databases, blocks, and search.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
- Node.js + npx
|
|
7
|
+
- Notion API token ([My Integrations](https://www.notion.so/my-integrations))
|
|
8
|
+
|
|
9
|
+
> **Important:** After creating the integration, share the pages/databases you want accessible with it (page → ··· → Connections → Add your integration).
|
|
10
|
+
|
|
11
|
+
## Quick Install
|
|
12
|
+
|
|
13
|
+
### Linux / macOS
|
|
14
|
+
```bash
|
|
15
|
+
cd ~/.openclaw/extensions/mcp-client/servers/notion
|
|
16
|
+
chmod +x install.sh && ./install.sh
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Windows (PowerShell)
|
|
20
|
+
```powershell
|
|
21
|
+
cd $env:USERPROFILE\.openclaw\extensions\mcp-client\servers\notion
|
|
22
|
+
.\install.ps1
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Manual Setup
|
|
26
|
+
1. Get your token: https://www.notion.so/my-integrations
|
|
27
|
+
2. Add to .env: `NOTION_API_KEY=ntn_xxxxx`
|
|
28
|
+
3. Add config to openclaw.json (see config.json)
|
|
29
|
+
4. Restart gateway
|
|
30
|
+
|
|
31
|
+
## What you get
|
|
32
|
+
- 22 tools: search, pages, databases, blocks, users, comments
|
|
33
|
+
- Full Notion API coverage
|
|
34
|
+
- Official package: [@notionhq/notion-mcp-server](https://www.npmjs.com/package/@notionhq/notion-mcp-server)
|
|
35
|
+
|
|
36
|
+
## Remove
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
./install-server.sh notion --remove
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Removes the server from config and cleans up the API token. The server recipe stays in `servers/notion/` for easy reinstall.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"name": "notion",
|
|
4
|
+
"description": "notes & databases",
|
|
5
|
+
"transport": "stdio",
|
|
6
|
+
"command": "npx",
|
|
7
|
+
"args": [
|
|
8
|
+
"-y",
|
|
9
|
+
"@notionhq/notion-mcp-server"
|
|
10
|
+
],
|
|
11
|
+
"env": {
|
|
12
|
+
"NOTION_TOKEN": "${NOTION_API_KEY}"
|
|
13
|
+
},
|
|
14
|
+
"authRequired": true,
|
|
15
|
+
"credentialsUrl": "https://www.notion.so/my-integrations",
|
|
16
|
+
"homepage": "https://www.notion.so/"
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
NOTION_API_KEY
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Stripe MCP Server
|
|
2
|
+
|
|
3
|
+
Stripe MCP server for billing and payments operations.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
- Node.js + npx
|
|
7
|
+
- Stripe API key
|
|
8
|
+
|
|
9
|
+
## Quick Install
|
|
10
|
+
|
|
11
|
+
### Linux / macOS
|
|
12
|
+
```bash
|
|
13
|
+
cd ~/.openclaw/extensions/mcp-client/servers/stripe
|
|
14
|
+
chmod +x install.sh && ./install.sh
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Windows (PowerShell)
|
|
18
|
+
```powershell
|
|
19
|
+
cd $env:USERPROFILE\.openclaw\extensions\mcp-client\servers\stripe
|
|
20
|
+
.\install.ps1
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Manual Setup
|
|
24
|
+
1. Get your token: https://dashboard.stripe.com/apikeys
|
|
25
|
+
2. Add to .env: `STRIPE_API_KEY=your_token`
|
|
26
|
+
3. Add config to openclaw.json (see config.json)
|
|
27
|
+
4. Restart gateway
|
|
28
|
+
|
|
29
|
+
## What you get
|
|
30
|
+
- Customer and subscription tools
|
|
31
|
+
- Invoices and payment intent tools
|
|
32
|
+
- Refund, dispute, and balance tools
|
|
33
|
+
|
|
34
|
+
## Remove
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
./install-server.sh stripe --remove
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Removes the server from config and cleans up the API token. The server recipe stays in `servers/stripe/` for easy reinstall.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"name": "stripe",
|
|
4
|
+
"description": "payments & billing",
|
|
5
|
+
"transport": "stdio",
|
|
6
|
+
"command": "npx",
|
|
7
|
+
"args": [
|
|
8
|
+
"-y",
|
|
9
|
+
"@anthropic-pb/stripe-mcp-server",
|
|
10
|
+
"--tools=all",
|
|
11
|
+
"--api-key=${STRIPE_API_KEY}"
|
|
12
|
+
],
|
|
13
|
+
"env": {
|
|
14
|
+
"STRIPE_API_KEY": "${STRIPE_API_KEY}"
|
|
15
|
+
},
|
|
16
|
+
"authRequired": true,
|
|
17
|
+
"credentialsUrl": "https://dashboard.stripe.com/apikeys",
|
|
18
|
+
"homepage": "https://stripe.com/"
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
STRIPE_API_KEY
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Tavily MCP Server
|
|
2
|
+
|
|
3
|
+
Tavily MCP search and extraction tools.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
- Node.js + npx
|
|
7
|
+
- Tavily API key
|
|
8
|
+
|
|
9
|
+
## Quick Install
|
|
10
|
+
|
|
11
|
+
### Linux / macOS
|
|
12
|
+
```bash
|
|
13
|
+
cd ~/.openclaw/extensions/mcp-client/servers/tavily
|
|
14
|
+
chmod +x install.sh && ./install.sh
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Windows (PowerShell)
|
|
18
|
+
```powershell
|
|
19
|
+
cd $env:USERPROFILE\.openclaw\extensions\mcp-client\servers\tavily
|
|
20
|
+
.\install.ps1
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Manual Setup
|
|
24
|
+
1. Get your token: https://app.tavily.com/home
|
|
25
|
+
2. Add to .env: `TAVILY_API_KEY=your_token`
|
|
26
|
+
3. Add config to openclaw.json (see config.json)
|
|
27
|
+
4. Restart gateway
|
|
28
|
+
|
|
29
|
+
## What you get
|
|
30
|
+
- Web search tools
|
|
31
|
+
- URL extraction and crawling tools
|
|
32
|
+
- Research and mapping helpers
|
|
33
|
+
|
|
34
|
+
## Remove
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
./install-server.sh tavily --remove
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Removes the server from config and cleans up the API token. The server recipe stays in `servers/tavily/` for easy reinstall.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"name": "tavily",
|
|
4
|
+
"description": "AI-optimized web search",
|
|
5
|
+
"transport": "stdio",
|
|
6
|
+
"command": "npx",
|
|
7
|
+
"args": [
|
|
8
|
+
"-y",
|
|
9
|
+
"tavily-mcp@0.3.0"
|
|
10
|
+
],
|
|
11
|
+
"env": {
|
|
12
|
+
"TAVILY_API_KEY": "${TAVILY_API_KEY}"
|
|
13
|
+
},
|
|
14
|
+
"authRequired": true,
|
|
15
|
+
"credentialsUrl": "https://app.tavily.com/home",
|
|
16
|
+
"homepage": "https://tavily.com/"
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
TAVILY_API_KEY
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Todoist MCP Server
|
|
2
|
+
|
|
3
|
+
Todoist MCP server for tasks, projects, and productivity workflows.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
- Node.js + npx
|
|
7
|
+
- Todoist API token
|
|
8
|
+
|
|
9
|
+
## Quick Install
|
|
10
|
+
|
|
11
|
+
### Linux / macOS
|
|
12
|
+
```bash
|
|
13
|
+
cd ~/.openclaw/extensions/mcp-client/servers/todoist
|
|
14
|
+
chmod +x install.sh && ./install.sh
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Windows (PowerShell)
|
|
18
|
+
```powershell
|
|
19
|
+
cd $env:USERPROFILE\.openclaw\extensions\mcp-client\servers\todoist
|
|
20
|
+
.\install.ps1
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Manual Setup
|
|
24
|
+
1. Get your token: https://app.todoist.com/app/settings/integrations/developer
|
|
25
|
+
2. Add to .env: `TODOIST_API_TOKEN=your_token`
|
|
26
|
+
3. Add config to openclaw.json (see config.json)
|
|
27
|
+
4. Restart gateway
|
|
28
|
+
|
|
29
|
+
## What you get
|
|
30
|
+
- Task and project CRUD tools
|
|
31
|
+
- Sections, labels, and comments tools
|
|
32
|
+
- Scheduling and tracking helpers
|
|
33
|
+
|
|
34
|
+
## Remove
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
./install-server.sh todoist --remove
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Removes the server from config and cleans up the API token. The server recipe stays in `servers/todoist/` for easy reinstall.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"name": "todoist",
|
|
4
|
+
"description": "task management",
|
|
5
|
+
"transport": "stdio",
|
|
6
|
+
"command": "npx",
|
|
7
|
+
"args": [
|
|
8
|
+
"-y",
|
|
9
|
+
"@doist/todoist-ai"
|
|
10
|
+
],
|
|
11
|
+
"env": {
|
|
12
|
+
"TODOIST_API_KEY": "${TODOIST_API_TOKEN}"
|
|
13
|
+
},
|
|
14
|
+
"authRequired": true,
|
|
15
|
+
"credentialsUrl": "https://app.todoist.com/app/settings/integrations/developer",
|
|
16
|
+
"homepage": "https://todoist.com/"
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
TODOIST_API_TOKEN
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Wise MCP Server
|
|
2
|
+
|
|
3
|
+
Wise MCP server for multi-currency account and transfer workflows.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
- Git
|
|
7
|
+
- Node.js + npm
|
|
8
|
+
- Wise API token
|
|
9
|
+
|
|
10
|
+
## Quick Install
|
|
11
|
+
|
|
12
|
+
### Linux / macOS
|
|
13
|
+
```bash
|
|
14
|
+
cd ~/.openclaw/extensions/mcp-client/servers/wise
|
|
15
|
+
chmod +x install.sh && ./install.sh
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Windows (PowerShell)
|
|
19
|
+
```powershell
|
|
20
|
+
cd $env:USERPROFILE\.openclaw\extensions\mcp-client\servers\wise
|
|
21
|
+
.\install.ps1
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Manual Setup
|
|
25
|
+
1. Get your token: https://wise.com/settings/api-tokens
|
|
26
|
+
2. Add to .env: `WISE_API_TOKEN=your_token`
|
|
27
|
+
3. Add config to openclaw.json (see config.json)
|
|
28
|
+
4. Restart gateway
|
|
29
|
+
|
|
30
|
+
## What you get
|
|
31
|
+
- Profile and balance lookup tools
|
|
32
|
+
- Quote and transfer workflow tools
|
|
33
|
+
- Recipient and transaction tools
|
|
34
|
+
|
|
35
|
+
## Remove
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
./install-server.sh wise --remove
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Removes the server from config and cleans up the API token. The server recipe stays in `servers/wise/` for easy reinstall.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"name": "wise",
|
|
4
|
+
"description": "international payments",
|
|
5
|
+
"transport": "stdio",
|
|
6
|
+
"command": "node",
|
|
7
|
+
"args": [
|
|
8
|
+
"path/to/wise-mcp/dist/cli.js"
|
|
9
|
+
],
|
|
10
|
+
"env": {
|
|
11
|
+
"WISE_API_TOKEN": "${WISE_API_TOKEN}"
|
|
12
|
+
},
|
|
13
|
+
"authRequired": true,
|
|
14
|
+
"credentialsUrl": "https://wise.com/settings/api-tokens",
|
|
15
|
+
"homepage": "https://wise.com/"
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
WISE_API_TOKEN
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { readFileSync, existsSync, mkdirSync, writeFileSync, chmodSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { homedir } from "os";
|
|
4
|
+
import { BridgeConfig, Logger } from "./types.js";
|
|
5
|
+
import { resolveEnvVars } from "./transport-base.js";
|
|
6
|
+
import { randomBytes } from "crypto";
|
|
7
|
+
|
|
8
|
+
const DEFAULT_CONFIG_DIR = join(homedir(), ".mcp-bridge");
|
|
9
|
+
const DEFAULT_CONFIG_FILE = "config.json";
|
|
10
|
+
const DEFAULT_ENV_FILE = ".env";
|
|
11
|
+
|
|
12
|
+
/** Parse a simple KEY=VALUE .env file (no npm dependency). */
|
|
13
|
+
export function parseEnvFile(content: string): Record<string, string> {
|
|
14
|
+
const env: Record<string, string> = {};
|
|
15
|
+
for (const line of content.split("\n")) {
|
|
16
|
+
const trimmed = line.trim();
|
|
17
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
18
|
+
const eqIdx = trimmed.indexOf("=");
|
|
19
|
+
if (eqIdx === -1) continue;
|
|
20
|
+
const key = trimmed.substring(0, eqIdx).trim();
|
|
21
|
+
let value = trimmed.substring(eqIdx + 1).trim();
|
|
22
|
+
// Strip surrounding quotes
|
|
23
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
24
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
25
|
+
value = value.slice(1, -1);
|
|
26
|
+
}
|
|
27
|
+
if (key) env[key] = value;
|
|
28
|
+
}
|
|
29
|
+
return env;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Recursively resolve ${VAR} placeholders in a JSON-compatible value. */
|
|
33
|
+
function resolveConfigValue(value: unknown, extraEnv: Record<string, string | undefined>): unknown {
|
|
34
|
+
if (typeof value === "string") {
|
|
35
|
+
return resolveEnvVars(value, "config value", extraEnv);
|
|
36
|
+
}
|
|
37
|
+
if (Array.isArray(value)) {
|
|
38
|
+
return value.map(item => resolveConfigValue(item, extraEnv));
|
|
39
|
+
}
|
|
40
|
+
if (value !== null && typeof value === "object") {
|
|
41
|
+
const resolved: Record<string, unknown> = {};
|
|
42
|
+
for (const [k, v] of Object.entries(value)) {
|
|
43
|
+
resolved[k] = resolveConfigValue(v, extraEnv);
|
|
44
|
+
}
|
|
45
|
+
return resolved;
|
|
46
|
+
}
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface LoadConfigOptions {
|
|
51
|
+
configPath?: string;
|
|
52
|
+
logger?: Logger;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Load and validate bridge config.
|
|
57
|
+
* 1. Read ~/.mcp-bridge/config.json (or custom path)
|
|
58
|
+
* 2. Parse ~/.mcp-bridge/.env
|
|
59
|
+
* 3. Resolve ${ENV_VAR} in config values
|
|
60
|
+
* 4. Validate required fields
|
|
61
|
+
*/
|
|
62
|
+
export function loadConfig(options: LoadConfigOptions = {}): BridgeConfig {
|
|
63
|
+
const configDir = options.configPath
|
|
64
|
+
? join(options.configPath, "..") // If a file path is given, derive directory
|
|
65
|
+
: DEFAULT_CONFIG_DIR;
|
|
66
|
+
|
|
67
|
+
const configPath = options.configPath || join(DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILE);
|
|
68
|
+
const envPath = join(
|
|
69
|
+
options.configPath ? join(options.configPath, "..") : DEFAULT_CONFIG_DIR,
|
|
70
|
+
DEFAULT_ENV_FILE
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
if (!existsSync(configPath)) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
`Config file not found: ${configPath}\nRun 'mcp-bridge init' to set up.`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Load .env file
|
|
80
|
+
let dotEnv: Record<string, string> = {};
|
|
81
|
+
if (existsSync(envPath)) {
|
|
82
|
+
try {
|
|
83
|
+
dotEnv = parseEnvFile(readFileSync(envPath, "utf-8"));
|
|
84
|
+
} catch (err) {
|
|
85
|
+
options.logger?.warn(`[mcp-bridge] Failed to parse .env file: ${err instanceof Error ? err.message : err}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Merge .env into process.env (don't overwrite existing)
|
|
90
|
+
for (const [key, value] of Object.entries(dotEnv)) {
|
|
91
|
+
if (process.env[key] === undefined) {
|
|
92
|
+
process.env[key] = value;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Read and parse config
|
|
97
|
+
const rawConfig = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
98
|
+
|
|
99
|
+
// Resolve ${VAR} placeholders using .env + process.env
|
|
100
|
+
const mergedEnv: Record<string, string | undefined> = { ...dotEnv };
|
|
101
|
+
for (const [k, v] of Object.entries(process.env)) {
|
|
102
|
+
if (mergedEnv[k] === undefined) mergedEnv[k] = v;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
let config: BridgeConfig;
|
|
106
|
+
try {
|
|
107
|
+
config = resolveConfigValue(rawConfig, mergedEnv) as BridgeConfig;
|
|
108
|
+
} catch (err) {
|
|
109
|
+
throw new Error(`Config resolution failed: ${err instanceof Error ? err.message : err}`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Validate required fields
|
|
113
|
+
if (!config.servers || typeof config.servers !== "object") {
|
|
114
|
+
throw new Error("Config must have a 'servers' object");
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return config;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Get the default config directory path. */
|
|
121
|
+
export function getConfigDir(configPath?: string): string {
|
|
122
|
+
return configPath ? join(configPath, "..") : DEFAULT_CONFIG_DIR;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Initialize the config directory with template files. */
|
|
126
|
+
export function initConfigDir(logger: Logger): void {
|
|
127
|
+
const dir = DEFAULT_CONFIG_DIR;
|
|
128
|
+
|
|
129
|
+
mkdirSync(dir, { recursive: true });
|
|
130
|
+
|
|
131
|
+
// Set directory permissions (Linux/macOS)
|
|
132
|
+
try {
|
|
133
|
+
chmodSync(dir, 0o700);
|
|
134
|
+
} catch { /* Windows doesn't support chmod */ }
|
|
135
|
+
|
|
136
|
+
const configPath = join(dir, DEFAULT_CONFIG_FILE);
|
|
137
|
+
if (!existsSync(configPath)) {
|
|
138
|
+
const template: BridgeConfig = {
|
|
139
|
+
mode: "router",
|
|
140
|
+
servers: {},
|
|
141
|
+
toolPrefix: true,
|
|
142
|
+
connectionTimeoutMs: 5000,
|
|
143
|
+
requestTimeoutMs: 60000,
|
|
144
|
+
routerIdleTimeoutMs: 600000,
|
|
145
|
+
routerMaxConcurrent: 5,
|
|
146
|
+
http: {
|
|
147
|
+
auth: {
|
|
148
|
+
type: "bearer",
|
|
149
|
+
token: "${MCP_BRIDGE_TOKEN}"
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
writeFileSync(configPath, JSON.stringify(template, null, 2) + "\n");
|
|
154
|
+
logger.info(`Created config: ${configPath}`);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const envPath = join(dir, DEFAULT_ENV_FILE);
|
|
158
|
+
if (!existsSync(envPath)) {
|
|
159
|
+
const token = randomBytes(32).toString("hex");
|
|
160
|
+
writeFileSync(envPath, `# MCP Bridge environment variables\nMCP_BRIDGE_TOKEN=${token}\n`);
|
|
161
|
+
try {
|
|
162
|
+
chmodSync(envPath, 0o600);
|
|
163
|
+
} catch { /* Windows */ }
|
|
164
|
+
logger.info(`Created .env: ${envPath} (with generated token)`);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
logger.info(`Config directory ready: ${dir}`);
|
|
168
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Core exports for @aiwerk/mcp-bridge
|
|
2
|
+
|
|
3
|
+
// Transport classes
|
|
4
|
+
export { BaseTransport, resolveEnvVars, resolveEnvRecord, resolveArgs, warnIfNonTlsRemoteUrl } from "./transport-base.js";
|
|
5
|
+
export { StdioTransport } from "./transport-stdio.js";
|
|
6
|
+
export { SseTransport } from "./transport-sse.js";
|
|
7
|
+
export { StreamableHttpTransport } from "./transport-streamable-http.js";
|
|
8
|
+
|
|
9
|
+
// Router
|
|
10
|
+
export { McpRouter } from "./mcp-router.js";
|
|
11
|
+
export type { RouterToolHint, RouterServerStatus, RouterDispatchResponse, RouterTransportRefs } from "./mcp-router.js";
|
|
12
|
+
|
|
13
|
+
// Schema conversion
|
|
14
|
+
export { convertJsonSchemaToTypeBox, createToolParameters, setTypeBoxLoader, setSchemaLogger } from "./schema-convert.js";
|
|
15
|
+
|
|
16
|
+
// Protocol helpers
|
|
17
|
+
export { initializeProtocol, fetchToolsList, PACKAGE_VERSION } from "./protocol.js";
|
|
18
|
+
|
|
19
|
+
// Config
|
|
20
|
+
export { loadConfig, parseEnvFile, initConfigDir, getConfigDir } from "./config.js";
|
|
21
|
+
|
|
22
|
+
// Types
|
|
23
|
+
export type {
|
|
24
|
+
Logger,
|
|
25
|
+
McpServerConfig,
|
|
26
|
+
McpClientConfig,
|
|
27
|
+
McpTool,
|
|
28
|
+
McpRequest,
|
|
29
|
+
McpResponse,
|
|
30
|
+
McpTransport,
|
|
31
|
+
McpServerConnection,
|
|
32
|
+
BridgeConfig,
|
|
33
|
+
} from "./types.js";
|
|
34
|
+
export { nextRequestId } from "./types.js";
|
|
35
|
+
|
|
36
|
+
// Tool naming
|
|
37
|
+
export { pickRegisteredToolName } from "./tool-naming.js";
|
|
38
|
+
|
|
39
|
+
// Standalone server
|
|
40
|
+
export { StandaloneServer } from "./standalone-server.js";
|
|
41
|
+
|
|
42
|
+
// Update checker
|
|
43
|
+
export { checkForUpdate, getUpdateNotice, runUpdate, resetNoticeFlag } from "./update-checker.js";
|
|
44
|
+
export type { UpdateInfo } from "./update-checker.js";
|