Skip to content

fix(gateway): point all 18 tools + 2 resources at api.wave.online/v1/*, not the 404ing marketing site - #92

Open
yakimoto wants to merge 5 commits into
mainfrom
fix/gateway-base-url-91
Open

fix(gateway): point all 18 tools + 2 resources at api.wave.online/v1/*, not the 404ing marketing site#92
yakimoto wants to merge 5 commits into
mainfrom
fix/gateway-base-url-91

Conversation

@yakimoto

@yakimoto yakimoto commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

What

Fixes #91: every one of this package's 18 tools (plus both wave:// resources) built requests as ${WAVE_BASE_URL}/api/v1/... against a default WAVE_BASE_URL of https://wave.online — the marketing/docs Next.js site. Neither wave.online nor api.wave.online serve /api/v1/*: per wave-gateway's forward.ts:262 (ORIGIN_PATH_PREFIX), that prefix is the gateway's internal forwarding shape to the WSC origin, never a path a client should call directly. Every customer using the published package (currently 0.2.0 on npm) got a prerendered Next.js 404 on every tool call — a live prod defect, not hypothetical.

Root cause, confirmed against wave-gateway

wave-gateway PR #835 (same session, filed the finding as issue #91 here) independently probed all 18 routes with zero credentials and receipts in the PR body:

$ ./scripts/probe-agent-plugin-redline.sh https://api.wave.online /v1
... 18/18 routes -> 402 PAYMENT_REQUIRED  (PASS: route exists AND is priced/gated)

$ ./scripts/probe-agent-plugin-redline.sh https://wave.online /api/v1
$ ./scripts/probe-agent-plugin-redline.sh https://api.wave.online /api/v1
... 18/18 routes -> 404 HTML(non-gateway origin), x-nextjs-cache: HIT (FAIL: absent, not gated)

So this is not a "never wired up" bug — the backend routes are real, live, and correctly gated at the gateway-public /v1/* shape. This package was simply pointed at the wrong origin and the wrong (internal) path prefix.

Fix

  • src/auth.ts: DEFAULT_BASE_URLhttps://api.wave.online (was https://wave.online)
  • src/tools/*.ts, src/resources/*.ts: /api/v1/*/v1/* (18 call sites across streams.ts, studio.ts, analytics.ts, billing.ts, production.ts, plus both resources/*.ts)
  • README.md: corrected the documented WAVE_BASE_URL default
  • CHANGELOG.md: Unreleased entry

WAVE_BASE_URL env override still works unchanged for anyone pointed at a non-default environment (staging, etc).

Tests

This repo had no test runner at all. Added tsx (pinned, devDependency) + a test npm script (node --import tsx --test), and three test files:

  • src/auth.test.ts — unit tests for getBaseUrl()'s default + WAVE_BASE_URL override, getApiKey()'s error message
  • src/tools/regression-91.test.ts — mocks the HTTP layer, invokes all 18 tool handlers with minimal valid args, asserts every one calls https://api.wave.online/v1/* and never /api/v1/*
  • src/resources/regression-91.test.ts — same proof for the two wave:// resources

Verified the tests actually catch the bug, not just pass trivially: ran the same test files against a scratch copy with the old /api/v1/* paths and wave.online default restored — 18/18 tool subtests plus the base-URL assertion failed there, confirming the test is a real regression guard, not a tautology. All pass against this fix (23/23).

$ NODE_ENV=development npm test
# tests 23
# pass 23
# fail 0

$ NODE_ENV=development npm run type-check   # clean
$ NODE_ENV=development npm run lint         # clean, --max-warnings 0
$ NODE_ENV=development npm run build        # clean; grepped dist/ bundle for
                                             # "api/v1" (0 hits) and confirmed
                                             # DEFAULT_BASE_URL = api.wave.online

Not in scope (flagged, not fixed here)

  • capabilities.json says "version": "0.1.5" vs package.json's 0.2.0 (noted as a follow-up in wave-gateway#835, doc-drift only, unrelated to this bug)
  • src/tools/shared.ts's User-Agent: wave-mcp-server/0.1.0 string is stale too, but not part of this defect

Note on the "never wired up" branch of this investigation

The task that produced this PR explicitly considered the alternative root cause — that these 18 tools' backend routes might never have existed in wave-gateway at all (package shipped ahead of backend). Ruled out: wave-gateway PR #835's redteam probe proves all 18 gateway-public /v1/* routes are live and scope-gated today. This is a wrong-URL bug in this package, fully fixable here, not a cross-repo/product decision.

🤖 Generated with Claude Code


Note

Cursor Bugbot is generating a summary for commit 0a51952. Configure here.


View with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is enabled.

Review in cubic

Note

Fix all 18 tools and 2 resources to call api.wave.online/v1/* instead of the marketing site

  • Changes DEFAULT_BASE_URL in auth.ts from https://wave.online to https://api.wave.online, fixing 404s across all handlers.
  • Strips the /api prefix from every hardcoded path across all tool and resource handlers so requests target /v1/* instead of /api/v1/*.
  • Adds regression tests in src/tools/regression-91.test.ts and src/resources/regression-91.test.ts that intercept fetch and assert all calls go to https://api.wave.online/v1/*.
  • Behavioral Change: any deployment relying on the old https://wave.online default or /api/v1/* paths must update WAVE_BASE_URL if it was overriding to the correct host — all requests now go to api.wave.online/v1/* by default.

Macroscope summarized 0a51952.

…e 404ing marketing site (#91)

Every tool/resource built requests as `${WAVE_BASE_URL}/api/v1/...` against a
default WAVE_BASE_URL of https://wave.online (the marketing/docs Next.js
site). Neither wave.online nor api.wave.online serve /api/v1/* — that prefix
is wave-gateway internal forwarding shape to the WSC origin
(forward.ts ORIGIN_PATH_PREFIX), never a path a client should call directly.
Every customer using the published package got a prerendered Next.js 404 on
every tool call.

wave-gateway PR #835 proved, with zero credentials and receipts in the PR
body, that the gateway-public equivalents at /v1/* against
https://api.wave.online are live and scope-gated: 18/18 routes answered 402
PAYMENT_REQUIRED. Fixed this package to build exactly that shape:

- src/auth.ts: DEFAULT_BASE_URL -> https://api.wave.online
- src/tools/*.ts, src/resources/*.ts: /api/v1/* -> /v1/*
- README.md: corrected the documented WAVE_BASE_URL default

Adds a regression test suite (no test runner previously existed in this repo
- added tsx + a node:test script) that mocks the HTTP layer and proves every
one of the 18 tools and both wave:// resources now calls
https://api.wave.online/v1/*, and never /api/v1/*. Verified the test suite
actually catches the bug by running it against a scratch copy with the old
paths restored (18/18 + base-url assertions fail there; all pass on this
fix).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@cursor

cursor Bot commented Aug 7, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_8f0d941e-178f-4948-9a17-ff7d9b3b1984)

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 18 minutes

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 75f5df8e-232a-4eaf-b0c5-e5202f0d0304

📥 Commits

Reviewing files that changed from the base of the PR and between 8411936 and cefe270.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (18)
  • .github/workflows/lint.yml
  • .wave/repo.json
  • CHANGELOG.md
  • MCP-DEBUGGING.md
  • README.md
  • package.json
  • src/auth.test.ts
  • src/auth.ts
  • src/resources/productions.ts
  • src/resources/regression-91.test.ts
  • src/resources/streams.ts
  • src/tools/analytics.ts
  • src/tools/billing.ts
  • src/tools/production.ts
  • src/tools/regression-91.test.ts
  • src/tools/streams.ts
  • src/tools/studio.ts
  • tsconfig.test.json

Comment @coderabbitai help to get the list of available commands.

@socket-security

socket-security Bot commented Aug 7, 2026

Copy link
Copy Markdown

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

fix(gateway): use api.wave.online/v1 for all tools/resources (fix #91)

🐞 Bug fix 🧪 Tests ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Fix default base URL and route prefix so calls hit wave-gateway /v1/*, not the marketing site.
• Update all 18 tool handlers and both wave:// resources to stop using internal /api/v1/* paths.
• Add a Node test harness plus regression tests to prevent this routing defect recurring.
Diagram

graph TD
  MCP["MCP server"] --> Tools["Tools (18)"] --> Auth["Auth/getBaseUrl"] --> HTTP["HTTP fetch"] --> Gateway{{"Wave Gateway /v1"}}
  MCP --> Resources["Resources (2)"] --> Auth --> HTTP --> Gateway
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Centralize API prefix constant
  • ➕ Eliminates repeated string literals (/v1/...) across tools/resources
  • ➕ Reduces chance of future drift between endpoints and docs/tests
  • ➖ Requires a small refactor (introduce constant/helper) beyond the minimal bug fix
2. Build URLs via URL/URLSearchParams + join helper
  • ➕ Avoids subtle slash/double-slash and query-string concatenation issues
  • ➕ Makes request construction more uniform across handlers
  • ➖ More code churn than necessary for the immediate production fix
  • ➖ May require updating many call sites to a new helper signature

Recommendation: The PR’s approach (explicitly switching base URL + path prefix and adding regression tests) is the best near-term fix for a production-facing outage. Consider a follow-up refactor to centralize the /v1 prefix in one helper/constant to prevent accidental reintroduction, but keep this PR focused on correctness + test coverage.

Files changed (15) +1109 / -321

Bug fix (8) +31 / -22
auth.tsSwitch default base URL to api.wave.online and clarify routing +11/-2

Switch default base URL to api.wave.online and clarify routing

• Changes 'DEFAULT_BASE_URL' from 'https://wave.online' to 'https://api.wave.online'. Expands module docs to explain why '/v1/*' is the public gateway surface and '/api/v1/*' is an internal gateway forwarding prefix.

src/auth.ts

productions.tsFix production resource URL to use /v1 +1/-1

Fix production resource URL to use /v1

• Updates the 'wave://productions/{id}' resource handler to fetch via '${getBaseUrl()}/v1/productions/{id}' instead of '/api/v1/...'. Aligns resource routing with the public gateway API.

src/resources/productions.ts

streams.tsFix stream resource URL to use /v1 +1/-1

Fix stream resource URL to use /v1

• Updates the 'wave://streams/{id}' resource handler to fetch via '${getBaseUrl()}/v1/streams/{id}' instead of '/api/v1/...'. Ensures resources target the gateway-public route shape.

src/resources/streams.ts

analytics.tsSwitch analytics tool endpoints from /api/v1 to /v1 +2/-2

Switch analytics tool endpoints from /api/v1 to /v1

• Updates analytics tool request paths to use the public '/v1/analytics/...' prefix. Ensures query-string composition remains unchanged while correcting the route shape.

src/tools/analytics.ts

billing.tsSwitch billing tool endpoints from /api/v1 to /v1 +2/-2

Switch billing tool endpoints from /api/v1 to /v1

• Updates billing tool calls ('subscription', 'usage') to use '/v1/...' instead of '/api/v1/...'. Aligns billing tools with the gateway’s public endpoints.

src/tools/billing.ts

production.tsSwitch production-related tool endpoints from /api/v1 to /v1 +7/-7

Switch production-related tool endpoints from /api/v1 to /v1

• Updates multiple production tool calls (switcher control, clips, graphics, camera control, moderation, captions, highlights) to use '/v1/...'. Removes reliance on the gateway’s internal forwarding prefix.

src/tools/production.ts

streams.tsSwitch stream tool endpoints from /api/v1 to /v1 +5/-5

Switch stream tool endpoints from /api/v1 to /v1

• Updates stream listing, creation, start/stop, and health-check endpoints to use '/v1/streams...'. Ensures the tools hit the gateway-public API shape.

src/tools/streams.ts

studio.tsSwitch studio tool endpoints from /api/v1 to /v1 +2/-2

Switch studio tool endpoints from /api/v1 to /v1

• Updates studio production list/create endpoints to use '/v1/studio/productions...'. Keeps payload/query behavior while correcting the path prefix.

src/tools/studio.ts

Tests (3) +216 / -0
auth.test.tsUnit tests for getBaseUrl/getApiKey behavior +42/-0

Unit tests for getBaseUrl/getApiKey behavior

• Adds tests asserting the default base URL is 'https://api.wave.online' and that 'WAVE_BASE_URL' still overrides it. Verifies 'getApiKey()' throws a clear error when 'WAVE_API_KEY' is unset.

src/auth.test.ts

regression-91.test.tsRegression test for resource URL construction +59/-0

Regression test for resource URL construction

• Adds tests that capture the resource handler callbacks and assert they call 'https://api.wave.online/v1/*'. Uses a fetch stub to avoid network calls while validating URL composition.

src/resources/regression-91.test.ts

regression-91.test.tsRegression test covering all 18 tools’ URL shape +115/-0

Regression test covering all 18 tools’ URL shape

• Adds an end-to-end regression test that iterates all declared tools and asserts each calls 'https://api.wave.online/v1/*' and never '/api/v1/*'. Also verifies 'WAVE_BASE_URL' override still composes correctly with '/v1/*'.

src/tools/regression-91.test.ts

Documentation (2) +14 / -1
CHANGELOG.mdDocument the #91 production 404 defect and fix +13/-0

Document the #91 production 404 defect and fix

• Adds an Unreleased changelog entry describing the incorrect default origin and internal '/api/v1/*' prefix usage. Notes the corrected gateway base URL and '/v1/*' routing shape.

CHANGELOG.md

README.mdCorrect documented default WAVE_BASE_URL +1/-1

Correct documented default WAVE_BASE_URL

• Updates the environment variable table to reflect 'https://api.wave.online' as the default base URL. Adds guidance not to point at 'wave.online' (marketing site).

README.md

Other (2) +848 / -298
package-lock.jsonAdd tsx and refresh lockfile dependencies +846/-298

Add tsx and refresh lockfile dependencies

• Introduces 'tsx' as a dev dependency (to run Node tests with TS/ESM import support). Updates various locked dependency versions consistent with a lockfile refresh.

package-lock.json

package.jsonAdd Node test script and tsx dev dependency +2/-0

Add Node test script and tsx dev dependency

• Adds a 'test' script using 'node --import tsx --test' over 'src/**/*.test.ts'. Pins 'tsx' in devDependencies to support running TypeScript tests without a separate build step.

