diff --git a/README.md b/README.md
index 32de4c18..19d24918 100644
--- a/README.md
+++ b/README.md
@@ -614,7 +614,7 @@ point is `evaluateWizardReadiness()`, which returns one of three values:
| --- | --- |
| `types.ts` | Enums, interfaces (`ServiceHealthStatus`, `AllServicesHealth`, etc.) |
| `statuspage.ts` | Statuspage.io v2 API helpers + checks for Anthropic, PostHog, GitHub, npm, Cloudflare |
-| `endpoints.ts` | Direct endpoint checks for LLM Gateway (`/_liveness`), MCP (`/`), and the skills origins (`skill-menu.json` on GitHub Releases + the AWS mirror) |
+| `endpoints.ts` | Direct endpoint checks for MCP (`/`) and the skills origins (`skill-menu.json` on GitHub Releases + the AWS mirror) |
| `readiness.ts` | `checkAllExternalServices`, `evaluateWizardReadiness`, readiness config |
| `index.ts` | Barrel re-export |
| `testme.md` | Test running instructions and endpoint reference |
@@ -632,10 +632,14 @@ two arrays:
### Current defaults
```ts
-downBlocksRun: ['anthropic', 'npmOverall', 'llmGateway', 'mcp', 'skillsOrigin'],
+downBlocksRun: ['anthropic', 'npmOverall', 'mcp', 'skillsOrigin'],
degradedBlocksRun: ['anthropic'],
```
+The AI gateway is deliberately absent: its URL is only known from the run's
+token mint at bootstrap, so there is nothing static to probe — and a failed
+mint already stops the run with the server's reason.
+
`skillsOrigin` is one entry covering two origins: skills are published to
GitHub Releases and an AWS mirror under the same filenames, and downloads fail
over between them (`src/lib/fetch-retry.ts`). Both are probed in parallel, so
diff --git a/src/lib/health-checks/__tests__/health-checks.test.ts b/src/lib/health-checks/__tests__/health-checks.test.ts
index 66ebca37..cbafb207 100644
--- a/src/lib/health-checks/__tests__/health-checks.test.ts
+++ b/src/lib/health-checks/__tests__/health-checks.test.ts
@@ -8,9 +8,7 @@
* summary.json – same rollup plus component list; component statuses:
* operational | degraded_performance | partial_outage | major_outage | under_maintenance
* https://support.atlassian.com/statuspage/docs/show-service-status-with-components
- *
- * LLM Gateway – FastAPI service, GET /_liveness returns {"status":"alive"} (200)
- * Source: posthog/services/llm-gateway/src/llm_gateway/api/health.py
+
*
* MCP – Cloudflare Worker, GET / returns an HTML landing page (200)
* Source: posthog/services/mcp/src/index.ts
@@ -23,7 +21,6 @@ import {
checkCloudflareOverallHealth,
checkGithubHealth,
checkSkillsOriginHealth,
- checkLlmGatewayHealth,
checkMcpHealth,
checkNpmComponentHealth,
checkNpmOverallHealth,
@@ -35,6 +32,7 @@ import {
ServiceHealthStatus,
WizardReadiness,
} from '@lib/health-checks/index';
+import { fetchEndpointHealth } from '@lib/health-checks/endpoints';
// ---------------------------------------------------------------------------
// Real-world Statuspage.io v2 response factories
@@ -191,9 +189,6 @@ const POSTHOG_INCIDENTIO_HEALTHY = {
scheduled_maintenances: [],
};
-// LLM Gateway /_liveness response (from posthog/services/llm-gateway/src/llm_gateway/api/health.py)
-const LLM_GATEWAY_LIVENESS_BODY = JSON.stringify({ status: 'alive' });
-
// MCP / landing page (from posthog/services/mcp/src/index.ts + src/static/landing.html)
const MCP_LANDING_HTML =
'
PostHog MCP Server';
@@ -210,7 +205,6 @@ const URLS = {
npmSummary: 'https://status.npmjs.org/api/v2/summary.json',
cloudflareStatus: 'https://www.cloudflarestatus.com/api/v2/status.json',
cloudflareSummary: 'https://www.cloudflarestatus.com/api/v2/summary.json',
- llmGatewayLiveness: 'https://gateway.us.posthog.com/_liveness',
mcpLanding: 'https://mcp.posthog.com/',
githubSkillMenu:
'https://github.com/PostHog/context-mill/releases/latest/download/skill-menu.json',
@@ -251,10 +245,6 @@ const HEALTHY_RESPONSES: Record =
body: JSON.stringify(CLOUDFLARE_SUMMARY_HEALTHY),
contentType: 'application/json',
},
- [URLS.llmGatewayLiveness]: {
- body: LLM_GATEWAY_LIVENESS_BODY,
- contentType: 'application/json',
- },
[URLS.mcpLanding]: {
body: MCP_LANDING_HTML,
contentType: 'text/html; charset=utf-8',
@@ -722,54 +712,64 @@ describe('health-checks', () => {
});
// -----------------------------------------------------------------------
- // LLM Gateway (fetchEndpointHealth – /_liveness)
+ // fetchEndpointHealth (retry + status-taxonomy machinery, probed directly
+ // against a synthetic URL — no production probe uses the strict defaults
+ // any more, but every endpoint check shares this loop)
// -----------------------------------------------------------------------
- describe('checkLlmGatewayHealth', () => {
- it('returns healthy when gateway responds 200 with {"status":"alive"}', async () => {
- const result = await checkLlmGatewayHealth();
+ describe('fetchEndpointHealth', () => {
+ const PROBE_URL = 'https://probe.posthog.test/_liveness';
+
+ it('returns healthy on a 200', async () => {
+ (global.fetch as Mock).mockImplementation(
+ overrideFetch({
+ [PROBE_URL]: () =>
+ Promise.resolve(new Response('ok', { status: 200 })),
+ }),
+ );
+ const result = await fetchEndpointHealth(PROBE_URL);
expect(result.status).toBe(ServiceHealthStatus.Healthy);
expect(result.rawIndicator).toBe('HTTP 200');
expect(global.fetch).toHaveBeenCalledWith(
- URLS.llmGatewayLiveness,
+ PROBE_URL,
expect.objectContaining({ signal: expect.any(AbortSignal) }),
);
});
- it('returns down on 302 — the gateway probe stays strict, redirects are not OK here', async () => {
+ it('returns down on 302 — the default predicate stays strict, redirects are not OK', async () => {
(global.fetch as Mock).mockImplementation(
overrideFetch({
- [URLS.llmGatewayLiveness]: () =>
+ [PROBE_URL]: () =>
Promise.resolve(new Response(null, { status: 302 })),
}),
);
- const result = await checkLlmGatewayHealth();
+ const result = await fetchEndpointHealth(PROBE_URL);
expect(result.status).toBe(ServiceHealthStatus.Down);
expect(result.error).toContain('HTTP 302');
});
- it('returns down when gateway responds 503 (e.g. deploying)', async () => {
+ it('returns down when the endpoint responds 503 (e.g. deploying)', async () => {
(global.fetch as Mock).mockImplementation(
overrideFetch({
- [URLS.llmGatewayLiveness]: () =>
+ [PROBE_URL]: () =>
Promise.resolve(
new Response('Service Unavailable', { status: 503 }),
),
}),
);
- const result = await checkLlmGatewayHealth();
+ const result = await fetchEndpointHealth(PROBE_URL);
expect(result.status).toBe(ServiceHealthStatus.Down);
expect(result.error).toContain('HTTP 503');
});
- it('returns down when gateway responds 502 (bad gateway)', async () => {
+ it('returns down when the endpoint responds 502 (bad gateway)', async () => {
(global.fetch as Mock).mockImplementation(
overrideFetch({
- [URLS.llmGatewayLiveness]: () =>
+ [PROBE_URL]: () =>
Promise.resolve(new Response('Bad Gateway', { status: 502 })),
}),
);
- const result = await checkLlmGatewayHealth();
+ const result = await fetchEndpointHealth(PROBE_URL);
expect(result.status).toBe(ServiceHealthStatus.Down);
expect(result.error).toContain('HTTP 502');
});
@@ -777,15 +777,15 @@ describe('health-checks', () => {
it('returns no-connection on DNS resolution failure (no status-page corroboration)', async () => {
(global.fetch as Mock).mockImplementation(
overrideFetch({
- [URLS.llmGatewayLiveness]: () =>
+ [PROBE_URL]: () =>
Promise.reject(
- new Error('getaddrinfo ENOTFOUND gateway.us.posthog.com'),
+ new Error('getaddrinfo ENOTFOUND probe.posthog.test'),
),
}),
);
- const result = await checkLlmGatewayHealth();
+ const result = await fetchEndpointHealth(PROBE_URL);
expect(result.status).toBe(ServiceHealthStatus.NoConnection);
- expect(result.error).toBe('getaddrinfo ENOTFOUND gateway.us.posthog.com');
+ expect(result.error).toBe('getaddrinfo ENOTFOUND probe.posthog.test');
});
it('returns no-connection on timeout (AbortError)', async () => {
@@ -793,10 +793,10 @@ describe('health-checks', () => {
abortError.name = 'AbortError';
(global.fetch as Mock).mockImplementation(
overrideFetch({
- [URLS.llmGatewayLiveness]: () => Promise.reject(abortError),
+ [PROBE_URL]: () => Promise.reject(abortError),
}),
);
- const result = await checkLlmGatewayHealth();
+ const result = await fetchEndpointHealth(PROBE_URL);
expect(result.status).toBe(ServiceHealthStatus.NoConnection);
expect(result.error).toBe('Request timed out after 5000ms');
});
@@ -805,18 +805,16 @@ describe('health-checks', () => {
let calls = 0;
(global.fetch as Mock).mockImplementation(
overrideFetch({
- [URLS.llmGatewayLiveness]: () => {
+ [PROBE_URL]: () => {
calls++;
if (calls < 3) {
return Promise.reject(new Error('ECONNRESET'));
}
- return Promise.resolve(
- new Response(LLM_GATEWAY_LIVENESS_BODY, { status: 200 }),
- );
+ return Promise.resolve(new Response('ok', { status: 200 }));
},
}),
);
- const result = await checkLlmGatewayHealth();
+ const result = await fetchEndpointHealth(PROBE_URL);
expect(result.status).toBe(ServiceHealthStatus.Healthy);
expect(result.rawIndicator).toContain('attempts=3');
expect(calls).toBe(3);
@@ -826,7 +824,7 @@ describe('health-checks', () => {
let calls = 0;
(global.fetch as Mock).mockImplementation(
overrideFetch({
- [URLS.llmGatewayLiveness]: () => {
+ [PROBE_URL]: () => {
calls++;
return Promise.resolve(
new Response('Service Unavailable', { status: 503 }),
@@ -834,7 +832,7 @@ describe('health-checks', () => {
},
}),
);
- const result = await checkLlmGatewayHealth();
+ const result = await fetchEndpointHealth(PROBE_URL);
expect(result.status).toBe(ServiceHealthStatus.Down);
expect(calls).toBe(3);
expect(result.error).toContain('HTTP 503');
@@ -845,20 +843,18 @@ describe('health-checks', () => {
let calls = 0;
(global.fetch as Mock).mockImplementation(
overrideFetch({
- [URLS.llmGatewayLiveness]: () => {
+ [PROBE_URL]: () => {
calls++;
if (calls < 3) {
return Promise.resolve(
new Response('Bad Gateway', { status: 502 }),
);
}
- return Promise.resolve(
- new Response(LLM_GATEWAY_LIVENESS_BODY, { status: 200 }),
- );
+ return Promise.resolve(new Response('ok', { status: 200 }));
},
}),
);
- const result = await checkLlmGatewayHealth();
+ const result = await fetchEndpointHealth(PROBE_URL);
expect(result.status).toBe(ServiceHealthStatus.Healthy);
expect(result.rawIndicator).toContain('attempts=3');
expect(calls).toBe(3);
@@ -868,7 +864,7 @@ describe('health-checks', () => {
let calls = 0;
(global.fetch as Mock).mockImplementation(
overrideFetch({
- [URLS.llmGatewayLiveness]: () => {
+ [PROBE_URL]: () => {
calls++;
if (calls < 3) return Promise.reject(new Error('ECONNRESET'));
return Promise.resolve(
@@ -877,7 +873,7 @@ describe('health-checks', () => {
},
}),
);
- const result = await checkLlmGatewayHealth();
+ const result = await fetchEndpointHealth(PROBE_URL);
expect(result.status).toBe(ServiceHealthStatus.Down);
expect(result.error).toContain('HTTP 502');
});
@@ -1082,7 +1078,7 @@ describe('health-checks', () => {
// -----------------------------------------------------------------------
describe('checkAllExternalServices', () => {
- it('returns all 11 service keys when everything is healthy', async () => {
+ it('returns all 10 service keys when everything is healthy', async () => {
const health = await checkAllExternalServices();
const keys = Object.keys(health);
expect(keys).toEqual(
@@ -1095,18 +1091,17 @@ describe('health-checks', () => {
'npmComponents',
'cloudflareOverall',
'cloudflareComponents',
- 'llmGateway',
'mcp',
'skillsOrigin',
]),
);
- expect(keys).toHaveLength(11);
+ expect(keys).toHaveLength(10);
for (const val of Object.values(health)) {
expect(val.status).toBe(ServiceHealthStatus.Healthy);
}
});
- it('upgrades NoConnection llmGateway/mcp to Down when status page reports an outage', async () => {
+ it('upgrades NoConnection mcp to Down when status page reports an outage', async () => {
const incidentBody = {
...POSTHOG_INCIDENTIO_HEALTHY,
ongoing_incidents: [
@@ -1128,20 +1123,17 @@ describe('health-checks', () => {
Promise.resolve(
new Response(JSON.stringify(incidentBody), { status: 200 }),
),
- [URLS.llmGatewayLiveness]: () =>
- Promise.reject(new Error('ECONNRESET')),
[URLS.mcpLanding]: () => Promise.reject(new Error('ECONNRESET')),
}),
);
const health = await checkAllExternalServices();
expect(health.posthogOverall.status).toBe(ServiceHealthStatus.Down);
- expect(health.llmGateway.status).toBe(ServiceHealthStatus.Down);
- expect(health.llmGateway.error).toContain('corroborated by status page');
expect(health.mcp.status).toBe(ServiceHealthStatus.Down);
+ expect(health.mcp.error).toContain('corroborated by status page');
});
- it('keeps llmGateway/mcp as NoConnection when posthogstatus.com itself is unreachable (the bug-fix scenario)', async () => {
+ it('keeps mcp as NoConnection when posthogstatus.com itself is unreachable (the bug-fix scenario)', async () => {
// User on flaky wifi: every PostHog-owned URL fetch fails at the
// network layer, including posthogstatus.com. Previously
// incidentio.ts returned Degraded for fetch failures, which
@@ -1152,8 +1144,6 @@ describe('health-checks', () => {
overrideFetch({
[URLS.posthogIncidentIo]: () =>
Promise.reject(new Error('ECONNRESET')),
- [URLS.llmGatewayLiveness]: () =>
- Promise.reject(new Error('ECONNRESET')),
[URLS.mcpLanding]: () => Promise.reject(new Error('ECONNRESET')),
}),
);
@@ -1162,22 +1152,18 @@ describe('health-checks', () => {
expect(health.posthogOverall.status).toBe(
ServiceHealthStatus.NoConnection,
);
- expect(health.llmGateway.status).toBe(ServiceHealthStatus.NoConnection);
expect(health.mcp.status).toBe(ServiceHealthStatus.NoConnection);
});
- it('keeps llmGateway/mcp as NoConnection when status page reports no incident', async () => {
+ it('keeps mcp as NoConnection when status page reports no incident', async () => {
(global.fetch as Mock).mockImplementation(
overrideFetch({
- [URLS.llmGatewayLiveness]: () =>
- Promise.reject(new Error('ETIMEDOUT')),
[URLS.mcpLanding]: () => Promise.reject(new Error('ETIMEDOUT')),
}),
);
const health = await checkAllExternalServices();
expect(health.posthogOverall.status).toBe(ServiceHealthStatus.Healthy);
- expect(health.llmGateway.status).toBe(ServiceHealthStatus.NoConnection);
expect(health.mcp.status).toBe(ServiceHealthStatus.NoConnection);
});
@@ -1187,9 +1173,8 @@ describe('health-checks', () => {
typeof c[0] === 'string' ? c[0] : (c[0] as URL).toString(),
);
// PostHog uses a single incident.io endpoint for both overall + components
- expect(calledUrls).toHaveLength(11);
+ expect(calledUrls).toHaveLength(10);
expect(calledUrls).toContain(URLS.posthogIncidentIo);
- expect(calledUrls).toContain(URLS.llmGatewayLiveness);
expect(calledUrls).toContain(URLS.mcpLanding);
expect(calledUrls).toContain(URLS.githubSkillMenu);
expect(calledUrls).toContain(URLS.awsSkillMenu);
@@ -1231,22 +1216,6 @@ describe('health-checks', () => {
expect(result.health.anthropic.status).toBe(ServiceHealthStatus.Degraded);
});
- it('returns No when LLM Gateway is down (downBlocksRun)', async () => {
- (global.fetch as Mock).mockImplementation(
- overrideFetch({
- [URLS.llmGatewayLiveness]: () =>
- Promise.resolve(
- new Response('Service Unavailable', { status: 503 }),
- ),
- }),
- );
- const result = await evaluateWizardReadiness(
- DEFAULT_WIZARD_READINESS_CONFIG,
- );
- expect(result.decision).toBe(WizardReadiness.No);
- expect(result.health.llmGateway.status).toBe(ServiceHealthStatus.Down);
- });
-
it('returns No when MCP is down (downBlocksRun)', async () => {
(global.fetch as Mock).mockImplementation(
overrideFetch({
@@ -1316,7 +1285,6 @@ describe('health-checks', () => {
expect(result.reasons.some((r) => r.includes('GitHub'))).toBe(true);
expect(result.reasons.some((r) => r.includes('npm'))).toBe(true);
expect(result.reasons.some((r) => r.includes('Cloudflare'))).toBe(true);
- expect(result.reasons.some((r) => r.includes('LLM Gateway'))).toBe(true);
expect(result.reasons.some((r) => r.includes('MCP'))).toBe(true);
});
});
diff --git a/src/lib/health-checks/endpoints.ts b/src/lib/health-checks/endpoints.ts
index ccb2fa16..2be4c5df 100644
--- a/src/lib/health-checks/endpoints.ts
+++ b/src/lib/health-checks/endpoints.ts
@@ -13,10 +13,6 @@ import { ServiceHealthStatus, type BaseHealthResult } from './types';
// NoConnection means we don't know whose fault it is; readiness reconciles
// against the status page before deciding how to surface it to the user.
//
-// LLM Gateway – FastAPI service
-// Source: posthog/services/llm-gateway/src/llm_gateway/api/health.py
-// GET /_liveness → 200 {"status":"alive"}
-//
// MCP – Cloudflare Worker
// Source: posthog/services/mcp/src/index.ts
// GET / → 302 to posthog.com docs. The redirect proves the worker is up.
@@ -65,7 +61,8 @@ async function attemptFetch(
}
}
-async function fetchEndpointHealth(
+// Exported so tests can pin the retry/taxonomy machinery directly.
+export async function fetchEndpointHealth(
url: string,
timeoutMs = 5000,
isExpectedStatus: (status: number) => boolean = (s) => s === 200,
@@ -137,9 +134,6 @@ async function fetchEndpointHealth(
return result;
}
-export const checkLlmGatewayHealth = (): Promise =>
- fetchEndpointHealth('https://gateway.us.posthog.com/_liveness');
-
export const checkMcpHealth = (): Promise =>
fetchEndpointHealth(
'https://mcp.posthog.com/',
diff --git a/src/lib/health-checks/index.ts b/src/lib/health-checks/index.ts
index be2d40e8..b4c3f604 100644
--- a/src/lib/health-checks/index.ts
+++ b/src/lib/health-checks/index.ts
@@ -22,11 +22,7 @@ export {
resetPosthogHealthCache,
} from './incidentio';
-export {
- checkLlmGatewayHealth,
- checkMcpHealth,
- checkSkillsOriginHealth,
-} from './endpoints';
+export { checkMcpHealth, checkSkillsOriginHealth } from './endpoints';
export {
type WizardReadinessConfig,
diff --git a/src/lib/health-checks/readiness.ts b/src/lib/health-checks/readiness.ts
index 018cf84d..6cd88367 100644
--- a/src/lib/health-checks/readiness.ts
+++ b/src/lib/health-checks/readiness.ts
@@ -17,11 +17,7 @@ import {
checkPosthogOverallHealth,
checkPosthogComponentHealth,
} from './incidentio';
-import {
- checkLlmGatewayHealth,
- checkMcpHealth,
- checkSkillsOriginHealth,
-} from './endpoints';
+import { checkMcpHealth, checkSkillsOriginHealth } from './endpoints';
import { logToFile } from '@utils/debug';
// ---------------------------------------------------------------------------
@@ -37,7 +33,6 @@ export const SERVICE_LABELS: Record = {
npmComponents: 'npm (components)',
cloudflareOverall: 'Cloudflare',
cloudflareComponents: 'Cloudflare (components)',
- llmGateway: 'LLM Gateway',
mcp: 'MCP',
skillsOrigin: 'Skills download',
};
@@ -56,26 +51,24 @@ export interface WizardReadinessConfig {
/**
* See README section "Health checks" for the full rationale.
* Adjust these arrays to change what blocks a wizard run.
+ *
+ * The AI gateway is not probed: its URL is only known from the run's token
+ * mint, and a failed mint already stops the run at bootstrap with the
+ * server's reason.
*/
export const DEFAULT_WIZARD_READINESS_CONFIG: WizardReadinessConfig = {
- downBlocksRun: [
- 'anthropic',
- 'npmOverall',
- 'llmGateway',
- 'mcp',
- 'skillsOrigin',
- ],
+ downBlocksRun: ['anthropic', 'npmOverall', 'mcp', 'skillsOrigin'],
degradedBlocksRun: ['anthropic'],
};
/**
* Reduced readiness config for --signup provisioning flows.
*
- * Provisioning only needs PostHog and the LLM Gateway - it doesn't
- * use Anthropic directly, npm, the skills origins, or MCP.
+ * Provisioning only needs PostHog - it doesn't use Anthropic directly, npm,
+ * the skills origins, or MCP.
*/
export const SIGNUP_WIZARD_READINESS_CONFIG: WizardReadinessConfig = {
- downBlocksRun: ['posthogOverall', 'llmGateway'],
+ downBlocksRun: ['posthogOverall'],
};
// ---------------------------------------------------------------------------
@@ -92,7 +85,6 @@ export async function checkAllExternalServices(): Promise {
npmComponents,
cloudflareOverall,
cloudflareComponents,
- llmGateway,
mcp,
skillsOrigin,
] = await Promise.all([
@@ -104,7 +96,6 @@ export async function checkAllExternalServices(): Promise {
checkNpmComponentHealth(),
checkCloudflareOverallHealth(),
checkCloudflareComponentHealth(),
- checkLlmGatewayHealth(),
checkMcpHealth(),
checkSkillsOriginHealth(),
]);
@@ -118,7 +109,6 @@ export async function checkAllExternalServices(): Promise {
npmComponents,
cloudflareOverall,
cloudflareComponents,
- llmGateway,
mcp,
skillsOrigin,
};
@@ -131,7 +121,7 @@ export async function checkAllExternalServices(): Promise {
* official status page (`posthogstatus.com`):
*
* - Status page says PostHog is `Down` / `Degraded` → upgrade
- * llmGateway / mcp to `Down`. The status page corroborates.
+ * mcp to `Down`. The status page corroborates.
* - Status page is `Healthy` → keep `NoConnection`. The status page
* contradicts; this is probably the user's network.
* - Status page is also `NoConnection` → keep `NoConnection`. User
@@ -145,11 +135,11 @@ export async function checkAllExternalServices(): Promise {
* when incident.io's API parsed successfully and reported a real
* `partial_outage` or `degraded_performance` for some component. That's
* PostHog acknowledging an issue, even if narrower than a full outage.
- * If our gateway probe is also failing, those two signals together
+ * If our MCP probe is also failing, those two signals together
* justify pointing at PostHog rather than the user.
*
* A narrower variant — only corroborate when the affected component is
- * gateway-related (LLM, US/EU Cloud, app) — would be more precise. We
+ * MCP-related (US/EU Cloud, app) — would be more precise. We
* have the data in `posthogComponents` but don't use it here. If the
* analytics show false positives concentrated in this case, it's a
* cheap follow-up.
@@ -179,7 +169,6 @@ export function reconcilePosthogReachability(
return {
...health,
- llmGateway: upgrade(health.llmGateway),
mcp: upgrade(health.mcp),
};
}
@@ -346,7 +335,6 @@ function allUnknown(error: string): AllServicesHealth {
npmComponents: { ...base },
cloudflareOverall: base,
cloudflareComponents: { ...base },
- llmGateway: base,
mcp: base,
skillsOrigin: base,
};
diff --git a/src/lib/health-checks/testme.md b/src/lib/health-checks/testme.md
index 7eb5c32a..9cf6a720 100644
--- a/src/lib/health-checks/testme.md
+++ b/src/lib/health-checks/testme.md
@@ -40,7 +40,6 @@ responses captured from production endpoints on 2026-03-05.
| npm (components) | `https://status.npmjs.org/api/v2/summary.json` | Adds `components[]` array |
| Cloudflare | `https://www.cloudflarestatus.com/api/v2/status.json` | Same shape |
| Cloudflare (components) | `https://www.cloudflarestatus.com/api/v2/summary.json` | Adds `components[]` array |
-| LLM Gateway | `https://gateway.us.posthog.com/_liveness` | `{"status":"alive"}` (HTTP 200) |
| MCP | `https://mcp.posthog.com/` | HTML landing page (HTTP 200) |
### Statuspage.io API v2 reference
@@ -54,13 +53,6 @@ responses captured from production endpoints on 2026-03-05.
- Component docs:
-### LLM Gateway
-
-- Source: `posthog/services/llm-gateway/src/llm_gateway/api/health.py`
-- `GET /` → `{"service":"llm-gateway","status":"running"}`
-- `GET /_liveness` → `{"status":"alive"}` (no DB dependency)
-- `GET /_readiness` → `{"status":"ready"}` (checks Postgres with `SELECT 1`)
-
### MCP
- Source: `posthog/services/mcp/src/index.ts`
diff --git a/src/lib/health-checks/types.ts b/src/lib/health-checks/types.ts
index 02aeed48..f838bbf9 100644
--- a/src/lib/health-checks/types.ts
+++ b/src/lib/health-checks/types.ts
@@ -37,7 +37,6 @@ export interface AllServicesHealth {
npmComponents: ComponentHealthResult;
cloudflareOverall: BaseHealthResult;
cloudflareComponents: ComponentHealthResult;
- llmGateway: BaseHealthResult;
mcp: BaseHealthResult;
skillsOrigin: BaseHealthResult;
}
diff --git a/src/ui/tui/playground/demos/HealthCheckDemo.tsx b/src/ui/tui/playground/demos/HealthCheckDemo.tsx
index 03c7064d..501f6972 100644
--- a/src/ui/tui/playground/demos/HealthCheckDemo.tsx
+++ b/src/ui/tui/playground/demos/HealthCheckDemo.tsx
@@ -44,7 +44,6 @@ const MOCK_CONFIRMED_OUTAGE: AllServicesHealth = {
},
cloudflareOverall: HEALTHY,
cloudflareComponents: { status: ServiceHealthStatus.Healthy },
- llmGateway: HEALTHY,
mcp: HEALTHY,
skillsOrigin: HEALTHY,
};
@@ -58,10 +57,6 @@ const MOCK_NO_CONNECTION: AllServicesHealth = {
npmComponents: { status: ServiceHealthStatus.Healthy },
cloudflareOverall: HEALTHY,
cloudflareComponents: { status: ServiceHealthStatus.Healthy },
- llmGateway: {
- status: ServiceHealthStatus.NoConnection,
- error: 'getaddrinfo ENOTFOUND gateway.us.posthog.com',
- },
mcp: {
status: ServiceHealthStatus.NoConnection,
error: 'fetch failed',
diff --git a/src/ui/tui/store.ts b/src/ui/tui/store.ts
index 1f2f8a16..12cf174a 100644
--- a/src/ui/tui/store.ts
+++ b/src/ui/tui/store.ts
@@ -156,7 +156,7 @@ function captureHealthCheckBlocked(result: WizardReadinessResult): void {
const posthogStatus = health.posthogOverall?.status;
const retriesUsed = Math.max(
0,
- ...(['llmGateway', 'mcp', 'skillsOrigin'] as const).map((k) => {
+ ...(['mcp', 'skillsOrigin'] as const).map((k) => {
const ind = health[k]?.rawIndicator ?? '';
const m = ind.match(/attempts=(\d+)/);
return m ? Number(m[1]) - 1 : 0;