# null Source: https://gofastmcp.com/changelog ## [v2.10.5: Middle Management](https://github.com/jlowin/fastmcp/releases/tag/v2.10.5) A maintenance release focused on OpenAPI refinements and middleware fixes, plus console improvements. ## What's Changed ### Enhancements πŸ”§ * Fix Claude Code CLI detection for npm global installations by [@jlowin](https://github.com/jlowin) in [#1106](https://github.com/jlowin/fastmcp/pull/1106) * Fix OpenAPI parameter name collisions with location suffixing by [@jlowin](https://github.com/jlowin) in [#1107](https://github.com/jlowin/fastmcp/pull/1107) * Add mirrored component support for proxy servers by [@jlowin](https://github.com/jlowin) in [#1105](https://github.com/jlowin/fastmcp/pull/1105) ### Fixes 🐞 * Fix OpenAPI deepObject style parameter encoding by [@jlowin](https://github.com/jlowin) in [#1122](https://github.com/jlowin/fastmcp/pull/1122) * xfail when github token is not set ('' or None) by [@jlowin](https://github.com/jlowin) in [#1123](https://github.com/jlowin/fastmcp/pull/1123) * fix: replace oneOf with anyOf in OpenAPI output schemas by [@MagnusS0](https://github.com/MagnusS0) in [#1119](https://github.com/jlowin/fastmcp/pull/1119) * Fix middleware list result types by [@jlowin](https://github.com/jlowin) in [#1125](https://github.com/jlowin/fastmcp/pull/1125) * Improve console width for logo by [@jlowin](https://github.com/jlowin) in [#1126](https://github.com/jlowin/fastmcp/pull/1126) ### Docs πŸ“š * Improve transport + integration docs by [@jlowin](https://github.com/jlowin) in [#1103](https://github.com/jlowin/fastmcp/pull/1103) * Update proxy.mdx by [@coldfire-x](https://github.com/coldfire-x) in [#1108](https://github.com/jlowin/fastmcp/pull/1108) ### Other Changes 🦾 * Update github remote server tests with secret by [@jlowin](https://github.com/jlowin) in [#1112](https://github.com/jlowin/fastmcp/pull/1112) ## New Contributors * [@coldfire-x](https://github.com/coldfire-x) made their first contribution in [#1108](https://github.com/jlowin/fastmcp/pull/1108) * [@MagnusS0](https://github.com/MagnusS0) made their first contribution in [#1119](https://github.com/jlowin/fastmcp/pull/1119) **Full Changelog**: [v2.10.4...v2.10.5](https://github.com/jlowin/fastmcp/compare/v2.10.4...v2.10.5) ## [v2.10.4: Transport-ation](https://github.com/jlowin/fastmcp/releases/tag/v2.10.4) A quick fix to ensure the CLI accepts "streamable-http" as a valid transport option. ## What's Changed ### Fixes 🐞 * Ensure the CLI accepts "streamable-http" as a valid transport by [@jlowin](https://github.com/jlowin) in [#1099](https://github.com/jlowin/fastmcp/pull/1099) **Full Changelog**: [v2.10.3...v2.10.4](https://github.com/jlowin/fastmcp/compare/v2.10.3...v2.10.4) ## [v2.10.3: CLI Me a River](https://github.com/jlowin/fastmcp/releases/tag/v2.10.3) A major CLI overhaul featuring a complete refactor from typer to cyclopts, new IDE integrations, and comprehensive OpenAPI improvements. ## What's Changed ### New Features πŸŽ‰ * Refactor CLI from typer to cyclopts and add comprehensive tests by [@jlowin](https://github.com/jlowin) in [#1062](https://github.com/jlowin/fastmcp/pull/1062) * Add output schema support for OpenAPI tools by [@jlowin](https://github.com/jlowin) in [#1073](https://github.com/jlowin/fastmcp/pull/1073) ### Enhancements πŸ”§ * Add Cursor support via CLI integration by [@jlowin](https://github.com/jlowin) in [#1052](https://github.com/jlowin/fastmcp/pull/1052) * Add Claude Code install integration by [@jlowin](https://github.com/jlowin) in [#1053](https://github.com/jlowin/fastmcp/pull/1053) * Generate MCP JSON config output from CLI as new `fastmcp install` command by [@jlowin](https://github.com/jlowin) in [#1056](https://github.com/jlowin/fastmcp/pull/1056) * Use isawaitable instead of iscoroutine by [@jlowin](https://github.com/jlowin) in [#1059](https://github.com/jlowin/fastmcp/pull/1059) * feat: Add `--path` Option to CLI for HTTP/SSE Route by [@davidbk-legit](https://github.com/davidbk-legit) in [#1087](https://github.com/jlowin/fastmcp/pull/1087) * Fix concurrent proxy client operations with session isolation by [@jlowin](https://github.com/jlowin) in [#1083](https://github.com/jlowin/fastmcp/pull/1083) ### Fixes 🐞 * Refactor Client context management to avoid concurrency issue by [@hopeful0](https://github.com/hopeful0) in [#1054](https://github.com/jlowin/fastmcp/pull/1054) * Keep json schema \$defs on transform by [@strawgate](https://github.com/strawgate) in [#1066](https://github.com/jlowin/fastmcp/pull/1066) * Ensure fastmcp version copy is plaintext by [@jlowin](https://github.com/jlowin) in [#1071](https://github.com/jlowin/fastmcp/pull/1071) * Fix single-element list unwrapping in tool content by [@jlowin](https://github.com/jlowin) in [#1074](https://github.com/jlowin/fastmcp/pull/1074) * Fix max recursion error when pruning OpenAPI definitions by [@dimitribarbot](https://github.com/dimitribarbot) in [#1092](https://github.com/jlowin/fastmcp/pull/1092) * Fix OpenAPI tool name registration when modified by mcp\_component\_fn by [@jlowin](https://github.com/jlowin) in [#1096](https://github.com/jlowin/fastmcp/pull/1096) ### Docs πŸ“š * Docs: add example of more concise way to use bearer auth by [@neilconway](https://github.com/neilconway) in [#1055](https://github.com/jlowin/fastmcp/pull/1055) * Update favicon by [@jlowin](https://github.com/jlowin) in [#1058](https://github.com/jlowin/fastmcp/pull/1058) * Update environment note by [@jlowin](https://github.com/jlowin) in [#1075](https://github.com/jlowin/fastmcp/pull/1075) * Add fastmcp version --copy documentation by [@jlowin](https://github.com/jlowin) in [#1076](https://github.com/jlowin/fastmcp/pull/1076) ### Other Changes 🦾 * Remove asserts and add documentation following #1054 by [@jlowin](https://github.com/jlowin) in [#1057](https://github.com/jlowin/fastmcp/pull/1057) * Add --copy flag for fastmcp version by [@jlowin](https://github.com/jlowin) in [#1063](https://github.com/jlowin/fastmcp/pull/1063) * Fix docstring format for fastmcp.client.Client by [@neilconway](https://github.com/neilconway) in [#1094](https://github.com/jlowin/fastmcp/pull/1094) ## New Contributors * [@neilconway](https://github.com/neilconway) made their first contribution in [#1055](https://github.com/jlowin/fastmcp/pull/1055) * [@davidbk-legit](https://github.com/davidbk-legit) made their first contribution in [#1087](https://github.com/jlowin/fastmcp/pull/1087) * [@dimitribarbot](https://github.com/dimitribarbot) made their first contribution in [#1092](https://github.com/jlowin/fastmcp/pull/1092) **Full Changelog**: [v2.10.2...v2.10.3](https://github.com/jlowin/fastmcp/compare/v2.10.2...v2.10.3) ## [v2.10.2: Forward March](https://github.com/jlowin/fastmcp/releases/tag/v2.10.2) The headline feature of this release is the ability to "forward" advanced MCP interactions like logging, progress, and elicitation through proxy servers. If the remote server requests an elicitation, the proxy client will pass that request to the new, "ultimate" client. ## What's Changed ### New Features πŸŽ‰ * Proxy support advanced MCP features by [@hopeful0](https://github.com/hopeful0) in [#1022](https://github.com/jlowin/fastmcp/pull/1022) ### Enhancements πŸ”§ * Re-add splash screen by [@jlowin](https://github.com/jlowin) in [#1027](https://github.com/jlowin/fastmcp/pull/1027) * Reduce banner padding by [@jlowin](https://github.com/jlowin) in [#1030](https://github.com/jlowin/fastmcp/pull/1030) * Allow per-server timeouts in MCPConfig by [@cegersdoerfer](https://github.com/cegersdoerfer) in [#1031](https://github.com/jlowin/fastmcp/pull/1031) * Support 'scp' claim for OAuth scopes in BearerAuthProvider by [@jlowin](https://github.com/jlowin) in [#1033](https://github.com/jlowin/fastmcp/pull/1033) * Add path expansion to image/audio/file by [@jlowin](https://github.com/jlowin) in [#1038](https://github.com/jlowin/fastmcp/pull/1038) * Ensure multi-client configurations use new ProxyClient by [@jlowin](https://github.com/jlowin) in [#1045](https://github.com/jlowin/fastmcp/pull/1045) ### Fixes 🐞 * Expose stateless\_http kwarg for mcp.run() by [@jlowin](https://github.com/jlowin) in [#1018](https://github.com/jlowin/fastmcp/pull/1018) * Avoid propagating logs by [@jlowin](https://github.com/jlowin) in [#1042](https://github.com/jlowin/fastmcp/pull/1042) ### Docs πŸ“š * Clean up docs by [@jlowin](https://github.com/jlowin) in [#1028](https://github.com/jlowin/fastmcp/pull/1028) * Docs: clarify server URL paths for ChatGPT integration by [@thap2331](https://github.com/thap2331) in [#1017](https://github.com/jlowin/fastmcp/pull/1017) ### Other Changes 🦾 * Split giant openapi test file into smaller files by [@jlowin](https://github.com/jlowin) in [#1034](https://github.com/jlowin/fastmcp/pull/1034) * Add comprehensive OpenAPI 3.0 vs 3.1 compatibility tests by [@jlowin](https://github.com/jlowin) in [#1035](https://github.com/jlowin/fastmcp/pull/1035) * Update banner and use console.log by [@jlowin](https://github.com/jlowin) in [#1041](https://github.com/jlowin/fastmcp/pull/1041) ## New Contributors * [@cegersdoerfer](https://github.com/cegersdoerfer) made their first contribution in [#1031](https://github.com/jlowin/fastmcp/pull/1031) * [@hopeful0](https://github.com/hopeful0) made their first contribution in [#1022](https://github.com/jlowin/fastmcp/pull/1022) * [@thap2331](https://github.com/thap2331) made their first contribution in [#1017](https://github.com/jlowin/fastmcp/pull/1017) **Full Changelog**: [v2.10.1...v2.10.2](https://github.com/jlowin/fastmcp/compare/v2.10.1...v2.10.2) ## [v2.10.1: Revert to Sender](https://github.com/jlowin/fastmcp/releases/tag/v2.10.1) A quick patch to revert the CLI banner that was added in v2.10.0. ## What's Changed ### Docs πŸ“š * Update changelog.mdx by [@jlowin](https://github.com/jlowin) in [#1009](https://github.com/jlowin/fastmcp/pull/1009) * Revert "Add CLI banner" by [@jlowin](https://github.com/jlowin) in [#1011](https://github.com/jlowin/fastmcp/pull/1011) **Full Changelog**: [v2.10.0...v2.10.1](https://github.com/jlowin/fastmcp/compare/v2.10.0...v2.10.1) ## [v2.10.0: Great Spec-tations](https://github.com/jlowin/fastmcp/releases/tag/v2.10.0) FastMCP 2.10 brings full compliance with the 6/18/2025 MCP spec update, introducing elicitation support for dynamic server-client communication and output schemas for structured tool responses. Please note that due to these changes, this release also includes a breaking change to the return signature of `client.call_tool()`. ### Elicitation Support Elicitation allows MCP servers to request additional information from clients during tool execution, enabling more interactive and dynamic server behavior. This opens up new possibilities for tools that need user input or confirmation during execution. ### Output Schemas Tools can now define structured output schemas, ensuring that responses conform to expected formats and making tool integration more predictable and type-safe. ## What's Changed ### New Features πŸŽ‰ * MCP 6/18/25: Add output schema to tools by [@jlowin](https://github.com/jlowin) in [#901](https://github.com/jlowin/fastmcp/pull/901) * MCP 6/18/25: Elicitation support by [@jlowin](https://github.com/jlowin) in [#889](https://github.com/jlowin/fastmcp/pull/889) ### Enhancements πŸ”§ * Update types + tests for SDK changes by [@jlowin](https://github.com/jlowin) in [#888](https://github.com/jlowin/fastmcp/pull/888) * MCP 6/18/25: Update auth primitives by [@jlowin](https://github.com/jlowin) in [#966](https://github.com/jlowin/fastmcp/pull/966) * Add OpenAPI extensions support to HTTPRoute by [@maddymanu](https://github.com/maddymanu) in [#977](https://github.com/jlowin/fastmcp/pull/977) * Add title field support to FastMCP components by [@jlowin](https://github.com/jlowin) in [#982](https://github.com/jlowin/fastmcp/pull/982) * Support implicit Elicitation acceptance by [@jlowin](https://github.com/jlowin) in [#983](https://github.com/jlowin/fastmcp/pull/983) * Support 'no response' elicitation requests by [@jlowin](https://github.com/jlowin) in [#992](https://github.com/jlowin/fastmcp/pull/992) * Add Support for Configurable Algorithms by [@sstene1](https://github.com/sstene1) in [#997](https://github.com/jlowin/fastmcp/pull/997) ### Fixes 🐞 * Improve stdio error handling to raise connection failures immediately by [@jlowin](https://github.com/jlowin) in [#984](https://github.com/jlowin/fastmcp/pull/984) * Fix type hints for FunctionResource:fn by [@CfirTsabari](https://github.com/CfirTsabari) in [#986](https://github.com/jlowin/fastmcp/pull/986) * Update link to OpenAI MCP example by [@mossbanay](https://github.com/mossbanay) in [#985](https://github.com/jlowin/fastmcp/pull/985) * Fix output schema generation edge case by [@jlowin](https://github.com/jlowin) in [#995](https://github.com/jlowin/fastmcp/pull/995) * Refactor array parameter formatting to reduce code duplication by [@jlowin](https://github.com/jlowin) in [#1007](https://github.com/jlowin/fastmcp/pull/1007) * Fix OpenAPI array parameter explode handling by [@jlowin](https://github.com/jlowin) in [#1008](https://github.com/jlowin/fastmcp/pull/1008) ### Breaking Changes πŸ›« * MCP 6/18/25: Upgrade to mcp 1.10 by [@jlowin](https://github.com/jlowin) in [#887](https://github.com/jlowin/fastmcp/pull/887) ### Docs πŸ“š * Update middleware imports and documentation by [@jlowin](https://github.com/jlowin) in [#999](https://github.com/jlowin/fastmcp/pull/999) * Update OpenAI docs by [@jlowin](https://github.com/jlowin) in [#1001](https://github.com/jlowin/fastmcp/pull/1001) * Add CLI banner by [@jlowin](https://github.com/jlowin) in [#1005](https://github.com/jlowin/fastmcp/pull/1005) ### Examples & Contrib πŸ’‘ * Component Manager by [@gorocode](https://github.com/gorocode) in [#976](https://github.com/jlowin/fastmcp/pull/976) ### Other Changes 🦾 * Minor auth improvements by [@jlowin](https://github.com/jlowin) in [#967](https://github.com/jlowin/fastmcp/pull/967) * Add .ccignore for copychat by [@jlowin](https://github.com/jlowin) in [#1000](https://github.com/jlowin/fastmcp/pull/1000) ## New Contributors * [@maddymanu](https://github.com/maddymanu) made their first contribution in [#977](https://github.com/jlowin/fastmcp/pull/977) * [@github0hello](https://github.com/github0hello) made their first contribution in [#979](https://github.com/jlowin/fastmcp/pull/979) * [@tommitt](https://github.com/tommitt) made their first contribution in [#975](https://github.com/jlowin/fastmcp/pull/975) * [@CfirTsabari](https://github.com/CfirTsabari) made their first contribution in [#986](https://github.com/jlowin/fastmcp/pull/986) * [@mossbanay](https://github.com/mossbanay) made their first contribution in [#985](https://github.com/jlowin/fastmcp/pull/985) * [@sstene1](https://github.com/sstene1) made their first contribution in [#997](https://github.com/jlowin/fastmcp/pull/997) **Full Changelog**: [v2.9.2...v2.10.0](https://github.com/jlowin/fastmcp/compare/v2.9.2...v2.10.0) ## [v2.9.2: Safety Pin](https://github.com/jlowin/fastmcp/releases/tag/v2.9.2) This is a patch release to pin `mcp` below 1.10, which includes changes related to the 6/18/2025 MCP spec update and could potentially break functionality for some FastMCP users. ## What's Changed ### Docs πŸ“š * Fix version badge for messages by [@jlowin](https://github.com/jlowin) in [#960](https://github.com/jlowin/fastmcp/pull/960) ### Dependencies πŸ“¦ * Pin mcp dependency by [@jlowin](https://github.com/jlowin) in [#962](https://github.com/jlowin/fastmcp/pull/962) **Full Changelog**: [v2.9.1...v2.9.2](https://github.com/jlowin/fastmcp/compare/v2.9.1...v2.9.2) ## [v2.9.1: Call Me Maybe](https://github.com/jlowin/fastmcp/releases/tag/v2.9.1) FastMCP 2.9.1 introduces automatic MCP list change notifications, allowing servers to notify clients when tools, resources, or prompts are dynamically updated. This enables more responsive and adaptive MCP integrations. ## What's Changed ### New Features πŸŽ‰ * Add automatic MCP list change notifications and client message handling by [@jlowin](https://github.com/jlowin) in [#939](https://github.com/jlowin/fastmcp/pull/939) ### Enhancements πŸ”§ * Add debug logging to bearer token authentication by [@jlowin](https://github.com/jlowin) in [#952](https://github.com/jlowin/fastmcp/pull/952) ### Fixes 🐞 * Fix duplicate error logging in exception handlers by [@jlowin](https://github.com/jlowin) in [#938](https://github.com/jlowin/fastmcp/pull/938) * Fix parameter location enum handling in OpenAPI parser by [@jlowin](https://github.com/jlowin) in [#953](https://github.com/jlowin/fastmcp/pull/953) * Fix external schema reference handling in OpenAPI parser by [@jlowin](https://github.com/jlowin) in [#954](https://github.com/jlowin/fastmcp/pull/954) ### Docs πŸ“š * Update changelog for 2.9 release by [@jlowin](https://github.com/jlowin) in [#929](https://github.com/jlowin/fastmcp/pull/929) * Regenerate API references by [@zzstoatzz](https://github.com/zzstoatzz) in [#935](https://github.com/jlowin/fastmcp/pull/935) * Regenerate API references by [@zzstoatzz](https://github.com/zzstoatzz) in [#947](https://github.com/jlowin/fastmcp/pull/947) * Regenerate API references by [@zzstoatzz](https://github.com/zzstoatzz) in [#949](https://github.com/jlowin/fastmcp/pull/949) ### Examples & Contrib πŸ’‘ * Add `create_thread` tool to bsky MCP server by [@zzstoatzz](https://github.com/zzstoatzz) in [#927](https://github.com/jlowin/fastmcp/pull/927) * Update `mount_example.py` to work with current fastmcp API by [@rajephon](https://github.com/rajephon) in [#957](https://github.com/jlowin/fastmcp/pull/957) ## New Contributors * [@rajephon](https://github.com/rajephon) made their first contribution in [#957](https://github.com/jlowin/fastmcp/pull/957) **Full Changelog**: [v2.9.0...v2.9.1](https://github.com/jlowin/fastmcp/compare/v2.9.0...v2.9.1) ## [v2.9.0: Stuck in the Middleware With You](https://github.com/jlowin/fastmcp/releases/tag/v2.9.0) FastMCP 2.9 introduces two important features that push beyond the basic MCP protocol: MCP Middleware and server-side type conversion. ### MCP Middleware MCP middleware lets you intercept and modify requests and responses at the protocol level, giving you powerful capabilities for logging, authentication, validation, and more. This is particularly useful for building production-ready MCP servers that need sophisticated request handling. ### Server-side Type Conversion This release also introduces server-side type conversion for prompt arguments, ensuring that data is properly formatted before being passed to your functions. This reduces the burden on individual tools and prompts to handle type validation and conversion. ## What's Changed ### New Features πŸŽ‰ * Add File utility for binary data by [@gorocode](https://github.com/gorocode) in [#843](https://github.com/jlowin/fastmcp/pull/843) * Consolidate prefix logic into FastMCP methods by [@jlowin](https://github.com/jlowin) in [#861](https://github.com/jlowin/fastmcp/pull/861) * Add MCP Middleware by [@jlowin](https://github.com/jlowin) in [#870](https://github.com/jlowin/fastmcp/pull/870) * Implement server-side type conversion for prompt arguments by [@jlowin](https://github.com/jlowin) in [#908](https://github.com/jlowin/fastmcp/pull/908) ### Enhancements πŸ”§ * Fix tool description indentation issue by [@zfflxx](https://github.com/zfflxx) in [#845](https://github.com/jlowin/fastmcp/pull/845) * Add version parameter to FastMCP constructor by [@mkyutani](https://github.com/mkyutani) in [#842](https://github.com/jlowin/fastmcp/pull/842) * Update version to not be positional by [@jlowin](https://github.com/jlowin) in [#848](https://github.com/jlowin/fastmcp/pull/848) * Add key to component by [@jlowin](https://github.com/jlowin) in [#869](https://github.com/jlowin/fastmcp/pull/869) * Add session\_id property to Context for data sharing by [@jlowin](https://github.com/jlowin) in [#881](https://github.com/jlowin/fastmcp/pull/881) * Fix CORS documentation example by [@jlowin](https://github.com/jlowin) in [#895](https://github.com/jlowin/fastmcp/pull/895) ### Fixes 🐞 * "report\_progress missing passing related\_request\_id causes notifications not working" by [@alexsee](https://github.com/alexsee) in [#838](https://github.com/jlowin/fastmcp/pull/838) * Fix JWT issuer validation to support string values per RFC 7519 by [@jlowin](https://github.com/jlowin) in [#892](https://github.com/jlowin/fastmcp/pull/892) * Fix BearerAuthProvider audience type annotations by [@jlowin](https://github.com/jlowin) in [#894](https://github.com/jlowin/fastmcp/pull/894) ### Docs πŸ“š * Add CLAUDE.md development guidelines by [@jlowin](https://github.com/jlowin) in [#880](https://github.com/jlowin/fastmcp/pull/880) * Update context docs for session\_id property by [@jlowin](https://github.com/jlowin) in [#882](https://github.com/jlowin/fastmcp/pull/882) * Add API reference by [@zzstoatzz](https://github.com/zzstoatzz) in [#893](https://github.com/jlowin/fastmcp/pull/893) * Fix API ref rendering by [@zzstoatzz](https://github.com/zzstoatzz) in [#900](https://github.com/jlowin/fastmcp/pull/900) * Simplify docs nav by [@jlowin](https://github.com/jlowin) in [#902](https://github.com/jlowin/fastmcp/pull/902) * Add fastmcp inspect command by [@jlowin](https://github.com/jlowin) in [#904](https://github.com/jlowin/fastmcp/pull/904) * Update client docs by [@jlowin](https://github.com/jlowin) in [#912](https://github.com/jlowin/fastmcp/pull/912) * Update docs nav by [@jlowin](https://github.com/jlowin) in [#913](https://github.com/jlowin/fastmcp/pull/913) * Update integration documentation for Claude Desktop, ChatGPT, and Claude Code by [@jlowin](https://github.com/jlowin) in [#915](https://github.com/jlowin/fastmcp/pull/915) * Add http as an alias for streamable http by [@jlowin](https://github.com/jlowin) in [#917](https://github.com/jlowin/fastmcp/pull/917) * Clean up parameter documentation by [@jlowin](https://github.com/jlowin) in [#918](https://github.com/jlowin/fastmcp/pull/918) * Add middleware examples for timing, logging, rate limiting, and error handling by [@jlowin](https://github.com/jlowin) in [#919](https://github.com/jlowin/fastmcp/pull/919) * ControlFlow β†’ FastMCP rename by [@jlowin](https://github.com/jlowin) in [#922](https://github.com/jlowin/fastmcp/pull/922) ### Examples & Contrib πŸ’‘ * Add contrib.mcp\_mixin support for annotations by [@rsp2k](https://github.com/rsp2k) in [#860](https://github.com/jlowin/fastmcp/pull/860) * Add ATProto (Bluesky) MCP Server Example by [@zzstoatzz](https://github.com/zzstoatzz) in [#916](https://github.com/jlowin/fastmcp/pull/916) * Fix path in atproto example pyproject by [@zzstoatzz](https://github.com/zzstoatzz) in [#920](https://github.com/jlowin/fastmcp/pull/920) * Remove uv source in example by [@zzstoatzz](https://github.com/zzstoatzz) in [#921](https://github.com/jlowin/fastmcp/pull/921) ## New Contributors * [@alexsee](https://github.com/alexsee) made their first contribution in [#838](https://github.com/jlowin/fastmcp/pull/838) * [@zfflxx](https://github.com/zfflxx) made their first contribution in [#845](https://github.com/jlowin/fastmcp/pull/845) * [@mkyutani](https://github.com/mkyutani) made their first contribution in [#842](https://github.com/jlowin/fastmcp/pull/842) * [@gorocode](https://github.com/gorocode) made their first contribution in [#843](https://github.com/jlowin/fastmcp/pull/843) * [@rsp2k](https://github.com/rsp2k) made their first contribution in [#860](https://github.com/jlowin/fastmcp/pull/860) * [@owtaylor](https://github.com/owtaylor) made their first contribution in [#897](https://github.com/jlowin/fastmcp/pull/897) * [@Jason-CKY](https://github.com/Jason-CKY) made their first contribution in [#906](https://github.com/jlowin/fastmcp/pull/906) **Full Changelog**: [v2.8.1...v2.9.0](https://github.com/jlowin/fastmcp/compare/v2.8.1...v2.9.0) ## [v2.8.1: Sound Judgement](https://github.com/jlowin/fastmcp/releases/tag/v2.8.1) 2.8.1 introduces audio support, as well as minor fixes and updates for deprecated features. ### Audio Support This release adds support for audio content in MCP tools and resources, expanding FastMCP's multimedia capabilities beyond text and images. ## What's Changed ### New Features πŸŽ‰ * Add audio support by [@jlowin](https://github.com/jlowin) in [#833](https://github.com/jlowin/fastmcp/pull/833) ### Enhancements πŸ”§ * Add flag for disabling deprecation warnings by [@jlowin](https://github.com/jlowin) in [#802](https://github.com/jlowin/fastmcp/pull/802) * Add examples to Tool Arg Param transformation by [@strawgate](https://github.com/strawgate) in [#806](https://github.com/jlowin/fastmcp/pull/806) ### Fixes 🐞 * Restore .settings access as deprecated by [@jlowin](https://github.com/jlowin) in [#800](https://github.com/jlowin/fastmcp/pull/800) * Ensure handling of false http kwargs correctly; removed unused kwarg by [@jlowin](https://github.com/jlowin) in [#804](https://github.com/jlowin/fastmcp/pull/804) * Bump mcp 1.9.4 by [@jlowin](https://github.com/jlowin) in [#835](https://github.com/jlowin/fastmcp/pull/835) ### Docs πŸ“š * Update changelog for 2.8.0 by [@jlowin](https://github.com/jlowin) in [#794](https://github.com/jlowin/fastmcp/pull/794) * Update welcome docs by [@jlowin](https://github.com/jlowin) in [#808](https://github.com/jlowin/fastmcp/pull/808) * Update headers in docs by [@jlowin](https://github.com/jlowin) in [#809](https://github.com/jlowin/fastmcp/pull/809) * Add MCP group to tutorials by [@jlowin](https://github.com/jlowin) in [#810](https://github.com/jlowin/fastmcp/pull/810) * Add Community section to documentation by [@zzstoatzz](https://github.com/zzstoatzz) in [#819](https://github.com/jlowin/fastmcp/pull/819) * Add 2.8 update by [@jlowin](https://github.com/jlowin) in [#821](https://github.com/jlowin/fastmcp/pull/821) * Embed YouTube videos in community showcase by [@zzstoatzz](https://github.com/zzstoatzz) in [#820](https://github.com/jlowin/fastmcp/pull/820) ### Other Changes 🦾 * Ensure http args are passed through by [@jlowin](https://github.com/jlowin) in [#803](https://github.com/jlowin/fastmcp/pull/803) * Fix install link in readme by [@jlowin](https://github.com/jlowin) in [#836](https://github.com/jlowin/fastmcp/pull/836) **Full Changelog**: [v2.8.0...v2.8.1](https://github.com/jlowin/fastmcp/compare/v2.8.0...v2.8.1) ## [v2.8.0: Transform and Roll Out](https://github.com/jlowin/fastmcp/releases/tag/v2.8.0) FastMCP 2.8.0 introduces powerful new ways to customize and control your MCP servers! ### Tool Transformation The highlight of this release is first-class [**Tool Transformation**](/patterns/tool-transformation), a new feature that lets you create enhanced variations of existing tools. You can now easily rename arguments, hide parameters, modify descriptions, and even wrap tools with custom validation or post-processing logicβ€”all without rewriting the original code. This makes it easier than ever to adapt generic tools for specific LLM use cases or to simplify complex APIs. Huge thanks to [@strawgate](https://github.com/strawgate) for partnering on this, starting with [#591](https://github.com/jlowin/fastmcp/discussions/591) and [#599](https://github.com/jlowin/fastmcp/pull/599) and continuing offline. ### Component Control This release also gives you more granular control over which components are exposed to clients. With new [**tag-based filtering**](/servers/server#tag-based-filtering), you can selectively enable or disable tools, resources, and prompts based on tags, perfect for managing different environments or user permissions. Complementing this, every component now supports being [programmatically enabled or disabled](/servers/tools#disabling-tools), offering dynamic control over your server's capabilities. ### Tools-by-Default Finally, to improve compatibility with a wider range of LLM clients, this release changes the default behavior for OpenAPI integration: all API endpoints are now converted to `Tools` by default. This is a **breaking change** but pragmatically necessitated by the fact that the majority of MCP clients available today are, sadly, only compatible with MCP tools. Therefore, this change significantly simplifies the out-of-the-box experience and ensures your entire API is immediately accessible to any tool-using agent. ## What's Changed ### New Features πŸŽ‰ * First-class tool transformation by [@jlowin](https://github.com/jlowin) in [#745](https://github.com/jlowin/fastmcp/pull/745) * Support enable/disable for all FastMCP components (tools, prompts, resources, templates) by [@jlowin](https://github.com/jlowin) in [#781](https://github.com/jlowin/fastmcp/pull/781) * Add support for tag-based component filtering by [@jlowin](https://github.com/jlowin) in [#748](https://github.com/jlowin/fastmcp/pull/748) * Allow tag assignments for OpenAPI by [@jlowin](https://github.com/jlowin) in [#791](https://github.com/jlowin/fastmcp/pull/791) ### Enhancements πŸ”§ * Create common base class for components by [@jlowin](https://github.com/jlowin) in [#776](https://github.com/jlowin/fastmcp/pull/776) * Move components to own file; add resource by [@jlowin](https://github.com/jlowin) in [#777](https://github.com/jlowin/fastmcp/pull/777) * Update FastMCP component with **eq** and **repr** by [@jlowin](https://github.com/jlowin) in [#779](https://github.com/jlowin/fastmcp/pull/779) * Remove open-ended and server-specific settings by [@jlowin](https://github.com/jlowin) in [#750](https://github.com/jlowin/fastmcp/pull/750) ### Fixes 🐞 * Ensure client is only initialized once by [@jlowin](https://github.com/jlowin) in [#758](https://github.com/jlowin/fastmcp/pull/758) * Fix field validator for resource by [@jlowin](https://github.com/jlowin) in [#778](https://github.com/jlowin/fastmcp/pull/778) * Ensure proxies can overwrite remote tools without falling back to the remote by [@jlowin](https://github.com/jlowin) in [#782](https://github.com/jlowin/fastmcp/pull/782) ### Breaking Changes πŸ›« * Treat all openapi routes as tools by [@jlowin](https://github.com/jlowin) in [#788](https://github.com/jlowin/fastmcp/pull/788) * Fix issue with global OpenAPI tags by [@jlowin](https://github.com/jlowin) in [#792](https://github.com/jlowin/fastmcp/pull/792) ### Docs πŸ“š * Minor docs updates by [@jlowin](https://github.com/jlowin) in [#755](https://github.com/jlowin/fastmcp/pull/755) * Add 2.7 update by [@jlowin](https://github.com/jlowin) in [#756](https://github.com/jlowin/fastmcp/pull/756) * Reduce 2.7 image size by [@jlowin](https://github.com/jlowin) in [#757](https://github.com/jlowin/fastmcp/pull/757) * Update updates.mdx by [@jlowin](https://github.com/jlowin) in [#765](https://github.com/jlowin/fastmcp/pull/765) * Hide docs sidebar scrollbar by default by [@jlowin](https://github.com/jlowin) in [#766](https://github.com/jlowin/fastmcp/pull/766) * Add "stop vibe testing" to tutorials by [@jlowin](https://github.com/jlowin) in [#767](https://github.com/jlowin/fastmcp/pull/767) * Add docs links by [@jlowin](https://github.com/jlowin) in [#768](https://github.com/jlowin/fastmcp/pull/768) * Fix: updated variable name under Gemini remote client by [@yrangana](https://github.com/yrangana) in [#769](https://github.com/jlowin/fastmcp/pull/769) * Revert "Hide docs sidebar scrollbar by default" by [@jlowin](https://github.com/jlowin) in [#770](https://github.com/jlowin/fastmcp/pull/770) * Add updates by [@jlowin](https://github.com/jlowin) in [#773](https://github.com/jlowin/fastmcp/pull/773) * Add tutorials by [@jlowin](https://github.com/jlowin) in [#783](https://github.com/jlowin/fastmcp/pull/783) * Update LLM-friendly docs by [@jlowin](https://github.com/jlowin) in [#784](https://github.com/jlowin/fastmcp/pull/784) * Update oauth.mdx by [@JeremyCraigMartinez](https://github.com/JeremyCraigMartinez) in [#787](https://github.com/jlowin/fastmcp/pull/787) * Add changelog by [@jlowin](https://github.com/jlowin) in [#789](https://github.com/jlowin/fastmcp/pull/789) * Add tutorials by [@jlowin](https://github.com/jlowin) in [#790](https://github.com/jlowin/fastmcp/pull/790) * Add docs for tag-based filtering by [@jlowin](https://github.com/jlowin) in [#793](https://github.com/jlowin/fastmcp/pull/793) ### Other Changes 🦾 * Create dependabot.yml by [@jlowin](https://github.com/jlowin) in [#759](https://github.com/jlowin/fastmcp/pull/759) * Bump astral-sh/setup-uv from 3 to 6 by [@dependabot](https://github.com/dependabot) in [#760](https://github.com/jlowin/fastmcp/pull/760) * Add dependencies section to release by [@jlowin](https://github.com/jlowin) in [#761](https://github.com/jlowin/fastmcp/pull/761) * Remove extra imports for MCPConfig by [@Maanas-Verma](https://github.com/Maanas-Verma) in [#763](https://github.com/jlowin/fastmcp/pull/763) * Split out enhancements in release notes by [@jlowin](https://github.com/jlowin) in [#764](https://github.com/jlowin/fastmcp/pull/764) ## New Contributors * [@dependabot](https://github.com/dependabot) made their first contribution in [#760](https://github.com/jlowin/fastmcp/pull/760) * [@Maanas-Verma](https://github.com/Maanas-Verma) made their first contribution in [#763](https://github.com/jlowin/fastmcp/pull/763) * [@JeremyCraigMartinez](https://github.com/JeremyCraigMartinez) made their first contribution in [#787](https://github.com/jlowin/fastmcp/pull/787) **Full Changelog**: [v2.7.1...v2.8.0](https://github.com/jlowin/fastmcp/compare/v2.7.1...v2.8.0) ## [v2.7.1: The Bearer Necessities](https://github.com/jlowin/fastmcp/releases/tag/v2.7.1) This release primarily contains a fix for parsing string tokens that are provided to FastMCP clients. ### New Features πŸŽ‰ * Respect cache setting, set default to 1 second by [@jlowin](https://github.com/jlowin) in [#747](https://github.com/jlowin/fastmcp/pull/747) ### Fixes 🐞 * Ensure event store is properly typed by [@jlowin](https://github.com/jlowin) in [#753](https://github.com/jlowin/fastmcp/pull/753) * Fix passing token string to client auth & add auth to MCPConfig clients by [@jlowin](https://github.com/jlowin) in [#754](https://github.com/jlowin/fastmcp/pull/754) ### Docs πŸ“š * Docs : fix client to mcp\_client in Gemini example by [@yrangana](https://github.com/yrangana) in [#734](https://github.com/jlowin/fastmcp/pull/734) * update add tool docstring by [@strawgate](https://github.com/strawgate) in [#739](https://github.com/jlowin/fastmcp/pull/739) * Fix contrib link by [@richardkmichael](https://github.com/richardkmichael) in [#749](https://github.com/jlowin/fastmcp/pull/749) ### Other Changes 🦾 * Switch Pydantic defaults to kwargs by [@strawgate](https://github.com/strawgate) in [#731](https://github.com/jlowin/fastmcp/pull/731) * Fix Typo in CLI module by [@wfclark5](https://github.com/wfclark5) in [#737](https://github.com/jlowin/fastmcp/pull/737) * chore: fix prompt docstring by [@danb27](https://github.com/danb27) in [#752](https://github.com/jlowin/fastmcp/pull/752) * Add accept to excluded headers by [@jlowin](https://github.com/jlowin) in [#751](https://github.com/jlowin/fastmcp/pull/751) ### New Contributors * [@wfclark5](https://github.com/wfclark5) made their first contribution in [#737](https://github.com/jlowin/fastmcp/pull/737) * [@richardkmichael](https://github.com/richardkmichael) made their first contribution in [#749](https://github.com/jlowin/fastmcp/pull/749) * [@danb27](https://github.com/danb27) made their first contribution in [#752](https://github.com/jlowin/fastmcp/pull/752) **Full Changelog**: [v2.7.0...v2.7.1](https://github.com/jlowin/fastmcp/compare/v2.7.0...v2.7.1) ## [v2.7.0: Pare Programming](https://github.com/jlowin/fastmcp/releases/tag/v2.7.0) This is primarily a housekeeping release to remove or deprecate cruft that's accumulated since v1. Primarily, this release refactors FastMCP's internals in preparation for features planned in the next few major releases. However please note that as a result, this release has some minor breaking changes (which is why it's 2.7, not 2.6.2, in accordance with repo guidelines) though not to the core user-facing APIs. ### Breaking Changes πŸ›« * decorators return the objects they create, not the decorated function * websockets is an optional dependency * methods on the server for automatically converting functions into tools/resources/prompts have been deprecated in favor of using the decorators directly ### New Features πŸŽ‰ * allow passing flags to servers by [@zzstoatzz](https://github.com/zzstoatzz) in [#690](https://github.com/jlowin/fastmcp/pull/690) * replace $ref pointing to `#/components/schemas/` with `#/$defs/\` by [@phateffect](https://github.com/phateffect) in [#697](https://github.com/jlowin/fastmcp/pull/697) * Split Tool into Tool and FunctionTool by [@jlowin](https://github.com/jlowin) in [#700](https://github.com/jlowin/fastmcp/pull/700) * Use strict basemodel for Prompt; relax from\_function deprecation by [@jlowin](https://github.com/jlowin) in [#701](https://github.com/jlowin/fastmcp/pull/701) * Formalize resource/functionresource replationship by [@jlowin](https://github.com/jlowin) in [#702](https://github.com/jlowin/fastmcp/pull/702) * Formalize template/functiontemplate split by [@jlowin](https://github.com/jlowin) in [#703](https://github.com/jlowin/fastmcp/pull/703) * Support flexible @tool decorator call patterns by [@jlowin](https://github.com/jlowin) in [#706](https://github.com/jlowin/fastmcp/pull/706) * Ensure deprecation warnings have stacklevel=2 by [@jlowin](https://github.com/jlowin) in [#710](https://github.com/jlowin/fastmcp/pull/710) * Allow naked prompt decorator by [@jlowin](https://github.com/jlowin) in [#711](https://github.com/jlowin/fastmcp/pull/711) ### Fixes 🐞 * Updates / Fixes for Tool Content Conversion by [@strawgate](https://github.com/strawgate) in [#642](https://github.com/jlowin/fastmcp/pull/642) * Fix pr labeler permissions by [@jlowin](https://github.com/jlowin) in [#708](https://github.com/jlowin/fastmcp/pull/708) * remove -n auto by [@jlowin](https://github.com/jlowin) in [#709](https://github.com/jlowin/fastmcp/pull/709) * Fix links in README.md by [@alainivars](https://github.com/alainivars) in [#723](https://github.com/jlowin/fastmcp/pull/723) Happily, this release DOES permit the use of "naked" decorators to align with Pythonic practice: ```python @mcp.tool def my_tool(): ... ``` **Full Changelog**: [v2.6.2...v2.7.0](https://github.com/jlowin/fastmcp/compare/v2.6.2...v2.7.0) ## [v2.6.1: Blast Auth (second ignition)](https://github.com/jlowin/fastmcp/releases/tag/v2.6.1) This is a patch release to restore py.typed in #686. ### Docs πŸ“š * Update readme by [@jlowin](https://github.com/jlowin) in [#679](https://github.com/jlowin/fastmcp/pull/679) * Add gemini tutorial by [@jlowin](https://github.com/jlowin) in [#680](https://github.com/jlowin/fastmcp/pull/680) * Fix : fix path error to CLI Documentation by [@yrangana](https://github.com/yrangana) in [#684](https://github.com/jlowin/fastmcp/pull/684) * Update auth docs by [@jlowin](https://github.com/jlowin) in [#687](https://github.com/jlowin/fastmcp/pull/687) ### Other Changes 🦾 * Remove deprecation notice by [@jlowin](https://github.com/jlowin) in [#677](https://github.com/jlowin/fastmcp/pull/677) * Delete server.py by [@jlowin](https://github.com/jlowin) in [#681](https://github.com/jlowin/fastmcp/pull/681) * Restore py.typed by [@jlowin](https://github.com/jlowin) in [#686](https://github.com/jlowin/fastmcp/pull/686) ### New Contributors * [@yrangana](https://github.com/yrangana) made their first contribution in [#684](https://github.com/jlowin/fastmcp/pull/684) **Full Changelog**: [v2.6.0...v2.6.1](https://github.com/jlowin/fastmcp/compare/v2.6.0...v2.6.1) ## [v2.6.0: Blast Auth](https://github.com/jlowin/fastmcp/releases/tag/v2.6.0) ### New Features πŸŽ‰ * Introduce MCP client oauth flow by [@jlowin](https://github.com/jlowin) in [#478](https://github.com/jlowin/fastmcp/pull/478) * Support providing tools at init by [@jlowin](https://github.com/jlowin) in [#647](https://github.com/jlowin/fastmcp/pull/647) * Simplify code for running servers in processes during tests by [@jlowin](https://github.com/jlowin) in [#649](https://github.com/jlowin/fastmcp/pull/649) * Add basic bearer auth for server and client by [@jlowin](https://github.com/jlowin) in [#650](https://github.com/jlowin/fastmcp/pull/650) * Support configuring bearer auth from env vars by [@jlowin](https://github.com/jlowin) in [#652](https://github.com/jlowin/fastmcp/pull/652) * feat(tool): add support for excluding arguments from tool definition by [@deepak-stratforge](https://github.com/deepak-stratforge) in [#626](https://github.com/jlowin/fastmcp/pull/626) * Add docs for server + client auth by [@jlowin](https://github.com/jlowin) in [#655](https://github.com/jlowin/fastmcp/pull/655) ### Fixes 🐞 * fix: Support concurrency in FastMcpProxy (and Client) by [@Sillocan](https://github.com/Sillocan) in [#635](https://github.com/jlowin/fastmcp/pull/635) * Ensure Client.close() cleans up client context appropriately by [@jlowin](https://github.com/jlowin) in [#643](https://github.com/jlowin/fastmcp/pull/643) * Update client.mdx: ClientError namespace by [@mjkaye](https://github.com/mjkaye) in [#657](https://github.com/jlowin/fastmcp/pull/657) ### Docs πŸ“š * Make FastMCPTransport support simulated Streamable HTTP Transport (didn't work) by [@jlowin](https://github.com/jlowin) in [#645](https://github.com/jlowin/fastmcp/pull/645) * Document exclude\_args by [@jlowin](https://github.com/jlowin) in [#653](https://github.com/jlowin/fastmcp/pull/653) * Update welcome by [@jlowin](https://github.com/jlowin) in [#673](https://github.com/jlowin/fastmcp/pull/673) * Add Anthropic + Claude desktop integration guides by [@jlowin](https://github.com/jlowin) in [#674](https://github.com/jlowin/fastmcp/pull/674) * Minor docs design updates by [@jlowin](https://github.com/jlowin) in [#676](https://github.com/jlowin/fastmcp/pull/676) ### Other Changes 🦾 * Update test typing by [@jlowin](https://github.com/jlowin) in [#646](https://github.com/jlowin/fastmcp/pull/646) * Add OpenAI integration docs by [@jlowin](https://github.com/jlowin) in [#660](https://github.com/jlowin/fastmcp/pull/660) ### New Contributors * [@Sillocan](https://github.com/Sillocan) made their first contribution in [#635](https://github.com/jlowin/fastmcp/pull/635) * [@deepak-stratforge](https://github.com/deepak-stratforge) made their first contribution in [#626](https://github.com/jlowin/fastmcp/pull/626) * [@mjkaye](https://github.com/mjkaye) made their first contribution in [#657](https://github.com/jlowin/fastmcp/pull/657) **Full Changelog**: [v2.5.2...v2.6.0](https://github.com/jlowin/fastmcp/compare/v2.5.2...v2.6.0) ## [v2.5.2: Stayin' Alive](https://github.com/jlowin/fastmcp/releases/tag/v2.5.2) ### New Features πŸŽ‰ * Add graceful error handling for unreachable mounted servers by [@davenpi](https://github.com/davenpi) in [#605](https://github.com/jlowin/fastmcp/pull/605) * Improve type inference from client transport by [@jlowin](https://github.com/jlowin) in [#623](https://github.com/jlowin/fastmcp/pull/623) * Add keep\_alive param to reuse subprocess by [@jlowin](https://github.com/jlowin) in [#624](https://github.com/jlowin/fastmcp/pull/624) ### Fixes 🐞 * Fix handling tools without descriptions by [@jlowin](https://github.com/jlowin) in [#610](https://github.com/jlowin/fastmcp/pull/610) * Don't print env vars to console when format is wrong by [@jlowin](https://github.com/jlowin) in [#615](https://github.com/jlowin/fastmcp/pull/615) * Ensure behavior-affecting headers are excluded when forwarding proxies/openapi by [@jlowin](https://github.com/jlowin) in [#620](https://github.com/jlowin/fastmcp/pull/620) ### Docs πŸ“š * Add notes about uv and claude desktop by [@jlowin](https://github.com/jlowin) in [#597](https://github.com/jlowin/fastmcp/pull/597) ### Other Changes 🦾 * add init\_timeout for mcp client by [@jfouret](https://github.com/jfouret) in [#607](https://github.com/jlowin/fastmcp/pull/607) * Add init\_timeout for mcp client (incl settings) by [@jlowin](https://github.com/jlowin) in [#609](https://github.com/jlowin/fastmcp/pull/609) * Support for uppercase letters at the log level by [@ksawaray](https://github.com/ksawaray) in [#625](https://github.com/jlowin/fastmcp/pull/625) ### New Contributors * [@jfouret](https://github.com/jfouret) made their first contribution in [#607](https://github.com/jlowin/fastmcp/pull/607) * [@ksawaray](https://github.com/ksawaray) made their first contribution in [#625](https://github.com/jlowin/fastmcp/pull/625) **Full Changelog**: [v2.5.1...v2.5.2](https://github.com/jlowin/fastmcp/compare/v2.5.1...v2.5.2) ## [v2.5.1: Route Awakening (Part 2)](https://github.com/jlowin/fastmcp/releases/tag/v2.5.1) ### Fixes 🐞 * Ensure content-length is always stripped from client headers by [@jlowin](https://github.com/jlowin) in [#589](https://github.com/jlowin/fastmcp/pull/589) ### Docs πŸ“š * Fix redundant section of docs by [@jlowin](https://github.com/jlowin) in [#583](https://github.com/jlowin/fastmcp/pull/583) **Full Changelog**: [v2.5.0...v2.5.1](https://github.com/jlowin/fastmcp/compare/v2.5.0...v2.5.1) ## [v2.5.0: Route Awakening](https://github.com/jlowin/fastmcp/releases/tag/v2.5.0) This release introduces completely new tools for generating and customizing MCP servers from OpenAPI specs and FastAPI apps, including popular requests like mechanisms for determining what routes map to what MCP components; renaming routes; and customizing the generated MCP components. ### New Features πŸŽ‰ * Add FastMCP 1.0 server support for in-memory Client / Testing by [@jlowin](https://github.com/jlowin) in [#539](https://github.com/jlowin/fastmcp/pull/539) * Minor addition: add transport to stdio server in mcpconfig, with default by [@jlowin](https://github.com/jlowin) in [#555](https://github.com/jlowin/fastmcp/pull/555) * Raise an error if a Client is created with no servers in config by [@jlowin](https://github.com/jlowin) in [#554](https://github.com/jlowin/fastmcp/pull/554) * Expose model preferences in `Context.sample` for flexible model selection. by [@davenpi](https://github.com/davenpi) in [#542](https://github.com/jlowin/fastmcp/pull/542) * Ensure custom routes are respected by [@jlowin](https://github.com/jlowin) in [#558](https://github.com/jlowin/fastmcp/pull/558) * Add client method to send cancellation notifications by [@davenpi](https://github.com/davenpi) in [#563](https://github.com/jlowin/fastmcp/pull/563) * Enhance route map logic for include/exclude OpenAPI routes by [@jlowin](https://github.com/jlowin) in [#564](https://github.com/jlowin/fastmcp/pull/564) * Add tag-based route maps by [@jlowin](https://github.com/jlowin) in [#565](https://github.com/jlowin/fastmcp/pull/565) * Add advanced control of openAPI route creation by [@jlowin](https://github.com/jlowin) in [#566](https://github.com/jlowin/fastmcp/pull/566) * Make error masking configurable by [@jlowin](https://github.com/jlowin) in [#550](https://github.com/jlowin/fastmcp/pull/550) * Ensure client headers are passed through to remote servers by [@jlowin](https://github.com/jlowin) in [#575](https://github.com/jlowin/fastmcp/pull/575) * Use lowercase name for headers when comparing by [@jlowin](https://github.com/jlowin) in [#576](https://github.com/jlowin/fastmcp/pull/576) * Permit more flexible name generation for OpenAPI servers by [@jlowin](https://github.com/jlowin) in [#578](https://github.com/jlowin/fastmcp/pull/578) * Ensure that tools/templates/prompts are compatible with callable objects by [@jlowin](https://github.com/jlowin) in [#579](https://github.com/jlowin/fastmcp/pull/579) ### Docs πŸ“š * Add version badge for prefix formats by [@jlowin](https://github.com/jlowin) in [#537](https://github.com/jlowin/fastmcp/pull/537) * Add versioning note to docs by [@jlowin](https://github.com/jlowin) in [#551](https://github.com/jlowin/fastmcp/pull/551) * Bump 2.3.6 references to 2.4.0 by [@jlowin](https://github.com/jlowin) in [#567](https://github.com/jlowin/fastmcp/pull/567) **Full Changelog**: [v2.4.0...v2.5.0](https://github.com/jlowin/fastmcp/compare/v2.4.0...v2.5.0) ## [v2.4.0: Config and Conquer](https://github.com/jlowin/fastmcp/releases/tag/v2.4.0) **Note**: this release includes a backwards-incompatible change to how resources are prefixed when mounted in composed servers. However, it is only backwards-incompatible if users were running tests or manually loading resources by prefixed key; LLMs should not have any issue discovering the new route. See [Resource Prefix Formats](https://gofastmcp.com/servers/composition#resource-prefix-formats) for more. ### New Features πŸŽ‰ * Allow \* Methods and all routes as tools shortcuts by [@jlowin](https://github.com/jlowin) in [#520](https://github.com/jlowin/fastmcp/pull/520) * Improved support for config dicts by [@jlowin](https://github.com/jlowin) in [#522](https://github.com/jlowin/fastmcp/pull/522) * Support creating clients from MCP config dicts, including multi-server clients by [@jlowin](https://github.com/jlowin) in [#527](https://github.com/jlowin/fastmcp/pull/527) * Make resource prefix format configurable by [@jlowin](https://github.com/jlowin) in [#534](https://github.com/jlowin/fastmcp/pull/534) ### Fixes 🐞 * Avoid hanging on initializing server session by [@jlowin](https://github.com/jlowin) in [#523](https://github.com/jlowin/fastmcp/pull/523) ### Breaking Changes πŸ›« * Remove customizable separators; improve resource separator by [@jlowin](https://github.com/jlowin) in [#526](https://github.com/jlowin/fastmcp/pull/526) ### Docs πŸ“š * Improve client documentation by [@jlowin](https://github.com/jlowin) in [#517](https://github.com/jlowin/fastmcp/pull/517) ### Other Changes 🦾 * Ensure openapi path params are handled properly by [@jlowin](https://github.com/jlowin) in [#519](https://github.com/jlowin/fastmcp/pull/519) * better error when missing lifespan by [@zzstoatzz](https://github.com/zzstoatzz) in [#521](https://github.com/jlowin/fastmcp/pull/521) **Full Changelog**: [v2.3.5...v2.4.0](https://github.com/jlowin/fastmcp/compare/v2.3.5...v2.4.0) ## [v2.3.5: Making Progress](https://github.com/jlowin/fastmcp/releases/tag/v2.3.5) ### New Features πŸŽ‰ * support messages in progress notifications by [@rickygenhealth](https://github.com/rickygenhealth) in [#471](https://github.com/jlowin/fastmcp/pull/471) * feat: Add middleware option in server.run by [@Maxi91f](https://github.com/Maxi91f) in [#475](https://github.com/jlowin/fastmcp/pull/475) * Add lifespan property to app by [@jlowin](https://github.com/jlowin) in [#483](https://github.com/jlowin/fastmcp/pull/483) * Update `fastmcp run` to work with remote servers by [@jlowin](https://github.com/jlowin) in [#491](https://github.com/jlowin/fastmcp/pull/491) * Add FastMCP.as\_proxy() by [@jlowin](https://github.com/jlowin) in [#490](https://github.com/jlowin/fastmcp/pull/490) * Infer sse transport from urls containing /sse by [@jlowin](https://github.com/jlowin) in [#512](https://github.com/jlowin/fastmcp/pull/512) * Add progress handler to client by [@jlowin](https://github.com/jlowin) in [#513](https://github.com/jlowin/fastmcp/pull/513) * Store the initialize result on the client by [@jlowin](https://github.com/jlowin) in [#509](https://github.com/jlowin/fastmcp/pull/509) ### Fixes 🐞 * Remove patch and use upstream SSEServerTransport by [@jlowin](https://github.com/jlowin) in [#425](https://github.com/jlowin/fastmcp/pull/425) ### Docs πŸ“š * Update transport docs by [@jlowin](https://github.com/jlowin) in [#458](https://github.com/jlowin/fastmcp/pull/458) * update proxy docs + example by [@zzstoatzz](https://github.com/zzstoatzz) in [#460](https://github.com/jlowin/fastmcp/pull/460) * doc(asgi): Change custom route example to PlainTextResponse by [@mcw0933](https://github.com/mcw0933) in [#477](https://github.com/jlowin/fastmcp/pull/477) * Store FastMCP instance on app.state.fastmcp\_server by [@jlowin](https://github.com/jlowin) in [#489](https://github.com/jlowin/fastmcp/pull/489) * Improve AGENTS.md overview by [@jlowin](https://github.com/jlowin) in [#492](https://github.com/jlowin/fastmcp/pull/492) * Update release numbers for anticipated version by [@jlowin](https://github.com/jlowin) in [#516](https://github.com/jlowin/fastmcp/pull/516) ### Other Changes 🦾 * run tests on all PRs by [@jlowin](https://github.com/jlowin) in [#468](https://github.com/jlowin/fastmcp/pull/468) * add null check by [@zzstoatzz](https://github.com/zzstoatzz) in [#473](https://github.com/jlowin/fastmcp/pull/473) * strict typing for `server.py` by [@zzstoatzz](https://github.com/zzstoatzz) in [#476](https://github.com/jlowin/fastmcp/pull/476) * Doc(quickstart): Fix import statements by [@mai-nakagawa](https://github.com/mai-nakagawa) in [#479](https://github.com/jlowin/fastmcp/pull/479) * Add labeler by [@jlowin](https://github.com/jlowin) in [#484](https://github.com/jlowin/fastmcp/pull/484) * Fix flaky timeout test by increasing timeout (#474) by [@davenpi](https://github.com/davenpi) in [#486](https://github.com/jlowin/fastmcp/pull/486) * Skipping `test_permission_error` if runner is root. by [@ZiadAmerr](https://github.com/ZiadAmerr) in [#502](https://github.com/jlowin/fastmcp/pull/502) * allow passing full uvicorn config by [@zzstoatzz](https://github.com/zzstoatzz) in [#504](https://github.com/jlowin/fastmcp/pull/504) * Skip timeout tests on windows by [@jlowin](https://github.com/jlowin) in [#514](https://github.com/jlowin/fastmcp/pull/514) ### New Contributors * [@rickygenhealth](https://github.com/rickygenhealth) made their first contribution in [#471](https://github.com/jlowin/fastmcp/pull/471) * [@Maxi91f](https://github.com/Maxi91f) made their first contribution in [#475](https://github.com/jlowin/fastmcp/pull/475) * [@mcw0933](https://github.com/mcw0933) made their first contribution in [#477](https://github.com/jlowin/fastmcp/pull/477) * [@mai-nakagawa](https://github.com/mai-nakagawa) made their first contribution in [#479](https://github.com/jlowin/fastmcp/pull/479) * [@ZiadAmerr](https://github.com/ZiadAmerr) made their first contribution in [#502](https://github.com/jlowin/fastmcp/pull/502) **Full Changelog**: [v2.3.4...v2.3.5](https://github.com/jlowin/fastmcp/compare/v2.3.4...v2.3.5) ## [v2.3.4: Error Today, Gone Tomorrow](https://github.com/jlowin/fastmcp/releases/tag/v2.3.4) ### New Features πŸŽ‰ * logging stack trace for easier debugging by [@jbkoh](https://github.com/jbkoh) in [#413](https://github.com/jlowin/fastmcp/pull/413) * add missing StreamableHttpTransport in client exports by [@yihuang](https://github.com/yihuang) in [#408](https://github.com/jlowin/fastmcp/pull/408) * Improve error handling for tools and resources by [@jlowin](https://github.com/jlowin) in [#434](https://github.com/jlowin/fastmcp/pull/434) * feat: add support for removing tools from server by [@davenpi](https://github.com/davenpi) in [#437](https://github.com/jlowin/fastmcp/pull/437) * Prune titles from JSONSchemas by [@jlowin](https://github.com/jlowin) in [#449](https://github.com/jlowin/fastmcp/pull/449) * Declare toolsChanged capability for stdio server. by [@davenpi](https://github.com/davenpi) in [#450](https://github.com/jlowin/fastmcp/pull/450) * Improve handling of exceptiongroups when raised in clients by [@jlowin](https://github.com/jlowin) in [#452](https://github.com/jlowin/fastmcp/pull/452) * Add timeout support to client by [@jlowin](https://github.com/jlowin) in [#455](https://github.com/jlowin/fastmcp/pull/455) ### Fixes 🐞 * Pin to mcp 1.8.1 to resolve callback deadlocks with SHTTP by [@jlowin](https://github.com/jlowin) in [#427](https://github.com/jlowin/fastmcp/pull/427) * Add reprs for OpenAPI objects by [@jlowin](https://github.com/jlowin) in [#447](https://github.com/jlowin/fastmcp/pull/447) * Ensure openapi defs for structured objects are loaded properly by [@jlowin](https://github.com/jlowin) in [#448](https://github.com/jlowin/fastmcp/pull/448) * Ensure tests run against correct python version by [@jlowin](https://github.com/jlowin) in [#454](https://github.com/jlowin/fastmcp/pull/454) * Ensure result is only returned if a new key was found by [@jlowin](https://github.com/jlowin) in [#456](https://github.com/jlowin/fastmcp/pull/456) ### Docs πŸ“š * Add documentation for tool removal by [@jlowin](https://github.com/jlowin) in [#440](https://github.com/jlowin/fastmcp/pull/440) ### Other Changes 🦾 * Deprecate passing settings to the FastMCP instance by [@jlowin](https://github.com/jlowin) in [#424](https://github.com/jlowin/fastmcp/pull/424) * Add path prefix to test by [@jlowin](https://github.com/jlowin) in [#432](https://github.com/jlowin/fastmcp/pull/432) ### New Contributors * [@jbkoh](https://github.com/jbkoh) made their first contribution in [#413](https://github.com/jlowin/fastmcp/pull/413) * [@davenpi](https://github.com/davenpi) made their first contribution in [#437](https://github.com/jlowin/fastmcp/pull/437) **Full Changelog**: [v2.3.3...v2.3.4](https://github.com/jlowin/fastmcp/compare/v2.3.3...v2.3.4) ## [v2.3.3: SSE you later](https://github.com/jlowin/fastmcp/releases/tag/v2.3.3) This is a hotfix for a bug introduced in 2.3.2 that broke SSE servers ### Fixes 🐞 * Fix bug that sets message path and sse path to same value by [@jlowin](https://github.com/jlowin) in [#405](https://github.com/jlowin/fastmcp/pull/405) ### Docs πŸ“š * Update composition docs by [@jlowin](https://github.com/jlowin) in [#403](https://github.com/jlowin/fastmcp/pull/403) ### Other Changes 🦾 * Add test for no prefix when importing by [@jlowin](https://github.com/jlowin) in [#404](https://github.com/jlowin/fastmcp/pull/404) **Full Changelog**: [v2.3.2...v2.3.3](https://github.com/jlowin/fastmcp/compare/v2.3.2...v2.3.3) ## [v2.3.2: Stuck in the Middleware With You](https://github.com/jlowin/fastmcp/releases/tag/v2.3.2) ### New Features πŸŽ‰ * Allow users to pass middleware to starlette app constructors by [@jlowin](https://github.com/jlowin) in [#398](https://github.com/jlowin/fastmcp/pull/398) * Deprecate transport-specific methods on FastMCP server by [@jlowin](https://github.com/jlowin) in [#401](https://github.com/jlowin/fastmcp/pull/401) ### Docs πŸ“š * Update CLI docs by [@jlowin](https://github.com/jlowin) in [#402](https://github.com/jlowin/fastmcp/pull/402) ### Other Changes 🦾 * Adding 23 tests for CLI by [@didier-durand](https://github.com/didier-durand) in [#394](https://github.com/jlowin/fastmcp/pull/394) **Full Changelog**: [v2.3.1...v2.3.2](https://github.com/jlowin/fastmcp/compare/v2.3.1...v2.3.2) ## [v2.3.1: For Good-nests Sake](https://github.com/jlowin/fastmcp/releases/tag/v2.3.1) This release primarily patches a long-standing bug with nested ASGI SSE servers. ### Fixes 🐞 * Fix tool result serialization when the tool returns a list by [@strawgate](https://github.com/strawgate) in [#379](https://github.com/jlowin/fastmcp/pull/379) * Ensure FastMCP handles nested SSE and SHTTP apps properly in ASGI frameworks by [@jlowin](https://github.com/jlowin) in [#390](https://github.com/jlowin/fastmcp/pull/390) ### Docs πŸ“š * Update transport docs by [@jlowin](https://github.com/jlowin) in [#377](https://github.com/jlowin/fastmcp/pull/377) * Add llms.txt to docs by [@jlowin](https://github.com/jlowin) in [#384](https://github.com/jlowin/fastmcp/pull/384) * Fixing various text typos by [@didier-durand](https://github.com/didier-durand) in [#385](https://github.com/jlowin/fastmcp/pull/385) ### Other Changes 🦾 * Adding a few tests to Image type by [@didier-durand](https://github.com/didier-durand) in [#387](https://github.com/jlowin/fastmcp/pull/387) * Adding tests for TimedCache by [@didier-durand](https://github.com/didier-durand) in [#388](https://github.com/jlowin/fastmcp/pull/388) ### New Contributors * [@didier-durand](https://github.com/didier-durand) made their first contribution in [#385](https://github.com/jlowin/fastmcp/pull/385) **Full Changelog**: [v2.3.0...v2.3.1](https://github.com/jlowin/fastmcp/compare/v2.3.0...v2.3.1) ## [v2.3.0: Stream Me Up, Scotty](https://github.com/jlowin/fastmcp/releases/tag/v2.3.0) ### New Features πŸŽ‰ * Add streaming support for HTTP transport by [@jlowin](https://github.com/jlowin) in [#365](https://github.com/jlowin/fastmcp/pull/365) * Support streaming HTTP transport in clients by [@jlowin](https://github.com/jlowin) in [#366](https://github.com/jlowin/fastmcp/pull/366) * Add streaming support to CLI by [@jlowin](https://github.com/jlowin) in [#367](https://github.com/jlowin/fastmcp/pull/367) ### Fixes 🐞 * Fix streaming transport initialization by [@jlowin](https://github.com/jlowin) in [#368](https://github.com/jlowin/fastmcp/pull/368) ### Docs πŸ“š * Update transport documentation for streaming support by [@jlowin](https://github.com/jlowin) in [#369](https://github.com/jlowin/fastmcp/pull/369) **Full Changelog**: [v2.2.10...v2.3.0](https://github.com/jlowin/fastmcp/compare/v2.2.10...v2.3.0) ## [v2.2.10: That's JSON Bourne](https://github.com/jlowin/fastmcp/releases/tag/v2.2.10) ### Fixes 🐞 * Disable automatic JSON parsing of tool args by [@jlowin](https://github.com/jlowin) in [#341](https://github.com/jlowin/fastmcp/pull/341) * Fix prompt test by [@jlowin](https://github.com/jlowin) in [#342](https://github.com/jlowin/fastmcp/pull/342) ### Other Changes 🦾 * Update docs.json by [@jlowin](https://github.com/jlowin) in [#338](https://github.com/jlowin/fastmcp/pull/338) * Add test coverage + tests on 4 examples by [@alainivars](https://github.com/alainivars) in [#306](https://github.com/jlowin/fastmcp/pull/306) ### New Contributors * [@alainivars](https://github.com/alainivars) made their first contribution in [#306](https://github.com/jlowin/fastmcp/pull/306) **Full Changelog**: [v2.2.9...v2.2.10](https://github.com/jlowin/fastmcp/compare/v2.2.9...v2.2.10) ## [v2.2.9: Str-ing the Pot (Hotfix)](https://github.com/jlowin/fastmcp/releases/tag/v2.2.9) This release is a hotfix for the issue detailed in #330 ### Fixes 🐞 * Prevent invalid resource URIs by [@jlowin](https://github.com/jlowin) in [#336](https://github.com/jlowin/fastmcp/pull/336) * Coerce numbers to str by [@jlowin](https://github.com/jlowin) in [#337](https://github.com/jlowin/fastmcp/pull/337) ### Docs πŸ“š * Add client badge by [@jlowin](https://github.com/jlowin) in [#327](https://github.com/jlowin/fastmcp/pull/327) * Update bug.yml by [@jlowin](https://github.com/jlowin) in [#328](https://github.com/jlowin/fastmcp/pull/328) ### Other Changes 🦾 * Update quickstart.mdx example to include import by [@discdiver](https://github.com/discdiver) in [#329](https://github.com/jlowin/fastmcp/pull/329) ### New Contributors * [@discdiver](https://github.com/discdiver) made their first contribution in [#329](https://github.com/jlowin/fastmcp/pull/329) **Full Changelog**: [v2.2.8...v2.2.9](https://github.com/jlowin/fastmcp/compare/v2.2.8...v2.2.9) ## [v2.2.8: Parse and Recreation](https://github.com/jlowin/fastmcp/releases/tag/v2.2.8) ### New Features πŸŽ‰ * Replace custom parsing with TypeAdapter by [@jlowin](https://github.com/jlowin) in [#314](https://github.com/jlowin/fastmcp/pull/314) * Handle \*args/\*\*kwargs appropriately for various components by [@jlowin](https://github.com/jlowin) in [#317](https://github.com/jlowin/fastmcp/pull/317) * Add timeout-graceful-shutdown as a default config for SSE app by [@jlowin](https://github.com/jlowin) in [#323](https://github.com/jlowin/fastmcp/pull/323) * Ensure prompts return descriptions by [@jlowin](https://github.com/jlowin) in [#325](https://github.com/jlowin/fastmcp/pull/325) ### Fixes 🐞 * Ensure that tool serialization has a graceful fallback by [@jlowin](https://github.com/jlowin) in [#310](https://github.com/jlowin/fastmcp/pull/310) ### Docs πŸ“š * Update docs for clarity by [@jlowin](https://github.com/jlowin) in [#312](https://github.com/jlowin/fastmcp/pull/312) ### Other Changes 🦾 * Remove is\_async attribute by [@jlowin](https://github.com/jlowin) in [#315](https://github.com/jlowin/fastmcp/pull/315) * Dry out retrieving context kwarg by [@jlowin](https://github.com/jlowin) in [#316](https://github.com/jlowin/fastmcp/pull/316) **Full Changelog**: [v2.2.7...v2.2.8](https://github.com/jlowin/fastmcp/compare/v2.2.7...v2.2.8) ## [v2.2.7: You Auth to Know Better](https://github.com/jlowin/fastmcp/releases/tag/v2.2.7) ### New Features πŸŽ‰ * use pydantic\_core.to\_json by [@jlowin](https://github.com/jlowin) in [#290](https://github.com/jlowin/fastmcp/pull/290) * Ensure openapi descriptions are included in tool details by [@jlowin](https://github.com/jlowin) in [#293](https://github.com/jlowin/fastmcp/pull/293) * Bump mcp to 1.7.1 by [@jlowin](https://github.com/jlowin) in [#298](https://github.com/jlowin/fastmcp/pull/298) * Add support for tool annotations by [@jlowin](https://github.com/jlowin) in [#299](https://github.com/jlowin/fastmcp/pull/299) * Add auth support by [@jlowin](https://github.com/jlowin) in [#300](https://github.com/jlowin/fastmcp/pull/300) * Add low-level methods to client by [@jlowin](https://github.com/jlowin) in [#301](https://github.com/jlowin/fastmcp/pull/301) * Add method for retrieving current starlette request to FastMCP context by [@jlowin](https://github.com/jlowin) in [#302](https://github.com/jlowin/fastmcp/pull/302) * get\_starlette\_request β†’ get\_http\_request by [@jlowin](https://github.com/jlowin) in [#303](https://github.com/jlowin/fastmcp/pull/303) * Support custom Serializer for Tools by [@strawgate](https://github.com/strawgate) in [#308](https://github.com/jlowin/fastmcp/pull/308) * Support proxy mount by [@jlowin](https://github.com/jlowin) in [#309](https://github.com/jlowin/fastmcp/pull/309) ### Other Changes 🦾 * Improve context injection type checks by [@jlowin](https://github.com/jlowin) in [#291](https://github.com/jlowin/fastmcp/pull/291) * add readme to smarthome example by [@zzstoatzz](https://github.com/zzstoatzz) in [#294](https://github.com/jlowin/fastmcp/pull/294) **Full Changelog**: [v2.2.6...v2.2.7](https://github.com/jlowin/fastmcp/compare/v2.2.6...v2.2.7) ## [v2.2.6: The REST is History](https://github.com/jlowin/fastmcp/releases/tag/v2.2.6) ### New Features πŸŽ‰ * Added feature : Load MCP server using config by [@sandipan1](https://github.com/sandipan1) in [#260](https://github.com/jlowin/fastmcp/pull/260) * small typing fixes by [@zzstoatzz](https://github.com/zzstoatzz) in [#237](https://github.com/jlowin/fastmcp/pull/237) * Expose configurable timeout for OpenAPI by [@jlowin](https://github.com/jlowin) in [#279](https://github.com/jlowin/fastmcp/pull/279) * Lower websockets pin for compatibility by [@jlowin](https://github.com/jlowin) in [#286](https://github.com/jlowin/fastmcp/pull/286) * Improve OpenAPI param handling by [@jlowin](https://github.com/jlowin) in [#287](https://github.com/jlowin/fastmcp/pull/287) ### Fixes 🐞 * Ensure openapi tool responses are properly converted by [@jlowin](https://github.com/jlowin) in [#283](https://github.com/jlowin/fastmcp/pull/283) * Fix OpenAPI examples by [@jlowin](https://github.com/jlowin) in [#285](https://github.com/jlowin/fastmcp/pull/285) * Fix client docs for advanced features, add tests for logging by [@jlowin](https://github.com/jlowin) in [#284](https://github.com/jlowin/fastmcp/pull/284) ### Other Changes 🦾 * add testing doc by [@jlowin](https://github.com/jlowin) in [#264](https://github.com/jlowin/fastmcp/pull/264) * \#267 Fix openapi template resource to support multiple path parameters by [@jeger-at](https://github.com/jeger-at) in [#278](https://github.com/jlowin/fastmcp/pull/278) ### New Contributors * [@sandipan1](https://github.com/sandipan1) made their first contribution in [#260](https://github.com/jlowin/fastmcp/pull/260) * [@jeger-at](https://github.com/jeger-at) made their first contribution in [#278](https://github.com/jlowin/fastmcp/pull/278) **Full Changelog**: [v2.2.5...v2.2.6](https://github.com/jlowin/fastmcp/compare/v2.2.5...v2.2.6) ## [v2.2.5: Context Switching](https://github.com/jlowin/fastmcp/releases/tag/v2.2.5) ### New Features πŸŽ‰ * Add tests for tool return types; improve serialization behavior by [@jlowin](https://github.com/jlowin) in [#262](https://github.com/jlowin/fastmcp/pull/262) * Support context injection in resources, templates, and prompts (like tools) by [@jlowin](https://github.com/jlowin) in [#263](https://github.com/jlowin/fastmcp/pull/263) ### Docs πŸ“š * Update wildcards to 2.2.4 by [@jlowin](https://github.com/jlowin) in [#257](https://github.com/jlowin/fastmcp/pull/257) * Update note in templates docs by [@jlowin](https://github.com/jlowin) in [#258](https://github.com/jlowin/fastmcp/pull/258) * Significant documentation and test expansion for tool input types by [@jlowin](https://github.com/jlowin) in [#261](https://github.com/jlowin/fastmcp/pull/261) **Full Changelog**: [v2.2.4...v2.2.5](https://github.com/jlowin/fastmcp/compare/v2.2.4...v2.2.5) ## [v2.2.4: The Wild Side, Actually](https://github.com/jlowin/fastmcp/releases/tag/v2.2.4) The wildcard URI templates exposed in v2.2.3 were blocked by a server-level check which is removed in this release. ### New Features πŸŽ‰ * Allow customization of inspector proxy port, ui port, and version by [@jlowin](https://github.com/jlowin) in [#253](https://github.com/jlowin/fastmcp/pull/253) ### Fixes 🐞 * fix: unintended type convert by [@cutekibry](https://github.com/cutekibry) in [#252](https://github.com/jlowin/fastmcp/pull/252) * Ensure openapi resources return valid responses by [@jlowin](https://github.com/jlowin) in [#254](https://github.com/jlowin/fastmcp/pull/254) * Ensure servers expose template wildcards by [@jlowin](https://github.com/jlowin) in [#256](https://github.com/jlowin/fastmcp/pull/256) ### Docs πŸ“š * Update README.md Grammar error by [@TechWithTy](https://github.com/TechWithTy) in [#249](https://github.com/jlowin/fastmcp/pull/249) ### Other Changes 🦾 * Add resource template tests by [@jlowin](https://github.com/jlowin) in [#255](https://github.com/jlowin/fastmcp/pull/255) ### New Contributors * [@TechWithTy](https://github.com/TechWithTy) made their first contribution in [#249](https://github.com/jlowin/fastmcp/pull/249) * [@cutekibry](https://github.com/cutekibry) made their first contribution in [#252](https://github.com/jlowin/fastmcp/pull/252) **Full Changelog**: [v2.2.3...v2.2.4](https://github.com/jlowin/fastmcp/compare/v2.2.3...v2.2.4) ## [v2.2.3: The Wild Side](https://github.com/jlowin/fastmcp/releases/tag/v2.2.3) ### New Features πŸŽ‰ * Add wildcard params for resource templates by [@jlowin](https://github.com/jlowin) in [#246](https://github.com/jlowin/fastmcp/pull/246) ### Docs πŸ“š * Indicate that Image class is for returns by [@jlowin](https://github.com/jlowin) in [#242](https://github.com/jlowin/fastmcp/pull/242) * Update mermaid diagram by [@jlowin](https://github.com/jlowin) in [#243](https://github.com/jlowin/fastmcp/pull/243) ### Other Changes 🦾 * update version badges by [@jlowin](https://github.com/jlowin) in [#248](https://github.com/jlowin/fastmcp/pull/248) **Full Changelog**: [v2.2.2...v2.2.3](https://github.com/jlowin/fastmcp/compare/v2.2.2...v2.2.3) ## [v2.2.2: Prompt and Circumstance](https://github.com/jlowin/fastmcp/releases/tag/v2.2.2) ### New Features πŸŽ‰ * Add prompt support by [@jlowin](https://github.com/jlowin) in [#235](https://github.com/jlowin/fastmcp/pull/235) ### Fixes 🐞 * Ensure that resource templates are properly exposed by [@jlowin](https://github.com/jlowin) in [#238](https://github.com/jlowin/fastmcp/pull/238) ### Docs πŸ“š * Update docs for prompts by [@jlowin](https://github.com/jlowin) in [#236](https://github.com/jlowin/fastmcp/pull/236) ### Other Changes 🦾 * Add prompt tests by [@jlowin](https://github.com/jlowin) in [#239](https://github.com/jlowin/fastmcp/pull/239) **Full Changelog**: [v2.2.1...v2.2.2](https://github.com/jlowin/fastmcp/compare/v2.2.1...v2.2.2) ## [v2.2.1: Template for Success](https://github.com/jlowin/fastmcp/releases/tag/v2.2.1) ### New Features πŸŽ‰ * Add resource templates by [@jlowin](https://github.com/jlowin) in [#230](https://github.com/jlowin/fastmcp/pull/230) ### Fixes 🐞 * Ensure that resource templates are properly exposed by [@jlowin](https://github.com/jlowin) in [#231](https://github.com/jlowin/fastmcp/pull/231) ### Docs πŸ“š * Update docs for resource templates by [@jlowin](https://github.com/jlowin) in [#232](https://github.com/jlowin/fastmcp/pull/232) ### Other Changes 🦾 * Add resource template tests by [@jlowin](https://github.com/jlowin) in [#233](https://github.com/jlowin/fastmcp/pull/233) **Full Changelog**: [v2.2.0...v2.2.1](https://github.com/jlowin/fastmcp/compare/v2.2.0...v2.2.1) ## [v2.2.0: Compose Yourself](https://github.com/jlowin/fastmcp/releases/tag/v2.2.0) ### New Features πŸŽ‰ * Add support for mounting FastMCP servers by [@jlowin](https://github.com/jlowin) in [#175](https://github.com/jlowin/fastmcp/pull/175) * Add support for duplicate behavior == ignore by [@jlowin](https://github.com/jlowin) in [#169](https://github.com/jlowin/fastmcp/pull/169) ### Breaking Changes πŸ›« * Refactor MCP composition by [@jlowin](https://github.com/jlowin) in [#176](https://github.com/jlowin/fastmcp/pull/176) ### Docs πŸ“š * Improve integration documentation by [@jlowin](https://github.com/jlowin) in [#184](https://github.com/jlowin/fastmcp/pull/184) * Improve documentation by [@jlowin](https://github.com/jlowin) in [#185](https://github.com/jlowin/fastmcp/pull/185) ### Other Changes 🦾 * Add transport kwargs for mcp.run() and fastmcp run by [@jlowin](https://github.com/jlowin) in [#161](https://github.com/jlowin/fastmcp/pull/161) * Allow resource templates to have optional / excluded arguments by [@jlowin](https://github.com/jlowin) in [#164](https://github.com/jlowin/fastmcp/pull/164) * Update resources.mdx by [@jlowin](https://github.com/jlowin) in [#165](https://github.com/jlowin/fastmcp/pull/165) ### New Contributors * [@kongqi404](https://github.com/kongqi404) made their first contribution in [#181](https://github.com/jlowin/fastmcp/pull/181) **Full Changelog**: [v2.1.2...v2.2.0](https://github.com/jlowin/fastmcp/compare/v2.1.2...v2.2.0) ## [v2.1.2: Copy That, Good Buddy](https://github.com/jlowin/fastmcp/releases/tag/v2.1.2) The main improvement in this release is a fix that allows FastAPI / OpenAPI-generated servers to be mounted as sub-servers. ### Fixes 🐞 * Ensure objects are copied properly and test mounting fastapi by [@jlowin](https://github.com/jlowin) in [#153](https://github.com/jlowin/fastmcp/pull/153) ### Docs πŸ“š * Fix broken links in docs by [@jlowin](https://github.com/jlowin) in [#154](https://github.com/jlowin/fastmcp/pull/154) ### Other Changes 🦾 * Update README.md by [@jlowin](https://github.com/jlowin) in [#149](https://github.com/jlowin/fastmcp/pull/149) * Only apply log config to FastMCP loggers by [@jlowin](https://github.com/jlowin) in [#155](https://github.com/jlowin/fastmcp/pull/155) * Update pyproject.toml by [@jlowin](https://github.com/jlowin) in [#156](https://github.com/jlowin/fastmcp/pull/156) **Full Changelog**: [v2.1.1...v2.1.2](https://github.com/jlowin/fastmcp/compare/v2.1.1...v2.1.2) ## [v2.1.1: Doc Holiday](https://github.com/jlowin/fastmcp/releases/tag/v2.1.1) FastMCP's docs are now available at gofastmcp.com. ### Docs πŸ“š * Add docs by [@jlowin](https://github.com/jlowin) in [#136](https://github.com/jlowin/fastmcp/pull/136) * Add docs link to readme by [@jlowin](https://github.com/jlowin) in [#137](https://github.com/jlowin/fastmcp/pull/137) * Minor docs updates by [@jlowin](https://github.com/jlowin) in [#138](https://github.com/jlowin/fastmcp/pull/138) ### Fixes 🐞 * fix branch name in example by [@zzstoatzz](https://github.com/zzstoatzz) in [#140](https://github.com/jlowin/fastmcp/pull/140) ### Other Changes 🦾 * smart home example by [@zzstoatzz](https://github.com/zzstoatzz) in [#115](https://github.com/jlowin/fastmcp/pull/115) * Remove mac os tests by [@jlowin](https://github.com/jlowin) in [#142](https://github.com/jlowin/fastmcp/pull/142) * Expand support for various method interactions by [@jlowin](https://github.com/jlowin) in [#143](https://github.com/jlowin/fastmcp/pull/143) * Update docs and add\_resource\_fn by [@jlowin](https://github.com/jlowin) in [#144](https://github.com/jlowin/fastmcp/pull/144) * Update description by [@jlowin](https://github.com/jlowin) in [#145](https://github.com/jlowin/fastmcp/pull/145) * Support openapi 3.0 and 3.1 by [@jlowin](https://github.com/jlowin) in [#147](https://github.com/jlowin/fastmcp/pull/147) **Full Changelog**: [v2.1.0...v2.1.1](https://github.com/jlowin/fastmcp/compare/v2.1.0...v2.1.1) ## [v2.1.0: Tag, You're It](https://github.com/jlowin/fastmcp/releases/tag/v2.1.0) The primary motivation for this release is the fix in #128 for Claude desktop compatibility, but the primary new feature of this release is per-object tags. Currently these are for bookkeeping only but will become useful in future releases. ### New Features πŸŽ‰ * Add tags for all core MCP objects by [@jlowin](https://github.com/jlowin) in [#121](https://github.com/jlowin/fastmcp/pull/121) * Ensure that openapi tags are transferred to MCP objects by [@jlowin](https://github.com/jlowin) in [#124](https://github.com/jlowin/fastmcp/pull/124) ### Fixes 🐞 * Change default mounted tool separator from / to \_ by [@jlowin](https://github.com/jlowin) in [#128](https://github.com/jlowin/fastmcp/pull/128) * Enter mounted app lifespans by [@jlowin](https://github.com/jlowin) in [#129](https://github.com/jlowin/fastmcp/pull/129) * Fix CLI that called mcp instead of fastmcp by [@jlowin](https://github.com/jlowin) in [#128](https://github.com/jlowin/fastmcp/pull/128) ### Breaking Changes πŸ›« * Changed configuration for duplicate resources/tools/prompts by [@jlowin](https://github.com/jlowin) in [#121](https://github.com/jlowin/fastmcp/pull/121) * Improve client return types by [@jlowin](https://github.com/jlowin) in [#123](https://github.com/jlowin/fastmcp/pull/123) ### Other Changes 🦾 * Add tests for tags in server decorators by [@jlowin](https://github.com/jlowin) in [#122](https://github.com/jlowin/fastmcp/pull/122) * Clean up server tests by [@jlowin](https://github.com/jlowin) in [#125](https://github.com/jlowin/fastmcp/pull/125) **Full Changelog**: [v2.0.0...v2.1.0](https://github.com/jlowin/fastmcp/compare/v2.0.0...v2.1.0) ## [v2.0.0: Second to None](https://github.com/jlowin/fastmcp/releases/tag/v2.0.0) ### New Features πŸŽ‰ * Support mounting FastMCP instances as sub-MCPs by [@jlowin](https://github.com/jlowin) in [#99](https://github.com/jlowin/fastmcp/pull/99) * Add in-memory client for calling FastMCP servers (and tests) by [@jlowin](https://github.com/jlowin) in [#100](https://github.com/jlowin/fastmcp/pull/100) * Add MCP proxy server by [@jlowin](https://github.com/jlowin) in [#105](https://github.com/jlowin/fastmcp/pull/105) * Update FastMCP for upstream changes by [@jlowin](https://github.com/jlowin) in [#107](https://github.com/jlowin/fastmcp/pull/107) * Generate FastMCP servers from OpenAPI specs and FastAPI by [@jlowin](https://github.com/jlowin) in [#110](https://github.com/jlowin/fastmcp/pull/110) * Reorganize all client / transports by [@jlowin](https://github.com/jlowin) in [#111](https://github.com/jlowin/fastmcp/pull/111) * Add sampling and roots by [@jlowin](https://github.com/jlowin) in [#117](https://github.com/jlowin/fastmcp/pull/117) ### Fixes 🐞 * Fix bug with tools that return lists by [@jlowin](https://github.com/jlowin) in [#116](https://github.com/jlowin/fastmcp/pull/116) ### Other Changes 🦾 * Add back FastMCP CLI by [@jlowin](https://github.com/jlowin) in [#108](https://github.com/jlowin/fastmcp/pull/108) * Update Readme for v2 by [@jlowin](https://github.com/jlowin) in [#112](https://github.com/jlowin/fastmcp/pull/112) * fix deprecation warnings by [@zzstoatzz](https://github.com/zzstoatzz) in [#113](https://github.com/jlowin/fastmcp/pull/113) * Readme by [@jlowin](https://github.com/jlowin) in [#118](https://github.com/jlowin/fastmcp/pull/118) * FastMCP 2.0 by [@jlowin](https://github.com/jlowin) in [#119](https://github.com/jlowin/fastmcp/pull/119) **Full Changelog**: [v1.0...v2.0.0](https://github.com/jlowin/fastmcp/compare/v1.0...v2.0.0) ## [v1.0: It's Official](https://github.com/jlowin/fastmcp/releases/tag/v1.0) This release commemorates FastMCP 1.0, which is included in the official Model Context Protocol SDK: ```python from mcp.server.fastmcp import FastMCP ``` To the best of my knowledge, v1 is identical to the upstream version included with `mcp`. ### Docs πŸ“š * Update readme to redirect to the official SDK by [@jlowin](https://github.com/jlowin) in [#79](https://github.com/jlowin/fastmcp/pull/79) ### Other Changes 🦾 * fix: use Mount instead of Route for SSE message handling by [@samihamine](https://github.com/samihamine) in [#77](https://github.com/jlowin/fastmcp/pull/77) ### New Contributors * [@samihamine](https://github.com/samihamine) made their first contribution in [#77](https://github.com/jlowin/fastmcp/pull/77) **Full Changelog**: [v0.4.1...v1.0](https://github.com/jlowin/fastmcp/compare/v0.4.1...v1.0) ## [v0.4.1: String Theory](https://github.com/jlowin/fastmcp/releases/tag/v0.4.1) ### Fixes 🐞 * fix: handle strings containing numbers correctly by [@sd2k](https://github.com/sd2k) in [#63](https://github.com/jlowin/fastmcp/pull/63) ### Docs πŸ“š * patch: Update pyproject.toml license by [@leonkozlowski](https://github.com/leonkozlowski) in [#67](https://github.com/jlowin/fastmcp/pull/67) ### Other Changes 🦾 * Avoid new try\_eval\_type unavailable with older pydantic by [@jurasofish](https://github.com/jurasofish) in [#57](https://github.com/jlowin/fastmcp/pull/57) * Decorator typing by [@jurasofish](https://github.com/jurasofish) in [#56](https://github.com/jlowin/fastmcp/pull/56) ### New Contributors * [@leonkozlowski](https://github.com/leonkozlowski) made their first contribution in [#67](https://github.com/jlowin/fastmcp/pull/67) **Full Changelog**: [v0.4.0...v0.4.1](https://github.com/jlowin/fastmcp/compare/v0.4.0...v0.4.1) ## [v0.4.0: Nice to MIT You](https://github.com/jlowin/fastmcp/releases/tag/v0.4.0) This is a relatively small release in terms of features, but the version is bumped to 0.4 to reflect that the code is being relicensed from Apache 2.0 to MIT. This is to facilitate FastMCP's inclusion in the official MCP SDK. ### New Features πŸŽ‰ * Add pyright + tests by [@jlowin](https://github.com/jlowin) in [#52](https://github.com/jlowin/fastmcp/pull/52) * add pgvector memory example by [@zzstoatzz](https://github.com/zzstoatzz) in [#49](https://github.com/jlowin/fastmcp/pull/49) ### Fixes 🐞 * fix: use stderr for logging by [@sd2k](https://github.com/sd2k) in [#51](https://github.com/jlowin/fastmcp/pull/51) ### Docs πŸ“š * Update ai-labeler.yml by [@jlowin](https://github.com/jlowin) in [#48](https://github.com/jlowin/fastmcp/pull/48) * Relicense from Apache 2.0 to MIT by [@jlowin](https://github.com/jlowin) in [#54](https://github.com/jlowin/fastmcp/pull/54) ### Other Changes 🦾 * fix warning and flake by [@zzstoatzz](https://github.com/zzstoatzz) in [#47](https://github.com/jlowin/fastmcp/pull/47) ### New Contributors * [@sd2k](https://github.com/sd2k) made their first contribution in [#51](https://github.com/jlowin/fastmcp/pull/51) **Full Changelog**: [v0.3.5...v0.4.0](https://github.com/jlowin/fastmcp/compare/v0.3.5...v0.4.0) ## [v0.3.5: Windows of Opportunity](https://github.com/jlowin/fastmcp/releases/tag/v0.3.5) This release is highlighted by the ability to handle complex JSON objects as MCP inputs and improved Windows compatibility. ### New Features πŸŽ‰ * Set up multiple os tests by [@jlowin](https://github.com/jlowin) in [#44](https://github.com/jlowin/fastmcp/pull/44) * Changes to accomodate windows users. by [@justjoehere](https://github.com/justjoehere) in [#42](https://github.com/jlowin/fastmcp/pull/42) * Handle complex inputs by [@jurasofish](https://github.com/jurasofish) in [#31](https://github.com/jlowin/fastmcp/pull/31) ### Docs πŸ“š * Make AI labeler more conservative by [@jlowin](https://github.com/jlowin) in [#46](https://github.com/jlowin/fastmcp/pull/46) ### Other Changes 🦾 * Additional Windows Fixes for Dev running and for importing modules in a server by [@justjoehere](https://github.com/justjoehere) in [#43](https://github.com/jlowin/fastmcp/pull/43) ### New Contributors * [@justjoehere](https://github.com/justjoehere) made their first contribution in [#42](https://github.com/jlowin/fastmcp/pull/42) * [@jurasofish](https://github.com/jurasofish) made their first contribution in [#31](https://github.com/jlowin/fastmcp/pull/31) **Full Changelog**: [v0.3.4...v0.3.5](https://github.com/jlowin/fastmcp/compare/v0.3.4...v0.3.5) ## [v0.3.4: URL's Well That Ends Well](https://github.com/jlowin/fastmcp/releases/tag/v0.3.4) ### Fixes 🐞 * Handle missing config file when installing by [@jlowin](https://github.com/jlowin) in [#37](https://github.com/jlowin/fastmcp/pull/37) * Remove BaseURL reference and use AnyURL by [@jlowin](https://github.com/jlowin) in [#40](https://github.com/jlowin/fastmcp/pull/40) **Full Changelog**: [v0.3.3...v0.3.4](https://github.com/jlowin/fastmcp/compare/v0.3.3...v0.3.4) ## [v0.3.3: Dependence Day](https://github.com/jlowin/fastmcp/releases/tag/v0.3.3) ### New Features πŸŽ‰ * Surge example by [@zzstoatzz](https://github.com/zzstoatzz) in [#29](https://github.com/jlowin/fastmcp/pull/29) * Support Python dependencies in Server by [@jlowin](https://github.com/jlowin) in [#34](https://github.com/jlowin/fastmcp/pull/34) ### Docs πŸ“š * add `Contributing` section to README by [@zzstoatzz](https://github.com/zzstoatzz) in [#32](https://github.com/jlowin/fastmcp/pull/32) **Full Changelog**: [v0.3.2...v0.3.3](https://github.com/jlowin/fastmcp/compare/v0.3.2...v0.3.3) ## [v0.3.2: Green with ENVy](https://github.com/jlowin/fastmcp/releases/tag/v0.3.2) ### New Features πŸŽ‰ * Support env vars when installing by [@jlowin](https://github.com/jlowin) in [#27](https://github.com/jlowin/fastmcp/pull/27) ### Docs πŸ“š * Remove top level env var by [@jlowin](https://github.com/jlowin) in [#28](https://github.com/jlowin/fastmcp/pull/28) **Full Changelog**: [v0.3.1...v0.3.2](https://github.com/jlowin/fastmcp/compare/v0.3.1...v0.3.2) ## [v0.3.1](https://github.com/jlowin/fastmcp/releases/tag/v0.3.1) ### New Features πŸŽ‰ * Update README.md by [@jlowin](https://github.com/jlowin) in [#23](https://github.com/jlowin/fastmcp/pull/23) * add rich handler and dotenv loading for settings by [@zzstoatzz](https://github.com/zzstoatzz) in [#22](https://github.com/jlowin/fastmcp/pull/22) * print exception when server can't start by [@jlowin](https://github.com/jlowin) in [#25](https://github.com/jlowin/fastmcp/pull/25) ### Docs πŸ“š * Update README.md by [@jlowin](https://github.com/jlowin) in [#24](https://github.com/jlowin/fastmcp/pull/24) ### Other Changes 🦾 * Remove log by [@jlowin](https://github.com/jlowin) in [#26](https://github.com/jlowin/fastmcp/pull/26) **Full Changelog**: [v0.3.0...v0.3.1](https://github.com/jlowin/fastmcp/compare/v0.3.0...v0.3.1) ## [v0.3.0: Prompt and Circumstance](https://github.com/jlowin/fastmcp/releases/tag/v0.3.0) ### New Features πŸŽ‰ * Update README by [@jlowin](https://github.com/jlowin) in [#3](https://github.com/jlowin/fastmcp/pull/3) * Make log levels strings by [@jlowin](https://github.com/jlowin) in [#4](https://github.com/jlowin/fastmcp/pull/4) * Make content method a function by [@jlowin](https://github.com/jlowin) in [#5](https://github.com/jlowin/fastmcp/pull/5) * Add template support by [@jlowin](https://github.com/jlowin) in [#6](https://github.com/jlowin/fastmcp/pull/6) * Refactor resources module by [@jlowin](https://github.com/jlowin) in [#7](https://github.com/jlowin/fastmcp/pull/7) * Clean up cli imports by [@jlowin](https://github.com/jlowin) in [#8](https://github.com/jlowin/fastmcp/pull/8) * Prepare to list templates by [@jlowin](https://github.com/jlowin) in [#11](https://github.com/jlowin/fastmcp/pull/11) * Move image to separate module by [@jlowin](https://github.com/jlowin) in [#9](https://github.com/jlowin/fastmcp/pull/9) * Add support for request context, progress, logging, etc. by [@jlowin](https://github.com/jlowin) in [#12](https://github.com/jlowin/fastmcp/pull/12) * Add context tests and better runtime loads by [@jlowin](https://github.com/jlowin) in [#13](https://github.com/jlowin/fastmcp/pull/13) * Refactor tools + resourcemanager by [@jlowin](https://github.com/jlowin) in [#14](https://github.com/jlowin/fastmcp/pull/14) * func β†’ fn everywhere by [@jlowin](https://github.com/jlowin) in [#15](https://github.com/jlowin/fastmcp/pull/15) * Add support for prompts by [@jlowin](https://github.com/jlowin) in [#16](https://github.com/jlowin/fastmcp/pull/16) * Create LICENSE by [@jlowin](https://github.com/jlowin) in [#18](https://github.com/jlowin/fastmcp/pull/18) * Update cli file spec by [@jlowin](https://github.com/jlowin) in [#19](https://github.com/jlowin/fastmcp/pull/19) * Update readmeUpdate README by [@jlowin](https://github.com/jlowin) in [#20](https://github.com/jlowin/fastmcp/pull/20) * Use hatchling for version by [@jlowin](https://github.com/jlowin) in [#21](https://github.com/jlowin/fastmcp/pull/21) ### Other Changes 🦾 * Add echo server by [@jlowin](https://github.com/jlowin) in [#1](https://github.com/jlowin/fastmcp/pull/1) * Add github workflows by [@jlowin](https://github.com/jlowin) in [#2](https://github.com/jlowin/fastmcp/pull/2) * typing updates by [@zzstoatzz](https://github.com/zzstoatzz) in [#17](https://github.com/jlowin/fastmcp/pull/17) ### New Contributors * [@jlowin](https://github.com/jlowin) made their first contribution in [#1](https://github.com/jlowin/fastmcp/pull/1) * [@zzstoatzz](https://github.com/zzstoatzz) made their first contribution in [#17](https://github.com/jlowin/fastmcp/pull/17) **Full Changelog**: [v0.2.0...v0.3.0](https://github.com/jlowin/fastmcp/compare/v0.2.0...v0.3.0) ## [v0.2.0](https://github.com/jlowin/fastmcp/releases/tag/v0.2.0) **Full Changelog**: [v0.1.0...v0.2.0](https://github.com/jlowin/fastmcp/compare/v0.1.0...v0.2.0) ## [v0.1.0](https://github.com/jlowin/fastmcp/releases/tag/v0.1.0) The very first release of FastMCP! πŸŽ‰ **Full Changelog**: [Initial commits](https://github.com/jlowin/fastmcp/commits/v0.1.0) # Bearer Token Authentication Source: https://gofastmcp.com/clients/auth/bearer Authenticate your FastMCP client with a Bearer token. export const VersionBadge = ({version}) => { return