package.json

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Risk: medium. Left a non-blocking comment — Cursor Bugbot and Cursor Security Agent both finished as skipped (Bugbot hit a usage limit), so required automated review signals are incomplete and this is not approved. Human review is needed; no eligible non-author reviewers were assignable from CODEOWNERS or recent editors.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

devin-ai-integration[bot]

This comment was marked as resolved.

…ontent policy

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…ave.online defaults in docs/SSOT

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
@qodo-code-review

qodo-code-review Bot commented Aug 7, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Node engine mismatch ✓ Resolved 🐞 Bug ☼ Reliability
Description
The package declares Node ">=18.0.0" support, but the lockfile now resolves a runtime dependency
(@hono/node-server@2.1.0, pulled via @modelcontextprotocol/sdk) that declares engines.node ">=20".
This makes the published compatibility contract inconsistent and can cause EBADENGINE warnings or
incompatibilities for Node 18 consumers/installers.
Code

package-lock.json[R778-780]

      "engines": {
-        "node": ">=18.14.1"
+        "node": ">=20"
      },
Evidence
The repo claims Node >=18 in package.json, but package-lock pins @hono/node-server@2.1.0 with an
engines.node requirement of >=20, and @modelcontextprotocol/sdk depends on @hono/node-server via a
range that permits 2.x (so the >=20 package is in the resolved runtime dependency graph).

