Skip to content

fix(mcp): explain 404 upstream dials and bump go-sdk to v1.8.0 - #987

Open
SantiagoDePolonia wants to merge 1 commit into
mainfrom
fix/stateless-mcp-servers
Open

SantiagoDePolonia wants to merge 1 commit into
mainfrom
fix/stateless-mcp-servers

Conversation

@SantiagoDePolonia

Copy link
Copy Markdown
Contributor

Fixes #986.

Stateless MCP servers (mcp-devtools v2, Firecrawl) already connect through the gateway; verified against a go-sdk stateless server and the live Firecrawl endpoint. The reported failed to connect (session ID: ): session not found is go-sdk v1.7.0 labelling a plain HTTP 404 from the configured URL, which happens when the url lacks the server's endpoint path (/http for mcp-devtools, /v2/mcp for Firecrawl, both changed recently).

User-visible impact:

  • go-sdk v1.8.0: a 404 is only reported as a missing session when a session exists. Also tolerates 404 on subscriptions/listen for stateless servers, fixes Client.Connect leaks and a subscriptionsListen deadlock, and lets 2026-07-28 clients renegotiate against our stateful /mcp handler instead of getting a plain 400.
  • A dial that gets HTTP 404 or 405 on the handshake now reports <url> answered HTTP 404 Not Found; no MCP endpoint at that path, check the url in logs and the dashboard's last error. Userinfo and query are stripped from the URL.
  • Docs: troubleshooting entries for the new message and the endpoint-path requirement.
  • Tests: stateless upstream connect and tool call; missing-endpoint error shape and redaction.

@mintlify

mintlify Bot commented Sep 14, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
gomodel 🟢 Ready View Preview Sep 14, 2026, 5:07 PM

💡 Tip: Enable Automations to automatically generate PRs for you.

@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 34 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 94fbdb37-f209-4aab-a394-b7738e9965a9

📥 Commits

Reviewing files that changed from the base of the PR and between bada99a and 6402762.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (6)
  • docs/features/mcp-gateway.mdx
  • docs/mcp-proxy/claude-code-and-codex.mdx
  • go.mod
  • internal/mcpgateway/service_test.go
  • internal/mcpgateway/upstream.go
  • internal/mcpgateway/upstream_test.go

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@greptile-apps

greptile-apps Bot commented Sep 14, 2026

Copy link
Copy Markdown

RetriggerConfidence Score: 3/5

Not safe to merge: the path-credential disclosure must be fixed before merging. The session-loss diagnostic is non-blocking but should be corrected so valid endpoint URLs are not misreported.

Reviews (1) · Last reviewed commit: "fix(mcp): explain 404 upstream dials and..."

Comment on lines +267 to +289
if err == nil && req.Method != http.MethodGet &&
(resp.StatusCode == http.StatusNotFound || resp.StatusCode == http.StatusMethodNotAllowed) {
p.status.Store(int32(resp.StatusCode))
}
return resp, err
}

// missingEndpoint returns the recorded status, or 0 when every POST of the
// dial reached an MCP endpoint.
func (p *connectProbe) missingEndpoint() int {
if p == nil {
return 0
}
return int(p.status.Load())
}

// connectError wraps a failed dial, naming the URL path when the probe saw
// that nothing MCP is served there.
func (u *upstream) connectError(err error, probe *connectProbe) error {
if status := probe.missingEndpoint(); status != 0 {
return fmt.Errorf("connect to mcp server %q: %s answered HTTP %d %s; no MCP endpoint at that path, check the url: %w",
u.spec.Name, endpointForLog(u.spec.URL), status, http.StatusText(status), err)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Avoid session-loss misdiagnosis

If a stateful MCP server loses its session after initialize succeeds, the later notifications/initialized POST can return 404. This probe records that later response and replaces the session-specific failure with “no MCP endpoint at that path,” even though the configured endpoint already returned 200 during initialization. Operators may change a correct URL instead of addressing the expired session. This is a non-blocking diagnostic accuracy concern.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Artifacts

Evidence from the check

  • Focused in-process Go test that accepts initialization and returns 404 after the stateful session disappears, demonstrating the incorrect diagnostic.

Command output from the check

  • Output from the prior revision showing the session-specific error without the endpoint-path diagnostic.

Command output from the check

  • Output from the changed revision showing successful initialization followed by the incorrect missing-endpoint diagnostic.

View artifacts

T-Rex Ran code and verified through T-Rex

Comment on lines +300 to +303
parsed.User = nil
parsed.RawQuery = ""
parsed.Fragment = ""
return parsed.String()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 security Redact path credentials

endpointForLog removes userinfo, query, and fragment values but preserves the complete URL path. If an upstream URL contains a credential in its path, a 404 or 405 connection failure includes that credential in the connection error and dashboard-facing LastError. This violates the repository directive never to expose secrets in errors or logs and can disclose an endpoint token to people who can view diagnostics.

How this was verified: A 404 and a 405 response each produced an error and dashboard value containing the configured path credential.

Context Used: AGENTS.md (source)

Artifacts

Evidence from the check

  • The authored in-process Go test configures a path credential and exercises 404 and 405 upstream failures, with assertions for error and dashboard propagation; it defines the exact reproduction.

Command output from the check

  • The executed Go test output records exit code 0 and shows the path credential in each 404/405 connect error and dashboard LastError; the finding is confirmed.

View artifacts

T-Rex Ran code and verified through T-Rex

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.

Issue: "failed to connect (session ID: ): session not found" error when connecting to stateless MCP servers

1 participant