New in version:Β  {version}

; }; Bearer Token authentication is only relevant for HTTP-based transports. You can configure your FastMCP client to use **bearer authentication** by supplying a valid access token. This is most appropriate for service accounts, long-lived API keys, CI/CD, applications where authentication is managed separately, or other non-interactive authentication methods. A Bearer token is a JSON Web Token (JWT) that is used to authenticate a request. It is most commonly used in the `Authorization` header of an HTTP request, using the `Bearer` scheme: ```http Authorization: Bearer ``` ## Client Usage The most straightforward way to use a pre-existing Bearer token is to provide it as a string to the `auth` parameter of the `fastmcp.Client` or transport instance. FastMCP will automatically format it correctly for the `Authorization` header and bearer scheme. If you're using a string token, do not include the `Bearer` prefix. FastMCP will add it for you. ```python {5} from fastmcp import Client async with Client( "https://fastmcp.cloud/mcp", auth="", ) as client: await client.ping() ``` You can also supply a Bearer token to a transport instance, such as `StreamableHttpTransport` or `SSETransport`: ```python {6} from fastmcp import Client from fastmcp.client.transports import StreamableHttpTransport transport = StreamableHttpTransport( "http://fastmcp.cloud/mcp", auth="", ) async with Client(transport) as client: await client.ping() ``` ## `BearerAuth` Helper If you prefer to be more explicit and not rely on FastMCP to transform your string token, you can use the `BearerAuth` class yourself, which implements the `httpx.Auth` interface. ```python {6} from fastmcp import Client from fastmcp.client.auth import BearerAuth async with Client( "https://fastmcp.cloud/mcp", auth=BearerAuth(token=""), ) as client: await client.ping() ``` ## Custom Headers If the MCP server expects a custom header or token scheme, you can manually set the client's `headers` instead of using the `auth` parameter by setting them on your transport: ```python {5} from fastmcp import Client from fastmcp.client.transports import StreamableHttpTransport async with Client( transport=StreamableHttpTransport( "https://fastmcp.cloud/mcp", headers={"X-API-Key": ""}, ), ) as client: await client.ping() ``` # OAuth Authentication Source: https://gofastmcp.com/clients/auth/oauth Authenticate your FastMCP client via OAuth 2.1. export const VersionBadge = ({version}) => { return

