stacklok / stacklok/toolhive

Add SSE backend test fake and table-drive HeaderForward regression test

Open
#5,303 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement vmcp
Dominant language
Go
Stars
2.2k
Forks
300
Avg merge
1d 15h
Merged PRs (30d)
184

Description

Motivation

PR #5301 fixed the per-session HTTP HeaderForward gap reported in #5289. The regression test TestHTTPSession_AppliesHeaderForwardToPostInitializeRequests (in pkg/vmcp/session/internal/backend/) drives a real MCP client through the production transport chain, but exercises only the streamable-http transport because that is the only transport our test fakes can speak.

createMCPClient (pkg/vmcp/session/internal/backend/mcp_session.go) supports both streamable-http and sse. The BuildHeaderForwardTripper wrap is applied to the shared base before the per-transport switch, so SSE is wired correctly today — but a future refactor that moves the wrap into the streamable-http arm only would silently re-break SSE (the exact failure mode of the original #5289 bug, just on a different branch).

What is needed

  1. Extend the canonical fakeBackend test helper (in pkg/vmcp/session/internal/backend/mcp_session_capabilities_test.go) to support the SSE transport, OR add a sibling SSE fake in the same file. The fake must:

    • Serve GET /sse with Content-Type: text/event-stream.
    • Push the initial endpoint event so the mark3labs mcp-go SSE client knows where to POST commands.
    • Accept POST /messages (or whatever endpoint the client requests) for outbound JSON-RPC requests, recording inbound headers per method (same recording shape fakeBackend already has for streamable-http after PR #5301's second commit).
    • Push responses back over the SSE stream in event: message, data: {...}\n\n format.
    • Close cleanly when the test ends.
  2. Table-drive TestHTTPSession_AppliesHeaderForwardToPostInitializeRequests over both transport types so the regression is enforced for SSE as well as streamable-http. Each table row asserts the post-initialize request carries the configured X-MCP-Toolsets header.

  3. Apply the same table-drive to the overlap-precedence and AddHeadersFromSecret subtests that PR #5301 added, so both subbranches get equivalent coverage.

Out of scope

  • This is a test-only enhancement; no production behavior change.
  • Not blocked by and does not block #4929 (pluggable backendConnector) or #4974 (vmcp-as-server SSE scaling).

Acceptance criteria

  • A test SSE fake exists in pkg/vmcp/session/internal/backend/ that can serve a full initializetools/listtools/call handshake to an mcp-go SSE client.
  • Header recording works identically for both transports (same headersFor(method) accessor).
  • TestHTTPSession_AppliesHeaderForwardToPostInitializeRequests runs as a table over both transports and passes for each.
  • No flakes under -race.

Related: #5289, #5301, #5302.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with fakeBackend in pkg/vmcp/session/internal/backend/mcp_session_capabilities_test.go and createMCPClient in mcp_session.go, then read TestHTTPSession_AppliesHeaderForwardToPostInitializeRequests and its overlap-precedence and AddHeadersFromSecret subtests. Add an SSE fake that supports the initialize, tools/list, and tools/call flow, records headers through headersFor(method), and table-drive the tests over both transports. Done means the tests pass for streamable-http and SSE, including under -race.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
backend, testing
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.