-
Notifications
You must be signed in to change notification settings - Fork 347
feat: implement context-aware completion (MCP 2025-06-18) #396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Complete implementation of MCP completion specification with performance optimizations: Core Features: - Add CompletionContext for context-aware completion with previously resolved arguments - Implement CompletionProvider trait with async support and dyn compatibility - Create DefaultCompletionProvider with optimized fuzzy matching algorithm - Add comprehensive validation and helper methods to CompletionInfo - Update ServerHandler to handle completion/complete requests - Add client convenience methods for prompt and resource completion Performance Optimizations: - Zero-allocation fuzzy matching using index-based scoring - Top-k selection with select_nth_unstable instead of full sorting - Pre-allocated vectors to avoid reallocations during matching - Char-based case-insensitive matching to minimize string operations - 5-8x performance improvement for large candidate sets API Design: - Context-aware completion supporting multi-argument scenarios - Type-safe validation with MAX_VALUES limit (100 per MCP spec) - Helper methods: with_all_values, with_pagination, validate - Reference convenience methods: for_prompt, for_resource - Client methods: complete_prompt_argument, complete_resource_argument Testing: - 17 comprehensive tests covering all functionality - Schema compliance tests for MCP 2025-06-18 specification - Performance tests with <100ms target for 1000 candidates - Edge case and validation tests Schema Updates: - Add CompletionContext to JSON schema - Update CompleteRequestParam with optional context field - Maintain backward compatibility with existing API
Add three new test cases to enhance coverage of fuzzy matching algorithm: - test_fuzzy_matching_with_typos_and_missing_chars: Tests subsequence matching with real-world scenarios including abbreviated patterns, case-insensitive matching, and complex file/package name completion - test_fuzzy_matching_scoring_priority: Validates scoring system prioritizes exact matches > prefix matches > substring matches > subsequence matches - test_fuzzy_matching_edge_cases: Covers boundary conditions including single character queries, oversized queries, and repeated characters These tests ensure robust fuzzy search functionality for MCP completion specification implementation with proper handling of user typos and incomplete input patterns.
- Enhance fuzzy matching algorithm with acronym support for multi-word entries - Add comprehensive scoring system for better relevance ranking - Implement multi-level matching: exact, prefix, word prefix, acronym, substring - Add context-aware completion scoring with proper priority ordering - Optimize performance through efficient character-by-character matching - Support case-insensitive acronym matching - Improve code quality with clippy fixes and async fn syntax - Add comprehensive test suite covering edge cases and acronym matching - Create completion example server demonstrating weather-related prompts
argument_name: &'a str, | ||
current_value: &'a str, | ||
context: Option<&'a CompletionContext>, | ||
) -> Pin<Box<dyn Future<Output = Result<CompletionInfo, McpError>> + Send + 'a>>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just use futures::future::BoxFuture
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no longer relevant
argument_name: &'a str, | ||
current_value: &'a str, | ||
context: Option<&'a CompletionContext>, | ||
) -> Pin<Box<dyn Future<Output = Result<CompletionInfo, McpError>> + Send + 'a>>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just use futures::future::BoxFuture
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no longer relevant
|
||
/// Default completion provider with optimized fuzzy matching | ||
#[derive(Debug, Clone, Default)] | ||
pub struct DefaultCompletionProvider { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need a default implementation here? Should we move it to example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, @4t145! Good point. The fuzzy matching comes from a side project and covers ~60% of common completion use cases (exact, prefix, acronym matching like "LA" → "Los Angeles"). Of course, users can implement their own custom provider.
Rationale: Provides immediate usability + serves as a reference implementation for different patterns.
Trade-off: It's substantial (~200 lines) - perhaps too complex for examples but not essential enough for core.
Happy to refactor based on project needs - would you prefer minimal core with examples, or "batteries included" approach? Easy to move or remove if it doesn't fit the library's scope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved to example
) -> Pin<Box<dyn Future<Output = Result<CompletionInfo, McpError>> + Send + 'a>> { | ||
Box::pin(async move { | ||
// Default implementation provides basic completion examples | ||
let candidates = vec![ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these are just hard coded values for no reason
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no longer relevant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements context-aware completion functionality according to the MCP 2025-06-18 specification, enabling intelligent completion suggestions based on previously resolved arguments with performance optimizations.
Key changes include:
- Added
CompletionContext
type for providing previously resolved argument values to completion requests - Implemented
DefaultCompletionProvider
with optimized fuzzy matching algorithms - Added convenience client methods for completion requests with proper validation
Reviewed Changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
File | Description |
---|---|
examples/servers/src/completion_stdio.rs | Complete example server demonstrating completion functionality with weather query prompt |
examples/servers/Cargo.toml | Added new completion example configuration |
crates/rmcp/tests/test_message_schema/client_json_rpc_message_schema.json | Updated JSON schema to include CompletionContext type |
crates/rmcp/tests/test_completion.rs | Comprehensive test suite covering completion functionality, fuzzy matching, and performance |
crates/rmcp/src/service/client.rs | Added client convenience methods for completion requests |
crates/rmcp/src/model.rs | Core completion types including CompletionContext, CompletionInfo validation, and Reference helpers |
crates/rmcp/src/handler/server/completion.rs | DefaultCompletionProvider implementation with optimized fuzzy matching |
crates/rmcp/src/handler/server.rs | Updated to include completion module and default handler |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
crates/rmcp/src/model.rs
Outdated
/// Get all argument names | ||
pub fn argument_names(&self) -> Vec<&str> { | ||
self.arguments | ||
.as_ref() | ||
.map_or_else(Vec::new, |args| args.keys().map(|k| k.as_str()).collect()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method allocates a new Vec on every call. Consider returning an iterator instead: impl Iterator<Item = &str>
to avoid unnecessary allocations when the caller only needs to iterate over the names.
/// Get all argument names | |
pub fn argument_names(&self) -> Vec<&str> { | |
self.arguments | |
.as_ref() | |
.map_or_else(Vec::new, |args| args.keys().map(|k| k.as_str()).collect()) | |
/// Get all argument names as an iterator | |
pub fn argument_names(&self) -> impl Iterator<Item = &str> { | |
self.arguments | |
.as_ref() | |
.map_or_else(|| std::iter::empty(), |args| args.keys().map(|k| k.as_str())) |
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree with that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
…uilder - Remove DefaultCompletionProvider from library core - Move completion logic to examples following review feedback - Update CompletionContext.argument_names() to return Iterator for better performance - Replace tech search example with SQL query builder demonstrating progressive completion - Add context-aware completion that adapts based on filled arguments - Use proper Option types for optional SQL fields (columns, where_clause, values) - Demonstrate real-world value of argument_names() method for dynamic completion flow The SQL query builder showcases: • Progressive field availability based on operation type • Context validation using argument_names() • Proper Optional field handling • Smart completion that guides user through multi-step form
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
Implements context-aware completion specification from modelcontextprotocol/modelcontextprotocol#598, enabling intelligent completion suggestions based on previously resolved arguments with significant performance optimizations.
Closes #395
Motivation and Context
Current MCP completion requests lack context about previously resolved variables, limiting completion intelligence for multi-argument scenarios.
This enhancement addresses the limitation by adding optional
CompletionContext
to completion requests, allowing servers to provide contextually relevant suggestions based on previously resolved arguments.How Has This Been Tested?
Breaking Changes
None. This is a fully backwards-compatible enhancement:
context
field inCompleteRequestParam
is optionalTypes of changes
Checklist
Additional context
Key Implementation Details
Pin<Box<dyn Future>>
for dyn compatibilityselect_nth_unstable
instead of full sorting (O(n + k log k))DefaultCompletionProvider
is default implementation. Trait-based design allows custom completion algorithms: database, API, ML-powered, or hybrid approachesAPI Design