Skip to content

test(mcp): add regression test for nil ClientInfo panic#848

Open
manusa wants to merge 1 commit intocontainers:mainfrom
marcnuri-forks:test/nil-client-info-regression
Open

test(mcp): add regression test for nil ClientInfo panic#848
manusa wants to merge 1 commit intocontainers:mainfrom
marcnuri-forks:test/nil-client-info-regression

Conversation

@manusa
Copy link
Member

@manusa manusa commented Feb 28, 2026

Adds a regression test for the nil ClientInfo panic fixed in #844 (originally reported in #842).

The existing TestFallsBackToServerPrefixWhenNoClientInfo test uses WithEmptyClientInfo() which sets ClientInfo to an empty (but non-nil) *Implementation{}. This doesn't cover the actual panic scenario where ClientInfo is nil — which happens when a client omits clientInfo from the initialize request entirely.

Since the go-sdk client always sets clientInfo and panics if the implementation is nil, we can't reproduce this through the standard test client. Instead, the new test sends raw HTTP JSON-RPC requests with an initialize payload that omits clientInfo, simulating a non-compliant client. This approach is inspired by the CallToolRaw pattern used in podman-mcp-server for testing raw JSON-RPC interactions.

The MCP spec mandates that clientInfo is sent during initialization, but some clients don't follow this, so we should handle it gracefully.

Add a test that sends a raw initialize request without clientInfo
to verify the server doesn't panic. The go-sdk client always sets
clientInfo, so we bypass it with raw HTTP to reproduce the scenario
from non-compliant clients.

Ref: containers#842, containers#844
Signed-off-by: Marc Nuri <marc@marcnuri.com>
@manusa manusa added this to the 0.1.0 milestone Feb 28, 2026
@manusa
Copy link
Member Author

manusa commented Mar 2, 2026

Note: overlap with #859

PR #859 introduces test.McpRawPost — a reusable helper for sending raw JSON-RPC requests to MCP HTTP endpoints, bypassing the go-sdk client's automatic normalization. This is the same pattern used inline in this PR.

If #859 merges first, this PR can be rebased and simplified by replacing the inline HTTP request construction with test.McpRawPost calls:

// Raw initialize (no clientInfo)
initResp := test.McpRawPost(s.T(), httpServer.URL+"/mcp", "",
    `{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-03-26"}}`)
defer initResp.Body.Close()
_, _ = io.ReadAll(initResp.Body)
sessionID := initResp.Header.Get("Mcp-Session-Id")

// Raw tool call
toolResp := test.McpRawPost(s.T(), httpServer.URL+"/mcp", sessionID,
    `{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"pods_list","arguments":{}}}`)
defer toolResp.Body.Close()

This eliminates the duplicated HTTP boilerplate (Content-Type, Accept headers, error handling) while keeping the custom httptest.Server setup this test needs for User-Agent stripping.

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.

1 participant