From 9d00bbe426d0f82c996e1a63256752dca0cd3bf9 Mon Sep 17 00:00:00 2001 From: huuyafwww Date: Tue, 17 Feb 2026 22:08:52 +0900 Subject: [PATCH 1/5] feat: Supports request header authentication with connectToMCPServer --- packages/core/lib/v3/mcp/connection.ts | 7 +++++-- packages/core/tests/public-api/v3-core.test.ts | 2 +- .../docs/v3/best-practices/mcp-integrations.mdx | 14 +++++++++++++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/packages/core/lib/v3/mcp/connection.ts b/packages/core/lib/v3/mcp/connection.ts index 0203b9a09..227eceee7 100644 --- a/packages/core/lib/v3/mcp/connection.ts +++ b/packages/core/lib/v3/mcp/connection.ts @@ -2,13 +2,14 @@ import { Client, ClientOptions, } from "@modelcontextprotocol/sdk/client/index.js"; -import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; +import { StreamableHTTPClientTransport, type StreamableHTTPClientTransportOptions } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"; import { MCPConnectionError } from "../types/public/sdkErrors"; export interface ConnectToMCPServerOptions { serverUrl: string | URL; clientOptions?: ClientOptions; + requestOptions?: StreamableHTTPClientTransportOptions; } export interface StdioServerConfig { @@ -23,6 +24,7 @@ export const connectToMCPServer = async ( try { let transport; let clientOptions: ClientOptions | undefined; + let requestOptions: StreamableHTTPClientTransportOptions | undefined; // Check if it's a stdio config (has 'command' property) if (typeof serverConfig === "object" && "command" in serverConfig) { @@ -37,9 +39,10 @@ export const connectToMCPServer = async ( serverUrl = (serverConfig as ConnectToMCPServerOptions).serverUrl; clientOptions = (serverConfig as ConnectToMCPServerOptions) .clientOptions; + requestOptions = (serverConfig as ConnectToMCPServerOptions).requestOptions; } - transport = new StreamableHTTPClientTransport(new URL(serverUrl)); + transport = new StreamableHTTPClientTransport(new URL(serverUrl), requestOptions); } const client = new Client({ diff --git a/packages/core/tests/public-api/v3-core.test.ts b/packages/core/tests/public-api/v3-core.test.ts index 9da299801..9e44ef357 100644 --- a/packages/core/tests/public-api/v3-core.test.ts +++ b/packages/core/tests/public-api/v3-core.test.ts @@ -156,7 +156,7 @@ describe("V3 Core public API types", () => { | string | URL | { command: string; args?: string[]; env?: Record } - | { serverUrl: string | URL; clientOptions?: unknown }; + | { serverUrl: string | URL; clientOptions?: unknown; requestOptions?: unknown }; it("has correct parameter types", () => { expectTypeOf( diff --git a/packages/docs/v3/best-practices/mcp-integrations.mdx b/packages/docs/v3/best-practices/mcp-integrations.mdx index ed44fbaaa..c1e275250 100644 --- a/packages/docs/v3/best-practices/mcp-integrations.mdx +++ b/packages/docs/v3/best-practices/mcp-integrations.mdx @@ -58,6 +58,18 @@ const supabaseClient = await connectToMCPServer( `https://server.smithery.ai/@supabase-community/supabase-mcp/mcp?api_key=${process.env.SMITHERY_API_KEY}` ); +// When setting the API key required for authentication in the request header +const deepWikiClient = await connectToMCPServer({ + serverUrl: "https://mcp.devin.ai/mcp", + requestOptions: { + requestInit: { + headers: { + Authorization: `Bearer ${process.env.DEEP_WIKI_API_KEY}`, + }, + }, + }, +}); + // You can also pass the config to start a local MCP server const notionClient = await connectToMCPServer({ command: "npx", @@ -71,7 +83,7 @@ const notionClient = await connectToMCPServer({ const agent = stagehand.agent({ provider: "openai", model: "computer-use-preview", - integrations: [supabaseClient, notionClient], + integrations: [supabaseClient, deepWikiClient, notionClient], systemPrompt: `You can interact with Supabase databases and Notion. Use these tools to store and retrieve data.`, options: { apiKey: process.env.OPENAI_API_KEY, From 2ee2589564764ddad994858293678fc141685c2d Mon Sep 17 00:00:00 2001 From: huuyafwww Date: Tue, 17 Feb 2026 22:19:33 +0900 Subject: [PATCH 2/5] run format --- packages/core/lib/v3/mcp/connection.ts | 13 ++++++++++--- packages/core/tests/public-api/v3-core.test.ts | 6 +++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/core/lib/v3/mcp/connection.ts b/packages/core/lib/v3/mcp/connection.ts index 227eceee7..3d6e2a9b9 100644 --- a/packages/core/lib/v3/mcp/connection.ts +++ b/packages/core/lib/v3/mcp/connection.ts @@ -2,7 +2,10 @@ import { Client, ClientOptions, } from "@modelcontextprotocol/sdk/client/index.js"; -import { StreamableHTTPClientTransport, type StreamableHTTPClientTransportOptions } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; +import { + StreamableHTTPClientTransport, + type StreamableHTTPClientTransportOptions, +} from "@modelcontextprotocol/sdk/client/streamableHttp.js"; import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"; import { MCPConnectionError } from "../types/public/sdkErrors"; @@ -39,10 +42,14 @@ export const connectToMCPServer = async ( serverUrl = (serverConfig as ConnectToMCPServerOptions).serverUrl; clientOptions = (serverConfig as ConnectToMCPServerOptions) .clientOptions; - requestOptions = (serverConfig as ConnectToMCPServerOptions).requestOptions; + requestOptions = (serverConfig as ConnectToMCPServerOptions) + .requestOptions; } - transport = new StreamableHTTPClientTransport(new URL(serverUrl), requestOptions); + transport = new StreamableHTTPClientTransport( + new URL(serverUrl), + requestOptions, + ); } const client = new Client({ diff --git a/packages/core/tests/public-api/v3-core.test.ts b/packages/core/tests/public-api/v3-core.test.ts index 9e44ef357..e2e9f1134 100644 --- a/packages/core/tests/public-api/v3-core.test.ts +++ b/packages/core/tests/public-api/v3-core.test.ts @@ -156,7 +156,11 @@ describe("V3 Core public API types", () => { | string | URL | { command: string; args?: string[]; env?: Record } - | { serverUrl: string | URL; clientOptions?: unknown; requestOptions?: unknown }; + | { + serverUrl: string | URL; + clientOptions?: unknown; + requestOptions?: unknown; + }; it("has correct parameter types", () => { expectTypeOf( From 91d5e1cc6b4724ff8dadec9a31778c46251156f1 Mon Sep 17 00:00:00 2001 From: huuyafwww Date: Tue, 17 Feb 2026 22:36:39 +0900 Subject: [PATCH 3/5] add changeset --- .changeset/tender-experts-obey.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/tender-experts-obey.md diff --git a/.changeset/tender-experts-obey.md b/.changeset/tender-experts-obey.md new file mode 100644 index 000000000..d5d50c4c6 --- /dev/null +++ b/.changeset/tender-experts-obey.md @@ -0,0 +1,6 @@ +--- +"@browserbasehq/stagehand": patch +"@browserbasehq/stagehand-docs": patch +--- + +Supports request header authentication with connectToMCPServer From 1f183b4b041904fd9b7862916dea5382c8c0d544 Mon Sep 17 00:00:00 2001 From: ci-test Date: Mon, 23 Feb 2026 17:44:21 -0700 Subject: [PATCH 4/5] docs: clarify authenticated MCP servers --- .../v3/best-practices/mcp-integrations.mdx | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/packages/docs/v3/best-practices/mcp-integrations.mdx b/packages/docs/v3/best-practices/mcp-integrations.mdx index c1e275250..b2d6e4e66 100644 --- a/packages/docs/v3/best-practices/mcp-integrations.mdx +++ b/packages/docs/v3/best-practices/mcp-integrations.mdx @@ -58,18 +58,6 @@ const supabaseClient = await connectToMCPServer( `https://server.smithery.ai/@supabase-community/supabase-mcp/mcp?api_key=${process.env.SMITHERY_API_KEY}` ); -// When setting the API key required for authentication in the request header -const deepWikiClient = await connectToMCPServer({ - serverUrl: "https://mcp.devin.ai/mcp", - requestOptions: { - requestInit: { - headers: { - Authorization: `Bearer ${process.env.DEEP_WIKI_API_KEY}`, - }, - }, - }, -}); - // You can also pass the config to start a local MCP server const notionClient = await connectToMCPServer({ command: "npx", @@ -79,11 +67,11 @@ const notionClient = await connectToMCPServer({ }, }); -// Use the connected client +// Use the connected clients (example with Supabase + Notion) const agent = stagehand.agent({ provider: "openai", model: "computer-use-preview", - integrations: [supabaseClient, deepWikiClient, notionClient], + integrations: [supabaseClient, notionClient], systemPrompt: `You can interact with Supabase databases and Notion. Use these tools to store and retrieve data.`, options: { apiKey: process.env.OPENAI_API_KEY, @@ -93,6 +81,23 @@ const agent = stagehand.agent({ await agent.execute("Search for restaurants in New Brunswick, NJ and save the first result to the database"); ``` +## Authenticated MCP Servers + +Some MCP servers require authentication via HTTP request headers. You can pass request headers through `requestOptions`: + +```typescript +const authenticatedClient = await connectToMCPServer({ + serverUrl: "https://mcp-server.example.com/mcp", + requestOptions: { + requestInit: { + headers: { + Authorization: `Bearer ${process.env.MCP_SERVER_API_KEY}`, + }, + }, + }, +}); +``` + ## Multiple Integrations From 6cee1df669b8011ebd54a164e3c7d5aee2b16dcd Mon Sep 17 00:00:00 2001 From: ci-test Date: Mon, 23 Feb 2026 17:45:14 -0700 Subject: [PATCH 5/5] chore(changeset): drop docs package bump --- .changeset/tender-experts-obey.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.changeset/tender-experts-obey.md b/.changeset/tender-experts-obey.md index d5d50c4c6..6e81f47fa 100644 --- a/.changeset/tender-experts-obey.md +++ b/.changeset/tender-experts-obey.md @@ -1,6 +1,5 @@ --- "@browserbasehq/stagehand": patch -"@browserbasehq/stagehand-docs": patch --- Supports request header authentication with connectToMCPServer