<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Haris Putratama</title>
    <description>The latest articles on DEV Community by Haris Putratama (@harisptrtm).</description>
    <link>https://dev.to/harisptrtm</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3954449%2F24975972-846c-47df-9eb5-676e9097d12d.jpg</url>
      <title>DEV Community: Haris Putratama</title>
      <link>https://dev.to/harisptrtm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/harisptrtm"/>
    <language>en</language>
    <item>
      <title>We Made Design Requestable by AI Agents — Here's How MCP Changes Creative Workflows</title>
      <dc:creator>Haris Putratama</dc:creator>
      <pubDate>Wed, 27 May 2026 14:00:01 +0000</pubDate>
      <link>https://dev.to/harisptrtm/we-made-design-requestable-by-ai-agents-heres-how-mcp-changes-creative-workflows-153n</link>
      <guid>https://dev.to/harisptrtm/we-made-design-requestable-by-ai-agents-heres-how-mcp-changes-creative-workflows-153n</guid>
      <description>&lt;p&gt;&lt;strong&gt;Most AI agent workflows end at code, data, and text.&lt;/strong&gt; Need a social media graphic? A product mockup? A brand asset? You're back to manual: open Figma, write a brief, wait for a designer, iterate.&lt;/p&gt;

&lt;p&gt;We built a design platform that AI agents can talk to directly — using Model Context Protocol (MCP).&lt;/p&gt;

&lt;p&gt;This post covers what we learned, how it works, and why design is the last major workflow that hasn't been automated by AI agents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Problem: AI Agents Can't "See" Design&lt;/strong&gt;&lt;br&gt;
Your AI coding assistant can write code, search docs, run terminal commands, query databases. But ask it to create a restaurant menu design, a social media carousel, or a brand asset — it hits a wall.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The typical workaround:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Developer → asks AI to write copy → manually opens Canva/Figma → &lt;br&gt;
pastes copy → adjusts layout → exports → uploads&lt;br&gt;
That's 4 manual steps for something that should be one instruction.&lt;/p&gt;

&lt;p&gt;What MCP Actually Is (30-Second Version)&lt;br&gt;
Model Context Protocol is an open standard (by Anthropic) that lets AI agents connect to external tools through a unified interface. Think of it as USB-C for AI — one protocol, any tool.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────┐     MCP      ┌──────────────┐
│  AI Agent   │ ◄──────────► │  Tool Server │
│ (Claude,    │   JSON-RPC   │  (your app)  │
│  Cursor,    │              │              │
│  any LLM)   │              │              │
└─────────────┘              └──────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An MCP server exposes tools (functions the agent can call) and resources (data the agent can read). The agent discovers available tools, decides when to use them, and calls them with structured parameters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Design is Perfect for MCP&lt;/strong&gt;&lt;br&gt;
Design requests are already structured:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "social_media_post",
  "platform": "instagram",
  "dimensions": "1080x1080",
  "brand": "my-coffee-shop",
  "copy": "Grand opening this Saturday!",
  "style": "warm, inviting, lifestyle photography",
  "include_logo": true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a function call. AI agents are built for exactly this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How We Implemented It&lt;/strong&gt;&lt;br&gt;
At Meepo, we built an MCP server that exposes design operations as tools using the official @modelcontextprotocol/sdk. Here's the simplified architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────┐     MCP      ┌──────────────┐     API      ┌──────────────┐
│  Your AI     │ ◄──────────► │  Meepo MCP   │ ◄──────────► │  Design      │
│  Agent       │              │  Server      │              │  Pipeline    │
│              │              │  (Node/Bun)  │              │  (AI + Human)│
└──────────────┘              └──────────────┘              └──────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Tools We Expose&lt;/strong&gt;&lt;br&gt;
Instead of a static array, the server uses standard MCP schema definitions to register tools dynamically. Here are the core tools our agent uses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { z } from 'zod'

const server = new McpServer({
  name: 'meepo-studio',
  version: '1.0.0'
})

// 1. List available brand profiles
server.tool(
  'brand_list',
  'List all brands for your company. Returns brand names, logos, color palettes, and IDs.',
  {},
  async () =&amp;gt; {
    const result = await designApi.get('/api/v1/brands')
    return { content: [{ type: 'text', text: JSON.stringify(result.data) }] }
  }
)

// 2. Fetch specific brand rules dynamically
server.tool(
  'brand_get',
  'Get detailed brand information including color palette, fonts, tone of voice, references, and product images.',
  { brandId: z.string().describe('The brand ID to retrieve') },
  async ({ brandId }) =&amp;gt; {
    const result = await designApi.get(`/api/v1/brands/${brandId}`)
    return { content: [{ type: 'text', text: JSON.stringify(result.data) }] }
  }
)

// 3. Initiate a design request thread
server.tool(
  'chat_create',
  'Create a new design request. Starts a conversation with the AI designer.',
  {
    brandId: z.string().describe('Brand ID for the design'),
    title: z.string().describe('Request title (e.g. "Instagram post")'),
    type: z.enum(['AI', 'HUMAN']).describe('AI for instant preview, HUMAN for designer queue'),
    prompt: z.string().describe('Design brief - describe what you want designed'),
    designFormat: z.string().optional().describe('Format e.g. "Social Media Post"'),
    ratio: z.string().optional().describe('Aspect ratio: 1:1, 9:16, 16:9, etc.'),
    multipleDesign: z.boolean().optional().describe('Set true for carousel/multi-slide designs'),
    maxSlides: z.number().optional().describe('Max slides for carousel (3-15)'),
  },
  async ({ brandId, title, type, prompt, ...opts }) =&amp;gt; {
    const result = await designApi.post('/api/v1/chats', { brandId, title, type, prompt, ...opts })
    return { content: [{ type: 'text', text: JSON.stringify(result.data) }] }
  }
)

// 4. Poll or check for generated output images
server.tool(
  'generation_poll',
  'Poll for AI-generated images until all slides are ready.',
  {
    chatId: z.string().describe('Chat ID to poll generations for'),
    expectedSlides: z.number().optional().describe('Number of slides to wait for')
  },
  async ({ chatId, expectedSlides = 1 }) =&amp;gt; {
    // Polling loop returning finalized assets...
  }
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What Happens When an Agent Calls chat_create&lt;/strong&gt;&lt;br&gt;
Agent sends structured request via MCP tool call.&lt;br&gt;
MCP server validates payload and starts a design request thread.&lt;br&gt;
AI pipeline generates initial concepts (seconds).&lt;br&gt;
Returns generated design records and image URLs to the agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "chat": {
    "id": "c_abc123",
    "title": "Instagram Announcement",
    "type": "AI"
  },
  "generations": [
    {
      "id": "g_xyz789",
      "urls": [
        "https://cdn.meepo.app/previews/d_abc123_v1.webp",
        "https://cdn.meepo.app/previews/d_abc123_v2.webp"
      ],
      "creditsUsed": 1
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Real Use Case: Automated Social Media Pipeline&lt;/strong&gt;&lt;br&gt;
Here's where it gets interesting. Imagine this agent workflow:&lt;/p&gt;

&lt;p&gt;Agent monitors your calendar/CRM for events.&lt;br&gt;
Detects: "Product launch next Tuesday".&lt;br&gt;
Calls chat_create → Instagram announcement post (1:1).&lt;br&gt;
Calls chat_create → LinkedIn banner (16:9).&lt;br&gt;
Calls chat_create → Twitter/X header.&lt;br&gt;
Schedules posts via social media API.&lt;br&gt;
Zero human intervention for routine marketing design. Your brand guidelines are pre-loaded, AI generates on-brand concepts, and if you want premium quality — human designers polish async.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Technical Gotchas We Hit&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Brand Consistency Across Calls
AI agents don't remember your brand colors. Every chat_create call needs access to the brand profile. Instead of maintaining complex static resources, we let the agent query brand assets dynamically via brand_get before launching design requests:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Step 1: Read brand guidelines
const brand = await mcpClient.callTool("brand_get", { brandId: "brand_coffee_shop" });

// Step 2: Feed brand-specific contexts into the design request brief
const design = await mcpClient.callTool("chat_create", {
  brandId: "brand_coffee_shop",
  title: "Special offer",
  type: "AI",
  prompt: `Use brand font ${brand.bodyFont}. Apply palette colors: ${brand.colorPalette.join(', ')}.`
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Async vs Sync&lt;br&gt;
AI-generated designs return in seconds (sync). Human-polished designs take hours (async). The agent needs to handle both. We solved this by using generation_poll to block/poll for AI-complete assets instantly, while exposing async task tools for tracking human designers' progress when a longer-term queue is preferred.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rate Limiting ≠ Credit System&lt;br&gt;
MCP doesn't have native rate limiting concepts. We map credits directly to tool calls and return remaining balance details. Agents check balance via subscription_get before scheduling heavy generation batches.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why This Matters Beyond Our Use Case&lt;/strong&gt;&lt;br&gt;
Design is just one example. The pattern applies to any creative service:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Video editing — agent sends footage + brief, gets edited video.&lt;/li&gt;
&lt;li&gt;Copywriting — agent sends context, gets brand-voice copy.&lt;/li&gt;
&lt;li&gt;Audio — agent sends script, gets voiceover.&lt;/li&gt;
&lt;li&gt;MCP makes all of these composable. An agent could chain: research → write copy → generate design → create video → schedule post — all through standard tool calls.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;&lt;br&gt;
If you're building an MCP server for any creative tool:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with the tool schema — what inputs does your creative process actually need?&lt;/li&gt;
&lt;li&gt;Expose brand/context dynamically — agents need real-time data access to produce consistent output.&lt;/li&gt;
&lt;li&gt;Handle async gracefully — creative work often has human-in-the-loop steps.&lt;/li&gt;
&lt;li&gt;Return previews, not just IDs — agents (and the humans using them) need to see results.
MCP specification: modelcontextprotocol.io&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to try design via MCP specifically, we're building this at Meepo — AI generates concepts instantly, human designers polish to agency quality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What creative workflows are you automating with AI agents?&lt;/strong&gt; Would love to hear what's worked (and what's been painful).&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>design</category>
      <category>automation</category>
    </item>
  </channel>
</rss>
