Repository navigation
vMCP: extend backend-init list-method tolerance to HTTP-level method-missing signals #5242
Description
Background
PR #5232 (issue #5231) added narrow tolerance in pkg/vmcp/session/internal/backend/mcp_session.go::initAndQueryCapabilities so that a backend advertising the resources or prompts capability but returning JSON-RPC -32601 (method not found) for resources/list / prompts/list no longer aborts backend init and silently drops every tool from that backend.
That fix is intentionally scoped to JSON-RPC -32601 envelopes only. The recovery comment now explicitly states "HTTP-level method absence is intentionally fatal" — review thread: #5232 (comment).
Problem
Some real-world backends sit behind reverse proxies, API gateways, or non-MCP front doors that surface "this method isn't implemented" as an HTTP-level response (404 / 405 / 501) rather than as a JSON-RPC -32601 envelope. Under those conditions:
mcp-go's streamable-HTTP / SSE transport layers return a non-sentinel transport error (not wrappingmcp.ErrMethodNotFound).errors.Is(listErr, mcp.ErrMethodNotFound)therefore evaluates false.- The fatal
case listErr != nilarm fires → init aborts → every tool from that backend is silently dropped.
This reproduces the original #5231 symptom for a slightly different class of misbehaving backends.
Proposed work
- Enumerate the transport-level signals to be treated as method-missing. Candidates: HTTP
404 Not Found,405 Method Not Allowed,501 Not Implemented. - Decide where the discrimination happens — at the adapter / transport boundary (preferred, keeps
pkg/vmcp/session/internal/backendclean) versus insideinitAndQueryCapabilities. - Extend the existing
errors.Is(listErr, mcp.ErrMethodNotFound)case inmcp_session.go(or replace it with a richer predicate) so the chosen transport-level errors recover with the same WARN-and-continue behavior as-32601. - Add tests that exercise each chosen HTTP status against the existing
fakeBackendharness inmcp_session_capabilities_test.go. - Keep
tools/liststrict — recovery should remain limited toresources/listandprompts/list, matching the scope of vMCP backend init fails fatally when server advertises resources capability without resources/list #5231.
Acceptance criteria
- Concrete list of HTTP statuses recovered, documented in the recovery comment alongside the existing
-32601note. - Recovery path emits the same
slog.Warnbreadcrumb (backendID/name/baseURL/method) as the JSON-RPC -32601 path. - Backend with
tools+resourcescapabilities andresources/listreturning HTTP 404/405/501 still initializes successfully and exposes its tools. - Backend with
tools/listreturning HTTP 404/405/501 still aborts init (regression guard). - Unit tests added for each recovered status.
References
- PR Tolerate spec-violating list methods on backend init #5232 — original
-32601fix. - Issue vMCP backend init fails fatally when server advertises resources capability without resources/list #5231 — Atlassian Rovo-style spec violation.
- Review comment that flagged this gap: Tolerate spec-violating list methods on backend init #5232 (comment)
Activity
hellouz818 commentedon Sep 14, 2026
Hi, I'd like to work on this.
I'm also looking at #6339, which is related but separate. I'll address the two issues in separate PRs to keep the fixes and reviews focused.
For this issue, I plan to extend the existing
-32601recovery forresources/listandprompts/listto also tolerate HTTP 404/405/501 responses, with matching unit tests.tools/listwill remain strict, as specified in the acceptance criteria.I have a production vMCP deployment running ToolHive v0.46.0 with Atlassian and Tableau backends, so I can also validate the behavior against real-world scenarios.
hellouz818 commentedon Sep 15, 2026
Hi, #6660 has been merged, which covers JSON-RPC -32601 tolerance for resources/list and prompts/list in the ListCapabilities path.
This issue extends that handling to HTTP-level method-missing signals (404 / 405 / 501) in the same area. I'd be happy to pick this up and open a PR if no one else is working on it. Please assign this to me if the scope looks right. :)
Extend session-init method-missing tolerance to HTTP-level signals