From aad1ca55b390505f0573202ddfffbc98b3bad868 Mon Sep 17 00:00:00 2001 From: Aman Orazaev Date: Fri, 16 May 2025 16:36:16 -0700 Subject: [PATCH 01/12] Add cors support --- src/config.ts | 1 + src/transport.ts | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/config.ts b/src/config.ts index 047fdc0a..70f5eb13 100644 --- a/src/config.ts +++ b/src/config.ts @@ -190,6 +190,7 @@ export async function configFromCLIOptions(cliOptions: CLIOptions): Promise, connectionList: Connection[]) { + res.setHeader('Access-Control-Allow-Origin', 'http://localhost:5001'); + res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); + res.setHeader('Access-Control-Max-Age', 2592000); + res.setHeader('Access-Control-Allow-Headers', 'mcp-session-id, content-type'); + + if (req.method === 'OPTIONS') { + res.statusCode = 204; + return res.end(); + } + if (req.method === 'POST') { const sessionId = url.searchParams.get('sessionId'); if (!sessionId) { @@ -50,6 +60,7 @@ async function handleSSE(config: FullConfig, req: http.IncomingMessage, res: htt return await transport.handlePostMessage(req, res); } else if (req.method === 'GET') { const transport = new SSEServerTransport('/sse', res); + console.log('SSE session initialized', transport.sessionId); sessions.set(transport.sessionId, transport); const connection = await createConnection(config); await connection.connect(transport); @@ -69,6 +80,8 @@ async function handleSSE(config: FullConfig, req: http.IncomingMessage, res: htt } async function handleStreamable(config: FullConfig, req: http.IncomingMessage, res: http.ServerResponse, sessions: Map, connectionList: Connection[]) { + console.log('Streamable request', req.method, req.url); + console.log('Raw request headers', req.rawHeaders); const sessionId = req.headers['mcp-session-id'] as string | undefined; if (sessionId) { const transport = sessions.get(sessionId); @@ -80,10 +93,22 @@ async function handleStreamable(config: FullConfig, req: http.IncomingMessage, r return await transport.handleRequest(req, res); } + res.setHeader('Access-Control-Allow-Origin', 'http://localhost:5001'); + res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); + res.setHeader('Access-Control-Max-Age', 2592000); + res.setHeader('Access-Control-Allow-Headers', 'mcp-session-id, content-type'); + + if (req.method === 'OPTIONS') { + res.statusCode = 204; + return res.end(); + } + if (req.method === 'POST') { + console.log('Handling POST request', req.method, req.url); const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: () => crypto.randomUUID(), onsessioninitialized: sessionId => { + console.log('Streamable session initialized', sessionId); sessions.set(sessionId, transport); } }); @@ -93,6 +118,8 @@ async function handleStreamable(config: FullConfig, req: http.IncomingMessage, r }; const connection = await createConnection(config); connectionList.push(connection); + console.log('Connection created', connection); + console.log('Streamable session connecting', transport.sessionId); await Promise.all([ connection.connect(transport), transport.handleRequest(req, res), From 9df697396e67daa19e2b08a53d908e81ad04b79e Mon Sep 17 00:00:00 2001 From: Aman Orazaev Date: Mon, 19 May 2025 18:06:04 -0700 Subject: [PATCH 02/12] Add cli option for allowing origins for CORS. Use regexp to compare. --- config.d.ts | 5 +++++ src/config.ts | 3 +++ src/program.ts | 1 + src/transport.ts | 35 +++++++++++++++++++++++------------ 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/config.d.ts b/config.d.ts index 1c010aaa..dd664a86 100644 --- a/config.d.ts +++ b/config.d.ts @@ -114,6 +114,11 @@ export type Config = { * List of origins to block the browser to request. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked. */ blockedOrigins?: string[]; + + /** + * Origins to allow by CORS policy. Can be regex. + */ + corsAllowOrigins?: RegExp[]; }; /** diff --git a/src/config.ts b/src/config.ts index 70f5eb13..9fd2698a 100644 --- a/src/config.ts +++ b/src/config.ts @@ -32,6 +32,7 @@ export type CLIOptions = { caps?: string; cdpEndpoint?: string; config?: string; + corsAllowOrigins?: string[]; device?: string; executablePath?: string; headless?: boolean; @@ -67,6 +68,7 @@ const defaultConfig: FullConfig = { network: { allowedOrigins: undefined, blockedOrigins: undefined, + corsAllowOrigins: undefined, }, outputDir: path.join(os.tmpdir(), 'playwright-mcp-output', sanitizeForFilePath(new Date().toISOString())), }; @@ -185,6 +187,7 @@ export async function configFromCLIOptions(cliOptions: CLIOptions): Promise new RegExp(o, "i")) : undefined, }, saveTrace: cliOptions.saveTrace, outputDir: cliOptions.outputDir, diff --git a/src/program.ts b/src/program.ts index 8638342c..a8cd5535 100644 --- a/src/program.ts +++ b/src/program.ts @@ -34,6 +34,7 @@ program .option('--caps ', 'comma-separated list of capabilities to enable, possible values: tabs, pdf, history, wait, files, install. Default is all.') .option('--cdp-endpoint ', 'CDP endpoint to connect to.') .option('--config ', 'path to the configuration file.') + .option('--cors-allow-origins ', 'semicolon-separated list of allowed origins by CORS policy. Can be regex.', semicolonSeparatedList) .option('--device ', 'device to emulate, for example: "iPhone 15"') .option('--executable-path ', 'path to the browser executable.') .option('--headless', 'run browser in headless mode, headed by default') diff --git a/src/transport.ts b/src/transport.ts index 92b21bf1..ab4b5eda 100644 --- a/src/transport.ts +++ b/src/transport.ts @@ -33,13 +33,29 @@ export async function startStdioTransport(config: FullConfig, connectionList: Co connectionList.push(connection); } -async function handleSSE(config: FullConfig, req: http.IncomingMessage, res: http.ServerResponse, url: URL, sessions: Map, connectionList: Connection[]) { - res.setHeader('Access-Control-Allow-Origin', 'http://localhost:5001'); - res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); - res.setHeader('Access-Control-Max-Age', 2592000); - res.setHeader('Access-Control-Allow-Headers', 'mcp-session-id, content-type'); +function checkCors(config: FullConfig, req: http.IncomingMessage, res: http.ServerResponse): boolean { + if (config.network?.corsAllowOrigins === undefined) { + return false; + } + + const origin = req.headers.origin; + if (!origin) { + return false; + } + + if (config.network.corsAllowOrigins.some(re => re.test(origin))) { + res.setHeader('Access-Control-Allow-Origin', origin); + res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); + res.setHeader('Access-Control-Max-Age', 2592000); + res.setHeader('Access-Control-Allow-Headers', 'mcp-session-id, content-type'); + return true; + } + + return false; +} - if (req.method === 'OPTIONS') { +async function handleSSE(config: FullConfig, req: http.IncomingMessage, res: http.ServerResponse, url: URL, sessions: Map, connectionList: Connection[]) { + if (checkCors(config, req, res) && req.method === 'OPTIONS') { res.statusCode = 204; return res.end(); } @@ -93,12 +109,7 @@ async function handleStreamable(config: FullConfig, req: http.IncomingMessage, r return await transport.handleRequest(req, res); } - res.setHeader('Access-Control-Allow-Origin', 'http://localhost:5001'); - res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); - res.setHeader('Access-Control-Max-Age', 2592000); - res.setHeader('Access-Control-Allow-Headers', 'mcp-session-id, content-type'); - - if (req.method === 'OPTIONS') { + if (checkCors(config, req, res) && req.method === 'OPTIONS') { res.statusCode = 204; return res.end(); } From 52115e20efda3485df479b1b28d5993f00c4d656 Mon Sep 17 00:00:00 2001 From: Aman Orazaev Date: Mon, 19 May 2025 18:12:25 -0700 Subject: [PATCH 03/12] cleanup console logs --- src/transport.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/transport.ts b/src/transport.ts index ab4b5eda..438a2148 100644 --- a/src/transport.ts +++ b/src/transport.ts @@ -76,7 +76,6 @@ async function handleSSE(config: FullConfig, req: http.IncomingMessage, res: htt return await transport.handlePostMessage(req, res); } else if (req.method === 'GET') { const transport = new SSEServerTransport('/sse', res); - console.log('SSE session initialized', transport.sessionId); sessions.set(transport.sessionId, transport); const connection = await createConnection(config); await connection.connect(transport); @@ -115,11 +114,9 @@ async function handleStreamable(config: FullConfig, req: http.IncomingMessage, r } if (req.method === 'POST') { - console.log('Handling POST request', req.method, req.url); const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: () => crypto.randomUUID(), onsessioninitialized: sessionId => { - console.log('Streamable session initialized', sessionId); sessions.set(sessionId, transport); } }); @@ -129,8 +126,6 @@ async function handleStreamable(config: FullConfig, req: http.IncomingMessage, r }; const connection = await createConnection(config); connectionList.push(connection); - console.log('Connection created', connection); - console.log('Streamable session connecting', transport.sessionId); await Promise.all([ connection.connect(transport), transport.handleRequest(req, res), From 3ee8cfacd33405d9af62177c94f8e58c786173b9 Mon Sep 17 00:00:00 2001 From: Aman Orazaev Date: Mon, 19 May 2025 18:14:06 -0700 Subject: [PATCH 04/12] clean up more logs --- src/config.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/config.ts b/src/config.ts index 9fd2698a..2f96f15d 100644 --- a/src/config.ts +++ b/src/config.ts @@ -193,7 +193,6 @@ export async function configFromCLIOptions(cliOptions: CLIOptions): Promise Date: Mon, 19 May 2025 18:26:12 -0700 Subject: [PATCH 05/12] cleanup after rebase --- src/transport.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/transport.ts b/src/transport.ts index 438a2148..5846998d 100644 --- a/src/transport.ts +++ b/src/transport.ts @@ -95,8 +95,6 @@ async function handleSSE(config: FullConfig, req: http.IncomingMessage, res: htt } async function handleStreamable(config: FullConfig, req: http.IncomingMessage, res: http.ServerResponse, sessions: Map, connectionList: Connection[]) { - console.log('Streamable request', req.method, req.url); - console.log('Raw request headers', req.rawHeaders); const sessionId = req.headers['mcp-session-id'] as string | undefined; if (sessionId) { const transport = sessions.get(sessionId); From 65f8c208a07509d72415f6dd38a13585cef36816 Mon Sep 17 00:00:00 2001 From: Aman Orazaev Date: Mon, 19 May 2025 18:34:42 -0700 Subject: [PATCH 06/12] Make linter happy --- README.md | 1 + src/config.ts | 2 +- src/transport.ts | 6 ++---- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5933c886..6b348b1c 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,7 @@ Playwright MCP server supports following arguments. They can be provided in the --storage-state path to the storage state file for isolated sessions. --user-agent specify user agent string + --user-data-dir path to the user data directory. If not specified, a temporary directory will be created. --viewport-size specify browser viewport size in pixels, for diff --git a/src/config.ts b/src/config.ts index 2f96f15d..0c5a42a1 100644 --- a/src/config.ts +++ b/src/config.ts @@ -187,7 +187,7 @@ export async function configFromCLIOptions(cliOptions: CLIOptions): Promise new RegExp(o, "i")) : undefined, + corsAllowOrigins: cliOptions.corsAllowOrigins ? cliOptions.corsAllowOrigins.map(o => new RegExp(o, 'i')) : undefined, }, saveTrace: cliOptions.saveTrace, outputDir: cliOptions.outputDir, diff --git a/src/transport.ts b/src/transport.ts index 5846998d..ad3b0f47 100644 --- a/src/transport.ts +++ b/src/transport.ts @@ -34,14 +34,12 @@ export async function startStdioTransport(config: FullConfig, connectionList: Co } function checkCors(config: FullConfig, req: http.IncomingMessage, res: http.ServerResponse): boolean { - if (config.network?.corsAllowOrigins === undefined) { + if (config.network?.corsAllowOrigins === undefined) return false; - } const origin = req.headers.origin; - if (!origin) { + if (origin === undefined) return false; - } if (config.network.corsAllowOrigins.some(re => re.test(origin))) { res.setHeader('Access-Control-Allow-Origin', origin); From ec3360f35c2c404d3284acafcf52dc5ccc1f49a0 Mon Sep 17 00:00:00 2001 From: Aman Orazaev Date: Tue, 20 May 2025 16:44:46 -0700 Subject: [PATCH 07/12] Move `corsAllowOrigins` configuration to `server` part of config. --- config.d.ts | 10 +++++----- src/config.ts | 3 +-- src/transport.ts | 4 ++-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/config.d.ts b/config.d.ts index dd664a86..08601ffa 100644 --- a/config.d.ts +++ b/config.d.ts @@ -75,6 +75,11 @@ export type Config = { * The host to bind the server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces. */ host?: string; + + /** + * Origins to allow by CORS policy. Can be regex. + */ + corsAllowOrigins?: RegExp[]; }, /** @@ -114,11 +119,6 @@ export type Config = { * List of origins to block the browser to request. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked. */ blockedOrigins?: string[]; - - /** - * Origins to allow by CORS policy. Can be regex. - */ - corsAllowOrigins?: RegExp[]; }; /** diff --git a/src/config.ts b/src/config.ts index 0c5a42a1..b40a16f9 100644 --- a/src/config.ts +++ b/src/config.ts @@ -68,7 +68,6 @@ const defaultConfig: FullConfig = { network: { allowedOrigins: undefined, blockedOrigins: undefined, - corsAllowOrigins: undefined, }, outputDir: path.join(os.tmpdir(), 'playwright-mcp-output', sanitizeForFilePath(new Date().toISOString())), }; @@ -181,13 +180,13 @@ export async function configFromCLIOptions(cliOptions: CLIOptions): Promise new RegExp(o, 'i')) : undefined, }, capabilities: cliOptions.caps?.split(',').map((c: string) => c.trim() as ToolCapability), vision: !!cliOptions.vision, network: { allowedOrigins: cliOptions.allowedOrigins, blockedOrigins: cliOptions.blockedOrigins, - corsAllowOrigins: cliOptions.corsAllowOrigins ? cliOptions.corsAllowOrigins.map(o => new RegExp(o, 'i')) : undefined, }, saveTrace: cliOptions.saveTrace, outputDir: cliOptions.outputDir, diff --git a/src/transport.ts b/src/transport.ts index ad3b0f47..b763ca56 100644 --- a/src/transport.ts +++ b/src/transport.ts @@ -34,14 +34,14 @@ export async function startStdioTransport(config: FullConfig, connectionList: Co } function checkCors(config: FullConfig, req: http.IncomingMessage, res: http.ServerResponse): boolean { - if (config.network?.corsAllowOrigins === undefined) + if (config.server?.corsAllowOrigins === undefined) return false; const origin = req.headers.origin; if (origin === undefined) return false; - if (config.network.corsAllowOrigins.some(re => re.test(origin))) { + if (config.server.corsAllowOrigins.some(re => re.test(origin))) { res.setHeader('Access-Control-Allow-Origin', origin); res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); res.setHeader('Access-Control-Max-Age', 2592000); From e69d714eee08437282c1ae91c63d28021313edd4 Mon Sep 17 00:00:00 2001 From: Aman Orazaev Date: Wed, 28 May 2025 15:28:42 -0700 Subject: [PATCH 08/12] Rename cli opiton `cors-allow-origins` -> `cors-allowed-origins` Do strict string check instead of regex. --- config.d.ts | 4 ++-- src/config.ts | 4 ++-- src/program.ts | 2 +- src/transport.ts | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/config.d.ts b/config.d.ts index 08601ffa..868fbaed 100644 --- a/config.d.ts +++ b/config.d.ts @@ -77,9 +77,9 @@ export type Config = { host?: string; /** - * Origins to allow by CORS policy. Can be regex. + * Origins to allow by CORS policy. */ - corsAllowOrigins?: RegExp[]; + corsAllowedOrigins?: string[]; }, /** diff --git a/src/config.ts b/src/config.ts index b40a16f9..cd581a46 100644 --- a/src/config.ts +++ b/src/config.ts @@ -32,7 +32,7 @@ export type CLIOptions = { caps?: string; cdpEndpoint?: string; config?: string; - corsAllowOrigins?: string[]; + corsAllowedOrigins?: string[]; device?: string; executablePath?: string; headless?: boolean; @@ -180,7 +180,7 @@ export async function configFromCLIOptions(cliOptions: CLIOptions): Promise new RegExp(o, 'i')) : undefined, + corsAllowedOrigins: cliOptions.corsAllowedOrigins ? cliOptions.corsAllowedOrigins : undefined, }, capabilities: cliOptions.caps?.split(',').map((c: string) => c.trim() as ToolCapability), vision: !!cliOptions.vision, diff --git a/src/program.ts b/src/program.ts index a8cd5535..19b703fa 100644 --- a/src/program.ts +++ b/src/program.ts @@ -34,7 +34,7 @@ program .option('--caps ', 'comma-separated list of capabilities to enable, possible values: tabs, pdf, history, wait, files, install. Default is all.') .option('--cdp-endpoint ', 'CDP endpoint to connect to.') .option('--config ', 'path to the configuration file.') - .option('--cors-allow-origins ', 'semicolon-separated list of allowed origins by CORS policy. Can be regex.', semicolonSeparatedList) + .option('--cors-allowed-origins ', 'semicolon-separated list of allowed origins by CORS policy.', semicolonSeparatedList) .option('--device ', 'device to emulate, for example: "iPhone 15"') .option('--executable-path ', 'path to the browser executable.') .option('--headless', 'run browser in headless mode, headed by default') diff --git a/src/transport.ts b/src/transport.ts index b763ca56..b1407d70 100644 --- a/src/transport.ts +++ b/src/transport.ts @@ -34,14 +34,14 @@ export async function startStdioTransport(config: FullConfig, connectionList: Co } function checkCors(config: FullConfig, req: http.IncomingMessage, res: http.ServerResponse): boolean { - if (config.server?.corsAllowOrigins === undefined) + if (config.server?.corsAllowedOrigins === undefined) return false; const origin = req.headers.origin; if (origin === undefined) return false; - if (config.server.corsAllowOrigins.some(re => re.test(origin))) { + if (config.server.corsAllowedOrigins.some(o => o === origin)) { res.setHeader('Access-Control-Allow-Origin', origin); res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); res.setHeader('Access-Control-Max-Age', 2592000); From 9eeab1eda5d888752e6691d70278c06250b2f7ab Mon Sep 17 00:00:00 2001 From: Aman Orazaev Date: Wed, 28 May 2025 15:40:45 -0700 Subject: [PATCH 09/12] run update-readme after rebase --- README.md | 96 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index 6b348b1c..fe3c9c86 100644 --- a/README.md +++ b/README.md @@ -114,53 +114,55 @@ Playwright MCP server supports following arguments. They can be provided in the ``` > npx @playwright/mcp@latest --help - --allowed-origins semicolon-separated list of origins to allow the - browser to request. Default is to allow all. - --blocked-origins semicolon-separated list of origins to block the - browser from requesting. Blocklist is evaluated - before allowlist. If used without the allowlist, - requests not matching the blocklist are still - allowed. - --block-service-workers block service workers - --browser browser or chrome channel to use, possible - values: chrome, firefox, webkit, msedge. - --caps comma-separated list of capabilities to enable, - possible values: tabs, pdf, history, wait, files, - install. Default is all. - --cdp-endpoint CDP endpoint to connect to. - --config path to the configuration file. - --device device to emulate, for example: "iPhone 15" - --executable-path path to the browser executable. - --headless run browser in headless mode, headed by default - --host host to bind server to. Default is localhost. Use - 0.0.0.0 to bind to all interfaces. - --ignore-https-errors ignore https errors - --isolated keep the browser profile in memory, do not save - it to disk. - --image-responses whether to send image responses to the client. - Can be "allow", "omit", or "auto". Defaults to - "auto", which sends images if the client can - display them. - --no-sandbox disable the sandbox for all process types that - are normally sandboxed. - --output-dir path to the directory for output files. - --port port to listen on for SSE transport. - --proxy-bypass comma-separated domains to bypass proxy, for - example ".com,chromium.org,.domain.com" - --proxy-server specify proxy server, for example - "http://myproxy:3128" or "socks5://myproxy:8080" - --save-trace Whether to save the Playwright Trace of the - session into the output directory. - --storage-state path to the storage state file for isolated - sessions. - --user-agent specify user agent string - - --user-data-dir path to the user data directory. If not - specified, a temporary directory will be created. - --viewport-size specify browser viewport size in pixels, for - example "1280, 720" - --vision Run server that uses screenshots (Aria snapshots - are used by default) + --allowed-origins semicolon-separated list of origins to allow + the browser to request. Default is to allow + all. + --blocked-origins semicolon-separated list of origins to block + the browser from requesting. Blocklist is + evaluated before allowlist. If used without + the allowlist, requests not matching the + blocklist are still allowed. + --block-service-workers block service workers + --browser browser or chrome channel to use, possible + values: chrome, firefox, webkit, msedge. + --caps comma-separated list of capabilities to + enable, possible values: tabs, pdf, history, + wait, files, install. Default is all. + --cdp-endpoint CDP endpoint to connect to. + --config path to the configuration file. + --cors-allowed-origins semicolon-separated list of allowed origins + by CORS policy. + --device device to emulate, for example: "iPhone 15" + --executable-path path to the browser executable. + --headless run browser in headless mode, headed by + default + --host host to bind server to. Default is localhost. + Use 0.0.0.0 to bind to all interfaces. + --ignore-https-errors ignore https errors + --isolated keep the browser profile in memory, do not + save it to disk. + --no-image-responses do not send image responses to the client. + --no-sandbox disable the sandbox for all process types + that are normally sandboxed. + --output-dir path to the directory for output files. + --port port to listen on for SSE transport. + --proxy-bypass comma-separated domains to bypass proxy, for + example ".com,chromium.org,.domain.com" + --proxy-server specify proxy server, for example + "http://myproxy:3128" or + "socks5://myproxy:8080" + --save-trace Whether to save the Playwright Trace of the + session into the output directory. + --storage-state path to the storage state file for isolated + sessions. + --user-agent specify user agent string + --user-data-dir path to the user data directory. If not + specified, a temporary directory will be + created. + --viewport-size specify browser viewport size in pixels, for + example "1280, 720" + --vision Run server that uses screenshots (Aria + snapshots are used by default) ``` From 7fe1227b31747204ce369686d149d41d4f667538 Mon Sep 17 00:00:00 2001 From: Aman Orazaev Date: Wed, 28 May 2025 15:46:34 -0700 Subject: [PATCH 10/12] Manually add `--image-responses` back --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index fe3c9c86..af46b1e9 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,10 @@ Playwright MCP server supports following arguments. They can be provided in the --isolated keep the browser profile in memory, do not save it to disk. --no-image-responses do not send image responses to the client. + --image-responses whether to send image responses to the + client. Can be "allow", "omit", or "auto". + Defaults to "auto", which sends images if the + client can display them. --no-sandbox disable the sandbox for all process types that are normally sandboxed. --output-dir path to the directory for output files. From 022f4958e46db1d41f297c9ae764d0ca6545aba8 Mon Sep 17 00:00:00 2001 From: Aman Orazaev Date: Wed, 28 May 2025 15:48:47 -0700 Subject: [PATCH 11/12] fix readme --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index af46b1e9..1ec6a049 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,6 @@ Playwright MCP server supports following arguments. They can be provided in the --ignore-https-errors ignore https errors --isolated keep the browser profile in memory, do not save it to disk. - --no-image-responses do not send image responses to the client. --image-responses whether to send image responses to the client. Can be "allow", "omit", or "auto". Defaults to "auto", which sends images if the From 5b9815acd14958a0cf6dca3fb2a3c7b21a242dbe Mon Sep 17 00:00:00 2001 From: Aman Orazaev Date: Wed, 28 May 2025 18:51:52 -0700 Subject: [PATCH 12/12] fix build break after merge --- src/transport.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/transport.ts b/src/transport.ts index 809939dc..529e9afa 100644 --- a/src/transport.ts +++ b/src/transport.ts @@ -22,6 +22,7 @@ import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js'; import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; +import type { FullConfig } from './config.js'; import type { Server } from './server.js'; export async function startStdioTransport(server: Server) { @@ -48,7 +49,7 @@ function checkCors(config: FullConfig, req: http.IncomingMessage, res: http.Serv } async function handleSSE(server: Server, req: http.IncomingMessage, res: http.ServerResponse, url: URL, sessions: Map) { - if (checkCors(config, req, res) && req.method === 'OPTIONS') { + if (checkCors(server.config, req, res) && req.method === 'OPTIONS') { res.statusCode = 204; return res.end(); } @@ -95,7 +96,7 @@ async function handleStreamable(server: Server, req: http.IncomingMessage, res: return await transport.handleRequest(req, res); } - if (checkCors(config, req, res) && req.method === 'OPTIONS') { + if (checkCors(server.config, req, res) && req.method === 'OPTIONS') { res.statusCode = 204; return res.end(); }