New in version:Β  {version}

; }; OAuth authentication is only relevant for HTTP-based transports and requires user interaction via a web browser. When your FastMCP client needs to access an MCP server protected by OAuth 2.1, and the process requires user interaction (like logging in and granting consent), you should use the Authorization Code Flow. FastMCP provides the `fastmcp.client.auth.OAuth` helper to simplify this entire process. This flow is common for user-facing applications where the application acts on behalf of the user. ## Client Usage ### Default Configuration The simplest way to use OAuth is to pass the string `"oauth"` to the `auth` parameter of the `Client` or transport instance. FastMCP will automatically configure the client to use OAuth with default settings: ```python {4} from fastmcp import Client # Uses default OAuth settings async with Client("https://fastmcp.cloud/mcp", auth="oauth") as client: await client.ping() ``` ### `OAuth` Helper To fully configure the OAuth flow, use the `OAuth` helper and pass it to the `auth` parameter of the `Client` or transport instance. `OAuth` manages the complexities of the OAuth 2.1 Authorization Code Grant with PKCE (Proof Key for Code Exchange) for enhanced security, and implements the full `httpx.Auth` interface. ```python {2, 4, 6} from fastmcp import Client from fastmcp.client.auth import OAuth oauth = OAuth(mcp_url="https://fastmcp.cloud/mcp") async with Client("https://fastmcp.cloud/mcp", auth=oauth) as client: await client.ping() ``` #### `OAuth` Parameters * **`mcp_url`** (`str`): The full URL of the target MCP server endpoint. Used to discover OAuth server metadata * **`scopes`** (`str | list[str]`, optional): OAuth scopes to request. Can be space-separated string or list of strings * **`client_name`** (`str`, optional): Client name for dynamic registration. Defaults to `"FastMCP Client"` * **`token_storage_cache_dir`** (`Path`, optional): Token cache directory. Defaults to `~/.fastmcp/oauth-mcp-client-cache/` * **`additional_client_metadata`** (`dict[str, Any]`, optional): Extra metadata for client registration ## OAuth Flow The OAuth flow is triggered when you use a FastMCP `Client` configured to use OAuth. The client first checks the `token_storage_cache_dir` for existing, valid tokens for the target server. If one is found, it will be used to authenticate the client. If no valid tokens exist, the client attempts to discover the OAuth server's endpoints using a well-known URI (e.g., `/.well-known/oauth-authorization-server`) based on the `mcp_url`. If the OAuth server supports it and the client isn't already registered (or credentials aren't cached), the client performs dynamic client registration according to RFC 7591. A temporary local HTTP server is started on an available port. This server's address (e.g., `http://127.0.0.1:/callback`) acts as the `redirect_uri` for the OAuth flow. The user's default web browser is automatically opened, directing them to the OAuth server's authorization endpoint. The user logs in and grants (or denies) the requested `scopes`. Upon approval, the OAuth server redirects the user's browser to the local callback server with an `authorization_code`. The client captures this code and exchanges it with the OAuth server's token endpoint for an `access_token` (and often a `refresh_token`) using PKCE for security. The obtained tokens are saved to the `token_storage_cache_dir` for future use, eliminating the need for repeated browser interactions. The access token is automatically included in the `Authorization` header for requests to the MCP server. If the access token expires, the client will automatically use the refresh token to get a new access token. ## Token Management ### Token Storage OAuth access tokens are automatically cached in `~/.fastmcp/oauth-mcp-client-cache/` and persist between application runs. Files are keyed by the OAuth server's base URL. ### Managing Cache To clear the tokens for a specific server, instantiate a `FileTokenStorage` instance and call the `clear` method: ```python from fastmcp.client.auth.oauth import FileTokenStorage storage = FileTokenStorage(server_url="https://fastmcp.cloud/mcp") await storage.clear() ``` To clear *all* tokens for all servers, call the `clear_all` method on the `FileTokenStorage` class: ```python from fastmcp.client.auth.oauth import FileTokenStorage FileTokenStorage.clear_all() ``` # The FastMCP Client Source: https://gofastmcp.com/clients/client Programmatic client for interacting with MCP servers through a well-typed, Pythonic interface. export const VersionBadge = ({version}) => { return

