langgenius / langgenius/mosoo

fix(runtime): MCP proxy router drops downstream subpaths and returns 404

Open
#626 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
147
Forks
26
Avg merge
5h 6m
Merged PRs (30d)
40

Description

### Area
Runtime

### Summary
`driver.all("/mcp/proxy/:serverId", ...)` in `apps/api/src/adapters/http/routes/driver-route.ts` only matches the single exact path segment without wildcard subpath matching (`/*`). When a client or driver sends requests with downstream subpaths (e.g. `/mcp/proxy/:serverId/messages` or `/mcp/proxy/:serverId/sse`), Hono returns 404 Route Not Found. Additionally, `toUpstreamProxyUrl` only copies search parameters and completely ignores incoming request pathnames, dropping any subpaths even if received.

### Steps to reproduce
1. Configure an MCP server with target URL (e.g. `https://mcp.example.com/base`).
2. Mint a runtime action grant for `mcp_proxy`.
3. Send an HTTP request to `/api/driver/mcp/proxy//messages` with the authorization grant.
4. Inspect the HTTP response status.

### Expected behavior
Requests with subpaths should match the proxy route, validate paths against directory traversal, and forward the request to `https://mcp.example.com/base/messages` with original query parameters (excluding the internal `grant` token).

### Actual behavior
1. Hono returns 404 Route Not Found because the router is defined as `driver.all("/mcp/proxy/:serverId", ...)` without wildcard support.
2. `toUpstreamProxyUrl` unconditionally discards incoming subpaths, resolving only `new URL(upstreamUrl)` with search parameters.

### Evidence
- In `apps/api/src/adapters/http/routes/driver-route.ts`, line 783 registers only the single-segment route:
```ts
driver.all("/mcp/proxy/:serverId", async (c) => { ... });
```
In contrast, LLM proxy (line 652) registers `/llm/proxy/:credentialId/*` and extracts subpaths via `extractLlmProxySubPath`.
- `toUpstreamProxyUrl` ignores `request.url` pathname completely:
```ts
function toUpstreamProxyUrl(request: Request, upstreamUrl: string): string {
const target = new URL(upstreamUrl);
const incoming = new URL(request.url);
for (const [key, value] of incoming.searchParams) {
if (key !== "grant") {
target.searchParams.append(key, value);
}
}
return target.toString();
}
```

### Environment
- Repository: `langgenius/mosoo`
- Revision: HEAD (`main`)
- Component: `apps/api` (Driver HTTP routes)

### Contribution
I can submit a PR

Contributor guide

Open the contributing guide

Research direction

Start in apps/api/src/adapters/http/routes/driver-route.ts, comparing the MCP proxy route around line 783 with the wildcard LLM proxy route around line 652 and tracing toUpstreamProxyUrl. Reproduce the /api/driver/mcp/proxy//messages request, then verify subpaths are validated and forwarded to the configured upstream with query parameters preserved except grant.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.