Skip to content

Commit a453048

Browse files
committed
feat: add streamable http
1 parent b10990b commit a453048

File tree

12 files changed

+271
-62
lines changed

12 files changed

+271
-62
lines changed

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ RUN addgroup -S mcp && adduser -S mcp -G mcp
44
RUN npm install -g mongodb-mcp-server@${VERSION}
55
USER mcp
66
WORKDIR /home/mcp
7+
ENV MDB_MCP_LOGGERS=stderr,mcp
78
ENTRYPOINT ["mongodb-mcp-server"]
89
LABEL maintainer="MongoDB Inc <[email protected]>"
910
LABEL description="MongoDB MCP Server"

README.md

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,27 @@ With Atlas API credentials:
225225
}
226226
```
227227

228+
#### Option 6: Running as an HTTP Server
229+
230+
You can run the MongoDB MCP Server as an HTTP server instead of the default stdio transport. This is useful if you want to interact with the server over HTTP, for example from a web client or to expose the server on a specific port.
231+
232+
To start the server with HTTP transport, use the `--transport http` option:
233+
234+
```shell
235+
npx -y mongodb-mcp-server --transport http
236+
```
237+
238+
By default, the server will listen on `http://127.0.0.1:3000`. You can customize the host and port using the `--httpHost` and `--httpPort` options:
239+
240+
```shell
241+
npx -y mongodb-mcp-server --transport http --httpHost=0.0.0.0 --httpPort=8080
242+
```
243+
244+
- `--httpHost` (default: 127.0.0.1): The host to bind the HTTP server.
245+
- `--httpPort` (default: 3000): The port number for the HTTP server.
246+
247+
> **Note:** The default transport is `stdio`, which is suitable for integration with most MCP clients. Use `http` transport if you need to interact with the server over HTTP.
248+
228249
## 🛠️ Supported Tools
229250

230251
### Tool List
@@ -278,16 +299,20 @@ The MongoDB MCP Server can be configured using multiple methods, with the follow
278299

279300
### Configuration Options
280301

281-
| Option | Description |
282-
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
283-
| `apiClientId` | Atlas API client ID for authentication. Required for running Atlas tools. |
284-
| `apiClientSecret` | Atlas API client secret for authentication. Required for running Atlas tools. |
285-
| `connectionString` | MongoDB connection string for direct database connections. Optional, if not set, you'll need to call the `connect` tool before interacting with MongoDB data. |
286-
| `logPath` | Folder to store logs. |
287-
| `disabledTools` | An array of tool names, operation types, and/or categories of tools that will be disabled. |
288-
| `readOnly` | When set to true, only allows read, connect, and metadata operation types, disabling create/update/delete operations. |
289-
| `indexCheck` | When set to true, enforces that query operations must use an index, rejecting queries that perform a collection scan. |
290-
| `telemetry` | When set to disabled, disables telemetry collection. |
302+
| Option | Default | Description |
303+
| ------------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
304+
| `apiClientId` | <not set> | Atlas API client ID for authentication. Required for running Atlas tools. |
305+
| `apiClientSecret` | <not set> | Atlas API client secret for authentication. Required for running Atlas tools. |
306+
| `connectionString` | <not set> | MongoDB connection string for direct database connections. Optional, if not set, you'll need to call the `connect` tool before interacting with MongoDB data. |
307+
| `logPath` | see note* | Folder to store logs. |
308+
| `disabledTools` | <not set> | An array of tool names, operation types, and/or categories of tools that will be disabled. |
309+
| `readOnly` | false | When set to true, only allows read, connect, and metadata operation types, disabling create/update/delete operations. |
310+
| `indexCheck` | false | When set to true, enforces that query operations must use an index, rejecting queries that perform a collection scan. |
311+
| `telemetry` | enabled | When set to disabled, disables telemetry collection. |
312+
| `transport` | stdio | Either 'stdio' or 'http'. |
313+
| `httpPort` | 3000 | Port number. |
314+
| `httpHost` | 127.0.0.1 | Host to bind the http server. |
315+
| `logger` | disk,mcp | Comma separated values, possible values are `mcp`, `disk` and `stderr`. |
291316

292317
#### Log Path
293318

package-lock.json

Lines changed: 99 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"@jest/globals": "^30.0.4",
3838
"@modelcontextprotocol/inspector": "^0.16.0",
3939
"@redocly/cli": "^1.34.4",
40+
"@types/express": "^5.0.1",
4041
"@types/jest": "^30.0.0",
4142
"@types/node": "^24.0.12",
4243
"@types/simple-oauth2": "^5.0.7",
@@ -65,6 +66,7 @@
6566
"@mongodb-js/devtools-connect": "^3.7.2",
6667
"@mongosh/service-provider-node-driver": "^3.6.0",
6768
"bson": "^6.10.4",
69+
"express": "^5.1.0",
6870
"lru-cache": "^11.1.0",
6971
"mongodb": "^6.17.0",
7072
"mongodb-connection-string-url": "^3.0.2",