New in version:Β  {version}

; }; The central piece of MCP client applications is the `fastmcp.Client` class. This class provides a **programmatic interface** for interacting with any Model Context Protocol (MCP) server, handling protocol details and connection management automatically. The FastMCP Client is designed for deterministic, controlled interactions rather than autonomous behavior, making it ideal for: * **Testing MCP servers** during development * **Building deterministic applications** that need reliable MCP interactions * **Creating the foundation for agentic or LLM-based clients** with structured, type-safe operations All client operations require using the `async with` context manager for proper connection lifecycle management. This is not an agentic client - it requires explicit function calls and provides direct control over all MCP operations. Use it as a building block for higher-level systems. ## Creating a Client Creating a client is straightforward. You provide a server source and the client automatically infers the appropriate transport mechanism. ```python import asyncio from fastmcp import Client, FastMCP # In-memory server (ideal for testing) server = FastMCP("TestServer") client = Client(server) # HTTP server client = Client("https://example.com/mcp") # Local Python script client = Client("my_mcp_server.py") async def main(): async with client: # Basic server interaction await client.ping() # List available operations tools = await client.list_tools() resources = await client.list_resources() prompts = await client.list_prompts() # Execute operations result = await client.call_tool("example_tool", {"param": "value"}) print(result) asyncio.run(main()) ``` ## Client-Transport Architecture The FastMCP Client separates concerns between protocol and connection: * **`Client`**: Handles MCP protocol operations (tools, resources, prompts) and manages callbacks * **`Transport`**: Establishes and maintains the connection (WebSockets, HTTP, Stdio, in-memory) ### Transport Inference The client automatically infers the appropriate transport based on the input: 1. **`FastMCP` instance** β†’ In-memory transport (perfect for testing) 2. **File path ending in `.py`** β†’ Python Stdio transport 3. **File path ending in `.js`** β†’ Node.js Stdio transport 4. **URL starting with `http://` or `https://`** β†’ HTTP transport 5. **`MCPConfig` dictionary** β†’ Multi-server client ```python from fastmcp import Client, FastMCP # Examples of transport inference client_memory = Client(FastMCP("TestServer")) client_script = Client("./server.py") client_http = Client("https://api.example.com/mcp") ``` For testing and development, always prefer the in-memory transport by passing a `FastMCP` server directly to the client. This eliminates network complexity and separate processes. ## Configuration-Based Clients Create clients from MCP configuration dictionaries, which can include multiple servers. While there is no official standard for MCP configuration format, FastMCP follows established conventions used by tools like Claude Desktop. ### Configuration Format ```python config = { "mcpServers": { "server_name": { # Remote HTTP/SSE server "transport": "http", # or "sse" "url": "https://api.example.com/mcp", "headers": {"Authorization": "Bearer token"}, "auth": "oauth" # or bearer token string }, "local_server": { # Local stdio server "transport": "stdio", "command": "python", "args": ["./server.py", "--verbose"], "env": {"DEBUG": "true"}, "cwd": "/path/to/server", } } } ``` ### Multi-Server Example ```python config = { "mcpServers": { "weather": {"url": "https://weather-api.example.com/mcp"}, "assistant": {"command": "python", "args": ["./assistant_server.py"]} } } client = Client(config) async with client: # Tools are prefixed with server names weather_data = await client.call_tool("weather_get_forecast", {"city": "London"}) response = await client.call_tool("assistant_answer_question", {"question": "What's the capital of France?"}) # Resources use prefixed URIs icons = await client.read_resource("weather://weather/icons/sunny") templates = await client.read_resource("resource://assistant/templates/list") ``` ## Connection Lifecycle The client operates asynchronously and uses context managers for connection management: ```python async def example(): client = Client("my_mcp_server.py") # Connection established here async with client: print(f"Connected: {client.is_connected()}") # Make multiple calls within the same session tools = await client.list_tools() result = await client.call_tool("greet", {"name": "World"}) # Connection closed automatically here print(f"Connected: {client.is_connected()}") ``` ## Operations FastMCP clients can interact with several types of server components: ### Tools Tools are server-side functions that the client can execute with arguments. ```python async with client: # List available tools tools = await client.list_tools() # Execute a tool result = await client.call_tool("multiply", {"a": 5, "b": 3}) print(result.data) # 15 ``` See [Tools](/clients/tools) for detailed documentation. ### Resources Resources are data sources that the client can read, either static or templated. ```python async with client: # List available resources resources = await client.list_resources() # Read a resource content = await client.read_resource("file:///config/settings.json") print(content[0].text) ``` See [Resources](/clients/resources) for detailed documentation. ### Prompts Prompts are reusable message templates that can accept arguments. ```python async with client: # List available prompts prompts = await client.list_prompts() # Get a rendered prompt messages = await client.get_prompt("analyze_data", {"data": [1, 2, 3]}) print(messages.messages) ``` See [Prompts](/clients/prompts) for detailed documentation. ### Server Connectivity Use `ping()` to verify the server is reachable: ```python async with client: await client.ping() print("Server is reachable") ``` ## Client Configuration Clients can be configured with additional handlers and settings for specialized use cases. ### Callback Handlers The client supports several callback handlers for advanced server interactions: ```python from fastmcp import Client from fastmcp.client.logging import LogMessage async def log_handler(message: LogMessage): print(f"Server log: {message.data}") async def progress_handler(progress: float, total: float | None, message: str | None): print(f"Progress: {progress}/{total} - {message}") async def sampling_handler(messages, params, context): # Integrate with your LLM service here return "Generated response" client = Client( "my_mcp_server.py", log_handler=log_handler, progress_handler=progress_handler, sampling_handler=sampling_handler, timeout=30.0 ) ``` The `Client` constructor accepts several configuration options: * `transport`: Transport instance or source for automatic inference * `log_handler`: Handle server log messages * `progress_handler`: Monitor long-running operations * `sampling_handler`: Respond to server LLM requests * `roots`: Provide local context to servers * `timeout`: Default timeout for requests (in seconds) ### Transport Configuration For detailed transport configuration (headers, authentication, environment variables), see the [Transports](/clients/transports) documentation. ## Next Steps Explore the detailed documentation for each operation type: ### Core Operations * **[Tools](/clients/tools)** - Execute server-side functions and handle results * **[Resources](/clients/resources)** - Access static and templated resources * **[Prompts](/clients/prompts)** - Work with message templates and argument serialization ### Advanced Features * **[Logging](/clients/logging)** - Handle server log messages * **[Progress](/clients/progress)** - Monitor long-running operations * **[Sampling](/clients/sampling)** - Respond to server LLM requests * **[Roots](/clients/roots)** - Provide local context to servers ### Connection Details * **[Transports](/clients/transports)** - Configure connection methods and parameters * **[Authentication](/clients/auth/oauth)** - Set up OAuth and bearer token authentication The FastMCP Client is designed as a foundational tool. Use it directly for deterministic operations, or build higher-level agentic systems on top of its reliable, type-safe interface. # User Elicitation Source: https://gofastmcp.com/clients/elicitation Handle server-initiated user input requests with structured schemas. export const VersionBadge = ({version}) => { return

