Skip to content

Commit 9413433

Browse files
Add API key auth for HTTP transport (#1)
1 parent 8be5ef8 commit 9413433

File tree

6 files changed

+52
-3
lines changed

6 files changed

+52
-3
lines changed

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ LOG_LEVEL=info # Logging level (default: info)
1212
MCP_TRANSPORT_TYPE=stdio # Transport type: 'stdio' or 'http' (default: stdio)
1313
MCP_HTTP_HOST=localhost # HTTP server host (default: localhost)
1414
MCP_HTTP_PORT=3000 # HTTP server port (default: 3000)
15+
MCP_API_KEY=your-api-key-here # API key for HTTP authentication

README.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ LOG_LEVEL=info # Logging level (default: info)
7676
MCP_TRANSPORT_TYPE=stdio # Transport type: 'stdio' or 'http' (default: stdio)
7777
MCP_HTTP_HOST=localhost # HTTP server host (default: localhost)
7878
MCP_HTTP_PORT=3000 # HTTP server port (default: 3000)
79+
MCP_HTTP_API_KEY=your-api-key-here # API key for HTTP authentication (used only for 'http' transport type)
7980
```
8081

8182
**⚠️ Important:** Never commit your `.env` file to version control!
@@ -122,6 +123,7 @@ For clients that support HTTP transport, configure the server with HTTP transpor
122123
MCP_TRANSPORT_TYPE=http
123124
MCP_HTTP_HOST=localhost
124125
MCP_HTTP_PORT=3000
126+
MCP_HTTP_API_KEY=your-api-key-here
125127

126128
# Start server
127129
npm start
@@ -135,6 +137,8 @@ The server will be available at:
135137
- `GET /mcp` - Server-to-client notifications (SSE)
136138
- `DELETE /mcp` - Session termination
137139

140+
**🔐 Authentication**: When using HTTP transport, it's highly recommended to include the `x-api-key` header in your requests. The value should match the `MCP_HTTP_API_KEY` from your configuration.
141+
138142
## 🐳 Docker Deployment
139143

140144
For easy deployment and containerized environments, you can run the MCP server using Docker.
@@ -147,9 +151,10 @@ Example `.env` configuration for Docker:
147151

148152
```bash
149153
# MCP Server Configuration
154+
MCP_TRANSPORT_TYPE=http
150155
MCP_HTTP_HOST=0.0.0.0
151156
MCP_HTTP_PORT=3000
152-
MCP_TRANSPORT_TYPE=http
157+
MCP_HTTP_API_KEY=your-api-key-here
153158

154159
# Fibaro HC3 Configuration (Required)
155160
HC3_HOST=192.168.1.100
@@ -180,19 +185,23 @@ Configure Claude Desktop to connect to the Docker container:
180185
"mcpServers": {
181186
"mcp-server-hc3": {
182187
"command": "curl",
183-
"args": ["-X", "POST", "-H", "Content-Type: application/json", "http://localhost:3000/mcp"]
188+
"args": ["-X", "POST", "-H", "Content-Type: application/json", "-H", "x-api-key: your-api-key-here", "http://localhost:3000/mcp"]
184189
}
185190
}
186191
}
187192
```
188193

194+
**🔐 Authentication**: Include the `x-api-key` header with the value matching your `MCP_HTTP_API_KEY` configuration for secure access.
195+
189196
#### **Custom MCP Client Integration**
190197

191198
Connect to the Docker container via HTTP:
192199

193200
- **Endpoint**: `http://localhost:3000/mcp`
194201
- **Transport**: HTTP-based MCP protocol
195-
- **Headers**: `Content-Type: application/json`
202+
- **Headers**:
203+
- `Content-Type: application/json`
204+
- `x-api-key: your-api-key-here` (highly recommended, should match `MCP_HTTP_API_KEY`)
196205

197206
## 🛠️ Development
198207

@@ -214,6 +223,7 @@ Connect to the Docker container via HTTP:
214223
| `MCP_TRANSPORT_TYPE` || `stdio` | Transport type: 'stdio' or 'http' |
215224
| `MCP_HTTP_HOST` || `localhost` | HTTP server bind address |
216225
| `MCP_HTTP_PORT` || `3000` | HTTP server port |
226+
| `MCP_HTTP_API_KEY` || - | API key for HTTP authentication |
217227

218228
### **Available Scripts**
219229

docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ services:
1212
- MCP_HTTP_HOST=0.0.0.0
1313
- MCP_HTTP_PORT=${MCP_HTTP_PORT:-3000}
1414
- MCP_TRANSPORT_TYPE=${MCP_TRANSPORT_TYPE:-http}
15+
- MCP_HTTP_API_KEY=${MCP_HTTP_API_KEY}
1516

1617
# HC3 Configuration (Required)
1718
- HC3_HOST=${HC3_HOST}

src/config/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { createConfigLogger } from '../logger.js';
44
const ConfigSchema = z.object({
55
MCP_HTTP_HOST: z.string().default('localhost'),
66
MCP_HTTP_PORT: z.coerce.number().int().positive().default(3000),
7+
MCP_HTTP_API_KEY: z.string().optional(),
78
MCP_TRANSPORT_TYPE: z.enum(['stdio', 'http']).default('stdio'),
89

910
HC3_HOST: z.string().min(1, 'HC3_HOST is required'),

src/mcp/auth.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import type { Request, Response, NextFunction } from 'express';
2+
import { getConfig } from '../config/index.js';
3+
import { getLogger } from '../logger.js';
4+
5+
/**
6+
* API Key authentication middleware
7+
*/
8+
export function auth(req: Request, res: Response, next: NextFunction): void {
9+
const config = getConfig();
10+
const logger = getLogger();
11+
12+
// Skip authentication if no API key is configured
13+
if (!config.MCP_HTTP_API_KEY) {
14+
logger.warn('⚠️ No MCP_HTTP_API_KEY configured - HTTP transport is unprotected');
15+
return next();
16+
}
17+
18+
const apiKey = req.headers['x-api-key'] as string | undefined;
19+
20+
if (!apiKey || apiKey !== config.MCP_HTTP_API_KEY) {
21+
logger.warn('Invalid API key provided');
22+
res.status(401).json({
23+
jsonrpc: '2.0',
24+
error: {
25+
code: -32001,
26+
message: 'Unauthorized',
27+
},
28+
id: null,
29+
});
30+
return;
31+
}
32+
33+
next();
34+
}

src/mcp/http.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
44
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
55
import type { HttpTransportConfig } from './types.js';
66
import { getLogger } from '../logger.js';
7+
import { auth } from './auth.js';
78

89
/**
910
* Set up HTTP transport for the MCP server using Express and StreamableHTTPServerTransport
@@ -19,6 +20,7 @@ export async function setupHttpTransport(
1920
const app = express.default();
2021

2122
app.use(express.default.json());
23+
app.use(auth);
2224

2325
// Store transports by session ID
2426
const transports: { [sessionId: string]: StreamableHTTPServerTransport } = {};

0 commit comments

Comments
 (0)