Skip to content

Add McpApp, ProxyApp, middleware, context features, and sampling support#16

Merged
0xeb merged 20 commits into
mainfrom
feature/combined-release
Dec 5, 2025
Merged

Add McpApp, ProxyApp, middleware, context features, and sampling support#16
0xeb merged 20 commits into
mainfrom
feature/combined-release

Conversation

@0xeb
Copy link
Copy Markdown
Owner

@0xeb 0xeb commented Dec 5, 2025

Summary

Major feature release combining multiple branches:

  • Resource templates - RFC 6570 URI template support
  • McpApp with mounting - Compose apps with prefixed tools/resources/prompts
  • ProxyApp - Proxy to backend MCP servers
  • Middleware pipeline - Built-in logging, rate limiting, auth, error handling
  • Tool transformation - Rename args, hide params, add metadata
  • Context features - State management, logging, progress reporting, notifications
  • ServerSession - Bidirectional transport for server-initiated requests
  • Sampling API - Server-initiated LLM completions via MCP sampling protocol
  • Extended test coverage - 58 unit tests + 178 interop tests

0xeb and others added 20 commits December 4, 2025 08:13
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
@0xeb 0xeb force-pushed the feature/combined-release branch from b2e2234 to 3dbd48d Compare December 5, 2025 18:50
@0xeb 0xeb merged commit c6b06bf into main Dec 5, 2025
8 of 17 checks passed
@0xeb 0xeb deleted the feature/combined-release branch December 5, 2025 21:50
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