New in version:Β  {version}

; }; ## What is Elicitation? Elicitation allows MCP servers to request structured input from users during tool execution. Instead of requiring all inputs upfront, servers can interactively ask users for information as needed - like prompting for missing parameters, requesting clarification, or gathering additional context. For example, a file management tool might ask "Which directory should I create?" or a data analysis tool might request "What date range should I analyze?" ## How FastMCP Makes Elicitation Easy FastMCP's client provides a helpful abstraction layer that: * **Converts JSON schemas to Python types**: The raw MCP protocol uses JSON schemas, but FastMCP automatically converts these to Python dataclasses * **Provides structured constructors**: Instead of manually building dictionaries that match the schema, you get dataclass constructors that ensure correct structure * **Handles type conversion**: FastMCP takes care of converting between JSON representations and Python objects * **Runtime introspection**: You can inspect the generated dataclass fields to understand the expected structure When you implement an elicitation handler, FastMCP gives you a dataclass type that matches the server's schema, making it easy to create properly structured responses without having to manually parse JSON schemas. ## Elicitation Handler Provide an `elicitation_handler` function when creating the client. FastMCP automatically converts the server's JSON schema into a Python dataclass type, making it easy to construct the response: ```python from fastmcp import Client from fastmcp.client.elicitation import ElicitResult async def elicitation_handler(message: str, response_type: type, params, context): # Present the message to the user and collect input user_input = input(f"{message}: ") # Create response using the provided dataclass type # FastMCP converted the JSON schema to this Python type for you response_data = response_type(value=user_input) # You can return data directly - FastMCP will implicitly accept the elicitation return response_data # Or explicitly return an ElicitResult for more control # return ElicitResult(action="accept", content=response_data) client = Client( "my_mcp_server.py", elicitation_handler=elicitation_handler, ) ``` ### Handler Parameters The elicitation handler receives four parameters: The prompt message to display to the user A Python dataclass type that FastMCP created from the server's JSON schema. Use this to construct your response with proper typing and IDE support. If the server requests an empty object (indicating no response), this will be `None`. The original MCP elicitation request parameters, including the raw JSON schema in `params.requestedSchema` if you need it Request context containing metadata about the elicitation request ### Response Actions The handler can return data directly (which implicitly accepts the elicitation) or an `ElicitResult` object for more control over the response action: How the user responded to the elicitation request The user's input data (required for "accept", omitted for "decline"/"cancel") **Action Types:** * **`accept`**: User provided valid input - include their data in the `content` field * **`decline`**: User chose not to provide the requested information - omit `content` * **`cancel`**: User cancelled the entire operation - omit `content` ## Basic Example ```python from fastmcp import Client from fastmcp.client.elicitation import ElicitResult async def basic_elicitation_handler(message: str, response_type: type, params, context): print(f"Server asks: {message}") # Simple text input for demonstration user_response = input("Your response: ") if not user_response: # For non-acceptance, use ElicitResult explicitly return ElicitResult(action="decline") # Use the response_type dataclass to create a properly structured response # FastMCP handles the conversion from JSON schema to Python type # Return data directly - FastMCP will implicitly accept the elicitation return response_type(value=user_response) client = Client( "my_mcp_server.py", elicitation_handler=basic_elicitation_handler ) ``` # Server Logging Source: https://gofastmcp.com/clients/logging Receive and handle log messages from MCP servers. export const VersionBadge = ({version}) => { return

