mcp: final protocol cleanup after removing screenshot tool

- Removed unused ImageContent from protocol.
- Simplified CallToolResult back to only support TextContent.
- Cleaned up CallToolResult usages in tools.zig.
This commit is contained in:
Adrià Arrufat
2026-04-01 14:49:56 +02:00
parent fffa8b6d4b
commit 1854627b69
2 changed files with 15 additions and 23 deletions

View File

@@ -168,17 +168,9 @@ pub fn TextContent(comptime T: type) type {
}; };
} }
pub fn ImageContent(comptime T: type) type {
return struct {
type: []const u8 = "image",
data: T,
mimeType: []const u8,
};
}
pub fn CallToolResult(comptime T: type) type { pub fn CallToolResult(comptime T: type) type {
return struct { return struct {
content: []const T, content: []const TextContent(T),
isError: bool = false, isError: bool = false,
}; };
} }

View File

@@ -342,7 +342,7 @@ fn handleGoto(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arg
try performGoto(server, args.url, id, args.timeout, args.waitUntil); try performGoto(server, args.url, id, args.timeout, args.waitUntil);
const content = [_]protocol.TextContent([]const u8){.{ .text = "Navigated successfully." }}; const content = [_]protocol.TextContent([]const u8){.{ .text = "Navigated successfully." }};
try server.sendResult(id, protocol.CallToolResult(protocol.TextContent([]const u8)){ .content = &content }); try server.sendResult(id, protocol.CallToolResult([]const u8){ .content = &content });
} }
fn handleMarkdown(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arguments: ?std.json.Value) !void { fn handleMarkdown(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arguments: ?std.json.Value) !void {
@@ -352,7 +352,7 @@ fn handleMarkdown(server: *Server, arena: std.mem.Allocator, id: std.json.Value,
const content = [_]protocol.TextContent(ToolStreamingText){.{ const content = [_]protocol.TextContent(ToolStreamingText){.{
.text = .{ .page = page, .action = .markdown }, .text = .{ .page = page, .action = .markdown },
}}; }};
server.sendResult(id, protocol.CallToolResult(protocol.TextContent(ToolStreamingText)){ .content = &content }) catch { server.sendResult(id, protocol.CallToolResult(ToolStreamingText){ .content = &content }) catch {
return server.sendError(id, .InternalError, "Failed to serialize markdown content"); return server.sendError(id, .InternalError, "Failed to serialize markdown content");
}; };
} }
@@ -364,7 +364,7 @@ fn handleLinks(server: *Server, arena: std.mem.Allocator, id: std.json.Value, ar
const content = [_]protocol.TextContent(ToolStreamingText){.{ const content = [_]protocol.TextContent(ToolStreamingText){.{
.text = .{ .page = page, .action = .links }, .text = .{ .page = page, .action = .links },
}}; }};
server.sendResult(id, protocol.CallToolResult(protocol.TextContent(ToolStreamingText)){ .content = &content }) catch { server.sendResult(id, protocol.CallToolResult(ToolStreamingText){ .content = &content }) catch {
return server.sendError(id, .InternalError, "Failed to serialize links content"); return server.sendError(id, .InternalError, "Failed to serialize links content");
}; };
} }
@@ -390,7 +390,7 @@ fn handleSemanticTree(server: *Server, arena: std.mem.Allocator, id: std.json.Va
.maxDepth = args.maxDepth, .maxDepth = args.maxDepth,
}, },
}}; }};
server.sendResult(id, protocol.CallToolResult(protocol.TextContent(ToolStreamingText)){ .content = &content }) catch { server.sendResult(id, protocol.CallToolResult(ToolStreamingText){ .content = &content }) catch {
return server.sendError(id, .InternalError, "Failed to serialize semantic tree content"); return server.sendError(id, .InternalError, "Failed to serialize semantic tree content");
}; };
} }
@@ -418,7 +418,7 @@ fn handleNodeDetails(server: *Server, arena: std.mem.Allocator, id: std.json.Val
try std.json.Stringify.value(&details, .{}, &aw.writer); try std.json.Stringify.value(&details, .{}, &aw.writer);
const content = [_]protocol.TextContent([]const u8){.{ .text = aw.written() }}; const content = [_]protocol.TextContent([]const u8){.{ .text = aw.written() }};
try server.sendResult(id, protocol.CallToolResult(protocol.TextContent([]const u8)){ .content = &content }); try server.sendResult(id, protocol.CallToolResult([]const u8){ .content = &content });
} }
fn handleInteractiveElements(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arguments: ?std.json.Value) !void { fn handleInteractiveElements(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arguments: ?std.json.Value) !void {
@@ -439,7 +439,7 @@ fn handleInteractiveElements(server: *Server, arena: std.mem.Allocator, id: std.
try std.json.Stringify.value(elements, .{}, &aw.writer); try std.json.Stringify.value(elements, .{}, &aw.writer);
const content = [_]protocol.TextContent([]const u8){.{ .text = aw.written() }}; const content = [_]protocol.TextContent([]const u8){.{ .text = aw.written() }};
try server.sendResult(id, protocol.CallToolResult(protocol.TextContent([]const u8)){ .content = &content }); try server.sendResult(id, protocol.CallToolResult([]const u8){ .content = &content });
} }
fn handleStructuredData(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arguments: ?std.json.Value) !void { fn handleStructuredData(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arguments: ?std.json.Value) !void {
@@ -454,7 +454,7 @@ fn handleStructuredData(server: *Server, arena: std.mem.Allocator, id: std.json.
try std.json.Stringify.value(data, .{}, &aw.writer); try std.json.Stringify.value(data, .{}, &aw.writer);
const content = [_]protocol.TextContent([]const u8){.{ .text = aw.written() }}; const content = [_]protocol.TextContent([]const u8){.{ .text = aw.written() }};
try server.sendResult(id, protocol.CallToolResult(protocol.TextContent([]const u8)){ .content = &content }); try server.sendResult(id, protocol.CallToolResult([]const u8){ .content = &content });
} }
fn handleDetectForms(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arguments: ?std.json.Value) !void { fn handleDetectForms(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arguments: ?std.json.Value) !void {
@@ -475,7 +475,7 @@ fn handleDetectForms(server: *Server, arena: std.mem.Allocator, id: std.json.Val
try std.json.Stringify.value(forms_data, .{}, &aw.writer); try std.json.Stringify.value(forms_data, .{}, &aw.writer);
const content = [_]protocol.TextContent([]const u8){.{ .text = aw.written() }}; const content = [_]protocol.TextContent([]const u8){.{ .text = aw.written() }};
try server.sendResult(id, protocol.CallToolResult(protocol.TextContent([]const u8)){ .content = &content }); try server.sendResult(id, protocol.CallToolResult([]const u8){ .content = &content });
} }
fn handleEvaluate(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arguments: ?std.json.Value) !void { fn handleEvaluate(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arguments: ?std.json.Value) !void {
@@ -496,13 +496,13 @@ fn handleEvaluate(server: *Server, arena: std.mem.Allocator, id: std.json.Value,
try caught.format(&aw.writer); try caught.format(&aw.writer);
const content = [_]protocol.TextContent([]const u8){.{ .text = aw.written() }}; const content = [_]protocol.TextContent([]const u8){.{ .text = aw.written() }};
return server.sendResult(id, protocol.CallToolResult(protocol.TextContent([]const u8)){ .content = &content, .isError = true }); return server.sendResult(id, protocol.CallToolResult([]const u8){ .content = &content, .isError = true });
}; };
const str_result = js_result.toStringSliceWithAlloc(arena) catch "undefined"; const str_result = js_result.toStringSliceWithAlloc(arena) catch "undefined";
const content = [_]protocol.TextContent([]const u8){.{ .text = str_result }}; const content = [_]protocol.TextContent([]const u8){.{ .text = str_result }};
try server.sendResult(id, protocol.CallToolResult(protocol.TextContent([]const u8)){ .content = &content }); try server.sendResult(id, protocol.CallToolResult([]const u8){ .content = &content });
} }
fn handleClick(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arguments: ?std.json.Value) !void { fn handleClick(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arguments: ?std.json.Value) !void {
@@ -533,7 +533,7 @@ fn handleClick(server: *Server, arena: std.mem.Allocator, id: std.json.Value, ar
page_title orelse "(none)", page_title orelse "(none)",
}); });
const content = [_]protocol.TextContent([]const u8){.{ .text = result_text }}; const content = [_]protocol.TextContent([]const u8){.{ .text = result_text }};
try server.sendResult(id, protocol.CallToolResult(protocol.TextContent([]const u8)){ .content = &content }); try server.sendResult(id, protocol.CallToolResult([]const u8){ .content = &content });
} }
fn handleFill(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arguments: ?std.json.Value) !void { fn handleFill(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arguments: ?std.json.Value) !void {
@@ -566,7 +566,7 @@ fn handleFill(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arg
page_title orelse "(none)", page_title orelse "(none)",
}); });
const content = [_]protocol.TextContent([]const u8){.{ .text = result_text }}; const content = [_]protocol.TextContent([]const u8){.{ .text = result_text }};
try server.sendResult(id, protocol.CallToolResult(protocol.TextContent([]const u8)){ .content = &content }); try server.sendResult(id, protocol.CallToolResult([]const u8){ .content = &content });
} }
fn handleScroll(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arguments: ?std.json.Value) !void { fn handleScroll(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arguments: ?std.json.Value) !void {
@@ -604,7 +604,7 @@ fn handleScroll(server: *Server, arena: std.mem.Allocator, id: std.json.Value, a
page_title orelse "(none)", page_title orelse "(none)",
}); });
const content = [_]protocol.TextContent([]const u8){.{ .text = result_text }}; const content = [_]protocol.TextContent([]const u8){.{ .text = result_text }};
try server.sendResult(id, protocol.CallToolResult(protocol.TextContent([]const u8)){ .content = &content }); try server.sendResult(id, protocol.CallToolResult([]const u8){ .content = &content });
} }
fn handleWaitForSelector(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arguments: ?std.json.Value) !void { fn handleWaitForSelector(server: *Server, arena: std.mem.Allocator, id: std.json.Value, arguments: ?std.json.Value) !void {
@@ -633,7 +633,7 @@ fn handleWaitForSelector(server: *Server, arena: std.mem.Allocator, id: std.json
const msg = std.fmt.allocPrint(arena, "Element found. backendNodeId: {d}", .{registered.id}) catch "Element found."; const msg = std.fmt.allocPrint(arena, "Element found. backendNodeId: {d}", .{registered.id}) catch "Element found.";
const content = [_]protocol.TextContent([]const u8){.{ .text = msg }}; const content = [_]protocol.TextContent([]const u8){.{ .text = msg }};
return server.sendResult(id, protocol.CallToolResult(protocol.TextContent([]const u8)){ .content = &content }); return server.sendResult(id, protocol.CallToolResult([]const u8){ .content = &content });
} }
fn ensurePage(server: *Server, id: std.json.Value, url: ?[:0]const u8, timeout: ?u32, waitUntil: ?lp.Config.WaitUntil) !*lp.Page { fn ensurePage(server: *Server, id: std.json.Value, url: ?[:0]const u8, timeout: ?u32, waitUntil: ?lp.Config.WaitUntil) !*lp.Page {