1.完成概述 #
Model Context Protocol (MCP) 为服务器提供了一种标准化方式,用于为提示符和资源URI提供参数自动补全建议。这实现了类似IDE的丰富体验,用户在输入参数值时能获得上下文相关的建议。
2.用户交互模型 #
MCP中的Completion功能旨在支持类似IDE代码补全的交互式用户体验。
例如,应用程序可能在用户输入时以下拉或弹出菜单的形式显示补全建议,并提供筛选和从可用选项中选择的功能。
然而,实现方可以自由选择适合其需求的任何接口模式来暴露完成功能——协议本身并未强制规定任何特定的用户交互模型。
3.能力声明 #
支持补全功能的服务器必须声明completions能力:
{
"capabilities": {
"completions": {}
}
}4.协议消息 #
4.1 请求补全 #
为了获取补全建议,客户端会发送一个completion/complete通过引用类型指定正在完成的内容的请求
请求:
{
"jsonrpc": "2.0",
"id": 1,
"method": "completion/complete",
"params": {
"ref": {
"type": "ref/prompt",
"name": "code_review"
},
"argument": {
"name": "language",
"value": "py"
}
}
}响应:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"completion": {
"values": ["python", "pytorch", "pyside"],
"total": 10,
"hasMore": true
}
}
}对于包含多个参数的提示或URI模板,客户端应将之前的补全内容包含在内。context.arguments为后续请求提供上下文的对象。
请求:
{
"jsonrpc": "2.0",
"id": 1,
"method": "completion/complete",
"params": {
"ref": {
"type": "ref/prompt",
"name": "code_review"
},
"argument": {
"name": "framework",
"value": "fla"
},
"context": {
"arguments": {
"language": "python"
}
}
}
}响应:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"completion": {
"values": ["flask"],
"total": 1,
"hasMore": false
}
}
}4.4 引用类型 #
该协议支持两种类型的completion引用:
| 类型 | 描述 | 示例 |
|---|---|---|
ref/prompt |
按名称引用提示 | {"type": "ref/prompt", "name": "code_review"} |
ref/resource |
引用一个资源URI | {"type": "ref/resource", "uri": "file:///{path}"} |
4.5 完成结果 #
服务器返回一个按相关性排序的补全值数组,其中包含:
- 每次响应最多返回100个项目
- 可选的总匹配数
- 表示是否存在更多结果的布尔值
5.消息流 #

