Add McpApp, ProxyApp, middleware, context features, and sampling support#16
Merged
Conversation
Add patterns for: - Additional build directories (out/, cmake-build-*/) - IDE files (.vscode/, .idea/, swap files) - Compiled objects (*.o, *.obj, *.a, *.lib, *.so, *.dll) - Executables (*.exe, *.out) - CMake generated files - Package managers (vcpkg_installed/, _deps/) - OS files (.DS_Store, Thumbs.db)
Implement parameterized resource URIs like "weather://{city}/current":
- ResourceTemplate struct with uri_template, provider, and parsed info
- URI template parsing with RFC 6570 subset support:
- {var} - path parameter matching [^/?#]+
- {var*} - wildcard parameter matching .+
- {?a,b,c} - query parameters
- URL encoding/decoding utilities
- ResourceManager.register_template() and list_templates()
- ResourceManager.read() now matches templates if exact URI not found
- MCP handler support for resources/templates/list method
- Unit tests covering all template features
Implement app mounting feature for composing MCP servers: - Add McpApp class bundling Server + managers with mount support - Support mounting sub-apps with prefixes (tools: prefix_name, resources: scheme://prefix/path, prompts: prefix_name) - Implement aggregated listing (list_all_tools/resources/prompts) - Implement routing to dispatch calls to correct mounted app - Support nested mounting (multi-level composition) - Add MCP handler overload for McpApp - Add comprehensive unit tests (12 tests covering all scenarios) This mirrors Python fastmcp's mounting capability for server composition.
- ProxyApp class with client factory pattern for backend connections - Aggregation of local + remote tools/resources/prompts - Local-first routing: try local managers, fall back to remote - MCP handler support for ProxyApp - 9 unit tests covering all proxy functionality
- Add as_proxy parameter to mount() for proxy-based communication - Add InProcessMcpTransport for in-process MCP handler communication - Add list_all_tools_info() method for proper proxy tool metadata - Update aggregation (tools, resources, prompts) to include proxy mounts - Update routing (invoke_tool, read_resource, get_prompt) for proxy mounts - Add 9 proxy mode mounting tests covering tools, resources, prompts - Fix MCP handler to use list_all_tools_info() for proxy compatibility
- MiddlewareContext: Request context with method, message, source, type - Middleware base class with virtual hooks for each MCP operation - MiddlewarePipeline: Chains middleware with CallNext pattern - Built-in implementations: * LoggingMiddleware: Request/response logging with optional payload * TimingMiddleware: Execution time tracking with per-method stats * CachingMiddleware: Response caching with TTL and size limits * RateLimitingMiddleware: Token bucket rate limiting * ErrorHandlingMiddleware: Exception->MCP error conversion - Comprehensive test suite (11 tests)
Implements ArgTransform and TransformedTool for renaming, hiding, and modifying tool arguments with schema transformation support.
Enhances Context class with Python fastmcp parity: - State management (set_state/get_state with std::any) - Logging with levels (debug, info, warning, error) - Progress reporting with callback support - List change notifications - client_id and progress_token accessors
- Add test_e2e_tool_logging_to_notifications: verifies Context logging generates proper MCP notification JSON format - Add test_e2e_context_in_tool_handler: verifies Context factory pattern in tool handlers - Add SSE notification public API: send_notification() and broadcast_notification() methods in SseServerWrapper - Add integration test for Context → SSE API wiring verification
Tests cover tool registration, lookup, invocation, schema retrieval, and context argument exclusion. Mirrors Python test_tool_manager.py coverage.
Implement MCP sampling support for server-to-client LLM requests: - Add SamplingMessage, SamplingParams, SamplingResult types - Add sample() method with string and message vector overloads - Add sample_text() convenience method - Add has_sampling() check and set_sampling_callback() - Add 10 unit tests covering all sampling functionality This is the foundation for sampling; actual transport wiring will follow in subsequent commits.
Infrastructure for server-initiated requests to clients: - ServerSession class with send_request() and handle_response() - Request ID generation and promise/future correlation - Client capability tracking (sampling, elicitation, roots) - RequestTimeoutError and ClientError exception types - Static helpers: is_request(), is_response(), is_notification() - Thread-safe with mutex-protected pending request map - 10 unit tests including concurrent request handling
Connect ServerSession to SSE transport for bidirectional requests: - Create ServerSession for each new SSE connection - Wire send callback to push events to connection queue - Route incoming responses through ServerSession::handle_response() - Distinguish client requests (handle normally) from server responses - Add get_session() and connection_count() public methods - Make conns_mutex_ mutable to support const methods This enables server-initiated requests (sampling, elicitation) via SSE.
Wire Context.sample() to ServerSession for server-initiated sampling: - Add SessionAccessor type for retrieving ServerSession by session_id - make_mcp_handler_with_sampling() creates handler with sampling support - Inject session_id into request params._meta for handler access - Advertise sampling capability in initialize response - Convenience overload accepting SseServerWrapper for easy integration
Extract capabilities from initialize request params and store in ServerSession. This enables checking if client supports sampling/ elicitation/roots before attempting server-initiated requests.
Fixes CI format-check failures.
GCC 13.3 rejects `= {}` as default argument for aggregate structs even
with `= default` constructor. Use overloaded constructors instead.
- Change on_message to operator() for LoggingMiddleware, TimingMiddleware, and RateLimitingMiddleware to properly intercept all requests - Fix mounting.cpp test assertions: remove extra quotes from expected text - Fix test_middleware_pipeline.cpp: set ctx.type="" to test on_message fallback
b2e2234 to
3dbd48d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Major feature release combining multiple branches: