Commit graph

112 commits

Author SHA1 Message Date
Jake Kaplan
b2025212d8
Fix proxy forwarding of MCP transport headers (#4853) 2026-08-18 12:36:24 -04:00
Jeremiah Lowin
3dd0886156
Fix StatefulProxyClient reconnection after session failure (#4829) 2026-08-13 16:01:19 -04:00
Jake Kaplan
9feb1f378b
Forward proxy server metadata across protocol eras (#4776)
* Forward proxy negotiation metadata

🤖 Generated with OpenAI Codex

* Limit forwarded proxy metadata

🤖 Generated with OpenAI Codex

* Tighten negotiation metadata forwarding

🤖 Generated with OpenAI Codex

* Tighten proxy metadata docs

🤖 Generated with OpenAI Codex

* Keep proxy metadata middleware with provider

🤖 Generated with OpenAI Codex

* Simplify proxy negotiation middleware API

🤖 Generated with OpenAI Codex

* Name proxy metadata middleware directly

🤖 Generated with OpenAI Codex

* Preserve discovery middleware contracts

🤖 Generated with OpenAI Codex

* Clarify proxy metadata ownership

🤖 Generated with OpenAI Codex

* Align proxy metadata wording

🤖 Generated with OpenAI Codex

* Call forwarded values server metadata

🤖 Generated with OpenAI Codex

* Harden proxy metadata reads

🤖 Generated with OpenAI Codex

* Expose configured discovery result

🤖 Generated with OpenAI Codex

* Preserve proxy discovery compatibility

🤖 Generated with OpenAI Codex

* Preserve deprecated initialization middleware

🤖 Generated with OpenAI Codex

* Harden proxy metadata boundaries

🤖 Generated with OpenAI Codex

* Restore deprecated middleware location

🤖 Generated with OpenAI Codex

* Simplify proxy metadata client lifecycle

🤖 Generated with OpenAI Codex

* Clarify proxy metadata lifecycle

🤖 Generated with OpenAI Codex

* Preserve proxy factory errors

🤖 Generated with OpenAI Codex

* Detach forwarded proxy metadata

🤖 Generated with OpenAI Codex

* Simplify proxy metadata implementation

🤖 Generated with OpenAI Codex

* Distinguish proxy metadata failures

🤖 Generated with OpenAI Codex

* Narrow proxy metadata validation fallback

🤖 Generated with OpenAI Codex

* Retrigger CI

🤖 Generated with OpenAI Codex
2026-08-06 19:09:05 -04:00
Jeremiah Lowin
875e8e18bd
Preserve legacy httpx compatibility without importing it (#4766) 2026-08-05 18:09:16 -04:00
Jake Kaplan
959daf2321
Sanitize forwarded request metadata where the proxy copies it (#4770)
* Separate proxy protocol policy from client construction

🤖 Generated with OpenAI Codex

* Strip connection-owned request metadata at the proxy backend boundary

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Sanitize forwarded request metadata where the proxy copies it

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Forward hop-safe request metadata for proxied resources, templates, and prompts

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-05 15:46:10 -04:00
Jeremiah Lowin
8b76710e66
Move to the stable MCP Python SDK 2.0.0 (#4655) 2026-07-28 16:31:49 -04:00
Jeremiah Lowin
a8b5da9770
Late-bind app tool names so UIs survive composition (#4682) 2026-07-28 10:54:19 -04:00
Jeremiah Lowin
7674645761
Flatten OpenAPI discriminator subtypes into request bodies (#4677)
* Flatten OpenAPI discriminator subtypes into request bodies

* Resolve schema-name discriminator mappings and union conflicting variant fields

* Advertise discriminator values for propertyless variants and document the behavior
2026-07-27 16:06:54 -04:00
苏紫辰
c3cbe8b9a3
Fix OpenAPI allOf reference fields (#4653)
* Fix OpenAPI allOf reference fields

🤖 Generated with Codex

* Add allOf reference crash regression

🤖 Generated with Codex

* Handle OpenAPI component refs in allOf

🤖 Generated with Codex

---------

Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
2026-07-27 15:25:22 -04:00
Jeremiah Lowin
ea7fb8cb2e
Remove 3.x-era compatibility shims (#4661)
* Remove 3.x-era compatibility shims

* Require response_type in ctx.elicit()

* Name the utilities path for the two non-re-exported auth helpers

* Point sampling handler migration at its submodule
2026-07-27 14:59:43 -04:00
Jeremiah Lowin
90f2e190d0
Silence ty deprecation diagnostics and drop stale sampling doc mentions 2026-07-26 14:45:55 -04:00
Jeremiah Lowin
704b74b3ab
Update tests for the removed sampling and roots server API 2026-07-26 14:38:26 -04:00
Jeremiah Lowin
2f992f71ea
Support routable transport headers for gateways (SEP-2243) (#4622) 2026-07-26 13:40:09 -04:00
Jeremiah Lowin
1c7ade215b
Merge remote-tracking branch 'origin/main' into claude/mcp-background-tasks-v2-0f883f 2026-07-23 08:00:29 -04:00
Jeremiah Lowin
6fce4e538f
Move task subsystem to fastmcp-tasks package, disconnect SEP-1686 wire from core
Engine modules (keys, context snapshot, docket lifespan, worker CLI,
client handles) move intact; SEP-1686 wire modules park in _legacy_wire
for adaptation to SEP-2663. Core keeps task=True declaration on tools
only and raises at serve time until the tasks extension is registered.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-21 21:51:45 -04:00
Jeremiah Lowin
30044c7864
Fix percent-encoded skill file names unreadable in resources mode (#4590)
* Fix percent-encoded skill file names unreadable in resources mode

Encode supporting-file paths explicitly (quote/unquote) when building
and resolving skill:// resource URIs, instead of relying on AnyUrl's
implicit encoding. This also closes the ambiguity where a file literally
named "setup%20guide.md" would collide with "setup guide.md" once both
were percent-encoded.

Fixes #4545

* Quote main_file_name when building its resource URI

Keeps the main-file URI on the same explicit quote/unquote round-trip
as supporting files, so a custom main_file_name containing a literal
'%' still resolves after the shared unquote() in _get_resource().
2026-07-21 15:34:09 -04:00
苏紫辰
16a09f0151
Fix skill frontmatter with UTF-8 BOM (#4533)
🤖 Generated with Codex
2026-07-21 12:48:40 -05:00
Jeremiah Lowin
e01c5932bf
Unpin tests whose defects #4579 fixed
Resource/prompt error detail and proxy instructions/connection-error
surfacing now work on the modern protocol era, so the tests pinned to
mode="legacy" with a TODO(defect)/TODO(mode="legacy" pin) marker run
on the default auto mode again.
2026-07-20 18:02:21 -04:00
Jeremiah Lowin
5f428aaced
Merge remote-tracking branch 'origin/main' into feature/client-auto-default 2026-07-20 17:53:27 -04:00
Jeremiah Lowin
57bbc9859e
Surface resource, prompt, and proxy errors on the modern protocol era (#4579)
Three defects hidden by tests pinned to the handshake era, where a raw
exception reaches the wire as str(exc). At 2026-07-28 the runner masks
anything that is not an MCPError/ValidationError as "Internal server error".

- _on_read_resource / _on_get_prompt now translate FastMCPError through
  to_mcp_error, mirroring _on_call_tool. Masking is unchanged.
- FastMCPProxy registers a server/discover handler so upstream instructions
  reach modern clients; on_initialize only fires for the handshake.
- ProxyProvider's list methods normalize transport failures into MCPError.
2026-07-20 17:52:12 -04:00
Jeremiah Lowin
bcf90d5ae7
Remove unnecessary mode="legacy" pins from proxy tests
Most pins in tests/server/providers/proxy/ were added only to keep tests
green while unpinning changed which protocol era the proxy's backend
connection used, not because the test's subject cared about the era. With
proxy era-mirroring (#4573) landed, a front client on auto correctly moves
the whole chain to the modern protocol, so plain tool/resource/prompt calls
through a proxy no longer need a pin.

Kept pins fall into three buckets, each commented at the call site: tests
whose subject is genuinely handshake-only (sampling, roots, elicitation
push-forwarding, ping, initialize handshake mechanics); tests whose backend
is a directly-constructed ProxyClient/StatefulProxyClient, which always
defaults to legacy independent of the front era; and two tests left pinned
with a TODO documenting a real defect this audit surfaced (upstream
instructions not forwarded to a modern-era client through a proxy, and
ProxyProvider.list_tools leaking an unwrapped connection error instead of
an MCPError).
2026-07-20 15:50:35 -04:00
Jeremiah Lowin
d2ac7ed3d2
Default fastmcp.Client to mode="auto"; surface extensions=/result_claims=
Client negotiates the newest mutual protocol era by default (probe
server/discover, fall back to the initialize handshake). ProxyClient and the
inspect utility explicitly pin the handshake era so proxy forwarding and
server_info reads are unchanged. SSE and multi-server config transports are
legacy-only. extensions= and result_claims= (SEP-2133) are thin passthroughs
to the SDK session.
2026-07-19 21:22:49 -04:00
Jeremiah Lowin
1e529ee27d
Stop proxies from validating backend results or mutating shared transports (#4552) 2026-07-19 19:24:11 -04:00
Jeremiah Lowin
18b5ab5852
Migrate to MCP SDK v2.0.0b2 (httpx2) (#4503) 2026-07-18 15:12:47 -04:00
Jeremiah Lowin
d779414f8a
Screen templated resource parameters for path traversal by default (#4482)
* Add ResourceSecurity screening for templated resources (defaults on)

* Add tests for resource path-security screening

* Document resource path-security; fix ty in tests

* Carry child template security policy through provider mount

Preserve a mounted template's explicit ResourceSecurity (per-param
exemptions or a deliberate opt-out) through FastMCPProviderResourceTemplate.wrap
so the parent read chokepoint honours it instead of the parent default.

* Defer mcp SDK import so fastmcp.resources loads without the [mcp] extra

* Make resource path-security docs examples self-contained and runnable

* Match exempt_params under both hyphen and underscore spellings

Template placeholders like {git-ref} extract as git_ref, so an exemption
written with the natural URI-template spelling never matched.

* Docs: describe net-depth traversal rule accurately; make example runnable

The screening only rejects .. segments that escape the starting depth
(foo/../bar passes) — saying any standalone .. is rejected overstated
the guarantee. Also define DOCS_ROOT so the example runs.
2026-07-17 17:42:48 -04:00
Grégoire
977f02347b
Forward upstream instructions through create_proxy (#4512)
Co-authored-by: Mistral Vibe <vibe@mistral.ai>
2026-07-17 17:29:15 -04:00
Jeremiah Lowin
f30f847e1f
Merge pull request #4449 from PrefectHQ/modernize/path-security
Route skill file access through SDK path-security primitives
2026-07-07 08:00:21 -04:00
Jeremiah Lowin
396fb876d3
Apply ruff-format: drop now-unused imports and reflow 2026-07-07 07:53:11 -04:00
Jeremiah Lowin
6a6fdcb2bb
Repoint tests and examples off removed deprecations
Replaces FastMCP.as_proxy() helper calls with create_proxy(), rewrites the
mount() as_proxy=/prefix= kwarg tests to plain mount() (the params are gone),
and deletes deprecation-only tests for as_proxy() and remove_tool().
2026-07-07 07:53:11 -04:00
Jeremiah Lowin
05be554e85
Apply ruff formatting to attack corpus tests 2026-07-06 21:32:47 -04:00
Jeremiah Lowin
389e3b78e7
Add path-safety attack corpus tests and document skill file confinement 2026-07-06 21:31:56 -04:00
Jeremiah Lowin
3522a98766
Migrate to MCP Python SDK v2 (#4437) 2026-07-06 17:36:45 -04:00
Jeremiah Lowin
691766b5d0
[codex] Fix OpenAPI resource template requests (#4407) 2026-07-05 19:11:03 -04:00
Jeremiah Lowin
a8bb1b08c2
Raise fastmcp.ValidationError for invalid tool arguments (#4392)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-27 11:14:20 -04:00
René Mulder
0f4f78c464
Fix resource templates with query params on proxied servers (#4251)
Co-authored-by: René Mulder <rene@silverflow.com>
2026-05-31 14:03:49 -04:00
Jeremiah Lowin
140d96aadd
Forward proxy initialize as bridge behavior (#4228) 2026-05-27 10:41:49 -04:00
Jeremiah Lowin
2bff3725bf
Surface proxy upstream failures (#4227) 2026-05-23 14:56:10 -04:00
Jeremiah Lowin
e242abee7d
Let ToolResult return an error result via is_error (#4217) 2026-05-22 20:20:52 -04:00
Bill Easton
1c4069efa3
fix(proxy): restore _current_server in _restore_request_context (#4168) 2026-05-20 10:34:00 -04:00
Craig Ringer
89b99ecfb9
fix(proxy): fall back to live identifier for backend_* span attributes (#4109)
🤖 Generated with Claude Code (Opus 4.7) on behalf of @ringerc

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 10:07:57 -04:00
Shaik Mohammed Kaif
6b6db33c4a
#4084 [Issues] Windows startup crash due to UnicodeDecodeError when l… (#4092)
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
2026-05-07 15:30:56 -04:00
Jeremiah Lowin
97bff96ef1
Revert "Forward backend capabilities in ProxyProvider (#3956)" (#3964)
Co-authored-by: Claude <noreply@anthropic.com>
2026-04-17 17:51:27 -04:00
Jeremiah Lowin
98f69bdba0
Forward backend capabilities in ProxyProvider (#3956)
Co-authored-by: Claude <noreply@anthropic.com>
2026-04-17 15:22:08 -04:00
Bill Easton
4ea102b433
fix: ProxyTool crashes on non-TextContent error responses (#3926)
* fix: handle non-TextContent error responses in ProxyTool

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Avoid serializing binary content into ToolError messages

Use type name instead of str(content) to prevent dumping
large base64 payloads into error messages.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* ruff format fix

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 12:10:23 -04:00
Jeremiah Lowin
9a447cb08d
test: bump OpenAPI init perf threshold to 200ms for Windows CI (#3879) 2026-04-12 17:17:14 -04:00
Bill Easton
fb03e85592
Fix high-severity test quality issues (#3854)
- Delete entirely commented-out test_run_server.py (99 lines dead code)
- Fix test_pydantic_model_with_stringified_json_no_strict: replace
  try/except-both-branches-pass with clear pytest.raises assertion
- Fix test_path_traversal_blocked: remove dead assertions after
  pytest.raises (lines after raise never execute)

Error handling middleware test fixes are in a separate PR (#3858)
which also fixes the underlying RetryMiddleware bug.

🤖 Generated with Claude Code

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 13:14:52 -04:00
Jeremiah Lowin
af957e773f
Replace ___ with hash-based backend tool routing and per-tool prefab resources (#3824)
Replaces the ___ separator for FastMCPApp backend tool routing with a
deterministic hash(app_name, tool_name) prefix, and replaces the shared
singleton prefab renderer resource with per-tool resources synthesized
on demand.

Backend tools are now callable via <hash>_<local_name> instead of
<app_name>___<local_name>. The dispatcher walks the provider tree
recursively via get_tool_by_hash (same pattern as get_app_tool).

Each prefab tool gets its own renderer resource at
ui://prefab/tool/<hash>/renderer.html with per-tool CSP — fixing the
bug where PrefabAppConfig(csp=...) never actually applied.

Closes #3735, closes #3805
2026-04-12 12:52:07 -04:00
Bill Easton
eec52b1f02
fix: materialize generators before result conversion, handle bytes gracefully (#3830)
- Detect async/sync generators after tool execution and materialize
  into lists before the result conversion pipeline processes them
- Generator materialization runs inside timeout scope so slow generators
  respect the configured timeout
- Handle bytes return types: UTF-8 bytes as text, non-UTF-8 as base64
- Suppress output_schema for bytes return types (can't be structured JSON)
- Catch UnicodeDecodeError alongside PydanticSerializationError in
  convert_result for robustness

Fixes #3829

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 11:23:51 -04:00
Rishav Mitra
99eaeb8af4
fix: substitute server variable defaults when building base URL from OpenAPI spec (#3770)
* fix: resolve OpenAPI 3.x server variables in _create_default_client

When an OpenAPI spec defines server variables (e.g. `https://{region}.api.example.com/v1`),
the default values are now substituted before constructing the httpx client base URL.
Previously, the URL was used as-is, causing all requests to fail for specs that use
server variable templating.

Fixes #1681

* fix: use str.replace instead of format_map for server variable substitution

format_map applies Python string formatting rules, so variable names
like {api.version} would be treated as attribute access and raise errors.
Literal token replacement handles all valid OpenAPI variable names safely.
2026-04-06 19:48:30 -04:00
Jeremiah Lowin
c397e68d39
Update ty ignore comments for 0.0.25 compatibility (#3614) 2026-03-24 20:26:26 -04:00