6.数据类型 #
6.1 完成请求 #
ref- 一个PromptReference或ResourceReferenceargument- 包含的对象:name- 参数名称value- 当前值
context- 包含的对象:arguments- 已解析参数名与其值的映射关系
6.2 完整结果 #
completion- 包含的对象:values- 建议数组(最多100条)total- 可选的总匹配数hasMore- 附加结果标志
7.错误处理 #
服务器应该返回标准JSON-RPC错误以处理常见故障情况:
- 未找到方法:
-32601(不支持此功能) - 无效的提示名称:
-32602(参数无效) - 缺少必要参数:
-32602(参数无效) - 内部错误:
-32603(内部错误)
8.实施注意事项 #
服务器应该:
- 按相关性排序返回建议
- 在适当的地方实现模糊匹配
- 速率限制完成请求
- 验证所有输入
客户端应该:
- 防抖快速完成请求
- 在适当情况下缓存补全结果
- 优雅处理缺失或不完整的结果
9.安全 #
实现必须:
- 验证所有完成输入
- 实施适当的速率限制
- 控制对敏感建议的访问权限
- 防止基于完成的信息泄露
10.最佳实践 #
10.1 服务器端实现 #
- 智能排序 - 根据用户输入和上下文提供最相关的建议
- 模糊匹配 - 支持部分匹配和拼写错误容忍
- 性能优化 - 实现高效的搜索算法和缓存机制
- 安全控制 - 确保敏感信息不会通过补全泄露
10.2 客户端实现 #
- 用户体验 - 提供流畅的补全体验,避免延迟
- 智能触发 - 在合适的时机触发补全请求
- 结果缓存 - 缓存常用结果以提高响应速度
- 错误处理 - 优雅处理网络错误和服务器错误
10.3 性能优化 #
- 请求防抖 - 避免频繁的补全请求
- 结果分页 - 支持大量结果的分页显示
- 缓存策略 - 实现合理的缓存策略
- 异步处理 - 使用异步处理避免阻塞用户界面
11.常见应用场景 #
11.1 提示参数补全 #
- 代码语言选择
- 框架和库名称
- 文件路径和URI
- 配置参数值
11.2 资源URI补全 #
- 文件系统路径
- 数据库连接字符串
- API端点URL
- 网络资源地址
11.3 动态内容补全 #
- 基于用户历史的建议
- 基于当前上下文的建议
- 基于权限的建议
- 基于性能的建议
12.实现示例 #
12.1 Python服务器示例 #
# 导入json模块
import json
# 从typing模块导入类型提示
from typing import List, Dict, Any
# 定义补全服务器类
class CompletionServer:
# 处理补全请求的方法
def handle_completion(self, ref: Dict[str, Any], argument: Dict[str, Any], context: Dict[str, Any] = None) -> Dict[str, Any]:
"""处理补全请求"""
# 根据引用类型判断处理方式
if ref["type"] == "ref/prompt":
# 如果是提示类型,调用处理提示补全的方法
return self._handle_prompt_completion(ref, argument, context)
elif ref["type"] == "ref/resource":
# 如果是资源类型,调用处理资源补全的方法
return self._handle_resource_completion(ref, argument, context)
# 如果类型不匹配,返回空结果
return {"values": [], "total": 0, "hasMore": False}
# 处理提示补全的方法
def _handle_prompt_completion(self, ref: Dict[str, Any], argument: Dict[str, Any], context: Dict[str, Any]) -> Dict[str, Any]:
"""处理提示补全"""
# 获取参数名称
name = argument["name"]
# 获取参数值
value = argument["value"]
# 根据参数名称选择建议来源
if name == "language":
# 如果是语言参数,获取语言建议
suggestions = self._get_language_suggestions(value)
elif name == "framework":
# 如果是框架参数,获取框架建议
suggestions = self._get_framework_suggestions(value, context)
else:
# 其他参数返回空列表
suggestions = []
# 返回建议结果,最多100条
return {
"values": suggestions[:100], # 限制最多100个结果
"total": len(suggestions),
"hasMore": len(suggestions) > 100
}
# 获取语言建议的方法
def _get_language_suggestions(self, prefix: str) -> List[str]:
"""获取语言建议"""
# 预设支持的语言列表
languages = ["python", "javascript", "java", "cpp", "rust", "go", "swift", "kotlin"]
# 返回以prefix开头的语言(忽略大小写)
return [lang for lang in languages if lang.startswith(prefix.lower())]
# 获取框架建议的方法
def _get_framework_suggestions(self, prefix: str, context: Dict[str, Any]) -> List[str]:
"""获取框架建议"""
# 预设不同语言对应的框架列表
frameworks = {
"python": ["flask", "django", "fastapi", "tornado", "bottle"],
"javascript": ["react", "vue", "angular", "express", "koa"],
"java": ["spring", "hibernate", "struts", "jsf", "wicket"]
}
# 从上下文中获取已选语言,默认为python
language = context.get("arguments", {}).get("language", "python")
# 获取该语言下的可用框架
available_frameworks = frameworks.get(language, [])
# 返回以prefix开头的框架(忽略大小写)
return [fw for fw in available_frameworks if fw.startswith(prefix.lower())]12.2 JavaScript客户端示例 #
// 定义一个补全客户端类
class CompletionClient {
// 构造函数,接收服务器地址
constructor(serverUrl) {
// 保存服务器地址
this.serverUrl = serverUrl;
// 初始化防抖定时器
this.debounceTimer = null;
// 初始化缓存Map
this.cache = new Map();
}
// 异步请求补全的方法
async requestCompletion(ref, argument, context = null) {
// 生成缓存键
const cacheKey = this._getCacheKey(ref, argument, context);
// 如果缓存中已有结果,直接返回
if (this.cache.has(cacheKey)) {
return this.cache.get(cacheKey);
}
// 清除上一次的防抖定时器
clearTimeout(this.debounceTimer);
// 返回一个Promise,处理防抖逻辑
return new Promise((resolve) => {
// 设置150ms防抖延迟
this.debounceTimer = setTimeout(async () => {
try {
// 发送请求获取补全结果
const response = await this._sendRequest(ref, argument, context);
// 将结果存入缓存
this.cache.set(cacheKey, response);
// 返回结果
resolve(response);
} catch (error) {
// 捕获异常并输出错误信息
console.error('Completion request failed:', error);
// 返回空补全结果
resolve({ values: [], total: 0, hasMore: false });
}
}, 150); // 150ms防抖延迟
});
}
// 实际发送请求的方法
async _sendRequest(ref, argument, context) {
// 构造请求体
const request = {
jsonrpc: "2.0",
id: Date.now(),
method: "completion/complete",
params: {
ref,
argument,
// 如果有context则合并进params
...(context && { context })
}
};
// 发送POST请求到服务器
const response = await fetch(this.serverUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
});
// 如果响应状态不是OK,抛出异常
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
// 解析响应JSON
const result = await response.json();
// 返回补全结果
return result.result.completion;
}
// 生成缓存键的方法
_getCacheKey(ref, argument, context) {
// 将参数序列化为字符串作为缓存键
return JSON.stringify({ ref, argument, context });
}
// 清除缓存的方法
clearCache() {
// 清空缓存Map
this.cache.clear();
}
}13.总结 #
MCP完成功能为应用程序提供了强大的参数补全能力,具有以下特点:
- 智能建议 - 基于上下文提供相关建议
- 高性能 - 支持缓存和防抖优化
- 安全性 - 内置安全控制和访问限制
- 灵活性 - 支持多种引用类型和参数格式
- 可扩展性 - 易于集成和自定义
通过遵循最佳实践和安全指南,完成功能可以显著提升用户体验,同时确保系统的安全性和性能。
参考资源: