mirror of
https://github.com/microsoft/playwright-mcp.git
synced 2025-07-27 00:52:27 +08:00
chore: respect server settings from config (#502)
This commit is contained in:
parent
eec177d3ac
commit
656779531c
@ -68,6 +68,7 @@ const defaultConfig: FullConfig = {
|
|||||||
allowedOrigins: undefined,
|
allowedOrigins: undefined,
|
||||||
blockedOrigins: undefined,
|
blockedOrigins: undefined,
|
||||||
},
|
},
|
||||||
|
server: {},
|
||||||
outputDir: path.join(os.tmpdir(), 'playwright-mcp-output', sanitizeForFilePath(new Date().toISOString())),
|
outputDir: path.join(os.tmpdir(), 'playwright-mcp-output', sanitizeForFilePath(new Date().toISOString())),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -81,6 +82,7 @@ export type FullConfig = Config & {
|
|||||||
},
|
},
|
||||||
network: NonNullable<Config['network']>,
|
network: NonNullable<Config['network']>,
|
||||||
outputDir: string;
|
outputDir: string;
|
||||||
|
server: NonNullable<Config['server']>,
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function resolveConfig(config: Config): Promise<FullConfig> {
|
export async function resolveConfig(config: Config): Promise<FullConfig> {
|
||||||
@ -256,6 +258,10 @@ function mergeConfig(base: FullConfig, overrides: Config): FullConfig {
|
|||||||
network: {
|
network: {
|
||||||
...pickDefined(base.network),
|
...pickDefined(base.network),
|
||||||
...pickDefined(overrides.network),
|
...pickDefined(overrides.network),
|
||||||
}
|
},
|
||||||
|
server: {
|
||||||
|
...pickDefined(base.server),
|
||||||
|
...pickDefined(overrides.server),
|
||||||
|
},
|
||||||
} as FullConfig;
|
} as FullConfig;
|
||||||
}
|
}
|
||||||
|
@ -56,8 +56,8 @@ program
|
|||||||
const server = new Server(config);
|
const server = new Server(config);
|
||||||
server.setupExitWatchdog();
|
server.setupExitWatchdog();
|
||||||
|
|
||||||
if (options.port)
|
if (config.server.port !== undefined)
|
||||||
startHttpTransport(server, +options.port, options.host);
|
startHttpTransport(server);
|
||||||
else
|
else
|
||||||
await startStdioTransport(server);
|
await startStdioTransport(server);
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ async function handleStreamable(server: Server, req: http.IncomingMessage, res:
|
|||||||
res.end('Invalid request');
|
res.end('Invalid request');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function startHttpTransport(server: Server, port: number, hostname: string | undefined) {
|
export function startHttpTransport(server: Server) {
|
||||||
const sseSessions = new Map<string, SSEServerTransport>();
|
const sseSessions = new Map<string, SSEServerTransport>();
|
||||||
const streamableSessions = new Map<string, StreamableHTTPServerTransport>();
|
const streamableSessions = new Map<string, StreamableHTTPServerTransport>();
|
||||||
const httpServer = http.createServer(async (req, res) => {
|
const httpServer = http.createServer(async (req, res) => {
|
||||||
@ -106,7 +106,8 @@ export function startHttpTransport(server: Server, port: number, hostname: strin
|
|||||||
else
|
else
|
||||||
await handleSSE(server, req, res, url, sseSessions);
|
await handleSSE(server, req, res, url, sseSessions);
|
||||||
});
|
});
|
||||||
httpServer.listen(port, hostname, () => {
|
const { host, port } = server.config.server;
|
||||||
|
httpServer.listen(port, host, () => {
|
||||||
const address = httpServer.address();
|
const address = httpServer.address();
|
||||||
assert(address, 'Could not bind server socket');
|
assert(address, 'Could not bind server socket');
|
||||||
let url: string;
|
let url: string;
|
||||||
|
@ -14,7 +14,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import fs from 'node:fs';
|
||||||
import url from 'node:url';
|
import url from 'node:url';
|
||||||
|
|
||||||
import { ChildProcess, spawn } from 'node:child_process';
|
import { ChildProcess, spawn } from 'node:child_process';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
||||||
@ -22,24 +24,25 @@ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/
|
|||||||
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
||||||
|
|
||||||
import { test as baseTest, expect } from './fixtures.js';
|
import { test as baseTest, expect } from './fixtures.js';
|
||||||
|
import type { Config } from '../config.d.ts';
|
||||||
|
|
||||||
// NOTE: Can be removed when we drop Node.js 18 support and changed to import.meta.filename.
|
// NOTE: Can be removed when we drop Node.js 18 support and changed to import.meta.filename.
|
||||||
const __filename = url.fileURLToPath(import.meta.url);
|
const __filename = url.fileURLToPath(import.meta.url);
|
||||||
|
|
||||||
const test = baseTest.extend<{ serverEndpoint: (args?: string[]) => Promise<{ url: URL, stderr: () => string }> }>({
|
const test = baseTest.extend<{ serverEndpoint: (options?: { args?: string[], noPort?: boolean }) => Promise<{ url: URL, stderr: () => string }> }>({
|
||||||
serverEndpoint: async ({ mcpHeadless }, use, testInfo) => {
|
serverEndpoint: async ({ mcpHeadless }, use, testInfo) => {
|
||||||
let cp: ChildProcess | undefined;
|
let cp: ChildProcess | undefined;
|
||||||
const userDataDir = testInfo.outputPath('user-data-dir');
|
const userDataDir = testInfo.outputPath('user-data-dir');
|
||||||
await use(async (args?: string[]) => {
|
await use(async (options?: { args?: string[], noPort?: boolean }) => {
|
||||||
if (cp)
|
if (cp)
|
||||||
throw new Error('Process already running');
|
throw new Error('Process already running');
|
||||||
|
|
||||||
cp = spawn('node', [
|
cp = spawn('node', [
|
||||||
path.join(path.dirname(__filename), '../cli.js'),
|
path.join(path.dirname(__filename), '../cli.js'),
|
||||||
'--port=0',
|
...(options?.noPort ? [] : ['--port=0']),
|
||||||
'--user-data-dir=' + userDataDir,
|
'--user-data-dir=' + userDataDir,
|
||||||
...(mcpHeadless ? ['--headless'] : []),
|
...(mcpHeadless ? ['--headless'] : []),
|
||||||
...(args || []),
|
...(options?.args || []),
|
||||||
], {
|
], {
|
||||||
stdio: 'pipe',
|
stdio: 'pipe',
|
||||||
env: {
|
env: {
|
||||||
@ -71,8 +74,24 @@ test('sse transport', async ({ serverEndpoint }) => {
|
|||||||
await client.ping();
|
await client.ping();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('sse transport (config)', async ({ serverEndpoint }) => {
|
||||||
|
const config: Config = {
|
||||||
|
server: {
|
||||||
|
port: 0,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const configFile = test.info().outputPath('config.json');
|
||||||
|
await fs.promises.writeFile(configFile, JSON.stringify(config, null, 2));
|
||||||
|
|
||||||
|
const { url } = await serverEndpoint({ noPort: true, args: ['--config=' + configFile] });
|
||||||
|
const transport = new SSEClientTransport(url);
|
||||||
|
const client = new Client({ name: 'test', version: '1.0.0' });
|
||||||
|
await client.connect(transport);
|
||||||
|
await client.ping();
|
||||||
|
});
|
||||||
|
|
||||||
test('sse transport browser lifecycle (isolated)', async ({ serverEndpoint, server }) => {
|
test('sse transport browser lifecycle (isolated)', async ({ serverEndpoint, server }) => {
|
||||||
const { url, stderr } = await serverEndpoint(['--isolated']);
|
const { url, stderr } = await serverEndpoint({ args: ['--isolated'] });
|
||||||
|
|
||||||
const transport1 = new SSEClientTransport(url);
|
const transport1 = new SSEClientTransport(url);
|
||||||
const client1 = new Client({ name: 'test', version: '1.0.0' });
|
const client1 = new Client({ name: 'test', version: '1.0.0' });
|
||||||
@ -109,7 +128,7 @@ test('sse transport browser lifecycle (isolated)', async ({ serverEndpoint, serv
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('sse transport browser lifecycle (isolated, multiclient)', async ({ serverEndpoint, server }) => {
|
test('sse transport browser lifecycle (isolated, multiclient)', async ({ serverEndpoint, server }) => {
|
||||||
const { url, stderr } = await serverEndpoint(['--isolated']);
|
const { url, stderr } = await serverEndpoint({ args: ['--isolated'] });
|
||||||
|
|
||||||
const transport1 = new SSEClientTransport(url);
|
const transport1 = new SSEClientTransport(url);
|
||||||
const client1 = new Client({ name: 'test', version: '1.0.0' });
|
const client1 = new Client({ name: 'test', version: '1.0.0' });
|
||||||
|
Loading…
x
Reference in New Issue
Block a user