Skip to main content
Glama
gimp-mcp-studio
by Onru-Labs

call_api

Run GIMP 3.2 Python commands through a persistent PyGObject console to edit images, layers, selections, and filters and return JSON results.

Instructions

Call GIMP 3.2 API methods through PyGObject console.

GIMP MCP Protocol:

  • Use api_path="exec" to execute Python code in GIMP

  • args[0] should be "pyGObject-console" for executing commands

  • args[1] should be array of Python code strings to execute

  • Commands execute in persistent context - imports and variables persist

  • Always call Gimp.displays_flush() after drawing operations

For image operations, use get_image_bitmap() which return proper MCP Image objects that Claude can process directly.

GUIDANCE PROMPTS:

  • For common operations and best practices, invoke the 'gimp_best_practices' prompt

  • For complex multi-element drawings with layers, invoke the 'gimp_iterative_workflow' prompt

Optional Initialization Pattern: ["images = Gimp.get_images()", "image1 = images[0]", "layers = image1.get_layers()", "layer1 = layers[0]", "drawable1 = layer1"]

Common Operations:

  • Draw line: ["Gimp.pencil(drawable1, [0, 0, 200, 200])", "Gimp.displays_flush()"]

  • Set color: ["from gi.repository import Gegl", "red_color = Gegl.Color.new('red')", "Gimp.context_set_foreground(red_color)"]

  • Draw ellipse: ["Gimp.Image.select_ellipse(image1, Gimp.ChannelOps.REPLACE, 100, 100, 30, 20)", "Gimp.Drawable.edit_fill(drawable1, Gimp.FillType.FOREGROUND)", "Gimp.Selection.none(image1)", "Gimp.displays_flush()"]

  • Paint curve: ["Gimp.paintbrush_default(drawable1, [50.0, 50.0, 150.0, 200.0, 250.0, 50.0, 350.0, 200.0])", "Gimp.displays_flush()"]

  • Draw bezier curve: ["path = Gimp.Path.new(image1, 'my_bezier_path')", "image1.insert_path(path, None, 0)", "stroke_id = path.bezier_stroke_new_moveto(100, 100)", "path.bezier_stroke_cubicto(stroke_id, 150, 50, 250, 150, 300, 100)", "Gimp.Drawable.edit_stroke_item(drawable1, path)", "Gimp.Selection.none(image1)", "Gimp.displays_flush()"]

  • Get open filenames: ["print([x.get_file().get_path() for x in Gimp.get_images()])"]

  • Copy layer between images: ["image1 = Gimp.get_images()[0]", "image2 = Gimp.get_images()[1]", "width = image1.get_width()", "height = image1.get_height()", "image1.select_rectangle(Gimp.ChannelOps.REPLACE, 0, 0, width, height)", "image1_layers = image1.get_selected_layers()", "drawable = image1_layers[0]", "Gimp.edit_copy([drawable])", "image2_layers = image2.get_layers()", "target_drawable = image2_layers[0]", "floating_sel = Gimp.edit_paste(target_drawable, True)[0]", "Gimp.floating_sel_anchor(floating_sel)", "Gimp.displays_flush()"]

  • New image: ["image1 = Gimp.Image.new(350, 800, Gimp.ImageBaseType.RGB)", "layer1 = Gimp.Layer.new(image1, 'Background', 350, 800, Gimp.ImageType.RGB_IMAGE, 100, Gimp.LayerMode.NORMAL)", "image1.insert_layer(layer1, None, 0)", "drawable1 = layer1", "white_color = Gegl.Color.new('white')", "Gimp.context_set_background(white_color)", "Gimp.Drawable.edit_fill(drawable1, Gimp.FillType.BACKGROUND)", "Gimp.Display.new(image1)"]

Important Tips:

  • When filling layers with color, ensure layer has alpha channel using Gimp.Layer.add_alpha()

  • Use Gimp.Drawable.fill() for reliable full-layer fills

  • Specify colors precisely with rgb(R, G, B) or rgba(R, G, B, A) to avoid transparency issues

  • After drawing operations, always call Gimp.displays_flush()

  • After selection operations for drawing, unselect with Gimp.Selection.none(image1)

GIMP 3.2 API Changes:

  • Use Gimp.get_images() instead of deprecated Gimp.list_images()

  • Use image.get_layers() instead of Gimp.get_active_layer()

  • gimpfu module not available in GIMP 3.2

  • Colors created with Gegl.Color.new('color_name')

  • Full API documentation: https://developer.gimp.org/api/3.0/libgimp/

Parameters:

  • api_path: Use "exec" for Python execution

  • args: ["pyGObject-console", ["python_code_array"]] or ["pyGObject-eval", ["expression"]]

  • kwargs: Dictionary of keyword arguments (rarely used)

Returns:

  • JSON string of the result or error message

Input Schema

NameRequiredDescriptionDefault
argsNo
kwargsNo
api_pathYes

Output Schema

NameRequiredDescriptionDefault
resultYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.1.0

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does disclose key behavior beyond the schema: commands execute in a persistent context where imports and variables survive between calls, results/errors come back as a JSON string, and GIMP 3.2-specific API changes apply. It stops short of warning that this is arbitrary code execution with potentially irreversible effects on open images, which keeps it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Headers and front-loading are good — purpose first, then protocol, then parameters — but the body is very long and a large fraction of the 'Common Operations' recipes duplicate functionality already offered by dedicated siblings. Several tips (displays_flush, Selection.none) are repeated across examples, adding length without new information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a three-parameter arbitrary-code execution tool with no annotations and no schema descriptions, the definition covers the essentials: argument encoding, persistent interpreter state, error return format, and version-specific API gotchas. An output schema exists so return values need little explanation. The main omission is any caution about destructive operations or preferring dedicated tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate and does: it explains api_path="exec", that args[0] must be "pyGObject-console" (or "pyGObject-eval"), that args[1] is an array of Python code strings, and that kwargs are a rarely-used keyword dictionary. Without this the zero-coverage schema would be nearly unusable; it adds the format meaning the schema lacks.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening line states a specific verb and resource: execute GIMP 3.2 API methods via the PyGObject console, with the concrete transport ('api_path="exec"', 'pyGObject-console') spelled out. It is clearly distinguishable as a raw escape hatch from the ~90 dedicated siblings (draw_line, fill_layer, etc.), but the definition never explicitly names that relationship, so the agent must infer it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than framed: it offers 'Common Operations' recipes and points to the gimp_best_practices and gimp_iterative_workflow prompts, but never says when to use this tool instead of the dedicated sibling tools that perform the same operations (draw_line, fill_ellipse, select_ellipse). No when-not-to-use or exclusion guidance is given, which is a real gap given the sibling set.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.