feat(view): save 2D board view to file instead of base64 (#161)

* Feat: save 2D board view to file instead of returning base64

The 2D view was returning base64-encoded image data in JSON, which
often exceeded token/message size limits. Now saves the rendered
image (PNG/JPG/SVG) next to the PCB file and returns the file path.
This makes the output usable by tools that can read image files
directly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(board): add opt-in responseMode param to get_board_2d_view

Add a responseMode string parameter (enum: inline | file, default inline)
so callers can choose how the rendered image is delivered.

- inline (default, pre-PR behavior): image bytes are base64-encoded
  and returned in the imageData response field -- backward-compatible.
- file: image is written next to the .kicad_pcb as
  <board>_2d_view.<ext> and filePath is returned -- resolves the
  MCP message-size limit problem on large boards.

Rendering logic is shared between both modes; only response packaging
differs. Updated tool schema (Python + TypeScript) and replaced the
existing test file with 5 focused unit tests covering inline/file modes
for PNG and SVG formats plus the default-is-inline contract.

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Gavin Colonese
2026-05-18 14:29:00 -04:00
committed by GitHub
parent c2c77f5995
commit b69a4eb88b
4 changed files with 256 additions and 26 deletions

View File

@@ -362,20 +362,33 @@ export function registerBoardTools(server: McpServer, callKicadScript: CommandFu
// ------------------------------------------------------
server.tool(
"get_board_2d_view",
"Render a 2D image of the current PCB board and return it as PNG, JPG or SVG.",
[
"Render a 2D image of the current PCB board and return it as PNG, JPG or SVG.",
"Use responseMode to choose how the image is delivered:",
' "inline" (default) — base64-encoded bytes returned in imageData; works well for small boards.',
' "file" — image written next to the .kicad_pcb as <board>_2d_view.<ext>; filePath is returned.',
"Use file mode for large boards to avoid hitting MCP message-size limits.",
].join(" "),
{
layers: z.array(z.string()).optional().describe("Optional array of layer names to include"),
width: z.number().optional().describe("Optional width of the image in pixels"),
height: z.number().optional().describe("Optional height of the image in pixels"),
format: z.enum(["png", "jpg", "svg"]).optional().describe("Image format"),
responseMode: z
.enum(["inline", "file"])
.optional()
.describe(
'How to return the image: "inline" (default) returns base64 imageData; "file" writes to disk and returns filePath',
),
},
async ({ layers, width, height, format }) => {
async ({ layers, width, height, format, responseMode }) => {
logger.debug("Getting 2D board view");
const result = await callKicadScript("get_board_2d_view", {
layers,
width,
height,
format,
responseMode,
});
return {