Skip to content

Commit f5f9313

Browse files
committed
fix(adapter,gateway): harden token TTL, stdio safety, formatting, error handling
1. nexus-mcp-adapter: Replace dangerous 1-hour token TTL fallback with conservative 5-minute default + warning log when expires_at is missing 2. nexus-mcp-adapter: Change all console.log to console.error to prevent corrupting MCP StdioServerTransport JSON-RPC channel 3. nexus-gateway: Fix spaces-to-tabs indentation in server.go (gofmt) 4. nexus-gateway: Replace opaque status code forwarding on unexpected broker responses with structured 502 broker_unexpected_status error All tests pass. go vet and go build clean.
1 parent 1281929 commit f5f9313

3 files changed

Lines changed: 15 additions & 10 deletions

File tree

nexus-gateway/pkg/server/server.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ func (s *Server) routes() {
5757
s.mux.Handle("/metrics", promhttp.Handler())
5858

5959
s.mux.Post("/v1/request-connection", s.handler.RequestConnection)
60-
s.mux.Get("/v1/check-connection/{connectionID}", s.handler.CheckConnection)
61-
s.mux.Get("/v1/resolve", s.handler.ResolveToken)
62-
s.mux.Get("/v1/token/{connectionID}", s.handler.GetToken)
63-
s.mux.Post("/v1/refresh/{connectionID}", s.handler.RefreshConnection)
60+
s.mux.Get("/v1/check-connection/{connectionID}", s.handler.CheckConnection)
61+
s.mux.Get("/v1/resolve", s.handler.ResolveToken)
62+
s.mux.Get("/v1/token/{connectionID}", s.handler.GetToken)
63+
s.mux.Post("/v1/refresh/{connectionID}", s.handler.RefreshConnection)
6464
s.mux.Get("/v1/providers", s.handler.GetProviders)
6565
s.mux.Get("/v1/providers/metadata", s.handler.GetProviders)
6666
s.mux.Post("/v1/providers", s.handler.CreateProvider)

nexus-gateway/pkg/usecase/handler.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,8 @@ func (h *Handler) ResolveToken(w http.ResponseWriter, r *http.Request) {
447447
return
448448
}
449449

450-
w.WriteHeader(resp.StatusCode())
450+
writeError(w, http.StatusBadGateway, "broker_unexpected_status",
451+
fmt.Sprintf("broker returned unexpected status %d", resp.StatusCode()), nil)
451452
}
452453

453454
func (h *Handler) GetToken(w http.ResponseWriter, r *http.Request) {

nexus-mcp-adapter/src/NexusClient.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export class NexusClient {
1717
* Currently mocks the response.
1818
*/
1919
private async fetchTokenFromGateway(workspaceId: string, provider: string): Promise<NexusTokenInfo> {
20-
console.log(`[NexusClient] Fetching fresh token from Gateway for workspace: ${workspaceId}, provider: ${provider}`);
20+
console.error(`[NexusClient] Fetching fresh token from Gateway for workspace: ${workspaceId}, provider: ${provider}`);
2121

2222
const url = new URL(`${this.gatewayUrl}/v1/resolve`);
2323
url.searchParams.append('workspace_id', workspaceId);
@@ -63,11 +63,15 @@ export class NexusClient {
6363
}
6464

6565
// Handle expiration parsing
66-
let expiresAt = Date.now() + (1000 * 60 * 60); // Default 1 hour fallback
66+
// Conservative 5-minute default — avoids serving stale tokens if the
67+
// upstream provider issued a short-lived token (some are 5–15 min).
68+
let expiresAt = Date.now() + (1000 * 60 * 5);
6769
if (data.credentials.expires_at) {
6870
expiresAt = new Date(data.credentials.expires_at).getTime();
6971
} else if (data.expires_at) {
70-
expiresAt = new Date(data.expires_at).getTime();
72+
expiresAt = new Date(data.expires_at).getTime();
73+
} else {
74+
console.warn(`[NexusClient] No expires_at in token response for workspace: ${workspaceId}, provider: ${provider}. Using conservative 5-minute TTL.`);
7175
}
7276

7377
return {
@@ -87,7 +91,7 @@ export class NexusClient {
8791
tokenInfo = await this.fetchTokenFromGateway(workspaceId, provider);
8892
this.tokenManager.setToken(workspaceId, provider, tokenInfo);
8993
} else {
90-
console.log(`[NexusClient] Using cached token for workspace: ${workspaceId}, provider: ${provider}`);
94+
console.error(`[NexusClient] Using cached token for workspace: ${workspaceId}, provider: ${provider}`);
9195
}
9296

9397
return tokenInfo;
@@ -120,7 +124,7 @@ export class NexusClient {
120124
};
121125

122126
// 4. Execute the actual fetch request
123-
console.log(`[NexusClient Fetcher] Executing proxy fetch to ${input.toString()}`);
127+
console.error(`[NexusClient Fetcher] Executing proxy fetch to ${input.toString()}`);
124128
return globalThis.fetch(input, updatedInit);
125129
};
126130
}

0 commit comments

Comments
 (0)