diff --git a/packages/mcp-server/test/server.test.ts b/packages/mcp-server/test/server.test.ts index 376aa2eee1..a3f51a3c95 100644 --- a/packages/mcp-server/test/server.test.ts +++ b/packages/mcp-server/test/server.test.ts @@ -1,9 +1,11 @@ import type * as http from 'http'; +import type * as net from 'net'; import jsonwebtoken from 'jsonwebtoken'; import request from 'supertest'; import createMockForestServerClient from './helpers/forest-server-client'; +import getAvailablePort from './test-utils/get-available-port'; import MockServer from './test-utils/mock-server'; import ForestMCPServer from '../src/server'; import { clearSchemaCache } from '../src/utils/schema-fetcher'; @@ -125,7 +127,7 @@ describe('ForestMCPServer Instance', () => { }); it('should start server on specified port', async () => { - const testPort = 39310; // Use a different port for testing + const testPort = await getAvailablePort(); process.env.MCP_SERVER_PORT = testPort.toString(); server = new ForestMCPServer({ @@ -142,9 +144,11 @@ describe('ForestMCPServer Instance', () => { setTimeout(resolve, 500); }); - // Verify the server is running by making a request + // Verify the server is running on the specified port const { httpServer } = server; expect(httpServer).toBeDefined(); + const address = (httpServer as http.Server).address() as net.AddressInfo; + expect(address.port).toBe(testPort); // Make a request to verify server is responding const response = await request(httpServer as http.Server) @@ -155,7 +159,7 @@ describe('ForestMCPServer Instance', () => { }); it('should create transport instance', async () => { - const testPort = 39311; + const testPort = await getAvailablePort(); process.env.MCP_SERVER_PORT = testPort.toString(); server = new ForestMCPServer({ @@ -175,13 +179,14 @@ describe('ForestMCPServer Instance', () => { describe('HTTP endpoint', () => { let httpServer: http.Server; + let httpEndpointPort: number; beforeAll(async () => { process.env.FOREST_ENV_SECRET = 'test-env-secret'; process.env.FOREST_AUTH_SECRET = 'test-auth-secret'; process.env.FOREST_SERVER_URL = 'https://test.forestadmin.com'; - const testPort = 39312; - process.env.MCP_SERVER_PORT = testPort.toString(); + httpEndpointPort = await getAvailablePort(); + process.env.MCP_SERVER_PORT = httpEndpointPort.toString(); server = new ForestMCPServer({ envSecret: 'test-env-secret', @@ -240,12 +245,16 @@ describe('ForestMCPServer Instance', () => { expect(response.status).toBe(200); expect(response.headers['content-type']).toMatch(/application\/json/); - expect(response.body.issuer).toBe('http://localhost:39312/'); + expect(response.body.issuer).toBe(`http://localhost:${httpEndpointPort}/`); expect(response.body.registration_endpoint).toBe( 'https://test.forestadmin.com/oauth/register', ); - expect(response.body.authorization_endpoint).toBe(`http://localhost:39312/oauth/authorize`); - expect(response.body.token_endpoint).toBe(`http://localhost:39312/oauth/token`); + expect(response.body.authorization_endpoint).toBe( + `http://localhost:${httpEndpointPort}/oauth/authorize`, + ); + expect(response.body.token_endpoint).toBe( + `http://localhost:${httpEndpointPort}/oauth/token`, + ); expect(response.body.revocation_endpoint).toBeUndefined(); expect(response.body.scopes_supported).toEqual([ 'mcp:read', @@ -266,7 +275,7 @@ describe('ForestMCPServer Instance', () => { // Clean up previous server await shutDownHttpServer(server?.httpServer as http.Server); - process.env.MCP_SERVER_PORT = '39314'; + process.env.MCP_SERVER_PORT = (await getAvailablePort()).toString(); server = new ForestMCPServer({ authSecret: 'AUTH_SECRET', @@ -424,7 +433,7 @@ describe('ForestMCPServer Instance', () => { process.env.FOREST_ENV_SECRET = 'test-env-secret'; process.env.FOREST_AUTH_SECRET = 'test-auth-secret'; process.env.FOREST_SERVER_URL = 'https://test.forestadmin.com'; - process.env.MCP_SERVER_PORT = '39320'; + process.env.MCP_SERVER_PORT = (await getAvailablePort()).toString(); // Setup mock for Forest Admin server API responses mcpMockServer = new MockServer(); @@ -904,7 +913,7 @@ describe('ForestMCPServer Instance', () => { process.env.FOREST_AUTH_SECRET = 'test-auth-secret'; process.env.FOREST_SERVER_URL = 'https://test.forestadmin.com'; process.env.AGENT_HOSTNAME = 'http://localhost:3310'; - process.env.MCP_SERVER_PORT = '39330'; + process.env.MCP_SERVER_PORT = (await getAvailablePort()).toString(); listMockServer = new MockServer(); listMockServer @@ -1975,7 +1984,7 @@ describe('ForestMCPServer Instance', () => { process.env.FOREST_AUTH_SECRET = 'test-auth-secret'; process.env.FOREST_SERVER_URL = 'https://test.forestadmin.com'; process.env.AGENT_HOSTNAME = 'http://localhost:3310'; - process.env.MCP_SERVER_PORT = '39331'; + process.env.MCP_SERVER_PORT = (await getAvailablePort()).toString(); loggingMockServer = new MockServer(); loggingMockServer diff --git a/packages/mcp-server/test/test-utils/get-available-port.ts b/packages/mcp-server/test/test-utils/get-available-port.ts new file mode 100644 index 0000000000..68f1e80f60 --- /dev/null +++ b/packages/mcp-server/test/test-utils/get-available-port.ts @@ -0,0 +1,12 @@ +import * as net from 'net'; + +export default function getAvailablePort(): Promise { + return new Promise((resolve, reject) => { + const srv = net.createServer(); + srv.listen(0, () => { + const { port } = srv.address() as net.AddressInfo; + srv.close(() => resolve(port)); + }); + srv.on('error', reject); + }); +}