Merge branch 'development_fix_mcpservers' into development_heroserver

* development_fix_mcpservers:
  refactor: introduce mcpcore and clean up STDIO transport
This commit is contained in:
2025-09-25 06:05:02 +04:00
19 changed files with 642 additions and 97 deletions

View File

@@ -2,7 +2,7 @@ module mcpcore
import x.json2
interface Backend {
pub interface Backend {
// Resource methods
resource_exists(uri string) !bool
resource_get(uri string) !Resource

View File

@@ -27,6 +27,8 @@ pub fn new_server(backend Backend, params ServerParams) !&Server {
// Core handlers
'initialize': server.initialize_handler
'notifications/initialized': initialized_notification_handler
// Logging handlers
'logging/setLevel': server.logging_set_level_handler
// Resource handlers
'resources/list': server.resources_list_handler
'resources/read': server.resources_read_handler

View File

@@ -1,8 +1,5 @@
module mcpcore
import time
import os
import log
import x.json2
import json
import freeflowuniverse.herolib.schemas.jsonrpc
@@ -113,11 +110,9 @@ fn (mut s Server) tools_call_handler(data string) !string {
}
}
log.error('Calling tool: ${tool_name} with arguments: ${arguments}')
// Note: Removed log.error() calls as they interfere with STDIO transport JSON-RPC communication
// Call the tool with the provided arguments
result := s.backend.tool_call(tool_name, arguments)!
log.error('Received result from tool: ${tool_name} with result: ${result}')
// Create a success response with the result
response := jsonrpc.new_response_generic[ToolCallResult](request_map['id'].int(),
result)
@@ -137,7 +132,7 @@ pub fn (mut s Server) send_tools_list_changed_notification() ! {
notification := jsonrpc.new_blank_notification('notifications/tools/list_changed')
s.send(json.encode(notification))
// Send the notification to all connected clients
log.info('Sending tools list changed notification: ${json.encode(notification)}')
// Note: Removed log.info() as it interferes with STDIO transport JSON-RPC communication
}
pub fn error_tool_call_result(err IError) ToolCallResult {

View File

@@ -2,8 +2,6 @@ module mcpcore
import time
import os
import log
import x.json2
import freeflowuniverse.herolib.schemas.jsonrpc
// Server is the main MCP server struct
@@ -18,7 +16,7 @@ pub mut:
// start starts the MCP server
pub fn (mut s Server) start() ! {
log.info('Starting MCP server')
// Note: Removed log.info() as it interferes with STDIO transport JSON-RPC communication
for {
// Read a message from stdin
message := os.get_line()
@@ -27,23 +25,31 @@ pub fn (mut s Server) start() ! {
continue
}
// Handle the message using the JSON-RPC handler
response := s.handler.handle(message) or {
log.error('message: ${message}')
log.error('Error handling message: ${err}')
// Try to extract the request ID
// Parse the JSON-RPC request
request := jsonrpc.decode_request(message) or {
// Note: Removed stderr logging as it can interfere with MCP Inspector
// Try to extract the request ID for error response
id := jsonrpc.decode_request_id(message) or { 0 }
// Create an internal error response
error_response := jsonrpc.new_error(id, jsonrpc.internal_error).encode()
print(error_response)
// Create an invalid request error response
error_response := jsonrpc.new_error(id, jsonrpc.invalid_request).encode()
println(error_response)
continue
}
// Send the response only if it's not empty (notifications return empty responses)
if response.len > 0 {
s.send(response)
// Handle the message using the JSON-RPC handler
response := s.handler.handle(request) or {
// Note: Removed stderr logging as it can interfere with MCP Inspector
// Create an internal error response
error_response := jsonrpc.new_error(request.id, jsonrpc.internal_error).encode()
println(error_response)
continue
}
// Send the response (notifications may return empty responses)
response_str := response.encode()
if response_str.len > 0 {
s.send(response_str)
}
}
}