package.json[57-59]
package-lock.json[773-783]
package-lock.json[890-897]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`package.json` advertises Node `>=18.0.0`, but the dependency resolution now includes packages that declare Node `>=20` support (notably `@hono/node-server@2.1.0`, which is a dependency of `@modelcontextprotocol/sdk`). This creates an inconsistent compatibility story for users on Node 18.

## Issue Context
- `@modelcontextprotocol/sdk` declares `node >=18`, but allows `@hono/node-server` `^1.19.9 || ^2.0.5`, and the lockfile currently selects `2.1.0` (engine `>=20`).

## Fix options
Choose one:
1) **Raise supported Node version**: Update `package.json#engines.node` (and README if needed) to `>=20` (or the exact minimum you support) to match the resolved dependency ecosystem.
2) **Preserve Node 18 support**: Ensure a Node-18-compatible `@hono/node-server` is selected by adding it as a direct dependency pinned to a `1.x` version that supports Node 18 (so npm can dedupe to it), and regenerate `package-lock.json` accordingly.

## Fix Focus Areas
- package.json[57-59]
- package-lock.json[773-783]
- package-lock.json[890-897]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context used
✅ Compliance rules (platform): 2 rules
Review mode: ⚖️ Balanced: This is a production-impacting runtime URL/contract fix across many tool and resource call sites, but the edits are largely mechanical and covered by focused regression tests rather than dense new logic warranting redundant review.

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

qodo-code-review[bot]

This comment was marked as resolved.

@qodo-code-review

Copy link
Copy Markdown

Qodo Fixer

No findings are within the configured fix scope. To change which findings are fixed, adjust the setting on your Qodo configuration page.

…ncy graph

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 new potential issues.

Open in Devin Review

Comment thread package.json Outdated
Comment thread src/auth.ts
*/

const DEFAULT_BASE_URL = "https://wave.online";
const DEFAULT_BASE_URL = "https://api.wave.online";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Behavior change for users who override WAVE_BASE_URL

Anyone who already pointed WAVE_BASE_URL at a self-hosted or staging origin that serves /api/v1/* will now get 404s, since every path lost the /api segment while the override mechanism is unchanged (src/auth.ts:23-25). MCP-DEBUGGING.md:82 still advertises https://staging.wave.online — worth confirming that origin serves the public /v1/* shape, otherwise staging users trade one 404 for another.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

All 18 tools broken against prod: /api/v1/* returns Next.js 404, not a gateway route

1 participant