src/common/config.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,17 @@ export interface UserConfig {
1717
apiBaseUrl: string;
1818
apiClientId?: string;
1919
apiClientSecret?: string;
20-
telemetry?: "enabled" | "disabled";
20+
telemetry: "enabled" | "disabled";
2121
logPath: string;
2222
connectionString?: string;
2323
connectOptions: ConnectOptions;
2424
disabledTools: Array<string>;
2525
readOnly?: boolean;
2626
indexCheck?: boolean;
27+
transport: "stdio" | "http";
28+
httpPort: number;
29+
httpHost: string;
30+
loggers: Array<"stderr" | "disk" | "mcp">;
2731
}
2832

2933
const defaults: UserConfig = {
@@ -39,6 +43,10 @@ const defaults: UserConfig = {
3943
telemetry: "enabled",
4044
readOnly: false,
4145
indexCheck: false,
46+
transport: "stdio",
47+
httpPort: 3000,
48+
httpHost: "127.0.0.1",
49+
loggers: ["disk", "mcp"],
4250
};
4351

4452
export const config = {

src/common/logger.ts

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,16 @@ export const LogId = {
3737
mongodbDisconnectFailure: mongoLogId(1_004_002),
3838

3939
toolUpdateFailure: mongoLogId(1_005_001),
40+
41+
streamableHttpTransportStarted: mongoLogId(1_006_001),
42+
streamableHttpTransportSessionInitialized: mongoLogId(1_006_002),
43+
streamableHttpTransportRequestFailure: mongoLogId(1_006_003),
44+
streamableHttpTransportCloseRequested: mongoLogId(1_006_004),
45+
streamableHttpTransportCloseSuccess: mongoLogId(1_006_005),
46+
streamableHttpTransportCloseFailure: mongoLogId(1_006_006),
4047
} as const;
4148

42-
abstract class LoggerBase {
49+
export abstract class LoggerBase {
4350
abstract log(level: LogLevel, id: MongoLogId, context: string, message: string): void;
4451

4552
info(id: MongoLogId, context: string, message: string): void {
@@ -74,14 +81,14 @@ abstract class LoggerBase {
7481
}
7582
}
7683

77-
class ConsoleLogger extends LoggerBase {
84+
export class ConsoleLogger extends LoggerBase {
7885
log(level: LogLevel, id: MongoLogId, context: string, message: string): void {
7986
message = redact(message);
80-
console.error(`[${level.toUpperCase()}] ${id.__value} - ${context}: ${message}`);
87+
console.error(`[${level.toUpperCase()}] ${id.__value} - ${context}: ${message} (${process.pid})`);
8188
}
8289
}
8390

84-
class DiskLogger extends LoggerBase {
91+
export class DiskLogger extends LoggerBase {
8592
private constructor(private logWriter: MongoLogWriter) {
8693
super();
8794
}
@@ -133,7 +140,7 @@ class DiskLogger extends LoggerBase {
133140
}
134141
}
135142

136-
class McpLogger extends LoggerBase {
143+
export class McpLogger extends LoggerBase {
137144
constructor(private server: McpServer) {
138145
super();
139146
}
@@ -152,18 +159,12 @@ class McpLogger extends LoggerBase {
152159
}
153160

154161
class CompositeLogger extends LoggerBase {
155-
private loggers: LoggerBase[];
162+
private loggers: LoggerBase[] = [];
156163

157164
constructor(...loggers: LoggerBase[]) {
158165
super();
159166

160-
if (loggers.length === 0) {
161-
// default to ConsoleLogger
162-
this.loggers = [new ConsoleLogger()];
163-
return;
164-
}
165-
166-
this.loggers = [...loggers];
167+
this.setLoggers(...loggers);
167168
}
168169

169170
setLoggers(...loggers: LoggerBase[]): void {
@@ -180,19 +181,5 @@ class CompositeLogger extends LoggerBase {
180181
}
181182
}
182183

183-
const logger = new CompositeLogger();
184-
export default logger;
185-
186-
export async function setStdioPreset(server: McpServer, logPath: string): Promise<void> {
187-
const diskLogger = await DiskLogger.fromPath(logPath);
188-
const mcpLogger = new McpLogger(server);
189-
190-
logger.setLoggers(mcpLogger, diskLogger);
191-
}
192-
193-
export function setContainerPreset(server: McpServer): void {
194-
const mcpLogger = new McpLogger(server);
195-
const consoleLogger = new ConsoleLogger();
196-
197-
logger.setLoggers(mcpLogger, consoleLogger);
198-
}
184+
const logger = new CompositeLogger(new ConsoleLogger());
185+
export default logger;

0 commit comments

Comments
 (0)