Commit graph

37 commits

Author SHA1 Message Date
YAO_001
9034a2eb4b
Fix CodeMode tool error propagation (#4704)
Co-authored-by: nate nowack <thrast36@gmail.com>
2026-08-02 09:41:36 -04:00
Jeremiah Lowin
3522a98766
Migrate to MCP Python SDK v2 (#4437) 2026-07-06 17:36:45 -04:00
Alex LaGuardia
27a0720928
Add real Monty sandbox e2e coverage for CodeMode call_tool (#4274)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
2026-06-24 11:52:27 -04:00
Bill Easton
9d384ffa7f
feat(code-mode): default sandbox limits and per-execution tool-call cap (#4170)
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
2026-05-20 10:47:12 -04:00
Bill Easton
bdbef49383
fix(code-mode): cancel Monty sandbox future on task cancellation (#4169) 2026-05-20 10:36:31 -04:00
Jeremiah Lowin
c397e68d39
Update ty ignore comments for 0.0.25 compatibility (#3614) 2026-03-24 20:26:26 -04:00
Jeremiah Lowin
360c9c31e5
fix: resolve Pyright "Module is not callable" on @tool, @resource, @prompt decorators (#3540)
* pin pydantic-monty to 0.0.8

* rename tool/prompt/resource base modules to avoid decorator name shadow

* add sys.modules shims for old submodule import paths

* preserve original module paths in deprecation warnings

* clarify when sys.modules shims can be removed
2026-03-17 18:11:42 -04:00
Jeremiah Lowin
f923b671ce Remove stale catalog cache from CodeMode execute 2026-03-03 16:49:50 -05:00
Jeremiah Lowin
404b820144
Add ListTools, search limit, and catalog size annotation to CodeMode (#3359)
* Add tests for two-stage pattern, empty full-detail results, empty inputs

* Add ListTools, search limit, catalog size annotation; split tests

Co-authored-by: Claude <noreply@anthropic.com>

* Remove BM25 internal cap so Search.limit is the sole truncation point

* Pass default_limit to BM25 instead of arbitrary high cap

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-02 18:00:21 -05:00
Jeremiah Lowin
59da3e4ed4
Decompose CodeMode into composable discovery tools (#3354)
* Decompose CodeMode into composable discovery tools

CodeMode now owns only the execute sandbox. Discovery tools (search,
get_schema, etc.) are composable via the discovery_tools parameter.
Each is a Callable[[GetToolCatalog], Tool] factory.

Ships SearchTool (lightweight name+description results) and SchemaTool
(brief markdown or full JSON schemas by tool name) as built-in defaults.

* Rename to Search/GetSchemas/Tags, add tag filtering, fix bugs

- Rename SearchTool→Search, SchemaTool→GetSchemas, Categories→Tags
- Add tags parameter to Search for LLM-side tag filtering
- Add Tags discovery tool for browsing tools by tag
- Fix shared singleton default factories (now per-instance)
- Fix get_schema full mode returning invalid JSON on partial matches
- Fix "untagged" filter inconsistency between Tags and Search
- Split serialization tests to comply with loq line limit
- Rewrite docs for conceptual clarity

* Add three-tier detail levels, remove default_arguments, rename Tags→GetTags, rewrite docs

* Clean up __all__ exports, return valid JSON for empty full-detail results
2026-03-02 16:35:55 -05:00
Magnus
1e72f2457b
Add search_result_serializer hook and serialize_tools_for_output_markdown (#3337) 2026-03-01 14:20:24 -05:00
Jeremiah Lowin
b01e66dc58 Add resource limits to MontySandboxProvider 2026-02-27 21:24:56 -05:00
Adam Azzam
b9153404f4
Add experimental CodeMode transform (#3297)
* code mode

* update uv.lock for monty optional dep

🤖 Generated with Claude Code

* retry CI

* Address PR review comments on CodeMode transform

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix ty unresolved-attribute error on search_helper

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* more idiomacy

* harden

* fix docs

* harden

* fix red CI

* Refactor CodeMode to use CatalogTransform base class

Removes the duplicate ContextVar bypass pattern in favor of the shared
CatalogTransform machinery. Also fixes a pre-existing bug where
`from __future__ import annotations` caused NameError for Annotated
in nested function scopes at runtime.

* Remove redundant _get_visible_tools wrapper in CodeMode

* Rewrite CodeMode docs with proper motivation and structure

* Fix type narrowing in collision test

* Stop unwrapping tool results in CodeMode's call_tool

call_tool() inside execute blocks now returns structured content as-is,
preserving the {"result": value} wrapping. This means the output schema
shown in search results accurately describes what call_tool() returns,
so LLMs can trust the schema when writing code.

Also adds examples/code_mode/ with a server and narrated client demo.

* Simplify call_tool return type: dict | str

* Fix example client to unwrap structured results

* Let server resolve tool versions instead of pinning first match

* Rewrite CodeMode docs to match current behavior

* Rename optional extra from monty to code-mode

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
2026-02-27 12:14:03 -05:00
Jeremiah Lowin
da77cfa73f
Unify SamplingHandler and promote OpenAI handler (#2616)
* Unify SamplingHandler and promote OpenAI handler

Consolidates ServerSamplingHandler and ClientSamplingHandler into a single
SamplingHandler type alias. Moves OpenAISamplingHandler from experimental
to fastmcp.client.sampling.handlers.openai as the canonical location.

Backwards compatibility maintained for imports from experimental.

* Remove unreachable code paths in OpenAI handler

* Fix docstring and use elif for mutually exclusive branches
2025-12-14 15:22:43 -05:00
Jeremiah Lowin
41ec7ee06d
SEP-1577: Sampling with tools (#2551)
* MCP → SDK (vocab change only)

* WIP: Sampling API with SamplingResult[T] and result_type

* SEP-1577: Sampling with tools

- Add tools and result_type parameters to ctx.sample()
- Update OpenAI handler for tool content types
- Client advertises sampling.tools capability by default
- Collect tool results into single message with list content

* Fix tool result content handling in OpenAI handler

* Remove @sampling_tool decorator - pass functions directly to sample()

Functions passed to ctx.sample(tools=[...]) are now auto-converted
via SamplingTool.from_function(). Users can still use that method
directly for custom name/description overrides.

* Remove auto-conversion of MCP tools to sampling tools

Users want MCP tools passed to ctx.sample() to go through the full MCP
machinery (middleware, native responses) rather than being auto-converted
to direct function calls. Now only SamplingTool and plain callables are
accepted - passing a FastMCP Tool raises a clear TypeError.

Also bumps mcp dependency to >=1.24.0 for required sampling features.

* Refactor sampling API: replace sample_iter() with sample_step()

Replace the mutable SampleRun/sample_iter() pattern with a simpler stateless
sample_step() function. sample_step() makes a single LLM call and returns a
SampleStep with the response and history. sample() now loops sample_step()
internally.

Key changes:
- Add sample_step() for fine-grained control over the sampling loop
- Remove SampleRun class and sample_iter() method
- Structured output uses tool description only (no prompt modification)
- execute_tools parameter controls automatic vs manual tool execution

* Address CodeRabbit nitpicks

* Address CodeRabbit review feedback for sampling tools

- Fix temperature=0.0 being dropped due to falsy evaluation
- Add ToolChoice.name support for forcing specific tools
- Replace assert statements with explicit RuntimeError checks
- Add mask_error_details parameter to sample()/sample_step() with ToolError escape hatch
- Fix hasattr patterns with proper isinstance checks
- Document mask_error_details and add OpenAI prerequisites to docs

* Address additional CodeRabbit review feedback

- Catch ValidationError specifically instead of bare Exception
- Update result_type docs to mention dataclasses and basic types
- Raise ValueError for unknown tool_choice modes
- Validate sampling_handler_behavior to catch typos
- Remove ToolChoice.name handling (not part of MCP spec)
- Validate tool_choice string in sample_step()

* Review fixes for sampling tools PR

- Remove internal functions from sampling __init__.py exports
- Remove fragile is_text property, use not is_tool_use instead
- Inline call_client into context.py, remove from run.py
- Fix SamplingMessage docs to use TextContent
- Handle result.text being None in doc examples
- Simplify client sampling docs to recommend OpenAISamplingHandler
- Add sampling_capabilities override documentation
- Raise iteration limit from 50 to 100
- Remove _parse_model_preferences duplication
- Use AsyncOpenAI in OpenAISamplingHandler
- Fix tool_choice docstring

* Fix OpenAI handler tests to use AsyncOpenAI

* Address remaining CodeRabbit review comments

- Fix message ordering in OpenAI handler: tool results now correctly
  follow assistant message with tool_calls
- sample_step() now always includes assistant message in history
- Raise ValueError on JSON parse errors instead of silent {}
- Add has_sampling capability check when behavior is None
- Raise RuntimeError when structured output receives text response
- Wrap primitive result_type schemas in object wrapper
- Fix docs example using invalid SamplingMessage construction
- Add comprehensive client_sampling_test.py example

* Add return type annotation to OpenAISamplingHandler.__init__

* Use explicit 'is not None' check for sampling_capabilities defaulting

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Bill Easton <strawgate@users.noreply.github.com>
2025-12-14 13:51:05 -05:00
Jeremiah Lowin
b501f05794
Switch to new OpenAPI parser as default (#2513)
* Switch to new OpenAPI parser as default

Remove the legacy OpenAPI parser and make the experimental parser the
default. The experimental parser (introduced in 2.11) offers better
performance, improved compatibility, and a more maintainable architecture.

- Delete legacy parser (server/openapi.py, utilities/openapi.py)
- Move experimental parser to main locations
- Remove enable_new_openapi_parser feature flag
- Update documentation to remove experimental references

* Add deprecation stubs for experimental OpenAPI imports

* Add deprecated enable_new_openapi_parser setting and deprecation tests

* SDK docs

* REview comments

* Fix docstrings

* Update docstring

* Review comments

* Fix broken links
2025-12-01 20:29:18 -05:00
Jeremiah Lowin
6cc9559f84
Bump ty to ==0.0.1a25 (#2350)
* Bump ty to >=0.0.1a25 with type fixes

Follow-up to #2295. Updates ty and fixes compatibility issues with alpha 25, including:

- Updated ignore comment syntax (possibly-unbound-attribute → possibly-missing-attribute)
- Fixed async generator type handling with anext()
- Fixed type narrowing for timeout parameters
- Converted base_url assignments to AnyHttpUrl after string manipulation
- Added CallToolResult to return type annotations
- Removed redundant type casts
- Fixed test form data to use strings instead of bytes

ty alpha 25 has limitations with isinstance() narrowing on unions (see pyproject.toml for details), requiring some targeted type ignores.

* Pin ty to ==0.0.1a25

Alpha releases can have breaking changes, so pin to the tested version.
2025-11-02 20:02:45 -05:00
Jeremiah Lowin
19fbc8435e
delete ratio test (#2250) 2025-10-24 19:10:19 -04:00
claude[bot]
638111990d Mark test_github_api_schema_performance as integration test
This test makes external HTTP requests to GitHub and is subject to
network latency, causing CI timeouts. Marking it as an integration test
excludes it from default test runs while keeping it available for
explicit integration testing.

Co-authored-by: William Easton <strawgate@users.noreply.github.com>
2025-10-24 20:59:55 +00:00
Jeremiah Lowin
3321644ad3
Replace subprocess tests with in-process async servers (#2006)
* Use anyio as testing backend

* Remove asyncio markers

* Update streamable http tests

* Replace all subprocess tests

* Replace anyio task groups with asyncio context managers in tests

- Convert run_server_async from anyio task group pattern to asyncio.create_task with async context manager
- Remove task_group fixture from conftest
- Update all test fixtures to use async with run_server_async pattern
- Remove TaskGroup imports from all test files
- Tests now work with pytest-asyncio instead of pytest-anyio

* Update test_github_provider_integration.py
2025-10-19 10:47:54 -04:00
Jeremiah Lowin
b45499292f
Fix nullable enum validation in OpenAPI converter (#2093) 2025-10-15 06:30:30 -07:00
Jeremiah Lowin
59aabe2741
Fix experimental parser missing top-level response schemas (#2087) (#2092) 2025-10-14 15:31:30 -07:00
shlomo666
92b7e92e05
Fix: Preserve OpenAPI parameter descriptions in experimental parser (#1877) 2025-09-21 10:43:50 -04:00
Jeremiah Lowin
9643ad8e1e
Fix FastAPI list parameter parsing in experimental OpenAPI parser (#1834)
Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
Co-authored-by: Jeremiah Lowin <jlowin@users.noreply.github.com>
2025-09-19 13:36:37 -04:00
Jeremiah Lowin
39dee1bdb3
feat(experimental/openapi): replace $ref in additionalProperties; add tests (#1735)
Co-authored-by: Hsiao, Cooper <cooper.hsiao@commscope.com>
Co-authored-by: Cooper <xcooper1030@gmail.com>
2025-09-19 13:35:45 -04:00
William Easton
fe4f31c2c7
Enable more type checking rules (#1775) 2025-09-07 11:11:44 -04:00
William Easton
d32a2b953e
Fallback to a Completions API when Sampling is not available (#1145) 2025-08-21 07:49:29 -04:00
Jeremiah Lowin
dd34846266
Optimize OpenAPI payload size by 46% (#1452)
Co-authored-by: Claude <noreply@anthropic.com>
2025-08-11 17:31:54 -04:00
Jeremiah Lowin
f8f05ca395
Clean up complexity from PR #1426 (#1435) 2025-08-10 21:55:17 -04:00
Jeremiah Lowin
558c7d2a66
Fix OpenAPI transitive references and performance (#1372) (#1426) 2025-08-09 20:53:51 -04:00
633WHU
5fe3287cee
Fix OpenAPI allOf handling at requestBody top level (#1378) (#1425) 2025-08-09 11:52:31 -04:00
Jeremiah Lowin
ec09310593
Increase performance test threshold to 100ms (#1406) 2025-08-08 12:19:22 -04:00
Jeremiah Lowin
6125b1ebfc
Improve OpenAPI-to-JSONSchema conversion utilities (#1283) 2025-07-28 21:02:03 -04:00
Jeremiah Lowin
52a0fc078a
Fix nullable field handling in OpenAPI to JSON Schema conversion (#1279)
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-28 20:31:23 -04:00
itaru2622
99f27da088
fix: experimental FastMCPOpenAPI server lost headers in request when __init__(client with headers) (#1254) 2025-07-25 11:04:41 -04:00
Jeremiah Lowin
d6bd800d88
Optimize OpenAPI parser performance with single-pass schema processing (#1214) 2025-07-21 21:29:56 -04:00
Jeremiah Lowin
4a38784194
Introduce experimental OpenAPI parser with improved performance and maintainability (#1209) 2025-07-21 16:17:36 -04:00