Skip to content
Open
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
7 changes: 1 addition & 6 deletions packages/core/src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2384,19 +2384,14 @@ type Flatten<T> = T extends Primitive

type Infer<Schema extends z.ZodTypeAny> = Flatten<z.infer<Schema>>;

/**
* Headers that are compatible with both Node.js and the browser.
*/
export type IsomorphicHeaders = Record<string, string | string[] | undefined>;

/**
* Information about the incoming request.
*/
export interface RequestInfo {
/**
* The headers of the request.
*/
headers: IsomorphicHeaders;
headers: Headers;
}

/**
Expand Down
13 changes: 9 additions & 4 deletions packages/middleware/node/test/streamableHttp.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import type {
JSONRPCResultResponse,
RequestId
} from '@modelcontextprotocol/core';
import type { EventId, EventStore, StreamId } from '@modelcontextprotocol/server';
import { McpServer } from '@modelcontextprotocol/server';
import type { ZodMatrixEntry } from '@modelcontextprotocol/test-helpers';
import { listenOnRandomPort, zodTestMatrix } from '@modelcontextprotocol/test-helpers';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';

import { NodeStreamableHTTPServerTransport } from '../src/streamableHttp.js';
import { McpServer } from '@modelcontextprotocol/server';
import type { EventId, EventStore, StreamId } from '@modelcontextprotocol/server';
import { describe, expect, beforeEach, afterEach, it } from 'vitest';

async function getFreePort() {
return new Promise(res => {
Expand Down Expand Up @@ -402,10 +402,15 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) => {
'A simple test tool with request info',
{ name: z.string().describe('Name to greet') },
async ({ name }, { requestInfo }): Promise<CallToolResult> => {
// Convert Headers object to plain object for JSON serialization
// Headers is a Web API class that doesn't serialize with JSON.stringify
const serializedRequestInfo = {
headers: Object.fromEntries(requestInfo?.headers ?? new Headers())
};
return {
content: [
{ type: 'text', text: `Hello, ${name}!` },
{ type: 'text', text: `${JSON.stringify(requestInfo)}` }
{ type: 'text', text: `${JSON.stringify(serializedRequestInfo)}` }
]
};
}
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export class Server<
if (this._capabilities.logging) {
this.setRequestHandler(SetLevelRequestSchema, async (request, extra) => {
const transportSessionId: string | undefined =
extra.sessionId || (extra.requestInfo?.headers['mcp-session-id'] as string) || undefined;
extra.sessionId || (extra.requestInfo?.headers.get('mcp-session-id') as string) || undefined;
const { level } = request.params;
const parseResult = LoggingLevelSchema.safeParse(level);
if (parseResult.success) {
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/server/streamableHttp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ export class WebStandardStreamableHTTPServerTransport implements Transport {

// Build request info from headers
const requestInfo: RequestInfo = {
headers: Object.fromEntries(req.headers.entries())
headers: req.headers
};

let rawMessage;
Expand Down
Loading