MCP server trong GraphQL plugin là một lớp adapter giúp MCP client truy cập các công cụ, tài nguyên và prompt phục vụ việc làm việc với GraphQL/admin runtime. Bên ngoài, server nhận HTTP request theo chuẩn JSON-RPC 2.0. Bên trong, server chuyển từng MCP method thành event nội bộ và để các event handler xử lý logic cụ thể.

Kiến Trúc Tổng Quát

MCP server không đặt toàn bộ logic vào HTTP controller. Controller chỉ làm phần giao tiếp protocol:
  • nhận request từ MCP client,
  • kiểm tra JSON-RPC version,
  • gắn admin access token vào request params,
  • chuyển MCP method thành event name nội bộ,
  • dispatch event,
  • đóng gói kết quả thành JSON-RPC response.
Phần khả năng thật của server nằm trong các event handler. Mỗi MCP method, tool, resource, prompt hoặc completion đều được đăng ký bằng một quy ước tên event.
Endpoint chính:
POST /graphql/mcp
Endpoint metadata:
GET /graphql/mcp
GET /graphql/mcp trả về tên server, protocol version, endpoint và các method hiện được hỗ trợ:
initialize
notifications/initialized
ping
tools/list
tools/call
resources/list
resources/read
prompts/list
prompts/get
completion/complete
logging/setLevel

Luồng Xử Lý Request

Một MCP request đi qua luồng sau:
flowchart TD
    A[MCP client] --> B[HTTP endpoint]
    B --> C[Kiểm tra JSON-RPC 2.0]
    C --> D[Gắn admin access token]
    D --> E[Đổi method thành event name]
    E --> F[Dispatch tới event handler]
    F --> G[Xử lý tool/resource/prompt/completion]
    G --> H[Trả result]
    H --> I[Đóng gói JSON-RPC response]
Ví dụ request:
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {}
}
Server sẽ chuyển tools/list thành event nội bộ tương ứng, gọi handler, rồi trả về danh sách tools.

Khởi Tạo Server

Khi client gọi:
initialize
server trả về:
  • protocolVersion
  • capabilities
  • serverInfo
  • instructions
Capabilities hiện tại:
{
  "tools": {
    "listChanged": true
  },
  "resources": {
    "listChanged": true
  },
  "prompts": {
    "listChanged": true
  },
  "logging": {}
}
Điều này cho biết server hỗ trợ tools, resources, prompts và logging. listChanged = true thể hiện danh sách tools/resources/prompts có thể thay đổi giữa các lần chạy hoặc khi plugin được cập nhật.
Sau initialize, client có thể gửi:
notifications/initialized
Server xử lý notification này bằng response no content.

JSON-RPC Response Và Error

Request hợp lệ có dạng:
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "ping",
  "params": {}
}
Response thường có dạng:
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {}
}
Nếu request không hợp lệ, server trả lỗi JSON-RPC:
{
  "jsonrpc": "2.0",
  "id": null,
  "error": {
    "code": -32600,
    "message": "Invalid JSON-RPC request"
  }
}
Nếu method không tồn tại:
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32601,
    "message": "Method not found: ..."
  }
}
Nếu request không có id, server xem đó là notification và trả no content.

Bảo Mật

MCP endpoint yêu cầu admin authentication. Server lấy admin access token hiện tại và gắn vào:
params
params.arguments
nếu arguments tồn tại.
Nhờ đó, tool hoặc handler phía sau có thể tiếp tục gọi các service cần quyền admin theo đúng context của người dùng hiện tại. MCP server không phải endpoint public mở tự do; nó là giao diện tự động hóa cho MCP client đã được xác thực.

Tools

Tools được đăng ký bằng hai event handler:
<tool_name>_mcp_tool_schema_event
<tool_name>_mcp_tool_event
Schema handler trả metadata:
{
  "name": "tool_name",
  "title": "Tool Title",
  "description": "...",
  "inputSchema": {},
  "outputSchema": {}
}
Khi client gọi:
tools/list
server scan các handler có suffix _mcp_tool_schema_event, gọi từng handler để lấy metadata, sắp xếp theo tên tool và trả về:
{
  "tools": []
}
Khi client gọi:
tools/call
server đọc params.name, tìm handler <tool_name>_mcp_tool_event, rồi truyền params.arguments vào handler.
Tool result thường có dạng:
{
  "content": [
    {
      "type": "text",
      "text": "..."
    }
  ],
  "structuredContent": {},
  "isError": false
}
Nếu tool không tồn tại hoặc params không hợp lệ, server trả tool result có isError = true.

Các Tool Hiện Có

