| ... | @@ -8,16 +8,18 @@ import { ServerEnvironment } from "../environment/Services/ServerEnvironment.ts" | ... | @@ -8,16 +8,18 @@ import { ServerEnvironment } from "../environment/Services/ServerEnvironment.ts" |
| 8 | import * as McpSessionRegistry from "./McpSessionRegistry.ts"; | 8 | import * as McpSessionRegistry from "./McpSessionRegistry.ts"; |
| 9 | | 9 | |
| 10 | const environmentId = EnvironmentId.make("environment-1"); | 10 | const environmentId = EnvironmentId.make("environment-1"); |
| 11 | const fakeHttpServer = HttpServer.HttpServer.of({ | 11 | const makeFakeHttpServer = (hostname: string, port = 43123) => |
| 12 | address: { _tag: "TcpAddress", hostname: "127.0.0.1", port: 43123 }, | 12 | HttpServer.HttpServer.of({ |
| 13 | serve: (() => Effect.void) as HttpServer.HttpServer["Service"]["serve"], | 13 | address: { _tag: "TcpAddress", hostname, port }, |
| 14 | }); | 14 | serve: (() => Effect.void) as HttpServer.HttpServer["Service"]["serve"], |
| | 15 | }); |
| | 16 | const fakeHttpServer = makeFakeHttpServer("127.0.0.1"); |
| 15 | const fakeEnvironment = ServerEnvironment.of({ | 17 | const fakeEnvironment = ServerEnvironment.of({ |
| 16 | getEnvironmentId: Effect.succeed(environmentId), | 18 | getEnvironmentId: Effect.succeed(environmentId), |
| 17 | getDescriptor: Effect.die("unused"), | 19 | getDescriptor: Effect.die("unused"), |
| 18 | }); | 20 | }); |
| 19 | | 21 | |
| 20 | const makeRegistry = (now: () => number) => | 22 | const makeRegistry = (now: () => number, httpServer = fakeHttpServer) => |
| 21 | McpSessionRegistry.__testing | 23 | McpSessionRegistry.__testing |
| 22 | .make({ | 24 | .make({ |
| 23 | now, | 25 | now, |
| ... | @@ -25,7 +27,7 @@ const makeRegistry = (now: () => number) => | ... | @@ -25,7 +27,7 @@ const makeRegistry = (now: () => number) => |
| 25 | maximumLifetimeMs: 1_000, | 27 | maximumLifetimeMs: 1_000, |
| 26 | }) | 28 | }) |
| 27 | .pipe( | 29 | .pipe( |
| 28 | Effect.provideService(HttpServer.HttpServer, fakeHttpServer), | 30 | Effect.provideService(HttpServer.HttpServer, httpServer), |
| 29 | Effect.provideService(ServerEnvironment, fakeEnvironment), | 31 | Effect.provideService(ServerEnvironment, fakeEnvironment), |
| 30 | Effect.provide(NodeServices.layer), | 32 | Effect.provide(NodeServices.layer), |
| 31 | ); | 33 | ); |
| ... | @@ -53,6 +55,26 @@ it.effect("stores only a token hash, resolves the bearer token, and revokes by t | ... | @@ -53,6 +55,26 @@ it.effect("stores only a token hash, resolves the bearer token, and revokes by t |
| 53 | }), | 55 | }), |
| 54 | ); | 56 | ); |
| 55 | | 57 | |
| | 58 | it.effect("builds MCP endpoints from the bound server host", () => |
| | 59 | Effect.gen(function* () { |
| | 60 | const cases = [ |
| | 61 | ["100.64.0.40", "http://100.64.0.40:43123/mcp"], |
| | 62 | ["0.0.0.0", "http://127.0.0.1:43123/mcp"], |
| | 63 | ["localhost", "http://localhost:43123/mcp"], |
| | 64 | ["127.0.0.1", "http://127.0.0.1:43123/mcp"], |
| | 65 | ] as const; |
| | 66 | |
| | 67 | for (const [hostname, expectedEndpoint] of cases) { |
| | 68 | const registry = yield* makeRegistry(() => 1_000, makeFakeHttpServer(hostname)); |
| | 69 | const issued = yield* registry.issue({ |
| | 70 | threadId: ThreadId.make(`thread-${hostname}`), |
| | 71 | providerInstanceId: ProviderInstanceId.make("codex"), |
| | 72 | }); |
| | 73 | expect(issued.config.endpoint).toBe(expectedEndpoint); |
| | 74 | } |
| | 75 | }), |
| | 76 | ); |
| | 77 | |
| 56 | it.effect("expires credentials after inactivity", () => | 78 | it.effect("expires credentials after inactivity", () => |
| 57 | Effect.gen(function* () { | 79 | Effect.gen(function* () { |
| 58 | let timestamp = 1_000; | 80 | let timestamp = 1_000; |