New in version:Β  {version}

; }; MCP servers can emit log messages to clients. The client can handle these logs through a log handler callback. ## Log Handler Provide a `log_handler` function when creating the client: ```python from fastmcp import Client from fastmcp.client.logging import LogMessage async def log_handler(message: LogMessage): level = message.level.upper() logger = message.logger or 'server' data = message.data print(f"[{level}] {logger}: {data}") client = Client( "my_mcp_server.py", log_handler=log_handler, ) ``` ### Handler Parameters The `log_handler` is called every time a log message is received. It receives a `LogMessage` object: The log level The logger name (optional, may be None) The actual log message content ```python async def detailed_log_handler(message: LogMessage): if message.level == "error": print(f"ERROR: {message.data}") elif message.level == "warning": print(f"WARNING: {message.data}") else: print(f"{message.level.upper()}: {message.data}") ``` ## Default Log Handling If you don't provide a custom `log_handler`, FastMCP uses a default handler that emits a DEBUG-level FastMCP log for every log message received from the server, which is useful for visibility without polluting your own logs. ```python client = Client("my_mcp_server.py") async with client: # Server logs will be emitted at DEBUG level automatically await client.call_tool("some_tool") ``` # Message Handling Source: https://gofastmcp.com/clients/messages Handle MCP messages, requests, and notifications with custom message handlers. export const VersionBadge = ({version}) => { return

