Skip to content

Commit 44efe87

Browse files
committed
fix(mcp): adds production origin to defaults
Adds https://gh.gordoncode.dev to ALLOWED_ORIGINS_DEFAULT so the WebSocket relay works out of the box for deployed SPA users. MCP_RELAY_ALLOWED_ORIGINS env var remains for custom domains/forks.
1 parent 388f442 commit 44efe87

4 files changed

Lines changed: 22 additions & 5 deletions

File tree

DEPLOY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ building.
2222

2323
5. **Cloudflare Turnstile** — Create a widget and set `VITE_TURNSTILE_SITE_KEY` in `.env`. Only needed for the planned Jira/GitLab token sealing feature.
2424
6. **Sentry error reporting** — Set `VITE_SENTRY_DSN` (build-time, via GitHub Actions variable) and `SENTRY_DSN` (Worker secret, via `wrangler secret put`) to the **same** DSN value. The Worker tunnel (`/api/error-reporting`) validates the incoming envelope DSN against `env.SENTRY_DSN` — different values cause all Sentry events to silently return 403. Leave both empty to disable.
25-
7. **MCP relay**Set `MCP_RELAY_ALLOWED_ORIGINS=https://YOUR-DOMAIN` when running the MCP server
25+
7. **MCP relay**If deploying to a custom domain, set `MCP_RELAY_ALLOWED_ORIGINS=https://YOUR-DOMAIN` when running the MCP server (`https://gh.gordoncode.dev` is allowed by default)
2626
8. **WAF smoke tests** — Set `DEPLOY_DOMAIN` as a GitHub Actions variable (e.g., `your-domain.example.com`). CI runs `pnpm test:waf https://$DEPLOY_DOMAIN` automatically. If `DEPLOY_DOMAIN` is not set, the WAF test is skipped. Run locally with: `pnpm test:waf https://YOUR-DOMAIN`.
2727
9. **Social metadata** — Update `og:image` and `og:url` in `index.html` to your domain
2828
10. **Security contact** — Update the email and scope domain in `SECURITY.md`

mcp/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ npm install -g github-tracker-mcp
1818
|----------|----------|---------|-------------|
1919
| `GITHUB_TOKEN` | No || Classic PAT with `repo` and `read:org` scopes (recommended), or fine-grained PAT with Actions (read), Contents (read), Issues (read), and Pull requests (read) permissions. Fine-grained PATs skip scope validation at startup. |
2020
| `MCP_WS_PORT` | No | `9876` | WebSocket relay port for receiving live data from the dashboard SPA. |
21-
| `MCP_RELAY_ALLOWED_ORIGINS` | No || Comma-separated additional origins for WebSocket connections (e.g., `https://your-domain.example.com`). Localhost origins are always allowed. |
21+
| `MCP_RELAY_ALLOWED_ORIGINS` | No || Comma-separated additional origins for WebSocket connections. Only needed if you deploy to a custom domain (the default `https://gh.gordoncode.dev` and localhost origins are always allowed). |
2222

2323
`GITHUB_TOKEN` is required for standalone (direct API) mode. In relay mode the server receives data from the dashboard and works without a token. If you set `GITHUB_TOKEN` alongside the relay, the server uses it as a fallback when the relay disconnects.
2424

mcp/src/ws-relay.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ const ALLOWED_ORIGINS_DEFAULT = new Set([
4444
"https://localhost",
4545
"http://127.0.0.1",
4646
"https://127.0.0.1",
47+
"https://gh.gordoncode.dev",
4748
]);
4849

4950
function buildAllowedOrigins(): Set<string> {
@@ -60,9 +61,9 @@ function buildAllowedOrigins(): Set<string> {
6061
// Computed once at module scope — origins don't change at runtime
6162
const ALLOWED_ORIGINS = buildAllowedOrigins();
6263

63-
// Warn if only localhost origins are configured — production domains need MCP_RELAY_ALLOWED_ORIGINS
64-
if (!process.env.MCP_RELAY_ALLOWED_ORIGINS) {
65-
console.warn("[mcp/ws] Warning: No MCP_RELAY_ALLOWED_ORIGINS set — only localhost connections allowed. Set this to your production domain to allow WebSocket relay from the deployed SPA.");
64+
// Log extra origins if configured (useful for custom deployments / forks)
65+
if (process.env.MCP_RELAY_ALLOWED_ORIGINS) {
66+
console.error("[mcp/ws] Additional allowed origins:", process.env.MCP_RELAY_ALLOWED_ORIGINS);
6667
}
6768

6869
function isOriginAllowed(origin: string | undefined): boolean {

mcp/tests/ws-relay.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,22 @@ describe("WebSocket relay server — origin validation", () => {
407407
expect(opened).toBe(true);
408408
});
409409

410+
it("allows connections from the production domain", async () => {
411+
const ws = new WebSocket(`ws://127.0.0.1:${port}`, {
412+
headers: { origin: "https://gh.gordoncode.dev" },
413+
});
414+
415+
const opened = await new Promise<boolean>((resolve) => {
416+
ws.once("open", () => { ws.close(); resolve(true); });
417+
ws.once("error", () => resolve(false));
418+
ws.once("close", (code) => {
419+
if (code !== 1000 && code !== 1001) resolve(false);
420+
});
421+
});
422+
423+
expect(opened).toBe(true);
424+
});
425+
410426
it("rejects connections from disallowed origins", async () => {
411427
// The server calls verifyClient with callback(false, 403, "Origin not allowed").
412428
// The ws library sends an HTTP 403 response, which the client sees as an error.

0 commit comments

Comments
 (0)