-
Notifications
You must be signed in to change notification settings - Fork 752
Description
Summary
Add server-side handlers for the completion API to enable argument autocompletion for prompts and resource templates.
Specification Reference
- Spec URL: https://modelcontextprotocol.io/specification/2025-11-25/server/utilities/completion
- Section: Server Features > Utilities > Completion
The spec describes completion as:
Arguments may be auto-completed through the completion API.
This applies to:
- Prompt arguments (in
prompts/getrequests) - Resource template arguments (in URI template variable expansion)
Current Implementation
Status: Partially implemented
The client-side types and request handling exist, but server-side handlers are missing.
What Exists
File: mcp/types.go (lines 1098-1145)
Complete type definitions:
// CompleteRequest is sent to request completion options
type CompleteRequest struct {
Method string `json:"method"`
Params CompleteParams `json:"params,omitempty"`
}
type CompleteParams struct {
Meta *Meta `json:"_meta,omitempty"`
Ref CompletionRef `json:"ref"`
Argument CompletionArgument `json:"argument"`
}
// Completion references
type ResourceReference struct {
Type string `json:"type"` // "ref/resource"
URI string `json:"uri"`
}
type PromptReference struct {
Type string `json:"type"` // "ref/prompt"
Name string `json:"name"`
}
type CompletionRef interface {
isCompletionRef()
}
// Argument being completed
type CompletionArgument struct {
Name string `json:"name"`
Value string `json:"value"`
}
// Result with completion suggestions
type CompleteResult struct {
Completion Completion `json:"completion"`
}
type Completion struct {
Values []string `json:"values"`
Total *int `json:"total,omitempty"`
HasMore *bool `json:"hasMore,omitempty"`
}File: client/client.go (lines 470-485)
Client can send completion requests:
func (c *Client) Complete(ctx context.Context, params mcp.CompleteParams) (*mcp.CompleteResult, error) {
// ... implementation exists
}What's Missing
No server-side handler in server/server.go for:
completion/completemethod- Mapping in request dispatcher
- Support for registering completion providers
Required Changes
1. Add Completion Handler Interface
New file: server/completion.go
package server
import (
"context"
"github.com/mark3labs/mcp-go/mcp"
)
// CompletionProvider defines how to provide completion suggestions
type CompletionProvider interface {
// CompletePromptArgument provides completions for a prompt argument
CompletePromptArgument(ctx context.Context, promptName string, argument mcp.CompletionArgument) (*mcp.Completion, error)
// CompleteResourceArgument provides completions for a resource template argument
CompleteResourceArgument(ctx context.Context, uri string, argument mcp.CompletionArgument) (*mcp.Completion, error)
}
// DefaultCompletionProvider returns no completions (fallback)
type DefaultCompletionProvider struct{}
func (p *DefaultCompletionProvider) CompletePromptArgument(ctx context.Context, promptName string, argument mcp.CompletionArgument) (*mcp.Completion, error) {
return &mcp.Completion{
Values: []string{},
}, nil
}
func (p *DefaultCompletionProvider) CompleteResourceArgument(ctx context.Context, uri string, argument mcp.CompletionArgument) (*mcp.Completion, error) {
return &mcp.Completion{
Values: []string{},
}, nil
}2. Add Completion Support to Server
File: server/server.go
Add field to MCPServer:
type MCPServer struct {
// ... existing fields ...
completionProvider CompletionProvider
}Add configuration option:
// WithCompletionProvider sets a custom completion provider
func WithCompletionProvider(provider CompletionProvider) Option {
return func(s *MCPServer) {
s.completionProvider = provider
}
}Initialize in NewMCPServer:
func NewMCPServer(name string, version string, opts ...Option) *MCPServer {
// ... existing code ...
// Default to no completions
if s.completionProvider == nil {
s.completionProvider = &DefaultCompletionProvider{}
}
// ... rest of initialization ...
}3. Add Server Capability Declaration
File: mcp/types.go (around line 520)
Add to ServerCapabilities:
type ServerCapabilities struct {
// ... existing fields ...
Completions *struct{} `json:"completions,omitempty"`
}File: server/server.go
Add option to enable:
// WithCompletions enables the completion capability
func WithCompletions() Option {
return func(s *MCPServer) {
s.capabilities.Completions = &struct{}{}
}
}4. Implement Request Handler
File: server/server.go
Add handler method:
func (s *MCPServer) handleComplete(ctx context.Context, request mcp.JSONRPCRequest) mcp.JSONRPCResponse {
var params mcp.CompleteParams
if err := json.Unmarshal(request.Params, ¶ms); err != nil {
return mcp.NewErrorResponse(request.ID, mcp.INVALID_PARAMS, "Invalid completion parameters", nil)
}
var completion *mcp.Completion
var err error
// Route based on reference type
switch ref := params.Ref.(type) {
case *mcp.PromptReference:
completion, err = s.completionProvider.CompletePromptArgument(ctx, ref.Name, params.Argument)
case *mcp.ResourceReference:
completion, err = s.completionProvider.CompleteResourceArgument(ctx, ref.URI, params.Argument)
default:
return mcp.NewErrorResponse(request.ID, mcp.INVALID_PARAMS, "Unknown reference type", nil)
}
if err != nil {
return mcp.NewErrorResponse(request.ID, mcp.INTERNAL_ERROR, err.Error(), nil)
}
result := mcp.CompleteResult{
Completion: *completion,
}
return mcp.NewResponse(request.ID, result)
}Add to request dispatcher:
func (s *MCPServer) handleRequest(ctx context.Context, request mcp.JSONRPCRequest) mcp.JSONRPCResponse {
switch request.Method {
// ... existing cases ...
case "completion/complete":
return s.handleComplete(ctx, request)
// ... rest of cases ...
}
}Usage Examples
Server: Simple Static Completions
type MyCompletionProvider struct{}
func (p *MyCompletionProvider) CompletePromptArgument(ctx context.Context, promptName string, arg mcp.CompletionArgument) (*mcp.Completion, error) {
// Example: Complete language argument for a code review prompt
if promptName == "code_review" && arg.Name == "language" {
return &mcp.Completion{
Values: []string{"go", "python", "javascript", "rust"},
}, nil
}
return &mcp.Completion{Values: []string{}}, nil
}
func (p *MyCompletionProvider) CompleteResourceArgument(ctx context.Context, uri string, arg mcp.CompletionArgument) (*mcp.Completion, error) {
// Example: Complete file paths
if arg.Name == "path" {
files, _ := filepath.Glob(arg.Value + "*")
return &mcp.Completion{
Values: files,
}, nil
}
return &mcp.Completion{Values: []string{}}, nil
}
// Create server with completion support
server := NewMCPServer("myserver", "1.0.0",
WithCompletions(),
WithCompletionProvider(&MyCompletionProvider{}),
)Server: Dynamic Completions with Pagination
func (p *MyCompletionProvider) CompleteResourceArgument(ctx context.Context, uri string, arg mcp.CompletionArgument) (*mcp.Completion, error) {
if arg.Name == "user" {
// Query database for users matching arg.Value
users := queryUsers(arg.Value, 10) // Get first 10 matches
total := getTotalUserCount(arg.Value)
hasMore := total > len(users)
return &mcp.Completion{
Values: users,
Total: &total,
HasMore: &hasMore,
}, nil
}
return &mcp.Completion{Values: []string{}}, nil
}Client: Request Completions
// Already works - client implementation exists
result, err := client.Complete(ctx, mcp.CompleteParams{
Ref: &mcp.PromptReference{
Type: "ref/prompt",
Name: "code_review",
},
Argument: mcp.CompletionArgument{
Name: "language",
Value: "py", // User typed "py"
},
})
// result.Completion.Values = ["python"]Testing Requirements
- Add unit tests for completion handler
- Test prompt argument completion
- Test resource argument completion
- Test invalid reference types
- Test pagination (Total, HasMore fields)
- Add example in
examples/everything/main.go - Integration test with real client
Related Files
mcp/types.go:1098-1145- Type definitions (already exist)client/client.go:470-485- Client implementation (already exists)server/server.go- Add handler (NEW)server/completion.go- Provider interface (NEW)
Implementation Notes
This feature improves developer/user experience by enabling IDE-like autocompletion for MCP prompt and resource arguments. While not strictly required for spec compliance, it's a valuable enhancement mentioned in the spec.
The completion API is optional - servers declare support via the completions capability.
Current implementation status: Partially implemented - types and client exist, server handler missing (as of commit 670a95a)