Skip to content

feat(parity): fastmcpp 3.1.1 — post-v3.1.0 sweep (F1–F9)#41

Merged
0xeb merged 4 commits intomainfrom
work
Apr 19, 2026
Merged

feat(parity): fastmcpp 3.1.1 — post-v3.1.0 sweep (F1–F9)#41
0xeb merged 4 commits intomainfrom
work

Conversation

@0xeb
Copy link
Copy Markdown
Owner

@0xeb 0xeb commented Apr 19, 2026

Summary

Closes the seven parity gaps surfaced by the independent post-v3.1.0 review
against Python fastmcp at v3.1.0-89-g00ed31f2. Six mirror specific upstream
commits; F6 is a regression lock (fastmcpp's direct-dispatch mount model
didn't carry the Python bug), and F7 adds a brand-new public API
(FastMCP::add_custom_route) that previously didn't exist in the C++ port.

The most user-visible change: resource templates with typed query parameters
now coerce values and reject malformed ones at the server instead of silently
passing strings through. search://{q}{?verbose} with verbose=banana now
surfaces a ValidationError / JSON-RPC -32602 rather than pass-through.

New public interfaces

  • fastmcpp::resources::ParamKind, ResourceTemplate::build_typed_params()
  • fastmcpp::util::read_fastmcp_metadata()
  • fastmcpp::util::versions::dedupe_with_versions<T>()
  • fastmcpp::tools::Tool::meta() / set_meta()
  • fastmcpp::CustomRoute, FastMCP::add_custom_route(), FastMCP::all_custom_routes()
  • HttpServerWrapper::set_custom_routes()

ABI: Tool and FastMCP gained tail-end fields only. Existing field order
and size unchanged.

0xeb added a commit that referenced this pull request Apr 19, 2026
Addresses the CI failures on PR #41:

- Format-check: clang-format pass across 26 files flagged by the
  workflow. Most are pre-existing drift (client/**, providers/search/**,
  server/streamable_http_server.*, mcp/handler.cpp, etc.) unrelated to
  F1-F9; the remainder are the F1-F9 surface itself.
- base.hpp compile error on gcc/clang: splits
  BaseSearchTransform(Options opts = {}) into a defaulted no-arg
  delegating ctor + explicit Options ctor, fixing the
  "default member initializer needed within definition of enclosing
  class outside of member functions" diagnostic. Pre-existing on main
  since 2026-03-18.
- streaming_sse and example_streaming_demo flakes: both handlers now
  return a proper JSON-RPC reply (jsonrpc/id/result) so the server's
  post-notification dispatch path no longer drops them as malformed.
  Pre-existing on main.

No functional change to F1-F9 logic.
@0xeb 0xeb closed this Apr 19, 2026
@0xeb 0xeb reopened this Apr 19, 2026
0xeb added a commit that referenced this pull request Apr 19, 2026
0xeb added 3 commits April 19, 2026 12:34
Squash of feature/parity-v3.1.0-post-sync (commit 6f5406c) onto main.
Implements the seven parity gaps identified in the post-v3.1.0 review
against Python fastmcp v3.1.0-89-g00ed31f2:

- F1 typed query-param coercion on resource templates (mirrors
  Python 9ccaef2b); ValidationError on invalid bool/int/number.
- F2 defensive read_fastmcp_metadata helper for _meta.fastmcp /
  _meta._fastmcp (mirrors 706b56d5). Not yet wired into any
  production path.
- F3 URI-template regex guard rethrowing as ValidationError
  (hardening on top of 5ff64ce2). Runtime path currently unreachable
  via any template string given escape_regex() design.
- F4 CatalogTransform::get_tool_catalog dedup with
  _meta.fastmcp.versions injection + Tool::meta()/set_meta()
  (mirrors 03673d9f + 0142fefe). New util/versions.hpp with
  dedupe_with_versions<T>().
- F5 preflight rename-collision detection in
  build_transformed_schema (mirrors d316f193).
- F6 mount + query-params: N/A under fastmcpp's direct-dispatch
  mount, locked by mount_query_params.cpp regression test.
- F7 FastMCP::add_custom_route / all_custom_routes +
  HttpServerWrapper::set_custom_routes (mirrors 68e76fea; ports
  the @server.custom_route API that didn't previously exist in
  fastmcpp).
- F8 manual-redirect policy comment in StreamableHttpTransport
  (mirrors 226bfb49).
- F9 version bump 3.1.0 -> 3.1.1.

Bonus: fixes pre-existing assertion bug in
tests/mcp/server_handler.cpp where the tools/list size assertion
lagged behind the audio_tool addition in upstream a817ecf.

Verification:
- Submodule ctest Release suite: 101/103 passing (2 pre-existing
  flakes fail identically on clean 9afa99f: fastmcpp_streaming_sse
  and fastmcpp_example_streaming_demo).
- Private monorepo interop (parent ports repo): 20/20 across
  F1/F2/F3/F4/F5/F7; stable over 5 back-to-back runs.

See kb/sync/review_of_parity_branch.md in the parent ports repo
for the full independent review.
Addresses the CI failures on PR #41:

- Format-check: clang-format pass across 26 files flagged by the
  workflow. Most are pre-existing drift (client/**, providers/search/**,
  server/streamable_http_server.*, mcp/handler.cpp, etc.) unrelated to
  F1-F9; the remainder are the F1-F9 surface itself.
- base.hpp compile error on gcc/clang: splits
  BaseSearchTransform(Options opts = {}) into a defaulted no-arg
  delegating ctor + explicit Options ctor, fixing the
  "default member initializer needed within definition of enclosing
  class outside of member functions" diagnostic. Pre-existing on main
  since 2026-03-18.
- streaming_sse and example_streaming_demo flakes: both handlers now
  return a proper JSON-RPC reply (jsonrpc/id/result) so the server's
  post-notification dispatch path no longer drops them as malformed.
  Pre-existing on main.

No functional change to F1-F9 logic.
@0xeb 0xeb merged commit 88dca2f into main Apr 19, 2026
7 checks passed
@0xeb 0xeb deleted the work branch April 19, 2026 20:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant