Skip to main content
Glama

text_to_image_mystic_sync

Generate AI images from text descriptions with customizable parameters like style references, aspect ratios, and models for creative visual content.

Instructions

Convert descriptive text input into images using AI. This endpoint accepts a variety of parameters to customize the generated images.

Responses:

  • 200 (Success): OK - The request has succeeded and the Mystic process has started.

    • Content-Type: application/json

    • Response Properties:

    • Example:

{
  "data": {
    "generated": [
      "https://openapi-generator.tech",
      "https://openapi-generator.tech"
    ],
    "task_id": "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
    "status": "CREATED"
  }
}
  • 400: Bad Request - The server could not understand the request due to invalid syntax.

    • Content-Type: application/json

    • Response Properties:

    • Example:

{
  "message": "message"
}
  • 401: Unauthorized - The client must authenticate itself to get the requested response.

    • Content-Type: application/json

    • Response Properties:

    • Example:

{
  "message": "message"
}
  • 500: Internal Server Error - The server has encountered a situation it doesn't know how to handle.

    • Content-Type: application/json

    • Response Properties:

    • Example:

{
  "message": "Internal Server Error"
}
  • 503: Service Unavailable

    • Content-Type: application/json

    • Response Properties:

    • Example:

{
  "message": "Service Unavailable. Please try again later."
}

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
promptNo### AI Model Prompt Description The prompt is a short text that describes the image you want to generate. It can range from simple descriptions, like `"a cat"`, to detailed scenarios, such as `"a cat with wings, playing the guitar, and wearing a hat"`. If no prompt is provided, the AI will generate a random image. #### Adding Characters to the Prompt You can introduce characters into the prompt using the following syntax: - `@character_name`: Represents the character you want to include. Example: `My friend @john is a great artist.` #### Modifying Character Strength To adjust the influence or "strength" of a character in the image, use the following syntax: - `@character_name::strength`: Specify the character's strength by appending `::strength` to their name, where `strength` is a numerical value. Example: `My friend @john::200 is a great artist.` Higher strength values will make the character more prominent in the generated image.
webhook_urlNoOptional callback URL that will receive asynchronous notifications whenever the task changes status. The payload sent to this URL is the same as the corresponding GET endpoint response, but without the data field.
structure_referenceNo### Structure Reference Base64 image to use as structure reference. Using images as structure references allows you to influence the shape of your final image. This feature enables various creative applications such as coloring sketches, transforming cartoons into realistic images, texturing basic 3D models, or converting real images into cartoons. The outcome is entirely controlled by your prompt, offering limitless creative possibilities.
structure_strengthNoNote: This parameter only takes effect when a `"structure_reference"` image is provided. Allows to maintain the structure of the original image.
style_referenceNo### Style Reference Base64 image to use as style reference. Using images as style references allows you to influence the aesthetic of your creation. This is possibly the most powerful tool of Mystic, as it truly lets you create incredibly unique images.
adherenceNoNote: This parameter only takes effect when a `"style_reference"` image is provided. Increasing this value will make your generation more faithful to the prompt, but it may transfer the style a bit less accurately. Higher values can help fix small artifacts, anatomical errors and text readability. Lower values will give you more creative images and closer to the style reference.
hdrNoNote: This parameter only takes effect when a `"style_reference"` image is provided. Increasing this value can give you a more detailed image, at the cost of a more 'AI look' and slightly worse style transfer. Lower values have a more natural and artistic look but may increase artifacts.
resolutionNoResolution of the image2k
aspect_ratioNoImage size with the aspect ratio. The aspect ratio is the proportional relationship between an image's width and height, expressed as *_width_height (e.g., square_1_1, widescreen_16_9). It is calculated by dividing the width by the height.\ If not present, the default is `square_1_1`. Note: For the `fluid` model, only this values are valid: * square_1_1 * social_story_9_16 * widescreen_16_9 * traditional_3_4 * classic_4_3 square_1_1
modelNo* `zen` - for smoother, basic, and cleaner results. Fewer objects in the scene and less intricate details. The softer looking one. * `flexible` - good prompt adherence. However, it has results that are a bit more HDR and saturated than Realism or Fluid. It's especially good with illustrations, fantastical prompts, and for diving into the latent space in search of very specific visual styles. * `fluid` - the model that adheres best to prompts with great average quality for all kind of images. It can generate really creative images! It will always follow your input no matter what. However, since it is using Google's Imagen 3, it is a bit over-moderated, and some simple prompts containing words like "war" may be flagged and not generated (sorry about that! But there's nothing we can do!). * `realism` - with a more realistic color palette. It tries to give an extra boost of reality to your images, a kind of "less AI look". Works especially well with photographs but also magically works with illustrations too. IMPORTANT: you should use Zen, Flexible or Fluid if you are trying to generate something that is really fantastic or a known character, Realism may not follow your prompt well. * `super_real` - if reality is your priority, this is your model. Nearly as versatile as Flexible, it excels in realism outperforming Editorial Portraits in medium shots, though not as strong for close-ups. * `editorial_portraits` - the most amazing state-of-the-art generator for editorial portraits. You have never seen a level of realism like this before. Perfect for hyperrealistic close-up or medium shots. Unfortunately, in wide or distant shots, it generates anatomical problems and artifacts... but for close-ups, it is simply the best on the market. Tip: use the longest and most explanatory prompts possible, they really suit it well! realism
creative_detailingNoHigher values can achieve greater detail per pixel at higher resolutions at the cost of giving a somewhat more "HDR" or artificial look. Very high values can generate quite crazy things like eyes where they shouldn't appear, etc. Valid values range `[0, 100]`, default `33`
engineNoSelect the engine for the AI model. Available options: * `automatic` - default choice * `Illusio` - for smoother illustrations, landscapes, and nature. The softer looking one. * `Sharpy` - better for realistic images like photographs and for a more grainy look. It provides the sharpest and most detailed images. If you use it for illustrations it will give them more texture and a less softer look. * `Sparkle` - also good for realistic images. It's a middle ground between Illusio and Sharpy. automatic
fixed_generationNoWhen this option is enabled, using the same settings will consistently produce the same image. Fixed generations are ideal for fine-tuning, as it allows for incremental changes to parameters (such as the prompt) to see subtle variations in the output. When disabled, expect each generation to introduce a degree of randomness, leading to more diverse outcomes.
filter_nsfwNoControls **NSFW** (Not Safe For Work) content filtering during generation. This parameter is always set to `true` by default and NSFW filtering **cannot be disabled** for standard API usage. Only authorized clients with special permissions can disable this filter. **Important:** If your use case requires disabling NSFW filtering, please contact our support team to discuss your requirements and potential authorization.
stylingNo

Implementation Reference

  • Core implementation of the text-to-image generation: POSTs payload to /v1/ai/mystic to create task, polls /v1/ai/mystic/{task_id} until COMPLETED, with retries, progress reporting, and timeout handling.
    async def generate_image_with_polling(
        self,
        payload: dict[str, Any],
        ctx: Context,
        poll_interval: float = 5.0,
        timeout: float = 120.0,
    ) -> dict[str, Any]:
        start_time = time.time()
        await ctx.info("🎨 Starting image generation with Mystic...")
    
        # Create a fresh client with current configuration for this request
        client = HttpClientFactory.create_dynamic_client()
        
        try:
            # 1. Make POST request to create the task
            await ctx.debug(f"Sending POST request with payload: {payload}")
            response = await client.post("/v1/ai/mystic", json=payload)
            response.raise_for_status()
            data = response.json()
            ctx.info(f"Response: {data}")
            task_id = data.get("data", {}).get("task_id")
            if not task_id:
                await ctx.error("❌ No task_id received from Mystic")
                raise Exception("No task_id received from Mystic")
    
            await ctx.info(f"✅ Task created with ID: {task_id}")
    
            # 2. Poll until it's COMPLETED or fails
            status_url = f"/v1/ai/mystic/{task_id}"
            elapsed = 0.0
            poll_count = 0
    
            while elapsed < timeout:
                await asyncio.sleep(poll_interval)
                elapsed = time.time() - start_time
                poll_count += 1
    
                await ctx.debug(f"🔍 Query #{poll_count} - Elapsed time: {elapsed:.1f}s")
    
                # Retry GET up to 3 times if it fails
                status_data = None
    
                for attempt in range(3):  # 3 attempts maximum
                    try:
                        status_resp = await client.get(status_url)
                        status_resp.raise_for_status()
                        status_data = status_resp.json()
                        break  # If it works, exit the retry loop
                    except Exception as e:
                        if attempt < 2:  # If not the last attempt
                            await ctx.warning(
                                f"⚠️ Error in status query (attempt {attempt + 1}/3): {type(e).__name__}: {str(e)}"
                            )
                            await asyncio.sleep(1)  # Wait 1s before retrying
                        else:
                            await ctx.error(
                                f"❌ Error after 3 attempts querying status: {type(e).__name__}: {str(e)}"
                            )
                            raise Exception(
                                f"Error querying status after 3 attempts: {type(e).__name__}: {str(e)}"
                            )
    
                if status_data is None:
                    continue  # This shouldn't happen, but for safety
    
                mystic_status = status_data.get("data", {}).get("status")
    
                await ctx.report_progress(progress=poll_count, total=timeout, message=mystic_status)
                await ctx.info(
                    f"📊 Current status: {mystic_status} (query #{poll_count}, {elapsed:.1f}s elapsed)"
                )
    
                if mystic_status == "COMPLETED":
                    await ctx.report_progress(progress=100.0, total=100.0)
                    await ctx.info(f"🎉 Image generated successfully in {elapsed:.1f} seconds!")
                    result_data = status_data["data"]
                    return result_data if isinstance(result_data, dict) else {}
                if mystic_status in ("FAILED", "CANCELLED"):  # other error states
                    await ctx.error(f"❌ Mystic task failed: {mystic_status} after {elapsed:.1f}s")
                    raise Exception(f"Mystic task failed: {mystic_status}")
    
            await ctx.warning(f"⏰ Timeout after {elapsed:.1f}s waiting for Mystic to finish")
            raise TimeoutError("Timeout waiting for Mystic to complete the task")
            
        finally:
            # Always close the client to free resources
            await client.aclose()
  • Transforms the original OpenAPI POST /v1/ai/mystic tool into a synchronous 'text_to_image_mystic_sync' tool using the polling transform_fn.
    def mcp_component_fn(route: Any, component: Any) -> Any:
        # Only for the Mystic POST mystic tool
        if (
            route.path == "/v1/ai/mystic"
            and route.method == "POST"
            and isinstance(component, OpenAPITool)
        ):
            # Create a transformed tool
            transformed = Tool.from_tool(
                component,
                name="text_to_image_mystic_sync",
                transform_fn=mystic_transform_fn,
            )
            component.disable()
            transformed_tools.append(transformed)
            return transformed
  • The direct handler (transform_fn) for the 'text_to_image_mystic_sync' tool, which delegates to MysticService.generate_image_with_polling.
    async def mystic_transform_fn(**kwargs: Any) -> dict[str, Any]:
        # Get the active context using the dependency function
        ctx = get_context()
        # kwargs are the POST arguments
        return await mystic_service.generate_image_with_polling(kwargs, ctx, timeout=300.0)
  • Adds the transformed 'text_to_image_mystic_sync' tool to the FastMCP server instance.
    for tool in transformed_tools:
        server.add_tool(tool)
Behavior2/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions the tool is an 'endpoint' and includes HTTP response codes (200, 400, etc.), implying it's a web API call, but lacks critical behavioral details such as authentication requirements, rate limits, asynchronous processing (implied by 'task_id' but not explained), or potential side effects like resource consumption.

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

Conciseness2/5

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

The description is poorly structured and not front-loaded. It starts with a concise purpose statement but devotes most of its length to verbose HTTP response examples and formatting, which are redundant for an AI agent and clutter the core information. This wastes space and reduces clarity.

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

Completeness2/5

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

Given the tool's complexity (15 parameters, no annotations, no output schema), the description is incomplete. It lacks essential context such as authentication needs, rate limits, asynchronous behavior explanation, error handling beyond HTTP codes, and guidance on parameter combinations. The heavy reliance on the schema is insufficient for a tool of this sophistication.

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

Parameters3/5

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

Schema description coverage is high at 93%, so the baseline is 3. The description adds minimal value beyond the schema, stating only 'This endpoint accepts a variety of parameters to customize the generated images,' which is generic and doesn't elaborate on parameter interactions or usage scenarios. It doesn't compensate for the 7% coverage gap.

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

Purpose5/5

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

The description clearly states the tool's purpose: 'Convert descriptive text input into images using AI.' It specifies the verb ('convert'), resource ('descriptive text input'), and output ('images'), and distinguishes it from sibling tools like detect_ai_image or search_icons by focusing on generation rather than detection, download, or search.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It mentions 'This endpoint accepts a variety of parameters to customize the generated images,' but offers no explicit context, prerequisites, or comparisons to sibling tools, leaving the agent without usage direction.

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

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/freepik-company/freepik-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server