feat: support images in custom tool responses #6879

Open
opened 2026-02-16 18:05:30 -05:00 by yindo · 3 comments
Owner

Originally created by @leeweisern on GitHub (Jan 19, 2026).

Originally assigned to: @thdxr on GitHub.

Problem

Custom tools (defined in .opencode/tools/) can currently only return strings. MCP tools already support returning structured content with images via { content: [{type: "image", mimeType, data}] }. This limitation prevents custom tools from returning visual data like screenshots, charts, or processed images that the LLM could analyze.

Proposed Solution

Extend the custom tool API to support the same rich content pattern as MCP tools:

export default tool({
  description: 'Capture a screenshot',
  args: { url: z.string() },
  async execute(args) {
    const base64 = await captureScreenshot(args.url)
    return {
      content: [
        { type: 'text', text: 'Screenshot captured' },
        { type: 'image', mimeType: 'image/png', data: base64 }
      ]
    }
  }
})

Requirements

  • Custom tools can return either string (backwards compatible) or { content: ToolContentPart[] }
  • Images are converted to attachments and sent to the model (same as MCP tools)
  • Existing string-only tools continue to work unchanged
  • Validation for image mime types and size limits

Related

  • PR #4100 added image support for MCP tools - this extends that pattern to custom tools
Originally created by @leeweisern on GitHub (Jan 19, 2026). Originally assigned to: @thdxr on GitHub. ## Problem Custom tools (defined in `.opencode/tools/`) can currently only return strings. MCP tools already support returning structured content with images via `{ content: [{type: "image", mimeType, data}] }`. This limitation prevents custom tools from returning visual data like screenshots, charts, or processed images that the LLM could analyze. ## Proposed Solution Extend the custom tool API to support the same rich content pattern as MCP tools: ```typescript export default tool({ description: 'Capture a screenshot', args: { url: z.string() }, async execute(args) { const base64 = await captureScreenshot(args.url) return { content: [ { type: 'text', text: 'Screenshot captured' }, { type: 'image', mimeType: 'image/png', data: base64 } ] } } }) ``` ## Requirements - Custom tools can return either `string` (backwards compatible) or `{ content: ToolContentPart[] }` - Images are converted to attachments and sent to the model (same as MCP tools) - Existing string-only tools continue to work unchanged - Validation for image mime types and size limits ## Related - PR #4100 added image support for MCP tools - this extends that pattern to custom tools
Author
Owner

@github-actions[bot] commented on GitHub (Jan 19, 2026):

This issue might be a duplicate of existing issues. Please check:

  • #7590: Add ToolResult type for structured tool responses - directly addresses this for plugin/custom tools
  • #7878: Resource content type in MCP tool output not supported - shows the pattern for MCP tools that custom tools should follow
  • #2897: Tool.execute.after output has two different formats - related to standardizing structured responses
  • #3384: Allow tool.execute.after hook to modify MCP tool output - related to output handling consistency

Feel free to ignore if none of these address your specific case.

@github-actions[bot] commented on GitHub (Jan 19, 2026): This issue might be a duplicate of existing issues. Please check: - #7590: Add ToolResult type for structured tool responses - directly addresses this for plugin/custom tools - #7878: Resource content type in MCP tool output not supported - shows the pattern for MCP tools that custom tools should follow - #2897: Tool.execute.after output has two different formats - related to standardizing structured responses - #3384: Allow tool.execute.after hook to modify MCP tool output - related to output handling consistency Feel free to ignore if none of these address your specific case.
Author
Owner

@leeweisern commented on GitHub (Jan 19, 2026):

Currenty i am turning my custom tools into mcp to support images....

@leeweisern commented on GitHub (Jan 19, 2026): Currenty i am turning my custom tools into mcp to support images....
Author
Owner

@guilhermelowa commented on GitHub (Jan 20, 2026):

It would be super helpful to have this tool!

@guilhermelowa commented on GitHub (Jan 20, 2026): It would be super helpful to have this tool!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#6879