From 8b88d68f4aaae8fac60b68e2b51eddb6285f2918 Mon Sep 17 00:00:00 2001 From: Jake Kaplan Date: Thu, 6 Aug 2026 09:58:10 -0400 Subject: [PATCH] Clarify proxy metadata lifecycle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with OpenAI Codex --- docs/servers/providers/proxy.mdx | 2 +- fastmcp_slim/fastmcp/server/providers/proxy.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/servers/providers/proxy.mdx b/docs/servers/providers/proxy.mdx index 0223c2250..1ff116bbd 100644 --- a/docs/servers/providers/proxy.mdx +++ b/docs/servers/providers/proxy.mdx @@ -60,7 +60,7 @@ To mount a proxy inside another FastMCP server, see [Mounting External Servers]( ## Connection Semantics -FastMCP proxies are lazy bridges. Creating the proxy object and starting the local server do not contact the upstream server. During client negotiation, the proxy makes a best-effort connection to read optional server metadata; an unavailable backend does not prevent the client from connecting to the proxy. +FastMCP proxies are lazy bridges. Creating the proxy object and starting the local server do not contact the upstream server. During client negotiation, the proxy makes a best-effort request for optional server metadata using the backend client's existing lifecycle and negotiation mode; an unavailable backend does not prevent the client from connecting to the proxy. Subsequent MCP requests such as `ping`, `tools/list`, `resources/list`, `prompts/list`, tool calls, resource reads, sampling, elicitation, logging, and progress connect to the backend as needed. Component provider failures follow `provider_error_strategy`: the default `"warn"` logs and skips a failed provider, while `"raise"` reports the failure to the client. diff --git a/fastmcp_slim/fastmcp/server/providers/proxy.py b/fastmcp_slim/fastmcp/server/providers/proxy.py index 180dbc371..718516867 100644 --- a/fastmcp_slim/fastmcp/server/providers/proxy.py +++ b/fastmcp_slim/fastmcp/server/providers/proxy.py @@ -1167,7 +1167,10 @@ class ProxyMetadataMiddleware(Middleware): self.identity = identity async def _read_connected(self, client: Client) -> _UpstreamServerMetadata | None: + """Read metadata without changing the client's adopted negotiation state.""" if client.mode in MODERN_PROTOCOL_VERSIONS and client.prior_discover is None: + # An exact pin adopts a synthetic result without probing. Read the + # real result directly, but do not adopt it into this borrowed session. raw = await client.session.send_discover(client.mode) result_type = raw.get("resultType") if (