From b63d4cf6754300af78e0ec9cfddb004ae14aefaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A0=20Arrufat?= Date: Mon, 2 Mar 2026 11:47:02 +0900 Subject: [PATCH] mcp: improve RawJson stringification and schema formatting - Update `RawJson.jsonStringify` to parse and re-write JSON content, ensuring valid output. - Reformat tool input schemas in `tools.zig` using multi-line string literals for better readability. --- src/mcp/protocol.zig | 10 +++++--- src/mcp/tools.zig | 59 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/mcp/protocol.zig b/src/mcp/protocol.zig index 827b9099..a8c7560d 100644 --- a/src/mcp/protocol.zig +++ b/src/mcp/protocol.zig @@ -101,9 +101,13 @@ pub const RawJson = struct { json: []const u8, pub fn jsonStringify(self: @This(), jw: anytype) !void { - try jw.beginWriteRaw(); - try jw.writer.writeAll(self.json); - jw.endWriteRaw(); + var arena: std.heap.ArenaAllocator = .init(std.heap.page_allocator); + defer arena.deinit(); + + const parsed = std.json.parseFromSlice(std.json.Value, arena.allocator(), self.json, .{}) catch return error.WriteFailed; + defer parsed.deinit(); + + try jw.write(parsed.value); } }; diff --git a/src/mcp/tools.zig b/src/mcp/tools.zig index b4522ff0..0f8a7693 100644 --- a/src/mcp/tools.zig +++ b/src/mcp/tools.zig @@ -13,32 +13,79 @@ pub const tool_list = [_]protocol.Tool{ .{ .name = "goto", .description = "Navigate to a specified URL and load the page in memory so it can be reused later for info extraction.", - .inputSchema = .{ .json = "{\"type\":\"object\",\"properties\":{\"url\":{\"type\":\"string\",\"description\":\"The URL to navigate to, must be a valid URL.\"}},\"required\":[\"url\"]}" }, + .inputSchema = .{ .json = + \\{ + \\ "type": "object", + \\ "properties": { + \\ "url": { "type": "string", "description": "The URL to navigate to, must be a valid URL." } + \\ }, + \\ "required": ["url"] + \\} + }, }, .{ .name = "search", .description = "Use a search engine to look for specific words, terms, sentences. The search page will then be loaded in memory.", - .inputSchema = .{ .json = "{\"type\":\"object\",\"properties\":{\"text\":{\"type\":\"string\",\"description\":\"The text to search for, must be a valid search query.\"}},\"required\":[\"text\"]}" }, + .inputSchema = .{ .json = + \\{ + \\ "type": "object", + \\ "properties": { + \\ "text": { "type": "string", "description": "The text to search for, must be a valid search query." } + \\ }, + \\ "required": ["text"] + \\} + }, }, .{ .name = "markdown", .description = "Get the page content in markdown format. If a url is provided, it navigates to that url first.", - .inputSchema = .{ .json = "{\"type\":\"object\",\"properties\":{\"url\":{\"type\":\"string\",\"description\":\"Optional URL to navigate to before fetching markdown.\"}}}" }, + .inputSchema = .{ .json = + \\{ + \\ "type": "object", + \\ "properties": { + \\ "url": { "type": "string", "description": "Optional URL to navigate to before fetching markdown." } + \\ } + \\} + }, }, .{ .name = "links", .description = "Extract all links in the opened page. If a url is provided, it navigates to that url first.", - .inputSchema = .{ .json = "{\"type\":\"object\",\"properties\":{\"url\":{\"type\":\"string\",\"description\":\"Optional URL to navigate to before extracting links.\"}}}" }, + .inputSchema = .{ .json = + \\{ + \\ "type": "object", + \\ "properties": { + \\ "url": { "type": "string", "description": "Optional URL to navigate to before extracting links." } + \\ } + \\} + }, }, .{ .name = "evaluate", .description = "Evaluate JavaScript in the current page context. If a url is provided, it navigates to that url first.", - .inputSchema = .{ .json = "{\"type\":\"object\",\"properties\":{\"script\":{\"type\":\"string\"},\"url\":{\"type\":\"string\",\"description\":\"Optional URL to navigate to before evaluating.\"}},\"required\":[\"script\"]}" }, + .inputSchema = .{ .json = + \\{ + \\ "type": "object", + \\ "properties": { + \\ "script": { "type": "string" }, + \\ "url": { "type": "string", "description": "Optional URL to navigate to before evaluating." } + \\ }, + \\ "required": ["script"] + \\} + }, }, .{ .name = "over", .description = "Used to indicate that the task is over and give the final answer if there is any. This is the last tool to be called in a task.", - .inputSchema = .{ .json = "{\"type\":\"object\",\"properties\":{\"result\":{\"type\":\"string\",\"description\":\"The final result of the task.\"}},\"required\":[\"result\"]}" }, + .inputSchema = .{ .json = + \\{ + \\ "type": "object", + \\ "properties": { + \\ "result": { "type": "string", "description": "The final result of the task." } + \\ }, + \\ "required": ["result"] + \\} + }, }, };