New in version:Β  {version}

; }; MCP clients can receive various types of messages from servers, including requests that need responses and notifications that don't. The message handler provides a unified way to process all these messages. ## Function-Based Handler The simplest way to handle messages is with a function that receives all messages: ```python from fastmcp import Client async def message_handler(message): """Handle all MCP messages from the server.""" if hasattr(message, 'root'): method = message.root.method print(f"Received: {method}") # Handle specific notifications if method == "notifications/tools/list_changed": print("Tools have changed - might want to refresh tool cache") elif method == "notifications/resources/list_changed": print("Resources have changed") client = Client( "my_mcp_server.py", message_handler=message_handler, ) ``` ## Message Handler Class For fine-grained targeting, FastMCP provides a `MessageHandler` class you can subclass to take advantage of specific hooks: ```python from fastmcp import Client from fastmcp.client.messages import MessageHandler import mcp.types class MyMessageHandler(MessageHandler): async def on_tool_list_changed( self, notification: mcp.types.ToolListChangedNotification ) -> None: """Handle tool list changes specifically.""" print("Tool list changed - refreshing available tools") client = Client( "my_mcp_server.py", message_handler=MyMessageHandler(), ) ``` ### Available Handler Methods All handler methods receive a single argument - the specific message type: Called for ALL messages (requests and notifications) Called for requests that expect responses Called for notifications (fire-and-forget) Called when the server's tool list changes Called when the server's resource list changes Called when the server's prompt list changes Called for progress updates during long-running operations Called for log messages from the server ## Example: Handling Tool Changes Here's a practical example of handling tool list changes: ```python from fastmcp.client.messages import MessageHandler import mcp.types class ToolCacheHandler(MessageHandler): def __init__(self): self.cached_tools = [] async def on_tool_list_changed( self, notification: mcp.types.ToolListChangedNotification ) -> None: """Clear tool cache when tools change.""" print("Tools changed - clearing cache") self.cached_tools = [] # Force refresh on next access client = Client("server.py", message_handler=ToolCacheHandler()) ``` ## Handling Requests While the message handler receives server-initiated requests, for most use cases you should use the dedicated callback parameters instead: * **Sampling requests**: Use [`sampling_handler`](/clients/sampling) * **Progress requests**: Use [`progress_handler`](/clients/progress) * **Log requests**: Use [`log_handler`](/clients/logging) The message handler is primarily for monitoring and handling notifications rather than responding to requests. # Progress Monitoring Source: https://gofastmcp.com/clients/progress Handle progress notifications from long-running server operations. export const VersionBadge = ({version}) => { return

New in version:Β  {version}

; }; MCP servers can report progress during long-running operations. The client can receive these updates through a progress handler. ## Progress Handler Set a progress handler when creating the client: ```python from fastmcp import Client async def my_progress_handler( progress: float, total: float | None, message: str | None ) -> None: if total is not None: percentage = (progress / total) * 100 print(f"Progress: {percentage:.1f}% - {message or ''}") else: print(f"Progress: {progress} - {message or ''}") client = Client( "my_mcp_server.py", progress_handler=my_progress_handler ) ``` ### Handler Parameters The progress handler receives three parameters: Current progress value Expected total value (may be None) Optional status message (may be None) ## Per-Call Progress Handler Override the progress handler for specific tool calls: ```python async with client: # Override with specific progress handler for this call result = await client.call_tool( "long_running_task", {"param": "value"}, progress_handler=my_progress_handler ) ``` # Prompts Source: https://gofastmcp.com/clients/prompts Use server-side prompt templates with automatic argument serialization. export const VersionBadge = ({version}) => { return

New in version:Β  {version}

; }; Prompts are reusable message templates exposed by MCP servers. They can accept arguments to generate personalized message sequences for LLM interactions. ## Listing Prompts Use `list_prompts()` to retrieve all available prompt templates: ```python async with client: prompts = await client.list_prompts() # prompts -> list[mcp.types.Prompt] for prompt in prompts: print(f"Prompt: {prompt.name}") print(f"Description: {prompt.description}") if prompt.arguments: print(f"Arguments: {[arg.name for arg in prompt.arguments]}") ``` ## Using Prompts ### Basic Usage Request a rendered prompt using `get_prompt()` with the prompt name and arguments: ```python async with client: # Simple prompt without arguments result = await client.get_prompt("welcome_message") # result -> mcp.types.GetPromptResult # Access the generated messages for message in result.messages: print(f"Role: {message.role}") print(f"Content: {message.content}") ``` ### Prompts with Arguments Pass arguments as a dictionary to customize the prompt: ```python async with client: # Prompt with simple arguments result = await client.get_prompt("user_greeting", { "name": "Alice", "role": "administrator" }) # Access the personalized messages for message in result.messages: print(f"Generated message: {message.content}") ``` ## Automatic Argument Serialization FastMCP automatically serializes complex arguments to JSON strings as required by the MCP specification. This allows you to pass typed objects directly: ```python from dataclasses import dataclass @dataclass class UserData: name: str age: int async with client: # Complex arguments are automatically serialized result = await client.get_prompt("analyze_user", { "user": UserData(name="Alice", age=30), # Automatically serialized to JSON "preferences": {"theme": "dark"}, # Dict serialized to JSON string "scores": [85, 92, 78], # List serialized to JSON string "simple_name": "Bob" # Strings passed through unchanged }) ``` The client handles serialization using `pydantic_core.to_json()` for consistent formatting. FastMCP servers can automatically deserialize these JSON strings back to the expected types. ### Serialization Examples ```python async with client: result = await client.get_prompt("data_analysis", { # These will be automatically serialized to JSON strings: "config": { "format": "csv", "include_headers": True, "delimiter": "," }, "filters": [ {"field": "age", "operator": ">", "value": 18}, {"field": "status", "operator": "==", "value": "active"} ], # This remains a string: "report_title": "Monthly Analytics Report" }) ``` ## Working with Prompt Results The `get_prompt()` method returns a `GetPromptResult` object containing a list of messages: ```python async with client: result = await client.get_prompt("conversation_starter", {"topic": "climate"}) # Access individual messages for i, message in enumerate(result.messages): print(f"Message {i + 1}:") print(f" Role: {message.role}") print(f" Content: {message.content.text if hasattr(message.content, 'text') else message.content}") ``` ## Raw MCP Protocol Access For access to the complete MCP protocol objects, use the `*_mcp` methods: ```python async with client: # Raw MCP method returns full protocol object prompts_result = await client.list_prompts_mcp() # prompts_result -> mcp.types.ListPromptsResult prompt_result = await client.get_prompt_mcp("example_prompt", {"arg": "value"}) # prompt_result -> mcp.types.GetPromptResult ``` ## Multi-Server Clients When using multi-server clients, prompts are accessible without prefixing (unlike tools): ```python async with client: # Multi-server client # Prompts from any server are directly accessible result1 = await client.get_prompt("weather_prompt", {"city": "London"}) result2 = await client.get_prompt("assistant_prompt", {"query": "help"}) ``` ## Common Prompt Patterns ### System Messages Many prompts generate system messages for LLM configuration: ```python async with client: result = await client.get_prompt("system_configuration", { "role": "helpful assistant", "expertise": "python programming" }) # Typically returns messages with role="system" system_message = result.messages[0] print(f"System prompt: {system_message.content}") ``` ### Conversation Templates Prompts can generate multi-turn conversation templates: ```python async with client: result = await client.get_prompt("interview_template", { "candidate_name": "Alice", "position": "Senior Developer" }) # Multiple messages for a conversation flow for message in result.messages: print(f"{message.role}: {message.content}") ``` Prompt arguments and their expected types depend on the specific prompt implementation. Check the server's documentation or use `list_prompts()` to see available arguments for each prompt. # Resource Operations Source: https://gofastmcp.com/clients/resources Access static and templated resources from MCP servers. export const VersionBadge = ({version}) => { return

New in version:Β  {version}

; }; Resources are data sources exposed by MCP servers. They can be static files or dynamic templates that generate content based on parameters. ## Types of Resources MCP servers expose two types of resources: * **Static Resources**: Fixed content accessible via URI (e.g., configuration files, documentation) * **Resource Templates**: Dynamic resources that accept parameters to generate content (e.g., API endpoints, database queries) ## Listing Resources ### Static Resources Use `list_resources()` to retrieve all static resources available on the server: ```python async with client: resources = await client.list_resources() # resources -> list[mcp.types.Resource] for resource in resources: print(f"Resource URI: {resource.uri}") print(f"Name: {resource.name}") print(f"Description: {resource.description}") print(f"MIME Type: {resource.mimeType}") ``` ### Resource Templates Use `list_resource_templates()` to retrieve available resource templates: ```python async with client: templates = await client.list_resource_templates() # templates -> list[mcp.types.ResourceTemplate] for template in templates: print(f"Template URI: {template.uriTemplate}") print(f"Name: {template.name}") print(f"Description: {template.description}") ``` ## Reading Resources ### Static Resources Read a static resource using its URI: ```python async with client: # Read a static resource content = await client.read_resource("file:///path/to/README.md") # content -> list[mcp.types.TextResourceContents | mcp.types.BlobResourceContents] # Access text content if hasattr(content[0], 'text'): print(content[0].text) # Access binary content if hasattr(content[0], 'blob'): print(f"Binary data: {len(content[0].blob)} bytes") ``` ### Resource Templates Read from a resource template by providing the URI with parameters: ```python async with client: # Read a resource generated from a template # For example, a template like "weather://{{city}}/current" weather_content = await client.read_resource("weather://london/current") # Access the generated content print(weather_content[0].text) # Assuming text JSON response ``` ## Content Types Resources can return different content types: ### Text Resources ```python async with client: content = await client.read_resource("resource://config/settings.json") for item in content: if hasattr(item, 'text'): print(f"Text content: {item.text}") print(f"MIME type: {item.mimeType}") ``` ### Binary Resources ```python async with client: content = await client.read_resource("resource://images/logo.png") for item in content: if hasattr(item, 'blob'): print(f"Binary content: {len(item.blob)} bytes") print(f"MIME type: {item.mimeType}") # Save to file with open("downloaded_logo.png", "wb") as f: f.write(item.blob) ``` ## Working with Multi-Server Clients When using multi-server clients, resource URIs are automatically prefixed with the server name: ```python async with client: # Multi-server client # Access resources from different servers weather_icons = await client.read_resource("weather://weather/icons/sunny") templates = await client.read_resource("resource://assistant/templates/list") print(f"Weather icon: {weather_icons[0].blob}") print(f"Templates: {templates[0].text}") ``` ## Raw MCP Protocol Access For access to the complete MCP protocol objects, use the `*_mcp` methods: ```python async with client: # Raw MCP methods return full protocol objects resources_result = await client.list_resources_mcp() # resources_result -> mcp.types.ListResourcesResult templates_result = await client.list_resource_templates_mcp() # templates_result -> mcp.types.ListResourceTemplatesResult content_result = await client.read_resource_mcp("resource://example") # content_result -> mcp.types.ReadResourceResult ``` ## Common Resource URI Patterns Different MCP servers may use various URI schemes: ```python # File system resources "file:///path/to/file.txt" # Custom protocol resources "weather://london/current" "database://users/123" # Generic resource protocol "resource://config/settings" "resource://templates/email" ``` Resource URIs and their formats depend on the specific MCP server implementation. Check the server's documentation for available resources and their URI patterns. # Client Roots Source: https://gofastmcp.com/clients/roots Provide local context and resource boundaries to MCP servers. export const VersionBadge = ({version}) => { return

