Hướng dẫn cài đặt MCP tool stream dữ liệu lớn tương thích với GraphQL plugin
Back to graphqlDùng pattern hiện tại của GraphQL plugin như sau: MCP tool chỉ trả metadata/download URL, còn dữ liệu lớn thì stream qua REST endpoint riêng. Đừng nhét nội dung file lớn vào JSON-RPC response vì client/LLM có thể đọc vào context và tốn token.
Trong repo đã có case mẫu:
- Tool schema: AdminMcpGetSqlScriptsToolSchemaEventHandler.java
- Tool call: AdminMcpGetSqlScriptsToolEventHandler.java
- REST stream endpoint: AdminGraphQLApiSqlScriptsController.java
- InputStream factory: AdminGraphQLSqlScriptFilesInputStreamFactory.java
Luồng Chuẩn
sequenceDiagram
participant Agent as MCP Client / Agent
participant MCP as GraphQL MCP Server
participant Tool as get_sql_scripts Tool
participant API as REST Download API
participant FS as SQL Files
Agent->>MCP: tools/list
MCP-->>Agent: get_sql_scripts schema
Agent->>MCP: tools/call get_sql_scripts
MCP->>Tool: get_sql_scripts_mcp_tool_event
Tool-->>MCP: download path + curl command
MCP-->>Agent: /graphql/api/v1/sql-scripts
Agent->>API: curl -o .agents/sql-scripts.sql /graphql/api/v1/sql-scripts
API->>FS: open SQL InputStreams
FS-->>API: stream chunks
API-->>Agent: sql-scripts.sql
Các Bước Cài Đặt MCP Tool Stream Dữ Liệu Lớn
- Tạo MCP tool schema handler
Tên event phải theo format:
<tool_name>_mcp_tool_schema_event
Ví dụ:
@EzySingleton public class AdminMcpGetSqlScriptsToolSchemaEventHandler extends AbstractEventHandler<Map<String, Object>, Object> { @Override public Object handleEventData(Map<String, Object> data) { return EzyMapBuilder.mapBuilder() .put("name", "get_sql_scripts") .put("title", "Get SQL Scripts") .put( "description", "Returns the download path for all SQL scripts. " + "Use curl/wget to save the file to disk — do NOT read into context." ) .put("inputSchema", newInputSchema()) .put("outputSchema", newOutputSchema()) .toMap(); } @Override public String getEventName() { return "get_sql_scripts_mcp_tool_schema_event"; } }
- Tạo MCP tool handler
Tên event phải theo format:
<tool_name>_mcp_tool_event
Tool handler không trả file content, chỉ trả hướng dẫn download:
@EzySingleton public class AdminMcpGetSqlScriptsToolEventHandler extends AbstractEventHandler<Map<String, Object>, Object> { private static final String DOWNLOAD_PATH = "/graphql/api/v1/sql-scripts"; @Override public Object handleEventData(Map<String, Object> arguments) { return EzyMapBuilder.mapBuilder() .put( "content", Collections.singletonList( EzyMapBuilder.mapBuilder() .put("type", "text") .put( "text", "SQL scripts are available at: " + DOWNLOAD_PATH + "nnUse curl to save to disk:n" + "curl --create-dirs -o .agents/sql-scripts.sql " + "<server_base_url>" + DOWNLOAD_PATH ) .toMap() ) ) .put("isError", Boolean.FALSE) .toMap(); } @Override public String getEventName() { return "get_sql_scripts_mcp_tool_event"; } }
- Tạo REST endpoint để stream file
@DoGet("/sql-scripts") public void sqlScriptsGet(HttpServletResponse response) throws Exception { response.setContentType("text/plain"); response.setHeader( "Content-Disposition", "attachment; filename="sql-scripts.sql"" ); try (InputStream inputStream = graphQLSqlScriptFilesInputStreamFactory.get() ) { OutputStream outputStream = response.getOutputStream(); byte[] buffer = new byte[8192]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } outputStream.flush(); } }
- Gom nhiều file bằng
SequenceInputStream
Case SQL hiện tại đang làm đúng hướng: gom SQL admin + SQL của activated modules, ngăn cách bằng
nn, rồi trả về một InputStream.
return new SequenceInputStream( Collections.enumeration(streams) );
Cách Agent Sử Dụng
Sau khi MCP server chạy, agent gọi tool:
get_sql_scripts
Tool trả về path:
/graphql/api/v1/sql-scripts
Agent tải file:
curl --create-dirs -o .agents/sql-scripts.sql \ http://localhost:<port>/graphql/api/v1/sql-scripts
Quy Ước Nên Theo
- Dữ liệu nhỏ: có thể trả trực tiếp trong MCP response.
- Dữ liệu lớn: MCP tool chỉ trả
downloadUrl,downloadPath, hoặc command mẫu. - File lớn nên lưu vào
.agents/để agent đọc bằng tool file/terminal khi cần. - Không để MCP tool trả raw SQL/schema/swagger lớn vào
content. - Tool là application feature; MCP method chỉ dành cho protocol như
initialize,ping,tools/list,tools/call.
Một điểm nhỏ nên chỉnh:
AdminMcpGetSqlScriptsToolSchemaEventHandler hiện mô tả outputSchema.content là “SQL scripts content”, nhưng thực tế tool chỉ trả text hướng dẫn download. Nên đổi description thành “download instruction content” cho khớp hành vi hiện tại.