Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ npmPreapprovedPackages:
# npmMinimalAgeGate window.
- 'nx'
- '@nx/*'
# TODO: remove once undici@7.30.2 (published 2026-11-05) is older than the
# npmMinimalAgeGate window. 7.30.2 is the security release fixing
# CVE-2026-116592, -120474, -120415, -120423, -120222 and -116630.
- 'undici'
4 changes: 2 additions & 2 deletions packages/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"@hyperdx/common-utils": "^0.32.0",
"@hyperdx/node-opentelemetry": "^0.9.0",
"@hyperdx/passport-local-mongoose": "^9.0.1",
"@modelcontextprotocol/sdk": "^1.27.1",
"@modelcontextprotocol/sdk": "^1.32.2",
"@opentelemetry/api": "^1.8.0",
"@opentelemetry/host-metrics": "^0.35.5",
"@opentelemetry/sdk-metrics": "^1.30.1",
Expand All @@ -50,7 +50,7 @@
"lodash": "^4.18.1",
"minimist": "^1.2.7",
"mongodb": "^6.15.0",
"mongoose": "^6.13.10",
"mongoose": "^6.13.12",
"ms": "^2.1.3",
"on-headers": "^1.1.0",
"passport": "^0.6.0",
Expand Down
32 changes: 32 additions & 0 deletions packages/api/src/mcp/__tests__/toolInputLimit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { MAX_TOOL_INPUT_ELEMENTS } from '@/mcp/mcpServer';
import { McpContext } from '@/mcp/tools/types';

import { callTool, createTestClient, getFirstText } from './mcpTestUtils';

const context: McpContext = { teamId: 'team-id', userId: 'user-id' };

// GHSA-46jr-4wx8-v453 / CVE-2026-111768: without maxToolInputElements the SDK
// validates arbitrarily many array elements / object keys per tool call and
// can be driven into heap exhaustion. The element count is checked before the
// tool's schema runs, so any registered tool exercises it.
describe('MCP tool input element limit', () => {
it('bounds the limit well above any model-generated tool input', () => {
expect(MAX_TOOL_INPUT_ELEMENTS).toBeGreaterThanOrEqual(10_000);
expect(Number.isFinite(MAX_TOOL_INPUT_ELEMENTS)).toBe(true);
});

it('rejects a tool call whose arguments exceed the limit', async () => {
const client = await createTestClient(context);
const { tools } = await client.listTools();
expect(tools.length).toBeGreaterThan(0);

const result = await callTool(client, tools[0].name, {
padding: new Array(MAX_TOOL_INPUT_ELEMENTS + 1).fill(0),
});

expect(result.isError).toBe(true);
expect(getFirstText(result)).toContain(
`more than the maximum of ${MAX_TOOL_INPUT_ELEMENTS} elements`,
);
});
});
7 changes: 7 additions & 0 deletions packages/api/src/mcp/mcpServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,16 @@ const SERVER_INFO: Implementation = {
}),
};

// Upper bound on array elements + object members in one tools/call `arguments`
// payload (GHSA-46jr-4wx8-v453): the SDK leaves it unlimited by default, which
// lets one request exhaust the heap during validation. Model-generated tool
// input stays orders of magnitude below this.
export const MAX_TOOL_INPUT_ELEMENTS = 100_000;