New in version:Β  {version}

; }; Roots are a way for clients to inform servers about the resources they have access to. Servers can use this information to adjust behavior or provide more relevant responses. ## Setting Static Roots Provide a list of roots when creating the client: ```python Static Roots from fastmcp import Client client = Client( "my_mcp_server.py", roots=["/path/to/root1", "/path/to/root2"] ) ``` ```python Dynamic Roots Callback from fastmcp import Client from fastmcp.client.roots import RequestContext async def roots_callback(context: RequestContext) -> list[str]: print(f"Server requested roots (Request ID: {context.request_id})") return ["/path/to/root1", "/path/to/root2"] client = Client( "my_mcp_server.py", roots=roots_callback ) ``` # LLM Sampling Source: https://gofastmcp.com/clients/sampling Handle server-initiated LLM sampling requests. export const VersionBadge = ({version}) => { return

New in version:Β  {version}

; }; MCP servers can request LLM completions from clients. The client handles these requests through a sampling handler callback. ## Sampling Handler Provide a `sampling_handler` function when creating the client: ```python from fastmcp import Client from fastmcp.client.sampling import ( SamplingMessage, SamplingParams, RequestContext, ) async def sampling_handler( messages: list[SamplingMessage], params: SamplingParams, context: RequestContext ) -> str: # Your LLM integration logic here # Extract text from messages and generate a response return "Generated response based on the messages" client = Client( "my_mcp_server.py", sampling_handler=sampling_handler, ) ``` ### Handler Parameters The sampling handler receives three parameters: The role of the message. The content of the message. TextContent is most common, and has a `.text` attribute. The messages to sample from The server's preferences for which model to select. The client MAY ignore these preferences. The hints to use for model selection. The cost priority for model selection. The speed priority for model selection. The intelligence priority for model selection. An optional system prompt the server wants to use for sampling. A request to include context from one or more MCP servers (including the caller), to be attached to the prompt. The sampling temperature. The maximum number of tokens to sample. The stop sequences to use for sampling. Optional metadata to pass through to the LLM provider. Unique identifier for the MCP request ## Basic Example ```python from fastmcp import Client from fastmcp.client.sampling import SamplingMessage, SamplingParams, RequestContext async def basic_sampling_handler( messages: list[SamplingMessage], params: SamplingParams, context: RequestContext ) -> str: # Extract message content conversation = [] for message in messages: content = message.content.text if hasattr(message.content, 'text') else str(message.content) conversation.append(f"{message.role}: {content}") # Use the system prompt if provided system_prompt = params.systemPrompt or "You are a helpful assistant." # Here you would integrate with your preferred LLM service # This is just a placeholder response return f"Response based on conversation: {' | '.join(conversation)}" client = Client( "my_mcp_server.py", sampling_handler=basic_sampling_handler ) ``` # Tool Operations Source: https://gofastmcp.com/clients/tools Discover and execute server-side tools with the FastMCP client. export const VersionBadge = ({version}) => { return

New in version:Β  {version}

; }; Tools are executable functions exposed by MCP servers. The FastMCP client provides methods to discover available tools and execute them with arguments. ## Discovering Tools Use `list_tools()` to retrieve all tools available on the server: ```python async with client: tools = await client.list_tools() # tools -> list[mcp.types.Tool] for tool in tools: print(f"Tool: {tool.name}") print(f"Description: {tool.description}") if tool.inputSchema: print(f"Parameters: {tool.inputSchema}") ``` ## Executing Tools ### Basic Execution Execute a tool using `call_tool()` with the tool name and arguments: ```python async with client: # Simple tool call result = await client.call_tool("add", {"a": 5, "b": 3}) # result -> CallToolResult with structured and unstructured data # Access structured data (automatically deserialized) print(result.data) # 8 (int) or {"result": 8} for primitive types # Access traditional content blocks print(result.content[0].text) # "8" (TextContent) ``` ### Advanced Execution Options The `call_tool()` method supports additional parameters for timeout control and progress monitoring: ```python async with client: # With timeout (aborts if execution takes longer than 2 seconds) result = await client.call_tool( "long_running_task", {"param": "value"}, timeout=2.0 ) # With progress handler (to track execution progress) result = await client.call_tool( "long_running_task", {"param": "value"}, progress_handler=my_progress_handler ) ``` **Parameters:** * `name`: The tool name (string) * `arguments`: Dictionary of arguments to pass to the tool (optional) * `timeout`: Maximum execution time in seconds (optional, overrides client-level timeout) * `progress_handler`: Progress callback function (optional, overrides client-level handler) ## Handling Results Tool execution returns a `CallToolResult` object with both structured and traditional content. FastMCP's standout feature is the `.data` property, which doesn't just provide raw JSON but actually hydrates complete Python objects including complex types like datetimes, UUIDs, and custom classes. ### CallToolResult Properties **FastMCP exclusive**: Fully hydrated Python objects with complex type support (datetimes, UUIDs, custom classes). Goes beyond JSON to provide complete object reconstruction from output schemas. Standard MCP content blocks (`TextContent`, `ImageContent`, `AudioContent`, etc.) available from all MCP servers. Standard MCP structured JSON data as sent by the server, available from all MCP servers that support structured outputs. Boolean indicating if the tool execution failed. ### Structured Data Access FastMCP's `.data` property provides fully hydrated Python objects, not just JSON dictionaries. This includes complex type reconstruction: ```python from datetime import datetime from uuid import UUID async with client: result = await client.call_tool("get_weather", {"city": "London"}) # FastMCP reconstructs complete Python objects from the server's output schema weather = result.data # Server-defined WeatherReport object print(f"Temperature: {weather.temperature}Β°C at {weather.timestamp}") print(f"Station: {weather.station_id}") print(f"Humidity: {weather.humidity}%") # The timestamp is a real datetime object, not a string! assert isinstance(weather.timestamp, datetime) assert isinstance(weather.station_id, UUID) # Compare with raw structured JSON (standard MCP) print(f"Raw JSON: {result.structured_content}") # {"temperature": 20, "timestamp": "2024-01-15T14:30:00Z", "station_id": "123e4567-..."} # Traditional content blocks (standard MCP) print(f"Text content: {result.content[0].text}") ``` ### Fallback Behavior For tools without output schemas or when deserialization fails, `.data` will be `None`: ```python async with client: result = await client.call_tool("legacy_tool", {"param": "value"}) if result.data is not None: # Structured output available and successfully deserialized print(f"Structured: {result.data}") else: # No structured output or deserialization failed - use content blocks for content in result.content: if hasattr(content, 'text'): print(f"Text result: {content.text}") elif hasattr(content, 'data'): print(f"Binary data: {len(content.data)} bytes") ``` ### Primitive Type Unwrapping FastMCP servers automatically wrap non-object results (like `int`, `str`, `bool`) in a `{"result": value}` structure to create valid structured outputs. FastMCP clients understand this convention and automatically unwrap the value in `.data` for convenience, so you get the original primitive value instead of a wrapper object. ```python async with client: result = await client.call_tool("calculate_sum", {"a": 5, "b": 3}) # FastMCP client automatically unwraps for convenience print(result.data) # 8 (int) - the original value # Raw structured content shows the server-side wrapping print(result.structured_content) # {"result": 8} # Other MCP clients would need to manually access ["result"] # value = result.structured_content["result"] # Not needed with FastMCP! ``` ## Error Handling ### Exception-Based Error Handling By default, `call_tool()` raises a `ToolError` if the tool execution fails: ```python from fastmcp.exceptions import ToolError async with client: try: result = await client.call_tool("potentially_failing_tool", {"param": "value"}) print("Tool succeeded:", result.data) except ToolError as e: print(f"Tool failed: {e}") ``` ### Manual Error Checking You can disable automatic error raising and manually check the result: ```python async with client: result = await client.call_tool( "potentially_failing_tool", {"param": "value"}, raise_on_error=False ) if result.is_error: print(f"Tool failed: {result.content[0].text}") else: print(f"Tool succeeded: {result.data}") ``` ### Raw MCP Protocol Access For complete control, use `call_tool_mcp()` which returns the raw MCP protocol object: ```python async with client: result = await client.call_tool_mcp("potentially_failing_tool", {"param": "value"}) # result -> mcp.types.CallToolResult if result.isError: print(f"Tool failed: {result.content}") else: print(f"Tool succeeded: {result.content}") # Note: No automatic deserialization with call_tool_mcp() ``` ## Argument Handling Arguments are passed as a dictionary to the tool: ```python async with client: # Simple arguments result = await client.call_tool("greet", {"name": "World"}) # Complex arguments result = await client.call_tool("process_data", { "config": {"format": "json", "validate": True}, "items": [1, 2, 3, 4, 5], "metadata": {"source": "api", "version": "1.0"} }) ``` For multi-server clients, tool names are automatically prefixed with the server name (e.g., `weather_get_forecast` for a tool named `get_forecast` on the `weather` server). # Client Transports Source: https://gofastmcp.com/clients/transports Configure how FastMCP Clients connect to and communicate with servers. export const VersionBadge = ({version}) => { return

New in version:Β  {version}

; }; The FastMCP `Client` communicates with MCP servers through transport objects that handle the underlying connection mechanics. While the client can automatically select a transport based on what you pass to it, instantiating transports explicitly gives you full control over configurationβ€”environment variables, authentication, session management, and more. Think of transports as configurable adapters between your client code and MCP servers. Each transport type handles a different communication pattern: subprocesses with pipes, HTTP connections, or direct in-memory calls. ## Choosing the Right Transport * **Use [STDIO Transport](#stdio-transport)** when you need to run local MCP servers with full control over their environment and lifecycle * **Use [Remote Transports](#remote-transports)** when connecting to production services or shared MCP servers running independently * **Use [In-Memory Transport](#in-memory-transport)** for testing FastMCP servers without subprocess or network overhead * **Use [MCP JSON Configuration](#mcp-json-configuration-transport)** when you need to connect to multiple servers defined in configuration files ## STDIO Transport STDIO (Standard Input/Output) transport communicates with MCP servers through subprocess pipes. This is the standard mechanism used by desktop clients like Claude Desktop and is the primary way to run local MCP servers. ### The Client Runs the Server **Critical Concept**: When using STDIO transport, your client actually launches and manages the server process. This is fundamentally different from network transports where you connect to an already-running server. Understanding this relationship is key to using STDIO effectively. With STDIO transport, your client: * Starts the server as a subprocess when you connect * Manages the server's lifecycle (start, stop, restart) * Controls the server's environment and configuration * Communicates through stdin/stdout pipes This architecture enables powerful local integrations but requires understanding environment isolation and process management. ### Environment Isolation STDIO servers run in isolated environments by default. This is a security feature enforced by the MCP protocol to prevent accidental exposure of sensitive data. When your client launches an MCP server: * The server does NOT inherit your shell's environment variables * API keys, paths, and other configuration must be explicitly passed * The working directory and system paths may differ from your shell To pass environment variables to your server, use the `env` parameter: ```python from fastmcp import Client # If your server needs environment variables (like API keys), # you must explicitly pass them: client = Client( "my_server.py", env={"API_KEY": "secret", "DEBUG": "true"} ) # This won't work - the server runs in isolation: # export API_KEY="secret" # in your shell # client = Client("my_server.py") # server can't see API_KEY ``` ### Basic Usage To use STDIO transport, you create a transport instance with the command and arguments needed to run your server: ```python from fastmcp.client.transports import StdioTransport transport = StdioTransport( command="python", args=["my_server.py"] ) client = Client(transport) ``` You can configure additional settings like environment variables, working directory, or command arguments: ```python transport = StdioTransport( command="python", args=["my_server.py", "--verbose"], env={"LOG_LEVEL": "DEBUG"}, cwd="/path/to/server" ) client = Client(transport) ``` For convenience, the client can also infer STDIO transport from file paths, but this doesn't allow configuration: ```python from fastmcp import Client client = Client("my_server.py") # Limited - no configuration options ``` ### Environment Variables Since STDIO servers don't inherit your environment, you need strategies for passing configuration. Here are two common approaches: **Selective forwarding** passes only the variables your server actually needs: ```python import os from fastmcp.client.transports import StdioTransport required_vars = ["API_KEY", "DATABASE_URL", "REDIS_HOST"] env = { var: os.environ[var] for var in required_vars if var in os.environ } transport = StdioTransport( command="python", args=["server.py"], env=env ) client = Client(transport) ``` **Loading from .env files** keeps configuration separate from code: ```python from dotenv import dotenv_values from fastmcp.client.transports import StdioTransport env = dotenv_values(".env") transport = StdioTransport( command="python", args=["server.py"], env=env ) client = Client(transport) ``` ### Session Persistence STDIO transports maintain sessions across multiple client contexts by default (`keep_alive=True`). This improves performance by reusing the same subprocess for multiple connections, but can be controlled when you need isolation. By default, the subprocess persists between connections: ```python from fastmcp.client.transports import StdioTransport transport = StdioTransport( command="python", args=["server.py"] ) client = Client(transport) async def efficient_multiple_operations(): async with client: await client.ping() async with client: # Reuses the same subprocess await client.call_tool("process_data", {"file": "data.csv"}) ``` For complete isolation between connections, disable session persistence: ```python transport = StdioTransport( command="python", args=["server.py"], keep_alive=False ) client = Client(transport) ``` Use `keep_alive=False` when you need complete isolation (e.g., in test suites) or when server state could cause issues between connections. ### Specialized STDIO Transports FastMCP provides convenience transports that are thin wrappers around `StdioTransport` with pre-configured commands: * **`PythonStdioTransport`** - Uses `python` command for `.py` files * **`NodeStdioTransport`** - Uses `node` command for `.js` files * **`UvxStdioTransport`** - Uses `uvx` for Python packages (uses `env_vars` parameter) * **`NpxStdioTransport`** - Uses `npx` for Node packages (uses `env_vars` parameter) For most use cases, instantiate `StdioTransport` directly with your desired command. These specialized transports are primarily useful for client inference shortcuts. ## Remote Transports Remote transports connect to MCP servers running as web services. This is a fundamentally different model from STDIO transportsβ€”instead of your client launching and managing a server process, you connect to an already-running service that manages its own environment and lifecycle. ### Streamable HTTP Transport Streamable HTTP is the recommended transport for production deployments, providing efficient bidirectional streaming over HTTP connections. * **Class:** `StreamableHttpTransport` * **Server compatibility:** FastMCP servers running with `mcp run --transport http` The transport requires a URL and optionally supports custom headers for authentication and configuration: ```python from fastmcp.client.transports import StreamableHttpTransport # Basic connection transport = StreamableHttpTransport(url="https://api.example.com/mcp") client = Client(transport) # With custom headers for authentication transport = StreamableHttpTransport( url="https://api.example.com/mcp", headers={ "Authorization": "Bearer your-token-here", "X-Custom-Header": "value" } ) client = Client(transport) ``` For convenience, FastMCP also provides authentication helpers: ```python from fastmcp.client.auth import BearerAuth client = Client( "https://api.example.com/mcp", auth=BearerAuth("your-token-here") ) ``` ### SSE Transport (Legacy) Server-Sent Events transport is maintained for backward compatibility but is superseded by Streamable HTTP for new deployments. * **Class:** `SSETransport` * **Server compatibility:** FastMCP servers running with `mcp run --transport sse` SSE transport supports the same configuration options as Streamable HTTP: ```python from fastmcp.client.transports import SSETransport transport = SSETransport( url="https://api.example.com/sse", headers={"Authorization": "Bearer token"} ) client = Client(transport) ``` Use Streamable HTTP for new deployments unless you have specific infrastructure requirements for SSE. ## In-Memory Transport In-memory transport connects directly to a FastMCP server instance within the same Python process. This eliminates both subprocess management and network overhead, making it ideal for testing and development. * **Class:** `FastMCPTransport` Unlike STDIO transports, in-memory servers have full access to your Python process's environment. They share the same memory space and environment variables as your client codeβ€”no isolation or explicit environment passing required. ```python from fastmcp import FastMCP, Client import os mcp = FastMCP("TestServer") @mcp.tool def greet(name: str) -> str: prefix = os.environ.get("GREETING_PREFIX", "Hello") return f"{prefix}, {name}!" client = Client(mcp) async with client: result = await client.call_tool("greet", {"name": "World"}) ``` ## MCP JSON Configuration Transport This transport supports the emerging MCP JSON configuration standard for defining multiple servers: * **Class:** `MCPConfigTransport` ```python config = { "mcpServers": { "weather": { "url": "https://weather.example.com/mcp", "transport": "http" }, "assistant": { "command": "python", "args": ["./assistant.py"], "env": {"LOG_LEVEL": "INFO"} } } } client = Client(config) async with client: # Tools are namespaced by server weather = await client.call_tool("weather_get_forecast", {"city": "NYC"}) answer = await client.call_tool("assistant_ask", {"question": "What?"}) ``` # Community Showcase Source: https://gofastmcp.com/community/showcase High-quality projects and examples from the FastMCP community export const YouTubeEmbed = ({videoId, title}) => { return