fix(server): reject a modern POST without the required MCP-Protocol-Version header (#2590)

Co-authored-by: Konstantin Konstantinov <konstantin@mach5technology.com>
Co-authored-by: Konstantin Konstantinov <KKonstantinov@users.noreply.github.com>
This commit is contained in:
David Pavlovschii 2026-08-17 09:31:47 +03:00 • committed by GitHub
commit 75dc7ea6e2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 328 additions and 43 deletions

View file

@ -31,7 +31,7 @@ import { createMcpHandler, isLegacyRequest, McpServer, WebStandardStreamableHTTP
import { expect, vi } from 'vitest';
import { z } from 'zod/v4';
import { modernEnvelopeMeta } from '../helpers/index';
import { modernEnvelopeMeta, modernStandardHeaders } from '../helpers/index';
import { verifies } from '../helpers/verifies';
const LEGACY = '2025-11-25';
@ -172,8 +172,7 @@ verifies('typescript:hosting:entry:byo-sessionful-legacy', async () => {
headers: {
'content-type': 'application/json',
accept: 'application/json, text/event-stream',
'mcp-method': 'tools/call',
'mcp-name': 'greet'
...modernStandardHeaders('tools/call', 'greet')
},
body: JSON.stringify({
jsonrpc: '2.0',

View file

@ -35,7 +35,7 @@ import {
import { expect, vi } from 'vitest';
import { z } from 'zod/v4';
import { modernEnvelopeMeta, tapWire, wire } from '../helpers/index';
import { modernEnvelopeMeta, modernStandardHeaders, tapWire, wire } from '../helpers/index';
import { verifies } from '../helpers/verifies';
import type { TestArgs } from '../types';
@ -1158,8 +1158,7 @@ verifies('protocol:meta:server-identity', async ({ transport }: TestArgs) => {
headers: {
'content-type': 'application/json',
accept: 'application/json, text/event-stream',
'mcp-protocol-version': '2026-07-28',
'mcp-method': 'server/discover'
...modernStandardHeaders('server/discover')
},
body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'server/discover', params: { _meta: modernEnvelopeMeta() } })
});
@ -1184,8 +1183,7 @@ verifies('protocol:envelope:client-info-optional', async ({ transport }: TestArg
headers: {
'content-type': 'application/json',
accept: 'application/json, text/event-stream',
'mcp-protocol-version': '2026-07-28',
'mcp-method': 'tools/list'
...modernStandardHeaders('tools/list')
},
body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'tools/list', params: { _meta: meta } })
});

View file

@ -11,7 +11,7 @@ import { createMcpHandler, McpServer, SUBSCRIPTION_ID_META_KEY } from '@modelcon
import { expect } from 'vitest';
import { z } from 'zod/v4';
import { modernEnvelopeMeta, wire } from '../helpers/index';
import { modernEnvelopeMeta, modernStandardHeaders, wire } from '../helpers/index';
import { verifies } from '../helpers/verifies';
import type { TestArgs } from '../types';
@ -72,7 +72,7 @@ verifies('subscriptions:listen:ack-first-stamped', async () => {
headers: {
'Content-Type': 'application/json',
Accept: 'application/json, text/event-stream',
'mcp-method': 'subscriptions/listen'
...modernStandardHeaders('subscriptions/listen')
},
body: JSON.stringify({
jsonrpc: '2.0',
@ -270,7 +270,7 @@ verifies('subscriptions:listen:capacity-guard', async () => {
headers: {
'Content-Type': 'application/json',
Accept: 'application/json, text/event-stream',
'mcp-method': 'subscriptions/listen'
...modernStandardHeaders('subscriptions/listen')
},
body: JSON.stringify({
jsonrpc: '2.0',