fastmcp/tests/deprecated/test_elicitation.py
Jeremiah Lowin de14ed1b7c
Audit mode="legacy" pins in server tests and top-level stragglers
Removes pins added while making the auto-default suite pass that weren't
actually testing older-protocol-only behavior, and keeps (with a stated
reason) the ones that are. Along the way, fixes two real defects the audit
surfaced in the modern protocol path: PingMiddleware could leak a
_active_sessions entry when a connection's exit_stack closed before its
keepalive task got its first scheduler turn, and FastMCP(experimental_
capabilities=...) was silently dropped from server/discover responses
(it only ever reached the legacy initialize handshake).
2026-07-20 16:00:27 -04:00

33 lines
1.2 KiB
Python

"""Tests for deprecated elicitation behavior."""
from typing import Any, cast
import pytest
from fastmcp import Context, FastMCP
from fastmcp.client.client import Client
from fastmcp.client.elicitation import ElicitResult
from fastmcp.exceptions import FastMCPDeprecationWarning
from fastmcp.server.elicitation import AcceptedElicitation
async def test_elicitation_none_response_type_warns_deprecation():
"""Passing response_type=None is deprecated — warn at call time."""
mcp = FastMCP("TestServer")
@mcp.tool
async def my_tool(context: Context) -> dict[str, Any]:
with pytest.warns(FastMCPDeprecationWarning, match="response_type"):
result = await context.elicit(message="", response_type=None)
assert isinstance(result, AcceptedElicitation)
return cast(dict[str, Any], result.data)
async def elicitation_handler(message, response_type, params, ctx):
return ElicitResult(action="accept", content={})
# `ctx.elicit` sends a server-initiated request down the client's
# back-channel, which only the older protocol has, so this pins that era.
async with Client(
mcp, mode="legacy", elicitation_handler=elicitation_handler
) as client:
await client.call_tool("my_tool", {})