Skip to content

Commit 2275dcc

Browse files
cablateclaude
andcommitted
feat: add --host CLI option to bind server to a specific hostname (#76)
Adds --host CLI argument and MCP_SERVER_HOST env var to control which network interface the HTTP server binds to. Defaults to 0.0.0.0 (all interfaces) for remote access support. - BaseMcpServer.startHttpServer now accepts host parameter - CLI: --host option with MCP_SERVER_HOST env var fallback - Log messages show actual bound host instead of hardcoded localhost - Updated README (EN + zh-TW) with --host examples and env var docs Closes #76 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 9f3253f commit 2275dcc

5 files changed

Lines changed: 33 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 0.0.52
4+
5+
- feat: add `--host` CLI option to bind server to a specific hostname (#76)
6+
37
## 0.0.51
48

59
- fix: improve transit error messages for unsupported regions (#75)

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ For multi-session deployments, per-request API key isolation, or remote access:
126126

127127
```bash
128128
npx @cablate/mcp-google-map --port 3000 --apikey "YOUR_API_KEY"
129+
130+
# Bind to all interfaces for remote access (e.g. Docker, LAN)
131+
npx @cablate/mcp-google-map --host 0.0.0.0 --port 3000 --apikey "YOUR_API_KEY"
129132
```
130133

131134
Then configure your MCP client:
@@ -198,6 +201,7 @@ API keys can be provided in three ways (priority order):
198201
```env
199202
GOOGLE_MAPS_API_KEY=your_api_key_here
200203
MCP_SERVER_PORT=3000
204+
MCP_SERVER_HOST=0.0.0.0
201205
```
202206

203207
## Development

README.zh-TW.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ npx @cablate/mcp-google-map --port 3000 --apikey "YOUR_API_KEY"
126126

127127
```bash
128128
npx @cablate/mcp-google-map --port 3000 --apikey "YOUR_API_KEY"
129+
130+
# 綁定所有網路介面以支援遠端存取(例如 Docker、區域網路)
131+
npx @cablate/mcp-google-map --host 0.0.0.0 --port 3000 --apikey "YOUR_API_KEY"
129132
```
130133

131134
然後設定你的 MCP 客戶端:
@@ -196,6 +199,7 @@ API key 可透過三種方式提供(優先順序):
196199
```env
197200
GOOGLE_MAPS_API_KEY=your_api_key_here
198201
MCP_SERVER_PORT=3000
202+
MCP_SERVER_HOST=0.0.0.0
199203
```
200204

201205
## 開發

src/cli.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,17 @@ dotenvConfig({ path: resolve(process.cwd(), ".env") });
2222
// Also try to load from the package installation directory
2323
dotenvConfig({ path: resolve(__dirname, "../.env") });
2424

25-
export async function startServer(port?: number, apiKey?: string): Promise<void> {
25+
export async function startServer(port?: number, apiKey?: string, host?: string): Promise<void> {
2626
// Override environment variables with CLI arguments if provided
2727
if (port) {
2828
process.env.MCP_SERVER_PORT = port.toString();
2929
}
3030
if (apiKey) {
3131
process.env.GOOGLE_MAPS_API_KEY = apiKey;
3232
}
33+
if (host) {
34+
process.env.MCP_SERVER_HOST = host;
35+
}
3336

3437
Logger.log("🚀 Starting Google Maps MCP Server...");
3538
Logger.log("📍 18 tools registered (set GOOGLE_MAPS_ENABLED_TOOLS to limit)");
@@ -55,10 +58,12 @@ export async function startServer(port?: number, apiKey?: string): Promise<void>
5558

5659
try {
5760
const server = new BaseMcpServer(config.name, filterTools(config.tools));
58-
Logger.log(`🔧 [${config.name}] Initializing MCP Server in HTTP mode on port ${serverPort}...`);
59-
await server.startHttpServer(serverPort);
61+
const serverHost = process.env.MCP_SERVER_HOST || "0.0.0.0";
62+
Logger.log(`🔧 [${config.name}] Initializing MCP Server in HTTP mode on ${serverHost}:${serverPort}...`);
63+
await server.startHttpServer(serverPort, serverHost);
64+
const displayHost = serverHost === "0.0.0.0" ? "localhost" : serverHost;
6065
Logger.log(`✅ [${config.name}] MCP Server started successfully!`);
61-
Logger.log(` 🌐 Endpoint: http://localhost:${serverPort}/mcp`);
66+
Logger.log(` 🌐 Endpoint: http://${displayHost}:${serverPort}/mcp`);
6267
Logger.log(` 📚 Tools: ${config.tools.length} available`);
6368
} catch (error) {
6469
Logger.error(`❌ [${config.name}] Failed to start MCP Server on port ${serverPort}:`, error);
@@ -423,6 +428,11 @@ if (isRunDirectly || isMainModule) {
423428
description: "Port to run the MCP server on",
424429
default: process.env.MCP_SERVER_PORT ? parseInt(process.env.MCP_SERVER_PORT) : 3000,
425430
})
431+
.option("host", {
432+
type: "string",
433+
description: "Hostname to bind the server to (e.g. 0.0.0.0 for all interfaces)",
434+
default: process.env.MCP_SERVER_HOST || "0.0.0.0",
435+
})
426436
.option("apikey", {
427437
alias: "k",
428438
type: "string",
@@ -437,6 +447,7 @@ if (isRunDirectly || isMainModule) {
437447
.example([
438448
["$0", "Start HTTP server with default settings"],
439449
['$0 --port 3000 --apikey "your_api_key"', "Start HTTP with custom port and API key"],
450+
["$0 --host 0.0.0.0 --port 3000", "Start HTTP accessible from all interfaces"],
440451
["$0 --stdio", "Start in stdio mode (for Claude Desktop, Cursor, etc.)"],
441452
]);
442453
},
@@ -463,7 +474,7 @@ if (isRunDirectly || isMainModule) {
463474
Logger.log("");
464475
}
465476

466-
startServer(argv.port as number, argv.apikey as string).catch((error) => {
477+
startServer(argv.port as number, argv.apikey as string, argv.host as string).catch((error) => {
467478
Logger.error("❌ Failed to start server:", error);
468479
process.exit(1);
469480
});

src/core/BaseMcpServer.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export class BaseMcpServer {
7474
Logger.log(`${this.serverName} connected and ready to process requests`);
7575
}
7676

77-
async startHttpServer(port: number): Promise<void> {
77+
async startHttpServer(port: number, host: string = "0.0.0.0"): Promise<void> {
7878
const app = express();
7979
app.use(express.json());
8080

@@ -174,9 +174,10 @@ export class BaseMcpServer {
174174
// Handle DELETE requests for session termination
175175
app.delete("/mcp", handleSessionRequest);
176176

177-
this.httpServer = app.listen(port, () => {
178-
Logger.log(`[${this.serverName}] HTTP server listening on port ${port}`);
179-
Logger.log(`[${this.serverName}] MCP endpoint available at http://localhost:${port}/mcp`);
177+
const displayHost = host === "0.0.0.0" ? "localhost" : host;
178+
this.httpServer = app.listen(port, host, () => {
179+
Logger.log(`[${this.serverName}] HTTP server listening on ${host}:${port}`);
180+
Logger.log(`[${this.serverName}] MCP endpoint available at http://${displayHost}:${port}/mcp`);
180181
});
181182
}
182183

0 commit comments

Comments
 (0)