Các tool schema hiện được đăng ký gồm:
ping
get_admin_class_schema
get_admin_entity_class_schema
get_admin_event_schema
get_admin_event_schema_by_name
get_admin_template_parameters_schema
get_admin_template_parameters_schema_by_type_and_name
get_admin_view_schema
get_admin_view_schema_by_uri
get_admin_ezy_function_schema
get_admin_swagger
get_web_class_schema
get_web_event_schema
get_web_event_schema_by_name
get_web_view_schema
get_web_view_schema_by_uri
get_web_ezy_function_schema
get_web_swagger
get_sql_scripts
Nhóm tool này phục vụ các nhu cầu chính:
  • kiểm tra kết nối MCP,
  • lấy schema class trong admin/web runtime,
  • lấy entity class schema,
  • lấy event schema,
  • lấy view schema,
  • lấy template parameter schema,
  • lấy ezy-function schema,
  • lấy Swagger/OpenAPI,
  • lấy SQL scripts.
Với dữ liệu nhỏ hoặc truy vấn theo tên cụ thể, tool có thể trả trực tiếp nội dung qua contentstructuredContent.
Với artifact lớn như Swagger, schema tổng hợp hoặc SQL scripts, tool thường trả hướng dẫn download qua URL thay vì nhồi toàn bộ nội dung vào MCP response. Cách này tránh làm phình context của MCP client.

Resources

Resources được đăng ký bằng hai event handler:
<resource_uri>_mcp_resource_schema_event
<resource_uri>_mcp_resource_event
Khi client gọi:
resources/list
server scan các handler có suffix _mcp_resource_schema_event, gọi từng handler để lấy metadata và trả về:
{
  "resources": []
}
Khi client gọi:
resources/read
server đọc params.uri, tìm handler <resource_uri>_mcp_resource_event, rồi trả nội dung resource.
Resource result thường có dạng:
{
  "contents": [
    {
      "uri": "guide://...",
      "mimeType": "text/plain",
      "text": "..."
    }
  ]
}
Resource hiện có:
guide://mcp-tool-installation
guide://ezy-function-installation
Hai resource này dùng để hướng dẫn cách thêm MCP tool mới và cách thêm ezy-function event handler.

Prompts

Prompts giúp MCP client lấy prompt template có cấu trúc thay vì phải tự đoán workflow.
Prompt được đăng ký bằng hai event handler:
<prompt_name>_mcp_prompt_schema_event
<prompt_name>_mcp_prompt_event
Khi client gọi:
prompts/list
server scan các handler có suffix _mcp_prompt_schema_event, gọi từng handler để lấy metadata và trả về:
{
  "prompts": []
}
Prompt schema có dạng:
{
  "name": "prompt_name",
  "title": "Prompt Title",
  "description": "...",
  "arguments": []
}
Khi client gọi:
prompts/get
server đọc params.name, tìm handler <prompt_name>_mcp_prompt_event, rồi truyền params.arguments vào handler.
Prompt result có dạng:
{
  "description": "...",
  "messages": [
    {
      "role": "user",
      "content": {
        "type": "text",
        "text": "..."
      }
    }
  ]
}
Nếu prompt không tồn tại, server trả một prompt result chứa message mô tả lỗi. Đây là lỗi ở tầng prompt, không phải JSON-RPC protocol error.

Prompt Hiện Có

Prompt hiện được đăng ký:
generate_checkout_link
Prompt này sinh instruction để tạo checkout URL trực tiếp cho một hoặc nhiều sản phẩm.
Arguments:
product_codes
quantities
color_names
size_names
material_names
clear_shopping_cart
product_codes là bắt buộc. Các argument còn lại là tùy chọn.
Prompt trả về hướng dẫn tạo URL theo các trường hợp:
  • một sản phẩm,
  • một sản phẩm kèm option,
  • nhiều sản phẩm,
  • clear shopping cart trước khi checkout,
  • URL-encode giá trị có dấu hoặc khoảng trắng.
Kết quả mong muốn từ AI client là checkout URL cuối cùng.

Completion

Server có method:
completion/complete
Completion handler dùng refargument để tìm completion cụ thể.
Quy tắc key:
<ref_name_or_uri>_<argument_name>
Nếu ref.typeref/resource, server dùng ref.uri.
Nếu không, server dùng ref.name.
Sau đó server tìm handler:
<ref_name_or_uri>_<argument_name>_mcp_completion_event
Nếu tìm thấy, handler trả:
{
  "completion": {
    "values": [],
    "total": 0,
    "hasMore": false
  }
}
Trong code hiện tại có method completion/complete và cơ chế registry completion, nhưng chưa thấy completion handler cụ thể được đăng ký. Vì vậy, ở trạng thái hiện tại, completion sẽ trả danh sách rỗng trừ khi plugin/module khác bổ sung handler có suffix _mcp_completion_event.

Logging

Server hỗ trợ method:
logging/setLevel
Method này nhận field:
level
Các giá trị hợp lệ:
debug
info
notice
warning
error
critical
alert
emergency
Nếu level hợp lệ, server lưu level hiện tại trong memory của handler và trả result rỗng. Nếu level không hợp lệ hoặc không có level, server không thay đổi gì và vẫn trả result rỗng.
Cần lưu ý: implementation hiện tại chỉ lưu level trong MCP handler. Không nên hiểu rằng method này đã tự động thay đổi toàn bộ logger runtime của platform, trừ khi có thành phần khác đọc và áp dụng giá trị này.

