vMCP: extend backend-init list-method tolerance to HTTP-level method-missing signals
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 2.2k
- Forks
- 300
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 184
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: https://github.com/stacklok/toolhive/pull/5232#discussion_r3211850406.
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 #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 #5232 — original
-32601fix. - Issue #5231 — Atlassian Rovo-style spec violation.
- Review comment that flagged this gap: https://github.com/stacklok/toolhive/pull/5232#discussion_r3211850406
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with pkg/vmcp/session/internal/backend/mcp_session.go, especially initAndQueryCapabilities and its existing errors.Is handling, then read mcp_session_capabilities_test.go and the fakeBackend harness. Trace how streamable-HTTP and SSE transport errors expose HTTP 404, 405, and 501, and run the capability tests. Done means the chosen statuses recover only for resources/list and prompts/list, preserve the warning fields, and tools/list remains fatal.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- backend, networking, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100