Skip to content

Commit 8a672ca

Browse files
committed
Enhance resolveTargetUrl function to support absolute URL construction
- Updated the resolveTargetUrl function to accept an optional absoluteUrl parameter, allowing for more flexible URL resolution. - Improved error handling for URL construction, ensuring robustness when dealing with relative URLs. - Adjusted the MCP route handlers to utilize the new absoluteUrl parameter for better context handling.
1 parent fafbdb2 commit 8a672ca

File tree

2 files changed

+62
-7
lines changed

2 files changed

+62
-7
lines changed

apps/mcp/src/index.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -433,10 +433,37 @@ app.get("/", async (c) => {
433433
);
434434
});
435435

436-
async function resolveTargetUrl(req: Request): Promise<string | null> {
436+
async function resolveTargetUrl(req: Request, absoluteUrl?: string): Promise<string | null> {
437437
// First, try to get target URL from header or query param (base64-encoded)
438+
// Use absoluteUrl if provided (from Hono context), otherwise try to construct from req.url
439+
let url: URL;
440+
try {
441+
if (absoluteUrl) {
442+
url = new URL(absoluteUrl);
443+
} else {
444+
// If req.url is relative, we need to construct an absolute URL
445+
// Try to use req.url directly first
446+
try {
447+
url = new URL(req.url);
448+
} catch {
449+
// If that fails, try constructing from headers
450+
const host = req.headers.get("host") || req.headers.get("x-forwarded-host");
451+
const protocol = req.headers.get("x-forwarded-proto") || "https";
452+
if (host) {
453+
url = new URL(req.url, `${protocol}://${host}`);
454+
} else {
455+
// Fallback: try req.url as-is (might work in some contexts)
456+
url = new URL(req.url, "http://localhost");
457+
}
458+
}
459+
}
460+
} catch (e) {
461+
// If URL construction fails, return null
462+
return null;
463+
}
464+
438465
const directUrlEncoded = req.headers.get("x-mcpay-target-url")
439-
?? new URL(req.url).searchParams.get("target-url");
466+
?? url.searchParams.get("target-url");
440467

441468
if (directUrlEncoded) {
442469
try {
@@ -479,7 +506,7 @@ app.all("/mcp", async (c) => {
479506
method: original.method,
480507
});
481508

482-
const targetUrl = await resolveTargetUrl(original);
509+
const targetUrl = await resolveTargetUrl(original, c.req.url);
483510
if (!targetUrl) {
484511
return new Response("target-url missing", { status: 400 });
485512
}

apps/mcp2/src/index.ts

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,35 @@ async function initializeStore(): Promise<void> {
2525
}
2626

2727
// Resolve upstream target MCP origin from header/query (base64) or store by server id
28-
async function resolveTargetUrl(req: Request): Promise<string | null> {
28+
async function resolveTargetUrl(req: Request, absoluteUrl?: string): Promise<string | null> {
2929
// No console logging
30-
const url = new URL(req.url);
30+
// Use absoluteUrl if provided (from Hono context), otherwise try to construct from req.url
31+
let url: URL;
32+
try {
33+
if (absoluteUrl) {
34+
url = new URL(absoluteUrl);
35+
} else {
36+
// If req.url is relative, we need to construct an absolute URL
37+
// Try to use req.url directly first
38+
try {
39+
url = new URL(req.url);
40+
} catch {
41+
// If that fails, try constructing from headers
42+
const host = req.headers.get("host") || req.headers.get("x-forwarded-host");
43+
const protocol = req.headers.get("x-forwarded-proto") || "https";
44+
if (host) {
45+
url = new URL(req.url, `${protocol}://${host}`);
46+
} else {
47+
// Fallback: try req.url as-is (might work in some contexts)
48+
url = new URL(req.url, "http://localhost");
49+
}
50+
}
51+
}
52+
} catch (e) {
53+
// If URL construction fails, return null
54+
return null;
55+
}
56+
3157
const id = url.searchParams.get("id");
3258
// No console logging
3359
if (id) {
@@ -229,7 +255,7 @@ app.get("/servers", async (c) => {
229255
app.all("/mcp", async (c) => {
230256
// No console logging
231257
const original = c.req.raw;
232-
const targetUrl = await resolveTargetUrl(original);
258+
const targetUrl = await resolveTargetUrl(original, c.req.url);
233259
// No console logging
234260

235261
let prices: Record<string, Price> = {};
@@ -245,7 +271,9 @@ app.all("/mcp", async (c) => {
245271
}
246272
}
247273

248-
const serverId = new URL(original.url).searchParams.get("id");
274+
// Use Hono's absolute URL instead of original.url which might be relative
275+
const currentUrl = new URL(c.req.url);
276+
const serverId = currentUrl.searchParams.get("id");
249277
if (!serverId) {
250278
return new Response("server-id missing", { status: 400 });
251279
}

0 commit comments

Comments
 (0)