fix: live-run wiring (SDK 1.29, zod 3.25, OAUTH_ISSUER split, alt host ports, web on 3001, log level cast, pino transport)
- Bump @modelcontextprotocol/sdk from 1.0.4 to 1.29.0 in runner-template (1.0.4 has no McpServer or StreamableHTTPServerTransport — file not found at runtime). - Bump zod to 3.25.76 across workspace to satisfy modern SDK peer dep. - Split OAUTH_ISSUER (canonical, host-reachable) from CONTROL_PLANE_URL (container-reachable for JWKS). Runner verifies iss against OAUTH_ISSUER; fetches JWKS from CONTROL_PLANE_URL. Both API and runner now agree on http://localhost:4000/oauth as the issuer in dev. - Move postgres host port 5432 to 5440, redis 6379 to 6390 to avoid collisions with native installs on the dev machine. - Move web from 3000 to 3001 (3000 occupied by Gitea on dev machine). - Drop pino-pretty transport from API to avoid runtime require of an unbundled dep. - Cast build_logs.level (varchar) to BuildEvent's literal union in WS replay path. - Remove unused reqBase helper in oauth.ts.
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
"bullmq": "5.34.5",
|
||||
"drizzle-orm": "0.36.4",
|
||||
"ioredis": "5.4.1",
|
||||
"zod": "3.23.8"
|
||||
"zod": "3.25.76"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "22.10.2",
|
||||
|
||||
@@ -9,6 +9,7 @@ const Env = z.object({
|
||||
RUNNER_PORT_RANGE_END: z.coerce.number().default(4999),
|
||||
CONTROL_PLANE_URL: z.string().default('http://host.docker.internal:4000'),
|
||||
CONTROL_PLANE_PUBLIC_URL: z.string().default('http://localhost:4000'),
|
||||
OAUTH_ISSUER: z.string().optional(),
|
||||
MODEL_GENERATE: z.string().default('claude-opus-4-7'),
|
||||
MODEL_FIX: z.string().default('claude-haiku-4-5-20251001'),
|
||||
});
|
||||
|
||||
@@ -61,6 +61,7 @@ import { randomUUID } from 'node:crypto';
|
||||
|
||||
const PUBLIC_URL = process.env.PUBLIC_URL ?? 'http://localhost:3000';
|
||||
const CONTROL_PLANE_URL = process.env.CONTROL_PLANE_URL ?? 'http://host.docker.internal:4000';
|
||||
const OAUTH_ISSUER = process.env.OAUTH_ISSUER ?? CONTROL_PLANE_URL + '/oauth';
|
||||
const PORT = Number.parseInt(process.env.PORT ?? '3000', 10);
|
||||
|
||||
const server = new McpServer(
|
||||
@@ -76,7 +77,7 @@ app.get('/health', async () => ({ ok: true }));
|
||||
|
||||
app.get('/.well-known/oauth-protected-resource', async () => ({
|
||||
resource: PUBLIC_URL,
|
||||
authorization_servers: [CONTROL_PLANE_URL + '/oauth'],
|
||||
authorization_servers: [OAUTH_ISSUER],
|
||||
bearer_methods_supported: ['header'],
|
||||
scopes_supported: ${JSON.stringify(spec.scopes)},
|
||||
}));
|
||||
@@ -101,7 +102,7 @@ app.all('/mcp', async (request, reply) => {
|
||||
const token = auth.slice(7);
|
||||
try {
|
||||
const { payload } = await jwtVerify(token, JWKS, {
|
||||
issuer: CONTROL_PLANE_URL + '/oauth',
|
||||
issuer: OAUTH_ISSUER,
|
||||
audience: PUBLIC_URL,
|
||||
});
|
||||
if (payload.aud !== PUBLIC_URL) {
|
||||
|
||||
@@ -79,6 +79,7 @@ export const worker = new Worker<JobData>(
|
||||
...secrets,
|
||||
PUBLIC_URL: publicUrl,
|
||||
CONTROL_PLANE_URL: config.CONTROL_PLANE_URL,
|
||||
OAUTH_ISSUER: `${config.CONTROL_PLANE_PUBLIC_URL}/oauth`,
|
||||
PORT: '3000',
|
||||
SERVER_ID: serverId,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user