Hướng dẫn cài đặt MCP Completion tương thích với GraphQL plugin
Back to graphqlMCP Completion là phần mở rộng của Model Context Protocol giúp server trả về gợi ý tự động hoàn thành cho tham số của prompt hoặc resource. Thay vì bắt người dùng nhớ chính xác mã sản phẩm, tên template, URI, locale hay loại dữ liệu, MCP client có thể gọi
completion/complete trong lúc người dùng đang nhập và hiển thị danh sách gợi ý giống autocomplete trong IDE. Theo MCP spec 2025-11-25, completion dùng request completion/complete, nhận ref, argument, có thể kèm context.arguments, và trả về completion.values, total, hasMore. Tham khảo: MCP Completion spec.Kiến trúc tổng quát
Trong GraphQL plugin, MCP server expose endpoint JSON-RPC tại:
POST /graphql/mcp
Method
completion/complete đã được route qua hệ thống event handler. GraphQL plugin không bắt bạn sửa dispatcher cho từng completion mới; bạn chỉ cần tạo thêm một event handler có tên đúng quy ước.
sequenceDiagram
participant Client as MCP Client
participant MCP as GraphQL MCP Endpoint
participant Router as MCP Method Handler
participant Completion as Completion Handler
Client->>MCP: completion/complete(ref, argument)
MCP->>Router: completion/complete_mcp_method_event
Router->>Router: tạo key = refName + "_" + argumentName
Router->>Completion: <key>_mcp_completion_event
Completion-->>Router: completion.values
Router-->>MCP: CompleteResult
MCP-->>Client: JSON-RPC result
Quy ước tương thích với GraphQL plugin
GraphQL plugin tìm completion handler bằng suffix:
_mcp_completion_event
Khi client gửi request completion, plugin tạo key theo công thức:
<refName>_<argumentName>
Sau đó plugin tìm event handler có event name:
<refName>_<argumentName>_mcp_completion_event
Trong đó:
ref.type = "ref/prompt" -> refName = ref.name ref.type = "ref/resource" -> refName = ref.uri argumentName -> argument.name
Ví dụ prompt tên
create_article, argument tên category thì completion handler cần trả về:create_article_category_mcp_completion_event
Cài đặt completion cho một prompt argument
Giả sử bạn có prompt
create_article và muốn autocomplete argument category.@EzySingleton public class CreateArticleCategoryMcpCompletionEventHandler extends AbstractEventHandler<Map<String, Object>, Object> { @Override public Object handleEventData(Map<String, Object> argument) { String value = argument != null ? (String) argument.getOrDefault("value", "") : ""; List<String> values = findCategories(value); return EzyMapBuilder.mapBuilder() .put( "completion", EzyMapBuilder.mapBuilder() .put("values", values) .put("total", values.size()) .put("hasMore", Boolean.FALSE) .toMap() ) .toMap(); } private List<String> findCategories(String keyword) { return Arrays.asList("news", "tutorial", "release-note") .stream() .filter(it -> it.startsWith(keyword)) .limit(100) .collect(Collectors.toList()); } @Override public String getEventName() { return "create_article_category_mcp_completion_event"; } }
Request kiểm thử
Sau khi restart plugin, có thể gọi thử:
{
"jsonrpc": "2.0",
"id": 1,
"method": "completion/complete",
"params": {
"ref": {
"type": "ref/prompt",
"name": "create_article"
},
"argument": {
"name": "category",
"value": "tu"
}
}
}
Response kỳ vọng:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"completion": {
"values": ["tutorial"],
"total": 1,
"hasMore": false
}
}
}
Lưu ý tương thích
Nếu không tìm thấy handler, GraphQL plugin trả completion rỗng:
{
"completion": {
"values": [],
"total": 0,
"hasMore": false
}
}
MCP spec yêu cầu server có completion nên khai báo capability
completions. Vì vậy, để client strict nhận biết tính năng này ngay từ initialize, nên đảm bảo response capabilities có thêm:
{
"capabilities": {
"completions": {}
}
}
Hiện flow completion của GraphQL plugin truyền
argument vào handler. Vì vậy handler đọc trực tiếp argument.name và argument.value; nếu muốn dùng context.arguments để gợi ý theo các argument đã chọn trước đó, cần mở rộng dispatcher để truyền thêm context hoặc gộp context vào dữ liệu gửi cho handler.Kết luận
Để cài MCP Completion tương thích với GraphQL plugin, phần quan trọng nhất là giữ đúng quy ước event name:
<refName>_<argumentName>_mcp_completion_event
Handler chỉ cần trả đúng shape
completion.values, total, hasMore. Với cách này, mỗi prompt hoặc resource có thể bổ sung autocomplete độc lập, không cần sửa danh sách method MCP hay cơ chế route chung của plugin.