Streaming Artifact Lớn

Controller có nhánh xử lý đặc biệt cho kết quả dạng input stream supplier. Khi handler trả loại kết quả này, server sẽ stream nội dung vào JSON-RPC result thay vì build toàn bộ object trong memory trước.
Cơ chế này hữu ích cho artifact lớn như schema tổng hợp hoặc SQL scripts. Tuy vậy, nhiều tool hiện vẫn chọn cách trả hướng dẫn download URL để tránh đưa dữ liệu quá lớn vào context của MCP client.

Caching Và Registry

Các method dạng list/get/call scan singleton event handlers lần đầu, sau đó cache map handler trong memory bằng field volatile.
Các nhóm có cache gồm:
tools/list
tools/call
resources/list
resources/read
prompts/list
prompts/get
completion/complete
Ưu điểm là request sau nhanh hơn. Hạn chế là nếu thêm handler mới khi runtime đang chạy, registry trong instance hiện tại có thể chưa tự cập nhật. Thực tế triển khai thường cần restart plugin sau khi thêm MCP handler mới.
initialize khai báo listChanged = true cho tools/resources/prompts, với HTTP request-response thuần thì việc server chủ động gửi notification thay đổi danh sách còn phụ thuộc vào transport/client. Cách chắc chắn là client gọi lại tools/list, resources/list, hoặc prompts/list.

Cách Mở Rộng

Để thêm tool mới:
<tool_name>_mcp_tool_schema_event
<tool_name>_mcp_tool_event
Schema handler trả metadata, input schema và output schema. Tool handler xử lý arguments và trả content, structuredContent nếu cần, và isError.
Để thêm resource mới:
<resource_uri>_mcp_resource_schema_event
<resource_uri>_mcp_resource_event
Schema handler trả metadata resource. Resource handler trả contents.
Để thêm prompt mới:
<prompt_name>_mcp_prompt_schema_event
<prompt_name>_mcp_prompt_event
Schema handler trả title, description và arguments. Prompt handler trả description và messages.
Để thêm completion cho một argument:
<ref_name_or_uri>_<argument_name>_mcp_completion_event
Ví dụ completion cho argument product_codes của prompt generate_checkout_link sẽ dùng key:
generate_checkout_link_product_codes
và event name:
generate_checkout_link_product_codes_mcp_completion_event

Ranh Giới Với GraphQL Và REST

MCP server không tự động biến GraphQL thành REST API, cũng không tự động thực thi GraphQL operation thay client.
Vai trò của MCP server là expose metadata, schema, prompt và công cụ hỗ trợ để MCP client hiểu hệ thống tốt hơn:
  • đọc schema class/view/event,
  • đọc Swagger/OpenAPI,
  • lấy SQL scripts,
  • đọc hướng dẫn cài đặt,
  • lấy prompt template,
  • dùng completion nếu có handler cụ thể.
REST API docs và Swagger vẫn là artifact riêng được sinh bởi bộ sinh tài liệu tương ứng. MCP chỉ cung cấp công cụ hoặc đường dẫn để truy cập chúng.

Giới Hạn Hiện Tại

Server hiện hỗ trợ tools, resources, prompts, completion endpoint và logging endpoint.
Một số giới hạn còn lại:
  • Chưa có sampling capability.
  • Completion endpoint đã có, nhưng hiện chưa thấy completion handler cụ thể được đăng ký.
  • Registry được cache sau lần scan đầu tiên, nên cập nhật động cần restart hoặc cơ chế invalidate riêng.
  • logging/setLevel lưu level trong memory handler, chưa thể hiện việc đổi global logger runtime.
  • Artifact lớn thường được trả qua hướng dẫn download, không đưa trực tiếp toàn bộ vào MCP response.
  • MCP server không trực tiếp thực thi GraphQL query/mutation thay client.

Kết Luận

Ở trạng thái code hiện tại, MCP server trong GraphQL plugin đã là một event-driven MCP adapter khá đầy đủ cho workflow AI-assisted development.
Nó cung cấp:
  • tools để lấy schema và artifact,
  • resources để đọc hướng dẫn,
  • prompts để chuẩn hóa tác vụ sinh nội dung,
  • completion endpoint để mở rộng autocomplete,
  • logging endpoint ở mức cơ bản,
  • admin authentication context để đảm bảo quyền truy cập.
Điểm mạnh của thiết kế là khả năng mở rộng bằng quy ước event name. Muốn thêm tool, resource, prompt hoặc completion mới, chỉ cần đăng ký handler đúng suffix. Controller vẫn giữ vai trò adapter JSON-RPC gọn nhẹ, còn runtime phía sau quyết định MCP server thực sự có những khả năng nào.