Migrate to MCP SDK v2 (dual-era) + security hardening + convertTime — v3.0.0 - #44
Merged
Conversation
Move from the monolithic @modelcontextprotocol/sdk to the v2 scoped packages (server/node/express). The same server now serves both the 2026-07-28 and legacy 2025-era protocols from one factory. - stdio via serveStdio(), HTTP via createMcpHandler() + toNodeHandler() - request context is ctx.mcpReq (signal, notify-based progress) - errors use ProtocolError / ProtocolErrorCode - handler returns typed against SDK result types (no 'as any') - resources/read validates the URI and returns InvalidParams (-32602) - experimental tasks removed (no v2 equivalent; moved to Extensions Track) - drop the zod dependency (now transitive via the SDK) and require Node 20
- add HTTP transport usage (--transport http, --port, --allowed-origins) and the Origin/403 DNS-rebinding note to the README and integration guide - fix the read-only description: it blocks write tools and aggregation write/JS operators, and no longer claims a secondary read preference - add a Security section recommending a read-only DB user for defense in depth - note the Node 20 requirement
Three limits surfaced while probing the server: - HTTP request bodies were capped at Express's 100kb default, far below stdio's ~10mb. Default to 10mb and make it configurable via --json-limit or MCP_HTTP_JSON_LIMIT. - Body-parser failures (payload too large, malformed JSON) returned an HTML error page; they now return a proper JSON-RPC error. - Deeply nested input could overflow the stack in processObjectIdInFilter; it now rejects nesting beyond 100 levels (MongoDB's own BSON limit) with a clear error.
An aggregation $out/$merge/$lookup targeting a different database could read from or write to any database the connection's credentials allow, escaping the database the server was pointed at. These stages are now rejected when their target database differs from the connected one. Opt back in to cross-database pipelines with --allow-cross-db or MCP_MONGODB_ALLOW_CROSS_DB=true. Same-database operations are unaffected.
- add --allow-cross-db / MCP_MONGODB_ALLOW_CROSS_DB and --json-limit / MCP_HTTP_JSON_LIMIT to the options and env tables - expand the Security section: database scope, read-only coverage of write/JS aggregation stages, and least-privilege DB users - note the 10mb HTTP body default and how to change it in the integration guide
…ction guard Aggregation $function/$where/$accumulator run arbitrary JavaScript on the MongoDB server (a code-execution and DoS surface). They are now rejected by default even outside read-only mode; opt back in with --allow-server-js or MCP_MONGODB_ALLOW_SERVER_JS=true. Also make the system-collection guard case-insensitive so casings like 'System.' can't slip past it. Documents the new flag in the README.
findAggOperator recurses over the whole pipeline for the read-only and server-side-JS checks, which run before processObjectIdInFilter's depth guard. A pathologically deep pipeline could overflow the stack there first, surfacing an opaque 'Maximum call stack size exceeded'. It now enforces the same MAX_OBJECT_DEPTH limit and reports a clear error.
Add --auth-token / MCP_HTTP_AUTH_TOKEN to require an 'Authorization: Bearer <token>' header on the HTTP endpoint. Missing or invalid tokens get a 401 with a WWW-Authenticate Bearer challenge; the token is compared in constant time. When unset, the endpoint stays open as before. This is a simple shared-secret check aligned with the MCP authorization spec's bearer mechanism, not a full OAuth flow (stdio keeps using environment-based credentials). Documented in the README and integration guide.
Add a convertTime tool that reports the current server time (with timezone) or converts a Unix timestamp / date string into UTC ISO 8601, GMT, and Unix seconds/milliseconds. This lets clients build unambiguous date queries when the server and user are in different timezones. Also broaden the date-string detection used when parsing filters to accept an explicit numeric offset (e.g. +03:00) in addition to 'Z', so offset-qualified timestamps convert to the correct instant. Timezone-less strings are still left untouched to avoid server-local interpretation.
The query handler already applied a sort option, but the query tool never declared 'sort' in its inputSchema, so the SDK dropped the argument before it reached the handler — sort was silently ignored and results came back in natural order. Declaring it makes sorting work through the tool interface.
Owner
Author
|
@modelcontextprotocol/server@2.0.0 is out. mcp-mongo-server can be verified and published with major version bump. |
kiliczsh
marked this pull request as ready for review
July 29, 2026 11:28
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Migrates
mcp-mongo-serverto the MCP SDK v2 while keeping full backward compatibility, and layers on a round of security hardening and two new capabilities.Pins
@modelcontextprotocol/*@^2.0.0(stable) and releases as3.0.0(major — see Breaking changes).What changed
Protocol / SDK
@modelcontextprotocol/server,/node,/express). UsesserveStdiofor stdio andcreateMcpHandler+toNodeHandlerfor HTTP.2026-07-28protocol while still serving legacy2025-11-25clients, so existing integrations keep working.InvalidParams(-32602) viaProtocolErrorinstead of the legacy-32002.readPreferencein read-only mode (was silently steering reads to secondaries).Security hardening (all opt-in, safe by default)
$lookup/$out/$mergeinto another db) are rejected unless--allow-cross-db(MCP_MONGODB_ALLOW_CROSS_DB).$where,$function,$accumulator,mapReducerequire--allow-server-js(MCP_MONGODB_ALLOW_SERVER_JS).system.*match) for both tools and resources.--json-limit/MCP_HTTP_JSON_LIMIT); oversized/malformed bodies return a proper JSON-RPC error instead of a raw stack.--auth-token/MCP_HTTP_AUTH_TOKEN), constant-time comparison, no separate auth server needed.Features & fixes
convertTimetool — converts a Unix timestamp or date string into UTC ISO 8601 / GMT / Unix seconds & ms, and reports the server's current time and timezone. Helps build unambiguous date queries across timezones. Date filters now honor explicit timezone offsets.sortparameter fix — thequerytool now declaressortin its input schema; previously the SDK stripped it, so sorts were silently ignored.createIndexresult fix — the driver returns the created index names (string[]), not the object the handler assumed, so success responses came back as an empty{}. Now returns{ acknowledged, createdIndexes, indexCount }.Docs
docs/updated: HTTP transport, all new flags/env vars, security section,convertTime, bearer auth, corrected read-only behavior.Breaking changes (why
3.0.0)2026-07-28protocol (legacy2025-11-25clients still supported).Validation
buildandbiome lintpass (0 warnings).serverInfo,listCollections,count,queryincl. sort,aggregate,insert,update,createIndex,convertTime).bun audit: 3 moderate advisories (ajvReDoS via$data) — transitive through the SDK, not exercised by this code.