export function createServer(context: McpContext) {
const server = new McpServer(SERVER_INFO, {
instructions: SERVER_INSTRUCTIONS,
maxToolInputElements: MAX_TOOL_INPUT_ELEMENTS,
});

const registerTool = createRegisterTool(server, context);
Expand Down
4 changes: 2 additions & 2 deletions packages/otel-collector/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ require (

require (
github.com/ClickHouse/ch-go v0.71.0 // indirect
github.com/andybalholm/brotli v1.2.0 // indirect
github.com/andybalholm/brotli v1.2.7 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/go-faster/city v1.0.1 // indirect
github.com/go-faster/errors v0.7.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/klauspost/compress v1.18.3 // indirect
github.com/klauspost/compress v1.20.2 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/mfridman/interpolate v0.0.2 // indirect
github.com/paulmach/orb v0.12.0 // indirect
Expand Down
8 changes: 4 additions & 4 deletions packages/otel-collector/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ github.com/ClickHouse/ch-go v0.71.0 h1:bUdZ/EZj/LcVHsMqaRUP2holqygrPWQKeMjc6nZoy
github.com/ClickHouse/ch-go v0.71.0/go.mod h1:NwbNc+7jaqfY58dmdDUbG4Jl22vThgx1cYjBw0vtgXw=
github.com/ClickHouse/clickhouse-go/v2 v2.43.0 h1:fUR05TrF1GyvLDa/mAQjkx7KbgwdLRffs2n9O3WobtE=
github.com/ClickHouse/clickhouse-go/v2 v2.43.0/go.mod h1:o6jf7JM/zveWC/PP277BLxjHy5KjnGX/jfljhM4s34g=
github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
github.com/andybalholm/brotli v1.2.7 h1:UgafRPGMam5ySHfRkhthMqOFA6IFoeF3D7mWIDLjG5A=
github.com/andybalholm/brotli v1.2.7/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
Expand All @@ -28,8 +28,8 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.18.3 h1:9PJRvfbmTabkOX8moIpXPbMMbYN60bWImDDU7L+/6zw=
github.com/klauspost/compress v1.18.3/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
github.com/klauspost/compress v1.20.2 h1:v5tiZvm1KGLyg5d5oXdXe3lsSPrbEUiKoXGia//I7Qo=
github.com/klauspost/compress v1.20.2/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
Expand Down
48 changes: 24 additions & 24 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4662,12 +4662,12 @@ __metadata:
languageName: node
linkType: hard

"@hono/node-server@npm:^1.19.9":
version: 1.19.17
resolution: "@hono/node-server@npm:1.19.17"
"@hono/node-server@npm:^1.19.9 || ^2.0.5":
version: 2.1.6
resolution: "@hono/node-server@npm:2.1.6"
peerDependencies:
hono: ^4
checksum: 10c0/e77907e3b5db8ab68ed4f297ad84807bfdd698636408de86ab8d36dab4658504ac4c0ed9d9436bc272a0172b9b7a5a4b578532e0b5baf97674c7b420cb5cff4b
hono: ^4 || ^5.0.0-0
checksum: 10c0/bb57a4e00f193b37f1e7c8a4b8206914ab3f6073d8e7da7ca4b005f0205d89ef9cd0bdb783a4b59869a4c9211f1567f3e0717f31e92704ed7b1801a33d3252d3
languageName: node
linkType: hard

Expand Down Expand Up @@ -4724,7 +4724,7 @@ __metadata:
"@hyperdx/common-utils": "npm:^0.32.0"
"@hyperdx/node-opentelemetry": "npm:^0.9.0"
"@hyperdx/passport-local-mongoose": "npm:^9.0.1"
"@modelcontextprotocol/sdk": "npm:^1.27.1"
"@modelcontextprotocol/sdk": "npm:^1.32.2"
"@opentelemetry/api": "npm:^1.8.0"
"@opentelemetry/host-metrics": "npm:^0.35.5"
"@opentelemetry/sdk-metrics": "npm:^1.30.1"
Expand Down Expand Up @@ -4767,7 +4767,7 @@ __metadata:
migrate-mongo: "npm:^11.0.0"
minimist: "npm:^1.2.7"
mongodb: "npm:^6.15.0"
mongoose: "npm:^6.13.10"
mongoose: "npm:^6.13.12"
ms: "npm:^2.1.3"
nodemon: "npm:^2.0.20"
on-headers: "npm:^1.1.0"
Expand Down Expand Up @@ -6578,11 +6578,11 @@ __metadata:
languageName: node
linkType: hard

"@modelcontextprotocol/sdk@npm:^1.27.1":
version: 1.29.0
resolution: "@modelcontextprotocol/sdk@npm:1.29.0"
"@modelcontextprotocol/sdk@npm:^1.32.2":
version: 1.32.2
resolution: "@modelcontextprotocol/sdk@npm:1.32.2"
dependencies:
"@hono/node-server": "npm:^1.19.9"
"@hono/node-server": "npm:^1.19.9 || ^2.0.5"
ajv: "npm:^8.17.1"
ajv-formats: "npm:^3.0.1"
content-type: "npm:^1.0.5"
Expand All @@ -6607,7 +6607,7 @@ __metadata:
optional: true
zod:
optional: false
checksum: 10c0/7c4bc339205b1652330cd4e6b121cc859079655f2b9c0506bbb15563ba0d07924bda3d949705530532db7f4d2cb86d633dc8f92bc32803d97c7bece2ac63e29f
checksum: 10c0/31d045fe1121242ee7871f5fc9d5dc1f2ad622d9a9750fab5c14d1a1da227dd7225b16df0e8f22783356981255b22f5da84d1f74985df264ad79f2f00cc6ac7b
languageName: node
linkType: hard

Expand Down Expand Up @@ -23646,18 +23646,18 @@ __metadata:
languageName: node
linkType: hard

"mongoose@npm:^6.13.10":
version: 6.13.10
resolution: "mongoose@npm:6.13.10"
"mongoose@npm:^6.13.12":
version: 6.13.12
resolution: "mongoose@npm:6.13.12"
dependencies:
bson: "npm:^4.7.2"
kareem: "npm:2.5.1"
mongodb: "npm:4.17.2"
mpath: "npm:0.9.0"
mquery: "npm:4.0.3"
mquery: "npm:4.0.4"
ms: "npm:2.1.3"
sift: "npm:16.0.1"
checksum: 10c0/87b28f1535c0250b5fb23e0d8c8da3f36be2942b383a9e2513cd4a88ee75028ebca31c4d9f3b81e8f8381ece518bc8fe41fd41c2da5a36943119a2f8b4a34f4a
checksum: 10c0/07d7ca1c146475408fc79cd90afb89a6ea4da9fcbb1eddda7cb19e7cc81a7be3fa3f580ffc45938b22e3fa47c7f52c7c527ce3df265adac9a80d47d0f7e0c08d
languageName: node
linkType: hard

Expand All @@ -23675,12 +23675,12 @@ __metadata:
languageName: node
linkType: hard

"mquery@npm:4.0.3":
version: 4.0.3
resolution: "mquery@npm:4.0.3"
"mquery@npm:4.0.4":
version: 4.0.4
resolution: "mquery@npm:4.0.4"
dependencies:
debug: "npm:4.x"
checksum: 10c0/771eb00466f2c1a1342737fa0379d50c21bb6c09545d6fa4488a81c096a62548ec2080d53e5ead57c8e19f7354d3315e2403878abfb5a6bc8f3e732236874374
checksum: 10c0/fe9eb6920768343d3f66aa864f3928856483491e10e13a86f8dbf25c0c4551522061d6966e24023282258feedea2df1669051258aa11b80601298f701b732d0b
languageName: node
linkType: hard

Expand Down Expand Up @@ -30441,9 +30441,9 @@ __metadata:
linkType: hard

"undici@npm:^7.29.0":
version: 7.30.0
resolution: "undici@npm:7.30.0"
checksum: 10c0/011a321a9198532b0f0504740faa43b9ab8fcc0e4f60104e5c9cb808a61faeb03e4be4aec4f0c65f47913d7c7d9d91591793a6cb9ab843f98ca2c3d711c4a34c
version: 7.30.2
resolution: "undici@npm:7.30.2"
checksum: 10c0/806e17f14fb49d2b63be314cf2be68efbe105469118b366d19a3cb6fd6686089220c74c1e8e947e6b337a16ff434c10c3860f3e637db314381c4ce8c071c3daf
languageName: node
linkType: hard

Expand Down
Loading